1 /***************************************************************************/
5 /* TrueType-specific tables loader (body). */
7 /* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008, 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_OBJECTS_H
22 #include FT_INTERNAL_STREAM_H
23 #include FT_TRUETYPE_TAGS_H
27 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
34 /*************************************************************************/
36 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
37 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
38 /* messages during execution. */
41 #define FT_COMPONENT trace_ttpload
44 /*************************************************************************/
47 /* tt_face_load_loca */
50 /* Load the locations table. */
53 /* face :: A handle to the target face object. */
56 /* stream :: The input stream. */
59 /* FreeType error code. 0 means success. */
61 FT_LOCAL_DEF( FT_Error
)
62 tt_face_load_loca( TT_Face face
,
70 /* we need the size of the `glyf' table for malformed `loca' tables */
71 error
= face
->goto_table( face
, TTAG_glyf
, stream
, &face
->glyf_len
);
73 /* it is possible that a font doesn't have a glyf table at all */
74 /* or its size is zero */
75 if ( error
== TT_Err_Table_Missing
)
80 FT_TRACE2(( "Locations " ));
81 error
= face
->goto_table( face
, TTAG_loca
, stream
, &table_len
);
84 error
= TT_Err_Locations_Missing
;
88 if ( face
->header
.Index_To_Loc_Format
!= 0 )
92 if ( table_len
>= 0x40000L
)
94 FT_TRACE2(( "table too large\n" ));
95 error
= TT_Err_Invalid_Table
;
98 face
->num_locations
= table_len
>> shift
;
104 if ( table_len
>= 0x20000L
)
106 FT_TRACE2(( "table too large\n" ));
107 error
= TT_Err_Invalid_Table
;
110 face
->num_locations
= table_len
>> shift
;
113 if ( face
->num_locations
!= (FT_ULong
)face
->root
.num_glyphs
)
115 FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n",
116 face
->num_locations
, face
->root
.num_glyphs
));
118 /* we only handle the case where `maxp' gives a larger value */
119 if ( face
->num_locations
< (FT_ULong
)face
->root
.num_glyphs
)
121 FT_Long new_loca_len
= (FT_Long
)face
->root
.num_glyphs
<< shift
;
123 TT_Table entry
= face
->dir_tables
;
124 TT_Table limit
= entry
+ face
->num_tables
;
126 FT_Long pos
= FT_Stream_Pos( stream
);
127 FT_Long dist
= 0x7FFFFFFFL
;
130 /* compute the distance to next table in font file */
131 for ( ; entry
< limit
; entry
++ )
133 FT_Long diff
= entry
->Offset
- pos
;
136 if ( diff
> 0 && diff
< dist
)
140 if ( new_loca_len
<= dist
)
142 face
->num_locations
= face
->root
.num_glyphs
;
143 table_len
= new_loca_len
;
145 FT_TRACE2(( "adjusting num_locations to %d\n",
146 face
->num_locations
));
152 * Extract the frame. We don't need to decompress it since
153 * we are able to parse it directly.
155 if ( FT_FRAME_EXTRACT( table_len
, face
->glyph_locations
) )
158 FT_TRACE2(( "loaded\n" ));
165 FT_LOCAL_DEF( FT_ULong
)
166 tt_face_get_location( TT_Face face
,
177 if ( gindex
< face
->num_locations
)
179 if ( face
->header
.Index_To_Loc_Format
!= 0 )
181 p
= face
->glyph_locations
+ gindex
* 4;
182 p_limit
= face
->glyph_locations
+ face
->num_locations
* 4;
184 pos1
= FT_NEXT_ULONG( p
);
187 if ( p
+ 4 <= p_limit
)
188 pos2
= FT_NEXT_ULONG( p
);
192 p
= face
->glyph_locations
+ gindex
* 2;
193 p_limit
= face
->glyph_locations
+ face
->num_locations
* 2;
195 pos1
= FT_NEXT_USHORT( p
);
198 if ( p
+ 2 <= p_limit
)
199 pos2
= FT_NEXT_USHORT( p
);
206 /* The `loca' table must be ordered; it refers to the length of */
207 /* an entry as the difference between the current and the next */
208 /* position. However, there do exist (malformed) fonts which */
209 /* don't obey this rule, so we are only able to provide an */
210 /* upper bound for the size. */
212 /* We get (intentionally) a wrong, non-zero result in case the */
213 /* `glyf' table is missing. */
215 *asize
= (FT_UInt
)( pos2
- pos1
);
217 *asize
= (FT_UInt
)( face
->glyf_len
- pos1
);
224 tt_face_done_loca( TT_Face face
)
226 FT_Stream stream
= face
->root
.stream
;
229 FT_FRAME_RELEASE( face
->glyph_locations
);
230 face
->num_locations
= 0;
235 /*************************************************************************/
238 /* tt_face_load_cvt */
241 /* Load the control value table into a face object. */
244 /* face :: A handle to the target face object. */
247 /* stream :: A handle to the input stream. */
250 /* FreeType error code. 0 means success. */
252 FT_LOCAL_DEF( FT_Error
)
253 tt_face_load_cvt( TT_Face face
,
256 #ifdef TT_USE_BYTECODE_INTERPRETER
259 FT_Memory memory
= stream
->memory
;
263 FT_TRACE2(( "CVT " ));
265 error
= face
->goto_table( face
, TTAG_cvt
, stream
, &table_len
);
268 FT_TRACE2(( "is missing\n" ));
277 face
->cvt_size
= table_len
/ 2;
279 if ( FT_NEW_ARRAY( face
->cvt
, face
->cvt_size
) )
282 if ( FT_FRAME_ENTER( face
->cvt_size
* 2L ) )
286 FT_Short
* cur
= face
->cvt
;
287 FT_Short
* limit
= cur
+ face
->cvt_size
;
290 for ( ; cur
< limit
; cur
++ )
291 *cur
= FT_GET_SHORT();
295 FT_TRACE2(( "loaded\n" ));
297 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
299 error
= tt_face_vary_cvt( face
, stream
);
305 #else /* !TT_USE_BYTECODE_INTERPRETER */
316 /*************************************************************************/
319 /* tt_face_load_fpgm */
322 /* Load the font program. */
325 /* face :: A handle to the target face object. */
328 /* stream :: A handle to the input stream. */
331 /* FreeType error code. 0 means success. */
333 FT_LOCAL_DEF( FT_Error
)
334 tt_face_load_fpgm( TT_Face face
,
337 #ifdef TT_USE_BYTECODE_INTERPRETER
343 FT_TRACE2(( "Font program " ));
345 /* The font program is optional */
346 error
= face
->goto_table( face
, TTAG_fpgm
, stream
, &table_len
);
349 face
->font_program
= NULL
;
350 face
->font_program_size
= 0;
353 FT_TRACE2(( "is missing\n" ));
357 face
->font_program_size
= table_len
;
358 if ( FT_FRAME_EXTRACT( table_len
, face
->font_program
) )
361 FT_TRACE2(( "loaded, %12d bytes\n", face
->font_program_size
));
367 #else /* !TT_USE_BYTECODE_INTERPRETER */
378 /*************************************************************************/
381 /* tt_face_load_prep */
384 /* Load the cvt program. */
387 /* face :: A handle to the target face object. */
390 /* stream :: A handle to the input stream. */
393 /* FreeType error code. 0 means success. */
395 FT_LOCAL_DEF( FT_Error
)
396 tt_face_load_prep( TT_Face face
,
399 #ifdef TT_USE_BYTECODE_INTERPRETER
405 FT_TRACE2(( "Prep program " ));
407 error
= face
->goto_table( face
, TTAG_prep
, stream
, &table_len
);
410 face
->cvt_program
= NULL
;
411 face
->cvt_program_size
= 0;
414 FT_TRACE2(( "is missing\n" ));
418 face
->cvt_program_size
= table_len
;
419 if ( FT_FRAME_EXTRACT( table_len
, face
->cvt_program
) )
422 FT_TRACE2(( "loaded, %12d bytes\n", face
->cvt_program_size
));
428 #else /* !TT_USE_BYTECODE_INTERPRETER */
439 /*************************************************************************/
442 /* tt_face_load_hdmx */
445 /* Load the `hdmx' table into the face object. */
448 /* face :: A handle to the target face object. */
450 /* stream :: A handle to the input stream. */
453 /* FreeType error code. 0 means success. */
456 FT_LOCAL_DEF( FT_Error
)
457 tt_face_load_hdmx( TT_Face face
,
461 FT_Memory memory
= stream
->memory
;
462 FT_UInt version
, nn
, num_records
;
463 FT_ULong table_size
, record_size
;
468 /* this table is optional */
469 error
= face
->goto_table( face
, TTAG_hdmx
, stream
, &table_size
);
470 if ( error
|| table_size
< 8 )
473 if ( FT_FRAME_EXTRACT( table_size
, face
->hdmx_table
) )
476 p
= face
->hdmx_table
;
477 limit
= p
+ table_size
;
479 version
= FT_NEXT_USHORT( p
);
480 num_records
= FT_NEXT_USHORT( p
);
481 record_size
= FT_NEXT_ULONG( p
);
483 /* The maximum number of bytes in an hdmx device record is the */
484 /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */
485 /* the reason why `record_size' is a long (which we read as */
486 /* unsigned long for convenience). In practice, two bytes */
487 /* sufficient to hold the size value. */
489 /* There are at least two fonts, HANNOM-A and HANNOM-B version */
490 /* 2.0 (2005), which get this wrong: The upper two bytes of */
491 /* the size value are set to 0xFF instead of 0x00. We catch */
494 if ( record_size
>= 0xFFFF0000UL
)
495 record_size
&= 0xFFFFU
;
497 /* The limit for `num_records' is a heuristic value. */
499 if ( version
!= 0 || num_records
> 255 || record_size
> 0x10001L
)
501 error
= TT_Err_Invalid_File_Format
;
505 if ( FT_NEW_ARRAY( face
->hdmx_record_sizes
, num_records
) )
508 for ( nn
= 0; nn
< num_records
; nn
++ )
510 if ( p
+ record_size
> limit
)
513 face
->hdmx_record_sizes
[nn
] = p
[0];
517 face
->hdmx_record_count
= nn
;
518 face
->hdmx_table_size
= table_size
;
519 face
->hdmx_record_size
= record_size
;
525 FT_FRAME_RELEASE( face
->hdmx_table
);
526 face
->hdmx_table_size
= 0;
532 tt_face_free_hdmx( TT_Face face
)
534 FT_Stream stream
= face
->root
.stream
;
535 FT_Memory memory
= stream
->memory
;
538 FT_FREE( face
->hdmx_record_sizes
);
539 FT_FRAME_RELEASE( face
->hdmx_table
);
543 /*************************************************************************/
545 /* Return the advance width table for a given pixel size if it is found */
546 /* in the font's `hdmx' table (if any). */
548 FT_LOCAL_DEF( FT_Byte
* )
549 tt_face_get_device_metrics( TT_Face face
,
554 FT_Byte
* result
= NULL
;
555 FT_ULong record_size
= face
->hdmx_record_size
;
556 FT_Byte
* record
= face
->hdmx_table
+ 8;
559 for ( nn
= 0; nn
< face
->hdmx_record_count
; nn
++ )
560 if ( face
->hdmx_record_sizes
[nn
] == ppem
)
563 if ( gindex
< record_size
)
564 result
= record
+ nn
* record_size
+ gindex
;