00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <ft2build.h>
00021 #include FT_INTERNAL_DEBUG_H
00022 #include FT_INTERNAL_STREAM_H
00023 #include FT_TRUETYPE_TAGS_H
00024 #include "ttload.h"
00025
00026 #include "sferrors.h"
00027
00028
00029
00030
00031
00032
00033
00034
00035 #undef FT_COMPONENT
00036 #define FT_COMPONENT trace_ttload
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 FT_LOCAL_DEF( TT_Table )
00056 tt_face_lookup_table( TT_Face face,
00057 FT_ULong tag )
00058 {
00059 TT_Table entry;
00060 TT_Table limit;
00061 #ifdef FT_DEBUG_LEVEL_TRACE
00062 FT_Bool zero_length = FALSE;
00063 #endif
00064
00065
00066 FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ",
00067 face,
00068 (FT_Char)( tag >> 24 ),
00069 (FT_Char)( tag >> 16 ),
00070 (FT_Char)( tag >> 8 ),
00071 (FT_Char)( tag ) ));
00072
00073 entry = face->dir_tables;
00074 limit = entry + face->num_tables;
00075
00076 for ( ; entry < limit; entry++ )
00077 {
00078
00079
00080 if ( entry->Tag == tag ) {
00081 if ( entry->Length != 0 )
00082 {
00083 FT_TRACE4(( "found table.\n" ));
00084 return entry;
00085 }
00086 #ifdef FT_DEBUG_LEVEL_TRACE
00087 zero_length = TRUE;
00088 #endif
00089 }
00090 }
00091
00092 #ifdef FT_DEBUG_LEVEL_TRACE
00093 if ( zero_length )
00094 FT_TRACE4(( "ignoring empty table\n" ));
00095 else
00096 FT_TRACE4(( "could not find table\n" ));
00097 #endif
00098
00099 return NULL;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 FT_LOCAL_DEF( FT_Error )
00125 tt_face_goto_table( TT_Face face,
00126 FT_ULong tag,
00127 FT_Stream stream,
00128 FT_ULong* length )
00129 {
00130 TT_Table table;
00131 FT_Error error;
00132
00133
00134 table = tt_face_lookup_table( face, tag );
00135 if ( table )
00136 {
00137 if ( length )
00138 *length = table->Length;
00139
00140 if ( FT_STREAM_SEEK( table->Offset ) )
00141 goto Exit;
00142 }
00143 else
00144 error = SFNT_Err_Table_Missing;
00145
00146 Exit:
00147 return error;
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 static FT_Error
00168 check_table_dir( SFNT_Header sfnt,
00169 FT_Stream stream )
00170 {
00171 FT_Error error;
00172 FT_UShort nn, valid_entries = 0;
00173 FT_UInt has_head = 0, has_sing = 0, has_meta = 0;
00174 FT_ULong offset = sfnt->offset + 12;
00175
00176 static const FT_Frame_Field table_dir_entry_fields[] =
00177 {
00178 #undef FT_STRUCTURE
00179 #define FT_STRUCTURE TT_TableRec
00180
00181 FT_FRAME_START( 16 ),
00182 FT_FRAME_ULONG( Tag ),
00183 FT_FRAME_ULONG( CheckSum ),
00184 FT_FRAME_ULONG( Offset ),
00185 FT_FRAME_ULONG( Length ),
00186 FT_FRAME_END
00187 };
00188
00189
00190 if ( FT_STREAM_SEEK( offset ) )
00191 goto Exit;
00192
00193 for ( nn = 0; nn < sfnt->num_tables; nn++ )
00194 {
00195 TT_TableRec table;
00196
00197
00198 if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )
00199 {
00200 nn--;
00201 FT_TRACE2(( "check_table_dir:"
00202 " can read only %d table%s in font (instead of %d)\n",
00203 nn, nn == 1 ? "" : "s", sfnt->num_tables ));
00204 sfnt->num_tables = nn;
00205 break;
00206 }
00207
00208
00209 if ( table.Offset + table.Length > stream->size )
00210 {
00211 FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
00212 continue;
00213 }
00214 else
00215 valid_entries++;
00216
00217 if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed )
00218 {
00219 FT_UInt32 magic;
00220
00221
00222 #ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
00223 if ( table.Tag == TTAG_head )
00224 #endif
00225 has_head = 1;
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 if ( table.Length < 0x36 )
00237 {
00238 FT_TRACE2(( "check_table_dir: `head' table too small\n" ));
00239 error = SFNT_Err_Table_Missing;
00240 goto Exit;
00241 }
00242
00243 if ( FT_STREAM_SEEK( table.Offset + 12 ) ||
00244 FT_READ_ULONG( magic ) )
00245 goto Exit;
00246
00247 if ( magic != 0x5F0F3CF5UL )
00248 {
00249 FT_TRACE2(( "check_table_dir:"
00250 " no magic number found in `head' table\n"));
00251 error = SFNT_Err_Table_Missing;
00252 goto Exit;
00253 }
00254
00255 if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) )
00256 goto Exit;
00257 }
00258 else if ( table.Tag == TTAG_SING )
00259 has_sing = 1;
00260 else if ( table.Tag == TTAG_META )
00261 has_meta = 1;
00262 }
00263
00264 sfnt->num_tables = valid_entries;
00265
00266 if ( sfnt->num_tables == 0 )
00267 {
00268 FT_TRACE2(( "check_table_dir: no tables found\n" ));
00269 error = SFNT_Err_Unknown_File_Format;
00270 goto Exit;
00271 }
00272
00273
00274 if ( has_head || ( has_sing && has_meta ) )
00275 {
00276 error = SFNT_Err_Ok;
00277 goto Exit;
00278 }
00279 else
00280 {
00281 FT_TRACE2(( "check_table_dir:" ));
00282 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
00283 FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" ));
00284 #else
00285 FT_TRACE2(( " neither `head' nor `sing' table found\n" ));
00286 #endif
00287 error = SFNT_Err_Table_Missing;
00288 }
00289
00290 Exit:
00291 return error;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 FT_LOCAL_DEF( FT_Error )
00318 tt_face_load_font_dir( TT_Face face,
00319 FT_Stream stream )
00320 {
00321 SFNT_HeaderRec sfnt;
00322 FT_Error error;
00323 FT_Memory memory = stream->memory;
00324 TT_TableRec* entry;
00325 FT_Int nn;
00326
00327 static const FT_Frame_Field offset_table_fields[] =
00328 {
00329 #undef FT_STRUCTURE
00330 #define FT_STRUCTURE SFNT_HeaderRec
00331
00332 FT_FRAME_START( 8 ),
00333 FT_FRAME_USHORT( num_tables ),
00334 FT_FRAME_USHORT( search_range ),
00335 FT_FRAME_USHORT( entry_selector ),
00336 FT_FRAME_USHORT( range_shift ),
00337 FT_FRAME_END
00338 };
00339
00340
00341 FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face ));
00342
00343
00344
00345 sfnt.offset = FT_STREAM_POS();
00346
00347 if ( FT_READ_ULONG( sfnt.format_tag ) ||
00348 FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) )
00349 goto Exit;
00350
00351
00352 #if 0
00353 if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 ) ||
00354 sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 )
00355 return SFNT_Err_Unknown_File_Format;
00356 #endif
00357
00358
00359
00360 FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables ));
00361 FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag ));
00362
00363
00364 error = check_table_dir( &sfnt, stream );
00365 if ( error )
00366 {
00367 FT_TRACE2(( "tt_face_load_font_dir:"
00368 " invalid table directory for TrueType\n" ));
00369
00370 goto Exit;
00371 }
00372
00373 face->num_tables = sfnt.num_tables;
00374 face->format_tag = sfnt.format_tag;
00375
00376 if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) )
00377 goto Exit;
00378
00379 if ( FT_STREAM_SEEK( sfnt.offset + 12 ) ||
00380 FT_FRAME_ENTER( face->num_tables * 16L ) )
00381 goto Exit;
00382
00383 entry = face->dir_tables;
00384
00385 for ( nn = 0; nn < sfnt.num_tables; nn++ )
00386 {
00387 entry->Tag = FT_GET_TAG4();
00388 entry->CheckSum = FT_GET_ULONG();
00389 entry->Offset = FT_GET_LONG();
00390 entry->Length = FT_GET_LONG();
00391
00392
00393 if ( entry->Offset + entry->Length > stream->size )
00394 continue;
00395 else
00396 {
00397 FT_TRACE2(( " %c%c%c%c - %08lx - %08lx\n",
00398 (FT_Char)( entry->Tag >> 24 ),
00399 (FT_Char)( entry->Tag >> 16 ),
00400 (FT_Char)( entry->Tag >> 8 ),
00401 (FT_Char)( entry->Tag ),
00402 entry->Offset,
00403 entry->Length ));
00404 entry++;
00405 }
00406 }
00407
00408 FT_FRAME_EXIT();
00409
00410 FT_TRACE2(( "table directory loaded\n\n" ));
00411
00412 Exit:
00413 return error;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 FT_LOCAL_DEF( FT_Error )
00458 tt_face_load_any( TT_Face face,
00459 FT_ULong tag,
00460 FT_Long offset,
00461 FT_Byte* buffer,
00462 FT_ULong* length )
00463 {
00464 FT_Error error;
00465 FT_Stream stream;
00466 TT_Table table;
00467 FT_ULong size;
00468
00469
00470 if ( tag != 0 )
00471 {
00472
00473 table = tt_face_lookup_table( face, tag );
00474 if ( !table )
00475 {
00476 error = SFNT_Err_Table_Missing;
00477 goto Exit;
00478 }
00479
00480 offset += table->Offset;
00481 size = table->Length;
00482 }
00483 else
00484
00485 size = face->root.stream->size;
00486
00487 if ( length && *length == 0 )
00488 {
00489 *length = size;
00490
00491 return SFNT_Err_Ok;
00492 }
00493
00494 if ( length )
00495 size = *length;
00496
00497 stream = face->root.stream;
00498
00499 if ( FT_STREAM_READ_AT( offset, buffer, size ) )
00500 goto Exit;
00501
00502 Exit:
00503 return error;
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 static FT_Error
00524 tt_face_load_generic_header( TT_Face face,
00525 FT_Stream stream,
00526 FT_ULong tag )
00527 {
00528 FT_Error error;
00529 TT_Header* header;
00530
00531 static const FT_Frame_Field header_fields[] =
00532 {
00533 #undef FT_STRUCTURE
00534 #define FT_STRUCTURE TT_Header
00535
00536 FT_FRAME_START( 54 ),
00537 FT_FRAME_ULONG ( Table_Version ),
00538 FT_FRAME_ULONG ( Font_Revision ),
00539 FT_FRAME_LONG ( CheckSum_Adjust ),
00540 FT_FRAME_LONG ( Magic_Number ),
00541 FT_FRAME_USHORT( Flags ),
00542 FT_FRAME_USHORT( Units_Per_EM ),
00543 FT_FRAME_LONG ( Created[0] ),
00544 FT_FRAME_LONG ( Created[1] ),
00545 FT_FRAME_LONG ( Modified[0] ),
00546 FT_FRAME_LONG ( Modified[1] ),
00547 FT_FRAME_SHORT ( xMin ),
00548 FT_FRAME_SHORT ( yMin ),
00549 FT_FRAME_SHORT ( xMax ),
00550 FT_FRAME_SHORT ( yMax ),
00551 FT_FRAME_USHORT( Mac_Style ),
00552 FT_FRAME_USHORT( Lowest_Rec_PPEM ),
00553 FT_FRAME_SHORT ( Font_Direction ),
00554 FT_FRAME_SHORT ( Index_To_Loc_Format ),
00555 FT_FRAME_SHORT ( Glyph_Data_Format ),
00556 FT_FRAME_END
00557 };
00558
00559
00560 error = face->goto_table( face, tag, stream, 0 );
00561 if ( error )
00562 goto Exit;
00563
00564 header = &face->header;
00565
00566 if ( FT_STREAM_READ_FIELDS( header_fields, header ) )
00567 goto Exit;
00568
00569 FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM ));
00570 FT_TRACE3(( "IndexToLoc: %4d\n", header->Index_To_Loc_Format ));
00571
00572 Exit:
00573 return error;
00574 }
00575
00576
00577 FT_LOCAL_DEF( FT_Error )
00578 tt_face_load_head( TT_Face face,
00579 FT_Stream stream )
00580 {
00581 return tt_face_load_generic_header( face, stream, TTAG_head );
00582 }
00583
00584
00585 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
00586
00587 FT_LOCAL_DEF( FT_Error )
00588 tt_face_load_bhed( TT_Face face,
00589 FT_Stream stream )
00590 {
00591 return tt_face_load_generic_header( face, stream, TTAG_bhed );
00592 }
00593
00594 #endif
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 FT_LOCAL_DEF( FT_Error )
00614 tt_face_load_maxp( TT_Face face,
00615 FT_Stream stream )
00616 {
00617 FT_Error error;
00618 TT_MaxProfile* maxProfile = &face->max_profile;
00619
00620 const FT_Frame_Field maxp_fields[] =
00621 {
00622 #undef FT_STRUCTURE
00623 #define FT_STRUCTURE TT_MaxProfile
00624
00625 FT_FRAME_START( 6 ),
00626 FT_FRAME_LONG ( version ),
00627 FT_FRAME_USHORT( numGlyphs ),
00628 FT_FRAME_END
00629 };
00630
00631 const FT_Frame_Field maxp_fields_extra[] =
00632 {
00633 FT_FRAME_START( 26 ),
00634 FT_FRAME_USHORT( maxPoints ),
00635 FT_FRAME_USHORT( maxContours ),
00636 FT_FRAME_USHORT( maxCompositePoints ),
00637 FT_FRAME_USHORT( maxCompositeContours ),
00638 FT_FRAME_USHORT( maxZones ),
00639 FT_FRAME_USHORT( maxTwilightPoints ),
00640 FT_FRAME_USHORT( maxStorage ),
00641 FT_FRAME_USHORT( maxFunctionDefs ),
00642 FT_FRAME_USHORT( maxInstructionDefs ),
00643 FT_FRAME_USHORT( maxStackElements ),
00644 FT_FRAME_USHORT( maxSizeOfInstructions ),
00645 FT_FRAME_USHORT( maxComponentElements ),
00646 FT_FRAME_USHORT( maxComponentDepth ),
00647 FT_FRAME_END
00648 };
00649
00650
00651 error = face->goto_table( face, TTAG_maxp, stream, 0 );
00652 if ( error )
00653 goto Exit;
00654
00655 if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) )
00656 goto Exit;
00657
00658 maxProfile->maxPoints = 0;
00659 maxProfile->maxContours = 0;
00660 maxProfile->maxCompositePoints = 0;
00661 maxProfile->maxCompositeContours = 0;
00662 maxProfile->maxZones = 0;
00663 maxProfile->maxTwilightPoints = 0;
00664 maxProfile->maxStorage = 0;
00665 maxProfile->maxFunctionDefs = 0;
00666 maxProfile->maxInstructionDefs = 0;
00667 maxProfile->maxStackElements = 0;
00668 maxProfile->maxSizeOfInstructions = 0;
00669 maxProfile->maxComponentElements = 0;
00670 maxProfile->maxComponentDepth = 0;
00671
00672 if ( maxProfile->version >= 0x10000L )
00673 {
00674 if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) )
00675 goto Exit;
00676
00677
00678
00679
00680
00681
00682
00683 if ( maxProfile->maxFunctionDefs == 0 )
00684 maxProfile->maxFunctionDefs = 64;
00685
00686
00687 if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) )
00688 {
00689 FT_TRACE0(( "tt_face_load_maxp:"
00690 " too much twilight points in `maxp' table;\n"
00691 " "
00692 " some glyphs might be rendered incorrectly\n" ));
00693
00694 maxProfile->maxTwilightPoints = 0xFFFFU - 4;
00695 }
00696 }
00697
00698 FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs ));
00699
00700 Exit:
00701 return error;
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 FT_LOCAL_DEF( FT_Error )
00722 tt_face_load_name( TT_Face face,
00723 FT_Stream stream )
00724 {
00725 FT_Error error;
00726 FT_Memory memory = stream->memory;
00727 FT_ULong table_pos, table_len;
00728 FT_ULong storage_start, storage_limit;
00729 FT_UInt count;
00730 TT_NameTable table;
00731
00732 static const FT_Frame_Field name_table_fields[] =
00733 {
00734 #undef FT_STRUCTURE
00735 #define FT_STRUCTURE TT_NameTableRec
00736
00737 FT_FRAME_START( 6 ),
00738 FT_FRAME_USHORT( format ),
00739 FT_FRAME_USHORT( numNameRecords ),
00740 FT_FRAME_USHORT( storageOffset ),
00741 FT_FRAME_END
00742 };
00743
00744 static const FT_Frame_Field name_record_fields[] =
00745 {
00746 #undef FT_STRUCTURE
00747 #define FT_STRUCTURE TT_NameEntryRec
00748
00749
00750 FT_FRAME_USHORT( platformID ),
00751 FT_FRAME_USHORT( encodingID ),
00752 FT_FRAME_USHORT( languageID ),
00753 FT_FRAME_USHORT( nameID ),
00754 FT_FRAME_USHORT( stringLength ),
00755 FT_FRAME_USHORT( stringOffset ),
00756 FT_FRAME_END
00757 };
00758
00759
00760 table = &face->name_table;
00761 table->stream = stream;
00762
00763 error = face->goto_table( face, TTAG_name, stream, &table_len );
00764 if ( error )
00765 goto Exit;
00766
00767 table_pos = FT_STREAM_POS();
00768
00769
00770 if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) )
00771 goto Exit;
00772
00773
00774
00775
00776
00777
00778
00779
00780 storage_start = table_pos + 6 + 12*table->numNameRecords;
00781 storage_limit = table_pos + table_len;
00782
00783 if ( storage_start > storage_limit )
00784 {
00785 FT_ERROR(( "tt_face_load_name: invalid `name' table\n" ));
00786 error = SFNT_Err_Name_Table_Missing;
00787 goto Exit;
00788 }
00789
00790
00791 count = table->numNameRecords;
00792 table->numNameRecords = 0;
00793
00794 if ( FT_NEW_ARRAY( table->names, count ) ||
00795 FT_FRAME_ENTER( count * 12 ) )
00796 goto Exit;
00797
00798
00799
00800 {
00801 TT_NameEntryRec* entry = table->names;
00802
00803
00804 for ( ; count > 0; count-- )
00805 {
00806 if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) )
00807 continue;
00808
00809
00810 if ( entry->stringLength == 0 )
00811 continue;
00812
00813
00814 entry->stringOffset += table_pos + table->storageOffset;
00815 if ( entry->stringOffset < storage_start ||
00816 entry->stringOffset + entry->stringLength > storage_limit )
00817 {
00818
00819 entry->stringOffset = 0;
00820 entry->stringLength = 0;
00821 continue;
00822 }
00823
00824 entry++;
00825 }
00826
00827 table->numNameRecords = (FT_UInt)( entry - table->names );
00828 }
00829
00830 FT_FRAME_EXIT();
00831
00832
00833 face->num_names = (FT_UShort) table->numNameRecords;
00834
00835 Exit:
00836 return error;
00837 }
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851 FT_LOCAL_DEF( void )
00852 tt_face_free_name( TT_Face face )
00853 {
00854 FT_Memory memory = face->root.driver->root.memory;
00855 TT_NameTable table = &face->name_table;
00856 TT_NameEntry entry = table->names;
00857 FT_UInt count = table->numNameRecords;
00858
00859
00860 if ( table->names )
00861 {
00862 for ( ; count > 0; count--, entry++ )
00863 {
00864 FT_FREE( entry->string );
00865 entry->stringLength = 0;
00866 }
00867
00868
00869 FT_FREE( table->names );
00870 }
00871
00872 table->numNameRecords = 0;
00873 table->format = 0;
00874 table->storageOffset = 0;
00875 }
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896 FT_LOCAL_DEF( FT_Error )
00897 tt_face_load_cmap( TT_Face face,
00898 FT_Stream stream )
00899 {
00900 FT_Error error;
00901
00902
00903 error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size );
00904 if ( error )
00905 goto Exit;
00906
00907 if ( FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) )
00908 face->cmap_size = 0;
00909
00910 Exit:
00911 return error;
00912 }
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932 FT_LOCAL_DEF( FT_Error )
00933 tt_face_load_os2( TT_Face face,
00934 FT_Stream stream )
00935 {
00936 FT_Error error;
00937 TT_OS2* os2;
00938
00939 const FT_Frame_Field os2_fields[] =
00940 {
00941 #undef FT_STRUCTURE
00942 #define FT_STRUCTURE TT_OS2
00943
00944 FT_FRAME_START( 78 ),
00945 FT_FRAME_USHORT( version ),
00946 FT_FRAME_SHORT ( xAvgCharWidth ),
00947 FT_FRAME_USHORT( usWeightClass ),
00948 FT_FRAME_USHORT( usWidthClass ),
00949 FT_FRAME_SHORT ( fsType ),
00950 FT_FRAME_SHORT ( ySubscriptXSize ),
00951 FT_FRAME_SHORT ( ySubscriptYSize ),
00952 FT_FRAME_SHORT ( ySubscriptXOffset ),
00953 FT_FRAME_SHORT ( ySubscriptYOffset ),
00954 FT_FRAME_SHORT ( ySuperscriptXSize ),
00955 FT_FRAME_SHORT ( ySuperscriptYSize ),
00956 FT_FRAME_SHORT ( ySuperscriptXOffset ),
00957 FT_FRAME_SHORT ( ySuperscriptYOffset ),
00958 FT_FRAME_SHORT ( yStrikeoutSize ),
00959 FT_FRAME_SHORT ( yStrikeoutPosition ),
00960 FT_FRAME_SHORT ( sFamilyClass ),
00961 FT_FRAME_BYTE ( panose[0] ),
00962 FT_FRAME_BYTE ( panose[1] ),
00963 FT_FRAME_BYTE ( panose[2] ),
00964 FT_FRAME_BYTE ( panose[3] ),
00965 FT_FRAME_BYTE ( panose[4] ),
00966 FT_FRAME_BYTE ( panose[5] ),
00967 FT_FRAME_BYTE ( panose[6] ),
00968 FT_FRAME_BYTE ( panose[7] ),
00969 FT_FRAME_BYTE ( panose[8] ),
00970 FT_FRAME_BYTE ( panose[9] ),
00971 FT_FRAME_ULONG ( ulUnicodeRange1 ),
00972 FT_FRAME_ULONG ( ulUnicodeRange2 ),
00973 FT_FRAME_ULONG ( ulUnicodeRange3 ),
00974 FT_FRAME_ULONG ( ulUnicodeRange4 ),
00975 FT_FRAME_BYTE ( achVendID[0] ),
00976 FT_FRAME_BYTE ( achVendID[1] ),
00977 FT_FRAME_BYTE ( achVendID[2] ),
00978 FT_FRAME_BYTE ( achVendID[3] ),
00979
00980 FT_FRAME_USHORT( fsSelection ),
00981 FT_FRAME_USHORT( usFirstCharIndex ),
00982 FT_FRAME_USHORT( usLastCharIndex ),
00983 FT_FRAME_SHORT ( sTypoAscender ),
00984 FT_FRAME_SHORT ( sTypoDescender ),
00985 FT_FRAME_SHORT ( sTypoLineGap ),
00986 FT_FRAME_USHORT( usWinAscent ),
00987 FT_FRAME_USHORT( usWinDescent ),
00988 FT_FRAME_END
00989 };
00990
00991 const FT_Frame_Field os2_fields_extra[] =
00992 {
00993 FT_FRAME_START( 8 ),
00994 FT_FRAME_ULONG( ulCodePageRange1 ),
00995 FT_FRAME_ULONG( ulCodePageRange2 ),
00996 FT_FRAME_END
00997 };
00998
00999 const FT_Frame_Field os2_fields_extra2[] =
01000 {
01001 FT_FRAME_START( 10 ),
01002 FT_FRAME_SHORT ( sxHeight ),
01003 FT_FRAME_SHORT ( sCapHeight ),
01004 FT_FRAME_USHORT( usDefaultChar ),
01005 FT_FRAME_USHORT( usBreakChar ),
01006 FT_FRAME_USHORT( usMaxContext ),
01007 FT_FRAME_END
01008 };
01009
01010
01011
01012
01013
01014 error = face->goto_table( face, TTAG_OS2, stream, 0 );
01015 if ( error )
01016 goto Exit;
01017
01018 os2 = &face->os2;
01019
01020 if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) )
01021 goto Exit;
01022
01023 os2->ulCodePageRange1 = 0;
01024 os2->ulCodePageRange2 = 0;
01025 os2->sxHeight = 0;
01026 os2->sCapHeight = 0;
01027 os2->usDefaultChar = 0;
01028 os2->usBreakChar = 0;
01029 os2->usMaxContext = 0;
01030
01031 if ( os2->version >= 0x0001 )
01032 {
01033
01034 if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) )
01035 goto Exit;
01036
01037 if ( os2->version >= 0x0002 )
01038 {
01039
01040 if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) )
01041 goto Exit;
01042 }
01043 }
01044
01045 FT_TRACE3(( "sTypoAscender: %4d\n", os2->sTypoAscender ));
01046 FT_TRACE3(( "sTypoDescender: %4d\n", os2->sTypoDescender ));
01047 FT_TRACE3(( "usWinAscent: %4u\n", os2->usWinAscent ));
01048 FT_TRACE3(( "usWinDescent: %4u\n", os2->usWinDescent ));
01049 FT_TRACE3(( "fsSelection: 0x%2x\n", os2->fsSelection ));
01050
01051 Exit:
01052 return error;
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072 FT_LOCAL_DEF( FT_Error )
01073 tt_face_load_post( TT_Face face,
01074 FT_Stream stream )
01075 {
01076 FT_Error error;
01077 TT_Postscript* post = &face->postscript;
01078
01079 static const FT_Frame_Field post_fields[] =
01080 {
01081 #undef FT_STRUCTURE
01082 #define FT_STRUCTURE TT_Postscript
01083
01084 FT_FRAME_START( 32 ),
01085 FT_FRAME_ULONG( FormatType ),
01086 FT_FRAME_ULONG( italicAngle ),
01087 FT_FRAME_SHORT( underlinePosition ),
01088 FT_FRAME_SHORT( underlineThickness ),
01089 FT_FRAME_ULONG( isFixedPitch ),
01090 FT_FRAME_ULONG( minMemType42 ),
01091 FT_FRAME_ULONG( maxMemType42 ),
01092 FT_FRAME_ULONG( minMemType1 ),
01093 FT_FRAME_ULONG( maxMemType1 ),
01094 FT_FRAME_END
01095 };
01096
01097
01098 error = face->goto_table( face, TTAG_post, stream, 0 );
01099 if ( error )
01100 return error;
01101
01102 if ( FT_STREAM_READ_FIELDS( post_fields, post ) )
01103 return error;
01104
01105
01106
01107
01108 FT_TRACE3(( "FormatType: 0x%x\n", post->FormatType ));
01109 FT_TRACE3(( "isFixedPitch: %s\n", post->isFixedPitch
01110 ? " yes" : " no" ));
01111
01112 return SFNT_Err_Ok;
01113 }
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132 FT_LOCAL_DEF( FT_Error )
01133 tt_face_load_pclt( TT_Face face,
01134 FT_Stream stream )
01135 {
01136 static const FT_Frame_Field pclt_fields[] =
01137 {
01138 #undef FT_STRUCTURE
01139 #define FT_STRUCTURE TT_PCLT
01140
01141 FT_FRAME_START( 54 ),
01142 FT_FRAME_ULONG ( Version ),
01143 FT_FRAME_ULONG ( FontNumber ),
01144 FT_FRAME_USHORT( Pitch ),
01145 FT_FRAME_USHORT( xHeight ),
01146 FT_FRAME_USHORT( Style ),
01147 FT_FRAME_USHORT( TypeFamily ),
01148 FT_FRAME_USHORT( CapHeight ),
01149 FT_FRAME_BYTES ( TypeFace, 16 ),
01150 FT_FRAME_BYTES ( CharacterComplement, 8 ),
01151 FT_FRAME_BYTES ( FileName, 6 ),
01152 FT_FRAME_CHAR ( StrokeWeight ),
01153 FT_FRAME_CHAR ( WidthType ),
01154 FT_FRAME_BYTE ( SerifStyle ),
01155 FT_FRAME_BYTE ( Reserved ),
01156 FT_FRAME_END
01157 };
01158
01159 FT_Error error;
01160 TT_PCLT* pclt = &face->pclt;
01161
01162
01163
01164 error = face->goto_table( face, TTAG_PCLT, stream, 0 );
01165 if ( error )
01166 goto Exit;
01167
01168 if ( FT_STREAM_READ_FIELDS( pclt_fields, pclt ) )
01169 goto Exit;
01170
01171 Exit:
01172 return error;
01173 }
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192 FT_LOCAL_DEF( FT_Error )
01193 tt_face_load_gasp( TT_Face face,
01194 FT_Stream stream )
01195 {
01196 FT_Error error;
01197 FT_Memory memory = stream->memory;
01198
01199 FT_UInt j,num_ranges;
01200 TT_GaspRange gaspranges;
01201
01202
01203
01204 error = face->goto_table( face, TTAG_gasp, stream, 0 );
01205 if ( error )
01206 goto Exit;
01207
01208 if ( FT_FRAME_ENTER( 4L ) )
01209 goto Exit;
01210
01211 face->gasp.version = FT_GET_USHORT();
01212 face->gasp.numRanges = FT_GET_USHORT();
01213
01214 FT_FRAME_EXIT();
01215
01216
01217 if ( face->gasp.version >= 2 )
01218 {
01219 face->gasp.numRanges = 0;
01220 error = SFNT_Err_Invalid_Table;
01221 goto Exit;
01222 }
01223
01224 num_ranges = face->gasp.numRanges;
01225 FT_TRACE3(( "numRanges: %u\n", num_ranges ));
01226
01227 if ( FT_QNEW_ARRAY( gaspranges, num_ranges ) ||
01228 FT_FRAME_ENTER( num_ranges * 4L ) )
01229 goto Exit;
01230
01231 face->gasp.gaspRanges = gaspranges;
01232
01233 for ( j = 0; j < num_ranges; j++ )
01234 {
01235 gaspranges[j].maxPPEM = FT_GET_USHORT();
01236 gaspranges[j].gaspFlag = FT_GET_USHORT();
01237
01238 FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n",
01239 j,
01240 gaspranges[j].maxPPEM,
01241 gaspranges[j].gaspFlag ));
01242 }
01243
01244 FT_FRAME_EXIT();
01245
01246 Exit:
01247 return error;
01248 }
01249
01250
01251