1 /***************************************************************************/
5 /* FreeType PFR loader (body). */
7 /* Copyright 2002, 2003, 2004, 2005, 2007, 2009 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:"
432 " invalid bitmap info table\n" ));
437 /* Load font ID. This is a so-called "unique" name that is rather
438 * long and descriptive (like "Tiresias ScreenFont v7.51").
440 * Note that a PFR font's family name is contained in an *undocumented*
441 * string of the "auxiliary data" portion of a physical font record. This
442 * may also contain the "real" style name!
444 * If no family name is present, the font ID is used instead for the
447 FT_CALLBACK_DEF( FT_Error
)
448 pfr_extra_item_load_font_id( FT_Byte
* p
,
450 PFR_PhyFont phy_font
)
453 FT_Memory memory
= phy_font
->memory
;
454 FT_PtrDist len
= limit
- p
;
457 if ( phy_font
->font_id
!= NULL
)
460 if ( FT_ALLOC( phy_font
->font_id
, len
+ 1 ) )
463 /* copy font ID name, and terminate it for safety */
464 FT_MEM_COPY( phy_font
->font_id
, p
, len
);
465 phy_font
->font_id
[len
] = 0;
472 /* load stem snap tables */
473 FT_CALLBACK_DEF( FT_Error
)
474 pfr_extra_item_load_stem_snaps( FT_Byte
* p
,
476 PFR_PhyFont phy_font
)
478 FT_UInt count
, num_vert
, num_horz
;
481 FT_Memory memory
= phy_font
->memory
;
484 if ( phy_font
->vertical
.stem_snaps
!= NULL
)
488 count
= PFR_NEXT_BYTE( p
);
490 num_vert
= count
& 15;
491 num_horz
= count
>> 4;
492 count
= num_vert
+ num_horz
;
494 PFR_CHECK( count
* 2 );
496 if ( FT_NEW_ARRAY( snaps
, count
) )
499 phy_font
->vertical
.stem_snaps
= snaps
;
500 phy_font
->horizontal
.stem_snaps
= snaps
+ num_vert
;
502 for ( ; count
> 0; count
--, snaps
++ )
503 *snaps
= FT_NEXT_SHORT( p
);
509 error
= PFR_Err_Invalid_Table
;
510 FT_ERROR(( "pfr_exta_item_load_stem_snaps:"
511 " invalid stem snaps table\n" ));
517 /* load kerning pair data */
518 FT_CALLBACK_DEF( FT_Error
)
519 pfr_extra_item_load_kerning_pairs( FT_Byte
* p
,
521 PFR_PhyFont phy_font
)
525 FT_Memory memory
= phy_font
->memory
;
528 FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" ));
530 if ( FT_NEW( item
) )
535 item
->pair_count
= PFR_NEXT_BYTE( p
);
536 item
->base_adj
= PFR_NEXT_SHORT( p
);
537 item
->flags
= PFR_NEXT_BYTE( p
);
538 item
->offset
= phy_font
->offset
+ ( p
- phy_font
->cursor
);
540 #ifndef PFR_CONFIG_NO_CHECKS
543 if ( item
->flags
& PFR_KERN_2BYTE_CHAR
)
544 item
->pair_size
+= 2;
546 if ( item
->flags
& PFR_KERN_2BYTE_ADJ
)
547 item
->pair_size
+= 1;
549 PFR_CHECK( item
->pair_count
* item
->pair_size
);
552 /* load first and last pairs into the item to speed up */
553 /* lookup later... */
554 if ( item
->pair_count
> 0 )
556 FT_UInt char1
, char2
;
560 if ( item
->flags
& PFR_KERN_2BYTE_CHAR
)
563 char1
= PFR_NEXT_USHORT( q
);
564 char2
= PFR_NEXT_USHORT( q
);
566 item
->pair1
= PFR_KERN_INDEX( char1
, char2
);
568 q
= p
+ item
->pair_size
* ( item
->pair_count
- 1 );
569 char1
= PFR_NEXT_USHORT( q
);
570 char2
= PFR_NEXT_USHORT( q
);
572 item
->pair2
= PFR_KERN_INDEX( char1
, char2
);
577 char1
= PFR_NEXT_BYTE( q
);
578 char2
= PFR_NEXT_BYTE( q
);
580 item
->pair1
= PFR_KERN_INDEX( char1
, char2
);
582 q
= p
+ item
->pair_size
* ( item
->pair_count
- 1 );
583 char1
= PFR_NEXT_BYTE( q
);
584 char2
= PFR_NEXT_BYTE( q
);
586 item
->pair2
= PFR_KERN_INDEX( char1
, char2
);
589 /* add new item to the current list */
591 *phy_font
->kern_items_tail
= item
;
592 phy_font
->kern_items_tail
= &item
->next
;
593 phy_font
->num_kern_pairs
+= item
->pair_count
;
607 error
= PFR_Err_Invalid_Table
;
608 FT_ERROR(( "pfr_extra_item_load_kerning_pairs:"
609 " invalid kerning pairs table\n" ));
615 static const PFR_ExtraItemRec pfr_phy_font_extra_items
[] =
617 { 1, (PFR_ExtraItem_ParseFunc
)pfr_extra_item_load_bitmap_info
},
618 { 2, (PFR_ExtraItem_ParseFunc
)pfr_extra_item_load_font_id
},
619 { 3, (PFR_ExtraItem_ParseFunc
)pfr_extra_item_load_stem_snaps
},
620 { 4, (PFR_ExtraItem_ParseFunc
)pfr_extra_item_load_kerning_pairs
},
625 /* Loads a name from the auxiliary data. Since this extracts undocumented
626 * strings from the font file, we need to be careful here.
629 pfr_aux_name_load( FT_Byte
* p
,
632 FT_String
* *astring
)
635 FT_String
* result
= NULL
;
639 if ( len
> 0 && p
[len
- 1] == 0 )
642 /* check that each character is ASCII for making sure not to
646 for ( n
= 0; n
< len
; n
++ )
647 if ( p
[n
] < 32 || p
[n
] > 127 )
655 if ( FT_ALLOC( result
, len
+ 1 ) )
658 FT_MEM_COPY( result
, p
, len
);
668 pfr_phy_font_done( PFR_PhyFont phy_font
,
671 FT_FREE( phy_font
->font_id
);
672 FT_FREE( phy_font
->family_name
);
673 FT_FREE( phy_font
->style_name
);
675 FT_FREE( phy_font
->vertical
.stem_snaps
);
676 phy_font
->vertical
.num_stem_snaps
= 0;
678 phy_font
->horizontal
.stem_snaps
= NULL
;
679 phy_font
->horizontal
.num_stem_snaps
= 0;
681 FT_FREE( phy_font
->strikes
);
682 phy_font
->num_strikes
= 0;
683 phy_font
->max_strikes
= 0;
685 FT_FREE( phy_font
->chars
);
686 phy_font
->num_chars
= 0;
687 phy_font
->chars_offset
= 0;
689 FT_FREE( phy_font
->blue_values
);
690 phy_font
->num_blue_values
= 0;
693 PFR_KernItem item
, next
;
696 item
= phy_font
->kern_items
;
703 phy_font
->kern_items
= NULL
;
704 phy_font
->kern_items_tail
= NULL
;
707 phy_font
->num_kern_pairs
= 0;
711 FT_LOCAL_DEF( FT_Error
)
712 pfr_phy_font_load( PFR_PhyFont phy_font
,
718 FT_Memory memory
= stream
->memory
;
725 phy_font
->memory
= memory
;
726 phy_font
->offset
= offset
;
728 phy_font
->kern_items
= NULL
;
729 phy_font
->kern_items_tail
= &phy_font
->kern_items
;
731 if ( FT_STREAM_SEEK( offset
) || FT_FRAME_ENTER( size
) )
734 phy_font
->cursor
= stream
->cursor
;
740 phy_font
->font_ref_number
= PFR_NEXT_USHORT( p
);
741 phy_font
->outline_resolution
= PFR_NEXT_USHORT( p
);
742 phy_font
->metrics_resolution
= PFR_NEXT_USHORT( p
);
743 phy_font
->bbox
.xMin
= PFR_NEXT_SHORT( p
);
744 phy_font
->bbox
.yMin
= PFR_NEXT_SHORT( p
);
745 phy_font
->bbox
.xMax
= PFR_NEXT_SHORT( p
);
746 phy_font
->bbox
.yMax
= PFR_NEXT_SHORT( p
);
747 phy_font
->flags
= flags
= PFR_NEXT_BYTE( p
);
749 /* get the standard advance for non-proportional fonts */
750 if ( !(flags
& PFR_PHY_PROPORTIONAL
) )
753 phy_font
->standard_advance
= PFR_NEXT_SHORT( p
);
756 /* load the extra items when present */
757 if ( flags
& PFR_PHY_EXTRA_ITEMS
)
759 error
= pfr_extra_items_parse( &p
, limit
,
760 pfr_phy_font_extra_items
, phy_font
);
766 /* In certain fonts, the auxiliary bytes contain interesting */
767 /* information. These are not in the specification but can be */
768 /* guessed by looking at the content of a few PFR0 fonts. */
770 num_aux
= PFR_NEXT_ULONG( p
);
778 PFR_CHECK( num_aux
);
781 while ( num_aux
> 0 )
783 FT_UInt length
, type
;
789 length
= PFR_NEXT_USHORT( q
);
790 if ( length
< 4 || length
> num_aux
)
794 type
= PFR_NEXT_USHORT( q
);
799 /* this seems to correspond to the font's family name,
800 * padded to 16-bits with one zero when necessary
802 error
= pfr_aux_name_load( q
, length
- 4U, memory
,
803 &phy_font
->family_name
);
813 phy_font
->ascent
= PFR_NEXT_SHORT( q
);
814 phy_font
->descent
= PFR_NEXT_SHORT( q
);
815 phy_font
->leading
= PFR_NEXT_SHORT( q
);
820 /* this seems to correspond to the font's style name,
821 * padded to 16-bits with one zero when necessary
823 error
= pfr_aux_name_load( q
, length
- 4U, memory
,
824 &phy_font
->style_name
);
838 /* read the blue values */
844 phy_font
->num_blue_values
= count
= PFR_NEXT_BYTE( p
);
846 PFR_CHECK( count
* 2 );
848 if ( FT_NEW_ARRAY( phy_font
->blue_values
, count
) )
851 for ( n
= 0; n
< count
; n
++ )
852 phy_font
->blue_values
[n
] = PFR_NEXT_SHORT( p
);
856 phy_font
->blue_fuzz
= PFR_NEXT_BYTE( p
);
857 phy_font
->blue_scale
= PFR_NEXT_BYTE( p
);
859 phy_font
->vertical
.standard
= PFR_NEXT_USHORT( p
);
860 phy_font
->horizontal
.standard
= PFR_NEXT_USHORT( p
);
862 /* read the character descriptors */
864 FT_UInt n
, count
, Size
;
867 phy_font
->num_chars
= count
= PFR_NEXT_USHORT( p
);
868 phy_font
->chars_offset
= offset
+ ( p
- stream
->cursor
);
870 if ( FT_NEW_ARRAY( phy_font
->chars
, count
) )
874 if ( flags
& PFR_PHY_2BYTE_CHARCODE
)
877 if ( flags
& PFR_PHY_PROPORTIONAL
)
880 if ( flags
& PFR_PHY_ASCII_CODE
)
883 if ( flags
& PFR_PHY_2BYTE_GPS_SIZE
)
886 if ( flags
& PFR_PHY_3BYTE_GPS_OFFSET
)
889 PFR_CHECK( count
* Size
);
891 for ( n
= 0; n
< count
; n
++ )
893 PFR_Char cur
= &phy_font
->chars
[n
];
896 cur
->char_code
= ( flags
& PFR_PHY_2BYTE_CHARCODE
)
897 ? PFR_NEXT_USHORT( p
)
898 : PFR_NEXT_BYTE( p
);
900 cur
->advance
= ( flags
& PFR_PHY_PROPORTIONAL
)
901 ? PFR_NEXT_SHORT( p
)
902 : (FT_Int
) phy_font
->standard_advance
;
905 cur
->ascii
= ( flags
& PFR_PHY_ASCII_CODE
)
909 if ( flags
& PFR_PHY_ASCII_CODE
)
912 cur
->gps_size
= ( flags
& PFR_PHY_2BYTE_GPS_SIZE
)
913 ? PFR_NEXT_USHORT( p
)
914 : PFR_NEXT_BYTE( p
);
916 cur
->gps_offset
= ( flags
& PFR_PHY_3BYTE_GPS_OFFSET
)
917 ? PFR_NEXT_ULONG( p
)
918 : PFR_NEXT_USHORT( p
);
927 /* save position of bitmap info */
928 phy_font
->bct_offset
= FT_STREAM_POS();
929 phy_font
->cursor
= NULL
;
935 error
= PFR_Err_Invalid_Table
;
936 FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" ));