1 /***************************************************************************/
5 /* FreeType PFR loader (body). */
7 /* Copyright 2002, 2003, 2004, 2005, 2007 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
29 /*************************************************************************/
30 /*************************************************************************/
32 /***** EXTRA ITEMS *****/
34 /*************************************************************************/
35 /*************************************************************************/
38 FT_LOCAL_DEF( FT_Error
)
39 pfr_extra_items_skip( FT_Byte
* *pp
,
42 return pfr_extra_items_parse( pp
, limit
, NULL
, NULL
);
46 FT_LOCAL_DEF( FT_Error
)
47 pfr_extra_items_parse( FT_Byte
* *pp
,
49 PFR_ExtraItem item_list
,
50 FT_Pointer item_data
)
54 FT_UInt num_items
, item_type
, item_size
;
58 num_items
= PFR_NEXT_BYTE( p
);
60 for ( ; num_items
> 0; num_items
-- )
63 item_size
= PFR_NEXT_BYTE( p
);
64 item_type
= PFR_NEXT_BYTE( p
);
66 PFR_CHECK( item_size
);
70 PFR_ExtraItem extra
= item_list
;
73 for ( extra
= item_list
; extra
->parser
!= NULL
; extra
++ )
75 if ( extra
->type
== item_type
)
77 error
= extra
->parser( p
, p
+ item_size
, item_data
);
78 if ( error
) goto Exit
;
93 FT_ERROR(( "pfr_extra_items_parse: invalid extra items table\n" ));
94 error
= PFR_Err_Invalid_Table
;
99 /*************************************************************************/
100 /*************************************************************************/
102 /***** PFR HEADER *****/
104 /*************************************************************************/
105 /*************************************************************************/
107 static const FT_Frame_Field pfr_header_fields
[] =
110 #define FT_STRUCTURE PFR_HeaderRec
112 FT_FRAME_START( 58 ),
113 FT_FRAME_ULONG ( signature
),
114 FT_FRAME_USHORT( version
),
115 FT_FRAME_USHORT( signature2
),
116 FT_FRAME_USHORT( header_size
),
118 FT_FRAME_USHORT( log_dir_size
),
119 FT_FRAME_USHORT( log_dir_offset
),
121 FT_FRAME_USHORT( log_font_max_size
),
122 FT_FRAME_UOFF3 ( log_font_section_size
),
123 FT_FRAME_UOFF3 ( log_font_section_offset
),
125 FT_FRAME_USHORT( phy_font_max_size
),
126 FT_FRAME_UOFF3 ( phy_font_section_size
),
127 FT_FRAME_UOFF3 ( phy_font_section_offset
),
129 FT_FRAME_USHORT( gps_max_size
),
130 FT_FRAME_UOFF3 ( gps_section_size
),
131 FT_FRAME_UOFF3 ( gps_section_offset
),
133 FT_FRAME_BYTE ( max_blue_values
),
134 FT_FRAME_BYTE ( max_x_orus
),
135 FT_FRAME_BYTE ( max_y_orus
),
137 FT_FRAME_BYTE ( phy_font_max_size_high
),
138 FT_FRAME_BYTE ( color_flags
),
140 FT_FRAME_UOFF3 ( bct_max_size
),
141 FT_FRAME_UOFF3 ( bct_set_max_size
),
142 FT_FRAME_UOFF3 ( phy_bct_set_max_size
),
144 FT_FRAME_USHORT( num_phy_fonts
),
145 FT_FRAME_BYTE ( max_vert_stem_snap
),
146 FT_FRAME_BYTE ( max_horz_stem_snap
),
147 FT_FRAME_USHORT( max_chars
),
152 FT_LOCAL_DEF( FT_Error
)
153 pfr_header_load( PFR_Header header
,
159 /* read header directly */
160 if ( !FT_STREAM_SEEK( 0 ) &&
161 !FT_STREAM_READ_FIELDS( pfr_header_fields
, header
) )
163 /* make a few adjustments to the header */
164 header
->phy_font_max_size
+=
165 (FT_UInt32
)header
->phy_font_max_size_high
<< 16;
172 FT_LOCAL_DEF( FT_Bool
)
173 pfr_header_check( PFR_Header header
)
178 /* check signature and header size */
179 if ( header
->signature
!= 0x50465230L
|| /* "PFR0" */
180 header
->version
> 4 ||
181 header
->header_size
< 58 ||
182 header
->signature2
!= 0x0d0a ) /* CR/LF */
190 /***********************************************************************/
191 /***********************************************************************/
193 /***** PFR LOGICAL FONTS *****/
195 /***********************************************************************/
196 /***********************************************************************/
199 FT_LOCAL_DEF( FT_Error
)
200 pfr_log_font_count( FT_Stream stream
,
201 FT_UInt32 section_offset
,
209 if ( FT_STREAM_SEEK( section_offset
) || FT_READ_USHORT( count
) )
220 FT_LOCAL_DEF( FT_Error
)
221 pfr_log_font_load( PFR_LogFont log_font
,
224 FT_UInt32 section_offset
,
225 FT_Bool size_increment
)
227 FT_UInt num_log_fonts
;
234 if ( FT_STREAM_SEEK( section_offset
) ||
235 FT_READ_USHORT( num_log_fonts
) )
238 if ( idx
>= num_log_fonts
)
239 return PFR_Err_Invalid_Argument
;
241 if ( FT_STREAM_SKIP( idx
* 5 ) ||
242 FT_READ_USHORT( size
) ||
243 FT_READ_UOFF3 ( offset
) )
246 /* save logical font size and offset */
247 log_font
->size
= size
;
248 log_font
->offset
= offset
;
250 /* now, check the rest of the table before loading it */
257 if ( FT_STREAM_SEEK( offset
) || FT_FRAME_ENTER( size
) )
265 log_font
->matrix
[0] = PFR_NEXT_LONG( p
);
266 log_font
->matrix
[1] = PFR_NEXT_LONG( p
);
267 log_font
->matrix
[2] = PFR_NEXT_LONG( p
);
268 log_font
->matrix
[3] = PFR_NEXT_LONG( p
);
270 flags
= PFR_NEXT_BYTE( p
);
273 if ( flags
& PFR_LOG_STROKE
)
276 if ( flags
& PFR_LOG_2BYTE_STROKE
)
279 if ( (flags
& PFR_LINE_JOIN_MASK
) == PFR_LINE_JOIN_MITER
)
282 if ( flags
& PFR_LOG_BOLD
)
285 if ( flags
& PFR_LOG_2BYTE_BOLD
)
291 if ( flags
& PFR_LOG_STROKE
)
293 log_font
->stroke_thickness
= ( flags
& PFR_LOG_2BYTE_STROKE
)
294 ? PFR_NEXT_SHORT( p
)
295 : PFR_NEXT_BYTE( p
);
297 if ( ( flags
& PFR_LINE_JOIN_MASK
) == PFR_LINE_JOIN_MITER
)
298 log_font
->miter_limit
= PFR_NEXT_LONG( p
);
301 if ( flags
& PFR_LOG_BOLD
)
303 log_font
->bold_thickness
= ( flags
& PFR_LOG_2BYTE_BOLD
)
304 ? PFR_NEXT_SHORT( p
)
305 : PFR_NEXT_BYTE( p
);
308 if ( flags
& PFR_LOG_EXTRA_ITEMS
)
310 error
= pfr_extra_items_skip( &p
, limit
);
311 if (error
) goto Fail
;
315 log_font
->phys_size
= PFR_NEXT_USHORT( p
);
316 log_font
->phys_offset
= PFR_NEXT_ULONG( p
);
317 if ( size_increment
)
320 log_font
->phys_size
+= (FT_UInt32
)PFR_NEXT_BYTE( p
) << 16;
331 FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" ));
332 error
= PFR_Err_Invalid_Table
;
337 /***********************************************************************/
338 /***********************************************************************/
340 /***** PFR PHYSICAL FONTS *****/
342 /***********************************************************************/
343 /***********************************************************************/
346 /* load bitmap strikes lists */
347 FT_CALLBACK_DEF( FT_Error
)
348 pfr_extra_item_load_bitmap_info( FT_Byte
* p
,
350 PFR_PhyFont phy_font
)
352 FT_Memory memory
= phy_font
->memory
;
355 FT_UInt n
, count
, size1
;
361 p
+= 3; /* skip bctSize */
362 flags0
= PFR_NEXT_BYTE( p
);
363 count
= PFR_NEXT_BYTE( p
);
365 /* re-allocate when needed */
366 if ( phy_font
->num_strikes
+ count
> phy_font
->max_strikes
)
368 FT_UInt new_max
= FT_PAD_CEIL( phy_font
->num_strikes
+ count
, 4 );
371 if ( FT_RENEW_ARRAY( phy_font
->strikes
,
372 phy_font
->num_strikes
,
376 phy_font
->max_strikes
= new_max
;
379 size1
= 1 + 1 + 1 + 2 + 2 + 1;
380 if ( flags0
& PFR_STRIKE_2BYTE_XPPM
)
383 if ( flags0
& PFR_STRIKE_2BYTE_YPPM
)
386 if ( flags0
& PFR_STRIKE_3BYTE_SIZE
)
389 if ( flags0
& PFR_STRIKE_3BYTE_OFFSET
)
392 if ( flags0
& PFR_STRIKE_2BYTE_COUNT
)
395 strike
= phy_font
->strikes
+ phy_font
->num_strikes
;
397 PFR_CHECK( count
* size1
);
399 for ( n
= 0; n
< count
; n
++, strike
++ )
401 strike
->x_ppm
= ( flags0
& PFR_STRIKE_2BYTE_XPPM
)
402 ? PFR_NEXT_USHORT( p
)
403 : PFR_NEXT_BYTE( p
);
405 strike
->y_ppm
= ( flags0
& PFR_STRIKE_2BYTE_YPPM
)
406 ? PFR_NEXT_USHORT( p
)
407 : PFR_NEXT_BYTE( p
);
409 strike
->flags
= PFR_NEXT_BYTE( p
);
411 strike
->bct_size
= ( flags0
& PFR_STRIKE_3BYTE_SIZE
)
412 ? PFR_NEXT_ULONG( p
)
413 : PFR_NEXT_USHORT( p
);
415 strike
->bct_offset
= ( flags0
& PFR_STRIKE_3BYTE_OFFSET
)
416 ? PFR_NEXT_ULONG( p
)
417 : PFR_NEXT_USHORT( p
);
419 strike
->num_bitmaps
= ( flags0
& PFR_STRIKE_2BYTE_COUNT
)
420 ? PFR_NEXT_USHORT( p
)
421 : PFR_NEXT_BYTE( p
);
424 phy_font
->num_strikes
+= count
;
430 error
= PFR_Err_Invalid_Table
;
431 FT_ERROR(( "pfr_extra_item_load_bitmap_info: invalid bitmap info table\n" ));
436 /* Load font ID. This is a so-called "unique" name that is rather
437 * long and descriptive (like "Tiresias ScreenFont v7.51").
439 * Note that a PFR font's family name is contained in an *undocumented*
440 * string of the "auxiliary data" portion of a physical font record. This
441 * may also contain the "real" style name!
443 * If no family name is present, the font ID is used instead for the
446 FT_CALLBACK_DEF( FT_Error
)
447 pfr_extra_item_load_font_id( FT_Byte
* p
,
449 PFR_PhyFont phy_font
)
452 FT_Memory memory
= phy_font
->memory
;
453 FT_PtrDist len
= limit
- p
;
456 if ( phy_font
->font_id
!= NULL
)
459 if ( FT_ALLOC( phy_font
->font_id
, len
+ 1 ) )
462 /* copy font ID name, and terminate it for safety */
463 FT_MEM_COPY( phy_font
->font_id
, p
, len
);
464 phy_font
->font_id
[len
] = 0;
471 /* load stem snap tables */
472 FT_CALLBACK_DEF( FT_Error
)
473 pfr_extra_item_load_stem_snaps( FT_Byte
* p
,
475 PFR_PhyFont phy_font
)
477 FT_UInt count
, num_vert
, num_horz
;
480 FT_Memory memory
= phy_font
->memory
;
483 if ( phy_font
->vertical
.stem_snaps
!= NULL
)
487 count
= PFR_NEXT_BYTE( p
);
489 num_vert
= count
& 15;
490 num_horz
= count
>> 4;
491 count
= num_vert
+ num_horz
;
493 PFR_CHECK( count
* 2 );
495 if ( FT_NEW_ARRAY( snaps
, count
) )
498 phy_font
->vertical
.stem_snaps
= snaps
;
499 phy_font
->horizontal
.stem_snaps
= snaps
+ num_vert
;
501 for ( ; count
> 0; count
--, snaps
++ )
502 *snaps
= FT_NEXT_SHORT( p
);
508 error
= PFR_Err_Invalid_Table
;
509 FT_ERROR(( "pfr_exta_item_load_stem_snaps: invalid stem snaps table\n" ));
515 /* load kerning pair data */
516 FT_CALLBACK_DEF( FT_Error
)
517 pfr_extra_item_load_kerning_pairs( FT_Byte
* p
,
519 PFR_PhyFont phy_font
)
523 FT_Memory memory
= phy_font
->memory
;
526 FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" ));
528 if ( FT_NEW( item
) )
533 item
->pair_count
= PFR_NEXT_BYTE( p
);
534 item
->base_adj
= PFR_NEXT_SHORT( p
);
535 item
->flags
= PFR_NEXT_BYTE( p
);
536 item
->offset
= phy_font
->offset
+ ( p
- phy_font
->cursor
);
538 #ifndef PFR_CONFIG_NO_CHECKS
541 if ( item
->flags
& PFR_KERN_2BYTE_CHAR
)
542 item
->pair_size
+= 2;
544 if ( item
->flags
& PFR_KERN_2BYTE_ADJ
)
545 item
->pair_size
+= 1;
547 PFR_CHECK( item
->pair_count
* item
->pair_size
);
550 /* load first and last pairs into the item to speed up */
551 /* lookup later... */
552 if ( item
->pair_count
> 0 )
554 FT_UInt char1
, char2
;
558 if ( item
->flags
& PFR_KERN_2BYTE_CHAR
)
561 char1
= PFR_NEXT_USHORT( q
);
562 char2
= PFR_NEXT_USHORT( q
);
564 item
->pair1
= PFR_KERN_INDEX( char1
, char2
);
566 q
= p
+ item
->pair_size
* ( item
->pair_count
- 1 );
567 char1
= PFR_NEXT_USHORT( q
);
568 char2
= PFR_NEXT_USHORT( q
);
570 item
->pair2
= PFR_KERN_INDEX( char1
, char2
);
575 char1
= PFR_NEXT_BYTE( q
);
576 char2
= PFR_NEXT_BYTE( q
);
578 item
->pair1
= PFR_KERN_INDEX( char1
, char2
);
580 q
= p
+ item
->pair_size
* ( item
->pair_count
- 1 );
581 char1
= PFR_NEXT_BYTE( q
);
582 char2
= PFR_NEXT_BYTE( q
);
584 item
->pair2
= PFR_KERN_INDEX( char1
, char2
);
587 /* add new item to the current list */
589 *phy_font
->kern_items_tail
= item
;
590 phy_font
->kern_items_tail
= &item
->next
;
591 phy_font
->num_kern_pairs
+= item
->pair_count
;
605 error
= PFR_Err_Invalid_Table
;
606 FT_ERROR(( "pfr_extra_item_load_kerning_pairs: "
607 "invalid kerning pairs table\n" ));
613 static const PFR_ExtraItemRec pfr_phy_font_extra_items
[] =
615 { 1, (PFR_ExtraItem_ParseFunc
)pfr_extra_item_load_bitmap_info
},
616 { 2, (PFR_ExtraItem_ParseFunc
)pfr_extra_item_load_font_id
},
617 { 3, (PFR_ExtraItem_ParseFunc
)pfr_extra_item_load_stem_snaps
},
618 { 4, (PFR_ExtraItem_ParseFunc
)pfr_extra_item_load_kerning_pairs
},
623 /* Loads a name from the auxiliary data. Since this extracts undocumented
624 * strings from the font file, we need to be careful here.
627 pfr_aux_name_load( FT_Byte
* p
,
630 FT_String
* *astring
)
633 FT_String
* result
= NULL
;
637 if ( len
> 0 && p
[len
- 1] == 0 )
640 /* check that each character is ASCII for making sure not to
644 for ( n
= 0; n
< len
; n
++ )
645 if ( p
[n
] < 32 || p
[n
] > 127 )
653 if ( FT_ALLOC( result
, len
+ 1 ) )
656 FT_MEM_COPY( result
, p
, len
);
666 pfr_phy_font_done( PFR_PhyFont phy_font
,
669 FT_FREE( phy_font
->font_id
);
670 FT_FREE( phy_font
->family_name
);
671 FT_FREE( phy_font
->style_name
);
673 FT_FREE( phy_font
->vertical
.stem_snaps
);
674 phy_font
->vertical
.num_stem_snaps
= 0;
676 phy_font
->horizontal
.stem_snaps
= NULL
;
677 phy_font
->horizontal
.num_stem_snaps
= 0;
679 FT_FREE( phy_font
->strikes
);
680 phy_font
->num_strikes
= 0;
681 phy_font
->max_strikes
= 0;
683 FT_FREE( phy_font
->chars
);
684 phy_font
->num_chars
= 0;
685 phy_font
->chars_offset
= 0;
687 FT_FREE( phy_font
->blue_values
);
688 phy_font
->num_blue_values
= 0;
691 PFR_KernItem item
, next
;
694 item
= phy_font
->kern_items
;
701 phy_font
->kern_items
= NULL
;
702 phy_font
->kern_items_tail
= NULL
;
705 phy_font
->num_kern_pairs
= 0;
709 FT_LOCAL_DEF( FT_Error
)
710 pfr_phy_font_load( PFR_PhyFont phy_font
,
716 FT_Memory memory
= stream
->memory
;
717 FT_UInt flags
, num_aux
;
722 phy_font
->memory
= memory
;
723 phy_font
->offset
= offset
;
725 phy_font
->kern_items
= NULL
;
726 phy_font
->kern_items_tail
= &phy_font
->kern_items
;
728 if ( FT_STREAM_SEEK( offset
) || FT_FRAME_ENTER( size
) )
731 phy_font
->cursor
= stream
->cursor
;
737 phy_font
->font_ref_number
= PFR_NEXT_USHORT( p
);
738 phy_font
->outline_resolution
= PFR_NEXT_USHORT( p
);
739 phy_font
->metrics_resolution
= PFR_NEXT_USHORT( p
);
740 phy_font
->bbox
.xMin
= PFR_NEXT_SHORT( p
);
741 phy_font
->bbox
.yMin
= PFR_NEXT_SHORT( p
);
742 phy_font
->bbox
.xMax
= PFR_NEXT_SHORT( p
);
743 phy_font
->bbox
.yMax
= PFR_NEXT_SHORT( p
);
744 phy_font
->flags
= flags
= PFR_NEXT_BYTE( p
);
746 /* get the standard advance for non-proportional fonts */
747 if ( !(flags
& PFR_PHY_PROPORTIONAL
) )
750 phy_font
->standard_advance
= PFR_NEXT_SHORT( p
);
753 /* load the extra items when present */
754 if ( flags
& PFR_PHY_EXTRA_ITEMS
)
756 error
= pfr_extra_items_parse( &p
, limit
,
757 pfr_phy_font_extra_items
, phy_font
);
763 /* In certain fonts, the auxiliary bytes contain interesting */
764 /* information. These are not in the specification but can be */
765 /* guessed by looking at the content of a few PFR0 fonts. */
767 num_aux
= PFR_NEXT_ULONG( p
);
775 PFR_CHECK( num_aux
);
778 while ( num_aux
> 0 )
780 FT_UInt length
, type
;
786 length
= PFR_NEXT_USHORT( q
);
787 if ( length
< 4 || length
> num_aux
)
791 type
= PFR_NEXT_USHORT( q
);
796 /* this seems to correspond to the font's family name,
797 * padded to 16-bits with one zero when necessary
799 error
= pfr_aux_name_load( q
, length
- 4U, memory
,
800 &phy_font
->family_name
);
810 phy_font
->ascent
= PFR_NEXT_SHORT( q
);
811 phy_font
->descent
= PFR_NEXT_SHORT( q
);
812 phy_font
->leading
= PFR_NEXT_SHORT( q
);
817 /* this seems to correspond to the font's style name,
818 * padded to 16-bits with one zero when necessary
820 error
= pfr_aux_name_load( q
, length
- 4U, memory
,
821 &phy_font
->style_name
);
835 /* read the blue values */
841 phy_font
->num_blue_values
= count
= PFR_NEXT_BYTE( p
);
843 PFR_CHECK( count
* 2 );
845 if ( FT_NEW_ARRAY( phy_font
->blue_values
, count
) )
848 for ( n
= 0; n
< count
; n
++ )
849 phy_font
->blue_values
[n
] = PFR_NEXT_SHORT( p
);
853 phy_font
->blue_fuzz
= PFR_NEXT_BYTE( p
);
854 phy_font
->blue_scale
= PFR_NEXT_BYTE( p
);
856 phy_font
->vertical
.standard
= PFR_NEXT_USHORT( p
);
857 phy_font
->horizontal
.standard
= PFR_NEXT_USHORT( p
);
859 /* read the character descriptors */
861 FT_UInt n
, count
, Size
;
864 phy_font
->num_chars
= count
= PFR_NEXT_USHORT( p
);
865 phy_font
->chars_offset
= offset
+ ( p
- stream
->cursor
);
867 if ( FT_NEW_ARRAY( phy_font
->chars
, count
) )
871 if ( flags
& PFR_PHY_2BYTE_CHARCODE
)
874 if ( flags
& PFR_PHY_PROPORTIONAL
)
877 if ( flags
& PFR_PHY_ASCII_CODE
)
880 if ( flags
& PFR_PHY_2BYTE_GPS_SIZE
)
883 if ( flags
& PFR_PHY_3BYTE_GPS_OFFSET
)
886 PFR_CHECK( count
* Size
);
888 for ( n
= 0; n
< count
; n
++ )
890 PFR_Char cur
= &phy_font
->chars
[n
];
893 cur
->char_code
= ( flags
& PFR_PHY_2BYTE_CHARCODE
)
894 ? PFR_NEXT_USHORT( p
)
895 : PFR_NEXT_BYTE( p
);
897 cur
->advance
= ( flags
& PFR_PHY_PROPORTIONAL
)
898 ? PFR_NEXT_SHORT( p
)
899 : (FT_Int
) phy_font
->standard_advance
;
902 cur
->ascii
= ( flags
& PFR_PHY_ASCII_CODE
)
906 if ( flags
& PFR_PHY_ASCII_CODE
)
909 cur
->gps_size
= ( flags
& PFR_PHY_2BYTE_GPS_SIZE
)
910 ? PFR_NEXT_USHORT( p
)
911 : PFR_NEXT_BYTE( p
);
913 cur
->gps_offset
= ( flags
& PFR_PHY_3BYTE_GPS_OFFSET
)
914 ? PFR_NEXT_ULONG( p
)
915 : PFR_NEXT_USHORT( p
);
924 /* save position of bitmap info */
925 phy_font
->bct_offset
= FT_STREAM_POS();
926 phy_font
->cursor
= NULL
;
932 error
= PFR_Err_Invalid_Table
;
933 FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" ));