1 /***************************************************************************/
5 /* FreeType PFR loader (body). */
7 /* Copyright 2002-2015 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
16 /***************************************************************************/
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_STREAM_H
26 #define FT_COMPONENT trace_pfr
30 * The overall structure of a PFR file is as follows.
33 * 58 bytes (contains nPhysFonts)
35 * Logical font directory (size at most 2^16 bytes)
37 * + nLogFonts * 5 bytes
39 * ==> nLogFonts <= 13106
41 * Logical font section (size at most 2^24 bytes)
42 * nLogFonts * logFontRecord
44 * logFontRecord (size at most 2^16 bytes)
45 * 12 bytes (fontMatrix)
47 * + 0-5 bytes (depending on `flags')
48 * + 0-(1+255*(2+255)) = 0-65536 (depending on `flags')
49 * + 5 bytes (physical font info)
50 * + 0-1 bytes (depending on PFR header)
52 * ==> minimum size 18 bytes
54 * Physical font section (size at most 2^24 bytes)
55 * nPhysFonts * (physFontRecord
56 * + nBitmapSizes * nBmapChars * bmapCharRecord)
58 * physFontRecord (size at most 2^24 bytes)
59 * 14 bytes (font info)
61 * + 0-2 (depending on `flags')
62 * + 0-? (structure too complicated to be shown here; depending on
63 * `flags'; contains `nBitmapSizes' and `nBmapChars')
64 * + 3 bytes (nAuxBytes)
66 * + 1 byte (nBlueValues)
68 * + 6 bytes (hinting data)
69 * + 2 bytes (nCharacters)
70 * + nCharacters * (4-10 bytes) (depending on `flags')
72 * ==> minimum size 27 bytes
77 * Glyph program strings (three possible types: simpleGps, compoundGps,
78 * and bitmapGps; size at most 2^24 bytes)
79 * simpleGps (size at most 2^16 bytes)
81 * 1-2 bytes (n[XY]orus, depending on `flags')
82 * 0-(64+512*2) = 0-1088 bytes (depending on `n[XY]orus')
83 * 0-? (structure too complicated to be shown here; depending on
85 * 1-? glyph data (faintly resembling PS Type 1 charstrings)
87 * ==> minimum size 3 bytes
89 * compoundGps (size at most 2^16 bytes)
90 * 1 byte (nElements <= 63, flags)
91 * + 0-(1+255*(2+255)) = 0-65536 (depending on `flags')
92 * + nElements * (6-14 bytes)
94 * bitmapGps (size at most 2^16 bytes)
96 * 3-13 bytes (position info, depending on `flags')
99 * ==> minimum size 4 bytes
105 * ==> minimum size of a valid PFR:
108 * + 27 (1 physFontRecord)
116 /*************************************************************************/
117 /*************************************************************************/
119 /***** EXTRA ITEMS *****/
121 /*************************************************************************/
122 /*************************************************************************/
125 FT_LOCAL_DEF( FT_Error
)
126 pfr_extra_items_skip( FT_Byte
* *pp
,
129 return pfr_extra_items_parse( pp
, limit
, NULL
, NULL
);
133 FT_LOCAL_DEF( FT_Error
)
134 pfr_extra_items_parse( FT_Byte
* *pp
,
136 PFR_ExtraItem item_list
,
137 FT_Pointer item_data
)
139 FT_Error error
= FT_Err_Ok
;
141 FT_UInt num_items
, item_type
, item_size
;
145 num_items
= PFR_NEXT_BYTE( p
);
147 for ( ; num_items
> 0; num_items
-- )
150 item_size
= PFR_NEXT_BYTE( p
);
151 item_type
= PFR_NEXT_BYTE( p
);
153 PFR_CHECK( item_size
);
157 PFR_ExtraItem extra
= item_list
;
160 for ( extra
= item_list
; extra
->parser
!= NULL
; extra
++ )
162 if ( extra
->type
== item_type
)
164 error
= extra
->parser( p
, p
+ item_size
, item_data
);
181 FT_ERROR(( "pfr_extra_items_parse: invalid extra items table\n" ));
182 error
= FT_THROW( Invalid_Table
);
187 /*************************************************************************/
188 /*************************************************************************/
190 /***** PFR HEADER *****/
192 /*************************************************************************/
193 /*************************************************************************/
195 static const FT_Frame_Field pfr_header_fields
[] =
198 #define FT_STRUCTURE PFR_HeaderRec
200 FT_FRAME_START( 58 ),
201 FT_FRAME_ULONG ( signature
),
202 FT_FRAME_USHORT( version
),
203 FT_FRAME_USHORT( signature2
),
204 FT_FRAME_USHORT( header_size
),
206 FT_FRAME_USHORT( log_dir_size
),
207 FT_FRAME_USHORT( log_dir_offset
),
209 FT_FRAME_USHORT( log_font_max_size
),
210 FT_FRAME_UOFF3 ( log_font_section_size
),
211 FT_FRAME_UOFF3 ( log_font_section_offset
),
213 FT_FRAME_USHORT( phy_font_max_size
),
214 FT_FRAME_UOFF3 ( phy_font_section_size
),
215 FT_FRAME_UOFF3 ( phy_font_section_offset
),
217 FT_FRAME_USHORT( gps_max_size
),
218 FT_FRAME_UOFF3 ( gps_section_size
),
219 FT_FRAME_UOFF3 ( gps_section_offset
),
221 FT_FRAME_BYTE ( max_blue_values
),
222 FT_FRAME_BYTE ( max_x_orus
),
223 FT_FRAME_BYTE ( max_y_orus
),
225 FT_FRAME_BYTE ( phy_font_max_size_high
),
226 FT_FRAME_BYTE ( color_flags
),
228 FT_FRAME_UOFF3 ( bct_max_size
),
229 FT_FRAME_UOFF3 ( bct_set_max_size
),
230 FT_FRAME_UOFF3 ( phy_bct_set_max_size
),
232 FT_FRAME_USHORT( num_phy_fonts
),
233 FT_FRAME_BYTE ( max_vert_stem_snap
),
234 FT_FRAME_BYTE ( max_horz_stem_snap
),
235 FT_FRAME_USHORT( max_chars
),
240 FT_LOCAL_DEF( FT_Error
)
241 pfr_header_load( PFR_Header header
,
247 /* read header directly */
248 if ( !FT_STREAM_SEEK( 0 ) &&
249 !FT_STREAM_READ_FIELDS( pfr_header_fields
, header
) )
251 /* make a few adjustments to the header */
252 header
->phy_font_max_size
+=
253 (FT_UInt32
)header
->phy_font_max_size_high
<< 16;
260 FT_LOCAL_DEF( FT_Bool
)
261 pfr_header_check( PFR_Header header
)
266 /* check signature and header size */
267 if ( header
->signature
!= 0x50465230L
|| /* "PFR0" */
268 header
->version
> 4 ||
269 header
->header_size
< 58 ||
270 header
->signature2
!= 0x0D0A ) /* CR/LF */
279 /***********************************************************************/
280 /***********************************************************************/
282 /***** PFR LOGICAL FONTS *****/
284 /***********************************************************************/
285 /***********************************************************************/
288 FT_LOCAL_DEF( FT_Error
)
289 pfr_log_font_count( FT_Stream stream
,
290 FT_UInt32 section_offset
,
298 if ( FT_STREAM_SEEK( section_offset
) ||
299 FT_READ_USHORT( count
) )
302 /* check maximum value and a rough minimum size */
303 if ( count
> ( ( 1 << 16 ) - 2 ) / 5 ||
304 2 + count
* 5 >= stream
->size
- section_offset
)
306 FT_ERROR(( "pfr_log_font_count:"
307 " invalid number of logical fonts\n" ));
308 error
= FT_THROW( Invalid_Table
);
315 *acount
= (FT_Long
)result
;
320 FT_LOCAL_DEF( FT_Error
)
321 pfr_log_font_load( PFR_LogFont log_font
,
324 FT_UInt32 section_offset
,
325 FT_Bool size_increment
)
327 FT_UInt num_log_fonts
;
334 if ( FT_STREAM_SEEK( section_offset
) ||
335 FT_READ_USHORT( num_log_fonts
) )
338 if ( idx
>= num_log_fonts
)
339 return FT_THROW( Invalid_Argument
);
341 if ( FT_STREAM_SKIP( idx
* 5 ) ||
342 FT_READ_USHORT( size
) ||
343 FT_READ_UOFF3 ( offset
) )
346 /* save logical font size and offset */
347 log_font
->size
= size
;
348 log_font
->offset
= offset
;
350 /* now, check the rest of the table before loading it */
357 if ( FT_STREAM_SEEK( offset
) ||
358 FT_FRAME_ENTER( size
) )
366 log_font
->matrix
[0] = PFR_NEXT_LONG( p
);
367 log_font
->matrix
[1] = PFR_NEXT_LONG( p
);
368 log_font
->matrix
[2] = PFR_NEXT_LONG( p
);
369 log_font
->matrix
[3] = PFR_NEXT_LONG( p
);
371 flags
= PFR_NEXT_BYTE( p
);
374 if ( flags
& PFR_LOG_STROKE
)
377 if ( flags
& PFR_LOG_2BYTE_STROKE
)
380 if ( (flags
& PFR_LINE_JOIN_MASK
) == PFR_LINE_JOIN_MITER
)
383 if ( flags
& PFR_LOG_BOLD
)
386 if ( flags
& PFR_LOG_2BYTE_BOLD
)
392 if ( flags
& PFR_LOG_STROKE
)
394 log_font
->stroke_thickness
= ( flags
& PFR_LOG_2BYTE_STROKE
)
395 ? PFR_NEXT_SHORT( p
)
396 : PFR_NEXT_BYTE( p
);
398 if ( ( flags
& PFR_LINE_JOIN_MASK
) == PFR_LINE_JOIN_MITER
)
399 log_font
->miter_limit
= PFR_NEXT_LONG( p
);
402 if ( flags
& PFR_LOG_BOLD
)
404 log_font
->bold_thickness
= ( flags
& PFR_LOG_2BYTE_BOLD
)
405 ? PFR_NEXT_SHORT( p
)
406 : PFR_NEXT_BYTE( p
);
409 if ( flags
& PFR_LOG_EXTRA_ITEMS
)
411 error
= pfr_extra_items_skip( &p
, limit
);
417 log_font
->phys_size
= PFR_NEXT_USHORT( p
);
418 log_font
->phys_offset
= PFR_NEXT_ULONG( p
);
419 if ( size_increment
)
422 log_font
->phys_size
+= (FT_UInt32
)PFR_NEXT_BYTE( p
) << 16;
433 FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" ));
434 error
= FT_THROW( Invalid_Table
);
439 /***********************************************************************/
440 /***********************************************************************/
442 /***** PFR PHYSICAL FONTS *****/
444 /***********************************************************************/
445 /***********************************************************************/
448 /* load bitmap strikes lists */
449 FT_CALLBACK_DEF( FT_Error
)
450 pfr_extra_item_load_bitmap_info( FT_Byte
* p
,
452 PFR_PhyFont phy_font
)
454 FT_Memory memory
= phy_font
->memory
;
457 FT_UInt n
, count
, size1
;
458 FT_Error error
= FT_Err_Ok
;
463 p
+= 3; /* skip bctSize */
464 flags0
= PFR_NEXT_BYTE( p
);
465 count
= PFR_NEXT_BYTE( p
);
467 /* re-allocate when needed */
468 if ( phy_font
->num_strikes
+ count
> phy_font
->max_strikes
)
470 FT_UInt new_max
= FT_PAD_CEIL( phy_font
->num_strikes
+ count
, 4 );
473 if ( FT_RENEW_ARRAY( phy_font
->strikes
,
474 phy_font
->num_strikes
,
478 phy_font
->max_strikes
= new_max
;
481 size1
= 1 + 1 + 1 + 2 + 2 + 1;
482 if ( flags0
& PFR_STRIKE_2BYTE_XPPM
)
485 if ( flags0
& PFR_STRIKE_2BYTE_YPPM
)
488 if ( flags0
& PFR_STRIKE_3BYTE_SIZE
)
491 if ( flags0
& PFR_STRIKE_3BYTE_OFFSET
)
494 if ( flags0
& PFR_STRIKE_2BYTE_COUNT
)
497 strike
= phy_font
->strikes
+ phy_font
->num_strikes
;
499 PFR_CHECK( count
* size1
);
501 for ( n
= 0; n
< count
; n
++, strike
++ )
503 strike
->x_ppm
= ( flags0
& PFR_STRIKE_2BYTE_XPPM
)
504 ? PFR_NEXT_USHORT( p
)
505 : PFR_NEXT_BYTE( p
);
507 strike
->y_ppm
= ( flags0
& PFR_STRIKE_2BYTE_YPPM
)
508 ? PFR_NEXT_USHORT( p
)
509 : PFR_NEXT_BYTE( p
);
511 strike
->flags
= PFR_NEXT_BYTE( p
);
513 strike
->bct_size
= ( flags0
& PFR_STRIKE_3BYTE_SIZE
)
514 ? PFR_NEXT_ULONG( p
)
515 : PFR_NEXT_USHORT( p
);
517 strike
->bct_offset
= ( flags0
& PFR_STRIKE_3BYTE_OFFSET
)
518 ? PFR_NEXT_ULONG( p
)
519 : PFR_NEXT_USHORT( p
);
521 strike
->num_bitmaps
= ( flags0
& PFR_STRIKE_2BYTE_COUNT
)
522 ? PFR_NEXT_USHORT( p
)
523 : PFR_NEXT_BYTE( p
);
526 phy_font
->num_strikes
+= count
;
532 error
= FT_THROW( Invalid_Table
);
533 FT_ERROR(( "pfr_extra_item_load_bitmap_info:"
534 " invalid bitmap info table\n" ));
539 /* Load font ID. This is a so-called `unique' name that is rather
540 * long and descriptive (like `Tiresias ScreenFont v7.51').
542 * Note that a PFR font's family name is contained in an *undocumented*
543 * string of the `auxiliary data' portion of a physical font record. This
544 * may also contain the `real' style name!
546 * If no family name is present, the font ID is used instead for the
549 FT_CALLBACK_DEF( FT_Error
)
550 pfr_extra_item_load_font_id( FT_Byte
* p
,
552 PFR_PhyFont phy_font
)
554 FT_Error error
= FT_Err_Ok
;
555 FT_Memory memory
= phy_font
->memory
;
556 FT_UInt len
= (FT_UInt
)( limit
- p
);
559 if ( phy_font
->font_id
!= NULL
)
562 if ( FT_ALLOC( phy_font
->font_id
, len
+ 1 ) )
565 /* copy font ID name, and terminate it for safety */
566 FT_MEM_COPY( phy_font
->font_id
, p
, len
);
567 phy_font
->font_id
[len
] = 0;
574 /* load stem snap tables */
575 FT_CALLBACK_DEF( FT_Error
)
576 pfr_extra_item_load_stem_snaps( FT_Byte
* p
,
578 PFR_PhyFont phy_font
)
580 FT_UInt count
, num_vert
, num_horz
;
581 FT_Int
* snaps
= NULL
;
582 FT_Error error
= FT_Err_Ok
;
583 FT_Memory memory
= phy_font
->memory
;
586 if ( phy_font
->vertical
.stem_snaps
!= NULL
)
590 count
= PFR_NEXT_BYTE( p
);
592 num_vert
= count
& 15;
593 num_horz
= count
>> 4;
594 count
= num_vert
+ num_horz
;
596 PFR_CHECK( count
* 2 );
598 if ( FT_NEW_ARRAY( snaps
, count
) )
601 phy_font
->vertical
.stem_snaps
= snaps
;
602 phy_font
->horizontal
.stem_snaps
= snaps
+ num_vert
;
604 for ( ; count
> 0; count
--, snaps
++ )
605 *snaps
= FT_NEXT_SHORT( p
);
611 error
= FT_THROW( Invalid_Table
);
612 FT_ERROR(( "pfr_exta_item_load_stem_snaps:"
613 " invalid stem snaps table\n" ));
619 /* load kerning pair data */
620 FT_CALLBACK_DEF( FT_Error
)
621 pfr_extra_item_load_kerning_pairs( FT_Byte
* p
,
623 PFR_PhyFont phy_font
)
625 PFR_KernItem item
= NULL
;
626 FT_Error error
= FT_Err_Ok
;
627 FT_Memory memory
= phy_font
->memory
;
630 if ( FT_NEW( item
) )
635 item
->pair_count
= PFR_NEXT_BYTE( p
);
636 item
->base_adj
= PFR_NEXT_SHORT( p
);
637 item
->flags
= PFR_NEXT_BYTE( p
);
638 item
->offset
= phy_font
->offset
+
639 (FT_Offset
)( p
- phy_font
->cursor
);
641 #ifndef PFR_CONFIG_NO_CHECKS
644 if ( item
->flags
& PFR_KERN_2BYTE_CHAR
)
645 item
->pair_size
+= 2;
647 if ( item
->flags
& PFR_KERN_2BYTE_ADJ
)
648 item
->pair_size
+= 1;
650 PFR_CHECK( item
->pair_count
* item
->pair_size
);
653 /* load first and last pairs into the item to speed up */
654 /* lookup later... */
655 if ( item
->pair_count
> 0 )
657 FT_UInt char1
, char2
;
661 if ( item
->flags
& PFR_KERN_2BYTE_CHAR
)
664 char1
= PFR_NEXT_USHORT( q
);
665 char2
= PFR_NEXT_USHORT( q
);
667 item
->pair1
= PFR_KERN_INDEX( char1
, char2
);
669 q
= p
+ item
->pair_size
* ( item
->pair_count
- 1 );
670 char1
= PFR_NEXT_USHORT( q
);
671 char2
= PFR_NEXT_USHORT( q
);
673 item
->pair2
= PFR_KERN_INDEX( char1
, char2
);
678 char1
= PFR_NEXT_BYTE( q
);
679 char2
= PFR_NEXT_BYTE( q
);
681 item
->pair1
= PFR_KERN_INDEX( char1
, char2
);
683 q
= p
+ item
->pair_size
* ( item
->pair_count
- 1 );
684 char1
= PFR_NEXT_BYTE( q
);
685 char2
= PFR_NEXT_BYTE( q
);
687 item
->pair2
= PFR_KERN_INDEX( char1
, char2
);
690 /* add new item to the current list */
692 *phy_font
->kern_items_tail
= item
;
693 phy_font
->kern_items_tail
= &item
->next
;
694 phy_font
->num_kern_pairs
+= item
->pair_count
;
708 error
= FT_THROW( Invalid_Table
);
709 FT_ERROR(( "pfr_extra_item_load_kerning_pairs:"
710 " invalid kerning pairs table\n" ));
715 static const PFR_ExtraItemRec pfr_phy_font_extra_items
[] =
717 { 1, (PFR_ExtraItem_ParseFunc
)pfr_extra_item_load_bitmap_info
},
718 { 2, (PFR_ExtraItem_ParseFunc
)pfr_extra_item_load_font_id
},
719 { 3, (PFR_ExtraItem_ParseFunc
)pfr_extra_item_load_stem_snaps
},
720 { 4, (PFR_ExtraItem_ParseFunc
)pfr_extra_item_load_kerning_pairs
},
726 * Load a name from the auxiliary data. Since this extracts undocumented
727 * strings from the font file, we need to be careful here.
730 pfr_aux_name_load( FT_Byte
* p
,
733 FT_String
* *astring
)
735 FT_Error error
= FT_Err_Ok
;
736 FT_String
* result
= NULL
;
740 if ( len
> 0 && p
[len
- 1] == 0 )
743 /* check that each character is ASCII for making sure not to
747 for ( n
= 0; n
< len
; n
++ )
748 if ( p
[n
] < 32 || p
[n
] > 127 )
756 if ( FT_ALLOC( result
, len
+ 1 ) )
759 FT_MEM_COPY( result
, p
, len
);
769 pfr_phy_font_done( PFR_PhyFont phy_font
,
772 FT_FREE( phy_font
->font_id
);
773 FT_FREE( phy_font
->family_name
);
774 FT_FREE( phy_font
->style_name
);
776 FT_FREE( phy_font
->vertical
.stem_snaps
);
777 phy_font
->vertical
.num_stem_snaps
= 0;
779 phy_font
->horizontal
.stem_snaps
= NULL
;
780 phy_font
->horizontal
.num_stem_snaps
= 0;
782 FT_FREE( phy_font
->strikes
);
783 phy_font
->num_strikes
= 0;
784 phy_font
->max_strikes
= 0;
786 FT_FREE( phy_font
->chars
);
787 phy_font
->num_chars
= 0;
788 phy_font
->chars_offset
= 0;
790 FT_FREE( phy_font
->blue_values
);
791 phy_font
->num_blue_values
= 0;
794 PFR_KernItem item
, next
;
797 item
= phy_font
->kern_items
;
804 phy_font
->kern_items
= NULL
;
805 phy_font
->kern_items_tail
= NULL
;
808 phy_font
->num_kern_pairs
= 0;
812 FT_LOCAL_DEF( FT_Error
)
813 pfr_phy_font_load( PFR_PhyFont phy_font
,
819 FT_Memory memory
= stream
->memory
;
826 phy_font
->memory
= memory
;
827 phy_font
->offset
= offset
;
829 phy_font
->kern_items
= NULL
;
830 phy_font
->kern_items_tail
= &phy_font
->kern_items
;
832 if ( FT_STREAM_SEEK( offset
) ||
833 FT_FRAME_ENTER( size
) )
836 phy_font
->cursor
= stream
->cursor
;
842 phy_font
->font_ref_number
= PFR_NEXT_USHORT( p
);
843 phy_font
->outline_resolution
= PFR_NEXT_USHORT( p
);
844 phy_font
->metrics_resolution
= PFR_NEXT_USHORT( p
);
845 phy_font
->bbox
.xMin
= PFR_NEXT_SHORT( p
);
846 phy_font
->bbox
.yMin
= PFR_NEXT_SHORT( p
);
847 phy_font
->bbox
.xMax
= PFR_NEXT_SHORT( p
);
848 phy_font
->bbox
.yMax
= PFR_NEXT_SHORT( p
);
849 phy_font
->flags
= flags
= PFR_NEXT_BYTE( p
);
851 /* get the standard advance for non-proportional fonts */
852 if ( !(flags
& PFR_PHY_PROPORTIONAL
) )
855 phy_font
->standard_advance
= PFR_NEXT_SHORT( p
);
858 /* load the extra items when present */
859 if ( flags
& PFR_PHY_EXTRA_ITEMS
)
861 error
= pfr_extra_items_parse( &p
, limit
,
862 pfr_phy_font_extra_items
, phy_font
);
868 /* In certain fonts, the auxiliary bytes contain interesting */
869 /* information. These are not in the specification but can be */
870 /* guessed by looking at the content of a few PFR0 fonts. */
872 num_aux
= PFR_NEXT_ULONG( p
);
880 PFR_CHECK_SIZE( num_aux
);
883 while ( num_aux
> 0 )
885 FT_UInt length
, type
;
891 length
= PFR_NEXT_USHORT( q
);
892 if ( length
< 4 || length
> num_aux
)
896 type
= PFR_NEXT_USHORT( q
);
901 /* this seems to correspond to the font's family name, padded to */
902 /* an even number of bytes with a zero byte appended if needed */
903 error
= pfr_aux_name_load( q
, length
- 4U, memory
,
904 &phy_font
->family_name
);
914 phy_font
->ascent
= PFR_NEXT_SHORT( q
);
915 phy_font
->descent
= PFR_NEXT_SHORT( q
);
916 phy_font
->leading
= PFR_NEXT_SHORT( q
);
920 /* this seems to correspond to the font's style name, padded to */
921 /* an even number of bytes with a zero byte appended if needed */
922 error
= pfr_aux_name_load( q
, length
- 4U, memory
,
923 &phy_font
->style_name
);
937 /* read the blue values */
943 phy_font
->num_blue_values
= count
= PFR_NEXT_BYTE( p
);
945 PFR_CHECK( count
* 2 );
947 if ( FT_NEW_ARRAY( phy_font
->blue_values
, count
) )
950 for ( n
= 0; n
< count
; n
++ )
951 phy_font
->blue_values
[n
] = PFR_NEXT_SHORT( p
);
955 phy_font
->blue_fuzz
= PFR_NEXT_BYTE( p
);
956 phy_font
->blue_scale
= PFR_NEXT_BYTE( p
);
958 phy_font
->vertical
.standard
= PFR_NEXT_USHORT( p
);
959 phy_font
->horizontal
.standard
= PFR_NEXT_USHORT( p
);
961 /* read the character descriptors */
963 FT_UInt n
, count
, Size
;
966 phy_font
->num_chars
= count
= PFR_NEXT_USHORT( p
);
967 phy_font
->chars_offset
= offset
+ (FT_Offset
)( p
- stream
->cursor
);
970 if ( flags
& PFR_PHY_2BYTE_CHARCODE
)
973 if ( flags
& PFR_PHY_PROPORTIONAL
)
976 if ( flags
& PFR_PHY_ASCII_CODE
)
979 if ( flags
& PFR_PHY_2BYTE_GPS_SIZE
)
982 if ( flags
& PFR_PHY_3BYTE_GPS_OFFSET
)
985 PFR_CHECK_SIZE( count
* Size
);
987 if ( FT_NEW_ARRAY( phy_font
->chars
, count
) )
990 for ( n
= 0; n
< count
; n
++ )
992 PFR_Char cur
= &phy_font
->chars
[n
];
995 cur
->char_code
= ( flags
& PFR_PHY_2BYTE_CHARCODE
)
996 ? PFR_NEXT_USHORT( p
)
997 : PFR_NEXT_BYTE( p
);
999 cur
->advance
= ( flags
& PFR_PHY_PROPORTIONAL
)
1000 ? PFR_NEXT_SHORT( p
)
1001 : phy_font
->standard_advance
;
1004 cur
->ascii
= ( flags
& PFR_PHY_ASCII_CODE
)
1005 ? PFR_NEXT_BYTE( p
)
1008 if ( flags
& PFR_PHY_ASCII_CODE
)
1011 cur
->gps_size
= ( flags
& PFR_PHY_2BYTE_GPS_SIZE
)
1012 ? PFR_NEXT_USHORT( p
)
1013 : PFR_NEXT_BYTE( p
);
1015 cur
->gps_offset
= ( flags
& PFR_PHY_3BYTE_GPS_OFFSET
)
1016 ? PFR_NEXT_ULONG( p
)
1017 : PFR_NEXT_USHORT( p
);
1026 /* save position of bitmap info */
1027 phy_font
->bct_offset
= FT_STREAM_POS();
1028 phy_font
->cursor
= NULL
;
1034 error
= FT_THROW( Invalid_Table
);
1035 FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" ));