|
|
Definition at line 712 of file pfrload.c.
Referenced by pfr_face_init().
{
FT_Error error;
FT_Memory memory = stream->memory;
FT_UInt flags;
FT_ULong num_aux;
FT_Byte* p;
FT_Byte* limit;
phy_font->memory = memory;
phy_font->offset = offset;
phy_font->kern_items = NULL;
phy_font->kern_items_tail = &phy_font->kern_items;
if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) )
goto Exit;
phy_font->cursor = stream->cursor;
p = stream->cursor;
limit = p + size;
PFR_CHECK( 15 );
phy_font->font_ref_number = PFR_NEXT_USHORT( p );
phy_font->outline_resolution = PFR_NEXT_USHORT( p );
phy_font->metrics_resolution = PFR_NEXT_USHORT( p );
phy_font->bbox.xMin = PFR_NEXT_SHORT( p );
phy_font->bbox.yMin = PFR_NEXT_SHORT( p );
phy_font->bbox.xMax = PFR_NEXT_SHORT( p );
phy_font->bbox.yMax = PFR_NEXT_SHORT( p );
phy_font->flags = flags = PFR_NEXT_BYTE( p );
if ( !(flags & PFR_PHY_PROPORTIONAL) )
{
PFR_CHECK( 2 );
phy_font->standard_advance = PFR_NEXT_SHORT( p );
}
if ( flags & PFR_PHY_EXTRA_ITEMS )
{
error = pfr_extra_items_parse( &p, limit,
pfr_phy_font_extra_items, phy_font );
if ( error )
goto Fail;
}
PFR_CHECK( 3 );
num_aux = PFR_NEXT_ULONG( p );
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:
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:
error = pfr_aux_name_load( q, length - 4U, memory,
&phy_font->style_name );
if ( error )
goto Exit;
break;
default:
;
}
q = q2;
num_aux -= length;
}
}
{
FT_UInt n, count;
PFR_CHECK( 1 );
phy_font->num_blue_values = count = PFR_NEXT_BYTE( p );
PFR_CHECK( count * 2 );
if ( FT_NEW_ARRAY( phy_font->blue_values, count ) )
goto Fail;
for ( n = 0; n < count; n++ )
phy_font->blue_values[n] = PFR_NEXT_SHORT( p );
}
PFR_CHECK( 8 );
phy_font->blue_fuzz = PFR_NEXT_BYTE( p );
phy_font->blue_scale = PFR_NEXT_BYTE( p );
phy_font->vertical.standard = PFR_NEXT_USHORT( p );
phy_font->horizontal.standard = PFR_NEXT_USHORT( p );
{
FT_UInt n, count, Size;
phy_font->num_chars = count = PFR_NEXT_USHORT( p );
phy_font->chars_offset = offset + ( p - stream->cursor );
if ( FT_NEW_ARRAY( phy_font->chars, count ) )
goto Fail;
Size = 1 + 1 + 2;
if ( flags & PFR_PHY_2BYTE_CHARCODE )
Size += 1;
if ( flags & PFR_PHY_PROPORTIONAL )
Size += 2;
if ( flags & PFR_PHY_ASCII_CODE )
Size += 1;
if ( flags & PFR_PHY_2BYTE_GPS_SIZE )
Size += 1;
if ( flags & PFR_PHY_3BYTE_GPS_OFFSET )
Size += 1;
PFR_CHECK( count * Size );
for ( n = 0; n < count; n++ )
{
PFR_Char cur = &phy_font->chars[n];
cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE )
? PFR_NEXT_USHORT( p )
: PFR_NEXT_BYTE( p );
cur->advance = ( flags & PFR_PHY_PROPORTIONAL )
? PFR_NEXT_SHORT( p )
: (FT_Int) phy_font->standard_advance;
#if 0
cur->ascii = ( flags & PFR_PHY_ASCII_CODE )
? PFR_NEXT_BYTE( p )
: 0;
#else
if ( flags & PFR_PHY_ASCII_CODE )
p += 1;
#endif
cur->gps_size = ( flags & PFR_PHY_2BYTE_GPS_SIZE )
? PFR_NEXT_USHORT( p )
: PFR_NEXT_BYTE( p );
cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET )
? PFR_NEXT_ULONG( p )
: PFR_NEXT_USHORT( p );
}
}
Fail:
FT_FRAME_EXIT();
phy_font->bct_offset = FT_STREAM_POS();
phy_font->cursor = NULL;
Exit:
return error;
Too_Short:
error = PFR_Err_Invalid_Table;
FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" ));
goto Fail;
}
|