* 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.
This commit is contained in:
Werner Lemberg 2004-12-14 16:01:29 +00:00
parent 0418a1c4c5
commit e97c3bdc29
8 changed files with 459 additions and 108 deletions

View File

@ -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

View File

@ -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

View File

@ -413,6 +413,18 @@
#define FT_GLYPH_H <freetype/ftglyph.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 <freetype/ftbitmap.h>
/*************************************************************************/
/* */
/* @macro: */

133
include/freetype/ftbitmap.h Normal file
View File

@ -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 <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 */

View File

@ -71,6 +71,7 @@
/* computations */
/* list_processing */
/* outline_processing */
/* bitmap_handling */
/* raster */
/* glyph_stroker */
/* system_interface */
@ -79,4 +80,3 @@
/* lzw */
/* */
/***************************************************************************/

262
src/base/ftbitmap.c Normal file
View File

@ -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 <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 */

View File

@ -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 \

View File

@ -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;