/src/freetype/src/sfnt/sfobjs.c

https://bitbucket.org/cabalistic/ogredeps/ · C · 1163 lines · 718 code · 228 blank · 217 comment · 179 complexity · d5c958f0d978210a769e9369ad03c97c MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* sfobjs.c */
  4. /* */
  5. /* SFNT object management (base). */
  6. /* */
  7. /* Copyright 1996-2008, 2010-2011 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 ), /* this is ULong in the specs */
  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. {
  313. FT_TRACE2(( " not a font using the SFNT container format\n" ));
  314. return SFNT_Err_Unknown_File_Format;
  315. }
  316. face->ttc_header.tag = TTAG_ttcf;
  317. if ( tag == TTAG_ttcf )
  318. {
  319. FT_Int n;
  320. FT_TRACE3(( "sfnt_open_font: file is a collection\n" ));
  321. if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
  322. return error;
  323. if ( face->ttc_header.count == 0 )
  324. return SFNT_Err_Invalid_Table;
  325. /* a rough size estimate: let's conservatively assume that there */
  326. /* is just a single table info in each subfont header (12 + 16*1 = */
  327. /* 28 bytes), thus we have (at least) `12 + 4*count' bytes for the */
  328. /* size of the TTC header plus `28*count' bytes for all subfont */
  329. /* headers */
  330. if ( (FT_ULong)face->ttc_header.count > stream->size / ( 28 + 4 ) )
  331. return SFNT_Err_Array_Too_Large;
  332. /* now read the offsets of each font in the file */
  333. if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
  334. return error;
  335. if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )
  336. return error;
  337. for ( n = 0; n < face->ttc_header.count; n++ )
  338. face->ttc_header.offsets[n] = FT_GET_ULONG();
  339. FT_FRAME_EXIT();
  340. }
  341. else
  342. {
  343. FT_TRACE3(( "sfnt_open_font: synthesize TTC\n" ));
  344. face->ttc_header.version = 1 << 16;
  345. face->ttc_header.count = 1;
  346. if ( FT_NEW( face->ttc_header.offsets ) )
  347. return error;
  348. face->ttc_header.offsets[0] = offset;
  349. }
  350. return error;
  351. }
  352. FT_LOCAL_DEF( FT_Error )
  353. sfnt_init_face( FT_Stream stream,
  354. TT_Face face,
  355. FT_Int face_index,
  356. FT_Int num_params,
  357. FT_Parameter* params )
  358. {
  359. FT_Error error;
  360. FT_Library library = face->root.driver->root.library;
  361. SFNT_Service sfnt;
  362. /* for now, parameters are unused */
  363. FT_UNUSED( num_params );
  364. FT_UNUSED( params );
  365. sfnt = (SFNT_Service)face->sfnt;
  366. if ( !sfnt )
  367. {
  368. sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
  369. if ( !sfnt )
  370. {
  371. FT_ERROR(( "sfnt_init_face: cannot access `sfnt' module\n" ));
  372. return SFNT_Err_Missing_Module;
  373. }
  374. face->sfnt = sfnt;
  375. face->goto_table = sfnt->goto_table;
  376. }
  377. FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );
  378. FT_TRACE2(( "SFNT driver\n" ));
  379. error = sfnt_open_font( stream, face );
  380. if ( error )
  381. return error;
  382. FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index ));
  383. if ( face_index < 0 )
  384. face_index = 0;
  385. if ( face_index >= face->ttc_header.count )
  386. return SFNT_Err_Invalid_Argument;
  387. if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
  388. return error;
  389. /* check that we have a valid TrueType file */
  390. error = sfnt->load_font_dir( face, stream );
  391. if ( error )
  392. return error;
  393. face->root.num_faces = face->ttc_header.count;
  394. face->root.face_index = face_index;
  395. return error;
  396. }
  397. #define LOAD_( x ) \
  398. do { \
  399. FT_TRACE2(( "`" #x "' " )); \
  400. FT_TRACE3(( "-->\n" )); \
  401. \
  402. error = sfnt->load_##x( face, stream ); \
  403. \
  404. FT_TRACE2(( "%s\n", ( !error ) \
  405. ? "loaded" \
  406. : ( error == SFNT_Err_Table_Missing ) \
  407. ? "missing" \
  408. : "failed to load" )); \
  409. FT_TRACE3(( "\n" )); \
  410. } while ( 0 )
  411. #define LOADM_( x, vertical ) \
  412. do { \
  413. FT_TRACE2(( "`%s" #x "' ", \
  414. vertical ? "vertical " : "" )); \
  415. FT_TRACE3(( "-->\n" )); \
  416. \
  417. error = sfnt->load_##x( face, stream, vertical ); \
  418. \
  419. FT_TRACE2(( "%s\n", ( !error ) \
  420. ? "loaded" \
  421. : ( error == SFNT_Err_Table_Missing ) \
  422. ? "missing" \
  423. : "failed to load" )); \
  424. FT_TRACE3(( "\n" )); \
  425. } while ( 0 )
  426. #define GET_NAME( id, field ) \
  427. do { \
  428. error = tt_face_get_name( face, TT_NAME_ID_##id, field ); \
  429. if ( error ) \
  430. goto Exit; \
  431. } while ( 0 )
  432. FT_LOCAL_DEF( FT_Error )
  433. sfnt_load_face( FT_Stream stream,
  434. TT_Face face,
  435. FT_Int face_index,
  436. FT_Int num_params,
  437. FT_Parameter* params )
  438. {
  439. FT_Error error;
  440. #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  441. FT_Error psnames_error;
  442. #endif
  443. FT_Bool has_outline;
  444. FT_Bool is_apple_sbit;
  445. FT_Bool ignore_preferred_family = FALSE;
  446. FT_Bool ignore_preferred_subfamily = FALSE;
  447. SFNT_Service sfnt = (SFNT_Service)face->sfnt;
  448. FT_UNUSED( face_index );
  449. /* Check parameters */
  450. {
  451. FT_Int i;
  452. for ( i = 0; i < num_params; i++ )
  453. {
  454. if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY )
  455. ignore_preferred_family = TRUE;
  456. else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY )
  457. ignore_preferred_subfamily = TRUE;
  458. }
  459. }
  460. /* Load tables */
  461. /* We now support two SFNT-based bitmapped font formats. They */
  462. /* are recognized easily as they do not include a `glyf' */
  463. /* table. */
  464. /* */
  465. /* The first format comes from Apple, and uses a table named */
  466. /* `bhed' instead of `head' to store the font header (using */
  467. /* the same format). It also doesn't include horizontal and */
  468. /* vertical metrics tables (i.e. `hhea' and `vhea' tables are */
  469. /* missing). */
  470. /* */
  471. /* The other format comes from Microsoft, and is used with */
  472. /* WinCE/PocketPC. It looks like a standard TTF, except that */
  473. /* it doesn't contain outlines. */
  474. /* */
  475. FT_TRACE2(( "sfnt_load_face: %08p\n\n", face ));
  476. /* do we have outlines in there? */
  477. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  478. has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 ||
  479. tt_face_lookup_table( face, TTAG_glyf ) != 0 ||
  480. tt_face_lookup_table( face, TTAG_CFF ) != 0 );
  481. #else
  482. has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 ||
  483. tt_face_lookup_table( face, TTAG_CFF ) != 0 );
  484. #endif
  485. is_apple_sbit = 0;
  486. /* if this font doesn't contain outlines, we try to load */
  487. /* a `bhed' table */
  488. if ( !has_outline && sfnt->load_bhed )
  489. {
  490. LOAD_( bhed );
  491. is_apple_sbit = FT_BOOL( !error );
  492. }
  493. /* load the font header (`head' table) if this isn't an Apple */
  494. /* sbit font file */
  495. if ( !is_apple_sbit )
  496. {
  497. LOAD_( head );
  498. if ( error )
  499. goto Exit;
  500. }
  501. if ( face->header.Units_Per_EM == 0 )
  502. {
  503. error = SFNT_Err_Invalid_Table;
  504. goto Exit;
  505. }
  506. /* the following tables are often not present in embedded TrueType */
  507. /* fonts within PDF documents, so don't check for them. */
  508. LOAD_( maxp );
  509. LOAD_( cmap );
  510. /* the following tables are optional in PCL fonts -- */
  511. /* don't check for errors */
  512. LOAD_( name );
  513. LOAD_( post );
  514. #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  515. psnames_error = error;
  516. #endif
  517. /* do not load the metrics headers and tables if this is an Apple */
  518. /* sbit font file */
  519. if ( !is_apple_sbit )
  520. {
  521. /* load the `hhea' and `hmtx' tables */
  522. LOADM_( hhea, 0 );
  523. if ( !error )
  524. {
  525. LOADM_( hmtx, 0 );
  526. if ( error == SFNT_Err_Table_Missing )
  527. {
  528. error = SFNT_Err_Hmtx_Table_Missing;
  529. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  530. /* If this is an incrementally loaded font and there are */
  531. /* overriding metrics, tolerate a missing `hmtx' table. */
  532. if ( face->root.internal->incremental_interface &&
  533. face->root.internal->incremental_interface->funcs->
  534. get_glyph_metrics )
  535. {
  536. face->horizontal.number_Of_HMetrics = 0;
  537. error = SFNT_Err_Ok;
  538. }
  539. #endif
  540. }
  541. }
  542. else if ( error == SFNT_Err_Table_Missing )
  543. {
  544. /* No `hhea' table necessary for SFNT Mac fonts. */
  545. if ( face->format_tag == TTAG_true )
  546. {
  547. FT_TRACE2(( "This is an SFNT Mac font.\n" ));
  548. has_outline = 0;
  549. error = SFNT_Err_Ok;
  550. }
  551. else
  552. {
  553. error = SFNT_Err_Horiz_Header_Missing;
  554. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  555. /* If this is an incrementally loaded font and there are */
  556. /* overriding metrics, tolerate a missing `hhea' table. */
  557. if ( face->root.internal->incremental_interface &&
  558. face->root.internal->incremental_interface->funcs->
  559. get_glyph_metrics )
  560. {
  561. face->horizontal.number_Of_HMetrics = 0;
  562. error = SFNT_Err_Ok;
  563. }
  564. #endif
  565. }
  566. }
  567. if ( error )
  568. goto Exit;
  569. /* try to load the `vhea' and `vmtx' tables */
  570. LOADM_( hhea, 1 );
  571. if ( !error )
  572. {
  573. LOADM_( hmtx, 1 );
  574. if ( !error )
  575. face->vertical_info = 1;
  576. }
  577. if ( error && error != SFNT_Err_Table_Missing )
  578. goto Exit;
  579. LOAD_( os2 );
  580. if ( error )
  581. {
  582. /* we treat the table as missing if there are any errors */
  583. face->os2.version = 0xFFFFU;
  584. }
  585. }
  586. /* the optional tables */
  587. /* embedded bitmap support */
  588. if ( sfnt->load_eblc )
  589. {
  590. LOAD_( eblc );
  591. if ( error )
  592. {
  593. /* a font which contains neither bitmaps nor outlines is */
  594. /* still valid (although rather useless in most cases); */
  595. /* however, you can find such stripped fonts in PDFs */
  596. if ( error == SFNT_Err_Table_Missing )
  597. error = SFNT_Err_Ok;
  598. else
  599. goto Exit;
  600. }
  601. }
  602. LOAD_( pclt );
  603. if ( error )
  604. {
  605. if ( error != SFNT_Err_Table_Missing )
  606. goto Exit;
  607. face->pclt.Version = 0;
  608. }
  609. /* consider the kerning and gasp tables as optional */
  610. LOAD_( gasp );
  611. LOAD_( kern );
  612. face->root.num_glyphs = face->max_profile.numGlyphs;
  613. /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */
  614. /* a WWS-only font face. `WWS' stands for `weight', width', and */
  615. /* `slope', a term used by Microsoft's Windows Presentation */
  616. /* Foundation (WPF). This flag has been introduced in version */
  617. /* 1.5 of the OpenType specification (May 2008). */
  618. face->root.family_name = NULL;
  619. face->root.style_name = NULL;
  620. if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 )
  621. {
  622. if ( !ignore_preferred_family )
  623. GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
  624. if ( !face->root.family_name )
  625. GET_NAME( FONT_FAMILY, &face->root.family_name );
  626. if ( !ignore_preferred_subfamily )
  627. GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
  628. if ( !face->root.style_name )
  629. GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
  630. }
  631. else
  632. {
  633. GET_NAME( WWS_FAMILY, &face->root.family_name );
  634. if ( !face->root.family_name && !ignore_preferred_family )
  635. GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
  636. if ( !face->root.family_name )
  637. GET_NAME( FONT_FAMILY, &face->root.family_name );
  638. GET_NAME( WWS_SUBFAMILY, &face->root.style_name );
  639. if ( !face->root.style_name && !ignore_preferred_subfamily )
  640. GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
  641. if ( !face->root.style_name )
  642. GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
  643. }
  644. /* now set up root fields */
  645. {
  646. FT_Face root = &face->root;
  647. FT_Long flags = root->face_flags;
  648. /*********************************************************************/
  649. /* */
  650. /* Compute face flags. */
  651. /* */
  652. if ( has_outline == TRUE )
  653. flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
  654. /* The sfnt driver only supports bitmap fonts natively, thus we */
  655. /* don't set FT_FACE_FLAG_HINTER. */
  656. flags |= FT_FACE_FLAG_SFNT | /* SFNT file format */
  657. FT_FACE_FLAG_HORIZONTAL; /* horizontal data */
  658. #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  659. if ( psnames_error == SFNT_Err_Ok &&
  660. face->postscript.FormatType != 0x00030000L )
  661. flags |= FT_FACE_FLAG_GLYPH_NAMES;
  662. #endif
  663. /* fixed width font? */
  664. if ( face->postscript.isFixedPitch )
  665. flags |= FT_FACE_FLAG_FIXED_WIDTH;
  666. /* vertical information? */
  667. if ( face->vertical_info )
  668. flags |= FT_FACE_FLAG_VERTICAL;
  669. /* kerning available ? */
  670. if ( TT_FACE_HAS_KERNING( face ) )
  671. flags |= FT_FACE_FLAG_KERNING;
  672. #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  673. /* Don't bother to load the tables unless somebody asks for them. */
  674. /* No need to do work which will (probably) not be used. */
  675. if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 &&
  676. tt_face_lookup_table( face, TTAG_fvar ) != 0 &&
  677. tt_face_lookup_table( face, TTAG_gvar ) != 0 )
  678. flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
  679. #endif
  680. root->face_flags = flags;
  681. /*********************************************************************/
  682. /* */
  683. /* Compute style flags. */
  684. /* */
  685. flags = 0;
  686. if ( has_outline == TRUE && face->os2.version != 0xFFFFU )
  687. {
  688. /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */
  689. /* indicates an oblique font face. This flag has been */
  690. /* introduced in version 1.5 of the OpenType specification. */
  691. if ( face->os2.fsSelection & 512 ) /* bit 9 */
  692. flags |= FT_STYLE_FLAG_ITALIC;
  693. else if ( face->os2.fsSelection & 1 ) /* bit 0 */
  694. flags |= FT_STYLE_FLAG_ITALIC;
  695. if ( face->os2.fsSelection & 32 ) /* bit 5 */
  696. flags |= FT_STYLE_FLAG_BOLD;
  697. }
  698. else
  699. {
  700. /* this is an old Mac font, use the header field */
  701. if ( face->header.Mac_Style & 1 )
  702. flags |= FT_STYLE_FLAG_BOLD;
  703. if ( face->header.Mac_Style & 2 )
  704. flags |= FT_STYLE_FLAG_ITALIC;
  705. }
  706. root->style_flags = flags;
  707. /*********************************************************************/
  708. /* */
  709. /* Polish the charmaps. */
  710. /* */
  711. /* Try to set the charmap encoding according to the platform & */
  712. /* encoding ID of each charmap. */
  713. /* */
  714. tt_face_build_cmaps( face ); /* ignore errors */
  715. /* set the encoding fields */
  716. {
  717. FT_Int m;
  718. for ( m = 0; m < root->num_charmaps; m++ )
  719. {
  720. FT_CharMap charmap = root->charmaps[m];
  721. charmap->encoding = sfnt_find_encoding( charmap->platform_id,
  722. charmap->encoding_id );
  723. #if 0
  724. if ( root->charmap == NULL &&
  725. charmap->encoding == FT_ENCODING_UNICODE )
  726. {
  727. /* set 'root->charmap' to the first Unicode encoding we find */
  728. root->charmap = charmap;
  729. }
  730. #endif
  731. }
  732. }
  733. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  734. /*
  735. * Now allocate the root array of FT_Bitmap_Size records and
  736. * populate them. Unfortunately, it isn't possible to indicate bit
  737. * depths in the FT_Bitmap_Size record. This is a design error.
  738. */
  739. {
  740. FT_UInt i, count;
  741. #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
  742. count = face->sbit_num_strikes;
  743. #else
  744. count = (FT_UInt)face->num_sbit_strikes;
  745. #endif
  746. if ( count > 0 )
  747. {
  748. FT_Memory memory = face->root.stream->memory;
  749. FT_UShort em_size = face->header.Units_Per_EM;
  750. FT_Short avgwidth = face->os2.xAvgCharWidth;
  751. FT_Size_Metrics metrics;
  752. if ( em_size == 0 || face->os2.version == 0xFFFFU )
  753. {
  754. avgwidth = 0;
  755. em_size = 1;
  756. }
  757. if ( FT_NEW_ARRAY( root->available_sizes, count ) )
  758. goto Exit;
  759. for ( i = 0; i < count; i++ )
  760. {
  761. FT_Bitmap_Size* bsize = root->available_sizes + i;
  762. error = sfnt->load_strike_metrics( face, i, &metrics );
  763. if ( error )
  764. goto Exit;
  765. bsize->height = (FT_Short)( metrics.height >> 6 );
  766. bsize->width = (FT_Short)(
  767. ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size );
  768. bsize->x_ppem = metrics.x_ppem << 6;
  769. bsize->y_ppem = metrics.y_ppem << 6;
  770. /* assume 72dpi */
  771. bsize->size = metrics.y_ppem << 6;
  772. }
  773. root->face_flags |= FT_FACE_FLAG_FIXED_SIZES;
  774. root->num_fixed_sizes = (FT_Int)count;
  775. }
  776. }
  777. #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
  778. /* a font with no bitmaps and no outlines is scalable; */
  779. /* it has only empty glyphs then */
  780. if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) )
  781. root->face_flags |= FT_FACE_FLAG_SCALABLE;
  782. /*********************************************************************/
  783. /* */
  784. /* Set up metrics. */
  785. /* */
  786. if ( FT_IS_SCALABLE( root ) )
  787. {
  788. /* XXX What about if outline header is missing */
  789. /* (e.g. sfnt wrapped bitmap)? */
  790. root->bbox.xMin = face->header.xMin;
  791. root->bbox.yMin = face->header.yMin;
  792. root->bbox.xMax = face->header.xMax;
  793. root->bbox.yMax = face->header.yMax;
  794. root->units_per_EM = face->header.Units_Per_EM;
  795. /* XXX: Computing the ascender/descender/height is very different */
  796. /* from what the specification tells you. Apparently, we */
  797. /* must be careful because */
  798. /* */
  799. /* - not all fonts have an OS/2 table; in this case, we take */
  800. /* the values in the horizontal header. However, these */
  801. /* values very often are not reliable. */
  802. /* */
  803. /* - otherwise, the correct typographic values are in the */
  804. /* sTypoAscender, sTypoDescender & sTypoLineGap fields. */
  805. /* */
  806. /* However, certain fonts have these fields set to 0. */
  807. /* Rather, they have usWinAscent & usWinDescent correctly */
  808. /* set (but with different values). */
  809. /* */
  810. /* As an example, Arial Narrow is implemented through four */
  811. /* files ARIALN.TTF, ARIALNI.TTF, ARIALNB.TTF & ARIALNBI.TTF */
  812. /* */
  813. /* Strangely, all fonts have the same values in their */
  814. /* sTypoXXX fields, except ARIALNB which sets them to 0. */
  815. /* */
  816. /* On the other hand, they all have different */
  817. /* usWinAscent/Descent values -- as a conclusion, the OS/2 */
  818. /* table cannot be used to compute the text height reliably! */
  819. /* */
  820. /* The ascender and descender are taken from the `hhea' table. */
  821. /* If zero, they are taken from the `OS/2' table. */
  822. root->ascender = face->horizontal.Ascender;
  823. root->descender = face->horizontal.Descender;
  824. root->height = (FT_Short)( root->ascender - root->descender +
  825. face->horizontal.Line_Gap );
  826. if ( !( root->ascender || root->descender ) )
  827. {
  828. if ( face->os2.version != 0xFFFFU )
  829. {
  830. if ( face->os2.sTypoAscender || face->os2.sTypoDescender )
  831. {
  832. root->ascender = face->os2.sTypoAscender;
  833. root->descender = face->os2.sTypoDescender;
  834. root->height = (FT_Short)( root->ascender - root->descender +
  835. face->os2.sTypoLineGap );
  836. }
  837. else
  838. {
  839. root->ascender = (FT_Short)face->os2.usWinAscent;
  840. root->descender = -(FT_Short)face->os2.usWinDescent;
  841. root->height = (FT_UShort)( root->ascender - root->descender );
  842. }
  843. }
  844. }
  845. root->max_advance_width = face->horizontal.advance_Width_Max;
  846. root->max_advance_height = (FT_Short)( face->vertical_info
  847. ? face->vertical.advance_Height_Max
  848. : root->height );
  849. /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */
  850. /* Adjust underline position from top edge to centre of */
  851. /* stroke to convert TrueType meaning to FreeType meaning. */
  852. root->underline_position = face->postscript.underlinePosition -
  853. face->postscript.underlineThickness / 2;
  854. root->underline_thickness = face->postscript.underlineThickness;
  855. }
  856. }
  857. Exit:
  858. FT_TRACE2(( "sfnt_load_face: done\n" ));
  859. return error;
  860. }
  861. #undef LOAD_
  862. #undef LOADM_
  863. #undef GET_NAME
  864. FT_LOCAL_DEF( void )
  865. sfnt_done_face( TT_Face face )
  866. {
  867. FT_Memory memory;
  868. SFNT_Service sfnt;
  869. if ( !face )
  870. return;
  871. memory = face->root.memory;
  872. sfnt = (SFNT_Service)face->sfnt;
  873. if ( sfnt )
  874. {
  875. /* destroy the postscript names table if it is loaded */
  876. if ( sfnt->free_psnames )
  877. sfnt->free_psnames( face );
  878. /* destroy the embedded bitmaps table if it is loaded */
  879. if ( sfnt->free_eblc )
  880. sfnt->free_eblc( face );
  881. }
  882. #ifdef TT_CONFIG_OPTION_BDF
  883. /* freeing the embedded BDF properties */
  884. tt_face_free_bdf_props( face );
  885. #endif
  886. /* freeing the kerning table */
  887. tt_face_done_kern( face );
  888. /* freeing the collection table */
  889. FT_FREE( face->ttc_header.offsets );
  890. face->ttc_header.count = 0;
  891. /* freeing table directory */
  892. FT_FREE( face->dir_tables );
  893. face->num_tables = 0;
  894. {
  895. FT_Stream stream = FT_FACE_STREAM( face );
  896. /* simply release the 'cmap' table frame */
  897. FT_FRAME_RELEASE( face->cmap_table );
  898. face->cmap_size = 0;
  899. }
  900. /* freeing the horizontal metrics */
  901. #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
  902. {
  903. FT_Stream stream = FT_FACE_STREAM( face );
  904. FT_FRAME_RELEASE( face->horz_metrics );
  905. FT_FRAME_RELEASE( face->vert_metrics );
  906. face->horz_metrics_size = 0;
  907. face->vert_metrics_size = 0;
  908. }
  909. #else
  910. FT_FREE( face->horizontal.long_metrics );
  911. FT_FREE( face->horizontal.short_metrics );
  912. #endif
  913. /* freeing the vertical ones, if any */
  914. if ( face->vertical_info )
  915. {
  916. FT_FREE( face->vertical.long_metrics );
  917. FT_FREE( face->vertical.short_metrics );
  918. face->vertical_info = 0;
  919. }
  920. /* freeing the gasp table */
  921. FT_FREE( face->gasp.gaspRanges );
  922. face->gasp.numRanges = 0;
  923. /* freeing the name table */
  924. if ( sfnt )
  925. sfnt->free_name( face );
  926. /* freeing family and style name */
  927. FT_FREE( face->root.family_name );
  928. FT_FREE( face->root.style_name );
  929. /* freeing sbit size table */
  930. FT_FREE( face->root.available_sizes );
  931. face->root.num_fixed_sizes = 0;
  932. FT_FREE( face->postscript_name );
  933. face->sfnt = 0;
  934. }
  935. /* END */