pfr_extra_items_skip( FT_Byte* *pp, FT_Byte* limit ) { return pfr_extra_items_parse( pp, limit, NULL, NULL ); }
pfr_phy_font_load( PFR_PhyFont phy_font, FT_Stream stream, FT_UInt32 offset, FT_UInt32 size ) { 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 ); /* get the standard advance for non-proportional fonts */ if ( !(flags & PFR_PHY_PROPORTIONAL) ) { PFR_CHECK( 2 ); phy_font->standard_advance = PFR_NEXT_SHORT( p ); } /* load the extra items when present */ if ( flags & PFR_PHY_EXTRA_ITEMS ) { error = pfr_extra_items_parse( &p, limit, pfr_phy_font_extra_items, phy_font ); if ( error ) goto Fail; } /* 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 ); if ( num_aux > 0 ) { FT_Byte* q = p; FT_Byte* q2; PFR_CHECK_SIZE( 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 */ /* an even number of bytes with a zero byte appended if needed */ 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 ); break; case 3: /* this seems to correspond to the font's style name, padded to */ /* an even number of bytes with a zero byte appended if needed */ 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 */ { 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 ); /* read the character descriptors */ { FT_UInt n, count, Size; phy_font->num_chars = count = PFR_NEXT_USHORT( p ); phy_font->chars_offset = offset + (FT_Offset)( p - stream->cursor ); 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_SIZE( count * Size ); if ( FT_NEW_ARRAY( phy_font->chars, count ) ) goto Fail; 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 ) : 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 ); } } /* that's it! */ Fail: FT_FRAME_EXIT(); /* save position of bitmap info */ phy_font->bct_offset = FT_STREAM_POS(); phy_font->cursor = NULL; Exit: return error; Too_Short: error = FT_THROW( Invalid_Table ); FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" )); goto Fail; }
pfr_phy_font_load( PFR_PhyFont phy_font, FT_Stream stream, FT_UInt32 offset, FT_UInt32 size ) { FT_Error error; FT_Memory memory = stream->memory; FT_UInt flags, num_aux; FT_Byte* p; FT_Byte* limit; phy_font->memory = memory; phy_font->offset = offset; if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) goto Exit; 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 ); /* get the standard advance for non-proprotional fonts */ if ( !(flags & PFR_PHY_PROPORTIONAL) ) { PFR_CHECK( 2 ); phy_font->standard_advance = PFR_NEXT_SHORT( p ); } /* load the extra items when present */ if ( flags & PFR_PHY_EXTRA_ITEMS ) { error = pfr_extra_items_parse( &p, limit, pfr_phy_font_extra_items, phy_font ); if ( error ) goto Fail; } /* skip the aux bytes */ PFR_CHECK( 3 ); num_aux = PFR_NEXT_ULONG( p ); PFR_CHECK( num_aux ); p += num_aux; /* read the blue values */ { 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 ); /* read the character descriptors */ { 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 ) : 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 ); } } /* that's it !! */ Fail: FT_FRAME_EXIT(); Exit: return error; Too_Short: error = PFR_Err_Invalid_Table; FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" )); goto Fail; }