summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Turner <david@freetype.org>2002-02-06 11:22:56 +0000
committerDavid Turner <david@freetype.org>2002-02-06 11:22:56 +0000
commita391b7e86f8958b53600ea52dc333a46103d4d62 (patch)
tree88e29c659801a5050bd440f6b67fcafacb338e09
parent025bbaa967ef69f0831bdf22fa621aaba476141f (diff)
downloadfreetype2-a391b7e86f8958b53600ea52dc333a46103d4d62.tar.gz
fixing memory leak in the PCF driver, and managing the
"AVERAGE_WIDTH" property in PCF fonts to return correct character pixel (width/height) pairs for embedded bitmaps..
-rw-r--r--ChangeLog22
-rw-r--r--src/pcf/pcf.h5
-rw-r--r--src/pcf/pcfdriver.c50
-rw-r--r--src/pcf/pcfread.c225
4 files changed, 162 insertions, 140 deletions
diff --git a/ChangeLog b/ChangeLog
index f40cab88e..a00d0d86a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2002-02-06 David Turner <david@freetype.org>
+
+ * src/sfnt/ttcmap.c: removing compiler warnings
+
+ * src/pcf/pcfread.c, src/pcf/pcf.h, src/pcf/pcfdriver.c:
+ removing minor bugs (delaying format checks out of
+ FT_Access_Frame .. FT_Forget_Frame blocks to avoid leaving the
+ stream in an incorrect state when encountering an invalid PCF
+ font)
+
+ reformatting / renaming a few functions for the sake of consistency
+
+
+2002-02-06 Detlef Würkner
+
+ * src/pcf/pcfdriver.c (FT_Done_Face): fixed small memory leak
+
+ * src/pcf/pcfread.c (pcf_load_font): now handles the "AVERAGE_WIDTH"
+ property to return correct character pixel (width/height) pairs for
+ embedded bitmaps..
+
+
2002-02-04 Keith Packard <keithp@keithp.com>
Adding the function `FT_Get_Next_Char', doing the obvious thing
diff --git a/src/pcf/pcf.h b/src/pcf/pcf.h
index 3941b6a3f..22d3da4fa 100644
--- a/src/pcf/pcf.h
+++ b/src/pcf/pcf.h
@@ -159,11 +159,6 @@ FT_BEGIN_HEADER
} PCF_FaceRec, *PCF_Face;
- /* XXX hack */
- FT_LOCAL FT_Error
- PCF_Done_Face( PCF_Face face );
-
-
/* macros for pcf font format */
#define LSBFirst 0
diff --git a/src/pcf/pcfdriver.c b/src/pcf/pcfdriver.c
index d172879d9..864036bbb 100644
--- a/src/pcf/pcfdriver.c
+++ b/src/pcf/pcfdriver.c
@@ -48,24 +48,32 @@ THE SOFTWARE.
#define FT_COMPONENT trace_pcfdriver
- FT_LOCAL_DEF FT_Error
- PCF_Done_Face( PCF_Face face )
+ static FT_Error
+ PCF_Face_Done( PCF_Face face )
{
FT_Memory memory = FT_FACE_MEMORY( face );
- PCF_Property tmp = face->properties;
- int i;
FREE( face->encodings );
FREE( face->metrics );
- for ( i = 0; i < face->nprops; i++ )
+ /* free properties */
{
- FREE( tmp->name );
- if ( tmp->isString )
- FREE( tmp->value );
+ PCF_Property prop = face->properties;
+ FT_Int i;
+
+ for ( i = 0; i < face->nprops; i++ )
+ {
+ prop = &face->properties[i];
+
+ FREE( prop->name );
+ if ( prop->isString )
+ FREE( prop->value );
+ }
+
+ FREE( face->properties );
}
- FREE( face->properties );
+
FREE( face->toc.tables );
FREE( face->root.family_name );
FREE( face->root.available_sizes );
@@ -79,7 +87,7 @@ THE SOFTWARE.
static FT_Error
- PCF_Init_Face( FT_Stream stream,
+ PCF_Face_Init( FT_Stream stream,
PCF_Face face,
FT_Int face_index,
FT_Int num_params,
@@ -100,7 +108,7 @@ THE SOFTWARE.
Fail:
FT_TRACE2(( "[not a valid PCF file]\n" ));
- PCF_Done_Face( face );
+ PCF_Face_Done( face );
return PCF_Err_Unknown_File_Format; /* error */
}
@@ -138,19 +146,19 @@ THE SOFTWARE.
static FT_Error
- PCF_Load_Glyph( FT_GlyphSlot slot,
+ PCF_Glyph_Load( FT_GlyphSlot slot,
FT_Size size,
FT_UInt glyph_index,
FT_Int load_flags )
{
PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
+ FT_Stream stream = face->root.stream;
FT_Error error = PCF_Err_Ok;
FT_Memory memory = FT_FACE(face)->memory;
FT_Bitmap* bitmap = &slot->bitmap;
PCF_Metric metric;
int bytes;
- FT_Stream stream = face->root.stream;
FT_UNUSED( load_flags );
@@ -249,7 +257,7 @@ THE SOFTWARE.
static FT_UInt
- PCF_Get_Char_Index( FT_CharMap charmap,
+ PCF_Char_Get_Index( FT_CharMap charmap,
FT_Long char_code )
{
PCF_Face face = (PCF_Face)charmap->face;
@@ -277,7 +285,7 @@ THE SOFTWARE.
static FT_Long
- PCF_Get_Next_Char( FT_CharMap charmap,
+ PCF_Char_Get_Next( FT_CharMap charmap,
FT_Long char_code )
{
PCF_Face face = (PCF_Face)charmap->face;
@@ -285,7 +293,7 @@ THE SOFTWARE.
int low, high, mid;
- FT_TRACE4(( "get_char_index %ld\n", char_code ));
+ FT_TRACE4(( "get_next_char %ld\n", char_code ));
char_code++;
low = 0;
@@ -338,8 +346,8 @@ THE SOFTWARE.
sizeof( FT_SizeRec ),
sizeof( FT_GlyphSlotRec ),
- (FTDriver_initFace) PCF_Init_Face,
- (FTDriver_doneFace) PCF_Done_Face,
+ (FTDriver_initFace) PCF_Face_Init,
+ (FTDriver_doneFace) PCF_Face_Done,
(FTDriver_initSize) 0,
(FTDriver_doneSize) 0,
(FTDriver_initGlyphSlot)0,
@@ -348,14 +356,14 @@ THE SOFTWARE.
(FTDriver_setCharSizes) PCF_Set_Pixel_Size,
(FTDriver_setPixelSizes)PCF_Set_Pixel_Size,
- (FTDriver_loadGlyph) PCF_Load_Glyph,
- (FTDriver_getCharIndex) PCF_Get_Char_Index,
+ (FTDriver_loadGlyph) PCF_Glyph_Load,
+ (FTDriver_getCharIndex) PCF_Char_Get_Index,
(FTDriver_getKerning) 0,
(FTDriver_attachFile) 0,
(FTDriver_getAdvances) 0,
- (FTDriver_getNextChar) PCF_Get_Next_Char
+ (FTDriver_getNextChar) PCF_Char_Get_Next,
};
diff --git a/src/pcf/pcfread.c b/src/pcf/pcfread.c
index 07acee32e..ffb28e980 100644
--- a/src/pcf/pcfread.c
+++ b/src/pcf/pcfread.c
@@ -94,8 +94,8 @@ THE SOFTWARE.
PCF_Toc toc = &face->toc;
PCF_Table tables;
- FT_Memory memory = FT_FACE(face)->memory;
- unsigned int n;
+ FT_Memory memory = FT_FACE(face)->memory;
+ FT_UInt n;
if ( FILE_Seek ( 0 ) ||
@@ -119,8 +119,8 @@ THE SOFTWARE.
#if defined( FT_DEBUG_LEVEL_TRACE )
{
- unsigned int i, j;
- const char *name = "?";
+ FT_UInt i, j;
+ const char* name = "?";
FT_TRACE4(( "Tables count: %ld\n", face->toc.count ));
@@ -128,8 +128,9 @@ THE SOFTWARE.
for ( i = 0; i < toc->count; i++ )
{
for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ )
- if ( tables[i].type == (unsigned int)( 1 << j ) )
+ if ( tables[i].type == (FT_UInt)( 1 << j ) )
name = tableNames[j];
+
FT_TRACE4(( "Table %d: type=%-6s format=0x%04lX "
"size=0x%06lX (%8ld) offset=0x%04lX\n",
i, name,
@@ -199,46 +200,6 @@ THE SOFTWARE.
};
- static FT_Error
- pcf_parse_metric( FT_Stream stream,
- const FT_Frame_Field* header,
- PCF_Metric metric )
- {
- FT_Error error = PCF_Err_Ok;
-
-
- if ( READ_Fields( header, metric ) )
- return error;
-
- return PCF_Err_Ok;
- }
-
-
- static FT_Error
- pcf_parse_compressed_metric( FT_Stream stream,
- PCF_Metric metric )
- {
- PCF_Compressed_MetricRec compr_metric;
- FT_Error error = PCF_Err_Ok;
-
-
- if ( READ_Fields( pcf_compressed_metric_header, &compr_metric ) )
- return error;
-
- metric->leftSideBearing =
- (FT_Short)( compr_metric.leftSideBearing - 0x80 );
- metric->rightSideBearing =
- (FT_Short)( compr_metric.rightSideBearing - 0x80 );
- metric->characterWidth =
- (FT_Short)( compr_metric.characterWidth - 0x80 );
- metric->ascent =
- (FT_Short)( compr_metric.ascent - 0x80 );
- metric->descent =
- (FT_Short)( compr_metric.descent - 0x80 );
- metric->attributes = 0;
-
- return PCF_Err_Ok;
- }
static FT_Error
@@ -246,33 +207,53 @@ THE SOFTWARE.
FT_ULong format,
PCF_Metric metric )
{
- FT_Error error = PCF_Err_Ok;
+ FT_Error error = PCF_Err_Ok;
if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
{
- if ( PCF_BYTE_ORDER( format ) == MSBFirst )
- error = pcf_parse_metric( stream, pcf_metric_msb_header, metric );
- else
- error = pcf_parse_metric( stream, pcf_metric_header, metric );
+ const FT_Frame_Field* fields;
+
+ /* parsing normal metrics */
+ fields = PCF_BYTE_ORDER( format ) == MSBFirst
+ ? pcf_metric_msb_header
+ : pcf_metric_header;
+
+ /* the following sets 'error' but doesn't return in case of failure */
+ (void) READ_Fields( fields, metric );
}
else
- error = pcf_parse_compressed_metric( stream, metric );
+ {
+ PCF_Compressed_MetricRec compr;
+
+
+ /* parsing compressed metrics */
+ if ( READ_Fields( pcf_compressed_metric_header, &compr ) )
+ goto Exit;
+
+ metric->leftSideBearing = (FT_Short)( compr.leftSideBearing - 0x80 );
+ metric->rightSideBearing = (FT_Short)( compr.rightSideBearing - 0x80 );
+ metric->characterWidth = (FT_Short)( compr.characterWidth - 0x80 );
+ metric->ascent = (FT_Short)( compr.ascent - 0x80 );
+ metric->descent = (FT_Short)( compr.descent - 0x80 );
+ metric->attributes = 0;
+ }
+ Exit:
return error;
}
static FT_Error
- pcfSeekToType( FT_Stream stream,
- PCF_Table tables,
- int ntables,
- FT_ULong type,
- FT_ULong* formatp,
- FT_ULong* sizep )
+ pcf_seek_to_table_type( FT_Stream stream,
+ PCF_Table tables,
+ FT_Int ntables,
+ FT_ULong type,
+ FT_ULong *aformat,
+ FT_ULong *asize )
{
FT_Error error;
- int i;
+ FT_Int i;
for ( i = 0; i < ntables; i++ )
@@ -280,10 +261,13 @@ THE SOFTWARE.
{
if ( stream->pos > tables[i].offset )
return PCF_Err_Invalid_Stream_Skip;
+
if ( FILE_Skip( tables[i].offset - stream->pos ) )
return PCF_Err_Invalid_Stream_Skip;
- *sizep = tables[i].size; /* unused - to be removed */
- *formatp = tables[i].format;
+
+ *asize = tables[i].size; /* unused - to be removed */
+ *aformat = tables[i].format;
+
return PCF_Err_Ok;
}
@@ -292,11 +276,11 @@ THE SOFTWARE.
static FT_Bool
- pcfHasType( PCF_Table tables,
- int ntables,
- FT_ULong type )
+ pcf_has_table_type( PCF_Table tables,
+ FT_Int ntables,
+ FT_ULong type )
{
- int i;
+ FT_Int i;
for ( i = 0; i < ntables; i++ )
@@ -336,8 +320,8 @@ THE SOFTWARE.
static PCF_Property
- find_property( PCF_Face face,
- const FT_String* prop )
+ pcf_find_property( PCF_Face face,
+ const FT_String* prop )
{
PCF_Property properties = face->properties;
FT_Bool found = 0;
@@ -363,7 +347,7 @@ THE SOFTWARE.
{
PCF_ParseProperty props = 0;
PCF_Property properties = 0;
- int nprops, i;
+ FT_Int nprops, i;
FT_ULong format, size;
FT_Error error;
FT_Memory memory = FT_FACE(face)->memory;
@@ -371,12 +355,12 @@ THE SOFTWARE.
FT_String* strings = 0;
- error = pcfSeekToType( stream,
- face->toc.tables,
- face->toc.count,
- PCF_PROPERTIES,
- &format,
- &size );
+ error = pcf_seek_to_table_type( stream,
+ face->toc.tables,
+ face->toc.count,
+ PCF_PROPERTIES,
+ &format,
+ &size );
if ( error )
goto Bail;
@@ -496,7 +480,7 @@ THE SOFTWARE.
int nmetrics = -1;
- error = pcfSeekToType( stream,
+ error = pcf_seek_to_table_type( stream,
face->toc.tables,
face->toc.count,
PCF_METRICS,
@@ -573,35 +557,36 @@ THE SOFTWARE.
char* bitmaps;
- error = pcfSeekToType( stream,
- face->toc.tables,
- face->toc.count,
- PCF_BITMAPS,
- &format,
- &size );
+ error = pcf_seek_to_table_type( stream,
+ face->toc.tables,
+ face->toc.count,
+ PCF_BITMAPS,
+ &format,
+ &size );
if ( error )
return error;
error = FT_Access_Frame( stream, 8 );
if ( error )
return error;
- format = GET_ULongLE();
- if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
- return PCF_Err_Invalid_File_Format;
+ format = GET_ULongLE();
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
nbitmaps = GET_ULong();
else
nbitmaps = GET_ULongLE();
+
FT_Forget_Frame( stream );
+
+ if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+ return PCF_Err_Invalid_File_Format;
+
if ( nbitmaps != face->nmetrics )
return PCF_Err_Invalid_File_Format;
if ( ALLOC( offsets, nbitmaps * sizeof ( FT_ULong ) ) )
return error;
- if ( error )
- goto Bail;
for ( i = 0; i < nbitmaps; i++ )
{
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
@@ -614,8 +599,6 @@ THE SOFTWARE.
if ( error )
goto Bail;
- if ( error )
- goto Bail;
for ( i = 0; i < GLYPHPADOPTIONS; i++ )
{
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
@@ -664,7 +647,7 @@ THE SOFTWARE.
PCF_Encoding tmpEncoding, encoding = 0;
- error = pcfSeekToType( stream,
+ error = pcf_seek_to_table_type( stream,
face->toc.tables,
face->toc.count,
PCF_BDF_ENCODINGS,
@@ -676,9 +659,8 @@ THE SOFTWARE.
error = FT_Access_Frame( stream, 14 );
if ( error )
return error;
+
format = GET_ULongLE();
- if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
- return PCF_Err_Invalid_File_Format;
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
{
@@ -699,6 +681,9 @@ THE SOFTWARE.
FT_Forget_Frame( stream );
+ if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+ return PCF_Err_Invalid_File_Format;
+
FT_TRACE4(( "enc: firstCol %d, lastCol %d, firstRow %d, lastRow %d\n",
firstCol, lastCol, firstRow, lastRow ));
@@ -810,16 +795,17 @@ THE SOFTWARE.
PCF_Accel accel = &face->accel;
- error = pcfSeekToType( stream,
- face->toc.tables,
- face->toc.count,
- type,
- &format,
- &size );
+ error = pcf_seek_to_table_type( stream,
+ face->toc.tables,
+ face->toc.count,
+ type,
+ &format,
+ &size );
if ( error )
goto Bail;
error = READ_ULongLE( format );
+
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
!PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
goto Bail;
@@ -838,6 +824,7 @@ THE SOFTWARE.
error = pcf_get_metric( stream, format, &(accel->minbounds) );
if ( error )
goto Bail;
+
error = pcf_get_metric( stream, format, &(accel->maxbounds) );
if ( error )
goto Bail;
@@ -847,6 +834,7 @@ THE SOFTWARE.
error = pcf_get_metric( stream, format, &(accel->ink_minbounds) );
if ( error )
goto Bail;
+
error = pcf_get_metric( stream, format, &(accel->ink_maxbounds) );
if ( error )
goto Bail;
@@ -881,7 +869,7 @@ THE SOFTWARE.
return error;;
/* Use the old accelerators if no BDF accelerators are in the file. */
- hasBDFAccelerators = pcfHasType( face->toc.tables,
+ hasBDFAccelerators = pcf_has_table_type( face->toc.tables,
face->toc.count,
PCF_BDF_ACCELERATORS );
if ( !hasBDFAccelerators )
@@ -933,14 +921,14 @@ THE SOFTWARE.
root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
root->style_flags = 0;
- prop = find_property( face, "SLANT" );
+ prop = pcf_find_property( face, "SLANT" );
if ( prop != NULL )
if ( prop->isString )
if ( ( *(prop->value.atom) == 'O' ) ||
( *(prop->value.atom) == 'I' ) )
root->style_flags |= FT_STYLE_FLAG_ITALIC;
- prop = find_property( face, "WEIGHT_NAME" );
+ prop = pcf_find_property( face, "WEIGHT_NAME" );
if ( prop != NULL )
if ( prop->isString )
if ( *(prop->value.atom) == 'B' )
@@ -957,7 +945,7 @@ THE SOFTWARE.
else if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
root->style_name = (char *)"Italic";
- prop = find_property( face, "FAMILY_NAME" );
+ prop = pcf_find_property( face, "FAMILY_NAME" );
if ( prop != NULL )
{
if ( prop->isString )
@@ -979,33 +967,43 @@ THE SOFTWARE.
if ( ALLOC_ARRAY( root->available_sizes, 1, FT_Bitmap_Size ) )
goto Bail;
- prop = find_property( face, "PIXEL_SIZE" );
+ prop = pcf_find_property( face, "PIXEL_SIZE" );
if ( prop != NULL )
{
+ root->available_sizes->height =
root->available_sizes->width = (FT_Short)( prop->value.integer );
- root->available_sizes->height = (FT_Short)( prop->value.integer );
+
+ prop = pcf_find_property( face, "AVERAGE_WIDTH" );
+ if ( prop != NULL )
+ root->available_sizes->width = (FT_Short)( prop->value.integer / 10 );
size_set = 1;
}
else
{
- prop = find_property( face, "POINT_SIZE" );
+ prop = pcf_find_property( face, "POINT_SIZE" );
if ( prop != NULL )
{
- PCF_Property xres = 0, yres = 0;
+ PCF_Property xres, yres, avgw;
+
+ xres = pcf_find_property( face, "RESOLUTION_X" );
+ yres = pcf_find_property( face, "RESOLUTION_Y" );
+ avgw = pcf_find_property( face, "AVERAGE_WIDTH" );
- xres = find_property( face, "RESOLUTION_X" );
- yres = find_property( face, "RESOLUTION_Y" );
-
- if ( ( xres != NULL ) && ( yres != NULL ) )
+ if ( ( yres != NULL ) && ( ( xres != NULL ) || ( avgw == NULL ) ) )
{
- root->available_sizes->width =
- (FT_Short)( prop->value.integer *
- xres->value.integer / 720 );
root->available_sizes->height =
(FT_Short)( prop->value.integer *
yres->value.integer / 720 );
+
+ if ( avgw != NULL )
+ root->available_sizes->width =
+ (FT_Short)( avgw->value.integer / 10 );
+ else
+ root->available_sizes->width =
+ (FT_Short)( prop->value.integer *
+ xres->value.integer / 720 );
size_set = 1;
}
@@ -1033,8 +1031,8 @@ THE SOFTWARE.
PCF_Property charset_registry = 0, charset_encoding = 0;
- charset_registry = find_property( face, "CHARSET_REGISTRY" );
- charset_encoding = find_property( face, "CHARSET_ENCODING" );
+ charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" );
+ charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" );
if ( ( charset_registry != NULL ) &&
( charset_encoding != NULL ) )
@@ -1072,7 +1070,6 @@ THE SOFTWARE.
return PCF_Err_Ok;
Bail:
- PCF_Done_Face( face );
return PCF_Err_Invalid_File_Format;
}