ref: 229d122e928c5b5b6a1d4b613435695a2077c99a
parent: a41d3f056ac14d6edd21ae7db5d8d7d9d94aa41f
author: David Turner <[email protected]>
date: Tue Feb 25 14:20:12 EST 2003
* src/gzip/ftgzip.c: fixed a bug that caused FreeType to loop endlessly when trying to read certain compressed gzip files. The following test could be used to reveal the bug: touch 0123456789 ; gzip 0123456789 ; ftdump 0123456789.gz * src/pfr/pfrobjs.c, src/pfr/pfrload.c, src/pfr/pfrtypes.h: several fixes to the PFR font driver: - the list of available embedded bitmaps was not correctly set in the root FT_FaceRec structure describing the face - the glyph loader always tried to load the outlines when FT_LOAD_SBITS_ONLY was specified - the table loaded now scans for *undocumented* elements of a physical font's auxiliary data record, this is necessary to retrieve the "real" family and style names. NOTE THAT THIS CHANGES THE FAMILY NAME OF MANY PFR FONTS !!
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2003-02-25 David Turner <[email protected]>
+
+ * src/gzip/ftgzip.c: fixed a bug that caused FreeType to loop endlessly
+ when trying to read certain compressed gzip files. The following test
+ could be used to reveal the bug:
+
+ touch 0123456789 ; gzip 0123456789 ; ftdump 0123456789.gz
+
+
+ * src/pfr/pfrobjs.c, src/pfr/pfrload.c, src/pfr/pfrtypes.h: several
+ fixes to the PFR font driver:
+
+ - the list of available embedded bitmaps was not correctly set
+ in the root FT_FaceRec structure describing the face
+
+ - the glyph loader always tried to load the outlines when
+ FT_LOAD_SBITS_ONLY was specified
+
+ - the table loaded now scans for *undocumented* elements of a
+ physical font's auxiliary data record, this is necessary to
+ retrieve the "real" family and style names.
+
+ NOTE THAT THIS CHANGES THE FAMILY NAME OF MANY PFR FONTS !!
+
+
+
2003-02-18 David Turner <[email protected]>
* src/truetype/ttdriver.c, src/truetype/ttobjs.h, src/truetype/ttobjs.c,
--- a/src/gzip/ftgzip.c
+++ b/src/gzip/ftgzip.c
@@ -376,6 +376,7 @@
if ( err == Z_STREAM_END )
{
zip->limit = zstream->next_out;
+ error = FT_Err_Invalid_Stream_Operation;
break;
}
else if ( err != Z_OK )
--- a/src/pfr/pfrload.c
+++ b/src/pfr/pfrload.c
@@ -432,7 +432,16 @@
}
- /* load font ID, i.e. name */
+ /* load font ID, this is a so-called "unique" name that is rather
+ * long and descriptive (like "Tiresias ScreenFont v7.51").
+ *
+ * note that a PFR font's family name is contained in an *undocumented*
+ * string of the "auxiliary data" portion of a physical font record. this
+ * may also contain the "real" style name !
+ *
+ * if no family name is present, the font id is used instead for the
+ * family
+ */
FT_CALLBACK_DEF( FT_Error )
pfr_extra_item_load_font_id( FT_Byte* p,
FT_Byte* limit,
@@ -693,12 +702,54 @@
};
+ /* loads a name from the auxiliary data. Since this extracts undocumented
+ * strings from the font file, we need to be careful here
+ */
+ static FT_Error
+ pfr_aux_name_load( FT_Byte* p,
+ FT_UInt len,
+ FT_Memory memory,
+ FT_String* *astring )
+ {
+ FT_Error error = 0;
+ FT_String* result = NULL;
+ FT_UInt n, ok;
+
+ if ( len > 0 && p[len-1] == 0 )
+ len--;
+
+ /* check that each character is ASCII, that's to be sure
+ * to not load garbage..
+ */
+ ok = (len > 0);
+ for ( n = 0; n < len; n++ )
+ if ( p[n] < 32 || p[n] > 127 )
+ {
+ ok = 0;
+ break;
+ }
+
+ if ( ok )
+ {
+ if ( FT_ALLOC( result, len+1 ) )
+ goto Exit;
+
+ FT_MEM_COPY( result, p, len );
+ result[len] = 0;
+ }
+ Exit:
+ *astring = result;
+ return error;
+ }
+
+
FT_LOCAL_DEF( void )
pfr_phy_font_done( PFR_PhyFont phy_font,
FT_Memory memory )
{
- if ( phy_font->font_id )
- FT_FREE( phy_font->font_id );
+ FT_FREE( phy_font->font_id );
+ FT_FREE( phy_font->family_name );
+ FT_FREE( phy_font->style_name );
FT_FREE( phy_font->vertical.stem_snaps );
phy_font->vertical.num_stem_snaps = 0;
@@ -736,6 +787,7 @@
}
+
FT_LOCAL_DEF( FT_Error )
pfr_phy_font_load( PFR_PhyFont phy_font,
FT_Stream stream,
@@ -790,12 +842,82 @@
goto Fail;
}
- /* skip the aux bytes */
+ /* in certain fonts, the auxiliary bytes contain interesting */
+ /* information. These are not in the specification but can be */
+ /* guessed by looking at the content of a few PFR0 fonts */
PFR_CHECK( 3 );
num_aux = PFR_NEXT_ULONG( p );
- PFR_CHECK( num_aux );
- p += num_aux;
+ if ( num_aux > 0 )
+ {
+ FT_Byte* q = p;
+ FT_Byte* q2;
+
+ PFR_CHECK( num_aux );
+ p += num_aux;
+
+ while ( num_aux >= 0 )
+ {
+ FT_UInt length, type;
+
+ if ( q + 4 > p )
+ break;
+
+ length = PFR_NEXT_USHORT(q);
+ if ( length < 4 || length > num_aux )
+ break;
+
+ q2 = q + length - 2;
+ type = PFR_NEXT_USHORT(q);
+
+ switch ( type )
+ {
+ case 1:
+ {
+ /* this seems to correspond to the font's family name,
+ * padded to 16-bits with one zero when necessary
+ */
+ error = pfr_aux_name_load( q, length-4U, memory,
+ &phy_font->family_name );
+ if ( error )
+ goto Exit;
+ }
+ break;
+
+ case 2:
+ {
+ if ( q + 32 > q2 )
+ break;
+
+ q += 10;
+ phy_font->ascent = PFR_NEXT_SHORT(q);
+ phy_font->descent = PFR_NEXT_SHORT(q);
+ phy_font->leading = PFR_NEXT_SHORT(q);
+ q += 16;
+ }
+ break;
+
+ case 3:
+ {
+ FT_UInt n, len, ok;
+
+ /* this seems to correspond to the font's style name,
+ * padded to 16-bits with one zero when necessary
+ */
+ error = pfr_aux_name_load( q, length-4U, memory,
+ &phy_font->style_name );
+ if ( error )
+ goto Exit;
+ }
+ break;
+
+ default:
+ ;
+ }
+ q = q2;
+ num_aux -= length;
+ }
+ }
/* read the blue values */
{
--- a/src/pfr/pfrobjs.c
+++ b/src/pfr/pfrobjs.c
@@ -41,6 +41,10 @@
FT_LOCAL_DEF( void )
pfr_face_done( PFR_Face face )
{
+ /* we don't want dangling pointers */
+ face->root.family_name = NULL;
+ face->root.style_name = NULL;
+
/* finalize the physical font record */
pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) );
@@ -136,9 +140,19 @@
if ( phy_font->num_kern_pairs > 0 )
root->face_flags |= FT_FACE_FLAG_KERNING;
- root->family_name = phy_font->font_id;
- root->style_name = NULL; /* no style name in font file */
+ /* if no family name was found in the "undocumented" auxiliary
+ * data, use the font ID instead. This sucks but is better than
+ * nothing
+ */
+ root->family_name = phy_font->family_name;
+ if ( root->family_name == NULL )
+ root->family_name = phy_font->font_id;
+ /* note that the style name can be NULL in certain PFR fonts,
+ * probably meaning "Regular"
+ */
+ root->style_name = phy_font->style_name;
+
root->num_fixed_sizes = 0;
root->available_sizes = 0;
@@ -150,6 +164,27 @@
( ( ( root->ascender - root->descender ) * 12 )
/ 10 );
+ if ( phy_font->num_strikes > 0 )
+ {
+ FT_UInt n, count = phy_font->num_strikes;
+ FT_Bitmap_Size* size;
+ PFR_Strike strike;
+ FT_Memory memory = root->stream->memory;
+
+
+ if ( FT_NEW_ARRAY( root->available_sizes, count ) )
+ goto Exit;
+
+ size = root->available_sizes;
+ strike = phy_font->strikes;
+ for ( n = 0; n < count; n++, size++, strike++ )
+ {
+ size->height = strike->y_ppm;
+ size->width = strike->x_ppm;
+ }
+ root->num_fixed_sizes = count;
+ }
+
/* now compute maximum advance width */
if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 )
root->max_advance_width = (FT_Short)phy_font->standard_advance;
@@ -253,6 +288,12 @@
error = pfr_slot_load_bitmap( slot, size, gindex );
if ( error == 0 )
goto Exit;
+ }
+
+ if ( load_flags & FT_LOAD_SBITS_ONLY )
+ {
+ error = FT_Err_Invalid_Argument;
+ goto Exit;
}
gchar = face->phy_font.chars + gindex;
--- a/src/pfr/pfrtypes.h
+++ b/src/pfr/pfrtypes.h
@@ -230,11 +230,17 @@
FT_BBox bbox;
FT_UInt flags;
FT_UInt standard_advance;
+
+ FT_Int ascent; /* optional, bbox.yMax if not present */
+ FT_Int descent; /* optional, bbox.yMin if not present */
+ FT_Int leading; /* optional, 0 if not present */
PFR_DimensionRec horizontal;
PFR_DimensionRec vertical;
FT_String* font_id;
+ FT_String* family_name;
+ FT_String* style_name;
FT_UInt num_strikes;
FT_UInt max_strikes;