/src/freetype/src/truetype/ttobjs.c

https://bitbucket.org/cabalistic/ogredeps/ · C · 1286 lines · 756 code · 263 blank · 267 comment · 107 complexity · 593c3c1b5aa70e976604f2fea1df01a9 MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* ttobjs.c */
  4. /* */
  5. /* Objects manager (body). */
  6. /* */
  7. /* Copyright 1996-2011 */
  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 FT_INTERNAL_DEBUG_H
  19. #include FT_INTERNAL_STREAM_H
  20. #include FT_TRUETYPE_TAGS_H
  21. #include FT_INTERNAL_SFNT_H
  22. #include "ttgload.h"
  23. #include "ttpload.h"
  24. #include "tterrors.h"
  25. #ifdef TT_USE_BYTECODE_INTERPRETER
  26. #include "ttinterp.h"
  27. #endif
  28. #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
  29. #include FT_TRUETYPE_UNPATENTED_H
  30. #endif
  31. #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  32. #include "ttgxvar.h"
  33. #endif
  34. /*************************************************************************/
  35. /* */
  36. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  37. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  38. /* messages during execution. */
  39. /* */
  40. #undef FT_COMPONENT
  41. #define FT_COMPONENT trace_ttobjs
  42. #ifdef TT_USE_BYTECODE_INTERPRETER
  43. /*************************************************************************/
  44. /* */
  45. /* GLYPH ZONE FUNCTIONS */
  46. /* */
  47. /*************************************************************************/
  48. /*************************************************************************/
  49. /* */
  50. /* <Function> */
  51. /* tt_glyphzone_done */
  52. /* */
  53. /* <Description> */
  54. /* Deallocate a glyph zone. */
  55. /* */
  56. /* <Input> */
  57. /* zone :: A pointer to the target glyph zone. */
  58. /* */
  59. FT_LOCAL_DEF( void )
  60. tt_glyphzone_done( TT_GlyphZone zone )
  61. {
  62. FT_Memory memory = zone->memory;
  63. if ( memory )
  64. {
  65. FT_FREE( zone->contours );
  66. FT_FREE( zone->tags );
  67. FT_FREE( zone->cur );
  68. FT_FREE( zone->org );
  69. FT_FREE( zone->orus );
  70. zone->max_points = zone->n_points = 0;
  71. zone->max_contours = zone->n_contours = 0;
  72. zone->memory = NULL;
  73. }
  74. }
  75. /*************************************************************************/
  76. /* */
  77. /* <Function> */
  78. /* tt_glyphzone_new */
  79. /* */
  80. /* <Description> */
  81. /* Allocate a new glyph zone. */
  82. /* */
  83. /* <Input> */
  84. /* memory :: A handle to the current memory object. */
  85. /* */
  86. /* maxPoints :: The capacity of glyph zone in points. */
  87. /* */
  88. /* maxContours :: The capacity of glyph zone in contours. */
  89. /* */
  90. /* <Output> */
  91. /* zone :: A pointer to the target glyph zone record. */
  92. /* */
  93. /* <Return> */
  94. /* FreeType error code. 0 means success. */
  95. /* */
  96. FT_LOCAL_DEF( FT_Error )
  97. tt_glyphzone_new( FT_Memory memory,
  98. FT_UShort maxPoints,
  99. FT_Short maxContours,
  100. TT_GlyphZone zone )
  101. {
  102. FT_Error error;
  103. FT_MEM_ZERO( zone, sizeof ( *zone ) );
  104. zone->memory = memory;
  105. if ( FT_NEW_ARRAY( zone->org, maxPoints ) ||
  106. FT_NEW_ARRAY( zone->cur, maxPoints ) ||
  107. FT_NEW_ARRAY( zone->orus, maxPoints ) ||
  108. FT_NEW_ARRAY( zone->tags, maxPoints ) ||
  109. FT_NEW_ARRAY( zone->contours, maxContours ) )
  110. {
  111. tt_glyphzone_done( zone );
  112. }
  113. else
  114. {
  115. zone->max_points = maxPoints;
  116. zone->max_contours = maxContours;
  117. }
  118. return error;
  119. }
  120. #endif /* TT_USE_BYTECODE_INTERPRETER */
  121. /* Compare the face with a list of well-known `tricky' fonts. */
  122. /* This list shall be expanded as we find more of them. */
  123. static FT_Bool
  124. tt_check_trickyness_family( FT_String* name )
  125. {
  126. #define TRICK_NAMES_MAX_CHARACTERS 16
  127. #define TRICK_NAMES_COUNT 8
  128. static const char trick_names[TRICK_NAMES_COUNT]
  129. [TRICK_NAMES_MAX_CHARACTERS + 1] =
  130. {
  131. "DFKaiSho-SB", /* dfkaisb.ttf */
  132. "DFKaiShu",
  133. "DFKai-SB", /* kaiu.ttf */
  134. "HuaTianKaiTi?", /* htkt2.ttf */
  135. "HuaTianSongTi?", /* htst3.ttf */
  136. "MingLiU", /* mingliu.ttf & mingliu.ttc */
  137. "PMingLiU", /* mingliu.ttc */
  138. "MingLi43", /* mingli.ttf */
  139. };
  140. int nn;
  141. for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ )
  142. if ( ft_strstr( name, trick_names[nn] ) )
  143. return TRUE;
  144. return FALSE;
  145. }
  146. /* XXX: This function should be in the `sfnt' module. */
  147. /* Some PDF generators clear the checksums in the TrueType header table. */
  148. /* For example, Quartz ContextPDF clears all entries, or Bullzip PDF */
  149. /* Printer clears the entries for subsetted subtables. We thus have to */
  150. /* recalculate the checksums where necessary. */
  151. static FT_UInt32
  152. tt_synth_sfnt_checksum( FT_Stream stream,
  153. FT_ULong length )
  154. {
  155. FT_Error error;
  156. FT_UInt32 checksum = 0;
  157. int i;
  158. if ( FT_FRAME_ENTER( length ) )
  159. return 0;
  160. for ( ; length > 3; length -= 4 )
  161. checksum += (FT_UInt32)FT_GET_ULONG();
  162. for ( i = 3; length > 0; length --, i-- )
  163. checksum += (FT_UInt32)( FT_GET_BYTE() << ( i * 8 ) );
  164. FT_FRAME_EXIT();
  165. return checksum;
  166. }
  167. /* XXX: This function should be in the `sfnt' module. */
  168. static FT_ULong
  169. tt_get_sfnt_checksum( TT_Face face,
  170. FT_UShort i )
  171. {
  172. #if 0 /* if we believe the written value, use following part. */
  173. if ( face->dir_tables[i].CheckSum )
  174. return face->dir_tables[i].CheckSum;
  175. #endif
  176. if ( !face->goto_table )
  177. return 0;
  178. if ( face->goto_table( face,
  179. face->dir_tables[i].Tag,
  180. face->root.stream,
  181. NULL ) )
  182. return 0;
  183. return (FT_ULong)tt_synth_sfnt_checksum( face->root.stream,
  184. face->dir_tables[i].Length );
  185. }
  186. typedef struct tt_sfnt_id_rec_
  187. {
  188. FT_ULong CheckSum;
  189. FT_ULong Length;
  190. } tt_sfnt_id_rec;
  191. static FT_Bool
  192. tt_check_trickyness_sfnt_ids( TT_Face face )
  193. {
  194. #define TRICK_SFNT_IDS_PER_FACE 3
  195. #define TRICK_SFNT_IDS_NUM_FACES 13
  196. static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]
  197. [TRICK_SFNT_IDS_PER_FACE] = {
  198. #define TRICK_SFNT_ID_cvt 0
  199. #define TRICK_SFNT_ID_fpgm 1
  200. #define TRICK_SFNT_ID_prep 2
  201. { /* MingLiU 1995 */
  202. { 0x05bcf058, 0x000002e4 }, /* cvt */
  203. { 0x28233bf1, 0x000087c4 }, /* fpgm */
  204. { 0xa344a1ea, 0x000001e1 } /* prep */
  205. },
  206. { /* MingLiU 1996- */
  207. { 0x05bcf058, 0x000002e4 }, /* cvt */
  208. { 0x28233bf1, 0x000087c4 }, /* fpgm */
  209. { 0xa344a1eb, 0x000001e1 } /* prep */
  210. },
  211. { /* DFKaiShu */
  212. { 0x11e5ead4, 0x00000350 }, /* cvt */
  213. { 0x5a30ca3b, 0x00009063 }, /* fpgm */
  214. { 0x13a42602, 0x0000007e } /* prep */
  215. },
  216. { /* HuaTianKaiTi */
  217. { 0xfffbfffc, 0x00000008 }, /* cvt */
  218. { 0x9c9e48b8, 0x0000bea2 }, /* fpgm */
  219. { 0x70020112, 0x00000008 } /* prep */
  220. },
  221. { /* HuaTianSongTi */
  222. { 0xfffbfffc, 0x00000008 }, /* cvt */
  223. { 0x0a5a0483, 0x00017c39 }, /* fpgm */
  224. { 0x70020112, 0x00000008 } /* prep */
  225. },
  226. { /* NEC fadpop7.ttf */
  227. { 0x00000000, 0x00000000 }, /* cvt */
  228. { 0x40c92555, 0x000000e5 }, /* fpgm */
  229. { 0xa39b58e3, 0x0000117c } /* prep */
  230. },
  231. { /* NEC fadrei5.ttf */
  232. { 0x00000000, 0x00000000 }, /* cvt */
  233. { 0x33c41652, 0x000000e5 }, /* fpgm */
  234. { 0x26d6c52a, 0x00000f6a } /* prep */
  235. },
  236. { /* NEC fangot7.ttf */
  237. { 0x00000000, 0x00000000 }, /* cvt */
  238. { 0x6db1651d, 0x0000019d }, /* fpgm */
  239. { 0x6c6e4b03, 0x00002492 } /* prep */
  240. },
  241. { /* NEC fangyo5.ttf */
  242. { 0x00000000, 0x00000000 }, /* cvt */
  243. { 0x40c92555, 0x000000e5 }, /* fpgm */
  244. { 0xde51fad0, 0x0000117c } /* prep */
  245. },
  246. { /* NEC fankyo5.ttf */
  247. { 0x00000000, 0x00000000 }, /* cvt */
  248. { 0x85e47664, 0x000000e5 }, /* fpgm */
  249. { 0xa6c62831, 0x00001caa } /* prep */
  250. },
  251. { /* NEC fanrgo5.ttf */
  252. { 0x00000000, 0x00000000 }, /* cvt */
  253. { 0x2d891cfd, 0x0000019d }, /* fpgm */
  254. { 0xa0604633, 0x00001de8 } /* prep */
  255. },
  256. { /* NEC fangot5.ttc */
  257. { 0x00000000, 0x00000000 }, /* cvt */
  258. { 0x40aa774c, 0x000001cb }, /* fpgm */
  259. { 0x9b5caa96, 0x00001f9a } /* prep */
  260. },
  261. { /* NEC fanmin3.ttc */
  262. { 0x00000000, 0x00000000 }, /* cvt */
  263. { 0x0d3de9cb, 0x00000141 }, /* fpgm */
  264. { 0xd4127766, 0x00002280 } /* prep */
  265. }
  266. };
  267. FT_ULong checksum;
  268. int num_matched_ids[TRICK_SFNT_IDS_NUM_FACES];
  269. FT_Bool has_cvt, has_fpgm, has_prep;
  270. FT_UShort i;
  271. int j, k;
  272. FT_MEM_SET( num_matched_ids, 0,
  273. sizeof ( int ) * TRICK_SFNT_IDS_NUM_FACES );
  274. has_cvt = FALSE;
  275. has_fpgm = FALSE;
  276. has_prep = FALSE;
  277. for ( i = 0; i < face->num_tables; i++ )
  278. {
  279. checksum = 0;
  280. switch( face->dir_tables[i].Tag )
  281. {
  282. case TTAG_cvt:
  283. k = TRICK_SFNT_ID_cvt;
  284. has_cvt = TRUE;
  285. break;
  286. case TTAG_fpgm:
  287. k = TRICK_SFNT_ID_fpgm;
  288. has_fpgm = TRUE;
  289. break;
  290. case TTAG_prep:
  291. k = TRICK_SFNT_ID_prep;
  292. has_prep = TRUE;
  293. break;
  294. default:
  295. continue;
  296. }
  297. for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
  298. if ( face->dir_tables[i].Length == sfnt_id[j][k].Length )
  299. {
  300. if ( !checksum )
  301. checksum = tt_get_sfnt_checksum( face, i );
  302. if ( sfnt_id[j][k].CheckSum == checksum )
  303. num_matched_ids[j]++;
  304. if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
  305. return TRUE;
  306. }
  307. }
  308. for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
  309. {
  310. if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length )
  311. num_matched_ids[j] ++;
  312. if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length )
  313. num_matched_ids[j] ++;
  314. if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length )
  315. num_matched_ids[j] ++;
  316. if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
  317. return TRUE;
  318. }
  319. return FALSE;
  320. }
  321. static FT_Bool
  322. tt_check_trickyness( FT_Face face )
  323. {
  324. if ( !face )
  325. return FALSE;
  326. /* For first, check the face name for quick check. */
  327. if ( face->family_name &&
  328. tt_check_trickyness_family( face->family_name ) )
  329. return TRUE;
  330. /* Type42 fonts may lack `name' tables, we thus try to identify */
  331. /* tricky fonts by checking the checksums of Type42-persistent */
  332. /* sfnt tables (`cvt', `fpgm', and `prep'). */
  333. if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) )
  334. return TRUE;
  335. return FALSE;
  336. }
  337. /* Check whether `.notdef' is the only glyph in the `loca' table. */
  338. static FT_Bool
  339. tt_check_single_notdef( FT_Face ttface )
  340. {
  341. FT_Bool result = FALSE;
  342. TT_Face face = (TT_Face)ttface;
  343. FT_UInt asize;
  344. FT_ULong i;
  345. FT_ULong glyph_index = 0;
  346. FT_UInt count = 0;
  347. for( i = 0; i < face->num_locations; i++ )
  348. {
  349. tt_face_get_location( face, i, &asize );
  350. if ( asize > 0 )
  351. {
  352. count += 1;
  353. if ( count > 1 )
  354. break;
  355. glyph_index = i;
  356. }
  357. }
  358. /* Only have a single outline. */
  359. if ( count == 1 )
  360. {
  361. if ( glyph_index == 0 )
  362. result = TRUE;
  363. else
  364. {
  365. /* FIXME: Need to test glyphname == .notdef ? */
  366. FT_Error error;
  367. char buf[8];
  368. error = FT_Get_Glyph_Name( ttface, glyph_index, buf, 8 );
  369. if ( !error &&
  370. buf[0] == '.' && !ft_strncmp( buf, ".notdef", 8 ) )
  371. result = TRUE;
  372. }
  373. }
  374. return result;
  375. }
  376. /*************************************************************************/
  377. /* */
  378. /* <Function> */
  379. /* tt_face_init */
  380. /* */
  381. /* <Description> */
  382. /* Initialize a given TrueType face object. */
  383. /* */
  384. /* <Input> */
  385. /* stream :: The source font stream. */
  386. /* */
  387. /* face_index :: The index of the font face in the resource. */
  388. /* */
  389. /* num_params :: Number of additional generic parameters. Ignored. */
  390. /* */
  391. /* params :: Additional generic parameters. Ignored. */
  392. /* */
  393. /* <InOut> */
  394. /* face :: The newly built face object. */
  395. /* */
  396. /* <Return> */
  397. /* FreeType error code. 0 means success. */
  398. /* */
  399. FT_LOCAL_DEF( FT_Error )
  400. tt_face_init( FT_Stream stream,
  401. FT_Face ttface, /* TT_Face */
  402. FT_Int face_index,
  403. FT_Int num_params,
  404. FT_Parameter* params )
  405. {
  406. FT_Error error;
  407. FT_Library library;
  408. SFNT_Service sfnt;
  409. TT_Face face = (TT_Face)ttface;
  410. FT_TRACE2(( "TTF driver\n" ));
  411. library = ttface->driver->root.library;
  412. sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
  413. if ( !sfnt )
  414. {
  415. FT_ERROR(( "tt_face_init: cannot access `sfnt' module\n" ));
  416. error = TT_Err_Missing_Module;
  417. goto Exit;
  418. }
  419. /* create input stream from resource */
  420. if ( FT_STREAM_SEEK( 0 ) )
  421. goto Exit;
  422. /* check that we have a valid TrueType file */
  423. error = sfnt->init_face( stream, face, face_index, num_params, params );
  424. if ( error )
  425. goto Exit;
  426. /* We must also be able to accept Mac/GX fonts, as well as OT ones. */
  427. /* The 0x00020000 tag is completely undocumented; some fonts from */
  428. /* Arphic made for Chinese Windows 3.1 have this. */
  429. if ( face->format_tag != 0x00010000L && /* MS fonts */
  430. face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */
  431. face->format_tag != TTAG_true ) /* Mac fonts */
  432. {
  433. FT_TRACE2(( " not a TTF font\n" ));
  434. goto Bad_Format;
  435. }
  436. #ifdef TT_USE_BYTECODE_INTERPRETER
  437. ttface->face_flags |= FT_FACE_FLAG_HINTER;
  438. #endif
  439. /* If we are performing a simple font format check, exit immediately. */
  440. if ( face_index < 0 )
  441. return TT_Err_Ok;
  442. /* Load font directory */
  443. error = sfnt->load_face( stream, face, face_index, num_params, params );
  444. if ( error )
  445. goto Exit;
  446. if ( tt_check_trickyness( ttface ) )
  447. ttface->face_flags |= FT_FACE_FLAG_TRICKY;
  448. error = tt_face_load_hdmx( face, stream );
  449. if ( error )
  450. goto Exit;
  451. if ( FT_IS_SCALABLE( ttface ) )
  452. {
  453. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  454. if ( !ttface->internal->incremental_interface )
  455. error = tt_face_load_loca( face, stream );
  456. if ( !error )
  457. error = tt_face_load_cvt( face, stream );
  458. if ( !error )
  459. error = tt_face_load_fpgm( face, stream );
  460. if ( !error )
  461. error = tt_face_load_prep( face, stream );
  462. /* Check the scalable flag based on `loca'. */
  463. if ( !ttface->internal->incremental_interface &&
  464. ttface->num_fixed_sizes &&
  465. face->glyph_locations &&
  466. tt_check_single_notdef( ttface ) )
  467. {
  468. FT_TRACE5(( "tt_face_init:"
  469. " Only the `.notdef' glyph has an outline.\n"
  470. " "
  471. " Resetting scalable flag to FALSE.\n" ));
  472. ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
  473. }
  474. #else
  475. if ( !error )
  476. error = tt_face_load_loca( face, stream );
  477. if ( !error )
  478. error = tt_face_load_cvt( face, stream );
  479. if ( !error )
  480. error = tt_face_load_fpgm( face, stream );
  481. if ( !error )
  482. error = tt_face_load_prep( face, stream );
  483. /* Check the scalable flag based on `loca'. */
  484. if ( ttface->num_fixed_sizes &&
  485. face->glyph_locations &&
  486. tt_check_single_notdef( ttface ) )
  487. {
  488. FT_TRACE5(( "tt_face_init:"
  489. " Only the `.notdef' glyph has an outline.\n"
  490. " "
  491. " Resetting scalable flag to FALSE.\n" ));
  492. ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
  493. }
  494. #endif
  495. }
  496. #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
  497. !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER )
  498. {
  499. FT_Bool unpatented_hinting;
  500. int i;
  501. /* Determine whether unpatented hinting is to be used for this face. */
  502. unpatented_hinting = FT_BOOL
  503. ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL );
  504. for ( i = 0; i < num_params && !face->unpatented_hinting; i++ )
  505. if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING )
  506. unpatented_hinting = TRUE;
  507. if ( !unpatented_hinting )
  508. ttface->internal->ignore_unpatented_hinter = TRUE;
  509. }
  510. #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING &&
  511. !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
  512. /* initialize standard glyph loading routines */
  513. TT_Init_Glyph_Loading( face );
  514. Exit:
  515. return error;
  516. Bad_Format:
  517. error = TT_Err_Unknown_File_Format;
  518. goto Exit;
  519. }
  520. /*************************************************************************/
  521. /* */
  522. /* <Function> */
  523. /* tt_face_done */
  524. /* */
  525. /* <Description> */
  526. /* Finalize a given face object. */
  527. /* */
  528. /* <Input> */
  529. /* face :: A pointer to the face object to destroy. */
  530. /* */
  531. FT_LOCAL_DEF( void )
  532. tt_face_done( FT_Face ttface ) /* TT_Face */
  533. {
  534. TT_Face face = (TT_Face)ttface;
  535. FT_Memory memory;
  536. FT_Stream stream;
  537. SFNT_Service sfnt;
  538. if ( !face )
  539. return;
  540. memory = ttface->memory;
  541. stream = ttface->stream;
  542. sfnt = (SFNT_Service)face->sfnt;
  543. /* for `extended TrueType formats' (i.e. compressed versions) */
  544. if ( face->extra.finalizer )
  545. face->extra.finalizer( face->extra.data );
  546. if ( sfnt )
  547. sfnt->done_face( face );
  548. /* freeing the locations table */
  549. tt_face_done_loca( face );
  550. tt_face_free_hdmx( face );
  551. /* freeing the CVT */
  552. FT_FREE( face->cvt );
  553. face->cvt_size = 0;
  554. /* freeing the programs */
  555. FT_FRAME_RELEASE( face->font_program );
  556. FT_FRAME_RELEASE( face->cvt_program );
  557. face->font_program_size = 0;
  558. face->cvt_program_size = 0;
  559. #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  560. tt_done_blend( memory, face->blend );
  561. face->blend = NULL;
  562. #endif
  563. }
  564. /*************************************************************************/
  565. /* */
  566. /* SIZE FUNCTIONS */
  567. /* */
  568. /*************************************************************************/
  569. #ifdef TT_USE_BYTECODE_INTERPRETER
  570. /*************************************************************************/
  571. /* */
  572. /* <Function> */
  573. /* tt_size_run_fpgm */
  574. /* */
  575. /* <Description> */
  576. /* Run the font program. */
  577. /* */
  578. /* <Input> */
  579. /* size :: A handle to the size object. */
  580. /* */
  581. /* pedantic :: Set if bytecode execution should be pedantic. */
  582. /* */
  583. /* <Return> */
  584. /* FreeType error code. 0 means success. */
  585. /* */
  586. FT_LOCAL_DEF( FT_Error )
  587. tt_size_run_fpgm( TT_Size size,
  588. FT_Bool pedantic )
  589. {
  590. TT_Face face = (TT_Face)size->root.face;
  591. TT_ExecContext exec;
  592. FT_Error error;
  593. /* debugging instances have their own context */
  594. if ( size->debug )
  595. exec = size->context;
  596. else
  597. exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
  598. if ( !exec )
  599. return TT_Err_Could_Not_Find_Context;
  600. TT_Load_Context( exec, face, size );
  601. exec->callTop = 0;
  602. exec->top = 0;
  603. exec->period = 64;
  604. exec->phase = 0;
  605. exec->threshold = 0;
  606. exec->instruction_trap = FALSE;
  607. exec->F_dot_P = 0x10000L;
  608. exec->pedantic_hinting = pedantic;
  609. {
  610. FT_Size_Metrics* metrics = &exec->metrics;
  611. TT_Size_Metrics* tt_metrics = &exec->tt_metrics;
  612. metrics->x_ppem = 0;
  613. metrics->y_ppem = 0;
  614. metrics->x_scale = 0;
  615. metrics->y_scale = 0;
  616. tt_metrics->ppem = 0;
  617. tt_metrics->scale = 0;
  618. tt_metrics->ratio = 0x10000L;
  619. }
  620. /* allow font program execution */
  621. TT_Set_CodeRange( exec,
  622. tt_coderange_font,
  623. face->font_program,
  624. face->font_program_size );
  625. /* disable CVT and glyph programs coderange */
  626. TT_Clear_CodeRange( exec, tt_coderange_cvt );
  627. TT_Clear_CodeRange( exec, tt_coderange_glyph );
  628. if ( face->font_program_size > 0 )
  629. {
  630. error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
  631. if ( !error )
  632. {
  633. FT_TRACE4(( "Executing `fpgm' table.\n" ));
  634. error = face->interpreter( exec );
  635. }
  636. }
  637. else
  638. error = TT_Err_Ok;
  639. if ( !error )
  640. TT_Save_Context( exec, size );
  641. return error;
  642. }
  643. /*************************************************************************/
  644. /* */
  645. /* <Function> */
  646. /* tt_size_run_prep */
  647. /* */
  648. /* <Description> */
  649. /* Run the control value program. */
  650. /* */
  651. /* <Input> */
  652. /* size :: A handle to the size object. */
  653. /* */
  654. /* pedantic :: Set if bytecode execution should be pedantic. */
  655. /* */
  656. /* <Return> */
  657. /* FreeType error code. 0 means success. */
  658. /* */
  659. FT_LOCAL_DEF( FT_Error )
  660. tt_size_run_prep( TT_Size size,
  661. FT_Bool pedantic )
  662. {
  663. TT_Face face = (TT_Face)size->root.face;
  664. TT_ExecContext exec;
  665. FT_Error error;
  666. /* debugging instances have their own context */
  667. if ( size->debug )
  668. exec = size->context;
  669. else
  670. exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
  671. if ( !exec )
  672. return TT_Err_Could_Not_Find_Context;
  673. TT_Load_Context( exec, face, size );
  674. exec->callTop = 0;
  675. exec->top = 0;
  676. exec->instruction_trap = FALSE;
  677. exec->pedantic_hinting = pedantic;
  678. TT_Set_CodeRange( exec,
  679. tt_coderange_cvt,
  680. face->cvt_program,
  681. face->cvt_program_size );
  682. TT_Clear_CodeRange( exec, tt_coderange_glyph );
  683. if ( face->cvt_program_size > 0 )
  684. {
  685. error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
  686. if ( !error && !size->debug )
  687. {
  688. FT_TRACE4(( "Executing `prep' table.\n" ));
  689. error = face->interpreter( exec );
  690. }
  691. }
  692. else
  693. error = TT_Err_Ok;
  694. /* save as default graphics state */
  695. size->GS = exec->GS;
  696. TT_Save_Context( exec, size );
  697. return error;
  698. }
  699. #endif /* TT_USE_BYTECODE_INTERPRETER */
  700. #ifdef TT_USE_BYTECODE_INTERPRETER
  701. static void
  702. tt_size_done_bytecode( FT_Size ftsize )
  703. {
  704. TT_Size size = (TT_Size)ftsize;
  705. TT_Face face = (TT_Face)ftsize->face;
  706. FT_Memory memory = face->root.memory;
  707. if ( size->debug )
  708. {
  709. /* the debug context must be deleted by the debugger itself */
  710. size->context = NULL;
  711. size->debug = FALSE;
  712. }
  713. FT_FREE( size->cvt );
  714. size->cvt_size = 0;
  715. /* free storage area */
  716. FT_FREE( size->storage );
  717. size->storage_size = 0;
  718. /* twilight zone */
  719. tt_glyphzone_done( &size->twilight );
  720. FT_FREE( size->function_defs );
  721. FT_FREE( size->instruction_defs );
  722. size->num_function_defs = 0;
  723. size->max_function_defs = 0;
  724. size->num_instruction_defs = 0;
  725. size->max_instruction_defs = 0;
  726. size->max_func = 0;
  727. size->max_ins = 0;
  728. size->bytecode_ready = 0;
  729. size->cvt_ready = 0;
  730. }
  731. /* Initialize bytecode-related fields in the size object. */
  732. /* We do this only if bytecode interpretation is really needed. */
  733. static FT_Error
  734. tt_size_init_bytecode( FT_Size ftsize,
  735. FT_Bool pedantic )
  736. {
  737. FT_Error error;
  738. TT_Size size = (TT_Size)ftsize;
  739. TT_Face face = (TT_Face)ftsize->face;
  740. FT_Memory memory = face->root.memory;
  741. FT_Int i;
  742. FT_UShort n_twilight;
  743. TT_MaxProfile* maxp = &face->max_profile;
  744. size->bytecode_ready = 1;
  745. size->cvt_ready = 0;
  746. size->max_function_defs = maxp->maxFunctionDefs;
  747. size->max_instruction_defs = maxp->maxInstructionDefs;
  748. size->num_function_defs = 0;
  749. size->num_instruction_defs = 0;
  750. size->max_func = 0;
  751. size->max_ins = 0;
  752. size->cvt_size = face->cvt_size;
  753. size->storage_size = maxp->maxStorage;
  754. /* Set default metrics */
  755. {
  756. TT_Size_Metrics* metrics = &size->ttmetrics;
  757. metrics->rotated = FALSE;
  758. metrics->stretched = FALSE;
  759. /* set default compensation (all 0) */
  760. for ( i = 0; i < 4; i++ )
  761. metrics->compensations[i] = 0;
  762. }
  763. /* allocate function defs, instruction defs, cvt, and storage area */
  764. if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) ||
  765. FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||
  766. FT_NEW_ARRAY( size->cvt, size->cvt_size ) ||
  767. FT_NEW_ARRAY( size->storage, size->storage_size ) )
  768. goto Exit;
  769. /* reserve twilight zone */
  770. n_twilight = maxp->maxTwilightPoints;
  771. /* there are 4 phantom points (do we need this?) */
  772. n_twilight += 4;
  773. error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight );
  774. if ( error )
  775. goto Exit;
  776. size->twilight.n_points = n_twilight;
  777. size->GS = tt_default_graphics_state;
  778. /* set `face->interpreter' according to the debug hook present */
  779. {
  780. FT_Library library = face->root.driver->root.library;
  781. face->interpreter = (TT_Interpreter)
  782. library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
  783. if ( !face->interpreter )
  784. face->interpreter = (TT_Interpreter)TT_RunIns;
  785. }
  786. /* Fine, now run the font program! */
  787. error = tt_size_run_fpgm( size, pedantic );
  788. Exit:
  789. if ( error )
  790. tt_size_done_bytecode( ftsize );
  791. return error;
  792. }
  793. FT_LOCAL_DEF( FT_Error )
  794. tt_size_ready_bytecode( TT_Size size,
  795. FT_Bool pedantic )
  796. {
  797. FT_Error error = TT_Err_Ok;
  798. if ( !size->bytecode_ready )
  799. {
  800. error = tt_size_init_bytecode( (FT_Size)size, pedantic );
  801. if ( error )
  802. goto Exit;
  803. }
  804. /* rescale CVT when needed */
  805. if ( !size->cvt_ready )
  806. {
  807. FT_UInt i;
  808. TT_Face face = (TT_Face)size->root.face;
  809. /* Scale the cvt values to the new ppem. */
  810. /* We use by default the y ppem to scale the CVT. */
  811. for ( i = 0; i < size->cvt_size; i++ )
  812. size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
  813. /* all twilight points are originally zero */
  814. for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )
  815. {
  816. size->twilight.org[i].x = 0;
  817. size->twilight.org[i].y = 0;
  818. size->twilight.cur[i].x = 0;
  819. size->twilight.cur[i].y = 0;
  820. }
  821. /* clear storage area */
  822. for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
  823. size->storage[i] = 0;
  824. size->GS = tt_default_graphics_state;
  825. error = tt_size_run_prep( size, pedantic );
  826. if ( !error )
  827. size->cvt_ready = 1;
  828. }
  829. Exit:
  830. return error;
  831. }
  832. #endif /* TT_USE_BYTECODE_INTERPRETER */
  833. /*************************************************************************/
  834. /* */
  835. /* <Function> */
  836. /* tt_size_init */
  837. /* */
  838. /* <Description> */
  839. /* Initialize a new TrueType size object. */
  840. /* */
  841. /* <InOut> */
  842. /* size :: A handle to the size object. */
  843. /* */
  844. /* <Return> */
  845. /* FreeType error code. 0 means success. */
  846. /* */
  847. FT_LOCAL_DEF( FT_Error )
  848. tt_size_init( FT_Size ttsize ) /* TT_Size */
  849. {
  850. TT_Size size = (TT_Size)ttsize;
  851. FT_Error error = TT_Err_Ok;
  852. #ifdef TT_USE_BYTECODE_INTERPRETER
  853. size->bytecode_ready = 0;
  854. size->cvt_ready = 0;
  855. #endif
  856. size->ttmetrics.valid = FALSE;
  857. size->strike_index = 0xFFFFFFFFUL;
  858. return error;
  859. }
  860. /*************************************************************************/
  861. /* */
  862. /* <Function> */
  863. /* tt_size_done */
  864. /* */
  865. /* <Description> */
  866. /* The TrueType size object finalizer. */
  867. /* */
  868. /* <Input> */
  869. /* size :: A handle to the target size object. */
  870. /* */
  871. FT_LOCAL_DEF( void )
  872. tt_size_done( FT_Size ttsize ) /* TT_Size */
  873. {
  874. TT_Size size = (TT_Size)ttsize;
  875. #ifdef TT_USE_BYTECODE_INTERPRETER
  876. if ( size->bytecode_ready )
  877. tt_size_done_bytecode( ttsize );
  878. #endif
  879. size->ttmetrics.valid = FALSE;
  880. }
  881. /*************************************************************************/
  882. /* */
  883. /* <Function> */
  884. /* tt_size_reset */
  885. /* */
  886. /* <Description> */
  887. /* Reset a TrueType size when resolutions and character dimensions */
  888. /* have been changed. */
  889. /* */
  890. /* <Input> */
  891. /* size :: A handle to the target size object. */
  892. /* */
  893. FT_LOCAL_DEF( FT_Error )
  894. tt_size_reset( TT_Size size )
  895. {
  896. TT_Face face;
  897. FT_Error error = TT_Err_Ok;
  898. FT_Size_Metrics* metrics;
  899. size->ttmetrics.valid = FALSE;
  900. face = (TT_Face)size->root.face;
  901. metrics = &size->metrics;
  902. /* copy the result from base layer */
  903. *metrics = size->root.metrics;
  904. if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
  905. return TT_Err_Invalid_PPem;
  906. /* This bit flag, if set, indicates that the ppems must be */
  907. /* rounded to integers. Nearly all TrueType fonts have this bit */
  908. /* set, as hinting won't work really well otherwise. */
  909. /* */
  910. if ( face->header.Flags & 8 )
  911. {
  912. metrics->x_scale = FT_DivFix( metrics->x_ppem << 6,
  913. face->root.units_per_EM );
  914. metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,
  915. face->root.units_per_EM );
  916. metrics->ascender =
  917. FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );
  918. metrics->descender =
  919. FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );
  920. metrics->height =
  921. FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );
  922. metrics->max_advance =
  923. FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
  924. metrics->x_scale ) );
  925. }
  926. /* compute new transformation */
  927. if ( metrics->x_ppem >= metrics->y_ppem )
  928. {
  929. size->ttmetrics.scale = metrics->x_scale;
  930. size->ttmetrics.ppem = metrics->x_ppem;
  931. size->ttmetrics.x_ratio = 0x10000L;
  932. size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
  933. 0x10000L,
  934. metrics->x_ppem );
  935. }
  936. else
  937. {
  938. size->ttmetrics.scale = metrics->y_scale;
  939. size->ttmetrics.ppem = metrics->y_ppem;
  940. size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
  941. 0x10000L,
  942. metrics->y_ppem );
  943. size->ttmetrics.y_ratio = 0x10000L;
  944. }
  945. #ifdef TT_USE_BYTECODE_INTERPRETER
  946. size->cvt_ready = 0;
  947. #endif /* TT_USE_BYTECODE_INTERPRETER */
  948. if ( !error )
  949. size->ttmetrics.valid = TRUE;
  950. return error;
  951. }
  952. /*************************************************************************/
  953. /* */
  954. /* <Function> */
  955. /* tt_driver_init */
  956. /* */
  957. /* <Description> */
  958. /* Initialize a given TrueType driver object. */
  959. /* */
  960. /* <Input> */
  961. /* driver :: A handle to the target driver object. */
  962. /* */
  963. /* <Return> */
  964. /* FreeType error code. 0 means success. */
  965. /* */
  966. FT_LOCAL_DEF( FT_Error )
  967. tt_driver_init( FT_Module ttdriver ) /* TT_Driver */
  968. {
  969. #ifdef TT_USE_BYTECODE_INTERPRETER
  970. TT_Driver driver = (TT_Driver)ttdriver;
  971. if ( !TT_New_Context( driver ) )
  972. return TT_Err_Could_Not_Find_Context;
  973. #else
  974. FT_UNUSED( ttdriver );
  975. #endif
  976. return TT_Err_Ok;
  977. }
  978. /*************************************************************************/
  979. /* */
  980. /* <Function> */
  981. /* tt_driver_done */
  982. /* */
  983. /* <Description> */
  984. /* Finalize a given TrueType driver. */
  985. /* */
  986. /* <Input> */
  987. /* driver :: A handle to the target TrueType driver. */
  988. /* */
  989. FT_LOCAL_DEF( void )
  990. tt_driver_done( FT_Module ttdriver ) /* TT_Driver */
  991. {
  992. #ifdef TT_USE_BYTECODE_INTERPRETER
  993. TT_Driver driver = (TT_Driver)ttdriver;
  994. /* destroy the execution context */
  995. if ( driver->context )
  996. {
  997. TT_Done_Context( driver->context );
  998. driver->context = NULL;
  999. }
  1000. #else
  1001. FT_UNUSED( ttdriver );
  1002. #endif
  1003. }
  1004. /*************************************************************************/
  1005. /* */
  1006. /* <Function> */
  1007. /* tt_slot_init */
  1008. /* */
  1009. /* <Description> */
  1010. /* Initialize a new slot object. */
  1011. /* */
  1012. /* <InOut> */
  1013. /* slot :: A handle to the slot object. */
  1014. /* */
  1015. /* <Return> */
  1016. /* FreeType error code. 0 means success. */
  1017. /* */
  1018. FT_LOCAL_DEF( FT_Error )
  1019. tt_slot_init( FT_GlyphSlot slot )
  1020. {
  1021. return FT_GlyphLoader_CreateExtra( slot->internal->loader );
  1022. }
  1023. /* END */