From f2438e1da975672c22e8794030e3c4450f7a3525 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Tue, 14 Dec 2004 16:01:29 +0000 Subject: [PATCH] * src/base/ftbitmap.c, include/freetype/ftbitmap.h: New files for handling various bitmap formats. * include/freetype/config/ftheader.h (FT_BITMAP_H): New macro. * src/base/rules.mk (BASE_EXT_SRC): Add ftbitmap.c. * src/bdf/bdfdrivr.c (BDF_Glyph_Load): Don't convert bitmaps to 8bpp but return them as-is. * docs/CHANGES: Mention new bitmap API. * include/freetype/ftchapter.s: Updated. --- ChangeLog | 15 ++ docs/CHANGES | 12 ++ include/freetype/config/ftheader.h | 12 ++ include/freetype/ftbitmap.h | 133 +++++++++++++++ include/freetype/ftchapters.h | 2 +- src/base/ftbitmap.c | 262 +++++++++++++++++++++++++++++ src/base/rules.mk | 3 +- src/bdf/bdfdrivr.c | 128 +++----------- 8 files changed, 459 insertions(+), 108 deletions(-) create mode 100644 include/freetype/ftbitmap.h create mode 100644 src/base/ftbitmap.c diff --git a/ChangeLog b/ChangeLog index 5274c6419..8fb96f6e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2004-12-14 Werner Lemberg + + * src/base/ftbitmap.c, include/freetype/ftbitmap.h: New files for + handling various bitmap formats. + + * include/freetype/config/ftheader.h (FT_BITMAP_H): New macro. + + * src/base/rules.mk (BASE_EXT_SRC): Add ftbitmap.c. + + * src/bdf/bdfdrivr.c (BDF_Glyph_Load): Don't convert bitmaps to 8bpp + but return them as-is. + + * docs/CHANGES: Mention new bitmap API. + * include/freetype/ftchapter.s: Updated. + 2004-12-11 Robert Clark * src/base/ftobjs.c (FT_Get_Kerning): Make kerning amount diff --git a/docs/CHANGES b/docs/CHANGES index 2d07a1270..24e4bf8c2 100644 --- a/docs/CHANGES +++ b/docs/CHANGES @@ -36,6 +36,18 @@ LATEST CHANGES BETWEEN 2.1.10 and 2.1.9 JSTF). After validation it is no longer necessary to check for errors in those tables while accessing them. + - A new API in FT_BITMAP_H (`FT_Bitmap_New', `FT_Bitmap_Convert', + `FT_Bitmap_Done') has been added. Its use is to convert + an FT_Bitmap structure in 1bpp, 2bpp, 4bpp, or 8bpp format into + another 8bpp FT_Bitmap, probably using a different pitch. + + III. MISCELLANEOUS + + - The BDF driver no longer converts all returned bitmaps with a + depth of 2bpp or 4bpp to a depth of 8bpp. The documentation has + not mentioned this explicitly, but implementors might have + relied on this after looking into the source files. + LATEST CHANGES BETWEEN 2.1.9 and 2.1.8 diff --git a/include/freetype/config/ftheader.h b/include/freetype/config/ftheader.h index 7b18813cc..a6df10d2a 100644 --- a/include/freetype/config/ftheader.h +++ b/include/freetype/config/ftheader.h @@ -413,6 +413,18 @@ #define FT_GLYPH_H + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_BITMAP_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the API of the optional bitmap conversion component. */ + /* */ +#define FT_BITMAP_H + + /*************************************************************************/ /* */ /* @macro: */ diff --git a/include/freetype/ftbitmap.h b/include/freetype/ftbitmap.h new file mode 100644 index 000000000..d69923850 --- /dev/null +++ b/include/freetype/ftbitmap.h @@ -0,0 +1,133 @@ +/***************************************************************************/ +/* */ +/* ftbitmap.h */ +/* */ +/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */ +/* bitmaps into 8bpp format (specification). */ +/* */ +/* Copyright 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTBITMAP_H__ +#define __FTBITMAP_H__ + + +#include +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /*
*/ + /* bitmap_handling */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Bitmap_New */ + /* */ + /* */ + /* Initialize a pointer to an FT_Bitmap structure. */ + /* */ + /* */ + /* abitmap :: A pointer to the bitmap structure. */ + /* */ + FT_EXPORT( void ) + FT_Bitmap_New( FT_Bitmap *abitmap ); + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Bitmap_Convert */ + /* */ + /* */ + /* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, or 8bpp to a */ + /* bitmap object with depth 8bpp, making the number of used bytes per */ + /* line (a.k.a. the `pitch') a multiple of `alignment'. */ + /* */ + /* */ + /* library :: A handle to a library object. */ + /* */ + /* source :: The source bitmap. */ + /* */ + /* alignment :: The pitch of the bitmap is a multiple of this */ + /* parameter. Common values are 1, 2, or 4. */ + /* */ + /* */ + /* target :: The target bitmap. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* It is possible to call @FT_Bitmap_Convert multiple times without */ + /* calling @FT_Bitmap_Done (the memory is simply reallocated). */ + /* */ + /* Use @FT_Bitmap_Done to finally remove the bitmap object. */ + /* */ + /* The `library' argument is taken to have access to FreeType's */ + /* memory handling functions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Convert( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target, + FT_Int alignment ); + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Bitmap_Done */ + /* */ + /* */ + /* Destroy a bitmap object created with @FT_Bitmap_New. */ + /* */ + /* */ + /* library :: A handle to a library object. */ + /* */ + /* bitmap :: The bitmap object to be freed. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* The `library' argument is taken to have access to FreeType's */ + /* memory handling functions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Done( FT_Library library, + FT_Bitmap *bitmap ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTBITMAP_H__ */ + + +/* END */ diff --git a/include/freetype/ftchapters.h b/include/freetype/ftchapters.h index 462859986..781160bd2 100644 --- a/include/freetype/ftchapters.h +++ b/include/freetype/ftchapters.h @@ -71,6 +71,7 @@ /* computations */ /* list_processing */ /* outline_processing */ +/* bitmap_handling */ /* raster */ /* glyph_stroker */ /* system_interface */ @@ -79,4 +80,3 @@ /* lzw */ /* */ /***************************************************************************/ - diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c new file mode 100644 index 000000000..3e3d0fc1e --- /dev/null +++ b/src/base/ftbitmap.c @@ -0,0 +1,262 @@ +/***************************************************************************/ +/* */ +/* ftbitmap.c */ +/* */ +/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */ +/* bitmaps into 8bpp format (body). */ +/* */ +/* Copyright 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include +#include FT_FREETYPE_H +#include FT_IMAGE_H +#include FT_INTERNAL_OBJECTS_H + + + static + const FT_Bitmap null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( void ) + FT_Bitmap_New( FT_Bitmap *abitmap ) + { + *abitmap = null_bitmap; + } + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Convert( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target, + FT_Int alignment ) + { + FT_Error error; + FT_Memory memory; + FT_Int i, j, old_size; + FT_Byte *s, *ss, *t, *tt; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + memory = library->memory; + + switch ( source->pixel_mode ) + { + case FT_PIXEL_MODE_MONO: + case FT_PIXEL_MODE_GRAY: + case FT_PIXEL_MODE_GRAY2: + case FT_PIXEL_MODE_GRAY4: + old_size = target->rows * target->pitch; + + target->pixel_mode = FT_PIXEL_MODE_GRAY; + target->rows = source->rows; + target->width = source->width; + target->pitch = ( source->width + alignment - 1 ) + / alignment * alignment; + + if ( target->rows * target->pitch > old_size ) + if ( FT_QREALLOC( target->buffer, + old_size, target->rows * target->pitch ) ) + return error; + + break; + + default: + error = FT_Err_Invalid_Argument; + } + + s = source->buffer; + t = target->buffer; + + switch ( source->pixel_mode ) + { + case FT_PIXEL_MODE_MONO: + target->num_grays = 2; + + for ( i = 0; i < source->rows; i++ ) + { + ss = s; + tt = t; + + /* get the full bytes */ + for ( j = 0; j < ( source->width >> 3 ); j++ ) + { + *(tt++) = (FT_Byte)( ( *ss & 0x80 ) >> 7 ); + *(tt++) = (FT_Byte)( ( *ss & 0x40 ) >> 6 ); + *(tt++) = (FT_Byte)( ( *ss & 0x20 ) >> 5 ); + *(tt++) = (FT_Byte)( ( *ss & 0x10 ) >> 4 ); + *(tt++) = (FT_Byte)( ( *ss & 0x08 ) >> 3 ); + *(tt++) = (FT_Byte)( ( *ss & 0x04 ) >> 2 ); + *(tt++) = (FT_Byte)( ( *ss & 0x02 ) >> 1 ); + *(tt++) = (FT_Byte)( *ss & 0x01 ); + + ss++; + } + + /* get remaining pixels (if any) */ + switch ( source->width & 7 ) + { + case 7: + *(tt++) = (FT_Byte)( ( *ss & 0x80 ) >> 7 ); + /* fall through */ + case 6: + *(tt++) = (FT_Byte)( ( *ss & 0x40 ) >> 6 ); + /* fall through */ + case 5: + *(tt++) = (FT_Byte)( ( *ss & 0x20 ) >> 5 ); + /* fall through */ + case 4: + *(tt++) = (FT_Byte)( ( *ss & 0x10 ) >> 4 ); + /* fall through */ + case 3: + *(tt++) = (FT_Byte)( ( *ss & 0x08 ) >> 3 ); + /* fall through */ + case 2: + *(tt++) = (FT_Byte)( ( *ss & 0x04 ) >> 2 ); + /* fall through */ + case 1: + *(tt++) = (FT_Byte)( ( *ss & 0x02 ) >> 1 ); + /* fall through */ + case 0: + break; + } + + s += source->pitch; + t += target->pitch; + } + break; + + case FT_PIXEL_MODE_GRAY: + target->num_grays = 256; + + for ( i = 0; i < source->rows; i++ ) + { + ss = s; + tt = t; + + for ( j = 0; j < source->width; j++ ) + *(tt++) = *(ss++); + + s += source->pitch; + t += target->pitch; + } + break; + + case FT_PIXEL_MODE_GRAY2: + target->num_grays = 4; + + for ( i = 0; i < source->rows; i++ ) + { + ss = s; + tt = t; + + /* get the full bytes */ + for ( j = 0; j < ( source->width >> 2 ); j++ ) + { + *(tt++) = (FT_Byte)( ( *ss & 0xC0 ) >> 6 ); + *(tt++) = (FT_Byte)( ( *ss & 0x30 ) >> 4 ); + *(tt++) = (FT_Byte)( ( *ss & 0x0C ) >> 2 ); + *(tt++) = (FT_Byte)( *ss & 0x03 ); + + ss++; + } + + /* get remaining pixels (if any) */ + switch ( source->width & 3 ) + { + case 3: + *(tt++) = (FT_Byte)( ( *ss & 0xC0 ) >> 6 ); + /* fall through */ + case 2: + *(tt++) = (FT_Byte)( ( *ss & 0x30 ) >> 4 ); + /* fall through */ + case 1: + *(tt++) = (FT_Byte)( ( *ss & 0x0C ) >> 2 ); + /* fall through */ + case 0: + break; + } + + s += source->pitch; + t += target->pitch; + } + break; + + case FT_PIXEL_MODE_GRAY4: + target->num_grays = 16; + + for ( i = 0; i < source->rows; i++ ) + { + ss = s; + tt = t; + + /* get the full bytes */ + for ( j = 0; j < ( source->width >> 1 ); j++ ) + { + *(tt++) = (FT_Byte)( ( *ss & 0xF0 ) >> 4 ); + *(tt++) = (FT_Byte)( *ss & 0x0F ); + + ss++; + } + + /* get remaining pixels (if any) */ + switch ( source->width & 1 ) + { + case 1: + *(tt++) = (FT_Byte)( ( *ss & 0xF0 ) >> 4 ); + /* fall through */ + case 0: + break; + } + + s += source->pitch; + t += target->pitch; + } + break; + + } + + return error; + } + + + /* documentation is in ftbitmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Bitmap_Done( FT_Library library, + FT_Bitmap *bitmap ) + { + FT_Memory memory; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !bitmap ) + return FT_Err_Invalid_Argument; + + memory = library->memory; + + FT_FREE( bitmap->buffer ); + *bitmap = null_bitmap; + + return FT_Err_Ok; + } + + +/* END */ diff --git a/src/base/rules.mk b/src/base/rules.mk index 74e66e20e..993b53266 100644 --- a/src/base/rules.mk +++ b/src/base/rules.mk @@ -50,7 +50,8 @@ BASE_SRC := $(BASE_DIR)/ftapi.c \ # object. It will then be linked to the final executable only if one of its # symbols is used by the application. # -BASE_EXT_SRC := $(BASE_DIR)/ftbbox.c \ +BASE_EXT_SRC := $(BASE_DIR)/ftbitmap.c \ + $(BASE_DIR)/ftbbox.c \ $(BASE_DIR)/ftbdf.c \ $(BASE_DIR)/ftglyph.c \ $(BASE_DIR)/ftmm.c \ diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c index b32e70d97..b28e7c3c3 100644 --- a/src/bdf/bdfdrivr.c +++ b/src/bdf/bdfdrivr.c @@ -643,13 +643,11 @@ THE SOFTWARE. FT_UInt glyph_index, FT_Int32 load_flags ) { - BDF_Face face = (BDF_Face)FT_SIZE_FACE( size ); - FT_Error error = BDF_Err_Ok; - FT_Bitmap* bitmap = &slot->bitmap; - bdf_glyph_t glyph; - int bpp = face->bdffont->bpp; - int i, j, count; - unsigned char *p, *pp; + BDF_Face face = (BDF_Face)FT_SIZE_FACE( size ); + FT_Error error = BDF_Err_Ok; + FT_Bitmap* bitmap = &slot->bitmap; + bdf_glyph_t glyph; + int bpp = face->bdffont->bpp; FT_UNUSED( load_flags ); @@ -671,109 +669,27 @@ THE SOFTWARE. bitmap->rows = glyph.bbx.height; bitmap->width = glyph.bbx.width; + bitmap->pitch = glyph.bpr; - if ( bpp == 1 ) + /* note: we don't allocate a new array to hold the bitmap; */ + /* we can simply point to it */ + ft_glyphslot_set_bitmap( slot, glyph.bitmap ); + + switch ( bpp ) { + case 1: bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - bitmap->pitch = glyph.bpr; - - /* note: we don't allocate a new array to hold the bitmap; */ - /* we can simply point to it */ - ft_glyphslot_set_bitmap( slot, glyph.bitmap ); - } - else - { - /* blow up pixmap to have 8 bits per pixel */ + break; + case 2: + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY2; + break; + case 4: + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY4; + break; + case 8: bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; - bitmap->pitch = bitmap->width; - - error = ft_glyphslot_alloc_bitmap( slot, bitmap->rows * bitmap->pitch ); - if ( error ) - goto Exit; - - switch ( bpp ) - { - case 2: - bitmap->num_grays = 4; - - count = 0; - p = glyph.bitmap; - - for ( i = 0; i < bitmap->rows; i++ ) - { - pp = p; - - /* get the full bytes */ - for ( j = 0; j < ( bitmap->width >> 2 ); j++ ) - { - bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xC0 ) >> 6 ); - bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x30 ) >> 4 ); - bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x0C ) >> 2 ); - bitmap->buffer[count++] = (FT_Byte)( *pp & 0x03 ); - - pp++; - } - - /* get remaining pixels (if any) */ - switch ( bitmap->width & 3 ) - { - case 3: - bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xC0 ) >> 6 ); - /* fall through */ - case 2: - bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x30 ) >> 4 ); - /* fall through */ - case 1: - bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x0C ) >> 2 ); - /* fall through */ - case 0: - break; - } - - p += glyph.bpr; - } - break; - - case 4: - bitmap->num_grays = 16; - - count = 0; - p = glyph.bitmap; - - for ( i = 0; i < bitmap->rows; i++ ) - { - pp = p; - - /* get the full bytes */ - for ( j = 0; j < ( bitmap->width >> 1 ); j++ ) - { - bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xF0 ) >> 4 ); - bitmap->buffer[count++] = (FT_Byte)( *pp & 0x0F ); - - pp++; - } - - /* get remaining pixel (if any) */ - switch ( bitmap->width & 1 ) - { - case 1: - bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xF0 ) >> 4 ); - /* fall through */ - case 0: - break; - } - - p += glyph.bpr; - } - break; - - case 8: - bitmap->num_grays = 256; - - FT_MEM_COPY( bitmap->buffer, glyph.bitmap, - bitmap->rows * bitmap->pitch ); - break; - } + bitmap->num_grays = 256; + break; } slot->bitmap_left = glyph.bbx.x_offset;