/modules/freetype2/src/sfnt/sfobjs.c

http://github.com/zpao/v8monkey · C · 1149 lines · 705 code · 227 blank · 217 comment · 178 complexity · dd212b4a188e5f3e77002516dcd72da2 MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* sfobjs.c */
  4. /* */
  5. /* SFNT object management (base). */
  6. /* */
  7. /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */
  8. /* David Turner, Robert Wilhelm, and Werner Lemberg. */
  9. /* */
  10. /* This file is part of the FreeType project, and may only be used, */
  11. /* modified, and distributed under the terms of the FreeType project */
  12. /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
  13. /* this file you indicate that you have read the license and */
  14. /* understand and accept it fully. */
  15. /* */
  16. /***************************************************************************/
  17. #include <ft2build.h>
  18. #include "sfobjs.h"
  19. #include "ttload.h"
  20. #include "ttcmap.h"
  21. #include "ttkern.h"
  22. #include FT_INTERNAL_SFNT_H
  23. #include FT_INTERNAL_DEBUG_H
  24. #include FT_TRUETYPE_IDS_H
  25. #include FT_TRUETYPE_TAGS_H
  26. #include FT_SERVICE_POSTSCRIPT_CMAPS_H
  27. #include FT_SFNT_NAMES_H
  28. #include "sferrors.h"
  29. #ifdef TT_CONFIG_OPTION_BDF
  30. #include "ttbdf.h"
  31. #endif
  32. /*************************************************************************/
  33. /* */
  34. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  35. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  36. /* messages during execution. */
  37. /* */
  38. #undef FT_COMPONENT
  39. #define FT_COMPONENT trace_sfobjs
  40. /* convert a UTF-16 name entry to ASCII */
  41. static FT_String*
  42. tt_name_entry_ascii_from_utf16( TT_NameEntry entry,
  43. FT_Memory memory )
  44. {
  45. FT_String* string = NULL;
  46. FT_UInt len, code, n;
  47. FT_Byte* read = (FT_Byte*)entry->string;
  48. FT_Error error;
  49. len = (FT_UInt)entry->stringLength / 2;
  50. if ( FT_NEW_ARRAY( string, len + 1 ) )
  51. return NULL;
  52. for ( n = 0; n < len; n++ )
  53. {
  54. code = FT_NEXT_USHORT( read );
  55. if ( code < 32 || code > 127 )
  56. code = '?';
  57. string[n] = (char)code;
  58. }
  59. string[len] = 0;
  60. return string;
  61. }
  62. /* convert an Apple Roman or symbol name entry to ASCII */
  63. static FT_String*
  64. tt_name_entry_ascii_from_other( TT_NameEntry entry,
  65. FT_Memory memory )
  66. {
  67. FT_String* string = NULL;
  68. FT_UInt len, code, n;
  69. FT_Byte* read = (FT_Byte*)entry->string;
  70. FT_Error error;
  71. len = (FT_UInt)entry->stringLength;
  72. if ( FT_NEW_ARRAY( string, len + 1 ) )
  73. return NULL;
  74. for ( n = 0; n < len; n++ )
  75. {
  76. code = *read++;
  77. if ( code < 32 || code > 127 )
  78. code = '?';
  79. string[n] = (char)code;
  80. }
  81. string[len] = 0;
  82. return string;
  83. }
  84. typedef FT_String* (*TT_NameEntry_ConvertFunc)( TT_NameEntry entry,
  85. FT_Memory memory );
  86. /*************************************************************************/
  87. /* */
  88. /* <Function> */
  89. /* tt_face_get_name */
  90. /* */
  91. /* <Description> */
  92. /* Returns a given ENGLISH name record in ASCII. */
  93. /* */
  94. /* <Input> */
  95. /* face :: A handle to the source face object. */
  96. /* */
  97. /* nameid :: The name id of the name record to return. */
  98. /* */
  99. /* <InOut> */
  100. /* name :: The address of a string pointer. NULL if no name is */
  101. /* present. */
  102. /* */
  103. /* <Return> */
  104. /* FreeType error code. 0 means success. */
  105. /* */
  106. static FT_Error
  107. tt_face_get_name( TT_Face face,
  108. FT_UShort nameid,
  109. FT_String** name )
  110. {
  111. FT_Memory memory = face->root.memory;
  112. FT_Error error = SFNT_Err_Ok;
  113. FT_String* result = NULL;
  114. FT_UShort n;
  115. TT_NameEntryRec* rec;
  116. FT_Int found_apple = -1;
  117. FT_Int found_apple_roman = -1;
  118. FT_Int found_apple_english = -1;
  119. FT_Int found_win = -1;
  120. FT_Int found_unicode = -1;
  121. FT_Bool is_english = 0;
  122. TT_NameEntry_ConvertFunc convert;
  123. FT_ASSERT( name );
  124. rec = face->name_table.names;
  125. for ( n = 0; n < face->num_names; n++, rec++ )
  126. {
  127. /* According to the OpenType 1.3 specification, only Microsoft or */
  128. /* Apple platform IDs might be used in the `name' table. The */
  129. /* `Unicode' platform is reserved for the `cmap' table, and the */
  130. /* `ISO' one is deprecated. */
  131. /* */
  132. /* However, the Apple TrueType specification doesn't say the same */
  133. /* thing and goes to suggest that all Unicode `name' table entries */
  134. /* should be coded in UTF-16 (in big-endian format I suppose). */
  135. /* */
  136. if ( rec->nameID == nameid && rec->stringLength > 0 )
  137. {
  138. switch ( rec->platformID )
  139. {
  140. case TT_PLATFORM_APPLE_UNICODE:
  141. case TT_PLATFORM_ISO:
  142. /* there is `languageID' to check there. We should use this */
  143. /* field only as a last solution when nothing else is */
  144. /* available. */
  145. /* */
  146. found_unicode = n;
  147. break;
  148. case TT_PLATFORM_MACINTOSH:
  149. /* This is a bit special because some fonts will use either */
  150. /* an English language id, or a Roman encoding id, to indicate */
  151. /* the English version of its font name. */
  152. /* */
  153. if ( rec->languageID == TT_MAC_LANGID_ENGLISH )
  154. found_apple_english = n;
  155. else if ( rec->encodingID == TT_MAC_ID_ROMAN )
  156. found_apple_roman = n;
  157. break;
  158. case TT_PLATFORM_MICROSOFT:
  159. /* we only take a non-English name when there is nothing */
  160. /* else available in the font */
  161. /* */
  162. if ( found_win == -1 || ( rec->languageID & 0x3FF ) == 0x009 )
  163. {
  164. switch ( rec->encodingID )
  165. {
  166. case TT_MS_ID_SYMBOL_CS:
  167. case TT_MS_ID_UNICODE_CS:
  168. case TT_MS_ID_UCS_4:
  169. is_english = FT_BOOL( ( rec->languageID & 0x3FF ) == 0x009 );
  170. found_win = n;
  171. break;
  172. default:
  173. ;
  174. }
  175. }
  176. break;
  177. default:
  178. ;
  179. }
  180. }
  181. }
  182. found_apple = found_apple_roman;
  183. if ( found_apple_english >= 0 )
  184. found_apple = found_apple_english;
  185. /* some fonts contain invalid Unicode or Macintosh formatted entries; */
  186. /* we will thus favor names encoded in Windows formats if available */
  187. /* (provided it is an English name) */
  188. /* */
  189. convert = NULL;
  190. if ( found_win >= 0 && !( found_apple >= 0 && !is_english ) )
  191. {
  192. rec = face->name_table.names + found_win;
  193. switch ( rec->encodingID )
  194. {
  195. /* all Unicode strings are encoded using UTF-16BE */
  196. case TT_MS_ID_UNICODE_CS:
  197. case TT_MS_ID_SYMBOL_CS:
  198. convert = tt_name_entry_ascii_from_utf16;
  199. break;
  200. case TT_MS_ID_UCS_4:
  201. /* Apparently, if this value is found in a name table entry, it is */
  202. /* documented as `full Unicode repertoire'. Experience with the */
  203. /* MsGothic font shipped with Windows Vista shows that this really */
  204. /* means UTF-16 encoded names (UCS-4 values are only used within */
  205. /* charmaps). */
  206. convert = tt_name_entry_ascii_from_utf16;
  207. break;
  208. default:
  209. ;
  210. }
  211. }
  212. else if ( found_apple >= 0 )
  213. {
  214. rec = face->name_table.names + found_apple;
  215. convert = tt_name_entry_ascii_from_other;
  216. }
  217. else if ( found_unicode >= 0 )
  218. {
  219. rec = face->name_table.names + found_unicode;
  220. convert = tt_name_entry_ascii_from_utf16;
  221. }
  222. if ( rec && convert )
  223. {
  224. if ( rec->string == NULL )
  225. {
  226. FT_Stream stream = face->name_table.stream;
  227. if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) ||
  228. FT_STREAM_SEEK( rec->stringOffset ) ||
  229. FT_STREAM_READ( rec->string, rec->stringLength ) )
  230. {
  231. FT_FREE( rec->string );
  232. rec->stringLength = 0;
  233. result = NULL;
  234. goto Exit;
  235. }
  236. }
  237. result = convert( rec, memory );
  238. }
  239. Exit:
  240. *name = result;
  241. return error;
  242. }
  243. static FT_Encoding
  244. sfnt_find_encoding( int platform_id,
  245. int encoding_id )
  246. {
  247. typedef struct TEncoding_
  248. {
  249. int platform_id;
  250. int encoding_id;
  251. FT_Encoding encoding;
  252. } TEncoding;
  253. static
  254. const TEncoding tt_encodings[] =
  255. {
  256. { TT_PLATFORM_ISO, -1, FT_ENCODING_UNICODE },
  257. { TT_PLATFORM_APPLE_UNICODE, -1, FT_ENCODING_UNICODE },
  258. { TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, FT_ENCODING_APPLE_ROMAN },
  259. { TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, FT_ENCODING_MS_SYMBOL },
  260. { TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, FT_ENCODING_UNICODE },
  261. { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE },
  262. { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, FT_ENCODING_SJIS },
  263. { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, FT_ENCODING_GB2312 },
  264. { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, FT_ENCODING_BIG5 },
  265. { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, FT_ENCODING_WANSUNG },
  266. { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, FT_ENCODING_JOHAB }
  267. };
  268. const TEncoding *cur, *limit;
  269. cur = tt_encodings;
  270. limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] );
  271. for ( ; cur < limit; cur++ )
  272. {
  273. if ( cur->platform_id == platform_id )
  274. {
  275. if ( cur->encoding_id == encoding_id ||
  276. cur->encoding_id == -1 )
  277. return cur->encoding;
  278. }
  279. }
  280. return FT_ENCODING_NONE;
  281. }
  282. /* Fill in face->ttc_header. If the font is not a TTC, it is */
  283. /* synthesized into a TTC with one offset table. */
  284. static FT_Error
  285. sfnt_open_font( FT_Stream stream,
  286. TT_Face face )
  287. {
  288. FT_Memory memory = stream->memory;
  289. FT_Error error;
  290. FT_ULong tag, offset;
  291. static const FT_Frame_Field ttc_header_fields[] =
  292. {
  293. #undef FT_STRUCTURE
  294. #define FT_STRUCTURE TTC_HeaderRec
  295. FT_FRAME_START( 8 ),
  296. FT_FRAME_LONG( version ),
  297. FT_FRAME_LONG( count ),
  298. FT_FRAME_END
  299. };
  300. face->ttc_header.tag = 0;
  301. face->ttc_header.version = 0;
  302. face->ttc_header.count = 0;
  303. offset = FT_STREAM_POS();
  304. if ( FT_READ_ULONG( tag ) )
  305. return error;
  306. if ( tag != 0x00010000UL &&
  307. tag != TTAG_ttcf &&
  308. tag != TTAG_OTTO &&
  309. tag != TTAG_true &&
  310. tag != TTAG_typ1 &&
  311. tag != 0x00020000UL )
  312. return SFNT_Err_Unknown_File_Format;
  313. face->ttc_header.tag = TTAG_ttcf;
  314. if ( tag == TTAG_ttcf )
  315. {
  316. FT_Int n;
  317. FT_TRACE3(( "sfnt_open_font: file is a collection\n" ));
  318. if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
  319. return error;
  320. /* now read the offsets of each font in the file */
  321. if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
  322. return error;
  323. if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )
  324. return error;
  325. for ( n = 0; n < face->ttc_header.count; n++ )
  326. face->ttc_header.offsets[n] = FT_GET_ULONG();
  327. FT_FRAME_EXIT();
  328. }
  329. else
  330. {
  331. FT_TRACE3(( "sfnt_open_font: synthesize TTC\n" ));
  332. face->ttc_header.version = 1 << 16;
  333. face->ttc_header.count = 1;
  334. if ( FT_NEW( face->ttc_header.offsets ) )
  335. return error;
  336. face->ttc_header.offsets[0] = offset;
  337. }
  338. return error;
  339. }
  340. FT_LOCAL_DEF( FT_Error )
  341. sfnt_init_face( FT_Stream stream,
  342. TT_Face face,
  343. FT_Int face_index,
  344. FT_Int num_params,
  345. FT_Parameter* params )
  346. {
  347. FT_Error error;
  348. FT_Library library = face->root.driver->root.library;
  349. SFNT_Service sfnt;
  350. /* for now, parameters are unused */
  351. FT_UNUSED( num_params );
  352. FT_UNUSED( params );
  353. sfnt = (SFNT_Service)face->sfnt;
  354. if ( !sfnt )
  355. {
  356. sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
  357. if ( !sfnt )
  358. return SFNT_Err_Invalid_File_Format;
  359. face->sfnt = sfnt;
  360. face->goto_table = sfnt->goto_table;
  361. }
  362. FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );
  363. error = sfnt_open_font( stream, face );
  364. if ( error )
  365. return error;
  366. FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index ));
  367. if ( face_index < 0 )
  368. face_index = 0;
  369. if ( face_index >= face->ttc_header.count )
  370. return SFNT_Err_Invalid_Argument;
  371. if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
  372. return error;
  373. /* check that we have a valid TrueType file */
  374. error = sfnt->load_font_dir( face, stream );
  375. if ( error )
  376. return error;
  377. face->root.num_faces = face->ttc_header.count;
  378. face->root.face_index = face_index;
  379. return error;
  380. }
  381. #define LOAD_( x ) \
  382. do { \
  383. FT_TRACE2(( "`" #x "' " )); \
  384. FT_TRACE3(( "-->\n" )); \
  385. \
  386. error = sfnt->load_##x( face, stream ); \
  387. \
  388. FT_TRACE2(( "%s\n", ( !error ) \
  389. ? "loaded" \
  390. : ( error == SFNT_Err_Table_Missing ) \
  391. ? "missing" \
  392. : "failed to load" )); \
  393. FT_TRACE3(( "\n" )); \
  394. } while ( 0 )
  395. #define LOADM_( x, vertical ) \
  396. do { \
  397. FT_TRACE2(( "`%s" #x "' ", \
  398. vertical ? "vertical " : "" )); \
  399. FT_TRACE3(( "-->\n" )); \
  400. \
  401. error = sfnt->load_##x( face, stream, vertical ); \
  402. \
  403. FT_TRACE2(( "%s\n", ( !error ) \
  404. ? "loaded" \
  405. : ( error == SFNT_Err_Table_Missing ) \
  406. ? "missing" \
  407. : "failed to load" )); \
  408. FT_TRACE3(( "\n" )); \
  409. } while ( 0 )
  410. #define GET_NAME( id, field ) \
  411. do { \
  412. error = tt_face_get_name( face, TT_NAME_ID_##id, field ); \
  413. if ( error ) \
  414. goto Exit; \
  415. } while ( 0 )
  416. FT_LOCAL_DEF( FT_Error )
  417. sfnt_load_face( FT_Stream stream,
  418. TT_Face face,
  419. FT_Int face_index,
  420. FT_Int num_params,
  421. FT_Parameter* params )
  422. {
  423. FT_Error error;
  424. #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  425. FT_Error psnames_error;
  426. #endif
  427. FT_Bool has_outline;
  428. FT_Bool is_apple_sbit;
  429. FT_Bool ignore_preferred_family = FALSE;
  430. FT_Bool ignore_preferred_subfamily = FALSE;
  431. SFNT_Service sfnt = (SFNT_Service)face->sfnt;
  432. FT_UNUSED( face_index );
  433. /* Check parameters */
  434. {
  435. FT_Int i;
  436. for ( i = 0; i < num_params; i++ )
  437. {
  438. if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY )
  439. ignore_preferred_family = TRUE;
  440. else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY )
  441. ignore_preferred_subfamily = TRUE;
  442. }
  443. }
  444. /* Load tables */
  445. /* We now support two SFNT-based bitmapped font formats. They */
  446. /* are recognized easily as they do not include a `glyf' */
  447. /* table. */
  448. /* */
  449. /* The first format comes from Apple, and uses a table named */
  450. /* `bhed' instead of `head' to store the font header (using */
  451. /* the same format). It also doesn't include horizontal and */
  452. /* vertical metrics tables (i.e. `hhea' and `vhea' tables are */
  453. /* missing). */
  454. /* */
  455. /* The other format comes from Microsoft, and is used with */
  456. /* WinCE/PocketPC. It looks like a standard TTF, except that */
  457. /* it doesn't contain outlines. */
  458. /* */
  459. FT_TRACE2(( "sfnt_load_face: %08p\n\n", face ));
  460. /* do we have outlines in there? */
  461. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  462. has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 ||
  463. tt_face_lookup_table( face, TTAG_glyf ) != 0 ||
  464. tt_face_lookup_table( face, TTAG_CFF ) != 0 );
  465. #else
  466. has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 ||
  467. tt_face_lookup_table( face, TTAG_CFF ) != 0 );
  468. #endif
  469. is_apple_sbit = 0;
  470. /* if this font doesn't contain outlines, we try to load */
  471. /* a `bhed' table */
  472. if ( !has_outline && sfnt->load_bhed )
  473. {
  474. LOAD_( bhed );
  475. is_apple_sbit = FT_BOOL( !error );
  476. }
  477. /* load the font header (`head' table) if this isn't an Apple */
  478. /* sbit font file */
  479. if ( !is_apple_sbit )
  480. {
  481. LOAD_( head );
  482. if ( error )
  483. goto Exit;
  484. }
  485. if ( face->header.Units_Per_EM == 0 )
  486. {
  487. error = SFNT_Err_Invalid_Table;
  488. goto Exit;
  489. }
  490. /* the following tables are often not present in embedded TrueType */
  491. /* fonts within PDF documents, so don't check for them. */
  492. LOAD_( maxp );
  493. LOAD_( cmap );
  494. /* the following tables are optional in PCL fonts -- */
  495. /* don't check for errors */
  496. LOAD_( name );
  497. LOAD_( post );
  498. #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  499. psnames_error = error;
  500. #endif
  501. /* do not load the metrics headers and tables if this is an Apple */
  502. /* sbit font file */
  503. if ( !is_apple_sbit )
  504. {
  505. /* load the `hhea' and `hmtx' tables */
  506. LOADM_( hhea, 0 );
  507. if ( !error )
  508. {
  509. LOADM_( hmtx, 0 );
  510. if ( error == SFNT_Err_Table_Missing )
  511. {
  512. error = SFNT_Err_Hmtx_Table_Missing;
  513. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  514. /* If this is an incrementally loaded font and there are */
  515. /* overriding metrics, tolerate a missing `hmtx' table. */
  516. if ( face->root.internal->incremental_interface &&
  517. face->root.internal->incremental_interface->funcs->
  518. get_glyph_metrics )
  519. {
  520. face->horizontal.number_Of_HMetrics = 0;
  521. error = SFNT_Err_Ok;
  522. }
  523. #endif
  524. }
  525. }
  526. else if ( error == SFNT_Err_Table_Missing )
  527. {
  528. /* No `hhea' table necessary for SFNT Mac fonts. */
  529. if ( face->format_tag == TTAG_true )
  530. {
  531. FT_TRACE2(( "This is an SFNT Mac font.\n" ));
  532. has_outline = 0;
  533. error = SFNT_Err_Ok;
  534. }
  535. else
  536. {
  537. error = SFNT_Err_Horiz_Header_Missing;
  538. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  539. /* If this is an incrementally loaded font and there are */
  540. /* overriding metrics, tolerate a missing `hhea' table. */
  541. if ( face->root.internal->incremental_interface &&
  542. face->root.internal->incremental_interface->funcs->
  543. get_glyph_metrics )
  544. {
  545. face->horizontal.number_Of_HMetrics = 0;
  546. error = SFNT_Err_Ok;
  547. }
  548. #endif
  549. }
  550. }
  551. if ( error )
  552. goto Exit;
  553. /* try to load the `vhea' and `vmtx' tables */
  554. LOADM_( hhea, 1 );
  555. if ( !error )
  556. {
  557. LOADM_( hmtx, 1 );
  558. if ( !error )
  559. face->vertical_info = 1;
  560. }
  561. if ( error && error != SFNT_Err_Table_Missing )
  562. goto Exit;
  563. LOAD_( os2 );
  564. if ( error )
  565. {
  566. if ( error != SFNT_Err_Table_Missing )
  567. goto Exit;
  568. face->os2.version = 0xFFFFU;
  569. }
  570. }
  571. /* the optional tables */
  572. /* embedded bitmap support */
  573. if ( sfnt->load_eblc )
  574. {
  575. LOAD_( eblc );
  576. if ( error )
  577. {
  578. /* a font which contains neither bitmaps nor outlines is */
  579. /* still valid (although rather useless in most cases); */
  580. /* however, you can find such stripped fonts in PDFs */
  581. if ( error == SFNT_Err_Table_Missing )
  582. error = SFNT_Err_Ok;
  583. else
  584. goto Exit;
  585. }
  586. }
  587. LOAD_( pclt );
  588. if ( error )
  589. {
  590. if ( error != SFNT_Err_Table_Missing )
  591. goto Exit;
  592. face->pclt.Version = 0;
  593. }
  594. /* consider the kerning and gasp tables as optional */
  595. LOAD_( gasp );
  596. LOAD_( kern );
  597. face->root.num_glyphs = face->max_profile.numGlyphs;
  598. /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */
  599. /* a WWS-only font face. `WWS' stands for `weight', width', and */
  600. /* `slope', a term used by Microsoft's Windows Presentation */
  601. /* Foundation (WPF). This flag has been introduced in version */
  602. /* 1.5 of the OpenType specification (May 2008). */
  603. face->root.family_name = NULL;
  604. face->root.style_name = NULL;
  605. if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 )
  606. {
  607. if ( !ignore_preferred_family )
  608. GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
  609. if ( !face->root.family_name )
  610. GET_NAME( FONT_FAMILY, &face->root.family_name );
  611. if ( !ignore_preferred_subfamily )
  612. GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
  613. if ( !face->root.style_name )
  614. GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
  615. }
  616. else
  617. {
  618. GET_NAME( WWS_FAMILY, &face->root.family_name );
  619. if ( !face->root.family_name && !ignore_preferred_family )
  620. GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
  621. if ( !face->root.family_name )
  622. GET_NAME( FONT_FAMILY, &face->root.family_name );
  623. GET_NAME( WWS_SUBFAMILY, &face->root.style_name );
  624. if ( !face->root.style_name && !ignore_preferred_subfamily )
  625. GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
  626. if ( !face->root.style_name )
  627. GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
  628. }
  629. /* now set up root fields */
  630. {
  631. FT_Face root = &face->root;
  632. FT_Long flags = root->face_flags;
  633. /*********************************************************************/
  634. /* */
  635. /* Compute face flags. */
  636. /* */
  637. if ( has_outline == TRUE )
  638. flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
  639. /* The sfnt driver only supports bitmap fonts natively, thus we */
  640. /* don't set FT_FACE_FLAG_HINTER. */
  641. flags |= FT_FACE_FLAG_SFNT | /* SFNT file format */
  642. FT_FACE_FLAG_HORIZONTAL; /* horizontal data */
  643. #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  644. if ( psnames_error == SFNT_Err_Ok &&
  645. face->postscript.FormatType != 0x00030000L )
  646. flags |= FT_FACE_FLAG_GLYPH_NAMES;
  647. #endif
  648. /* fixed width font? */
  649. if ( face->postscript.isFixedPitch )
  650. flags |= FT_FACE_FLAG_FIXED_WIDTH;
  651. /* vertical information? */
  652. if ( face->vertical_info )
  653. flags |= FT_FACE_FLAG_VERTICAL;
  654. /* kerning available ? */
  655. if ( TT_FACE_HAS_KERNING( face ) )
  656. flags |= FT_FACE_FLAG_KERNING;
  657. #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  658. /* Don't bother to load the tables unless somebody asks for them. */
  659. /* No need to do work which will (probably) not be used. */
  660. if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 &&
  661. tt_face_lookup_table( face, TTAG_fvar ) != 0 &&
  662. tt_face_lookup_table( face, TTAG_gvar ) != 0 )
  663. flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
  664. #endif
  665. root->face_flags = flags;
  666. /*********************************************************************/
  667. /* */
  668. /* Compute style flags. */
  669. /* */
  670. flags = 0;
  671. if ( has_outline == TRUE && face->os2.version != 0xFFFFU )
  672. {
  673. /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */
  674. /* indicates an oblique font face. This flag has been */
  675. /* introduced in version 1.5 of the OpenType specification. */
  676. if ( face->os2.fsSelection & 512 ) /* bit 9 */
  677. flags |= FT_STYLE_FLAG_ITALIC;
  678. else if ( face->os2.fsSelection & 1 ) /* bit 0 */
  679. flags |= FT_STYLE_FLAG_ITALIC;
  680. if ( face->os2.fsSelection & 32 ) /* bit 5 */
  681. flags |= FT_STYLE_FLAG_BOLD;
  682. }
  683. else
  684. {
  685. /* this is an old Mac font, use the header field */
  686. if ( face->header.Mac_Style & 1 )
  687. flags |= FT_STYLE_FLAG_BOLD;
  688. if ( face->header.Mac_Style & 2 )
  689. flags |= FT_STYLE_FLAG_ITALIC;
  690. }
  691. root->style_flags = flags;
  692. /*********************************************************************/
  693. /* */
  694. /* Polish the charmaps. */
  695. /* */
  696. /* Try to set the charmap encoding according to the platform & */
  697. /* encoding ID of each charmap. */
  698. /* */
  699. tt_face_build_cmaps( face ); /* ignore errors */
  700. /* set the encoding fields */
  701. {
  702. FT_Int m;
  703. for ( m = 0; m < root->num_charmaps; m++ )
  704. {
  705. FT_CharMap charmap = root->charmaps[m];
  706. charmap->encoding = sfnt_find_encoding( charmap->platform_id,
  707. charmap->encoding_id );
  708. #if 0
  709. if ( root->charmap == NULL &&
  710. charmap->encoding == FT_ENCODING_UNICODE )
  711. {
  712. /* set 'root->charmap' to the first Unicode encoding we find */
  713. root->charmap = charmap;
  714. }
  715. #endif
  716. }
  717. }
  718. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  719. /*
  720. * Now allocate the root array of FT_Bitmap_Size records and
  721. * populate them. Unfortunately, it isn't possible to indicate bit
  722. * depths in the FT_Bitmap_Size record. This is a design error.
  723. */
  724. {
  725. FT_UInt i, count;
  726. #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
  727. count = face->sbit_num_strikes;
  728. #else
  729. count = (FT_UInt)face->num_sbit_strikes;
  730. #endif
  731. if ( count > 0 )
  732. {
  733. FT_Memory memory = face->root.stream->memory;
  734. FT_UShort em_size = face->header.Units_Per_EM;
  735. FT_Short avgwidth = face->os2.xAvgCharWidth;
  736. FT_Size_Metrics metrics;
  737. if ( em_size == 0 || face->os2.version == 0xFFFFU )
  738. {
  739. avgwidth = 0;
  740. em_size = 1;
  741. }
  742. if ( FT_NEW_ARRAY( root->available_sizes, count ) )
  743. goto Exit;
  744. for ( i = 0; i < count; i++ )
  745. {
  746. FT_Bitmap_Size* bsize = root->available_sizes + i;
  747. error = sfnt->load_strike_metrics( face, i, &metrics );
  748. if ( error )
  749. goto Exit;
  750. bsize->height = (FT_Short)( metrics.height >> 6 );
  751. bsize->width = (FT_Short)(
  752. ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size );
  753. bsize->x_ppem = metrics.x_ppem << 6;
  754. bsize->y_ppem = metrics.y_ppem << 6;
  755. /* assume 72dpi */
  756. bsize->size = metrics.y_ppem << 6;
  757. }
  758. root->face_flags |= FT_FACE_FLAG_FIXED_SIZES;
  759. root->num_fixed_sizes = (FT_Int)count;
  760. }
  761. }
  762. #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
  763. /* a font with no bitmaps and no outlines is scalable; */
  764. /* it has only empty glyphs then */
  765. if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) )
  766. root->face_flags |= FT_FACE_FLAG_SCALABLE;
  767. /*********************************************************************/
  768. /* */
  769. /* Set up metrics. */
  770. /* */
  771. if ( FT_IS_SCALABLE( root ) )
  772. {
  773. /* XXX What about if outline header is missing */
  774. /* (e.g. sfnt wrapped bitmap)? */
  775. root->bbox.xMin = face->header.xMin;
  776. root->bbox.yMin = face->header.yMin;
  777. root->bbox.xMax = face->header.xMax;
  778. root->bbox.yMax = face->header.yMax;
  779. root->units_per_EM = face->header.Units_Per_EM;
  780. /* XXX: Computing the ascender/descender/height is very different */
  781. /* from what the specification tells you. Apparently, we */
  782. /* must be careful because */
  783. /* */
  784. /* - not all fonts have an OS/2 table; in this case, we take */
  785. /* the values in the horizontal header. However, these */
  786. /* values very often are not reliable. */
  787. /* */
  788. /* - otherwise, the correct typographic values are in the */
  789. /* sTypoAscender, sTypoDescender & sTypoLineGap fields. */
  790. /* */
  791. /* However, certain fonts have these fields set to 0. */
  792. /* Rather, they have usWinAscent & usWinDescent correctly */
  793. /* set (but with different values). */
  794. /* */
  795. /* As an example, Arial Narrow is implemented through four */
  796. /* files ARIALN.TTF, ARIALNI.TTF, ARIALNB.TTF & ARIALNBI.TTF */
  797. /* */
  798. /* Strangely, all fonts have the same values in their */
  799. /* sTypoXXX fields, except ARIALNB which sets them to 0. */
  800. /* */
  801. /* On the other hand, they all have different */
  802. /* usWinAscent/Descent values -- as a conclusion, the OS/2 */
  803. /* table cannot be used to compute the text height reliably! */
  804. /* */
  805. /* The ascender/descender/height are computed from the OS/2 table */
  806. /* when found. Otherwise, they're taken from the horizontal */
  807. /* header. */
  808. /* */
  809. root->ascender = face->horizontal.Ascender;
  810. root->descender = face->horizontal.Descender;
  811. root->height = (FT_Short)( root->ascender - root->descender +
  812. face->horizontal.Line_Gap );
  813. #if 0
  814. /* if the line_gap is 0, we add an extra 15% to the text height -- */
  815. /* this computation is based on various versions of Times New Roman */
  816. if ( face->horizontal.Line_Gap == 0 )
  817. root->height = (FT_Short)( ( root->height * 115 + 50 ) / 100 );
  818. #endif /* 0 */
  819. #if 0
  820. /* some fonts have the OS/2 "sTypoAscender", "sTypoDescender" & */
  821. /* "sTypoLineGap" fields set to 0, like ARIALNB.TTF */
  822. if ( face->os2.version != 0xFFFFU && root->ascender )
  823. {
  824. FT_Int height;
  825. root->ascender = face->os2.sTypoAscender;
  826. root->descender = -face->os2.sTypoDescender;
  827. height = root->ascender + root->descender + face->os2.sTypoLineGap;
  828. if ( height > root->height )
  829. root->height = height;
  830. }
  831. #endif /* 0 */
  832. root->max_advance_width = face->horizontal.advance_Width_Max;
  833. root->max_advance_height = (FT_Short)( face->vertical_info
  834. ? face->vertical.advance_Height_Max
  835. : root->height );
  836. /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */
  837. /* Adjust underline position from top edge to centre of */
  838. /* stroke to convert TrueType meaning to FreeType meaning. */
  839. root->underline_position = face->postscript.underlinePosition -
  840. face->postscript.underlineThickness / 2;
  841. root->underline_thickness = face->postscript.underlineThickness;
  842. }
  843. }
  844. Exit:
  845. FT_TRACE2(( "sfnt_load_face: done\n" ));
  846. return error;
  847. }
  848. #undef LOAD_
  849. #undef LOADM_
  850. #undef GET_NAME
  851. FT_LOCAL_DEF( void )
  852. sfnt_done_face( TT_Face face )
  853. {
  854. FT_Memory memory;
  855. SFNT_Service sfnt;
  856. if ( !face )
  857. return;
  858. memory = face->root.memory;
  859. sfnt = (SFNT_Service)face->sfnt;
  860. if ( sfnt )
  861. {
  862. /* destroy the postscript names table if it is loaded */
  863. if ( sfnt->free_psnames )
  864. sfnt->free_psnames( face );
  865. /* destroy the embedded bitmaps table if it is loaded */
  866. if ( sfnt->free_eblc )
  867. sfnt->free_eblc( face );
  868. }
  869. #ifdef TT_CONFIG_OPTION_BDF
  870. /* freeing the embedded BDF properties */
  871. tt_face_free_bdf_props( face );
  872. #endif
  873. /* freeing the kerning table */
  874. tt_face_done_kern( face );
  875. /* freeing the collection table */
  876. FT_FREE( face->ttc_header.offsets );
  877. face->ttc_header.count = 0;
  878. /* freeing table directory */
  879. FT_FREE( face->dir_tables );
  880. face->num_tables = 0;
  881. {
  882. FT_Stream stream = FT_FACE_STREAM( face );
  883. /* simply release the 'cmap' table frame */
  884. FT_FRAME_RELEASE( face->cmap_table );
  885. face->cmap_size = 0;
  886. }
  887. /* freeing the horizontal metrics */
  888. #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
  889. {
  890. FT_Stream stream = FT_FACE_STREAM( face );
  891. FT_FRAME_RELEASE( face->horz_metrics );
  892. FT_FRAME_RELEASE( face->vert_metrics );
  893. face->horz_metrics_size = 0;
  894. face->vert_metrics_size = 0;
  895. }
  896. #else
  897. FT_FREE( face->horizontal.long_metrics );
  898. FT_FREE( face->horizontal.short_metrics );
  899. #endif
  900. /* freeing the vertical ones, if any */
  901. if ( face->vertical_info )
  902. {
  903. FT_FREE( face->vertical.long_metrics );
  904. FT_FREE( face->vertical.short_metrics );
  905. face->vertical_info = 0;
  906. }
  907. /* freeing the gasp table */
  908. FT_FREE( face->gasp.gaspRanges );
  909. face->gasp.numRanges = 0;
  910. /* freeing the name table */
  911. if ( sfnt )
  912. sfnt->free_name( face );
  913. /* freeing family and style name */
  914. FT_FREE( face->root.family_name );
  915. FT_FREE( face->root.style_name );
  916. /* freeing sbit size table */
  917. FT_FREE( face->root.available_sizes );
  918. face->root.num_fixed_sizes = 0;
  919. FT_FREE( face->postscript_name );
  920. face->sfnt = 0;
  921. }
  922. /* END */