1
/***************************************************************************/
5
/* Load the basic TrueType tables, i.e., tables that can be either in */
6
/* TTF or OTF fonts (body). */
8
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
10
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
12
/* This file is part of the FreeType project, and may only be used, */
13
/* modified, and distributed under the terms of the FreeType project */
14
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
15
/* this file you indicate that you have read the license and */
16
/* understand and accept it fully. */
18
/***************************************************************************/
22
#include FT_INTERNAL_DEBUG_H
23
#include FT_INTERNAL_STREAM_H
24
#include FT_TRUETYPE_TAGS_H
30
/*************************************************************************/
32
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
33
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
34
/* messages during execution. */
37
#define FT_COMPONENT trace_ttload
40
/*************************************************************************/
43
/* tt_face_lookup_table */
46
/* Looks for a TrueType table by name. */
49
/* face :: A face object handle. */
51
/* tag :: The searched tag. */
54
/* A pointer to the table directory entry. 0 if not found. */
56
FT_LOCAL_DEF( TT_Table )
57
tt_face_lookup_table( TT_Face face,
62
#ifdef FT_DEBUG_LEVEL_TRACE
63
FT_Bool zero_length = FALSE;
67
FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ",
69
(FT_Char)( tag >> 24 ),
70
(FT_Char)( tag >> 16 ),
71
(FT_Char)( tag >> 8 ),
74
entry = face->dir_tables;
75
limit = entry + face->num_tables;
77
for ( ; entry < limit; entry++ )
79
/* For compatibility with Windows, we consider */
80
/* zero-length tables the same as missing tables. */
81
if ( entry->Tag == tag )
83
if ( entry->Length != 0 )
85
FT_TRACE4(( "found table.\n" ));
88
#ifdef FT_DEBUG_LEVEL_TRACE
94
#ifdef FT_DEBUG_LEVEL_TRACE
96
FT_TRACE4(( "ignoring empty table\n" ));
98
FT_TRACE4(( "could not find table\n" ));
105
/*************************************************************************/
108
/* tt_face_goto_table */
111
/* Looks for a TrueType table by name, then seek a stream to it. */
114
/* face :: A face object handle. */
116
/* tag :: The searched tag. */
118
/* stream :: The stream to seek when the table is found. */
121
/* length :: The length of the table if found, undefined otherwise. */
124
/* FreeType error code. 0 means success. */
126
FT_LOCAL_DEF( FT_Error )
127
tt_face_goto_table( TT_Face face,
136
table = tt_face_lookup_table( face, tag );
140
*length = table->Length;
142
if ( FT_STREAM_SEEK( table->Offset ) )
146
error = SFNT_Err_Table_Missing;
155
/* - check that `num_tables' is valid (and adjust it if necessary) */
157
/* - look for a `head' table, check its size, and parse it to check */
158
/* whether its `magic' field is correctly set */
160
/* - errors (except errors returned by stream handling) */
162
/* SFNT_Err_Unknown_File_Format: */
163
/* no table is defined in directory, it is not sfnt-wrapped */
165
/* SFNT_Err_Table_Missing: */
166
/* table directory is valid, but essential tables */
167
/* (head/bhed/SING) are missing */
170
check_table_dir( SFNT_Header sfnt,
174
FT_UShort nn, valid_entries = 0;
175
FT_UInt has_head = 0, has_sing = 0, has_meta = 0;
176
FT_ULong offset = sfnt->offset + 12;
178
static const FT_Frame_Field table_dir_entry_fields[] =
181
#define FT_STRUCTURE TT_TableRec
183
FT_FRAME_START( 16 ),
184
FT_FRAME_ULONG( Tag ),
185
FT_FRAME_ULONG( CheckSum ),
186
FT_FRAME_ULONG( Offset ),
187
FT_FRAME_ULONG( Length ),
192
if ( FT_STREAM_SEEK( offset ) )
195
for ( nn = 0; nn < sfnt->num_tables; nn++ )
200
if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )
203
FT_TRACE2(( "check_table_dir:"
204
" can read only %d table%s in font (instead of %d)\n",
205
nn, nn == 1 ? "" : "s", sfnt->num_tables ));
206
sfnt->num_tables = nn;
210
/* we ignore invalid tables */
211
if ( table.Offset + table.Length > stream->size )
213
FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
219
if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed )
224
#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
225
if ( table.Tag == TTAG_head )
230
* The table length should be 0x36, but certain font tools make it
231
* 0x38, so we will just check that it is greater.
233
* Note that according to the specification, the table must be
234
* padded to 32-bit lengths, but this doesn't apply to the value of
235
* its `Length' field!
238
if ( table.Length < 0x36 )
240
FT_TRACE2(( "check_table_dir: `head' table too small\n" ));
241
error = SFNT_Err_Table_Missing;
245
if ( FT_STREAM_SEEK( table.Offset + 12 ) ||
246
FT_READ_ULONG( magic ) )
249
if ( magic != 0x5F0F3CF5UL )
251
FT_TRACE2(( "check_table_dir:"
252
" no magic number found in `head' table\n"));
253
error = SFNT_Err_Table_Missing;
257
if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) )
260
else if ( table.Tag == TTAG_SING )
262
else if ( table.Tag == TTAG_META )
266
sfnt->num_tables = valid_entries;
268
if ( sfnt->num_tables == 0 )
270
FT_TRACE2(( "check_table_dir: no tables found\n" ));
271
error = SFNT_Err_Unknown_File_Format;
275
/* if `sing' and `meta' tables are present, there is no `head' table */
276
if ( has_head || ( has_sing && has_meta ) )
283
FT_TRACE2(( "check_table_dir:" ));
284
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
285
FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" ));
287
FT_TRACE2(( " neither `head' nor `sing' table found\n" ));
289
error = SFNT_Err_Table_Missing;
297
/*************************************************************************/
300
/* tt_face_load_font_dir */
303
/* Loads the header of a SFNT font file. */
306
/* face :: A handle to the target face object. */
308
/* stream :: The input stream. */
311
/* sfnt :: The SFNT header. */
314
/* FreeType error code. 0 means success. */
317
/* The stream cursor must be at the beginning of the font directory. */
319
FT_LOCAL_DEF( FT_Error )
320
tt_face_load_font_dir( TT_Face face,
325
FT_Memory memory = stream->memory;
329
static const FT_Frame_Field offset_table_fields[] =
332
#define FT_STRUCTURE SFNT_HeaderRec
335
FT_FRAME_USHORT( num_tables ),
336
FT_FRAME_USHORT( search_range ),
337
FT_FRAME_USHORT( entry_selector ),
338
FT_FRAME_USHORT( range_shift ),
343
FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face ));
345
/* read the offset table */
347
sfnt.offset = FT_STREAM_POS();
349
if ( FT_READ_ULONG( sfnt.format_tag ) ||
350
FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) )
353
/* many fonts don't have these fields set correctly */
355
if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 ) ||
356
sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 )
357
return SFNT_Err_Unknown_File_Format;
360
/* load the table directory */
362
FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables ));
363
FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag ));
366
error = check_table_dir( &sfnt, stream );
369
FT_TRACE2(( "tt_face_load_font_dir:"
370
" invalid table directory for TrueType\n" ));
375
face->num_tables = sfnt.num_tables;
376
face->format_tag = sfnt.format_tag;
378
if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) )
381
if ( FT_STREAM_SEEK( sfnt.offset + 12 ) ||
382
FT_FRAME_ENTER( face->num_tables * 16L ) )
385
entry = face->dir_tables;
388
" tag offset length checksum\n"
389
" ----------------------------------\n" ));
391
for ( nn = 0; nn < sfnt.num_tables; nn++ )
393
entry->Tag = FT_GET_TAG4();
394
entry->CheckSum = FT_GET_ULONG();
395
entry->Offset = FT_GET_LONG();
396
entry->Length = FT_GET_LONG();
398
/* ignore invalid tables */
399
if ( entry->Offset + entry->Length > stream->size )
403
FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx\n",
404
(FT_Char)( entry->Tag >> 24 ),
405
(FT_Char)( entry->Tag >> 16 ),
406
(FT_Char)( entry->Tag >> 8 ),
407
(FT_Char)( entry->Tag ),
417
FT_TRACE2(( "table directory loaded\n\n" ));
424
/*************************************************************************/
427
/* tt_face_load_any */
430
/* Loads any font table into client memory. */
433
/* face :: The face object to look for. */
435
/* tag :: The tag of table to load. Use the value 0 if you want */
436
/* to access the whole font file, else set this parameter */
437
/* to a valid TrueType table tag that you can forge with */
438
/* the MAKE_TT_TAG macro. */
440
/* offset :: The starting offset in the table (or the file if */
443
/* length :: The address of the decision variable: */
445
/* If length == NULL: */
446
/* Loads the whole table. Returns an error if */
449
/* If *length == 0: */
450
/* Exits immediately; returning the length of the given */
451
/* table or of the font file, depending on the value of */
454
/* If *length != 0: */
455
/* Loads the next `length' bytes of table or font, */
456
/* starting at offset `offset' (in table or font too). */
459
/* buffer :: The address of target buffer. */
462
/* FreeType error code. 0 means success. */
464
FT_LOCAL_DEF( FT_Error )
465
tt_face_load_any( TT_Face face,
479
/* look for tag in font directory */
480
table = tt_face_lookup_table( face, tag );
483
error = SFNT_Err_Table_Missing;
487
offset += table->Offset;
488
size = table->Length;
491
/* tag == 0 -- the user wants to access the font file directly */
492
size = face->root.stream->size;
494
if ( length && *length == 0 )
504
stream = face->root.stream;
505
/* the `if' is syntactic sugar for picky compilers */
506
if ( FT_STREAM_READ_AT( offset, buffer, size ) )
514
/*************************************************************************/
517
/* tt_face_load_generic_header */
520
/* Loads the TrueType table `head' or `bhed'. */
523
/* face :: A handle to the target face object. */
525
/* stream :: The input stream. */
528
/* FreeType error code. 0 means success. */
531
tt_face_load_generic_header( TT_Face face,
538
static const FT_Frame_Field header_fields[] =
541
#define FT_STRUCTURE TT_Header
543
FT_FRAME_START( 54 ),
544
FT_FRAME_ULONG ( Table_Version ),
545
FT_FRAME_ULONG ( Font_Revision ),
546
FT_FRAME_LONG ( CheckSum_Adjust ),
547
FT_FRAME_LONG ( Magic_Number ),
548
FT_FRAME_USHORT( Flags ),
549
FT_FRAME_USHORT( Units_Per_EM ),
550
FT_FRAME_LONG ( Created[0] ),
551
FT_FRAME_LONG ( Created[1] ),
552
FT_FRAME_LONG ( Modified[0] ),
553
FT_FRAME_LONG ( Modified[1] ),
554
FT_FRAME_SHORT ( xMin ),
555
FT_FRAME_SHORT ( yMin ),
556
FT_FRAME_SHORT ( xMax ),
557
FT_FRAME_SHORT ( yMax ),
558
FT_FRAME_USHORT( Mac_Style ),
559
FT_FRAME_USHORT( Lowest_Rec_PPEM ),
560
FT_FRAME_SHORT ( Font_Direction ),
561
FT_FRAME_SHORT ( Index_To_Loc_Format ),
562
FT_FRAME_SHORT ( Glyph_Data_Format ),
567
error = face->goto_table( face, tag, stream, 0 );
571
header = &face->header;
573
if ( FT_STREAM_READ_FIELDS( header_fields, header ) )
576
FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM ));
577
FT_TRACE3(( "IndexToLoc: %4d\n", header->Index_To_Loc_Format ));
584
FT_LOCAL_DEF( FT_Error )
585
tt_face_load_head( TT_Face face,
588
return tt_face_load_generic_header( face, stream, TTAG_head );
592
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
594
FT_LOCAL_DEF( FT_Error )
595
tt_face_load_bhed( TT_Face face,
598
return tt_face_load_generic_header( face, stream, TTAG_bhed );
601
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
604
/*************************************************************************/
607
/* tt_face_load_max_profile */
610
/* Loads the maximum profile into a face object. */
613
/* face :: A handle to the target face object. */
615
/* stream :: The input stream. */
618
/* FreeType error code. 0 means success. */
620
FT_LOCAL_DEF( FT_Error )
621
tt_face_load_maxp( TT_Face face,
625
TT_MaxProfile* maxProfile = &face->max_profile;
627
const FT_Frame_Field maxp_fields[] =
630
#define FT_STRUCTURE TT_MaxProfile
633
FT_FRAME_LONG ( version ),
634
FT_FRAME_USHORT( numGlyphs ),
638
const FT_Frame_Field maxp_fields_extra[] =
640
FT_FRAME_START( 26 ),
641
FT_FRAME_USHORT( maxPoints ),
642
FT_FRAME_USHORT( maxContours ),
643
FT_FRAME_USHORT( maxCompositePoints ),
644
FT_FRAME_USHORT( maxCompositeContours ),
645
FT_FRAME_USHORT( maxZones ),
646
FT_FRAME_USHORT( maxTwilightPoints ),
647
FT_FRAME_USHORT( maxStorage ),
648
FT_FRAME_USHORT( maxFunctionDefs ),
649
FT_FRAME_USHORT( maxInstructionDefs ),
650
FT_FRAME_USHORT( maxStackElements ),
651
FT_FRAME_USHORT( maxSizeOfInstructions ),
652
FT_FRAME_USHORT( maxComponentElements ),
653
FT_FRAME_USHORT( maxComponentDepth ),
658
error = face->goto_table( face, TTAG_maxp, stream, 0 );
662
if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) )
665
maxProfile->maxPoints = 0;
666
maxProfile->maxContours = 0;
667
maxProfile->maxCompositePoints = 0;
668
maxProfile->maxCompositeContours = 0;
669
maxProfile->maxZones = 0;
670
maxProfile->maxTwilightPoints = 0;
671
maxProfile->maxStorage = 0;
672
maxProfile->maxFunctionDefs = 0;
673
maxProfile->maxInstructionDefs = 0;
674
maxProfile->maxStackElements = 0;
675
maxProfile->maxSizeOfInstructions = 0;
676
maxProfile->maxComponentElements = 0;
677
maxProfile->maxComponentDepth = 0;
679
if ( maxProfile->version >= 0x10000L )
681
if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) )
684
/* XXX: an adjustment that is necessary to load certain */
685
/* broken fonts like `Keystrokes MT' :-( */
687
/* We allocate 64 function entries by default when */
688
/* the maxFunctionDefs value is smaller. */
690
if ( maxProfile->maxFunctionDefs < 64 )
691
maxProfile->maxFunctionDefs = 64;
693
/* we add 4 phantom points later */
694
if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) )
696
FT_TRACE0(( "tt_face_load_maxp:"
697
" too much twilight points in `maxp' table;\n"
699
" some glyphs might be rendered incorrectly\n" ));
701
maxProfile->maxTwilightPoints = 0xFFFFU - 4;
704
/* we arbitrarily limit recursion to avoid stack exhaustion */
705
if ( maxProfile->maxComponentDepth > 100 )
707
FT_TRACE0(( "tt_face_load_maxp:"
708
" abnormally large component depth (%d) set to 100\n",
709
maxProfile->maxComponentDepth ));
710
maxProfile->maxComponentDepth = 100;
714
FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs ));
721
/*************************************************************************/
724
/* tt_face_load_names */
727
/* Loads the name records. */
730
/* face :: A handle to the target face object. */
732
/* stream :: The input stream. */
735
/* FreeType error code. 0 means success. */
737
FT_LOCAL_DEF( FT_Error )
738
tt_face_load_name( TT_Face face,
742
FT_Memory memory = stream->memory;
743
FT_ULong table_pos, table_len;
744
FT_ULong storage_start, storage_limit;
748
static const FT_Frame_Field name_table_fields[] =
751
#define FT_STRUCTURE TT_NameTableRec
754
FT_FRAME_USHORT( format ),
755
FT_FRAME_USHORT( numNameRecords ),
756
FT_FRAME_USHORT( storageOffset ),
760
static const FT_Frame_Field name_record_fields[] =
763
#define FT_STRUCTURE TT_NameEntryRec
765
/* no FT_FRAME_START */
766
FT_FRAME_USHORT( platformID ),
767
FT_FRAME_USHORT( encodingID ),
768
FT_FRAME_USHORT( languageID ),
769
FT_FRAME_USHORT( nameID ),
770
FT_FRAME_USHORT( stringLength ),
771
FT_FRAME_USHORT( stringOffset ),
776
table = &face->name_table;
777
table->stream = stream;
779
error = face->goto_table( face, TTAG_name, stream, &table_len );
783
table_pos = FT_STREAM_POS();
786
if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) )
789
/* Some popular Asian fonts have an invalid `storageOffset' value */
790
/* (it should be at least "6 + 12*num_names"). However, the string */
791
/* offsets, computed as "storageOffset + entry->stringOffset", are */
792
/* valid pointers within the name table... */
794
/* We thus can't check `storageOffset' right now. */
796
storage_start = table_pos + 6 + 12*table->numNameRecords;
797
storage_limit = table_pos + table_len;
799
if ( storage_start > storage_limit )
801
FT_ERROR(( "tt_face_load_name: invalid `name' table\n" ));
802
error = SFNT_Err_Name_Table_Missing;
806
/* Allocate the array of name records. */
807
count = table->numNameRecords;
808
table->numNameRecords = 0;
810
if ( FT_NEW_ARRAY( table->names, count ) ||
811
FT_FRAME_ENTER( count * 12 ) )
814
/* Load the name records and determine how much storage is needed */
815
/* to hold the strings themselves. */
817
TT_NameEntryRec* entry = table->names;
820
for ( ; count > 0; count-- )
822
if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) )
825
/* check that the name is not empty */
826
if ( entry->stringLength == 0 )
829
/* check that the name string is within the table */
830
entry->stringOffset += table_pos + table->storageOffset;
831
if ( entry->stringOffset < storage_start ||
832
entry->stringOffset + entry->stringLength > storage_limit )
834
/* invalid entry - ignore it */
835
entry->stringOffset = 0;
836
entry->stringLength = 0;
843
table->numNameRecords = (FT_UInt)( entry - table->names );
848
/* everything went well, update face->num_names */
849
face->num_names = (FT_UShort) table->numNameRecords;
856
/*************************************************************************/
859
/* tt_face_free_names */
862
/* Frees the name records. */
865
/* face :: A handle to the target face object. */
868
tt_face_free_name( TT_Face face )
870
FT_Memory memory = face->root.driver->root.memory;
871
TT_NameTable table = &face->name_table;
872
TT_NameEntry entry = table->names;
873
FT_UInt count = table->numNameRecords;
878
for ( ; count > 0; count--, entry++ )
880
FT_FREE( entry->string );
881
entry->stringLength = 0;
884
/* free strings table */
885
FT_FREE( table->names );
888
table->numNameRecords = 0;
890
table->storageOffset = 0;
894
/*************************************************************************/
897
/* tt_face_load_cmap */
900
/* Loads the cmap directory in a face object. The cmaps themselves */
901
/* are loaded on demand in the `ttcmap.c' module. */
904
/* face :: A handle to the target face object. */
906
/* stream :: A handle to the input stream. */
909
/* FreeType error code. 0 means success. */
912
FT_LOCAL_DEF( FT_Error )
913
tt_face_load_cmap( TT_Face face,
919
error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size );
923
if ( FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) )
932
/*************************************************************************/
935
/* tt_face_load_os2 */
938
/* Loads the OS2 table. */
941
/* face :: A handle to the target face object. */
943
/* stream :: A handle to the input stream. */
946
/* FreeType error code. 0 means success. */
948
FT_LOCAL_DEF( FT_Error )
949
tt_face_load_os2( TT_Face face,
955
const FT_Frame_Field os2_fields[] =
958
#define FT_STRUCTURE TT_OS2
960
FT_FRAME_START( 78 ),
961
FT_FRAME_USHORT( version ),
962
FT_FRAME_SHORT ( xAvgCharWidth ),
963
FT_FRAME_USHORT( usWeightClass ),
964
FT_FRAME_USHORT( usWidthClass ),
965
FT_FRAME_SHORT ( fsType ),
966
FT_FRAME_SHORT ( ySubscriptXSize ),
967
FT_FRAME_SHORT ( ySubscriptYSize ),
968
FT_FRAME_SHORT ( ySubscriptXOffset ),
969
FT_FRAME_SHORT ( ySubscriptYOffset ),
970
FT_FRAME_SHORT ( ySuperscriptXSize ),
971
FT_FRAME_SHORT ( ySuperscriptYSize ),
972
FT_FRAME_SHORT ( ySuperscriptXOffset ),
973
FT_FRAME_SHORT ( ySuperscriptYOffset ),
974
FT_FRAME_SHORT ( yStrikeoutSize ),
975
FT_FRAME_SHORT ( yStrikeoutPosition ),
976
FT_FRAME_SHORT ( sFamilyClass ),
977
FT_FRAME_BYTE ( panose[0] ),
978
FT_FRAME_BYTE ( panose[1] ),
979
FT_FRAME_BYTE ( panose[2] ),
980
FT_FRAME_BYTE ( panose[3] ),
981
FT_FRAME_BYTE ( panose[4] ),
982
FT_FRAME_BYTE ( panose[5] ),
983
FT_FRAME_BYTE ( panose[6] ),
984
FT_FRAME_BYTE ( panose[7] ),
985
FT_FRAME_BYTE ( panose[8] ),
986
FT_FRAME_BYTE ( panose[9] ),
987
FT_FRAME_ULONG ( ulUnicodeRange1 ),
988
FT_FRAME_ULONG ( ulUnicodeRange2 ),
989
FT_FRAME_ULONG ( ulUnicodeRange3 ),
990
FT_FRAME_ULONG ( ulUnicodeRange4 ),
991
FT_FRAME_BYTE ( achVendID[0] ),
992
FT_FRAME_BYTE ( achVendID[1] ),
993
FT_FRAME_BYTE ( achVendID[2] ),
994
FT_FRAME_BYTE ( achVendID[3] ),
996
FT_FRAME_USHORT( fsSelection ),
997
FT_FRAME_USHORT( usFirstCharIndex ),
998
FT_FRAME_USHORT( usLastCharIndex ),
999
FT_FRAME_SHORT ( sTypoAscender ),
1000
FT_FRAME_SHORT ( sTypoDescender ),
1001
FT_FRAME_SHORT ( sTypoLineGap ),
1002
FT_FRAME_USHORT( usWinAscent ),
1003
FT_FRAME_USHORT( usWinDescent ),
1007
const FT_Frame_Field os2_fields_extra[] =
1009
FT_FRAME_START( 8 ),
1010
FT_FRAME_ULONG( ulCodePageRange1 ),
1011
FT_FRAME_ULONG( ulCodePageRange2 ),
1015
const FT_Frame_Field os2_fields_extra2[] =
1017
FT_FRAME_START( 10 ),
1018
FT_FRAME_SHORT ( sxHeight ),
1019
FT_FRAME_SHORT ( sCapHeight ),
1020
FT_FRAME_USHORT( usDefaultChar ),
1021
FT_FRAME_USHORT( usBreakChar ),
1022
FT_FRAME_USHORT( usMaxContext ),
1027
/* We now support old Mac fonts where the OS/2 table doesn't */
1028
/* exist. Simply put, we set the `version' field to 0xFFFF */
1029
/* and test this value each time we need to access the table. */
1030
error = face->goto_table( face, TTAG_OS2, stream, 0 );
1036
if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) )
1039
os2->ulCodePageRange1 = 0;
1040
os2->ulCodePageRange2 = 0;
1042
os2->sCapHeight = 0;
1043
os2->usDefaultChar = 0;
1044
os2->usBreakChar = 0;
1045
os2->usMaxContext = 0;
1047
if ( os2->version >= 0x0001 )
1049
/* only version 1 tables */
1050
if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) )
1053
if ( os2->version >= 0x0002 )
1055
/* only version 2 tables */
1056
if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) )
1061
FT_TRACE3(( "sTypoAscender: %4d\n", os2->sTypoAscender ));
1062
FT_TRACE3(( "sTypoDescender: %4d\n", os2->sTypoDescender ));
1063
FT_TRACE3(( "usWinAscent: %4u\n", os2->usWinAscent ));
1064
FT_TRACE3(( "usWinDescent: %4u\n", os2->usWinDescent ));
1065
FT_TRACE3(( "fsSelection: 0x%2x\n", os2->fsSelection ));
1072
/*************************************************************************/
1075
/* tt_face_load_postscript */
1078
/* Loads the Postscript table. */
1081
/* face :: A handle to the target face object. */
1083
/* stream :: A handle to the input stream. */
1086
/* FreeType error code. 0 means success. */
1088
FT_LOCAL_DEF( FT_Error )
1089
tt_face_load_post( TT_Face face,
1093
TT_Postscript* post = &face->postscript;
1095
static const FT_Frame_Field post_fields[] =
1098
#define FT_STRUCTURE TT_Postscript
1100
FT_FRAME_START( 32 ),
1101
FT_FRAME_ULONG( FormatType ),
1102
FT_FRAME_ULONG( italicAngle ),
1103
FT_FRAME_SHORT( underlinePosition ),
1104
FT_FRAME_SHORT( underlineThickness ),
1105
FT_FRAME_ULONG( isFixedPitch ),
1106
FT_FRAME_ULONG( minMemType42 ),
1107
FT_FRAME_ULONG( maxMemType42 ),
1108
FT_FRAME_ULONG( minMemType1 ),
1109
FT_FRAME_ULONG( maxMemType1 ),
1114
error = face->goto_table( face, TTAG_post, stream, 0 );
1118
if ( FT_STREAM_READ_FIELDS( post_fields, post ) )
1121
/* we don't load the glyph names, we do that in another */
1122
/* module (ttpost). */
1124
FT_TRACE3(( "FormatType: 0x%x\n", post->FormatType ));
1125
FT_TRACE3(( "isFixedPitch: %s\n", post->isFixedPitch
1126
? " yes" : " no" ));
1132
/*************************************************************************/
1135
/* tt_face_load_pclt */
1138
/* Loads the PCL 5 Table. */
1141
/* face :: A handle to the target face object. */
1143
/* stream :: A handle to the input stream. */
1146
/* FreeType error code. 0 means success. */
1148
FT_LOCAL_DEF( FT_Error )
1149
tt_face_load_pclt( TT_Face face,
1152
static const FT_Frame_Field pclt_fields[] =
1155
#define FT_STRUCTURE TT_PCLT
1157
FT_FRAME_START( 54 ),
1158
FT_FRAME_ULONG ( Version ),
1159
FT_FRAME_ULONG ( FontNumber ),
1160
FT_FRAME_USHORT( Pitch ),
1161
FT_FRAME_USHORT( xHeight ),
1162
FT_FRAME_USHORT( Style ),
1163
FT_FRAME_USHORT( TypeFamily ),
1164
FT_FRAME_USHORT( CapHeight ),
1165
FT_FRAME_BYTES ( TypeFace, 16 ),
1166
FT_FRAME_BYTES ( CharacterComplement, 8 ),
1167
FT_FRAME_BYTES ( FileName, 6 ),
1168
FT_FRAME_CHAR ( StrokeWeight ),
1169
FT_FRAME_CHAR ( WidthType ),
1170
FT_FRAME_BYTE ( SerifStyle ),
1171
FT_FRAME_BYTE ( Reserved ),
1176
TT_PCLT* pclt = &face->pclt;
1179
/* optional table */
1180
error = face->goto_table( face, TTAG_PCLT, stream, 0 );
1184
if ( FT_STREAM_READ_FIELDS( pclt_fields, pclt ) )
1192
/*************************************************************************/
1195
/* tt_face_load_gasp */
1198
/* Loads the `gasp' table into a face object. */
1201
/* face :: A handle to the target face object. */
1203
/* stream :: The input stream. */
1206
/* FreeType error code. 0 means success. */
1208
FT_LOCAL_DEF( FT_Error )
1209
tt_face_load_gasp( TT_Face face,
1213
FT_Memory memory = stream->memory;
1215
FT_UInt j,num_ranges;
1216
TT_GaspRange gaspranges;
1219
/* the gasp table is optional */
1220
error = face->goto_table( face, TTAG_gasp, stream, 0 );
1224
if ( FT_FRAME_ENTER( 4L ) )
1227
face->gasp.version = FT_GET_USHORT();
1228
face->gasp.numRanges = FT_GET_USHORT();
1232
/* only support versions 0 and 1 of the table */
1233
if ( face->gasp.version >= 2 )
1235
face->gasp.numRanges = 0;
1236
error = SFNT_Err_Invalid_Table;
1240
num_ranges = face->gasp.numRanges;
1241
FT_TRACE3(( "numRanges: %u\n", num_ranges ));
1243
if ( FT_QNEW_ARRAY( gaspranges, num_ranges ) ||
1244
FT_FRAME_ENTER( num_ranges * 4L ) )
1247
face->gasp.gaspRanges = gaspranges;
1249
for ( j = 0; j < num_ranges; j++ )
1251
gaspranges[j].maxPPEM = FT_GET_USHORT();
1252
gaspranges[j].gaspFlag = FT_GET_USHORT();
1254
FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n",
1256
gaspranges[j].maxPPEM,
1257
gaspranges[j].gaspFlag ));