1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* sfobjs.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* SFNT object management (base). */ 6*37da2899SCharles.Forsyth /* */ 7*37da2899SCharles.Forsyth /* Copyright 1996-2001, 2002 by */ 8*37da2899SCharles.Forsyth /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9*37da2899SCharles.Forsyth /* */ 10*37da2899SCharles.Forsyth /* This file is part of the FreeType project, and may only be used, */ 11*37da2899SCharles.Forsyth /* modified, and distributed under the terms of the FreeType project */ 12*37da2899SCharles.Forsyth /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13*37da2899SCharles.Forsyth /* this file you indicate that you have read the license and */ 14*37da2899SCharles.Forsyth /* understand and accept it fully. */ 15*37da2899SCharles.Forsyth /* */ 16*37da2899SCharles.Forsyth /***************************************************************************/ 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsyth 19*37da2899SCharles.Forsyth #include <ft2build.h> 20*37da2899SCharles.Forsyth #include "sfobjs.h" 21*37da2899SCharles.Forsyth #include "ttload.h" 22*37da2899SCharles.Forsyth #include "ttcmap0.h" 23*37da2899SCharles.Forsyth #include FT_INTERNAL_SFNT_H 24*37da2899SCharles.Forsyth #include FT_INTERNAL_POSTSCRIPT_NAMES_H 25*37da2899SCharles.Forsyth #include FT_TRUETYPE_IDS_H 26*37da2899SCharles.Forsyth #include FT_TRUETYPE_TAGS_H 27*37da2899SCharles.Forsyth 28*37da2899SCharles.Forsyth #include "sferrors.h" 29*37da2899SCharles.Forsyth 30*37da2899SCharles.Forsyth 31*37da2899SCharles.Forsyth /*************************************************************************/ 32*37da2899SCharles.Forsyth /* */ 33*37da2899SCharles.Forsyth /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 34*37da2899SCharles.Forsyth /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 35*37da2899SCharles.Forsyth /* messages during execution. */ 36*37da2899SCharles.Forsyth /* */ 37*37da2899SCharles.Forsyth #undef FT_COMPONENT 38*37da2899SCharles.Forsyth #define FT_COMPONENT trace_sfobjs 39*37da2899SCharles.Forsyth 40*37da2899SCharles.Forsyth 41*37da2899SCharles.Forsyth 42*37da2899SCharles.Forsyth /* convert a UTF-16 name entry to ASCII */ 43*37da2899SCharles.Forsyth static FT_String* tt_name_entry_ascii_from_utf16(TT_NameEntry entry,FT_Memory memory)44*37da2899SCharles.Forsyth tt_name_entry_ascii_from_utf16( TT_NameEntry entry, 45*37da2899SCharles.Forsyth FT_Memory memory ) 46*37da2899SCharles.Forsyth { 47*37da2899SCharles.Forsyth FT_String* string; 48*37da2899SCharles.Forsyth FT_UInt len, code, n; 49*37da2899SCharles.Forsyth FT_Byte* read = (FT_Byte*)entry->string; 50*37da2899SCharles.Forsyth 51*37da2899SCharles.Forsyth 52*37da2899SCharles.Forsyth len = (FT_UInt)entry->stringLength / 2; 53*37da2899SCharles.Forsyth 54*37da2899SCharles.Forsyth if ( FT_MEM_NEW_ARRAY( string, len + 1 ) ) 55*37da2899SCharles.Forsyth return NULL; 56*37da2899SCharles.Forsyth 57*37da2899SCharles.Forsyth for ( n = 0; n < len; n++ ) 58*37da2899SCharles.Forsyth { 59*37da2899SCharles.Forsyth code = FT_NEXT_USHORT( read ); 60*37da2899SCharles.Forsyth if ( code < 32 || code > 127 ) 61*37da2899SCharles.Forsyth code = '?'; 62*37da2899SCharles.Forsyth 63*37da2899SCharles.Forsyth string[n] = (char)code; 64*37da2899SCharles.Forsyth } 65*37da2899SCharles.Forsyth 66*37da2899SCharles.Forsyth string[len] = 0; 67*37da2899SCharles.Forsyth 68*37da2899SCharles.Forsyth return string; 69*37da2899SCharles.Forsyth } 70*37da2899SCharles.Forsyth 71*37da2899SCharles.Forsyth 72*37da2899SCharles.Forsyth /* convert a UCS-4 name entry to ASCII */ 73*37da2899SCharles.Forsyth static FT_String* tt_name_entry_ascii_from_ucs4(TT_NameEntry entry,FT_Memory memory)74*37da2899SCharles.Forsyth tt_name_entry_ascii_from_ucs4( TT_NameEntry entry, 75*37da2899SCharles.Forsyth FT_Memory memory ) 76*37da2899SCharles.Forsyth { 77*37da2899SCharles.Forsyth FT_String* string; 78*37da2899SCharles.Forsyth FT_UInt len, code, n; 79*37da2899SCharles.Forsyth FT_Byte* read = (FT_Byte*)entry->string; 80*37da2899SCharles.Forsyth 81*37da2899SCharles.Forsyth 82*37da2899SCharles.Forsyth len = (FT_UInt)entry->stringLength / 4; 83*37da2899SCharles.Forsyth 84*37da2899SCharles.Forsyth if ( FT_MEM_NEW_ARRAY( string, len + 1 ) ) 85*37da2899SCharles.Forsyth return NULL; 86*37da2899SCharles.Forsyth 87*37da2899SCharles.Forsyth for ( n = 0; n < len; n++ ) 88*37da2899SCharles.Forsyth { 89*37da2899SCharles.Forsyth code = (FT_UInt)FT_NEXT_ULONG( read ); 90*37da2899SCharles.Forsyth if ( code < 32 || code > 127 ) 91*37da2899SCharles.Forsyth code = '?'; 92*37da2899SCharles.Forsyth 93*37da2899SCharles.Forsyth string[n] = (char)code; 94*37da2899SCharles.Forsyth } 95*37da2899SCharles.Forsyth 96*37da2899SCharles.Forsyth string[len] = 0; 97*37da2899SCharles.Forsyth 98*37da2899SCharles.Forsyth return string; 99*37da2899SCharles.Forsyth } 100*37da2899SCharles.Forsyth 101*37da2899SCharles.Forsyth 102*37da2899SCharles.Forsyth /* convert an Apple Roman or symbol name entry to ASCII */ 103*37da2899SCharles.Forsyth static FT_String* tt_name_entry_ascii_from_other(TT_NameEntry entry,FT_Memory memory)104*37da2899SCharles.Forsyth tt_name_entry_ascii_from_other( TT_NameEntry entry, 105*37da2899SCharles.Forsyth FT_Memory memory ) 106*37da2899SCharles.Forsyth { 107*37da2899SCharles.Forsyth FT_String* string; 108*37da2899SCharles.Forsyth FT_UInt len, code, n; 109*37da2899SCharles.Forsyth FT_Byte* read = (FT_Byte*)entry->string; 110*37da2899SCharles.Forsyth 111*37da2899SCharles.Forsyth 112*37da2899SCharles.Forsyth len = (FT_UInt)entry->stringLength; 113*37da2899SCharles.Forsyth 114*37da2899SCharles.Forsyth if ( FT_MEM_NEW_ARRAY( string, len + 1 ) ) 115*37da2899SCharles.Forsyth return NULL; 116*37da2899SCharles.Forsyth 117*37da2899SCharles.Forsyth for ( n = 0; n < len; n++ ) 118*37da2899SCharles.Forsyth { 119*37da2899SCharles.Forsyth code = *read++; 120*37da2899SCharles.Forsyth if ( code < 32 || code > 127 ) 121*37da2899SCharles.Forsyth code = '?'; 122*37da2899SCharles.Forsyth 123*37da2899SCharles.Forsyth string[n] = (char)code; 124*37da2899SCharles.Forsyth } 125*37da2899SCharles.Forsyth 126*37da2899SCharles.Forsyth string[len] = 0; 127*37da2899SCharles.Forsyth 128*37da2899SCharles.Forsyth return string; 129*37da2899SCharles.Forsyth } 130*37da2899SCharles.Forsyth 131*37da2899SCharles.Forsyth 132*37da2899SCharles.Forsyth typedef FT_String* (*TT_NameEntry_ConvertFunc)( TT_NameEntry entry, 133*37da2899SCharles.Forsyth FT_Memory memory ); 134*37da2899SCharles.Forsyth 135*37da2899SCharles.Forsyth 136*37da2899SCharles.Forsyth /*************************************************************************/ 137*37da2899SCharles.Forsyth /* */ 138*37da2899SCharles.Forsyth /* <Function> */ 139*37da2899SCharles.Forsyth /* tt_face_get_name */ 140*37da2899SCharles.Forsyth /* */ 141*37da2899SCharles.Forsyth /* <Description> */ 142*37da2899SCharles.Forsyth /* Returns a given ENGLISH name record in ASCII. */ 143*37da2899SCharles.Forsyth /* */ 144*37da2899SCharles.Forsyth /* <Input> */ 145*37da2899SCharles.Forsyth /* face :: A handle to the source face object. */ 146*37da2899SCharles.Forsyth /* */ 147*37da2899SCharles.Forsyth /* nameid :: The name id of the name record to return. */ 148*37da2899SCharles.Forsyth /* */ 149*37da2899SCharles.Forsyth /* <Return> */ 150*37da2899SCharles.Forsyth /* Character string. NULL if no name is present. */ 151*37da2899SCharles.Forsyth /* */ 152*37da2899SCharles.Forsyth static FT_String* tt_face_get_name(TT_Face face,FT_UShort nameid)153*37da2899SCharles.Forsyth tt_face_get_name( TT_Face face, 154*37da2899SCharles.Forsyth FT_UShort nameid ) 155*37da2899SCharles.Forsyth { 156*37da2899SCharles.Forsyth FT_Memory memory = face->root.memory; 157*37da2899SCharles.Forsyth FT_String* result = NULL; 158*37da2899SCharles.Forsyth FT_UShort n; 159*37da2899SCharles.Forsyth TT_NameEntryRec* rec; 160*37da2899SCharles.Forsyth FT_Int found_apple = -1; 161*37da2899SCharles.Forsyth FT_Int found_win = -1; 162*37da2899SCharles.Forsyth FT_Int found_unicode = -1; 163*37da2899SCharles.Forsyth 164*37da2899SCharles.Forsyth TT_NameEntry_ConvertFunc convert; 165*37da2899SCharles.Forsyth 166*37da2899SCharles.Forsyth 167*37da2899SCharles.Forsyth rec = face->name_table.names; 168*37da2899SCharles.Forsyth for ( n = 0; n < face->num_names; n++, rec++ ) 169*37da2899SCharles.Forsyth { 170*37da2899SCharles.Forsyth /* According to the OpenType 1.3 specification, only Microsoft or */ 171*37da2899SCharles.Forsyth /* Apple platform IDs might be used in the `name' table. The */ 172*37da2899SCharles.Forsyth /* `Unicode' platform is reserved for the `cmap' table, and the */ 173*37da2899SCharles.Forsyth /* `Iso' one is deprecated. */ 174*37da2899SCharles.Forsyth /* */ 175*37da2899SCharles.Forsyth /* However, the Apple TrueType specification doesn't say the same */ 176*37da2899SCharles.Forsyth /* thing and goes to suggest that all Unicode `name' table entries */ 177*37da2899SCharles.Forsyth /* should be coded in UTF-16 (in big-endian format I suppose). */ 178*37da2899SCharles.Forsyth /* */ 179*37da2899SCharles.Forsyth if ( rec->nameID == nameid && rec->stringLength > 0 ) 180*37da2899SCharles.Forsyth { 181*37da2899SCharles.Forsyth switch ( rec->platformID ) 182*37da2899SCharles.Forsyth { 183*37da2899SCharles.Forsyth case TT_PLATFORM_APPLE_UNICODE: 184*37da2899SCharles.Forsyth case TT_PLATFORM_ISO: 185*37da2899SCharles.Forsyth /* there is `languageID' to check there. We should use this */ 186*37da2899SCharles.Forsyth /* field only as a last solution when nothing else is */ 187*37da2899SCharles.Forsyth /* available. */ 188*37da2899SCharles.Forsyth /* */ 189*37da2899SCharles.Forsyth found_unicode = n; 190*37da2899SCharles.Forsyth break; 191*37da2899SCharles.Forsyth 192*37da2899SCharles.Forsyth case TT_PLATFORM_MACINTOSH: 193*37da2899SCharles.Forsyth if ( rec->languageID == TT_MAC_LANGID_ENGLISH ) 194*37da2899SCharles.Forsyth found_apple = n; 195*37da2899SCharles.Forsyth 196*37da2899SCharles.Forsyth break; 197*37da2899SCharles.Forsyth 198*37da2899SCharles.Forsyth case TT_PLATFORM_MICROSOFT: 199*37da2899SCharles.Forsyth /* we only take a non-English name when there is nothing */ 200*37da2899SCharles.Forsyth /* else available in the font */ 201*37da2899SCharles.Forsyth /* */ 202*37da2899SCharles.Forsyth if ( found_win == -1 || ( rec->languageID & 0x3FF ) == 0x009 ) 203*37da2899SCharles.Forsyth { 204*37da2899SCharles.Forsyth switch ( rec->encodingID ) 205*37da2899SCharles.Forsyth { 206*37da2899SCharles.Forsyth case TT_MS_ID_SYMBOL_CS: 207*37da2899SCharles.Forsyth case TT_MS_ID_UNICODE_CS: 208*37da2899SCharles.Forsyth case TT_MS_ID_UCS_4: 209*37da2899SCharles.Forsyth found_win = n; 210*37da2899SCharles.Forsyth break; 211*37da2899SCharles.Forsyth 212*37da2899SCharles.Forsyth default: 213*37da2899SCharles.Forsyth ; 214*37da2899SCharles.Forsyth } 215*37da2899SCharles.Forsyth } 216*37da2899SCharles.Forsyth break; 217*37da2899SCharles.Forsyth 218*37da2899SCharles.Forsyth default: 219*37da2899SCharles.Forsyth ; 220*37da2899SCharles.Forsyth } 221*37da2899SCharles.Forsyth } 222*37da2899SCharles.Forsyth } 223*37da2899SCharles.Forsyth 224*37da2899SCharles.Forsyth /* some fonts contain invalid Unicode or Macintosh formatted entries; */ 225*37da2899SCharles.Forsyth /* we will thus favor names encoded in Windows formats if available */ 226*37da2899SCharles.Forsyth /* */ 227*37da2899SCharles.Forsyth convert = NULL; 228*37da2899SCharles.Forsyth if ( found_win >= 0 ) 229*37da2899SCharles.Forsyth { 230*37da2899SCharles.Forsyth rec = face->name_table.names + found_win; 231*37da2899SCharles.Forsyth switch ( rec->encodingID ) 232*37da2899SCharles.Forsyth { 233*37da2899SCharles.Forsyth case TT_MS_ID_UNICODE_CS: 234*37da2899SCharles.Forsyth case TT_MS_ID_SYMBOL_CS: 235*37da2899SCharles.Forsyth convert = tt_name_entry_ascii_from_utf16; 236*37da2899SCharles.Forsyth break; 237*37da2899SCharles.Forsyth 238*37da2899SCharles.Forsyth case TT_MS_ID_UCS_4: 239*37da2899SCharles.Forsyth convert = tt_name_entry_ascii_from_ucs4; 240*37da2899SCharles.Forsyth break; 241*37da2899SCharles.Forsyth 242*37da2899SCharles.Forsyth default: 243*37da2899SCharles.Forsyth ; 244*37da2899SCharles.Forsyth } 245*37da2899SCharles.Forsyth } 246*37da2899SCharles.Forsyth else if ( found_apple >= 0 ) 247*37da2899SCharles.Forsyth { 248*37da2899SCharles.Forsyth rec = face->name_table.names + found_apple; 249*37da2899SCharles.Forsyth convert = tt_name_entry_ascii_from_other; 250*37da2899SCharles.Forsyth } 251*37da2899SCharles.Forsyth else if ( found_unicode >= 0 ) 252*37da2899SCharles.Forsyth { 253*37da2899SCharles.Forsyth rec = face->name_table.names + found_unicode; 254*37da2899SCharles.Forsyth convert = tt_name_entry_ascii_from_utf16; 255*37da2899SCharles.Forsyth } 256*37da2899SCharles.Forsyth 257*37da2899SCharles.Forsyth if ( rec && convert ) 258*37da2899SCharles.Forsyth { 259*37da2899SCharles.Forsyth if ( rec->string == NULL ) 260*37da2899SCharles.Forsyth { 261*37da2899SCharles.Forsyth FT_Error error; 262*37da2899SCharles.Forsyth FT_Stream stream = face->name_table.stream; 263*37da2899SCharles.Forsyth 264*37da2899SCharles.Forsyth 265*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY ( rec->string, rec->stringLength ) || 266*37da2899SCharles.Forsyth FT_STREAM_SEEK( rec->stringOffset ) || 267*37da2899SCharles.Forsyth FT_STREAM_READ( rec->string, rec->stringLength ) ) 268*37da2899SCharles.Forsyth { 269*37da2899SCharles.Forsyth FT_FREE( rec->string ); 270*37da2899SCharles.Forsyth rec->stringLength = 0; 271*37da2899SCharles.Forsyth result = NULL; 272*37da2899SCharles.Forsyth goto Exit; 273*37da2899SCharles.Forsyth } 274*37da2899SCharles.Forsyth } 275*37da2899SCharles.Forsyth 276*37da2899SCharles.Forsyth result = convert( rec, memory ); 277*37da2899SCharles.Forsyth } 278*37da2899SCharles.Forsyth 279*37da2899SCharles.Forsyth Exit: 280*37da2899SCharles.Forsyth return result; 281*37da2899SCharles.Forsyth } 282*37da2899SCharles.Forsyth 283*37da2899SCharles.Forsyth 284*37da2899SCharles.Forsyth static FT_Encoding sfnt_find_encoding(int platform_id,int encoding_id)285*37da2899SCharles.Forsyth sfnt_find_encoding( int platform_id, 286*37da2899SCharles.Forsyth int encoding_id ) 287*37da2899SCharles.Forsyth { 288*37da2899SCharles.Forsyth typedef struct TEncoding 289*37da2899SCharles.Forsyth { 290*37da2899SCharles.Forsyth int platform_id; 291*37da2899SCharles.Forsyth int encoding_id; 292*37da2899SCharles.Forsyth FT_Encoding encoding; 293*37da2899SCharles.Forsyth 294*37da2899SCharles.Forsyth } TEncoding; 295*37da2899SCharles.Forsyth 296*37da2899SCharles.Forsyth static 297*37da2899SCharles.Forsyth const TEncoding tt_encodings[] = 298*37da2899SCharles.Forsyth { 299*37da2899SCharles.Forsyth { TT_PLATFORM_ISO, -1, FT_ENCODING_UNICODE }, 300*37da2899SCharles.Forsyth 301*37da2899SCharles.Forsyth { TT_PLATFORM_APPLE_UNICODE, -1, FT_ENCODING_UNICODE }, 302*37da2899SCharles.Forsyth 303*37da2899SCharles.Forsyth { TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, FT_ENCODING_APPLE_ROMAN }, 304*37da2899SCharles.Forsyth 305*37da2899SCharles.Forsyth { TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, FT_ENCODING_MS_SYMBOL }, 306*37da2899SCharles.Forsyth { TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, FT_ENCODING_UNICODE }, 307*37da2899SCharles.Forsyth { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE }, 308*37da2899SCharles.Forsyth { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, FT_ENCODING_MS_SJIS }, 309*37da2899SCharles.Forsyth { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, FT_ENCODING_MS_GB2312 }, 310*37da2899SCharles.Forsyth { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, FT_ENCODING_MS_BIG5 }, 311*37da2899SCharles.Forsyth { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, FT_ENCODING_MS_WANSUNG }, 312*37da2899SCharles.Forsyth { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, FT_ENCODING_MS_JOHAB } 313*37da2899SCharles.Forsyth }; 314*37da2899SCharles.Forsyth 315*37da2899SCharles.Forsyth const TEncoding *cur, *limit; 316*37da2899SCharles.Forsyth 317*37da2899SCharles.Forsyth 318*37da2899SCharles.Forsyth cur = tt_encodings; 319*37da2899SCharles.Forsyth limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] ); 320*37da2899SCharles.Forsyth 321*37da2899SCharles.Forsyth for ( ; cur < limit; cur++ ) 322*37da2899SCharles.Forsyth { 323*37da2899SCharles.Forsyth if ( cur->platform_id == platform_id ) 324*37da2899SCharles.Forsyth { 325*37da2899SCharles.Forsyth if ( cur->encoding_id == encoding_id || 326*37da2899SCharles.Forsyth cur->encoding_id == -1 ) 327*37da2899SCharles.Forsyth return cur->encoding; 328*37da2899SCharles.Forsyth } 329*37da2899SCharles.Forsyth } 330*37da2899SCharles.Forsyth 331*37da2899SCharles.Forsyth return FT_ENCODING_NONE; 332*37da2899SCharles.Forsyth } 333*37da2899SCharles.Forsyth 334*37da2899SCharles.Forsyth 335*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) sfnt_init_face(FT_Stream stream,TT_Face face,FT_Int face_index,FT_Int num_params,FT_Parameter * params)336*37da2899SCharles.Forsyth sfnt_init_face( FT_Stream stream, 337*37da2899SCharles.Forsyth TT_Face face, 338*37da2899SCharles.Forsyth FT_Int face_index, 339*37da2899SCharles.Forsyth FT_Int num_params, 340*37da2899SCharles.Forsyth FT_Parameter* params ) 341*37da2899SCharles.Forsyth { 342*37da2899SCharles.Forsyth FT_Error error; 343*37da2899SCharles.Forsyth FT_Library library = face->root.driver->root.library; 344*37da2899SCharles.Forsyth SFNT_Service sfnt; 345*37da2899SCharles.Forsyth SFNT_HeaderRec sfnt_header; 346*37da2899SCharles.Forsyth 347*37da2899SCharles.Forsyth /* for now, parameters are unused */ 348*37da2899SCharles.Forsyth FT_UNUSED( num_params ); 349*37da2899SCharles.Forsyth FT_UNUSED( params ); 350*37da2899SCharles.Forsyth 351*37da2899SCharles.Forsyth 352*37da2899SCharles.Forsyth sfnt = (SFNT_Service)face->sfnt; 353*37da2899SCharles.Forsyth if ( !sfnt ) 354*37da2899SCharles.Forsyth { 355*37da2899SCharles.Forsyth sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); 356*37da2899SCharles.Forsyth if ( !sfnt ) 357*37da2899SCharles.Forsyth { 358*37da2899SCharles.Forsyth error = SFNT_Err_Invalid_File_Format; 359*37da2899SCharles.Forsyth goto Exit; 360*37da2899SCharles.Forsyth } 361*37da2899SCharles.Forsyth 362*37da2899SCharles.Forsyth face->sfnt = sfnt; 363*37da2899SCharles.Forsyth face->goto_table = sfnt->goto_table; 364*37da2899SCharles.Forsyth } 365*37da2899SCharles.Forsyth 366*37da2899SCharles.Forsyth if ( !face->psnames ) 367*37da2899SCharles.Forsyth { 368*37da2899SCharles.Forsyth face->psnames = (PSNames_Service) 369*37da2899SCharles.Forsyth FT_Get_Module_Interface( library, "psnames" ); 370*37da2899SCharles.Forsyth } 371*37da2899SCharles.Forsyth 372*37da2899SCharles.Forsyth /* check that we have a valid TrueType file */ 373*37da2899SCharles.Forsyth error = sfnt->load_sfnt_header( face, stream, face_index, &sfnt_header ); 374*37da2899SCharles.Forsyth if ( error ) 375*37da2899SCharles.Forsyth goto Exit; 376*37da2899SCharles.Forsyth 377*37da2899SCharles.Forsyth face->format_tag = sfnt_header.format_tag; 378*37da2899SCharles.Forsyth face->num_tables = sfnt_header.num_tables; 379*37da2899SCharles.Forsyth 380*37da2899SCharles.Forsyth /* Load font directory */ 381*37da2899SCharles.Forsyth error = sfnt->load_directory( face, stream, &sfnt_header ); 382*37da2899SCharles.Forsyth if ( error ) 383*37da2899SCharles.Forsyth goto Exit; 384*37da2899SCharles.Forsyth 385*37da2899SCharles.Forsyth face->root.num_faces = face->ttc_header.count; 386*37da2899SCharles.Forsyth if ( face->root.num_faces < 1 ) 387*37da2899SCharles.Forsyth face->root.num_faces = 1; 388*37da2899SCharles.Forsyth 389*37da2899SCharles.Forsyth Exit: 390*37da2899SCharles.Forsyth return error; 391*37da2899SCharles.Forsyth } 392*37da2899SCharles.Forsyth 393*37da2899SCharles.Forsyth 394*37da2899SCharles.Forsyth #undef LOAD_ 395*37da2899SCharles.Forsyth #define LOAD_( x ) ( ( error = sfnt->load_##x( face, stream ) ) \ 396*37da2899SCharles.Forsyth != SFNT_Err_Ok ) 397*37da2899SCharles.Forsyth 398*37da2899SCharles.Forsyth 399*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) sfnt_load_face(FT_Stream stream,TT_Face face,FT_Int face_index,FT_Int num_params,FT_Parameter * params)400*37da2899SCharles.Forsyth sfnt_load_face( FT_Stream stream, 401*37da2899SCharles.Forsyth TT_Face face, 402*37da2899SCharles.Forsyth FT_Int face_index, 403*37da2899SCharles.Forsyth FT_Int num_params, 404*37da2899SCharles.Forsyth FT_Parameter* params ) 405*37da2899SCharles.Forsyth { 406*37da2899SCharles.Forsyth FT_Error error; 407*37da2899SCharles.Forsyth FT_Bool has_outline; 408*37da2899SCharles.Forsyth FT_Bool is_apple_sbit; 409*37da2899SCharles.Forsyth 410*37da2899SCharles.Forsyth SFNT_Service sfnt = (SFNT_Service)face->sfnt; 411*37da2899SCharles.Forsyth 412*37da2899SCharles.Forsyth FT_UNUSED( face_index ); 413*37da2899SCharles.Forsyth FT_UNUSED( num_params ); 414*37da2899SCharles.Forsyth FT_UNUSED( params ); 415*37da2899SCharles.Forsyth 416*37da2899SCharles.Forsyth 417*37da2899SCharles.Forsyth /* Load tables */ 418*37da2899SCharles.Forsyth 419*37da2899SCharles.Forsyth /* We now support two SFNT-based bitmapped font formats. They */ 420*37da2899SCharles.Forsyth /* are recognized easily as they do not include a `glyf' */ 421*37da2899SCharles.Forsyth /* table. */ 422*37da2899SCharles.Forsyth /* */ 423*37da2899SCharles.Forsyth /* The first format comes from Apple, and uses a table named */ 424*37da2899SCharles.Forsyth /* `bhed' instead of `head' to store the font header (using */ 425*37da2899SCharles.Forsyth /* the same format). It also doesn't include horizontal and */ 426*37da2899SCharles.Forsyth /* vertical metrics tables (i.e. `hhea' and `vhea' tables are */ 427*37da2899SCharles.Forsyth /* missing). */ 428*37da2899SCharles.Forsyth /* */ 429*37da2899SCharles.Forsyth /* The other format comes from Microsoft, and is used with */ 430*37da2899SCharles.Forsyth /* WinCE/PocketPC. It looks like a standard TTF, except that */ 431*37da2899SCharles.Forsyth /* it doesn't contain outlines. */ 432*37da2899SCharles.Forsyth /* */ 433*37da2899SCharles.Forsyth 434*37da2899SCharles.Forsyth /* do we have outlines in there? */ 435*37da2899SCharles.Forsyth #ifdef FT_CONFIG_OPTION_INCREMENTAL 436*37da2899SCharles.Forsyth has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 || 437*37da2899SCharles.Forsyth tt_face_lookup_table( face, TTAG_glyf ) != 0 || 438*37da2899SCharles.Forsyth tt_face_lookup_table( face, TTAG_CFF ) != 0 ); 439*37da2899SCharles.Forsyth #else 440*37da2899SCharles.Forsyth has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 || 441*37da2899SCharles.Forsyth tt_face_lookup_table( face, TTAG_CFF ) != 0 ); 442*37da2899SCharles.Forsyth #endif 443*37da2899SCharles.Forsyth 444*37da2899SCharles.Forsyth is_apple_sbit = 0; 445*37da2899SCharles.Forsyth 446*37da2899SCharles.Forsyth #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 447*37da2899SCharles.Forsyth 448*37da2899SCharles.Forsyth /* if this font doesn't contain outlines, we try to load */ 449*37da2899SCharles.Forsyth /* a `bhed' table */ 450*37da2899SCharles.Forsyth if ( !has_outline ) 451*37da2899SCharles.Forsyth is_apple_sbit = FT_BOOL( !LOAD_( bitmap_header ) ); 452*37da2899SCharles.Forsyth 453*37da2899SCharles.Forsyth #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 454*37da2899SCharles.Forsyth 455*37da2899SCharles.Forsyth /* load the font header (`head' table) if this isn't an Apple */ 456*37da2899SCharles.Forsyth /* sbit font file */ 457*37da2899SCharles.Forsyth if ( !is_apple_sbit && LOAD_( header ) ) 458*37da2899SCharles.Forsyth goto Exit; 459*37da2899SCharles.Forsyth 460*37da2899SCharles.Forsyth /* the following tables are often not present in embedded TrueType */ 461*37da2899SCharles.Forsyth /* fonts within PDF documents, so don't check for them. */ 462*37da2899SCharles.Forsyth (void)LOAD_( max_profile ); 463*37da2899SCharles.Forsyth (void)LOAD_( charmaps ); 464*37da2899SCharles.Forsyth 465*37da2899SCharles.Forsyth /* the following tables are optional in PCL fonts -- */ 466*37da2899SCharles.Forsyth /* don't check for errors */ 467*37da2899SCharles.Forsyth (void)LOAD_( names ); 468*37da2899SCharles.Forsyth (void)LOAD_( psnames ); 469*37da2899SCharles.Forsyth 470*37da2899SCharles.Forsyth /* do not load the metrics headers and tables if this is an Apple */ 471*37da2899SCharles.Forsyth /* sbit font file */ 472*37da2899SCharles.Forsyth if ( !is_apple_sbit ) 473*37da2899SCharles.Forsyth { 474*37da2899SCharles.Forsyth /* load the `hhea' and `hmtx' tables at once */ 475*37da2899SCharles.Forsyth error = sfnt->load_metrics( face, stream, 0 ); 476*37da2899SCharles.Forsyth if ( error ) 477*37da2899SCharles.Forsyth goto Exit; 478*37da2899SCharles.Forsyth 479*37da2899SCharles.Forsyth /* try to load the `vhea' and `vmtx' tables at once */ 480*37da2899SCharles.Forsyth error = sfnt->load_metrics( face, stream, 1 ); 481*37da2899SCharles.Forsyth if ( error ) 482*37da2899SCharles.Forsyth goto Exit; 483*37da2899SCharles.Forsyth 484*37da2899SCharles.Forsyth if ( LOAD_( os2 ) ) 485*37da2899SCharles.Forsyth goto Exit; 486*37da2899SCharles.Forsyth } 487*37da2899SCharles.Forsyth 488*37da2899SCharles.Forsyth /* the optional tables */ 489*37da2899SCharles.Forsyth 490*37da2899SCharles.Forsyth #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 491*37da2899SCharles.Forsyth 492*37da2899SCharles.Forsyth /* embedded bitmap support. */ 493*37da2899SCharles.Forsyth if ( sfnt->load_sbits && LOAD_( sbits ) ) 494*37da2899SCharles.Forsyth { 495*37da2899SCharles.Forsyth /* return an error if this font file has no outlines */ 496*37da2899SCharles.Forsyth if ( error == SFNT_Err_Table_Missing && has_outline ) 497*37da2899SCharles.Forsyth error = SFNT_Err_Ok; 498*37da2899SCharles.Forsyth else 499*37da2899SCharles.Forsyth goto Exit; 500*37da2899SCharles.Forsyth } 501*37da2899SCharles.Forsyth 502*37da2899SCharles.Forsyth #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 503*37da2899SCharles.Forsyth 504*37da2899SCharles.Forsyth if ( LOAD_( hdmx ) || 505*37da2899SCharles.Forsyth LOAD_( gasp ) || 506*37da2899SCharles.Forsyth LOAD_( kerning ) || 507*37da2899SCharles.Forsyth LOAD_( pclt ) ) 508*37da2899SCharles.Forsyth goto Exit; 509*37da2899SCharles.Forsyth 510*37da2899SCharles.Forsyth face->root.family_name = tt_face_get_name( face, 511*37da2899SCharles.Forsyth TT_NAME_ID_FONT_FAMILY ); 512*37da2899SCharles.Forsyth face->root.style_name = tt_face_get_name( face, 513*37da2899SCharles.Forsyth TT_NAME_ID_FONT_SUBFAMILY ); 514*37da2899SCharles.Forsyth 515*37da2899SCharles.Forsyth /* now set up root fields */ 516*37da2899SCharles.Forsyth { 517*37da2899SCharles.Forsyth FT_Face root = &face->root; 518*37da2899SCharles.Forsyth FT_Int32 flags = 0; 519*37da2899SCharles.Forsyth FT_Memory memory; 520*37da2899SCharles.Forsyth 521*37da2899SCharles.Forsyth 522*37da2899SCharles.Forsyth memory = root->memory; 523*37da2899SCharles.Forsyth 524*37da2899SCharles.Forsyth /*********************************************************************/ 525*37da2899SCharles.Forsyth /* */ 526*37da2899SCharles.Forsyth /* Compute face flags. */ 527*37da2899SCharles.Forsyth /* */ 528*37da2899SCharles.Forsyth if ( has_outline == TRUE ) 529*37da2899SCharles.Forsyth flags = FT_FACE_FLAG_SCALABLE; /* scalable outlines */ 530*37da2899SCharles.Forsyth 531*37da2899SCharles.Forsyth flags |= FT_FACE_FLAG_SFNT | /* SFNT file format */ 532*37da2899SCharles.Forsyth FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ 533*37da2899SCharles.Forsyth 534*37da2899SCharles.Forsyth #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES 535*37da2899SCharles.Forsyth /* might need more polish to detect the presence of a Postscript */ 536*37da2899SCharles.Forsyth /* name table in the font */ 537*37da2899SCharles.Forsyth flags |= FT_FACE_FLAG_GLYPH_NAMES; 538*37da2899SCharles.Forsyth #endif 539*37da2899SCharles.Forsyth 540*37da2899SCharles.Forsyth /* fixed width font? */ 541*37da2899SCharles.Forsyth if ( face->postscript.isFixedPitch ) 542*37da2899SCharles.Forsyth flags |= FT_FACE_FLAG_FIXED_WIDTH; 543*37da2899SCharles.Forsyth 544*37da2899SCharles.Forsyth /* vertical information? */ 545*37da2899SCharles.Forsyth if ( face->vertical_info ) 546*37da2899SCharles.Forsyth flags |= FT_FACE_FLAG_VERTICAL; 547*37da2899SCharles.Forsyth 548*37da2899SCharles.Forsyth /* kerning available ? */ 549*37da2899SCharles.Forsyth if ( face->kern_pairs ) 550*37da2899SCharles.Forsyth flags |= FT_FACE_FLAG_KERNING; 551*37da2899SCharles.Forsyth 552*37da2899SCharles.Forsyth root->face_flags = flags; 553*37da2899SCharles.Forsyth 554*37da2899SCharles.Forsyth /*********************************************************************/ 555*37da2899SCharles.Forsyth /* */ 556*37da2899SCharles.Forsyth /* Compute style flags. */ 557*37da2899SCharles.Forsyth /* */ 558*37da2899SCharles.Forsyth flags = 0; 559*37da2899SCharles.Forsyth if ( has_outline == TRUE && face->os2.version != 0xFFFF ) 560*37da2899SCharles.Forsyth { 561*37da2899SCharles.Forsyth /* we have an OS/2 table; use the `fsSelection' field */ 562*37da2899SCharles.Forsyth if ( face->os2.fsSelection & 1 ) 563*37da2899SCharles.Forsyth flags |= FT_STYLE_FLAG_ITALIC; 564*37da2899SCharles.Forsyth 565*37da2899SCharles.Forsyth if ( face->os2.fsSelection & 32 ) 566*37da2899SCharles.Forsyth flags |= FT_STYLE_FLAG_BOLD; 567*37da2899SCharles.Forsyth } 568*37da2899SCharles.Forsyth else 569*37da2899SCharles.Forsyth { 570*37da2899SCharles.Forsyth /* this is an old Mac font, use the header field */ 571*37da2899SCharles.Forsyth if ( face->header.Mac_Style & 1 ) 572*37da2899SCharles.Forsyth flags |= FT_STYLE_FLAG_BOLD; 573*37da2899SCharles.Forsyth 574*37da2899SCharles.Forsyth if ( face->header.Mac_Style & 2 ) 575*37da2899SCharles.Forsyth flags |= FT_STYLE_FLAG_ITALIC; 576*37da2899SCharles.Forsyth } 577*37da2899SCharles.Forsyth 578*37da2899SCharles.Forsyth root->style_flags = flags; 579*37da2899SCharles.Forsyth 580*37da2899SCharles.Forsyth /*********************************************************************/ 581*37da2899SCharles.Forsyth /* */ 582*37da2899SCharles.Forsyth /* Polish the charmaps. */ 583*37da2899SCharles.Forsyth /* */ 584*37da2899SCharles.Forsyth /* Try to set the charmap encoding according to the platform & */ 585*37da2899SCharles.Forsyth /* encoding ID of each charmap. */ 586*37da2899SCharles.Forsyth /* */ 587*37da2899SCharles.Forsyth 588*37da2899SCharles.Forsyth tt_face_build_cmaps( face ); /* ignore errors */ 589*37da2899SCharles.Forsyth 590*37da2899SCharles.Forsyth 591*37da2899SCharles.Forsyth /* set the encoding fields */ 592*37da2899SCharles.Forsyth { 593*37da2899SCharles.Forsyth FT_Int m; 594*37da2899SCharles.Forsyth 595*37da2899SCharles.Forsyth 596*37da2899SCharles.Forsyth for ( m = 0; m < root->num_charmaps; m++ ) 597*37da2899SCharles.Forsyth { 598*37da2899SCharles.Forsyth FT_CharMap charmap = root->charmaps[m]; 599*37da2899SCharles.Forsyth 600*37da2899SCharles.Forsyth 601*37da2899SCharles.Forsyth charmap->encoding = sfnt_find_encoding( charmap->platform_id, 602*37da2899SCharles.Forsyth charmap->encoding_id ); 603*37da2899SCharles.Forsyth 604*37da2899SCharles.Forsyth #if 0 605*37da2899SCharles.Forsyth if ( root->charmap == NULL && 606*37da2899SCharles.Forsyth charmap->encoding == FT_ENCODING_UNICODE ) 607*37da2899SCharles.Forsyth { 608*37da2899SCharles.Forsyth /* set 'root->charmap' to the first Unicode encoding we find */ 609*37da2899SCharles.Forsyth root->charmap = charmap; 610*37da2899SCharles.Forsyth } 611*37da2899SCharles.Forsyth #endif 612*37da2899SCharles.Forsyth } 613*37da2899SCharles.Forsyth } 614*37da2899SCharles.Forsyth 615*37da2899SCharles.Forsyth 616*37da2899SCharles.Forsyth #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 617*37da2899SCharles.Forsyth 618*37da2899SCharles.Forsyth if ( face->num_sbit_strikes ) 619*37da2899SCharles.Forsyth { 620*37da2899SCharles.Forsyth FT_ULong n; 621*37da2899SCharles.Forsyth 622*37da2899SCharles.Forsyth 623*37da2899SCharles.Forsyth root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; 624*37da2899SCharles.Forsyth 625*37da2899SCharles.Forsyth #if 0 626*37da2899SCharles.Forsyth /* XXX: I don't know criteria whether layout is horizontal */ 627*37da2899SCharles.Forsyth /* or vertical. */ 628*37da2899SCharles.Forsyth if ( has_outline.... ) 629*37da2899SCharles.Forsyth { 630*37da2899SCharles.Forsyth ... 631*37da2899SCharles.Forsyth root->face_flags |= FT_FACE_FLAG_VERTICAL; 632*37da2899SCharles.Forsyth } 633*37da2899SCharles.Forsyth #endif 634*37da2899SCharles.Forsyth root->num_fixed_sizes = face->num_sbit_strikes; 635*37da2899SCharles.Forsyth 636*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( root->available_sizes, face->num_sbit_strikes ) ) 637*37da2899SCharles.Forsyth goto Exit; 638*37da2899SCharles.Forsyth 639*37da2899SCharles.Forsyth for ( n = 0 ; n < face->num_sbit_strikes ; n++ ) 640*37da2899SCharles.Forsyth { 641*37da2899SCharles.Forsyth root->available_sizes[n].width = 642*37da2899SCharles.Forsyth face->sbit_strikes[n].x_ppem; 643*37da2899SCharles.Forsyth 644*37da2899SCharles.Forsyth root->available_sizes[n].height = 645*37da2899SCharles.Forsyth face->sbit_strikes[n].y_ppem; 646*37da2899SCharles.Forsyth } 647*37da2899SCharles.Forsyth } 648*37da2899SCharles.Forsyth else 649*37da2899SCharles.Forsyth 650*37da2899SCharles.Forsyth #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 651*37da2899SCharles.Forsyth 652*37da2899SCharles.Forsyth { 653*37da2899SCharles.Forsyth root->num_fixed_sizes = 0; 654*37da2899SCharles.Forsyth root->available_sizes = 0; 655*37da2899SCharles.Forsyth } 656*37da2899SCharles.Forsyth 657*37da2899SCharles.Forsyth /*********************************************************************/ 658*37da2899SCharles.Forsyth /* */ 659*37da2899SCharles.Forsyth /* Set up metrics. */ 660*37da2899SCharles.Forsyth /* */ 661*37da2899SCharles.Forsyth if ( has_outline == TRUE ) 662*37da2899SCharles.Forsyth { 663*37da2899SCharles.Forsyth /* XXX What about if outline header is missing */ 664*37da2899SCharles.Forsyth /* (e.g. sfnt wrapped outline)? */ 665*37da2899SCharles.Forsyth root->bbox.xMin = face->header.xMin; 666*37da2899SCharles.Forsyth root->bbox.yMin = face->header.yMin; 667*37da2899SCharles.Forsyth root->bbox.xMax = face->header.xMax; 668*37da2899SCharles.Forsyth root->bbox.yMax = face->header.yMax; 669*37da2899SCharles.Forsyth root->units_per_EM = face->header.Units_Per_EM; 670*37da2899SCharles.Forsyth 671*37da2899SCharles.Forsyth 672*37da2899SCharles.Forsyth /* XXX: Computing the ascender/descender/height is very different */ 673*37da2899SCharles.Forsyth /* from what the specification tells you. Apparently, we */ 674*37da2899SCharles.Forsyth /* must be careful because */ 675*37da2899SCharles.Forsyth /* */ 676*37da2899SCharles.Forsyth /* - not all fonts have an OS/2 table; in this case, we take */ 677*37da2899SCharles.Forsyth /* the values in the horizontal header. However, these */ 678*37da2899SCharles.Forsyth /* values very often are not reliable. */ 679*37da2899SCharles.Forsyth /* */ 680*37da2899SCharles.Forsyth /* - otherwise, the correct typographic values are in the */ 681*37da2899SCharles.Forsyth /* sTypoAscender, sTypoDescender & sTypoLineGap fields. */ 682*37da2899SCharles.Forsyth /* */ 683*37da2899SCharles.Forsyth /* However, certains fonts have these fields set to 0. */ 684*37da2899SCharles.Forsyth /* Rather, they have usWinAscent & usWinDescent correctly */ 685*37da2899SCharles.Forsyth /* set (but with different values). */ 686*37da2899SCharles.Forsyth /* */ 687*37da2899SCharles.Forsyth /* As an example, Arial Narrow is implemented through four */ 688*37da2899SCharles.Forsyth /* files ARIALN.TTF, ARIALNI.TTF, ARIALNB.TTF & ARIALNBI.TTF */ 689*37da2899SCharles.Forsyth /* */ 690*37da2899SCharles.Forsyth /* Strangely, all fonts have the same values in their */ 691*37da2899SCharles.Forsyth /* sTypoXXX fields, except ARIALNB which sets them to 0. */ 692*37da2899SCharles.Forsyth /* */ 693*37da2899SCharles.Forsyth /* On the other hand, they all have different */ 694*37da2899SCharles.Forsyth /* usWinAscent/Descent values -- as a conclusion, the OS/2 */ 695*37da2899SCharles.Forsyth /* table cannot be used to compute the text height reliably! */ 696*37da2899SCharles.Forsyth /* */ 697*37da2899SCharles.Forsyth 698*37da2899SCharles.Forsyth /* The ascender/descender/height are computed from the OS/2 table */ 699*37da2899SCharles.Forsyth /* when found. Otherwise, they're taken from the horizontal */ 700*37da2899SCharles.Forsyth /* header. */ 701*37da2899SCharles.Forsyth /* */ 702*37da2899SCharles.Forsyth 703*37da2899SCharles.Forsyth root->ascender = face->horizontal.Ascender; 704*37da2899SCharles.Forsyth root->descender = face->horizontal.Descender; 705*37da2899SCharles.Forsyth 706*37da2899SCharles.Forsyth root->height = (FT_Short)( root->ascender - root->descender + 707*37da2899SCharles.Forsyth face->horizontal.Line_Gap ); 708*37da2899SCharles.Forsyth 709*37da2899SCharles.Forsyth /* if the line_gap is 0, we add an extra 15% to the text height -- */ 710*37da2899SCharles.Forsyth /* this computation is based on various versions of Times New Roman */ 711*37da2899SCharles.Forsyth if ( face->horizontal.Line_Gap == 0 ) 712*37da2899SCharles.Forsyth root->height = (FT_Short)( ( root->height * 115 + 50 ) / 100 ); 713*37da2899SCharles.Forsyth 714*37da2899SCharles.Forsyth #if 0 715*37da2899SCharles.Forsyth 716*37da2899SCharles.Forsyth /* some fonts have the OS/2 "sTypoAscender", "sTypoDescender" & */ 717*37da2899SCharles.Forsyth /* "sTypoLineGap" fields set to 0, like ARIALNB.TTF */ 718*37da2899SCharles.Forsyth if ( face->os2.version != 0xFFFF && root->ascender ) 719*37da2899SCharles.Forsyth { 720*37da2899SCharles.Forsyth FT_Int height; 721*37da2899SCharles.Forsyth 722*37da2899SCharles.Forsyth 723*37da2899SCharles.Forsyth root->ascender = face->os2.sTypoAscender; 724*37da2899SCharles.Forsyth root->descender = -face->os2.sTypoDescender; 725*37da2899SCharles.Forsyth 726*37da2899SCharles.Forsyth height = root->ascender + root->descender + face->os2.sTypoLineGap; 727*37da2899SCharles.Forsyth if ( height > root->height ) 728*37da2899SCharles.Forsyth root->height = height; 729*37da2899SCharles.Forsyth } 730*37da2899SCharles.Forsyth 731*37da2899SCharles.Forsyth #endif /* 0 */ 732*37da2899SCharles.Forsyth 733*37da2899SCharles.Forsyth root->max_advance_width = face->horizontal.advance_Width_Max; 734*37da2899SCharles.Forsyth 735*37da2899SCharles.Forsyth root->max_advance_height = (FT_Short)( face->vertical_info 736*37da2899SCharles.Forsyth ? face->vertical.advance_Height_Max 737*37da2899SCharles.Forsyth : root->height ); 738*37da2899SCharles.Forsyth 739*37da2899SCharles.Forsyth root->underline_position = face->postscript.underlinePosition; 740*37da2899SCharles.Forsyth root->underline_thickness = face->postscript.underlineThickness; 741*37da2899SCharles.Forsyth 742*37da2899SCharles.Forsyth /* root->max_points -- already set up */ 743*37da2899SCharles.Forsyth /* root->max_contours -- already set up */ 744*37da2899SCharles.Forsyth } 745*37da2899SCharles.Forsyth } 746*37da2899SCharles.Forsyth 747*37da2899SCharles.Forsyth Exit: 748*37da2899SCharles.Forsyth return error; 749*37da2899SCharles.Forsyth } 750*37da2899SCharles.Forsyth 751*37da2899SCharles.Forsyth 752*37da2899SCharles.Forsyth #undef LOAD_ 753*37da2899SCharles.Forsyth 754*37da2899SCharles.Forsyth 755*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) sfnt_done_face(TT_Face face)756*37da2899SCharles.Forsyth sfnt_done_face( TT_Face face ) 757*37da2899SCharles.Forsyth { 758*37da2899SCharles.Forsyth FT_Memory memory = face->root.memory; 759*37da2899SCharles.Forsyth SFNT_Service sfnt = (SFNT_Service)face->sfnt; 760*37da2899SCharles.Forsyth 761*37da2899SCharles.Forsyth 762*37da2899SCharles.Forsyth if ( sfnt ) 763*37da2899SCharles.Forsyth { 764*37da2899SCharles.Forsyth /* destroy the postscript names table if it is loaded */ 765*37da2899SCharles.Forsyth if ( sfnt->free_psnames ) 766*37da2899SCharles.Forsyth sfnt->free_psnames( face ); 767*37da2899SCharles.Forsyth 768*37da2899SCharles.Forsyth /* destroy the embedded bitmaps table if it is loaded */ 769*37da2899SCharles.Forsyth if ( sfnt->free_sbits ) 770*37da2899SCharles.Forsyth sfnt->free_sbits( face ); 771*37da2899SCharles.Forsyth } 772*37da2899SCharles.Forsyth 773*37da2899SCharles.Forsyth /* freeing the kerning table */ 774*37da2899SCharles.Forsyth FT_FREE( face->kern_pairs ); 775*37da2899SCharles.Forsyth face->num_kern_pairs = 0; 776*37da2899SCharles.Forsyth 777*37da2899SCharles.Forsyth /* freeing the collection table */ 778*37da2899SCharles.Forsyth FT_FREE( face->ttc_header.offsets ); 779*37da2899SCharles.Forsyth face->ttc_header.count = 0; 780*37da2899SCharles.Forsyth 781*37da2899SCharles.Forsyth /* freeing table directory */ 782*37da2899SCharles.Forsyth FT_FREE( face->dir_tables ); 783*37da2899SCharles.Forsyth face->num_tables = 0; 784*37da2899SCharles.Forsyth 785*37da2899SCharles.Forsyth { 786*37da2899SCharles.Forsyth FT_Stream stream = FT_FACE_STREAM( face ); 787*37da2899SCharles.Forsyth 788*37da2899SCharles.Forsyth 789*37da2899SCharles.Forsyth /* simply release the 'cmap' table frame */ 790*37da2899SCharles.Forsyth FT_FRAME_RELEASE( face->cmap_table ); 791*37da2899SCharles.Forsyth face->cmap_size = 0; 792*37da2899SCharles.Forsyth } 793*37da2899SCharles.Forsyth 794*37da2899SCharles.Forsyth /* freeing the horizontal metrics */ 795*37da2899SCharles.Forsyth FT_FREE( face->horizontal.long_metrics ); 796*37da2899SCharles.Forsyth FT_FREE( face->horizontal.short_metrics ); 797*37da2899SCharles.Forsyth 798*37da2899SCharles.Forsyth /* freeing the vertical ones, if any */ 799*37da2899SCharles.Forsyth if ( face->vertical_info ) 800*37da2899SCharles.Forsyth { 801*37da2899SCharles.Forsyth FT_FREE( face->vertical.long_metrics ); 802*37da2899SCharles.Forsyth FT_FREE( face->vertical.short_metrics ); 803*37da2899SCharles.Forsyth face->vertical_info = 0; 804*37da2899SCharles.Forsyth } 805*37da2899SCharles.Forsyth 806*37da2899SCharles.Forsyth /* freeing the gasp table */ 807*37da2899SCharles.Forsyth FT_FREE( face->gasp.gaspRanges ); 808*37da2899SCharles.Forsyth face->gasp.numRanges = 0; 809*37da2899SCharles.Forsyth 810*37da2899SCharles.Forsyth /* freeing the name table */ 811*37da2899SCharles.Forsyth sfnt->free_names( face ); 812*37da2899SCharles.Forsyth 813*37da2899SCharles.Forsyth /* freeing the hdmx table */ 814*37da2899SCharles.Forsyth sfnt->free_hdmx( face ); 815*37da2899SCharles.Forsyth 816*37da2899SCharles.Forsyth /* freeing family and style name */ 817*37da2899SCharles.Forsyth FT_FREE( face->root.family_name ); 818*37da2899SCharles.Forsyth FT_FREE( face->root.style_name ); 819*37da2899SCharles.Forsyth 820*37da2899SCharles.Forsyth /* freeing sbit size table */ 821*37da2899SCharles.Forsyth face->root.num_fixed_sizes = 0; 822*37da2899SCharles.Forsyth if ( face->root.available_sizes ) 823*37da2899SCharles.Forsyth FT_FREE( face->root.available_sizes ); 824*37da2899SCharles.Forsyth 825*37da2899SCharles.Forsyth face->sfnt = 0; 826*37da2899SCharles.Forsyth } 827*37da2899SCharles.Forsyth 828*37da2899SCharles.Forsyth 829*37da2899SCharles.Forsyth /* END */ 830