00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ft2build.h>
00020 #include "sfobjs.h"
00021 #include "ttload.h"
00022 #include "ttcmap.h"
00023 #include "ttkern.h"
00024 #include FT_INTERNAL_SFNT_H
00025 #include FT_INTERNAL_DEBUG_H
00026 #include FT_TRUETYPE_IDS_H
00027 #include FT_TRUETYPE_TAGS_H
00028 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
00029 #include FT_SFNT_NAMES_H
00030 #include "sferrors.h"
00031
00032 #ifdef TT_CONFIG_OPTION_BDF
00033 #include "ttbdf.h"
00034 #endif
00035
00036
00037
00038
00039
00040
00041
00042
00043 #undef FT_COMPONENT
00044 #define FT_COMPONENT trace_sfobjs
00045
00046
00047
00048
00049 static FT_String*
00050 tt_name_entry_ascii_from_utf16( TT_NameEntry entry,
00051 FT_Memory memory )
00052 {
00053 FT_String* string;
00054 FT_UInt len, code, n;
00055 FT_Byte* read = (FT_Byte*)entry->string;
00056 FT_Error error;
00057
00058
00059 len = (FT_UInt)entry->stringLength / 2;
00060
00061 if ( FT_NEW_ARRAY( string, len + 1 ) )
00062 return NULL;
00063
00064 for ( n = 0; n < len; n++ )
00065 {
00066 code = FT_NEXT_USHORT( read );
00067 if ( code < 32 || code > 127 )
00068 code = '?';
00069
00070 string[n] = (char)code;
00071 }
00072
00073 string[len] = 0;
00074
00075 return string;
00076 }
00077
00078
00079
00080 static FT_String*
00081 tt_name_entry_ascii_from_other( TT_NameEntry entry,
00082 FT_Memory memory )
00083 {
00084 FT_String* string;
00085 FT_UInt len, code, n;
00086 FT_Byte* read = (FT_Byte*)entry->string;
00087 FT_Error error;
00088
00089
00090 len = (FT_UInt)entry->stringLength;
00091
00092 if ( FT_NEW_ARRAY( string, len + 1 ) )
00093 return NULL;
00094
00095 for ( n = 0; n < len; n++ )
00096 {
00097 code = *read++;
00098 if ( code < 32 || code > 127 )
00099 code = '?';
00100
00101 string[n] = (char)code;
00102 }
00103
00104 string[len] = 0;
00105
00106 return string;
00107 }
00108
00109
00110 typedef FT_String* (*TT_NameEntry_ConvertFunc)( TT_NameEntry entry,
00111 FT_Memory memory );
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 static FT_Error
00135 tt_face_get_name( TT_Face face,
00136 FT_UShort nameid,
00137 FT_String** name )
00138 {
00139 FT_Memory memory = face->root.memory;
00140 FT_Error error = SFNT_Err_Ok;
00141 FT_String* result = NULL;
00142 FT_UShort n;
00143 TT_NameEntryRec* rec;
00144 FT_Int found_apple = -1;
00145 FT_Int found_apple_roman = -1;
00146 FT_Int found_apple_english = -1;
00147 FT_Int found_win = -1;
00148 FT_Int found_unicode = -1;
00149
00150 FT_Bool is_english = 0;
00151
00152 TT_NameEntry_ConvertFunc convert;
00153
00154
00155 FT_ASSERT( name );
00156
00157 rec = face->name_table.names;
00158 for ( n = 0; n < face->num_names; n++, rec++ )
00159 {
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 if ( rec->nameID == nameid && rec->stringLength > 0 )
00170 {
00171 switch ( rec->platformID )
00172 {
00173 case TT_PLATFORM_APPLE_UNICODE:
00174 case TT_PLATFORM_ISO:
00175
00176
00177
00178
00179 found_unicode = n;
00180 break;
00181
00182 case TT_PLATFORM_MACINTOSH:
00183
00184
00185
00186
00187 if ( rec->languageID == TT_MAC_LANGID_ENGLISH )
00188 found_apple_english = n;
00189 else if ( rec->encodingID == TT_MAC_ID_ROMAN )
00190 found_apple_roman = n;
00191 break;
00192
00193 case TT_PLATFORM_MICROSOFT:
00194
00195
00196
00197 if ( found_win == -1 || ( rec->languageID & 0x3FF ) == 0x009 )
00198 {
00199 switch ( rec->encodingID )
00200 {
00201 case TT_MS_ID_SYMBOL_CS:
00202 case TT_MS_ID_UNICODE_CS:
00203 case TT_MS_ID_UCS_4:
00204 is_english = FT_BOOL( ( rec->languageID & 0x3FF ) == 0x009 );
00205 found_win = n;
00206 break;
00207
00208 default:
00209 ;
00210 }
00211 }
00212 break;
00213
00214 default:
00215 ;
00216 }
00217 }
00218 }
00219
00220 found_apple = found_apple_roman;
00221 if ( found_apple_english >= 0 )
00222 found_apple = found_apple_english;
00223
00224
00225
00226
00227
00228 convert = NULL;
00229 if ( found_win >= 0 && !( found_apple >= 0 && !is_english ) )
00230 {
00231 rec = face->name_table.names + found_win;
00232 switch ( rec->encodingID )
00233 {
00234
00235 case TT_MS_ID_UNICODE_CS:
00236 case TT_MS_ID_SYMBOL_CS:
00237 convert = tt_name_entry_ascii_from_utf16;
00238 break;
00239
00240 case TT_MS_ID_UCS_4:
00241
00242
00243
00244
00245
00246 convert = tt_name_entry_ascii_from_utf16;
00247 break;
00248
00249 default:
00250 ;
00251 }
00252 }
00253 else if ( found_apple >= 0 )
00254 {
00255 rec = face->name_table.names + found_apple;
00256 convert = tt_name_entry_ascii_from_other;
00257 }
00258 else if ( found_unicode >= 0 )
00259 {
00260 rec = face->name_table.names + found_unicode;
00261 convert = tt_name_entry_ascii_from_utf16;
00262 }
00263
00264 if ( rec && convert )
00265 {
00266 if ( rec->string == NULL )
00267 {
00268 FT_Stream stream = face->name_table.stream;
00269
00270
00271 if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) ||
00272 FT_STREAM_SEEK( rec->stringOffset ) ||
00273 FT_STREAM_READ( rec->string, rec->stringLength ) )
00274 {
00275 FT_FREE( rec->string );
00276 rec->stringLength = 0;
00277 result = NULL;
00278 goto Exit;
00279 }
00280 }
00281
00282 result = convert( rec, memory );
00283 }
00284
00285 Exit:
00286 *name = result;
00287 return error;
00288 }
00289
00290
00291 static FT_Encoding
00292 sfnt_find_encoding( int platform_id,
00293 int encoding_id )
00294 {
00295 typedef struct TEncoding_
00296 {
00297 int platform_id;
00298 int encoding_id;
00299 FT_Encoding encoding;
00300
00301 } TEncoding;
00302
00303 static
00304 const TEncoding tt_encodings[] =
00305 {
00306 { TT_PLATFORM_ISO, -1, FT_ENCODING_UNICODE },
00307
00308 { TT_PLATFORM_APPLE_UNICODE, -1, FT_ENCODING_UNICODE },
00309
00310 { TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, FT_ENCODING_APPLE_ROMAN },
00311
00312 { TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, FT_ENCODING_MS_SYMBOL },
00313 { TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, FT_ENCODING_UNICODE },
00314 { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE },
00315 { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, FT_ENCODING_SJIS },
00316 { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, FT_ENCODING_GB2312 },
00317 { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, FT_ENCODING_BIG5 },
00318 { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, FT_ENCODING_WANSUNG },
00319 { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, FT_ENCODING_JOHAB }
00320 };
00321
00322 const TEncoding *cur, *limit;
00323
00324
00325 cur = tt_encodings;
00326 limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] );
00327
00328 for ( ; cur < limit; cur++ )
00329 {
00330 if ( cur->platform_id == platform_id )
00331 {
00332 if ( cur->encoding_id == encoding_id ||
00333 cur->encoding_id == -1 )
00334 return cur->encoding;
00335 }
00336 }
00337
00338 return FT_ENCODING_NONE;
00339 }
00340
00341
00342
00343
00344 static FT_Error
00345 sfnt_open_font( FT_Stream stream,
00346 TT_Face face )
00347 {
00348 FT_Memory memory = stream->memory;
00349 FT_Error error;
00350 FT_ULong tag, offset;
00351
00352 static const FT_Frame_Field ttc_header_fields[] =
00353 {
00354 #undef FT_STRUCTURE
00355 #define FT_STRUCTURE TTC_HeaderRec
00356
00357 FT_FRAME_START( 8 ),
00358 FT_FRAME_LONG( version ),
00359 FT_FRAME_LONG( count ),
00360 FT_FRAME_END
00361 };
00362
00363
00364 face->ttc_header.tag = 0;
00365 face->ttc_header.version = 0;
00366 face->ttc_header.count = 0;
00367
00368 offset = FT_STREAM_POS();
00369
00370 if ( FT_READ_ULONG( tag ) )
00371 return error;
00372
00373 if ( tag != 0x00010000UL &&
00374 tag != TTAG_ttcf &&
00375 tag != TTAG_OTTO &&
00376 tag != TTAG_true &&
00377 tag != TTAG_typ1 &&
00378 tag != 0x00020000UL )
00379 return SFNT_Err_Unknown_File_Format;
00380
00381 face->ttc_header.tag = TTAG_ttcf;
00382
00383 if ( tag == TTAG_ttcf )
00384 {
00385 FT_Int n;
00386
00387
00388 FT_TRACE3(( "sfnt_open_font: file is a collection\n" ));
00389
00390 if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
00391 return error;
00392
00393
00394 if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
00395 return error;
00396
00397 if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )
00398 return error;
00399
00400 for ( n = 0; n < face->ttc_header.count; n++ )
00401 face->ttc_header.offsets[n] = FT_GET_ULONG();
00402
00403 FT_FRAME_EXIT();
00404 }
00405 else
00406 {
00407 FT_TRACE3(( "sfnt_open_font: synthesize TTC\n" ));
00408
00409 face->ttc_header.version = 1 << 16;
00410 face->ttc_header.count = 1;
00411
00412 if ( FT_NEW( face->ttc_header.offsets ) )
00413 return error;
00414
00415 face->ttc_header.offsets[0] = offset;
00416 }
00417
00418 return error;
00419 }
00420
00421
00422 FT_LOCAL_DEF( FT_Error )
00423 sfnt_init_face( FT_Stream stream,
00424 TT_Face face,
00425 FT_Int face_index,
00426 FT_Int num_params,
00427 FT_Parameter* params )
00428 {
00429 FT_Error error;
00430 FT_Library library = face->root.driver->root.library;
00431 SFNT_Service sfnt;
00432
00433
00434
00435 FT_UNUSED( num_params );
00436 FT_UNUSED( params );
00437
00438
00439 sfnt = (SFNT_Service)face->sfnt;
00440 if ( !sfnt )
00441 {
00442 sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
00443 if ( !sfnt )
00444 return SFNT_Err_Invalid_File_Format;
00445
00446 face->sfnt = sfnt;
00447 face->goto_table = sfnt->goto_table;
00448 }
00449
00450 FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );
00451
00452 error = sfnt_open_font( stream, face );
00453 if ( error )
00454 return error;
00455
00456 FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index ));
00457
00458 if ( face_index < 0 )
00459 face_index = 0;
00460
00461 if ( face_index >= face->ttc_header.count )
00462 return SFNT_Err_Invalid_Argument;
00463
00464 if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
00465 return error;
00466
00467
00468 error = sfnt->load_font_dir( face, stream );
00469 if ( error )
00470 return error;
00471
00472 face->root.num_faces = face->ttc_header.count;
00473 face->root.face_index = face_index;
00474
00475 return error;
00476 }
00477
00478
00479 #define LOAD_( x ) \
00480 do { \
00481 FT_TRACE2(( "`" #x "' " )); \
00482 FT_TRACE3(( "-->\n" )); \
00483 \
00484 error = sfnt->load_##x( face, stream ); \
00485 \
00486 FT_TRACE2(( "%s\n", ( !error ) \
00487 ? "loaded" \
00488 : ( error == SFNT_Err_Table_Missing ) \
00489 ? "missing" \
00490 : "failed to load" )); \
00491 FT_TRACE3(( "\n" )); \
00492 } while ( 0 )
00493
00494 #define LOADM_( x, vertical ) \
00495 do { \
00496 FT_TRACE2(( "`%s" #x "' ", \
00497 vertical ? "vertical " : "" )); \
00498 FT_TRACE3(( "-->\n" )); \
00499 \
00500 error = sfnt->load_##x( face, stream, vertical ); \
00501 \
00502 FT_TRACE2(( "%s\n", ( !error ) \
00503 ? "loaded" \
00504 : ( error == SFNT_Err_Table_Missing ) \
00505 ? "missing" \
00506 : "failed to load" )); \
00507 FT_TRACE3(( "\n" )); \
00508 } while ( 0 )
00509
00510 #define GET_NAME( id, field ) \
00511 do { \
00512 error = tt_face_get_name( face, TT_NAME_ID_##id, field ); \
00513 if ( error ) \
00514 goto Exit; \
00515 } while ( 0 )
00516
00517
00518 FT_LOCAL_DEF( FT_Error )
00519 sfnt_load_face( FT_Stream stream,
00520 TT_Face face,
00521 FT_Int face_index,
00522 FT_Int num_params,
00523 FT_Parameter* params )
00524 {
00525 FT_Error error;
00526 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
00527 FT_Error psnames_error;
00528 #endif
00529 FT_Bool has_outline;
00530 FT_Bool is_apple_sbit;
00531 FT_Bool ignore_preferred_family = FALSE;
00532 FT_Bool ignore_preferred_subfamily = FALSE;
00533
00534 SFNT_Service sfnt = (SFNT_Service)face->sfnt;
00535
00536 FT_UNUSED( face_index );
00537
00538
00539
00540 {
00541 FT_Int i;
00542
00543
00544 for ( i = 0; i < num_params; i++ )
00545 {
00546 if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY )
00547 ignore_preferred_family = TRUE;
00548 else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY )
00549 ignore_preferred_subfamily = TRUE;
00550 }
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 FT_TRACE2(( "sfnt_load_face: %08p\n\n", face ));
00571
00572
00573 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00574 has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 ||
00575 tt_face_lookup_table( face, TTAG_glyf ) != 0 ||
00576 tt_face_lookup_table( face, TTAG_CFF ) != 0 );
00577 #else
00578 has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 ||
00579 tt_face_lookup_table( face, TTAG_CFF ) != 0 );
00580 #endif
00581
00582 is_apple_sbit = 0;
00583
00584
00585
00586 if ( !has_outline && sfnt->load_bhed )
00587 {
00588 LOAD_( bhed );
00589 is_apple_sbit = FT_BOOL( !error );
00590 }
00591
00592
00593
00594 if ( !is_apple_sbit )
00595 {
00596 LOAD_( head );
00597 if ( error )
00598 goto Exit;
00599 }
00600
00601 if ( face->header.Units_Per_EM == 0 )
00602 {
00603 error = SFNT_Err_Invalid_Table;
00604
00605 goto Exit;
00606 }
00607
00608
00609
00610 LOAD_( maxp );
00611 LOAD_( cmap );
00612
00613
00614
00615 LOAD_( name );
00616 LOAD_( post );
00617
00618 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
00619 psnames_error = error;
00620 #endif
00621
00622
00623
00624 if ( !is_apple_sbit )
00625 {
00626
00627 LOADM_( hhea, 0 );
00628 if ( !error )
00629 {
00630 LOADM_( hmtx, 0 );
00631 if ( error == SFNT_Err_Table_Missing )
00632 {
00633 error = SFNT_Err_Hmtx_Table_Missing;
00634
00635 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00636
00637
00638 if ( face->root.internal->incremental_interface &&
00639 face->root.internal->incremental_interface->funcs->
00640 get_glyph_metrics )
00641 {
00642 face->horizontal.number_Of_HMetrics = 0;
00643 error = SFNT_Err_Ok;
00644 }
00645 #endif
00646 }
00647 }
00648 else if ( error == SFNT_Err_Table_Missing )
00649 {
00650
00651 if ( face->format_tag == TTAG_true )
00652 {
00653 FT_TRACE2(( "This is an SFNT Mac font.\n" ));
00654 has_outline = 0;
00655 error = SFNT_Err_Ok;
00656 }
00657 else
00658 {
00659 error = SFNT_Err_Horiz_Header_Missing;
00660
00661 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00662
00663
00664 if ( face->root.internal->incremental_interface &&
00665 face->root.internal->incremental_interface->funcs->
00666 get_glyph_metrics )
00667 {
00668 face->horizontal.number_Of_HMetrics = 0;
00669 error = SFNT_Err_Ok;
00670 }
00671 #endif
00672
00673 }
00674 }
00675
00676 if ( error )
00677 goto Exit;
00678
00679
00680 LOADM_( hhea, 1 );
00681 if ( !error )
00682 {
00683 LOADM_( hmtx, 1 );
00684 if ( !error )
00685 face->vertical_info = 1;
00686 }
00687
00688 if ( error && error != SFNT_Err_Table_Missing )
00689 goto Exit;
00690
00691 LOAD_( os2 );
00692 if ( error )
00693 {
00694 if ( error != SFNT_Err_Table_Missing )
00695 goto Exit;
00696
00697 face->os2.version = 0xFFFFU;
00698 }
00699 }
00700
00701
00702
00703
00704 if ( sfnt->load_eblc )
00705 {
00706 LOAD_( eblc );
00707 if ( error )
00708 {
00709
00710
00711
00712 if ( error == SFNT_Err_Table_Missing )
00713 error = SFNT_Err_Ok;
00714 else
00715 goto Exit;
00716 }
00717 }
00718
00719 LOAD_( pclt );
00720 if ( error )
00721 {
00722 if ( error != SFNT_Err_Table_Missing )
00723 goto Exit;
00724
00725 face->pclt.Version = 0;
00726 }
00727
00728
00729 LOAD_( gasp );
00730 LOAD_( kern );
00731
00732 face->root.num_glyphs = face->max_profile.numGlyphs;
00733
00734
00735
00736
00737
00738
00739
00740 face->root.family_name = NULL;
00741 face->root.style_name = NULL;
00742 if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 )
00743 {
00744 if ( !ignore_preferred_family )
00745 GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
00746 if ( !face->root.family_name )
00747 GET_NAME( FONT_FAMILY, &face->root.family_name );
00748
00749 if ( !ignore_preferred_subfamily )
00750 GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
00751 if ( !face->root.style_name )
00752 GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
00753 }
00754 else
00755 {
00756 GET_NAME( WWS_FAMILY, &face->root.family_name );
00757 if ( !face->root.family_name && !ignore_preferred_family )
00758 GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
00759 if ( !face->root.family_name )
00760 GET_NAME( FONT_FAMILY, &face->root.family_name );
00761
00762 GET_NAME( WWS_SUBFAMILY, &face->root.style_name );
00763 if ( !face->root.style_name && !ignore_preferred_subfamily )
00764 GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
00765 if ( !face->root.style_name )
00766 GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
00767 }
00768
00769
00770 {
00771 FT_Face root = &face->root;
00772 FT_Long flags = root->face_flags;
00773
00774
00775
00776
00777
00778
00779 if ( has_outline == TRUE )
00780 flags |= FT_FACE_FLAG_SCALABLE;
00781
00782
00783
00784 flags |= FT_FACE_FLAG_SFNT |
00785 FT_FACE_FLAG_HORIZONTAL;
00786
00787 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
00788 if ( psnames_error == SFNT_Err_Ok &&
00789 face->postscript.FormatType != 0x00030000L )
00790 flags |= FT_FACE_FLAG_GLYPH_NAMES;
00791 #endif
00792
00793
00794 if ( face->postscript.isFixedPitch )
00795 flags |= FT_FACE_FLAG_FIXED_WIDTH;
00796
00797
00798 if ( face->vertical_info )
00799 flags |= FT_FACE_FLAG_VERTICAL;
00800
00801
00802 if ( TT_FACE_HAS_KERNING( face ) )
00803 flags |= FT_FACE_FLAG_KERNING;
00804
00805 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
00806
00807
00808 if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 &&
00809 tt_face_lookup_table( face, TTAG_fvar ) != 0 &&
00810 tt_face_lookup_table( face, TTAG_gvar ) != 0 )
00811 flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
00812 #endif
00813
00814 root->face_flags = flags;
00815
00816
00817
00818
00819
00820
00821 flags = 0;
00822 if ( has_outline == TRUE && face->os2.version != 0xFFFFU )
00823 {
00824
00825
00826
00827
00828 if ( face->os2.fsSelection & 512 )
00829 flags |= FT_STYLE_FLAG_ITALIC;
00830 else if ( face->os2.fsSelection & 1 )
00831 flags |= FT_STYLE_FLAG_ITALIC;
00832
00833 if ( face->os2.fsSelection & 32 )
00834 flags |= FT_STYLE_FLAG_BOLD;
00835 }
00836 else
00837 {
00838
00839
00840 if ( face->header.Mac_Style & 1 )
00841 flags |= FT_STYLE_FLAG_BOLD;
00842
00843 if ( face->header.Mac_Style & 2 )
00844 flags |= FT_STYLE_FLAG_ITALIC;
00845 }
00846
00847 root->style_flags = flags;
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857 tt_face_build_cmaps( face );
00858
00859
00860
00861 {
00862 FT_Int m;
00863
00864
00865 for ( m = 0; m < root->num_charmaps; m++ )
00866 {
00867 FT_CharMap charmap = root->charmaps[m];
00868
00869
00870 charmap->encoding = sfnt_find_encoding( charmap->platform_id,
00871 charmap->encoding_id );
00872
00873 #if 0
00874 if ( root->charmap == NULL &&
00875 charmap->encoding == FT_ENCODING_UNICODE )
00876 {
00877
00878 root->charmap = charmap;
00879 }
00880 #endif
00881 }
00882 }
00883
00884 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
00885
00886
00887
00888
00889
00890
00891 {
00892 FT_UInt i, count;
00893
00894
00895 #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
00896 count = face->sbit_num_strikes;
00897 #else
00898 count = (FT_UInt)face->num_sbit_strikes;
00899 #endif
00900
00901 if ( count > 0 )
00902 {
00903 FT_Memory memory = face->root.stream->memory;
00904 FT_UShort em_size = face->header.Units_Per_EM;
00905 FT_Short avgwidth = face->os2.xAvgCharWidth;
00906 FT_Size_Metrics metrics;
00907
00908
00909 if ( em_size == 0 || face->os2.version == 0xFFFFU )
00910 {
00911 avgwidth = 0;
00912 em_size = 1;
00913 }
00914
00915 if ( FT_NEW_ARRAY( root->available_sizes, count ) )
00916 goto Exit;
00917
00918 for ( i = 0; i < count; i++ )
00919 {
00920 FT_Bitmap_Size* bsize = root->available_sizes + i;
00921
00922
00923 error = sfnt->load_strike_metrics( face, i, &metrics );
00924 if ( error )
00925 goto Exit;
00926
00927 bsize->height = (FT_Short)( metrics.height >> 6 );
00928 bsize->width = (FT_Short)(
00929 ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size );
00930
00931 bsize->x_ppem = metrics.x_ppem << 6;
00932 bsize->y_ppem = metrics.y_ppem << 6;
00933
00934
00935 bsize->size = metrics.y_ppem << 6;
00936 }
00937
00938 root->face_flags |= FT_FACE_FLAG_FIXED_SIZES;
00939 root->num_fixed_sizes = (FT_Int)count;
00940 }
00941 }
00942
00943 #endif
00944
00945
00946
00947 if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) )
00948 root->face_flags |= FT_FACE_FLAG_SCALABLE;
00949
00950
00951
00952
00953
00954
00955 if ( FT_IS_SCALABLE( root ) )
00956 {
00957
00958
00959 root->bbox.xMin = face->header.xMin;
00960 root->bbox.yMin = face->header.yMin;
00961 root->bbox.xMax = face->header.xMax;
00962 root->bbox.yMax = face->header.yMax;
00963 root->units_per_EM = face->header.Units_Per_EM;
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997 root->ascender = face->horizontal.Ascender;
00998 root->descender = face->horizontal.Descender;
00999
01000 root->height = (FT_Short)( root->ascender - root->descender +
01001 face->horizontal.Line_Gap );
01002
01003 #if 0
01004
01005
01006 if ( face->horizontal.Line_Gap == 0 )
01007 root->height = (FT_Short)( ( root->height * 115 + 50 ) / 100 );
01008 #endif
01009
01010 #if 0
01011
01012
01013 if ( face->os2.version != 0xFFFFU && root->ascender )
01014 {
01015 FT_Int height;
01016
01017
01018 root->ascender = face->os2.sTypoAscender;
01019 root->descender = -face->os2.sTypoDescender;
01020
01021 height = root->ascender + root->descender + face->os2.sTypoLineGap;
01022 if ( height > root->height )
01023 root->height = height;
01024 }
01025 #endif
01026
01027 root->max_advance_width = face->horizontal.advance_Width_Max;
01028 root->max_advance_height = (FT_Short)( face->vertical_info
01029 ? face->vertical.advance_Height_Max
01030 : root->height );
01031
01032
01033
01034
01035 root->underline_position = face->postscript.underlinePosition -
01036 face->postscript.underlineThickness / 2;
01037 root->underline_thickness = face->postscript.underlineThickness;
01038 }
01039
01040 }
01041
01042 Exit:
01043 FT_TRACE2(( "sfnt_load_face: done\n" ));
01044
01045 return error;
01046 }
01047
01048
01049 #undef LOAD_
01050 #undef LOADM_
01051 #undef GET_NAME
01052
01053
01054 FT_LOCAL_DEF( void )
01055 sfnt_done_face( TT_Face face )
01056 {
01057 FT_Memory memory;
01058 SFNT_Service sfnt;
01059
01060
01061 if ( !face )
01062 return;
01063
01064 memory = face->root.memory;
01065 sfnt = (SFNT_Service)face->sfnt;
01066
01067 if ( sfnt )
01068 {
01069
01070 if ( sfnt->free_psnames )
01071 sfnt->free_psnames( face );
01072
01073
01074 if ( sfnt->free_eblc )
01075 sfnt->free_eblc( face );
01076 }
01077
01078 #ifdef TT_CONFIG_OPTION_BDF
01079
01080 tt_face_free_bdf_props( face );
01081 #endif
01082
01083
01084 tt_face_done_kern( face );
01085
01086
01087 FT_FREE( face->ttc_header.offsets );
01088 face->ttc_header.count = 0;
01089
01090
01091 FT_FREE( face->dir_tables );
01092 face->num_tables = 0;
01093
01094 {
01095 FT_Stream stream = FT_FACE_STREAM( face );
01096
01097
01098
01099 FT_FRAME_RELEASE( face->cmap_table );
01100 face->cmap_size = 0;
01101 }
01102
01103
01104 #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
01105 {
01106 FT_Stream stream = FT_FACE_STREAM( face );
01107
01108
01109 FT_FRAME_RELEASE( face->horz_metrics );
01110 FT_FRAME_RELEASE( face->vert_metrics );
01111 face->horz_metrics_size = 0;
01112 face->vert_metrics_size = 0;
01113 }
01114 #else
01115 FT_FREE( face->horizontal.long_metrics );
01116 FT_FREE( face->horizontal.short_metrics );
01117 #endif
01118
01119
01120 if ( face->vertical_info )
01121 {
01122 FT_FREE( face->vertical.long_metrics );
01123 FT_FREE( face->vertical.short_metrics );
01124 face->vertical_info = 0;
01125 }
01126
01127
01128 FT_FREE( face->gasp.gaspRanges );
01129 face->gasp.numRanges = 0;
01130
01131
01132 if ( sfnt )
01133 sfnt->free_name( face );
01134
01135
01136 FT_FREE( face->root.family_name );
01137 FT_FREE( face->root.style_name );
01138
01139
01140 FT_FREE( face->root.available_sizes );
01141 face->root.num_fixed_sizes = 0;
01142
01143 FT_FREE( face->postscript_name );
01144
01145 face->sfnt = 0;
01146 }
01147
01148
01149