* 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 !!
This commit is contained in:
parent
21493df9bd
commit
fd37c4b8ac
26
ChangeLog
26
ChangeLog
|
@ -1,3 +1,29 @@
|
|||
2003-02-25 David Turner <david@freetype.org>
|
||||
|
||||
* 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 <david@freetype.org>
|
||||
|
||||
* src/truetype/ttdriver.c, src/truetype/ttobjs.h, src/truetype/ttobjs.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 )
|
||||
|
|
|
@ -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 */
|
||||
{
|
||||
|
|
|
@ -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,8 +140,18 @@
|
|||
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;
|
||||
|
@ -255,6 +290,12 @@
|
|||
goto Exit;
|
||||
}
|
||||
|
||||
if ( load_flags & FT_LOAD_SBITS_ONLY )
|
||||
{
|
||||
error = FT_Err_Invalid_Argument;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
gchar = face->phy_font.chars + gindex;
|
||||
slot->root.format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
outline->n_points = 0;
|
||||
|
|
|
@ -230,11 +230,17 @@ FT_BEGIN_HEADER
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue