ref: f2438e1da975672c22e8794030e3c4450f7a3525
parent: ece8b20e6c51924b85f3055e555a430a2d4bfd1b
author: Werner Lemberg <wl@gnu.org>
date: Tue Dec 14 11:01:29 EST 2004
* 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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2004-12-14 Werner Lemberg <wl@gnu.org>
+
+ * 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 <freetype@ratty.org.uk>
* src/base/ftobjs.c (FT_Get_Kerning): Make kerning amount
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -36,6 +36,18 @@
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
--- a/include/freetype/config/ftheader.h
+++ b/include/freetype/config/ftheader.h
@@ -416,6 +416,18 @@
/*************************************************************************/
/* */
/* @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 <freetype/ftbitmap.h>
+
+
+ /*************************************************************************/
+ /* */
+ /* @macro: */
/* FT_BBOX_H */
/* */
/* @description: */
--- /dev/null
+++ b/include/freetype/ftbitmap.h
@@ -1,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 <ft2build.h>
+#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
+
+
+ /*************************************************************************/
+ /* */
+ /* <Section> */
+ /* bitmap_handling */
+ /* */
+ /*************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Bitmap_New */
+ /* */
+ /* <Description> */
+ /* Initialize a pointer to an FT_Bitmap structure. */
+ /* */
+ /* <InOut> */
+ /* abitmap :: A pointer to the bitmap structure. */
+ /* */
+ FT_EXPORT( void )
+ FT_Bitmap_New( FT_Bitmap *abitmap );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Bitmap_Convert */
+ /* */
+ /* <Description> */
+ /* 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'. */
+ /* */
+ /* <Input> */
+ /* 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. */
+ /* */
+ /* <Output> */
+ /* target :: The target bitmap. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* 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 );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Bitmap_Done */
+ /* */
+ /* <Description> */
+ /* Destroy a bitmap object created with @FT_Bitmap_New. */
+ /* */
+ /* <Input> */
+ /* library :: A handle to a library object. */
+ /* */
+ /* bitmap :: The bitmap object to be freed. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ /* <Note> */
+ /* 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 */
--- 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 */
/* */
/***************************************************************************/
-
--- /dev/null
+++ b/src/base/ftbitmap.c
@@ -1,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 <ft2build.h>
+#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 */
--- a/src/base/rules.mk
+++ b/src/base/rules.mk
@@ -50,7 +50,8 @@
# 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 \
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -643,13 +643,11 @@
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 @@
bitmap->rows = glyph.bbx.height;
bitmap->width = glyph.bbx.width;
+ bitmap->pitch = glyph.bpr;
- if ( bpp == 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 );
- /* 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
+ switch ( bpp )
{- /* blow up pixmap to have 8 bits per pixel */
+ case 1:
+ bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
+ 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;
--
⑨