/src/compiler/android-ndk/jni/freetype/src/truetype/ttpload.c

http://ftk.googlecode.com/ · C · 572 lines · 308 code · 122 blank · 142 comment · 47 complexity · 2b72428ea48e839ff249fb335063702b MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* ttpload.c */
  4. /* */
  5. /* TrueType-specific tables loader (body). */
  6. /* */
  7. /* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 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 FT_INTERNAL_DEBUG_H
  19. #include FT_INTERNAL_OBJECTS_H
  20. #include FT_INTERNAL_STREAM_H
  21. #include FT_TRUETYPE_TAGS_H
  22. #include "ttpload.h"
  23. #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  24. #include "ttgxvar.h"
  25. #endif
  26. #include "tterrors.h"
  27. /*************************************************************************/
  28. /* */
  29. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  30. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  31. /* messages during execution. */
  32. /* */
  33. #undef FT_COMPONENT
  34. #define FT_COMPONENT trace_ttpload
  35. /*************************************************************************/
  36. /* */
  37. /* <Function> */
  38. /* tt_face_load_loca */
  39. /* */
  40. /* <Description> */
  41. /* Load the locations table. */
  42. /* */
  43. /* <InOut> */
  44. /* face :: A handle to the target face object. */
  45. /* */
  46. /* <Input> */
  47. /* stream :: The input stream. */
  48. /* */
  49. /* <Return> */
  50. /* FreeType error code. 0 means success. */
  51. /* */
  52. FT_LOCAL_DEF( FT_Error )
  53. tt_face_load_loca( TT_Face face,
  54. FT_Stream stream )
  55. {
  56. FT_Error error;
  57. FT_ULong table_len;
  58. FT_Int shift;
  59. /* we need the size of the `glyf' table for malformed `loca' tables */
  60. error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len );
  61. /* it is possible that a font doesn't have a glyf table at all */
  62. /* or its size is zero */
  63. if ( error == TT_Err_Table_Missing )
  64. face->glyf_len = 0;
  65. else if ( error )
  66. goto Exit;
  67. FT_TRACE2(( "Locations " ));
  68. error = face->goto_table( face, TTAG_loca, stream, &table_len );
  69. if ( error )
  70. {
  71. error = TT_Err_Locations_Missing;
  72. goto Exit;
  73. }
  74. if ( face->header.Index_To_Loc_Format != 0 )
  75. {
  76. shift = 2;
  77. if ( table_len >= 0x40000L )
  78. {
  79. FT_TRACE2(( "table too large\n" ));
  80. error = TT_Err_Invalid_Table;
  81. goto Exit;
  82. }
  83. face->num_locations = table_len >> shift;
  84. }
  85. else
  86. {
  87. shift = 1;
  88. if ( table_len >= 0x20000L )
  89. {
  90. FT_TRACE2(( "table too large\n" ));
  91. error = TT_Err_Invalid_Table;
  92. goto Exit;
  93. }
  94. face->num_locations = table_len >> shift;
  95. }
  96. if ( face->num_locations != (FT_ULong)face->root.num_glyphs )
  97. {
  98. FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n",
  99. face->num_locations, face->root.num_glyphs ));
  100. /* we only handle the case where `maxp' gives a larger value */
  101. if ( face->num_locations < (FT_ULong)face->root.num_glyphs )
  102. {
  103. FT_Long new_loca_len = (FT_Long)face->root.num_glyphs << shift;
  104. TT_Table entry = face->dir_tables;
  105. TT_Table limit = entry + face->num_tables;
  106. FT_Long pos = FT_Stream_Pos( stream );
  107. FT_Long dist = 0x7FFFFFFFL;
  108. /* compute the distance to next table in font file */
  109. for ( ; entry < limit; entry++ )
  110. {
  111. FT_Long diff = entry->Offset - pos;
  112. if ( diff > 0 && diff < dist )
  113. dist = diff;
  114. }
  115. if ( new_loca_len <= dist )
  116. {
  117. face->num_locations = face->root.num_glyphs;
  118. table_len = new_loca_len;
  119. FT_TRACE2(( "adjusting num_locations to %d\n",
  120. face->num_locations ));
  121. }
  122. }
  123. }
  124. /*
  125. * Extract the frame. We don't need to decompress it since
  126. * we are able to parse it directly.
  127. */
  128. if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) )
  129. goto Exit;
  130. FT_TRACE2(( "loaded\n" ));
  131. Exit:
  132. return error;
  133. }
  134. FT_LOCAL_DEF( FT_ULong )
  135. tt_face_get_location( TT_Face face,
  136. FT_UInt gindex,
  137. FT_UInt *asize )
  138. {
  139. FT_ULong pos1, pos2;
  140. FT_Byte* p;
  141. FT_Byte* p_limit;
  142. pos1 = pos2 = 0;
  143. if ( gindex < face->num_locations )
  144. {
  145. if ( face->header.Index_To_Loc_Format != 0 )
  146. {
  147. p = face->glyph_locations + gindex * 4;
  148. p_limit = face->glyph_locations + face->num_locations * 4;
  149. pos1 = FT_NEXT_ULONG( p );
  150. pos2 = pos1;
  151. if ( p + 4 <= p_limit )
  152. pos2 = FT_NEXT_ULONG( p );
  153. }
  154. else
  155. {
  156. p = face->glyph_locations + gindex * 2;
  157. p_limit = face->glyph_locations + face->num_locations * 2;
  158. pos1 = FT_NEXT_USHORT( p );
  159. pos2 = pos1;
  160. if ( p + 2 <= p_limit )
  161. pos2 = FT_NEXT_USHORT( p );
  162. pos1 <<= 1;
  163. pos2 <<= 1;
  164. }
  165. }
  166. /* The `loca' table must be ordered; it refers to the length of */
  167. /* an entry as the difference between the current and the next */
  168. /* position. However, there do exist (malformed) fonts which */
  169. /* don't obey this rule, so we are only able to provide an */
  170. /* upper bound for the size. */
  171. /* */
  172. /* We get (intentionally) a wrong, non-zero result in case the */
  173. /* `glyf' table is missing. */
  174. if ( pos2 >= pos1 )
  175. *asize = (FT_UInt)( pos2 - pos1 );
  176. else
  177. *asize = (FT_UInt)( face->glyf_len - pos1 );
  178. return pos1;
  179. }
  180. FT_LOCAL_DEF( void )
  181. tt_face_done_loca( TT_Face face )
  182. {
  183. FT_Stream stream = face->root.stream;
  184. FT_FRAME_RELEASE( face->glyph_locations );
  185. face->num_locations = 0;
  186. }
  187. /*************************************************************************/
  188. /* */
  189. /* <Function> */
  190. /* tt_face_load_cvt */
  191. /* */
  192. /* <Description> */
  193. /* Load the control value table into a face object. */
  194. /* */
  195. /* <InOut> */
  196. /* face :: A handle to the target face object. */
  197. /* */
  198. /* <Input> */
  199. /* stream :: A handle to the input stream. */
  200. /* */
  201. /* <Return> */
  202. /* FreeType error code. 0 means success. */
  203. /* */
  204. FT_LOCAL_DEF( FT_Error )
  205. tt_face_load_cvt( TT_Face face,
  206. FT_Stream stream )
  207. {
  208. #ifdef TT_USE_BYTECODE_INTERPRETER
  209. FT_Error error;
  210. FT_Memory memory = stream->memory;
  211. FT_ULong table_len;
  212. FT_TRACE2(( "CVT " ));
  213. error = face->goto_table( face, TTAG_cvt, stream, &table_len );
  214. if ( error )
  215. {
  216. FT_TRACE2(( "is missing\n" ));
  217. face->cvt_size = 0;
  218. face->cvt = NULL;
  219. error = TT_Err_Ok;
  220. goto Exit;
  221. }
  222. face->cvt_size = table_len / 2;
  223. if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) )
  224. goto Exit;
  225. if ( FT_FRAME_ENTER( face->cvt_size * 2L ) )
  226. goto Exit;
  227. {
  228. FT_Short* cur = face->cvt;
  229. FT_Short* limit = cur + face->cvt_size;
  230. for ( ; cur < limit; cur++ )
  231. *cur = FT_GET_SHORT();
  232. }
  233. FT_FRAME_EXIT();
  234. FT_TRACE2(( "loaded\n" ));
  235. #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  236. if ( face->doblend )
  237. error = tt_face_vary_cvt( face, stream );
  238. #endif
  239. Exit:
  240. return error;
  241. #else /* !TT_USE_BYTECODE_INTERPRETER */
  242. FT_UNUSED( face );
  243. FT_UNUSED( stream );
  244. return TT_Err_Ok;
  245. #endif
  246. }
  247. /*************************************************************************/
  248. /* */
  249. /* <Function> */
  250. /* tt_face_load_fpgm */
  251. /* */
  252. /* <Description> */
  253. /* Load the font program. */
  254. /* */
  255. /* <InOut> */
  256. /* face :: A handle to the target face object. */
  257. /* */
  258. /* <Input> */
  259. /* stream :: A handle to the input stream. */
  260. /* */
  261. /* <Return> */
  262. /* FreeType error code. 0 means success. */
  263. /* */
  264. FT_LOCAL_DEF( FT_Error )
  265. tt_face_load_fpgm( TT_Face face,
  266. FT_Stream stream )
  267. {
  268. #ifdef TT_USE_BYTECODE_INTERPRETER
  269. FT_Error error;
  270. FT_ULong table_len;
  271. FT_TRACE2(( "Font program " ));
  272. /* The font program is optional */
  273. error = face->goto_table( face, TTAG_fpgm, stream, &table_len );
  274. if ( error )
  275. {
  276. face->font_program = NULL;
  277. face->font_program_size = 0;
  278. error = TT_Err_Ok;
  279. FT_TRACE2(( "is missing\n" ));
  280. }
  281. else
  282. {
  283. face->font_program_size = table_len;
  284. if ( FT_FRAME_EXTRACT( table_len, face->font_program ) )
  285. goto Exit;
  286. FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size ));
  287. }
  288. Exit:
  289. return error;
  290. #else /* !TT_USE_BYTECODE_INTERPRETER */
  291. FT_UNUSED( face );
  292. FT_UNUSED( stream );
  293. return TT_Err_Ok;
  294. #endif
  295. }
  296. /*************************************************************************/
  297. /* */
  298. /* <Function> */
  299. /* tt_face_load_prep */
  300. /* */
  301. /* <Description> */
  302. /* Load the cvt program. */
  303. /* */
  304. /* <InOut> */
  305. /* face :: A handle to the target face object. */
  306. /* */
  307. /* <Input> */
  308. /* stream :: A handle to the input stream. */
  309. /* */
  310. /* <Return> */
  311. /* FreeType error code. 0 means success. */
  312. /* */
  313. FT_LOCAL_DEF( FT_Error )
  314. tt_face_load_prep( TT_Face face,
  315. FT_Stream stream )
  316. {
  317. #ifdef TT_USE_BYTECODE_INTERPRETER
  318. FT_Error error;
  319. FT_ULong table_len;
  320. FT_TRACE2(( "Prep program " ));
  321. error = face->goto_table( face, TTAG_prep, stream, &table_len );
  322. if ( error )
  323. {
  324. face->cvt_program = NULL;
  325. face->cvt_program_size = 0;
  326. error = TT_Err_Ok;
  327. FT_TRACE2(( "is missing\n" ));
  328. }
  329. else
  330. {
  331. face->cvt_program_size = table_len;
  332. if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) )
  333. goto Exit;
  334. FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size ));
  335. }
  336. Exit:
  337. return error;
  338. #else /* !TT_USE_BYTECODE_INTERPRETER */
  339. FT_UNUSED( face );
  340. FT_UNUSED( stream );
  341. return TT_Err_Ok;
  342. #endif
  343. }
  344. /*************************************************************************/
  345. /* */
  346. /* <Function> */
  347. /* tt_face_load_hdmx */
  348. /* */
  349. /* <Description> */
  350. /* Load the `hdmx' table into the face object. */
  351. /* */
  352. /* <Input> */
  353. /* face :: A handle to the target face object. */
  354. /* */
  355. /* stream :: A handle to the input stream. */
  356. /* */
  357. /* <Return> */
  358. /* FreeType error code. 0 means success. */
  359. /* */
  360. FT_LOCAL_DEF( FT_Error )
  361. tt_face_load_hdmx( TT_Face face,
  362. FT_Stream stream )
  363. {
  364. FT_Error error;
  365. FT_Memory memory = stream->memory;
  366. FT_UInt version, nn, num_records;
  367. FT_ULong table_size, record_size;
  368. FT_Byte* p;
  369. FT_Byte* limit;
  370. /* this table is optional */
  371. error = face->goto_table( face, TTAG_hdmx, stream, &table_size );
  372. if ( error || table_size < 8 )
  373. return TT_Err_Ok;
  374. if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) )
  375. goto Exit;
  376. p = face->hdmx_table;
  377. limit = p + table_size;
  378. version = FT_NEXT_USHORT( p );
  379. num_records = FT_NEXT_USHORT( p );
  380. record_size = FT_NEXT_ULONG( p );
  381. /* The maximum number of bytes in an hdmx device record is the */
  382. /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */
  383. /* the reason why `record_size' is a long (which we read as */
  384. /* unsigned long for convenience). In practice, two bytes */
  385. /* sufficient to hold the size value. */
  386. /* */
  387. /* There are at least two fonts, HANNOM-A and HANNOM-B version */
  388. /* 2.0 (2005), which get this wrong: The upper two bytes of */
  389. /* the size value are set to 0xFF instead of 0x00. We catch */
  390. /* and fix this. */
  391. if ( record_size >= 0xFFFF0000UL )
  392. record_size &= 0xFFFFU;
  393. /* The limit for `num_records' is a heuristic value. */
  394. if ( version != 0 || num_records > 255 || record_size > 0x10001L )
  395. {
  396. error = TT_Err_Invalid_File_Format;
  397. goto Fail;
  398. }
  399. if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) )
  400. goto Fail;
  401. for ( nn = 0; nn < num_records; nn++ )
  402. {
  403. if ( p + record_size > limit )
  404. break;
  405. face->hdmx_record_sizes[nn] = p[0];
  406. p += record_size;
  407. }
  408. face->hdmx_record_count = nn;
  409. face->hdmx_table_size = table_size;
  410. face->hdmx_record_size = record_size;
  411. Exit:
  412. return error;
  413. Fail:
  414. FT_FRAME_RELEASE( face->hdmx_table );
  415. face->hdmx_table_size = 0;
  416. goto Exit;
  417. }
  418. FT_LOCAL_DEF( void )
  419. tt_face_free_hdmx( TT_Face face )
  420. {
  421. FT_Stream stream = face->root.stream;
  422. FT_Memory memory = stream->memory;
  423. FT_FREE( face->hdmx_record_sizes );
  424. FT_FRAME_RELEASE( face->hdmx_table );
  425. }
  426. /*************************************************************************/
  427. /* */
  428. /* Return the advance width table for a given pixel size if it is found */
  429. /* in the font's `hdmx' table (if any). */
  430. /* */
  431. FT_LOCAL_DEF( FT_Byte* )
  432. tt_face_get_device_metrics( TT_Face face,
  433. FT_UInt ppem,
  434. FT_UInt gindex )
  435. {
  436. FT_UInt nn;
  437. FT_Byte* result = NULL;
  438. FT_ULong record_size = face->hdmx_record_size;
  439. FT_Byte* record = face->hdmx_table + 8;
  440. for ( nn = 0; nn < face->hdmx_record_count; nn++ )
  441. if ( face->hdmx_record_sizes[nn] == ppem )
  442. {
  443. gindex += 2;
  444. if ( gindex < record_size )
  445. result = record + nn * record_size + gindex;
  446. break;
  447. }
  448. return result;
  449. }
  450. /* END */