134 |
} |
} |
135 |
|
|
136 |
|
|
137 |
/* Here, we: */ |
/* Here, we */ |
138 |
/* */ |
/* */ |
139 |
/* - check that `num_tables' is valid */ |
/* - check that `num_tables' is valid */ |
140 |
/* - look for a "head" table, check its size, and parse it to */ |
/* - look for a `head' table, check its size, and parse it to check */ |
141 |
/* see if its "magic" field is correctly set */ |
/* whether its `magic' field is correctly set */ |
142 |
/* */ |
/* */ |
143 |
/* When checking directory entries, ignore the tables `glyx' and `locx' */ |
/* When checking directory entries, ignore the tables `glyx' and `locx' */ |
144 |
/* which are hacked-out versions of `glyf' and `loca' in some PostScript */ |
/* which are hacked-out versions of `glyf' and `loca' in some PostScript */ |
145 |
/* Type 42 fonts, and will generally be invalid. */ |
/* Type 42 fonts, and which are generally invalid. */ |
146 |
/* */ |
/* */ |
147 |
static FT_Error |
static FT_Error |
148 |
sfnt_dir_check( SFNT_Header sfnt, |
sfnt_dir_check( SFNT_Header sfnt, |
170 |
}; |
}; |
171 |
|
|
172 |
|
|
173 |
if ( sfnt->num_tables == 0 || |
if ( sfnt->num_tables == 0 || |
174 |
offset + sfnt->num_tables * 16 > stream->size ) |
offset + sfnt->num_tables * 16 > stream->size ) |
175 |
return SFNT_Err_Unknown_File_Format; |
return SFNT_Err_Unknown_File_Format; |
176 |
|
|
185 |
if ( FT_STREAM_READ_FIELDS( sfnt_dir_entry_fields, &table ) ) |
if ( FT_STREAM_READ_FIELDS( sfnt_dir_entry_fields, &table ) ) |
186 |
return error; |
return error; |
187 |
|
|
188 |
if ( table.Offset + table.Length > stream->size && |
if ( table.Offset + table.Length > stream->size && |
189 |
table.Tag != glyx_tag && table.Tag != locx_tag ) |
table.Tag != glyx_tag && |
190 |
|
table.Tag != locx_tag ) |
191 |
return SFNT_Err_Unknown_File_Format; |
return SFNT_Err_Unknown_File_Format; |
192 |
|
|
193 |
if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed ) |
if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed ) |
199 |
#endif |
#endif |
200 |
has_head = 1; |
has_head = 1; |
201 |
|
|
202 |
/* The table length should be 0x36, but certain font tools |
/* |
203 |
* make it 0x38, so we will just check that it is greater. |
* The table length should be 0x36, but certain font tools make it |
204 |
|
* 0x38, so we will just check that it is greater. |
205 |
|
* |
206 |
|
* Note that according to the specification, the table must be |
207 |
|
* padded to 32-bit lengths, but this doesn't apply to the value of |
208 |
|
* its `Length' field! |
209 |
* |
* |
|
* Note that according to the specification, |
|
|
* the table must be padded to 32-bit lengths, but this doesn't |
|
|
* apply to the value of its "Length" field! |
|
210 |
*/ |
*/ |
211 |
if ( table.Length < 0x36 ) |
if ( table.Length < 0x36 ) |
212 |
return SFNT_Err_Unknown_File_Format; |
return SFNT_Err_Unknown_File_Format; |
213 |
|
|
214 |
if ( FT_STREAM_SEEK( table.Offset + 12 ) || |
if ( FT_STREAM_SEEK( table.Offset + 12 ) || |
215 |
FT_READ_ULONG( magic ) ) |
FT_READ_ULONG( magic ) ) |
216 |
return error; |
return error; |
217 |
|
|
218 |
if ( magic != 0x5F0F3CF5UL ) |
if ( magic != 0x5F0F3CF5UL ) |
227 |
has_meta = 1; |
has_meta = 1; |
228 |
} |
} |
229 |
|
|
230 |
|
/* if `sing' and `meta' tables are present, there is no `head' table */ |
231 |
if ( has_head || ( has_sing && has_meta ) ) |
if ( has_head || ( has_sing && has_meta ) ) |
232 |
return SFNT_Err_Ok; |
return SFNT_Err_Ok; |
233 |
else |
else |
235 |
} |
} |
236 |
|
|
237 |
|
|
238 |
/* Fill in face->ttc_header. If the font is not a TTC, it is */ |
/* Fill in face->ttc_header. If the font is not a TTC, it is */ |
239 |
/* synthesized into a TTC with one offset table. */ |
/* synthesized into a TTC with one offset table. */ |
240 |
static FT_Error |
static FT_Error |
241 |
sfnt_init( FT_Stream stream, |
sfnt_init( FT_Stream stream, |
242 |
TT_Face face ) |
TT_Face face ) |
256 |
FT_FRAME_END |
FT_FRAME_END |
257 |
}; |
}; |
258 |
|
|
259 |
face->ttc_header.tag = 0; |
|
260 |
|
face->ttc_header.tag = 0; |
261 |
face->ttc_header.version = 0; |
face->ttc_header.version = 0; |
262 |
face->ttc_header.count = 0; |
face->ttc_header.count = 0; |
263 |
|
|
264 |
offset = FT_STREAM_POS(); |
offset = FT_STREAM_POS(); |
265 |
|
|
292 |
} |
} |
293 |
else |
else |
294 |
{ |
{ |
295 |
|
FT_TRACE3(( "sfnt_init: synthesize TTC\n" )); |
296 |
|
|
297 |
face->ttc_header.version = 1 << 16; |
face->ttc_header.version = 1 << 16; |
298 |
face->ttc_header.count = 1; |
face->ttc_header.count = 1; |
299 |
|
|
300 |
if ( FT_NEW( face->ttc_header.offsets) ) |
if ( FT_NEW( face->ttc_header.offsets) ) |
301 |
return error; |
return error; |
378 |
return error; |
return error; |
379 |
|
|
380 |
/* read offset table */ |
/* read offset table */ |
381 |
if ( FT_READ_ULONG( sfnt->format_tag ) || |
if ( FT_READ_ULONG( sfnt->format_tag ) || |
382 |
FT_STREAM_READ_FIELDS( sfnt_header_fields, sfnt ) ) |
FT_STREAM_READ_FIELDS( sfnt_header_fields, sfnt ) ) |
383 |
return error; |
return error; |
384 |
|
|
385 |
/* many fonts don't have these fields set correctly */ |
/* many fonts don't have these fields set correctly */ |
386 |
#if 0 |
#if 0 |
387 |
if ( sfnt->search_range != 1 << ( sfnt->entry_selector + 4 ) || |
if ( sfnt->search_range != 1 << ( sfnt->entry_selector + 4 ) || |
388 |
sfnt->search_range + sfnt->range_shift != sfnt->num_tables << 4 ) |
sfnt->search_range + sfnt->range_shift != sfnt->num_tables << 4 ) |
389 |
return SFNT_Err_Unknown_File_Format; |
return SFNT_Err_Unknown_File_Format; |
390 |
#endif |
#endif |
433 |
|
|
434 |
/* check first */ |
/* check first */ |
435 |
error = sfnt_dir_check( sfnt, stream ); |
error = sfnt_dir_check( sfnt, stream ); |
436 |
if ( error ) { |
if ( error ) |
437 |
|
{ |
438 |
FT_TRACE2(( "tt_face_load_directory: directory checking failed!\n" )); |
FT_TRACE2(( "tt_face_load_directory: directory checking failed!\n" )); |
439 |
|
|
440 |
return error; |
return error; |