PageRenderTime 95ms CodeModel.GetById 16ms RepoModel.GetById 2ms app.codeStats 1ms

/src/freetype/src/sfnt/ttcmap.c

https://bitbucket.org/cabalistic/ogredeps/
C | 3512 lines | 2201 code | 753 blank | 558 comment | 421 complexity | e2ba5752d3f982bbb5241ef0bfd41888 MD5 | raw file
Possible License(s): LGPL-3.0, BSD-3-Clause, CPL-1.0, Unlicense, GPL-2.0, GPL-3.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, BSD-2-Clause, LGPL-2.1
  1. /***************************************************************************/
  2. /* */
  3. /* ttcmap.c */
  4. /* */
  5. /* TrueType character mapping table (cmap) support (body). */
  6. /* */
  7. /* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 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 FT_INTERNAL_DEBUG_H
  19. #include "sferrors.h" /* must come before FT_INTERNAL_VALIDATE_H */
  20. #include FT_INTERNAL_VALIDATE_H
  21. #include FT_INTERNAL_STREAM_H
  22. #include "ttload.h"
  23. #include "ttcmap.h"
  24. #include "sfntpic.h"
  25. /*************************************************************************/
  26. /* */
  27. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  28. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  29. /* messages during execution. */
  30. /* */
  31. #undef FT_COMPONENT
  32. #define FT_COMPONENT trace_ttcmap
  33. #define TT_PEEK_SHORT FT_PEEK_SHORT
  34. #define TT_PEEK_USHORT FT_PEEK_USHORT
  35. #define TT_PEEK_UINT24 FT_PEEK_UOFF3
  36. #define TT_PEEK_LONG FT_PEEK_LONG
  37. #define TT_PEEK_ULONG FT_PEEK_ULONG
  38. #define TT_NEXT_SHORT FT_NEXT_SHORT
  39. #define TT_NEXT_USHORT FT_NEXT_USHORT
  40. #define TT_NEXT_UINT24 FT_NEXT_UOFF3
  41. #define TT_NEXT_LONG FT_NEXT_LONG
  42. #define TT_NEXT_ULONG FT_NEXT_ULONG
  43. FT_CALLBACK_DEF( FT_Error )
  44. tt_cmap_init( TT_CMap cmap,
  45. FT_Byte* table )
  46. {
  47. cmap->data = table;
  48. return SFNT_Err_Ok;
  49. }
  50. /*************************************************************************/
  51. /*************************************************************************/
  52. /***** *****/
  53. /***** FORMAT 0 *****/
  54. /***** *****/
  55. /*************************************************************************/
  56. /*************************************************************************/
  57. /*************************************************************************/
  58. /* */
  59. /* TABLE OVERVIEW */
  60. /* -------------- */
  61. /* */
  62. /* NAME OFFSET TYPE DESCRIPTION */
  63. /* */
  64. /* format 0 USHORT must be 0 */
  65. /* length 2 USHORT table length in bytes */
  66. /* language 4 USHORT Mac language code */
  67. /* glyph_ids 6 BYTE[256] array of glyph indices */
  68. /* 262 */
  69. /* */
  70. #ifdef TT_CONFIG_CMAP_FORMAT_0
  71. FT_CALLBACK_DEF( FT_Error )
  72. tt_cmap0_validate( FT_Byte* table,
  73. FT_Validator valid )
  74. {
  75. FT_Byte* p = table + 2;
  76. FT_UInt length = TT_NEXT_USHORT( p );
  77. if ( table + length > valid->limit || length < 262 )
  78. FT_INVALID_TOO_SHORT;
  79. /* check glyph indices whenever necessary */
  80. if ( valid->level >= FT_VALIDATE_TIGHT )
  81. {
  82. FT_UInt n, idx;
  83. p = table + 6;
  84. for ( n = 0; n < 256; n++ )
  85. {
  86. idx = *p++;
  87. if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
  88. FT_INVALID_GLYPH_ID;
  89. }
  90. }
  91. return SFNT_Err_Ok;
  92. }
  93. FT_CALLBACK_DEF( FT_UInt )
  94. tt_cmap0_char_index( TT_CMap cmap,
  95. FT_UInt32 char_code )
  96. {
  97. FT_Byte* table = cmap->data;
  98. return char_code < 256 ? table[6 + char_code] : 0;
  99. }
  100. FT_CALLBACK_DEF( FT_UInt32 )
  101. tt_cmap0_char_next( TT_CMap cmap,
  102. FT_UInt32 *pchar_code )
  103. {
  104. FT_Byte* table = cmap->data;
  105. FT_UInt32 charcode = *pchar_code;
  106. FT_UInt32 result = 0;
  107. FT_UInt gindex = 0;
  108. table += 6; /* go to glyph IDs */
  109. while ( ++charcode < 256 )
  110. {
  111. gindex = table[charcode];
  112. if ( gindex != 0 )
  113. {
  114. result = charcode;
  115. break;
  116. }
  117. }
  118. *pchar_code = result;
  119. return gindex;
  120. }
  121. FT_CALLBACK_DEF( FT_Error )
  122. tt_cmap0_get_info( TT_CMap cmap,
  123. TT_CMapInfo *cmap_info )
  124. {
  125. FT_Byte* p = cmap->data + 4;
  126. cmap_info->format = 0;
  127. cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
  128. return SFNT_Err_Ok;
  129. }
  130. FT_DEFINE_TT_CMAP(tt_cmap0_class_rec,
  131. sizeof ( TT_CMapRec ),
  132. (FT_CMap_InitFunc) tt_cmap_init,
  133. (FT_CMap_DoneFunc) NULL,
  134. (FT_CMap_CharIndexFunc)tt_cmap0_char_index,
  135. (FT_CMap_CharNextFunc) tt_cmap0_char_next,
  136. NULL, NULL, NULL, NULL, NULL
  137. ,
  138. 0,
  139. (TT_CMap_ValidateFunc) tt_cmap0_validate,
  140. (TT_CMap_Info_GetFunc) tt_cmap0_get_info
  141. )
  142. #endif /* TT_CONFIG_CMAP_FORMAT_0 */
  143. /*************************************************************************/
  144. /*************************************************************************/
  145. /***** *****/
  146. /***** FORMAT 2 *****/
  147. /***** *****/
  148. /***** This is used for certain CJK encodings that encode text in a *****/
  149. /***** mixed 8/16 bits encoding along the following lines: *****/
  150. /***** *****/
  151. /***** * Certain byte values correspond to an 8-bit character code *****/
  152. /***** (typically in the range 0..127 for ASCII compatibility). *****/
  153. /***** *****/
  154. /***** * Certain byte values signal the first byte of a 2-byte *****/
  155. /***** character code (but these values are also valid as the *****/
  156. /***** second byte of a 2-byte character). *****/
  157. /***** *****/
  158. /***** The following charmap lookup and iteration functions all *****/
  159. /***** assume that the value "charcode" correspond to following: *****/
  160. /***** *****/
  161. /***** - For one byte characters, "charcode" is simply the *****/
  162. /***** character code. *****/
  163. /***** *****/
  164. /***** - For two byte characters, "charcode" is the 2-byte *****/
  165. /***** character code in big endian format. More exactly: *****/
  166. /***** *****/
  167. /***** (charcode >> 8) is the first byte value *****/
  168. /***** (charcode & 0xFF) is the second byte value *****/
  169. /***** *****/
  170. /***** Note that not all values of "charcode" are valid according *****/
  171. /***** to these rules, and the function moderately check the *****/
  172. /***** arguments. *****/
  173. /***** *****/
  174. /*************************************************************************/
  175. /*************************************************************************/
  176. /*************************************************************************/
  177. /* */
  178. /* TABLE OVERVIEW */
  179. /* -------------- */
  180. /* */
  181. /* NAME OFFSET TYPE DESCRIPTION */
  182. /* */
  183. /* format 0 USHORT must be 2 */
  184. /* length 2 USHORT table length in bytes */
  185. /* language 4 USHORT Mac language code */
  186. /* keys 6 USHORT[256] sub-header keys */
  187. /* subs 518 SUBHEAD[NSUBS] sub-headers array */
  188. /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */
  189. /* */
  190. /* The `keys' table is used to map charcode high-bytes to sub-headers. */
  191. /* The value of `NSUBS' is the number of sub-headers defined in the */
  192. /* table and is computed by finding the maximum of the `keys' table. */
  193. /* */
  194. /* Note that for any n, `keys[n]' is a byte offset within the `subs' */
  195. /* table, i.e., it is the corresponding sub-header index multiplied */
  196. /* by 8. */
  197. /* */
  198. /* Each sub-header has the following format: */
  199. /* */
  200. /* NAME OFFSET TYPE DESCRIPTION */
  201. /* */
  202. /* first 0 USHORT first valid low-byte */
  203. /* count 2 USHORT number of valid low-bytes */
  204. /* delta 4 SHORT see below */
  205. /* offset 6 USHORT see below */
  206. /* */
  207. /* A sub-header defines, for each high-byte, the range of valid */
  208. /* low-bytes within the charmap. Note that the range defined by `first' */
  209. /* and `count' must be completely included in the interval [0..255] */
  210. /* according to the specification. */
  211. /* */
  212. /* If a character code is contained within a given sub-header, then */
  213. /* mapping it to a glyph index is done as follows: */
  214. /* */
  215. /* * The value of `offset' is read. This is a _byte_ distance from the */
  216. /* location of the `offset' field itself into a slice of the */
  217. /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[] too). */
  218. /* */
  219. /* * The value `slice[char.lo - first]' is read. If it is 0, there is */
  220. /* no glyph for the charcode. Otherwise, the value of `delta' is */
  221. /* added to it (modulo 65536) to form a new glyph index. */
  222. /* */
  223. /* It is up to the validation routine to check that all offsets fall */
  224. /* within the glyph IDs table (and not within the `subs' table itself or */
  225. /* outside of the CMap). */
  226. /* */
  227. #ifdef TT_CONFIG_CMAP_FORMAT_2
  228. FT_CALLBACK_DEF( FT_Error )
  229. tt_cmap2_validate( FT_Byte* table,
  230. FT_Validator valid )
  231. {
  232. FT_Byte* p = table + 2; /* skip format */
  233. FT_UInt length = TT_PEEK_USHORT( p );
  234. FT_UInt n, max_subs;
  235. FT_Byte* keys; /* keys table */
  236. FT_Byte* subs; /* sub-headers */
  237. FT_Byte* glyph_ids; /* glyph ID array */
  238. if ( table + length > valid->limit || length < 6 + 512 )
  239. FT_INVALID_TOO_SHORT;
  240. keys = table + 6;
  241. /* parse keys to compute sub-headers count */
  242. p = keys;
  243. max_subs = 0;
  244. for ( n = 0; n < 256; n++ )
  245. {
  246. FT_UInt idx = TT_NEXT_USHORT( p );
  247. /* value must be multiple of 8 */
  248. if ( valid->level >= FT_VALIDATE_PARANOID && ( idx & 7 ) != 0 )
  249. FT_INVALID_DATA;
  250. idx >>= 3;
  251. if ( idx > max_subs )
  252. max_subs = idx;
  253. }
  254. FT_ASSERT( p == table + 518 );
  255. subs = p;
  256. glyph_ids = subs + (max_subs + 1) * 8;
  257. if ( glyph_ids > valid->limit )
  258. FT_INVALID_TOO_SHORT;
  259. /* parse sub-headers */
  260. for ( n = 0; n <= max_subs; n++ )
  261. {
  262. FT_UInt first_code, code_count, offset;
  263. FT_Int delta;
  264. FT_Byte* ids;
  265. first_code = TT_NEXT_USHORT( p );
  266. code_count = TT_NEXT_USHORT( p );
  267. delta = TT_NEXT_SHORT( p );
  268. offset = TT_NEXT_USHORT( p );
  269. /* many Dynalab fonts have empty sub-headers */
  270. if ( code_count == 0 )
  271. continue;
  272. /* check range within 0..255 */
  273. if ( valid->level >= FT_VALIDATE_PARANOID )
  274. {
  275. if ( first_code >= 256 || first_code + code_count > 256 )
  276. FT_INVALID_DATA;
  277. }
  278. /* check offset */
  279. if ( offset != 0 )
  280. {
  281. ids = p - 2 + offset;
  282. if ( ids < glyph_ids || ids + code_count*2 > table + length )
  283. FT_INVALID_OFFSET;
  284. /* check glyph IDs */
  285. if ( valid->level >= FT_VALIDATE_TIGHT )
  286. {
  287. FT_Byte* limit = p + code_count * 2;
  288. FT_UInt idx;
  289. for ( ; p < limit; )
  290. {
  291. idx = TT_NEXT_USHORT( p );
  292. if ( idx != 0 )
  293. {
  294. idx = ( idx + delta ) & 0xFFFFU;
  295. if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
  296. FT_INVALID_GLYPH_ID;
  297. }
  298. }
  299. }
  300. }
  301. }
  302. return SFNT_Err_Ok;
  303. }
  304. /* return sub header corresponding to a given character code */
  305. /* NULL on invalid charcode */
  306. static FT_Byte*
  307. tt_cmap2_get_subheader( FT_Byte* table,
  308. FT_UInt32 char_code )
  309. {
  310. FT_Byte* result = NULL;
  311. if ( char_code < 0x10000UL )
  312. {
  313. FT_UInt char_lo = (FT_UInt)( char_code & 0xFF );
  314. FT_UInt char_hi = (FT_UInt)( char_code >> 8 );
  315. FT_Byte* p = table + 6; /* keys table */
  316. FT_Byte* subs = table + 518; /* subheaders table */
  317. FT_Byte* sub;
  318. if ( char_hi == 0 )
  319. {
  320. /* an 8-bit character code -- we use subHeader 0 in this case */
  321. /* to test whether the character code is in the charmap */
  322. /* */
  323. sub = subs; /* jump to first sub-header */
  324. /* check that the sub-header for this byte is 0, which */
  325. /* indicates that it is really a valid one-byte value */
  326. /* Otherwise, return 0 */
  327. /* */
  328. p += char_lo * 2;
  329. if ( TT_PEEK_USHORT( p ) != 0 )
  330. goto Exit;
  331. }
  332. else
  333. {
  334. /* a 16-bit character code */
  335. /* jump to key entry */
  336. p += char_hi * 2;
  337. /* jump to sub-header */
  338. sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) );
  339. /* check that the high byte isn't a valid one-byte value */
  340. if ( sub == subs )
  341. goto Exit;
  342. }
  343. result = sub;
  344. }
  345. Exit:
  346. return result;
  347. }
  348. FT_CALLBACK_DEF( FT_UInt )
  349. tt_cmap2_char_index( TT_CMap cmap,
  350. FT_UInt32 char_code )
  351. {
  352. FT_Byte* table = cmap->data;
  353. FT_UInt result = 0;
  354. FT_Byte* subheader;
  355. subheader = tt_cmap2_get_subheader( table, char_code );
  356. if ( subheader )
  357. {
  358. FT_Byte* p = subheader;
  359. FT_UInt idx = (FT_UInt)(char_code & 0xFF);
  360. FT_UInt start, count;
  361. FT_Int delta;
  362. FT_UInt offset;
  363. start = TT_NEXT_USHORT( p );
  364. count = TT_NEXT_USHORT( p );
  365. delta = TT_NEXT_SHORT ( p );
  366. offset = TT_PEEK_USHORT( p );
  367. idx -= start;
  368. if ( idx < count && offset != 0 )
  369. {
  370. p += offset + 2 * idx;
  371. idx = TT_PEEK_USHORT( p );
  372. if ( idx != 0 )
  373. result = (FT_UInt)( idx + delta ) & 0xFFFFU;
  374. }
  375. }
  376. return result;
  377. }
  378. FT_CALLBACK_DEF( FT_UInt32 )
  379. tt_cmap2_char_next( TT_CMap cmap,
  380. FT_UInt32 *pcharcode )
  381. {
  382. FT_Byte* table = cmap->data;
  383. FT_UInt gindex = 0;
  384. FT_UInt32 result = 0;
  385. FT_UInt32 charcode = *pcharcode + 1;
  386. FT_Byte* subheader;
  387. while ( charcode < 0x10000UL )
  388. {
  389. subheader = tt_cmap2_get_subheader( table, charcode );
  390. if ( subheader )
  391. {
  392. FT_Byte* p = subheader;
  393. FT_UInt start = TT_NEXT_USHORT( p );
  394. FT_UInt count = TT_NEXT_USHORT( p );
  395. FT_Int delta = TT_NEXT_SHORT ( p );
  396. FT_UInt offset = TT_PEEK_USHORT( p );
  397. FT_UInt char_lo = (FT_UInt)( charcode & 0xFF );
  398. FT_UInt pos, idx;
  399. if ( offset == 0 )
  400. goto Next_SubHeader;
  401. if ( char_lo < start )
  402. {
  403. char_lo = start;
  404. pos = 0;
  405. }
  406. else
  407. pos = (FT_UInt)( char_lo - start );
  408. p += offset + pos * 2;
  409. charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo;
  410. for ( ; pos < count; pos++, charcode++ )
  411. {
  412. idx = TT_NEXT_USHORT( p );
  413. if ( idx != 0 )
  414. {
  415. gindex = ( idx + delta ) & 0xFFFFU;
  416. if ( gindex != 0 )
  417. {
  418. result = charcode;
  419. goto Exit;
  420. }
  421. }
  422. }
  423. }
  424. /* jump to next sub-header, i.e. higher byte value */
  425. Next_SubHeader:
  426. charcode = FT_PAD_FLOOR( charcode, 256 ) + 256;
  427. }
  428. Exit:
  429. *pcharcode = result;
  430. return gindex;
  431. }
  432. FT_CALLBACK_DEF( FT_Error )
  433. tt_cmap2_get_info( TT_CMap cmap,
  434. TT_CMapInfo *cmap_info )
  435. {
  436. FT_Byte* p = cmap->data + 4;
  437. cmap_info->format = 2;
  438. cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
  439. return SFNT_Err_Ok;
  440. }
  441. FT_DEFINE_TT_CMAP(tt_cmap2_class_rec,
  442. sizeof ( TT_CMapRec ),
  443. (FT_CMap_InitFunc) tt_cmap_init,
  444. (FT_CMap_DoneFunc) NULL,
  445. (FT_CMap_CharIndexFunc)tt_cmap2_char_index,
  446. (FT_CMap_CharNextFunc) tt_cmap2_char_next,
  447. NULL, NULL, NULL, NULL, NULL
  448. ,
  449. 2,
  450. (TT_CMap_ValidateFunc) tt_cmap2_validate,
  451. (TT_CMap_Info_GetFunc) tt_cmap2_get_info
  452. )
  453. #endif /* TT_CONFIG_CMAP_FORMAT_2 */
  454. /*************************************************************************/
  455. /*************************************************************************/
  456. /***** *****/
  457. /***** FORMAT 4 *****/
  458. /***** *****/
  459. /*************************************************************************/
  460. /*************************************************************************/
  461. /*************************************************************************/
  462. /* */
  463. /* TABLE OVERVIEW */
  464. /* -------------- */
  465. /* */
  466. /* NAME OFFSET TYPE DESCRIPTION */
  467. /* */
  468. /* format 0 USHORT must be 4 */
  469. /* length 2 USHORT table length */
  470. /* in bytes */
  471. /* language 4 USHORT Mac language code */
  472. /* */
  473. /* segCountX2 6 USHORT 2*NUM_SEGS */
  474. /* searchRange 8 USHORT 2*(1 << LOG_SEGS) */
  475. /* entrySelector 10 USHORT LOG_SEGS */
  476. /* rangeShift 12 USHORT segCountX2 - */
  477. /* searchRange */
  478. /* */
  479. /* endCount 14 USHORT[NUM_SEGS] end charcode for */
  480. /* each segment; last */
  481. /* is 0xFFFF */
  482. /* */
  483. /* pad 14+NUM_SEGS*2 USHORT padding */
  484. /* */
  485. /* startCount 16+NUM_SEGS*2 USHORT[NUM_SEGS] first charcode for */
  486. /* each segment */
  487. /* */
  488. /* idDelta 16+NUM_SEGS*4 SHORT[NUM_SEGS] delta for each */
  489. /* segment */
  490. /* idOffset 16+NUM_SEGS*6 SHORT[NUM_SEGS] range offset for */
  491. /* each segment; can be */
  492. /* zero */
  493. /* */
  494. /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID */
  495. /* ranges */
  496. /* */
  497. /* Character codes are modelled by a series of ordered (increasing) */
  498. /* intervals called segments. Each segment has start and end codes, */
  499. /* provided by the `startCount' and `endCount' arrays. Segments must */
  500. /* not overlap, and the last segment should always contain the value */
  501. /* 0xFFFF for `endCount'. */
  502. /* */
  503. /* The fields `searchRange', `entrySelector' and `rangeShift' are better */
  504. /* ignored (they are traces of over-engineering in the TrueType */
  505. /* specification). */
  506. /* */
  507. /* Each segment also has a signed `delta', as well as an optional offset */
  508. /* within the `glyphIds' table. */
  509. /* */
  510. /* If a segment's idOffset is 0, the glyph index corresponding to any */
  511. /* charcode within the segment is obtained by adding the value of */
  512. /* `idDelta' directly to the charcode, modulo 65536. */
  513. /* */
  514. /* Otherwise, a glyph index is taken from the glyph IDs sub-array for */
  515. /* the segment, and the value of `idDelta' is added to it. */
  516. /* */
  517. /* */
  518. /* Finally, note that a lot of fonts contain an invalid last segment, */
  519. /* where `start' and `end' are correctly set to 0xFFFF but both `delta' */
  520. /* and `offset' are incorrect (e.g., `opens___.ttf' which comes with */
  521. /* OpenOffice.org). We need special code to deal with them correctly. */
  522. /* */
  523. #ifdef TT_CONFIG_CMAP_FORMAT_4
  524. typedef struct TT_CMap4Rec_
  525. {
  526. TT_CMapRec cmap;
  527. FT_UInt32 cur_charcode; /* current charcode */
  528. FT_UInt cur_gindex; /* current glyph index */
  529. FT_UInt num_ranges;
  530. FT_UInt cur_range;
  531. FT_UInt cur_start;
  532. FT_UInt cur_end;
  533. FT_Int cur_delta;
  534. FT_Byte* cur_values;
  535. } TT_CMap4Rec, *TT_CMap4;
  536. FT_CALLBACK_DEF( FT_Error )
  537. tt_cmap4_init( TT_CMap4 cmap,
  538. FT_Byte* table )
  539. {
  540. FT_Byte* p;
  541. cmap->cmap.data = table;
  542. p = table + 6;
  543. cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1;
  544. cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
  545. cmap->cur_gindex = 0;
  546. return SFNT_Err_Ok;
  547. }
  548. static FT_Int
  549. tt_cmap4_set_range( TT_CMap4 cmap,
  550. FT_UInt range_index )
  551. {
  552. FT_Byte* table = cmap->cmap.data;
  553. FT_Byte* p;
  554. FT_UInt num_ranges = cmap->num_ranges;
  555. while ( range_index < num_ranges )
  556. {
  557. FT_UInt offset;
  558. p = table + 14 + range_index * 2;
  559. cmap->cur_end = FT_PEEK_USHORT( p );
  560. p += 2 + num_ranges * 2;
  561. cmap->cur_start = FT_PEEK_USHORT( p );
  562. p += num_ranges * 2;
  563. cmap->cur_delta = FT_PEEK_SHORT( p );
  564. p += num_ranges * 2;
  565. offset = FT_PEEK_USHORT( p );
  566. /* some fonts have an incorrect last segment; */
  567. /* we have to catch it */
  568. if ( range_index >= num_ranges - 1 &&
  569. cmap->cur_start == 0xFFFFU &&
  570. cmap->cur_end == 0xFFFFU )
  571. {
  572. TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face;
  573. FT_Byte* limit = face->cmap_table + face->cmap_size;
  574. if ( offset && p + offset + 2 > limit )
  575. {
  576. cmap->cur_delta = 1;
  577. offset = 0;
  578. }
  579. }
  580. if ( offset != 0xFFFFU )
  581. {
  582. cmap->cur_values = offset ? p + offset : NULL;
  583. cmap->cur_range = range_index;
  584. return 0;
  585. }
  586. /* we skip empty segments */
  587. range_index++;
  588. }
  589. return -1;
  590. }
  591. /* search the index of the charcode next to cmap->cur_charcode; */
  592. /* caller should call tt_cmap4_set_range with proper range */
  593. /* before calling this function */
  594. /* */
  595. static void
  596. tt_cmap4_next( TT_CMap4 cmap )
  597. {
  598. FT_UInt charcode;
  599. if ( cmap->cur_charcode >= 0xFFFFUL )
  600. goto Fail;
  601. charcode = (FT_UInt)cmap->cur_charcode + 1;
  602. if ( charcode < cmap->cur_start )
  603. charcode = cmap->cur_start;
  604. for ( ;; )
  605. {
  606. FT_Byte* values = cmap->cur_values;
  607. FT_UInt end = cmap->cur_end;
  608. FT_Int delta = cmap->cur_delta;
  609. if ( charcode <= end )
  610. {
  611. if ( values )
  612. {
  613. FT_Byte* p = values + 2 * ( charcode - cmap->cur_start );
  614. do
  615. {
  616. FT_UInt gindex = FT_NEXT_USHORT( p );
  617. if ( gindex != 0 )
  618. {
  619. gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU );
  620. if ( gindex != 0 )
  621. {
  622. cmap->cur_charcode = charcode;
  623. cmap->cur_gindex = gindex;
  624. return;
  625. }
  626. }
  627. } while ( ++charcode <= end );
  628. }
  629. else
  630. {
  631. do
  632. {
  633. FT_UInt gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU );
  634. if ( gindex != 0 )
  635. {
  636. cmap->cur_charcode = charcode;
  637. cmap->cur_gindex = gindex;
  638. return;
  639. }
  640. } while ( ++charcode <= end );
  641. }
  642. }
  643. /* we need to find another range */
  644. if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 )
  645. break;
  646. if ( charcode < cmap->cur_start )
  647. charcode = cmap->cur_start;
  648. }
  649. Fail:
  650. cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
  651. cmap->cur_gindex = 0;
  652. }
  653. FT_CALLBACK_DEF( FT_Error )
  654. tt_cmap4_validate( FT_Byte* table,
  655. FT_Validator valid )
  656. {
  657. FT_Byte* p = table + 2; /* skip format */
  658. FT_UInt length = TT_NEXT_USHORT( p );
  659. FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids;
  660. FT_UInt num_segs;
  661. FT_Error error = SFNT_Err_Ok;
  662. if ( length < 16 )
  663. FT_INVALID_TOO_SHORT;
  664. /* in certain fonts, the `length' field is invalid and goes */
  665. /* out of bound. We try to correct this here... */
  666. if ( table + length > valid->limit )
  667. {
  668. if ( valid->level >= FT_VALIDATE_TIGHT )
  669. FT_INVALID_TOO_SHORT;
  670. length = (FT_UInt)( valid->limit - table );
  671. }
  672. p = table + 6;
  673. num_segs = TT_NEXT_USHORT( p ); /* read segCountX2 */
  674. if ( valid->level >= FT_VALIDATE_PARANOID )
  675. {
  676. /* check that we have an even value here */
  677. if ( num_segs & 1 )
  678. FT_INVALID_DATA;
  679. }
  680. num_segs /= 2;
  681. if ( length < 16 + num_segs * 2 * 4 )
  682. FT_INVALID_TOO_SHORT;
  683. /* check the search parameters - even though we never use them */
  684. /* */
  685. if ( valid->level >= FT_VALIDATE_PARANOID )
  686. {
  687. /* check the values of `searchRange', `entrySelector', `rangeShift' */
  688. FT_UInt search_range = TT_NEXT_USHORT( p );
  689. FT_UInt entry_selector = TT_NEXT_USHORT( p );
  690. FT_UInt range_shift = TT_NEXT_USHORT( p );
  691. if ( ( search_range | range_shift ) & 1 ) /* must be even values */
  692. FT_INVALID_DATA;
  693. search_range /= 2;
  694. range_shift /= 2;
  695. /* `search range' is the greatest power of 2 that is <= num_segs */
  696. if ( search_range > num_segs ||
  697. search_range * 2 < num_segs ||
  698. search_range + range_shift != num_segs ||
  699. search_range != ( 1U << entry_selector ) )
  700. FT_INVALID_DATA;
  701. }
  702. ends = table + 14;
  703. starts = table + 16 + num_segs * 2;
  704. deltas = starts + num_segs * 2;
  705. offsets = deltas + num_segs * 2;
  706. glyph_ids = offsets + num_segs * 2;
  707. /* check last segment; its end count value must be 0xFFFF */
  708. if ( valid->level >= FT_VALIDATE_PARANOID )
  709. {
  710. p = ends + ( num_segs - 1 ) * 2;
  711. if ( TT_PEEK_USHORT( p ) != 0xFFFFU )
  712. FT_INVALID_DATA;
  713. }
  714. {
  715. FT_UInt start, end, offset, n;
  716. FT_UInt last_start = 0, last_end = 0;
  717. FT_Int delta;
  718. FT_Byte* p_start = starts;
  719. FT_Byte* p_end = ends;
  720. FT_Byte* p_delta = deltas;
  721. FT_Byte* p_offset = offsets;
  722. for ( n = 0; n < num_segs; n++ )
  723. {
  724. p = p_offset;
  725. start = TT_NEXT_USHORT( p_start );
  726. end = TT_NEXT_USHORT( p_end );
  727. delta = TT_NEXT_SHORT( p_delta );
  728. offset = TT_NEXT_USHORT( p_offset );
  729. if ( start > end )
  730. FT_INVALID_DATA;
  731. /* this test should be performed at default validation level; */
  732. /* unfortunately, some popular Asian fonts have overlapping */
  733. /* ranges in their charmaps */
  734. /* */
  735. if ( start <= last_end && n > 0 )
  736. {
  737. if ( valid->level >= FT_VALIDATE_TIGHT )
  738. FT_INVALID_DATA;
  739. else
  740. {
  741. /* allow overlapping segments, provided their start points */
  742. /* and end points, respectively, are in ascending order */
  743. /* */
  744. if ( last_start > start || last_end > end )
  745. error |= TT_CMAP_FLAG_UNSORTED;
  746. else
  747. error |= TT_CMAP_FLAG_OVERLAPPING;
  748. }
  749. }
  750. if ( offset && offset != 0xFFFFU )
  751. {
  752. p += offset; /* start of glyph ID array */
  753. /* check that we point within the glyph IDs table only */
  754. if ( valid->level >= FT_VALIDATE_TIGHT )
  755. {
  756. if ( p < glyph_ids ||
  757. p + ( end - start + 1 ) * 2 > table + length )
  758. FT_INVALID_DATA;
  759. }
  760. /* Some fonts handle the last segment incorrectly. In */
  761. /* theory, 0xFFFF might point to an ordinary glyph -- */
  762. /* a cmap 4 is versatile and could be used for any */
  763. /* encoding, not only Unicode. However, reality shows */
  764. /* that far too many fonts are sloppy and incorrectly */
  765. /* set all fields but `start' and `end' for the last */
  766. /* segment if it contains only a single character. */
  767. /* */
  768. /* We thus omit the test here, delaying it to the */
  769. /* routines which actually access the cmap. */
  770. else if ( n != num_segs - 1 ||
  771. !( start == 0xFFFFU && end == 0xFFFFU ) )
  772. {
  773. if ( p < glyph_ids ||
  774. p + ( end - start + 1 ) * 2 > valid->limit )
  775. FT_INVALID_DATA;
  776. }
  777. /* check glyph indices within the segment range */
  778. if ( valid->level >= FT_VALIDATE_TIGHT )
  779. {
  780. FT_UInt i, idx;
  781. for ( i = start; i < end; i++ )
  782. {
  783. idx = FT_NEXT_USHORT( p );
  784. if ( idx != 0 )
  785. {
  786. idx = (FT_UInt)( idx + delta ) & 0xFFFFU;
  787. if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
  788. FT_INVALID_GLYPH_ID;
  789. }
  790. }
  791. }
  792. }
  793. else if ( offset == 0xFFFFU )
  794. {
  795. /* some fonts (erroneously?) use a range offset of 0xFFFF */
  796. /* to mean missing glyph in cmap table */
  797. /* */
  798. if ( valid->level >= FT_VALIDATE_PARANOID ||
  799. n != num_segs - 1 ||
  800. !( start == 0xFFFFU && end == 0xFFFFU ) )
  801. FT_INVALID_DATA;
  802. }
  803. last_start = start;
  804. last_end = end;
  805. }
  806. }
  807. return error;
  808. }
  809. static FT_UInt
  810. tt_cmap4_char_map_linear( TT_CMap cmap,
  811. FT_UInt32* pcharcode,
  812. FT_Bool next )
  813. {
  814. FT_UInt num_segs2, start, end, offset;
  815. FT_Int delta;
  816. FT_UInt i, num_segs;
  817. FT_UInt32 charcode = *pcharcode;
  818. FT_UInt gindex = 0;
  819. FT_Byte* p;
  820. p = cmap->data + 6;
  821. num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
  822. num_segs = num_segs2 >> 1;
  823. if ( !num_segs )
  824. return 0;
  825. if ( next )
  826. charcode++;
  827. /* linear search */
  828. for ( ; charcode <= 0xFFFFU; charcode++ )
  829. {
  830. FT_Byte* q;
  831. p = cmap->data + 14; /* ends table */
  832. q = cmap->data + 16 + num_segs2; /* starts table */
  833. for ( i = 0; i < num_segs; i++ )
  834. {
  835. end = TT_NEXT_USHORT( p );
  836. start = TT_NEXT_USHORT( q );
  837. if ( charcode >= start && charcode <= end )
  838. {
  839. p = q - 2 + num_segs2;
  840. delta = TT_PEEK_SHORT( p );
  841. p += num_segs2;
  842. offset = TT_PEEK_USHORT( p );
  843. /* some fonts have an incorrect last segment; */
  844. /* we have to catch it */
  845. if ( i >= num_segs - 1 &&
  846. start == 0xFFFFU && end == 0xFFFFU )
  847. {
  848. TT_Face face = (TT_Face)cmap->cmap.charmap.face;
  849. FT_Byte* limit = face->cmap_table + face->cmap_size;
  850. if ( offset && p + offset + 2 > limit )
  851. {
  852. delta = 1;
  853. offset = 0;
  854. }
  855. }
  856. if ( offset == 0xFFFFU )
  857. continue;
  858. if ( offset )
  859. {
  860. p += offset + ( charcode - start ) * 2;
  861. gindex = TT_PEEK_USHORT( p );
  862. if ( gindex != 0 )
  863. gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;
  864. }
  865. else
  866. gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU;
  867. break;
  868. }
  869. }
  870. if ( !next || gindex )
  871. break;
  872. }
  873. if ( next && gindex )
  874. *pcharcode = charcode;
  875. return gindex;
  876. }
  877. static FT_UInt
  878. tt_cmap4_char_map_binary( TT_CMap cmap,
  879. FT_UInt32* pcharcode,
  880. FT_Bool next )
  881. {
  882. FT_UInt num_segs2, start, end, offset;
  883. FT_Int delta;
  884. FT_UInt max, min, mid, num_segs;
  885. FT_UInt charcode = (FT_UInt)*pcharcode;
  886. FT_UInt gindex = 0;
  887. FT_Byte* p;
  888. p = cmap->data + 6;
  889. num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
  890. if ( !num_segs2 )
  891. return 0;
  892. num_segs = num_segs2 >> 1;
  893. /* make compiler happy */
  894. mid = num_segs;
  895. end = 0xFFFFU;
  896. if ( next )
  897. charcode++;
  898. min = 0;
  899. max = num_segs;
  900. /* binary search */
  901. while ( min < max )
  902. {
  903. mid = ( min + max ) >> 1;
  904. p = cmap->data + 14 + mid * 2;
  905. end = TT_PEEK_USHORT( p );
  906. p += 2 + num_segs2;
  907. start = TT_PEEK_USHORT( p );
  908. if ( charcode < start )
  909. max = mid;
  910. else if ( charcode > end )
  911. min = mid + 1;
  912. else
  913. {
  914. p += num_segs2;
  915. delta = TT_PEEK_SHORT( p );
  916. p += num_segs2;
  917. offset = TT_PEEK_USHORT( p );
  918. /* some fonts have an incorrect last segment; */
  919. /* we have to catch it */
  920. if ( mid >= num_segs - 1 &&
  921. start == 0xFFFFU && end == 0xFFFFU )
  922. {
  923. TT_Face face = (TT_Face)cmap->cmap.charmap.face;
  924. FT_Byte* limit = face->cmap_table + face->cmap_size;
  925. if ( offset && p + offset + 2 > limit )
  926. {
  927. delta = 1;
  928. offset = 0;
  929. }
  930. }
  931. /* search the first segment containing `charcode' */
  932. if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING )
  933. {
  934. FT_UInt i;
  935. /* call the current segment `max' */
  936. max = mid;
  937. if ( offset == 0xFFFFU )
  938. mid = max + 1;
  939. /* search in segments before the current segment */
  940. for ( i = max ; i > 0; i-- )
  941. {
  942. FT_UInt prev_end;
  943. FT_Byte* old_p;
  944. old_p = p;
  945. p = cmap->data + 14 + ( i - 1 ) * 2;
  946. prev_end = TT_PEEK_USHORT( p );
  947. if ( charcode > prev_end )
  948. {
  949. p = old_p;
  950. break;
  951. }
  952. end = prev_end;
  953. p += 2 + num_segs2;
  954. start = TT_PEEK_USHORT( p );
  955. p += num_segs2;
  956. delta = TT_PEEK_SHORT( p );
  957. p += num_segs2;
  958. offset = TT_PEEK_USHORT( p );
  959. if ( offset != 0xFFFFU )
  960. mid = i - 1;
  961. }
  962. /* no luck */
  963. if ( mid == max + 1 )
  964. {
  965. if ( i != max )
  966. {
  967. p = cmap->data + 14 + max * 2;
  968. end = TT_PEEK_USHORT( p );
  969. p += 2 + num_segs2;
  970. start = TT_PEEK_USHORT( p );
  971. p += num_segs2;
  972. delta = TT_PEEK_SHORT( p );
  973. p += num_segs2;
  974. offset = TT_PEEK_USHORT( p );
  975. }
  976. mid = max;
  977. /* search in segments after the current segment */
  978. for ( i = max + 1; i < num_segs; i++ )
  979. {
  980. FT_UInt next_end, next_start;
  981. p = cmap->data + 14 + i * 2;
  982. next_end = TT_PEEK_USHORT( p );
  983. p += 2 + num_segs2;
  984. next_start = TT_PEEK_USHORT( p );
  985. if ( charcode < next_start )
  986. break;
  987. end = next_end;
  988. start = next_start;
  989. p += num_segs2;
  990. delta = TT_PEEK_SHORT( p );
  991. p += num_segs2;
  992. offset = TT_PEEK_USHORT( p );
  993. if ( offset != 0xFFFFU )
  994. mid = i;
  995. }
  996. i--;
  997. /* still no luck */
  998. if ( mid == max )
  999. {
  1000. mid = i;
  1001. break;
  1002. }
  1003. }
  1004. /* end, start, delta, and offset are for the i'th segment */
  1005. if ( mid != i )
  1006. {
  1007. p = cmap->data + 14 + mid * 2;
  1008. end = TT_PEEK_USHORT( p );
  1009. p += 2 + num_segs2;
  1010. start = TT_PEEK_USHORT( p );
  1011. p += num_segs2;
  1012. delta = TT_PEEK_SHORT( p );
  1013. p += num_segs2;
  1014. offset = TT_PEEK_USHORT( p );
  1015. }
  1016. }
  1017. else
  1018. {
  1019. if ( offset == 0xFFFFU )
  1020. break;
  1021. }
  1022. if ( offset )
  1023. {
  1024. p += offset + ( charcode - start ) * 2;
  1025. gindex = TT_PEEK_USHORT( p );
  1026. if ( gindex != 0 )
  1027. gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;
  1028. }
  1029. else
  1030. gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU;
  1031. break;
  1032. }
  1033. }
  1034. if ( next )
  1035. {
  1036. TT_CMap4 cmap4 = (TT_CMap4)cmap;
  1037. /* if `charcode' is not in any segment, then `mid' is */
  1038. /* the segment nearest to `charcode' */
  1039. /* */
  1040. if ( charcode > end )
  1041. {
  1042. mid++;
  1043. if ( mid == num_segs )
  1044. return 0;
  1045. }
  1046. if ( tt_cmap4_set_range( cmap4, mid ) )
  1047. {
  1048. if ( gindex )
  1049. *pcharcode = charcode;
  1050. }
  1051. else
  1052. {
  1053. cmap4->cur_charcode = charcode;
  1054. if ( gindex )
  1055. cmap4->cur_gindex = gindex;
  1056. else
  1057. {
  1058. cmap4->cur_charcode = charcode;
  1059. tt_cmap4_next( cmap4 );
  1060. gindex = cmap4->cur_gindex;
  1061. }
  1062. if ( gindex )
  1063. *pcharcode = cmap4->cur_charcode;
  1064. }
  1065. }
  1066. return gindex;
  1067. }
  1068. FT_CALLBACK_DEF( FT_UInt )
  1069. tt_cmap4_char_index( TT_CMap cmap,
  1070. FT_UInt32 char_code )
  1071. {
  1072. if ( char_code >= 0x10000UL )
  1073. return 0;
  1074. if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
  1075. return tt_cmap4_char_map_linear( cmap, &char_code, 0 );
  1076. else
  1077. return tt_cmap4_char_map_binary( cmap, &char_code, 0 );
  1078. }
  1079. FT_CALLBACK_DEF( FT_UInt32 )
  1080. tt_cmap4_char_next( TT_CMap cmap,
  1081. FT_UInt32 *pchar_code )
  1082. {
  1083. FT_UInt gindex;
  1084. if ( *pchar_code >= 0xFFFFU )
  1085. return 0;
  1086. if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
  1087. gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 );
  1088. else
  1089. {
  1090. TT_CMap4 cmap4 = (TT_CMap4)cmap;
  1091. /* no need to search */
  1092. if ( *pchar_code == cmap4->cur_charcode )
  1093. {
  1094. tt_cmap4_next( cmap4 );
  1095. gindex = cmap4->cur_gindex;
  1096. if ( gindex )
  1097. *pchar_code = cmap4->cur_charcode;
  1098. }
  1099. else
  1100. gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 );
  1101. }
  1102. return gindex;
  1103. }
  1104. FT_CALLBACK_DEF( FT_Error )
  1105. tt_cmap4_get_info( TT_CMap cmap,
  1106. TT_CMapInfo *cmap_info )
  1107. {
  1108. FT_Byte* p = cmap->data + 4;
  1109. cmap_info->format = 4;
  1110. cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
  1111. return SFNT_Err_Ok;
  1112. }
  1113. FT_DEFINE_TT_CMAP(tt_cmap4_class_rec,
  1114. sizeof ( TT_CMap4Rec ),
  1115. (FT_CMap_InitFunc) tt_cmap4_init,
  1116. (FT_CMap_DoneFunc) NULL,
  1117. (FT_CMap_CharIndexFunc)tt_cmap4_char_index,
  1118. (FT_CMap_CharNextFunc) tt_cmap4_char_next,
  1119. NULL, NULL, NULL, NULL, NULL
  1120. ,
  1121. 4,
  1122. (TT_CMap_ValidateFunc) tt_cmap4_validate,
  1123. (TT_CMap_Info_GetFunc) tt_cmap4_get_info
  1124. )
  1125. #endif /* TT_CONFIG_CMAP_FORMAT_4 */
  1126. /*************************************************************************/
  1127. /*************************************************************************/
  1128. /***** *****/
  1129. /***** FORMAT 6 *****/
  1130. /***** *****/
  1131. /*************************************************************************/
  1132. /*************************************************************************/
  1133. /*************************************************************************/
  1134. /* */
  1135. /* TABLE OVERVIEW */
  1136. /* -------------- */
  1137. /* */
  1138. /* NAME OFFSET TYPE DESCRIPTION */
  1139. /* */
  1140. /* format 0 USHORT must be 4 */
  1141. /* length 2 USHORT table length in bytes */
  1142. /* language 4 USHORT Mac language code */
  1143. /* */
  1144. /* first 6 USHORT first segment code */
  1145. /* count 8 USHORT segment size in chars */
  1146. /* glyphIds 10 USHORT[count] glyph IDs */
  1147. /* */
  1148. /* A very simplified segment mapping. */
  1149. /* */
  1150. #ifdef TT_CONFIG_CMAP_FORMAT_6
  1151. FT_CALLBACK_DEF( FT_Error )
  1152. tt_cmap6_validate( FT_Byte* table,
  1153. FT_Validator valid )
  1154. {
  1155. FT_Byte* p;
  1156. FT_UInt length, count;
  1157. if ( table + 10 > valid->limit )
  1158. FT_INVALID_TOO_SHORT;
  1159. p = table + 2;
  1160. length = TT_NEXT_USHORT( p );
  1161. p = table + 8; /* skip language and start index */
  1162. count = TT_NEXT_USHORT( p );
  1163. if ( table + length > valid->limit || length < 10 + count * 2 )
  1164. FT_INVALID_TOO_SHORT;
  1165. /* check glyph indices */
  1166. if ( valid->level >= FT_VALIDATE_TIGHT )
  1167. {
  1168. FT_UInt gindex;
  1169. for ( ; count > 0; count-- )
  1170. {
  1171. gindex = TT_NEXT_USHORT( p );
  1172. if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )
  1173. FT_INVALID_GLYPH_ID;
  1174. }
  1175. }
  1176. return SFNT_Err_Ok;
  1177. }
  1178. FT_CALLBACK_DEF( FT_UInt )
  1179. tt_cmap6_char_index( TT_CMap cmap,
  1180. FT_UInt32 char_code )
  1181. {
  1182. FT_Byte* table = cmap->data;
  1183. FT_UInt result = 0;
  1184. FT_Byte* p = table + 6;
  1185. FT_UInt start = TT_NEXT_USHORT( p );
  1186. FT_UInt count = TT_NEXT_USHORT( p );
  1187. FT_UInt idx = (FT_UInt)( char_code - start );
  1188. if ( idx < count )
  1189. {
  1190. p += 2 * idx;
  1191. result = TT_PEEK_USHORT( p );
  1192. }
  1193. return result;
  1194. }
  1195. FT_CALLBACK_DEF( FT_UInt32 )
  1196. tt_cmap6_char_next( TT_CMap cmap,
  1197. FT_UInt32 *pchar_code )
  1198. {
  1199. FT_Byte* table = cmap->data;
  1200. FT_UInt32 result = 0;
  1201. FT_UInt32 char_code = *pchar_code + 1;
  1202. FT_UInt gindex = 0;
  1203. FT_Byte* p = table + 6;
  1204. FT_UInt start = TT_NEXT_USHORT( p );
  1205. FT_UInt count = TT_NEXT_USHORT( p );
  1206. FT_UInt idx;
  1207. if ( char_code >= 0x10000UL )
  1208. goto Exit;
  1209. if ( char_code < start )
  1210. char_code = start;
  1211. idx = (FT_UInt)( char_code - start );
  1212. p += 2 * idx;
  1213. for ( ; idx < count; idx++ )
  1214. {
  1215. gindex = TT_NEXT_USHORT( p );
  1216. if ( gindex != 0 )
  1217. {
  1218. result = char_code;
  1219. break;
  1220. }
  1221. char_code++;
  1222. }
  1223. Exit:
  1224. *pchar_code = result;
  1225. return gindex;
  1226. }
  1227. FT_CALLBACK_DEF( FT_Error )
  1228. tt_cmap6_get_info( TT_CMap cmap,
  1229. TT_CMapInfo *cmap_info )
  1230. {
  1231. FT_Byte* p = cmap->data + 4;
  1232. cmap_info->format = 6;
  1233. cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
  1234. return SFNT_Err_Ok;
  1235. }
  1236. FT_DEFINE_TT_CMAP(tt_cmap6_class_rec,
  1237. sizeof ( TT_CMapRec ),
  1238. (FT_CMap_InitFunc) tt_cmap_init,
  1239. (FT_CMap_DoneFunc) NULL,
  1240. (FT_CMap_CharIndexFunc)tt_cmap6_char_index,
  1241. (FT_CMap_CharNextFunc) tt_cmap6_char_next,
  1242. NULL, NULL, NULL, NULL, NULL
  1243. ,
  1244. 6,
  1245. (TT_CMap_ValidateFunc) tt_cmap6_validate,
  1246. (TT_CMap_Info_GetFunc) tt_cmap6_get_info
  1247. )
  1248. #endif /* TT_CONFIG_CMAP_FORMAT_6 */
  1249. /*************************************************************************/
  1250. /*************************************************************************/
  1251. /***** *****/
  1252. /***** FORMAT 8 *****/
  1253. /***** *****/
  1254. /***** It is hard to completely understand what the OpenType spec *****/
  1255. /***** says about this format, but here is my conclusion. *****/
  1256. /***** *****/
  1257. /***** The purpose of this format is to easily map UTF-16 text to *****/
  1258. /***** glyph indices. Basically, the `char_code' must be in one of *****/
  1259. /***** the following formats: *****/
  1260. /***** *****/
  1261. /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/
  1262. /***** Area (i.e. U+D800-U+DFFF). *****/
  1263. /***** *****/
  1264. /***** - A 32-bit value, made of two surrogate values, i.e.. if *****/
  1265. /***** `char_code = (char_hi << 16) | char_lo', then both *****/
  1266. /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/
  1267. /***** Area. *****/
  1268. /***** *****/
  1269. /***** The `is32' table embedded in the charmap indicates whether a *****/
  1270. /***** given 16-bit value is in the surrogates area or not. *****/
  1271. /***** *****/
  1272. /***** So, for any given `char_code', we can assert the following: *****/
  1273. /***** *****/
  1274. /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/
  1275. /***** *****/
  1276. /***** If `char_hi != 0' then we must have both *****/
  1277. /***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/
  1278. /***** *****/
  1279. /*************************************************************************/
  1280. /*************************************************************************/
  1281. /*************************************************************************/
  1282. /* */
  1283. /* TABLE OVERVIEW */
  1284. /* -------------- */
  1285. /* */
  1286. /* NAME OFFSET TYPE DESCRIPTION */
  1287. /* */
  1288. /* format 0 USHORT must be 8 */
  1289. /* reserved 2 USHORT reserved */
  1290. /* length 4 ULONG length in bytes */
  1291. /* language 8 ULONG Mac language code */
  1292. /* is32 12 BYTE[8192] 32-bitness bitmap */
  1293. /* count 8204 ULONG number of groups */
  1294. /* */
  1295. /* This header is followed by `count' groups of the following format: */
  1296. /* */
  1297. /* start 0 ULONG first charcode */
  1298. /* end 4 ULONG last charcode */
  1299. /* startId 8 ULONG start glyph ID for the group */
  1300. /* */
  1301. #ifdef TT_CONFIG_CMAP_FORMAT_8
  1302. FT_CALLBACK_DEF( FT_Error )
  1303. tt_cmap8_validate( FT_Byte* table,
  1304. FT_Validator valid )
  1305. {
  1306. FT_Byte* p = table + 4;
  1307. FT_Byte* is32;
  1308. FT_UInt32 length;
  1309. FT_UInt32 num_groups;
  1310. if ( table + 16 + 8192 > valid->limit )
  1311. FT_INVALID_TOO_SHORT;
  1312. length = TT_NEXT_ULONG( p );
  1313. if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 )
  1314. FT_INVALID_TOO_SHORT;
  1315. is32 = table + 12;
  1316. p = is32 + 8192; /* skip `is32' array */
  1317. num_groups = TT_NEXT_ULONG( p );
  1318. if ( p + num_groups * 12 > valid->limit )
  1319. FT_INVALID_TOO_SHORT;
  1320. /* check groups, they must be in increasing order */
  1321. {
  1322. FT_UInt32 n, start, end, start_id, count, last = 0;
  1323. for ( n = 0; n < num_groups; n++ )
  1324. {
  1325. FT_UInt hi, lo;
  1326. start = TT_NEXT_ULONG( p );
  1327. end = TT_NEXT_ULONG( p );
  1328. start_id = TT_NEXT_ULONG( p );
  1329. if ( start > end )
  1330. FT_INVALID_DATA;
  1331. if ( n > 0 && start <= last )
  1332. FT_INVALID_DATA;
  1333. if ( valid->level >= FT_VALIDATE_TIGHT )
  1334. {
  1335. if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) )
  1336. FT_INVALID_GLYPH_ID;
  1337. count = (FT_UInt32)( end - start + 1 );
  1338. if ( start & ~0xFFFFU )
  1339. {
  1340. /* start_hi != 0; check that is32[i] is 1 for each i in */
  1341. /* the `hi' and `lo' of the range [start..end] */
  1342. for ( ; count > 0; count--, start++ )
  1343. {
  1344. hi = (FT_UInt)( start >> 16 );
  1345. lo = (FT_UInt)( start & 0xFFFFU );
  1346. if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 )
  1347. FT_INVALID_DATA;
  1348. if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 )
  1349. FT_INVALID_DATA;
  1350. }
  1351. }
  1352. else
  1353. {
  1354. /* start_hi == 0; check that is32[i] is 0 for each i in */
  1355. /* the range [start..end] */
  1356. /* end_hi cannot be != 0! */
  1357. if ( end & ~0xFFFFU )
  1358. FT_INVALID_DATA;
  1359. for ( ; count > 0; count--, start++ )
  1360. {
  1361. lo = (FT_UInt)( start & 0xFFFFU );
  1362. if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 )
  1363. FT_INVALID_DATA;
  1364. }
  1365. }
  1366. }
  1367. last = end;
  1368. }
  1369. }
  1370. return SFNT_Err_Ok;
  1371. }
  1372. FT_CALLBACK_DEF( FT_UInt )
  1373. tt_cmap8_char_index( TT_CMap cmap,
  1374. FT_UInt32 char_code )
  1375. {
  1376. FT_Byte* table = cmap->data;
  1377. FT_UInt result = 0;
  1378. FT_Byte* p = table + 8204;
  1379. FT_UInt32 num_groups = TT_NEXT_ULONG( p );
  1380. FT_UInt32 start, end, start_id;
  1381. for ( ; num_groups > 0; num_groups-- )
  1382. {
  1383. start = TT_NEXT_ULONG( p );
  1384. end = TT_NEXT_ULONG( p );
  1385. start_id = TT_NEXT_ULONG( p );
  1386. if ( char_code < start )
  1387. break;
  1388. if ( char_code <= end )
  1389. {
  1390. result = (FT_UInt)( start_id + char_code - start );
  1391. break;
  1392. }
  1393. }
  1394. return result;
  1395. }
  1396. FT_CALLBACK_DEF( FT_UInt32 )
  1397. tt_cmap8_char_next( TT_CMap cmap,
  1398. FT_UInt32 *pchar_code )
  1399. {
  1400. FT_UInt32 result = 0;
  1401. FT_UInt32 char_code = *pchar_code + 1;
  1402. FT_UInt gindex = 0;
  1403. FT_Byte* table = cmap->data;
  1404. FT_Byte* p = table + 8204;
  1405. FT_UInt32 num_groups = TT_NEXT_ULONG( p );
  1406. FT_UInt32 start, end, start_id;
  1407. p = table + 8208;
  1408. for ( ; num_groups > 0; num_groups-- )
  1409. {
  1410. start = TT_NEXT_ULONG( p );
  1411. end = TT_NEXT_ULONG( p );
  1412. start_id = TT_NEXT_ULONG( p );
  1413. if ( char_code < start )
  1414. char_code = start;
  1415. if ( char_code <= end )
  1416. {
  1417. gindex = (FT_UInt)( char_code - start + start_id );
  1418. if ( gindex != 0 )
  1419. {
  1420. result = char_code;
  1421. goto Exit;
  1422. }
  1423. }
  1424. }
  1425. Exit:
  1426. *pchar_code = result;
  1427. return gindex;
  1428. }
  1429. FT_CALLBACK_DEF( FT_Error )
  1430. tt_cmap8_get_info( TT_CMap cmap,
  1431. TT_CMapInfo *cmap_info )
  1432. {
  1433. FT_Byte* p = cmap->data + 8;
  1434. cmap_info->format = 8;
  1435. cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
  1436. return SFNT_Err_Ok;
  1437. }
  1438. FT_DEFINE_TT_CMAP(tt_cmap8_class_rec,
  1439. sizeof ( TT_CMapRec ),
  1440. (FT_CMap_InitFunc) tt_cmap_init,
  1441. (FT_CMap_DoneFunc) NULL,
  1442. (FT_CMap_CharIndexFunc)tt_cmap8_char_index,
  1443. (FT_CMap_CharNextFunc) tt_cmap8_char_next,
  1444. NULL, NULL, NULL, NULL, NULL
  1445. ,
  1446. 8,
  1447. (TT_CMap_ValidateFunc) tt_cmap8_validate,
  1448. (TT_CMap_Info_GetFunc) tt_cmap8_get_info
  1449. )
  1450. #endif /* TT_CONFIG_CMAP_FORMAT_8 */
  1451. /*************************************************************************/
  1452. /*************************************************************************/
  1453. /***** *****/
  1454. /***** FORMAT 10 *****/
  1455. /***** *****/
  1456. /*************************************************************************/
  1457. /*************************************************************************/
  1458. /*************************************************************************/
  1459. /* */
  1460. /* TABLE OVERVIEW */
  1461. /* -------------- */
  1462. /* */
  1463. /* NAME OFFSET TYPE DESCRIPTION */
  1464. /* */
  1465. /* format 0 USHORT must be 10 */
  1466. /* reserved 2 USHORT reserved */
  1467. /* length 4 ULONG length in bytes */
  1468. /* language 8 ULONG Mac language code */
  1469. /* */
  1470. /* start 12 ULONG first char in range */
  1471. /* count 16 ULONG number of chars in range */
  1472. /* glyphIds 20 USHORT[count] glyph indices covered */
  1473. /* */
  1474. #ifdef TT_CONFIG_CMAP_FORMAT_10
  1475. FT_CALLBACK_DEF( FT_Error )
  1476. tt_cmap10_validate( FT_Byte* table,
  1477. FT_Validator valid )
  1478. {
  1479. FT_Byte* p = table + 4;
  1480. FT_ULong length, count;
  1481. if ( table + 20 > valid->limit )
  1482. FT_INVALID_TOO_SHORT;
  1483. length = TT_NEXT_ULONG( p );
  1484. p = table + 16;
  1485. count = TT_NEXT_ULONG( p );
  1486. if ( length > (FT_ULong)( valid->limit - table ) ||
  1487. length < 20 + count * 2 )
  1488. FT_INVALID_TOO_SHORT;
  1489. /* check glyph indices */
  1490. if ( valid->level >= FT_VALIDATE_TIGHT )
  1491. {
  1492. FT_UInt gindex;
  1493. for ( ; count > 0; count-- )
  1494. {
  1495. gindex = TT_NEXT_USHORT( p );
  1496. if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) )
  1497. FT_INVALID_GLYPH_ID;
  1498. }
  1499. }
  1500. return SFNT_Err_Ok;
  1501. }
  1502. FT_CALLBACK_DEF( FT_UInt )
  1503. tt_cmap10_char_index( TT_CMap cmap,
  1504. FT_UInt32 char_code )
  1505. {
  1506. FT_Byte* table = cmap->data;
  1507. FT_UInt result = 0;
  1508. FT_Byte* p = table + 12;
  1509. FT_UInt32 start = TT_NEXT_ULONG( p );
  1510. FT_UInt32 count = TT_NEXT_ULONG( p );
  1511. FT_UInt32 idx = (FT_ULong)( char_code - start );
  1512. if ( idx < count )
  1513. {
  1514. p += 2 * idx;
  1515. result = TT_PEEK_USHORT( p );
  1516. }
  1517. return result;
  1518. }
  1519. FT_CALLBACK_DEF( FT_UInt32 )
  1520. tt_cmap10_char_next( TT_CMap cmap,
  1521. FT_UInt32 *pchar_code )
  1522. {
  1523. FT_Byte* table = cmap->data;
  1524. FT_UInt32 char_code = *pchar_code + 1;
  1525. FT_UInt gindex = 0;
  1526. FT_Byte* p = table + 12;
  1527. FT_UInt32 start = TT_NEXT_ULONG( p );
  1528. FT_UInt32 count = TT_NEXT_ULONG( p );
  1529. FT_UInt32 idx;
  1530. if ( char_code < start )
  1531. char_code = start;
  1532. idx = (FT_UInt32)( char_code - start );
  1533. p += 2 * idx;
  1534. for ( ; idx < count; idx++ )
  1535. {
  1536. gindex = TT_NEXT_USHORT( p );
  1537. if ( gindex != 0 )
  1538. break;
  1539. char_code++;
  1540. }
  1541. *pchar_code = char_code;
  1542. return gindex;
  1543. }
  1544. FT_CALLBACK_DEF( FT_Error )
  1545. tt_cmap10_get_info( TT_CMap cmap,
  1546. TT_CMapInfo *cmap_info )
  1547. {
  1548. FT_Byte* p = cmap->data + 8;
  1549. cmap_info->format = 10;
  1550. cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
  1551. return SFNT_Err_Ok;
  1552. }
  1553. FT_DEFINE_TT_CMAP(tt_cmap10_class_rec,
  1554. sizeof ( TT_CMapRec ),
  1555. (FT_CMap_InitFunc) tt_cmap_init,
  1556. (FT_CMap_DoneFunc) NULL,
  1557. (FT_CMap_CharIndexFunc)tt_cmap10_char_index,
  1558. (FT_CMap_CharNextFunc) tt_cmap10_char_next,
  1559. NULL, NULL, NULL, NULL, NULL
  1560. ,
  1561. 10,
  1562. (TT_CMap_ValidateFunc) tt_cmap10_validate,
  1563. (TT_CMap_Info_GetFunc) tt_cmap10_get_info
  1564. )
  1565. #endif /* TT_CONFIG_CMAP_FORMAT_10 */
  1566. /*************************************************************************/
  1567. /*************************************************************************/
  1568. /***** *****/
  1569. /***** FORMAT 12 *****/
  1570. /***** *****/
  1571. /*************************************************************************/
  1572. /*************************************************************************/
  1573. /*************************************************************************/
  1574. /* */
  1575. /* TABLE OVERVIEW */
  1576. /* -------------- */
  1577. /* */
  1578. /* NAME OFFSET TYPE DESCRIPTION */
  1579. /* */
  1580. /* format 0 USHORT must be 12 */
  1581. /* reserved 2 USHORT reserved */
  1582. /* length 4 ULONG length in bytes */
  1583. /* language 8 ULONG Mac language code */
  1584. /* count 12 ULONG number of groups */
  1585. /* 16 */
  1586. /* */
  1587. /* This header is followed by `count' groups of the following format: */
  1588. /* */
  1589. /* start 0 ULONG first charcode */
  1590. /* end 4 ULONG last charcode */
  1591. /* startId 8 ULONG start glyph ID for the group */
  1592. /* */
  1593. #ifdef TT_CONFIG_CMAP_FORMAT_12
  1594. typedef struct TT_CMap12Rec_
  1595. {
  1596. TT_CMapRec cmap;
  1597. FT_Bool valid;
  1598. FT_ULong cur_charcode;
  1599. FT_UInt cur_gindex;
  1600. FT_ULong cur_group;
  1601. FT_ULong num_groups;
  1602. } TT_CMap12Rec, *TT_CMap12;
  1603. FT_CALLBACK_DEF( FT_Error )
  1604. tt_cmap12_init( TT_CMap12 cmap,
  1605. FT_Byte* table )
  1606. {
  1607. cmap->cmap.data = table;
  1608. table += 12;
  1609. cmap->num_groups = FT_PEEK_ULONG( table );
  1610. cmap->valid = 0;
  1611. return SFNT_Err_Ok;
  1612. }
  1613. FT_CALLBACK_DEF( FT_Error )
  1614. tt_cmap12_validate( FT_Byte* table,
  1615. FT_Validator valid )
  1616. {
  1617. FT_Byte* p;
  1618. FT_ULong length;
  1619. FT_ULong num_groups;
  1620. if ( table + 16 > valid->limit )
  1621. FT_INVALID_TOO_SHORT;
  1622. p = table + 4;
  1623. length = TT_NEXT_ULONG( p );
  1624. p = table + 12;
  1625. num_groups = TT_NEXT_ULONG( p );
  1626. if ( length > (FT_ULong)( valid->limit - table ) ||
  1627. length < 16 + 12 * num_groups )
  1628. FT_INVALID_TOO_SHORT;
  1629. /* check groups, they must be in increasing order */
  1630. {
  1631. FT_ULong n, start, end, start_id, last = 0;
  1632. for ( n = 0; n < num_groups; n++ )
  1633. {
  1634. start = TT_NEXT_ULONG( p );
  1635. end = TT_NEXT_ULONG( p );
  1636. start_id = TT_NEXT_ULONG( p );
  1637. if ( start > end )
  1638. FT_INVALID_DATA;
  1639. if ( n > 0 && start <= last )
  1640. FT_INVALID_DATA;
  1641. if ( valid->level >= FT_VALIDATE_TIGHT )
  1642. {
  1643. if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) )
  1644. FT_INVALID_GLYPH_ID;
  1645. }
  1646. last = end;
  1647. }
  1648. }
  1649. return SFNT_Err_Ok;
  1650. }
  1651. /* search the index of the charcode next to cmap->cur_charcode */
  1652. /* cmap->cur_group should be set up properly by caller */
  1653. /* */
  1654. static void
  1655. tt_cmap12_next( TT_CMap12 cmap )
  1656. {
  1657. FT_Byte* p;
  1658. FT_ULong start, end, start_id, char_code;
  1659. FT_ULong n;
  1660. FT_UInt gindex;
  1661. if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
  1662. goto Fail;
  1663. char_code = cmap->cur_charcode + 1;
  1664. n = cmap->cur_group;
  1665. for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
  1666. {
  1667. p = cmap->cmap.data + 16 + 12 * n;
  1668. start = TT_NEXT_ULONG( p );
  1669. end = TT_NEXT_ULONG( p );
  1670. start_id = TT_PEEK_ULONG( p );
  1671. if ( char_code < start )
  1672. char_code = start;
  1673. for ( ; char_code <= end; char_code++ )
  1674. {
  1675. gindex = (FT_UInt)( start_id + char_code - start );
  1676. if ( gindex )
  1677. {
  1678. cmap->cur_charcode = char_code;;
  1679. cmap->cur_gindex = gindex;
  1680. cmap->cur_group = n;
  1681. return;
  1682. }
  1683. }
  1684. }
  1685. Fail:
  1686. cmap->valid = 0;
  1687. }
  1688. static FT_UInt
  1689. tt_cmap12_char_map_binary( TT_CMap cmap,
  1690. FT_UInt32* pchar_code,
  1691. FT_Bool next )
  1692. {
  1693. FT_UInt gindex = 0;
  1694. FT_Byte* p = cmap->data + 12;
  1695. FT_UInt32 num_groups = TT_PEEK_ULONG( p );
  1696. FT_UInt32 char_code = *pchar_code;
  1697. FT_UInt32 start, end, start_id;
  1698. FT_UInt32 max, min, mid;
  1699. if ( !num_groups )
  1700. return 0;
  1701. /* make compiler happy */
  1702. mid = num_groups;
  1703. end = 0xFFFFFFFFUL;
  1704. if ( next )
  1705. char_code++;
  1706. min = 0;
  1707. max = num_groups;
  1708. /* binary search */
  1709. while ( min < max )
  1710. {
  1711. mid = ( min + max ) >> 1;
  1712. p = cmap->data + 16 + 12 * mid;
  1713. start = TT_NEXT_ULONG( p );
  1714. end = TT_NEXT_ULONG( p );
  1715. if ( char_code < start )
  1716. max = mid;
  1717. else if ( char_code > end )
  1718. min = mid + 1;
  1719. else
  1720. {
  1721. start_id = TT_PEEK_ULONG( p );
  1722. gindex = (FT_UInt)( start_id + char_code - start );
  1723. break;
  1724. }
  1725. }
  1726. if ( next )
  1727. {
  1728. TT_CMap12 cmap12 = (TT_CMap12)cmap;
  1729. /* if `char_code' is not in any group, then `mid' is */
  1730. /* the group nearest to `char_code' */
  1731. /* */
  1732. if ( char_code > end )
  1733. {
  1734. mid++;
  1735. if ( mid == num_groups )
  1736. return 0;
  1737. }
  1738. cmap12->valid = 1;
  1739. cmap12->cur_charcode = char_code;
  1740. cmap12->cur_group = mid;
  1741. if ( !gindex )
  1742. {
  1743. tt_cmap12_next( cmap12 );
  1744. if ( cmap12->valid )
  1745. gindex = cmap12->cur_gindex;
  1746. }
  1747. else
  1748. cmap12->cur_gindex = gindex;
  1749. if ( gindex )
  1750. *pchar_code = cmap12->cur_charcode;
  1751. }
  1752. return gindex;
  1753. }
  1754. FT_CALLBACK_DEF( FT_UInt )
  1755. tt_cmap12_char_index( TT_CMap cmap,
  1756. FT_UInt32 char_code )
  1757. {
  1758. return tt_cmap12_char_map_binary( cmap, &char_code, 0 );
  1759. }
  1760. FT_CALLBACK_DEF( FT_UInt32 )
  1761. tt_cmap12_char_next( TT_CMap cmap,
  1762. FT_UInt32 *pchar_code )
  1763. {
  1764. TT_CMap12 cmap12 = (TT_CMap12)cmap;
  1765. FT_ULong gindex;
  1766. if ( cmap12->cur_charcode >= 0xFFFFFFFFUL )
  1767. return 0;
  1768. /* no need to search */
  1769. if ( cmap12->valid && cmap12->cur_charcode == *pchar_code )
  1770. {
  1771. tt_cmap12_next( cmap12 );
  1772. if ( cmap12->valid )
  1773. {
  1774. gindex = cmap12->cur_gindex;
  1775. /* XXX: check cur_charcode overflow is expected */
  1776. if ( gindex )
  1777. *pchar_code = (FT_UInt32)cmap12->cur_charcode;
  1778. }
  1779. else
  1780. gindex = 0;
  1781. }
  1782. else
  1783. gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 );
  1784. /* XXX: check gindex overflow is expected */
  1785. return (FT_UInt32)gindex;
  1786. }
  1787. FT_CALLBACK_DEF( FT_Error )
  1788. tt_cmap12_get_info( TT_CMap cmap,
  1789. TT_CMapInfo *cmap_info )
  1790. {
  1791. FT_Byte* p = cmap->data + 8;
  1792. cmap_info->format = 12;
  1793. cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
  1794. return SFNT_Err_Ok;
  1795. }
  1796. FT_DEFINE_TT_CMAP(tt_cmap12_class_rec,
  1797. sizeof ( TT_CMap12Rec ),
  1798. (FT_CMap_InitFunc) tt_cmap12_init,
  1799. (FT_CMap_DoneFunc) NULL,
  1800. (FT_CMap_CharIndexFunc)tt_cmap12_char_index,
  1801. (FT_CMap_CharNextFunc) tt_cmap12_char_next,
  1802. NULL, NULL, NULL, NULL, NULL
  1803. ,
  1804. 12,
  1805. (TT_CMap_ValidateFunc) tt_cmap12_validate,
  1806. (TT_CMap_Info_GetFunc) tt_cmap12_get_info
  1807. )
  1808. #endif /* TT_CONFIG_CMAP_FORMAT_12 */
  1809. /*************************************************************************/
  1810. /*************************************************************************/
  1811. /***** *****/
  1812. /***** FORMAT 13 *****/
  1813. /***** *****/
  1814. /*************************************************************************/
  1815. /*************************************************************************/
  1816. /*************************************************************************/
  1817. /* */
  1818. /* TABLE OVERVIEW */
  1819. /* -------------- */
  1820. /* */
  1821. /* NAME OFFSET TYPE DESCRIPTION */
  1822. /* */
  1823. /* format 0 USHORT must be 13 */
  1824. /* reserved 2 USHORT reserved */
  1825. /* length 4 ULONG length in bytes */
  1826. /* language 8 ULONG Mac language code */
  1827. /* count 12 ULONG number of groups */
  1828. /* 16 */
  1829. /* */
  1830. /* This header is followed by `count' groups of the following format: */
  1831. /* */
  1832. /* start 0 ULONG first charcode */
  1833. /* end 4 ULONG last charcode */
  1834. /* glyphId 8 ULONG glyph ID for the whole group */
  1835. /* */
  1836. #ifdef TT_CONFIG_CMAP_FORMAT_13
  1837. typedef struct TT_CMap13Rec_
  1838. {
  1839. TT_CMapRec cmap;
  1840. FT_Bool valid;
  1841. FT_ULong cur_charcode;
  1842. FT_UInt cur_gindex;
  1843. FT_ULong cur_group;
  1844. FT_ULong num_groups;
  1845. } TT_CMap13Rec, *TT_CMap13;
  1846. FT_CALLBACK_DEF( FT_Error )
  1847. tt_cmap13_init( TT_CMap13 cmap,
  1848. FT_Byte* table )
  1849. {
  1850. cmap->cmap.data = table;
  1851. table += 12;
  1852. cmap->num_groups = FT_PEEK_ULONG( table );
  1853. cmap->valid = 0;
  1854. return SFNT_Err_Ok;
  1855. }
  1856. FT_CALLBACK_DEF( FT_Error )
  1857. tt_cmap13_validate( FT_Byte* table,
  1858. FT_Validator valid )
  1859. {
  1860. FT_Byte* p;
  1861. FT_ULong length;
  1862. FT_ULong num_groups;
  1863. if ( table + 16 > valid->limit )
  1864. FT_INVALID_TOO_SHORT;
  1865. p = table + 4;
  1866. length = TT_NEXT_ULONG( p );
  1867. p = table + 12;
  1868. num_groups = TT_NEXT_ULONG( p );
  1869. if ( length > (FT_ULong)( valid->limit - table ) ||
  1870. length < 16 + 12 * num_groups )
  1871. FT_INVALID_TOO_SHORT;
  1872. /* check groups, they must be in increasing order */
  1873. {
  1874. FT_ULong n, start, end, glyph_id, last = 0;
  1875. for ( n = 0; n < num_groups; n++ )
  1876. {
  1877. start = TT_NEXT_ULONG( p );
  1878. end = TT_NEXT_ULONG( p );
  1879. glyph_id = TT_NEXT_ULONG( p );
  1880. if ( start > end )
  1881. FT_INVALID_DATA;
  1882. if ( n > 0 && start <= last )
  1883. FT_INVALID_DATA;
  1884. if ( valid->level >= FT_VALIDATE_TIGHT )
  1885. {
  1886. if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) )
  1887. FT_INVALID_GLYPH_ID;
  1888. }
  1889. last = end;
  1890. }
  1891. }
  1892. return SFNT_Err_Ok;
  1893. }
  1894. /* search the index of the charcode next to cmap->cur_charcode */
  1895. /* cmap->cur_group should be set up properly by caller */
  1896. /* */
  1897. static void
  1898. tt_cmap13_next( TT_CMap13 cmap )
  1899. {
  1900. FT_Byte* p;
  1901. FT_ULong start, end, glyph_id, char_code;
  1902. FT_ULong n;
  1903. FT_UInt gindex;
  1904. if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
  1905. goto Fail;
  1906. char_code = cmap->cur_charcode + 1;
  1907. n = cmap->cur_group;
  1908. for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
  1909. {
  1910. p = cmap->cmap.data + 16 + 12 * n;
  1911. start = TT_NEXT_ULONG( p );
  1912. end = TT_NEXT_ULONG( p );
  1913. glyph_id = TT_PEEK_ULONG( p );
  1914. if ( char_code < start )
  1915. char_code = start;
  1916. if ( char_code <= end )
  1917. {
  1918. gindex = (FT_UInt)glyph_id;
  1919. if ( gindex )
  1920. {
  1921. cmap->cur_charcode = char_code;;
  1922. cmap->cur_gindex = gindex;
  1923. cmap->cur_group = n;
  1924. return;
  1925. }
  1926. }
  1927. }
  1928. Fail:
  1929. cmap->valid = 0;
  1930. }
  1931. static FT_UInt
  1932. tt_cmap13_char_map_binary( TT_CMap cmap,
  1933. FT_UInt32* pchar_code,
  1934. FT_Bool next )
  1935. {
  1936. FT_UInt gindex = 0;
  1937. FT_Byte* p = cmap->data + 12;
  1938. FT_UInt32 num_groups = TT_PEEK_ULONG( p );
  1939. FT_UInt32 char_code = *pchar_code;
  1940. FT_UInt32 start, end;
  1941. FT_UInt32 max, min, mid;
  1942. if ( !num_groups )
  1943. return 0;
  1944. /* make compiler happy */
  1945. mid = num_groups;
  1946. end = 0xFFFFFFFFUL;
  1947. if ( next )
  1948. char_code++;
  1949. min = 0;
  1950. max = num_groups;
  1951. /* binary search */
  1952. while ( min < max )
  1953. {
  1954. mid = ( min + max ) >> 1;
  1955. p = cmap->data + 16 + 12 * mid;
  1956. start = TT_NEXT_ULONG( p );
  1957. end = TT_NEXT_ULONG( p );
  1958. if ( char_code < start )
  1959. max = mid;
  1960. else if ( char_code > end )
  1961. min = mid + 1;
  1962. else
  1963. {
  1964. gindex = (FT_UInt)TT_PEEK_ULONG( p );
  1965. break;
  1966. }
  1967. }
  1968. if ( next )
  1969. {
  1970. TT_CMap13 cmap13 = (TT_CMap13)cmap;
  1971. /* if `char_code' is not in any group, then `mid' is */
  1972. /* the group nearest to `char_code' */
  1973. /* */
  1974. if ( char_code > end )
  1975. {
  1976. mid++;
  1977. if ( mid == num_groups )
  1978. return 0;
  1979. }
  1980. cmap13->valid = 1;
  1981. cmap13->cur_charcode = char_code;
  1982. cmap13->cur_group = mid;
  1983. if ( !gindex )
  1984. {
  1985. tt_cmap13_next( cmap13 );
  1986. if ( cmap13->valid )
  1987. gindex = cmap13->cur_gindex;
  1988. }
  1989. else
  1990. cmap13->cur_gindex = gindex;
  1991. if ( gindex )
  1992. *pchar_code = cmap13->cur_charcode;
  1993. }
  1994. return gindex;
  1995. }
  1996. FT_CALLBACK_DEF( FT_UInt )
  1997. tt_cmap13_char_index( TT_CMap cmap,
  1998. FT_UInt32 char_code )
  1999. {
  2000. return tt_cmap13_char_map_binary( cmap, &char_code, 0 );
  2001. }
  2002. FT_CALLBACK_DEF( FT_UInt32 )
  2003. tt_cmap13_char_next( TT_CMap cmap,
  2004. FT_UInt32 *pchar_code )
  2005. {
  2006. TT_CMap13 cmap13 = (TT_CMap13)cmap;
  2007. FT_UInt gindex;
  2008. if ( cmap13->cur_charcode >= 0xFFFFFFFFUL )
  2009. return 0;
  2010. /* no need to search */
  2011. if ( cmap13->valid && cmap13->cur_charcode == *pchar_code )
  2012. {
  2013. tt_cmap13_next( cmap13 );
  2014. if ( cmap13->valid )
  2015. {
  2016. gindex = cmap13->cur_gindex;
  2017. if ( gindex )
  2018. *pchar_code = cmap13->cur_charcode;
  2019. }
  2020. else
  2021. gindex = 0;
  2022. }
  2023. else
  2024. gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 );
  2025. return gindex;
  2026. }
  2027. FT_CALLBACK_DEF( FT_Error )
  2028. tt_cmap13_get_info( TT_CMap cmap,
  2029. TT_CMapInfo *cmap_info )
  2030. {
  2031. FT_Byte* p = cmap->data + 8;
  2032. cmap_info->format = 13;
  2033. cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
  2034. return SFNT_Err_Ok;
  2035. }
  2036. FT_DEFINE_TT_CMAP(tt_cmap13_class_rec,
  2037. sizeof ( TT_CMap13Rec ),
  2038. (FT_CMap_InitFunc) tt_cmap13_init,
  2039. (FT_CMap_DoneFunc) NULL,
  2040. (FT_CMap_CharIndexFunc)tt_cmap13_char_index,
  2041. (FT_CMap_CharNextFunc) tt_cmap13_char_next,
  2042. NULL, NULL, NULL, NULL, NULL
  2043. ,
  2044. 13,
  2045. (TT_CMap_ValidateFunc) tt_cmap13_validate,
  2046. (TT_CMap_Info_GetFunc) tt_cmap13_get_info
  2047. )
  2048. #endif /* TT_CONFIG_CMAP_FORMAT_13 */
  2049. /*************************************************************************/
  2050. /*************************************************************************/
  2051. /***** *****/
  2052. /***** FORMAT 14 *****/
  2053. /***** *****/
  2054. /*************************************************************************/
  2055. /*************************************************************************/
  2056. /*************************************************************************/
  2057. /* */
  2058. /* TABLE OVERVIEW */
  2059. /* -------------- */
  2060. /* */
  2061. /* NAME OFFSET TYPE DESCRIPTION */
  2062. /* */
  2063. /* format 0 USHORT must be 14 */
  2064. /* length 2 ULONG table length in bytes */
  2065. /* numSelector 6 ULONG number of variation sel. records */
  2066. /* */
  2067. /* Followed by numSelector records, each of which looks like */
  2068. /* */
  2069. /* varSelector 0 UINT24 Unicode codepoint of sel. */
  2070. /* defaultOff 3 ULONG offset to a default UVS table */
  2071. /* describing any variants to be found in */
  2072. /* the normal Unicode subtable. */
  2073. /* nonDefOff 7 ULONG offset to a non-default UVS table */
  2074. /* describing any variants not in the */
  2075. /* standard cmap, with GIDs here */
  2076. /* (either offset may be 0 NULL) */
  2077. /* */
  2078. /* Selectors are sorted by code point. */
  2079. /* */
  2080. /* A default Unicode Variation Selector (UVS) subtable is just a list of */
  2081. /* ranges of code points which are to be found in the standard cmap. No */
  2082. /* glyph IDs (GIDs) here. */
  2083. /* */
  2084. /* numRanges 0 ULONG number of ranges following */
  2085. /* */
  2086. /* A range looks like */
  2087. /* */
  2088. /* uniStart 0 UINT24 code point of the first character in */
  2089. /* this range */
  2090. /* additionalCnt 3 UBYTE count of additional characters in this */
  2091. /* range (zero means a range of a single */
  2092. /* character) */
  2093. /* */
  2094. /* Ranges are sorted by `uniStart'. */
  2095. /* */
  2096. /* A non-default Unicode Variation Selector (UVS) subtable is a list of */
  2097. /* mappings from codepoint to GID. */
  2098. /* */
  2099. /* numMappings 0 ULONG number of mappings */
  2100. /* */
  2101. /* A range looks like */
  2102. /* */
  2103. /* uniStart 0 UINT24 code point of the first character in */
  2104. /* this range */
  2105. /* GID 3 USHORT and its GID */
  2106. /* */
  2107. /* Ranges are sorted by `uniStart'. */
  2108. #ifdef TT_CONFIG_CMAP_FORMAT_14
  2109. typedef struct TT_CMap14Rec_
  2110. {
  2111. TT_CMapRec cmap;
  2112. FT_ULong num_selectors;
  2113. /* This array is used to store the results of various
  2114. * cmap 14 query functions. The data is overwritten
  2115. * on each call to these functions.
  2116. */
  2117. FT_UInt32 max_results;
  2118. FT_UInt32* results;
  2119. FT_Memory memory;
  2120. } TT_CMap14Rec, *TT_CMap14;
  2121. FT_CALLBACK_DEF( void )
  2122. tt_cmap14_done( TT_CMap14 cmap )
  2123. {
  2124. FT_Memory memory = cmap->memory;
  2125. cmap->max_results = 0;
  2126. if ( memory != NULL && cmap->results != NULL )
  2127. FT_FREE( cmap->results );
  2128. }
  2129. static FT_Error
  2130. tt_cmap14_ensure( TT_CMap14 cmap,
  2131. FT_UInt32 num_results,
  2132. FT_Memory memory )
  2133. {
  2134. FT_UInt32 old_max = cmap->max_results;
  2135. FT_Error error = SFNT_Err_Ok;
  2136. if ( num_results > cmap->max_results )
  2137. {
  2138. cmap->memory = memory;
  2139. if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) )
  2140. return error;
  2141. cmap->max_results = num_results;
  2142. }
  2143. return error;
  2144. }
  2145. FT_CALLBACK_DEF( FT_Error )
  2146. tt_cmap14_init( TT_CMap14 cmap,
  2147. FT_Byte* table )
  2148. {
  2149. cmap->cmap.data = table;
  2150. table += 6;
  2151. cmap->num_selectors = FT_PEEK_ULONG( table );
  2152. cmap->max_results = 0;
  2153. cmap->results = NULL;
  2154. return SFNT_Err_Ok;
  2155. }
  2156. FT_CALLBACK_DEF( FT_Error )
  2157. tt_cmap14_validate( FT_Byte* table,
  2158. FT_Validator valid )
  2159. {
  2160. FT_Byte* p = table + 2;
  2161. FT_ULong length = TT_NEXT_ULONG( p );
  2162. FT_ULong num_selectors = TT_NEXT_ULONG( p );
  2163. if ( length > (FT_ULong)( valid->limit - table ) ||
  2164. length < 10 + 11 * num_selectors )
  2165. FT_INVALID_TOO_SHORT;
  2166. /* check selectors, they must be in increasing order */
  2167. {
  2168. /* we start lastVarSel at 1 because a variant selector value of 0
  2169. * isn't valid.
  2170. */
  2171. FT_ULong n, lastVarSel = 1;
  2172. for ( n = 0; n < num_selectors; n++ )
  2173. {
  2174. FT_ULong varSel = TT_NEXT_UINT24( p );
  2175. FT_ULong defOff = TT_NEXT_ULONG( p );
  2176. FT_ULong nondefOff = TT_NEXT_ULONG( p );
  2177. if ( defOff >= length || nondefOff >= length )
  2178. FT_INVALID_TOO_SHORT;
  2179. if ( varSel < lastVarSel )
  2180. FT_INVALID_DATA;
  2181. lastVarSel = varSel + 1;
  2182. /* check the default table (these glyphs should be reached */
  2183. /* through the normal Unicode cmap, no GIDs, just check order) */
  2184. if ( defOff != 0 )
  2185. {
  2186. FT_Byte* defp = table + defOff;
  2187. FT_ULong numRanges = TT_NEXT_ULONG( defp );
  2188. FT_ULong i;
  2189. FT_ULong lastBase = 0;
  2190. if ( defp + numRanges * 4 > valid->limit )
  2191. FT_INVALID_TOO_SHORT;
  2192. for ( i = 0; i < numRanges; ++i )
  2193. {
  2194. FT_ULong base = TT_NEXT_UINT24( defp );
  2195. FT_ULong cnt = FT_NEXT_BYTE( defp );
  2196. if ( base + cnt >= 0x110000UL ) /* end of Unicode */
  2197. FT_INVALID_DATA;
  2198. if ( base < lastBase )
  2199. FT_INVALID_DATA;
  2200. lastBase = base + cnt + 1U;
  2201. }
  2202. }
  2203. /* and the non-default table (these glyphs are specified here) */
  2204. if ( nondefOff != 0 )
  2205. {
  2206. FT_Byte* ndp = table + nondefOff;
  2207. FT_ULong numMappings = TT_NEXT_ULONG( ndp );
  2208. FT_ULong i, lastUni = 0;
  2209. if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) )
  2210. FT_INVALID_TOO_SHORT;
  2211. for ( i = 0; i < numMappings; ++i )
  2212. {
  2213. FT_ULong uni = TT_NEXT_UINT24( ndp );
  2214. FT_ULong gid = TT_NEXT_USHORT( ndp );
  2215. if ( uni >= 0x110000UL ) /* end of Unicode */
  2216. FT_INVALID_DATA;
  2217. if ( uni < lastUni )
  2218. FT_INVALID_DATA;
  2219. lastUni = uni + 1U;
  2220. if ( valid->level >= FT_VALIDATE_TIGHT &&
  2221. gid >= TT_VALID_GLYPH_COUNT( valid ) )
  2222. FT_INVALID_GLYPH_ID;
  2223. }
  2224. }
  2225. }
  2226. }
  2227. return SFNT_Err_Ok;
  2228. }
  2229. FT_CALLBACK_DEF( FT_UInt )
  2230. tt_cmap14_char_index( TT_CMap cmap,
  2231. FT_UInt32 char_code )
  2232. {
  2233. FT_UNUSED( cmap );
  2234. FT_UNUSED( char_code );
  2235. /* This can't happen */
  2236. return 0;
  2237. }
  2238. FT_CALLBACK_DEF( FT_UInt32 )
  2239. tt_cmap14_char_next( TT_CMap cmap,
  2240. FT_UInt32 *pchar_code )
  2241. {
  2242. FT_UNUSED( cmap );
  2243. /* This can't happen */
  2244. *pchar_code = 0;
  2245. return 0;
  2246. }
  2247. FT_CALLBACK_DEF( FT_Error )
  2248. tt_cmap14_get_info( TT_CMap cmap,
  2249. TT_CMapInfo *cmap_info )
  2250. {
  2251. FT_UNUSED( cmap );
  2252. cmap_info->format = 14;
  2253. /* subtable 14 does not define a language field */
  2254. cmap_info->language = 0xFFFFFFFFUL;
  2255. return SFNT_Err_Ok;
  2256. }
  2257. static FT_UInt
  2258. tt_cmap14_char_map_def_binary( FT_Byte *base,
  2259. FT_UInt32 char_code )
  2260. {
  2261. FT_UInt32 numRanges = TT_PEEK_ULONG( base );
  2262. FT_UInt32 max, min;
  2263. min = 0;
  2264. max = numRanges;
  2265. base += 4;
  2266. /* binary search */
  2267. while ( min < max )
  2268. {
  2269. FT_UInt32 mid = ( min + max ) >> 1;
  2270. FT_Byte* p = base + 4 * mid;
  2271. FT_ULong start = TT_NEXT_UINT24( p );
  2272. FT_UInt cnt = FT_NEXT_BYTE( p );
  2273. if ( char_code < start )
  2274. max = mid;
  2275. else if ( char_code > start+cnt )
  2276. min = mid + 1;
  2277. else
  2278. return TRUE;
  2279. }
  2280. return FALSE;
  2281. }
  2282. static FT_UInt
  2283. tt_cmap14_char_map_nondef_binary( FT_Byte *base,
  2284. FT_UInt32 char_code )
  2285. {
  2286. FT_UInt32 numMappings = TT_PEEK_ULONG( base );
  2287. FT_UInt32 max, min;
  2288. min = 0;
  2289. max = numMappings;
  2290. base += 4;
  2291. /* binary search */
  2292. while ( min < max )
  2293. {
  2294. FT_UInt32 mid = ( min + max ) >> 1;
  2295. FT_Byte* p = base + 5 * mid;
  2296. FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
  2297. if ( char_code < uni )
  2298. max = mid;
  2299. else if ( char_code > uni )
  2300. min = mid + 1;
  2301. else
  2302. return TT_PEEK_USHORT( p );
  2303. }
  2304. return 0;
  2305. }
  2306. static FT_Byte*
  2307. tt_cmap14_find_variant( FT_Byte *base,
  2308. FT_UInt32 variantCode )
  2309. {
  2310. FT_UInt32 numVar = TT_PEEK_ULONG( base );
  2311. FT_UInt32 max, min;
  2312. min = 0;
  2313. max = numVar;
  2314. base += 4;
  2315. /* binary search */
  2316. while ( min < max )
  2317. {
  2318. FT_UInt32 mid = ( min + max ) >> 1;
  2319. FT_Byte* p = base + 11 * mid;
  2320. FT_ULong varSel = TT_NEXT_UINT24( p );
  2321. if ( variantCode < varSel )
  2322. max = mid;
  2323. else if ( variantCode > varSel )
  2324. min = mid + 1;
  2325. else
  2326. return p;
  2327. }
  2328. return NULL;
  2329. }
  2330. FT_CALLBACK_DEF( FT_UInt )
  2331. tt_cmap14_char_var_index( TT_CMap cmap,
  2332. TT_CMap ucmap,
  2333. FT_UInt32 charcode,
  2334. FT_UInt32 variantSelector)
  2335. {
  2336. FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
  2337. FT_ULong defOff;
  2338. FT_ULong nondefOff;
  2339. if ( !p )
  2340. return 0;
  2341. defOff = TT_NEXT_ULONG( p );
  2342. nondefOff = TT_PEEK_ULONG( p );
  2343. if ( defOff != 0 &&
  2344. tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
  2345. {
  2346. /* This is the default variant of this charcode. GID not stored */
  2347. /* here; stored in the normal Unicode charmap instead. */
  2348. return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode );
  2349. }
  2350. if ( nondefOff != 0 )
  2351. return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
  2352. charcode );
  2353. return 0;
  2354. }
  2355. FT_CALLBACK_DEF( FT_Int )
  2356. tt_cmap14_char_var_isdefault( TT_CMap cmap,
  2357. FT_UInt32 charcode,
  2358. FT_UInt32 variantSelector )
  2359. {
  2360. FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
  2361. FT_ULong defOff;
  2362. FT_ULong nondefOff;
  2363. if ( !p )
  2364. return -1;
  2365. defOff = TT_NEXT_ULONG( p );
  2366. nondefOff = TT_NEXT_ULONG( p );
  2367. if ( defOff != 0 &&
  2368. tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
  2369. return 1;
  2370. if ( nondefOff != 0 &&
  2371. tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
  2372. charcode ) != 0 )
  2373. return 0;
  2374. return -1;
  2375. }
  2376. FT_CALLBACK_DEF( FT_UInt32* )
  2377. tt_cmap14_variants( TT_CMap cmap,
  2378. FT_Memory memory )
  2379. {
  2380. TT_CMap14 cmap14 = (TT_CMap14)cmap;
  2381. FT_UInt32 count = cmap14->num_selectors;
  2382. FT_Byte* p = cmap->data + 10;
  2383. FT_UInt32* result;
  2384. FT_UInt32 i;
  2385. if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
  2386. return NULL;
  2387. result = cmap14->results;
  2388. for ( i = 0; i < count; ++i )
  2389. {
  2390. result[i] = (FT_UInt32)TT_NEXT_UINT24( p );
  2391. p += 8;
  2392. }
  2393. result[i] = 0;
  2394. return result;
  2395. }
  2396. FT_CALLBACK_DEF( FT_UInt32 * )
  2397. tt_cmap14_char_variants( TT_CMap cmap,
  2398. FT_Memory memory,
  2399. FT_UInt32 charCode )
  2400. {
  2401. TT_CMap14 cmap14 = (TT_CMap14) cmap;
  2402. FT_UInt32 count = cmap14->num_selectors;
  2403. FT_Byte* p = cmap->data + 10;
  2404. FT_UInt32* q;
  2405. if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
  2406. return NULL;
  2407. for ( q = cmap14->results; count > 0; --count )
  2408. {
  2409. FT_UInt32 varSel = TT_NEXT_UINT24( p );
  2410. FT_ULong defOff = TT_NEXT_ULONG( p );
  2411. FT_ULong nondefOff = TT_NEXT_ULONG( p );
  2412. if ( ( defOff != 0 &&
  2413. tt_cmap14_char_map_def_binary( cmap->data + defOff,
  2414. charCode ) ) ||
  2415. ( nondefOff != 0 &&
  2416. tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
  2417. charCode ) != 0 ) )
  2418. {
  2419. q[0] = varSel;
  2420. q++;
  2421. }
  2422. }
  2423. q[0] = 0;
  2424. return cmap14->results;
  2425. }
  2426. static FT_UInt
  2427. tt_cmap14_def_char_count( FT_Byte *p )
  2428. {
  2429. FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
  2430. FT_UInt tot = 0;
  2431. p += 3; /* point to the first `cnt' field */
  2432. for ( ; numRanges > 0; numRanges-- )
  2433. {
  2434. tot += 1 + p[0];
  2435. p += 4;
  2436. }
  2437. return tot;
  2438. }
  2439. static FT_UInt32*
  2440. tt_cmap14_get_def_chars( TT_CMap cmap,
  2441. FT_Byte* p,
  2442. FT_Memory memory )
  2443. {
  2444. TT_CMap14 cmap14 = (TT_CMap14) cmap;
  2445. FT_UInt32 numRanges;
  2446. FT_UInt cnt;
  2447. FT_UInt32* q;
  2448. cnt = tt_cmap14_def_char_count( p );
  2449. numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
  2450. if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) )
  2451. return NULL;
  2452. for ( q = cmap14->results; numRanges > 0; --numRanges )
  2453. {
  2454. FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
  2455. cnt = FT_NEXT_BYTE( p ) + 1;
  2456. do
  2457. {
  2458. q[0] = uni;
  2459. uni += 1;
  2460. q += 1;
  2461. } while ( --cnt != 0 );
  2462. }
  2463. q[0] = 0;
  2464. return cmap14->results;
  2465. }
  2466. static FT_UInt32*
  2467. tt_cmap14_get_nondef_chars( TT_CMap cmap,
  2468. FT_Byte *p,
  2469. FT_Memory memory )
  2470. {
  2471. TT_CMap14 cmap14 = (TT_CMap14) cmap;
  2472. FT_UInt32 numMappings;
  2473. FT_UInt i;
  2474. FT_UInt32 *ret;
  2475. numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
  2476. if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) )
  2477. return NULL;
  2478. ret = cmap14->results;
  2479. for ( i = 0; i < numMappings; ++i )
  2480. {
  2481. ret[i] = (FT_UInt32)TT_NEXT_UINT24( p );
  2482. p += 2;
  2483. }
  2484. ret[i] = 0;
  2485. return ret;
  2486. }
  2487. FT_CALLBACK_DEF( FT_UInt32 * )
  2488. tt_cmap14_variant_chars( TT_CMap cmap,
  2489. FT_Memory memory,
  2490. FT_UInt32 variantSelector )
  2491. {
  2492. FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6,
  2493. variantSelector );
  2494. FT_UInt32 *ret;
  2495. FT_Int i;
  2496. FT_ULong defOff;
  2497. FT_ULong nondefOff;
  2498. if ( !p )
  2499. return NULL;
  2500. defOff = TT_NEXT_ULONG( p );
  2501. nondefOff = TT_NEXT_ULONG( p );
  2502. if ( defOff == 0 && nondefOff == 0 )
  2503. return NULL;
  2504. if ( defOff == 0 )
  2505. return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
  2506. memory );
  2507. else if ( nondefOff == 0 )
  2508. return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
  2509. memory );
  2510. else
  2511. {
  2512. /* Both a default and a non-default glyph set? That's probably not */
  2513. /* good font design, but the spec allows for it... */
  2514. TT_CMap14 cmap14 = (TT_CMap14) cmap;
  2515. FT_UInt32 numRanges;
  2516. FT_UInt32 numMappings;
  2517. FT_UInt32 duni;
  2518. FT_UInt32 dcnt;
  2519. FT_UInt32 nuni;
  2520. FT_Byte* dp;
  2521. FT_UInt di, ni, k;
  2522. p = cmap->data + nondefOff;
  2523. dp = cmap->data + defOff;
  2524. numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
  2525. dcnt = tt_cmap14_def_char_count( dp );
  2526. numRanges = (FT_UInt32)TT_NEXT_ULONG( dp );
  2527. if ( numMappings == 0 )
  2528. return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
  2529. memory );
  2530. if ( dcnt == 0 )
  2531. return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
  2532. memory );
  2533. if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) )
  2534. return NULL;
  2535. ret = cmap14->results;
  2536. duni = (FT_UInt32)TT_NEXT_UINT24( dp );
  2537. dcnt = FT_NEXT_BYTE( dp );
  2538. di = 1;
  2539. nuni = (FT_UInt32)TT_NEXT_UINT24( p );
  2540. p += 2;
  2541. ni = 1;
  2542. i = 0;
  2543. for ( ;; )
  2544. {
  2545. if ( nuni > duni + dcnt )
  2546. {
  2547. for ( k = 0; k <= dcnt; ++k )
  2548. ret[i++] = duni + k;
  2549. ++di;
  2550. if ( di > numRanges )
  2551. break;
  2552. duni = (FT_UInt32)TT_NEXT_UINT24( dp );
  2553. dcnt = FT_NEXT_BYTE( dp );
  2554. }
  2555. else
  2556. {
  2557. if ( nuni < duni )
  2558. ret[i++] = nuni;
  2559. /* If it is within the default range then ignore it -- */
  2560. /* that should not have happened */
  2561. ++ni;
  2562. if ( ni > numMappings )
  2563. break;
  2564. nuni = (FT_UInt32)TT_NEXT_UINT24( p );
  2565. p += 2;
  2566. }
  2567. }
  2568. if ( ni <= numMappings )
  2569. {
  2570. /* If we get here then we have run out of all default ranges. */
  2571. /* We have read one non-default mapping which we haven't stored */
  2572. /* and there may be others that need to be read. */
  2573. ret[i++] = nuni;
  2574. while ( ni < numMappings )
  2575. {
  2576. ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p );
  2577. p += 2;
  2578. ++ni;
  2579. }
  2580. }
  2581. else if ( di <= numRanges )
  2582. {
  2583. /* If we get here then we have run out of all non-default */
  2584. /* mappings. We have read one default range which we haven't */
  2585. /* stored and there may be others that need to be read. */
  2586. for ( k = 0; k <= dcnt; ++k )
  2587. ret[i++] = duni + k;
  2588. while ( di < numRanges )
  2589. {
  2590. duni = (FT_UInt32)TT_NEXT_UINT24( dp );
  2591. dcnt = FT_NEXT_BYTE( dp );
  2592. for ( k = 0; k <= dcnt; ++k )
  2593. ret[i++] = duni + k;
  2594. ++di;
  2595. }
  2596. }
  2597. ret[i] = 0;
  2598. return ret;
  2599. }
  2600. }
  2601. FT_DEFINE_TT_CMAP(tt_cmap14_class_rec,
  2602. sizeof ( TT_CMap14Rec ),
  2603. (FT_CMap_InitFunc) tt_cmap14_init,
  2604. (FT_CMap_DoneFunc) tt_cmap14_done,
  2605. (FT_CMap_CharIndexFunc)tt_cmap14_char_index,
  2606. (FT_CMap_CharNextFunc) tt_cmap14_char_next,
  2607. /* Format 14 extension functions */
  2608. (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index,
  2609. (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
  2610. (FT_CMap_VariantListFunc) tt_cmap14_variants,
  2611. (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
  2612. (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars
  2613. ,
  2614. 14,
  2615. (TT_CMap_ValidateFunc)tt_cmap14_validate,
  2616. (TT_CMap_Info_GetFunc)tt_cmap14_get_info
  2617. )
  2618. #endif /* TT_CONFIG_CMAP_FORMAT_14 */
  2619. #ifndef FT_CONFIG_OPTION_PIC
  2620. static const TT_CMap_Class tt_cmap_classes[] =
  2621. {
  2622. #define TTCMAPCITEM(a) &a,
  2623. #include "ttcmapc.h"
  2624. NULL,
  2625. };
  2626. #else /*FT_CONFIG_OPTION_PIC*/
  2627. void FT_Destroy_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class* clazz)
  2628. {
  2629. FT_Memory memory = library->memory;
  2630. if ( clazz )
  2631. FT_FREE( clazz );
  2632. }
  2633. FT_Error FT_Create_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class** output_class)
  2634. {
  2635. TT_CMap_Class* clazz;
  2636. TT_CMap_ClassRec* recs;
  2637. FT_Error error;
  2638. FT_Memory memory = library->memory;
  2639. int i = 0;
  2640. #define TTCMAPCITEM(a) i++;
  2641. #include "ttcmapc.h"
  2642. /* allocate enough space for both the pointers +terminator and the class instances */
  2643. if ( FT_ALLOC( clazz, sizeof(*clazz)*(i+1)+sizeof(TT_CMap_ClassRec)*i ) )
  2644. return error;
  2645. /* the location of the class instances follows the array of pointers */
  2646. recs = (TT_CMap_ClassRec*) (((char*)clazz)+(sizeof(*clazz)*(i+1)));
  2647. i=0;
  2648. #undef TTCMAPCITEM
  2649. #define TTCMAPCITEM(a) \
  2650. FT_Init_Class_##a(&recs[i]); \
  2651. clazz[i] = &recs[i]; \
  2652. i++;
  2653. #include "ttcmapc.h"
  2654. clazz[i] = NULL;
  2655. *output_class = clazz;
  2656. return SFNT_Err_Ok;
  2657. }
  2658. #endif /*FT_CONFIG_OPTION_PIC*/
  2659. /* parse the `cmap' table and build the corresponding TT_CMap objects */
  2660. /* in the current face */
  2661. /* */
  2662. FT_LOCAL_DEF( FT_Error )
  2663. tt_face_build_cmaps( TT_Face face )
  2664. {
  2665. FT_Byte* table = face->cmap_table;
  2666. FT_Byte* limit = table + face->cmap_size;
  2667. FT_UInt volatile num_cmaps;
  2668. FT_Byte* volatile p = table;
  2669. FT_Library library = FT_FACE_LIBRARY( face );
  2670. FT_UNUSED( library );
  2671. if ( !p || p + 4 > limit )
  2672. return SFNT_Err_Invalid_Table;
  2673. /* only recognize format 0 */
  2674. if ( TT_NEXT_USHORT( p ) != 0 )
  2675. {
  2676. p -= 2;
  2677. FT_ERROR(( "tt_face_build_cmaps:"
  2678. " unsupported `cmap' table format = %d\n",
  2679. TT_PEEK_USHORT( p ) ));
  2680. return SFNT_Err_Invalid_Table;
  2681. }
  2682. num_cmaps = TT_NEXT_USHORT( p );
  2683. #ifdef FT_MAX_CHARMAP_CACHEABLE
  2684. if ( num_cmaps > FT_MAX_CHARMAP_CACHEABLE )
  2685. FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables(%d) "
  2686. "subtable#%d and later are loaded but cannot be searched\n",
  2687. num_cmaps, FT_MAX_CHARMAP_CACHEABLE + 1 ));
  2688. #endif
  2689. for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- )
  2690. {
  2691. FT_CharMapRec charmap;
  2692. FT_UInt32 offset;
  2693. charmap.platform_id = TT_NEXT_USHORT( p );
  2694. charmap.encoding_id = TT_NEXT_USHORT( p );
  2695. charmap.face = FT_FACE( face );
  2696. charmap.encoding = FT_ENCODING_NONE; /* will be filled later */
  2697. offset = TT_NEXT_ULONG( p );
  2698. if ( offset && offset <= face->cmap_size - 2 )
  2699. {
  2700. FT_Byte* volatile cmap = table + offset;
  2701. volatile FT_UInt format = TT_PEEK_USHORT( cmap );
  2702. const TT_CMap_Class* volatile pclazz = FT_TT_CMAP_CLASSES_GET;
  2703. TT_CMap_Class volatile clazz;
  2704. for ( ; *pclazz; pclazz++ )
  2705. {
  2706. clazz = *pclazz;
  2707. if ( clazz->format == format )
  2708. {
  2709. volatile TT_ValidatorRec valid;
  2710. volatile FT_Error error = SFNT_Err_Ok;
  2711. ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit,
  2712. FT_VALIDATE_DEFAULT );
  2713. valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs;
  2714. if ( ft_setjmp(
  2715. *((ft_jmp_buf*)&FT_VALIDATOR( &valid )->jump_buffer) ) == 0 )
  2716. {
  2717. /* validate this cmap sub-table */
  2718. error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
  2719. }
  2720. if ( valid.validator.error == 0 )
  2721. {
  2722. FT_CMap ttcmap;
  2723. /* It might make sense to store the single variation selector */
  2724. /* cmap somewhere special. But it would have to be in the */
  2725. /* public FT_FaceRec, and we can't change that. */
  2726. if ( !FT_CMap_New( (FT_CMap_Class)clazz,
  2727. cmap, &charmap, &ttcmap ) )
  2728. {
  2729. /* it is simpler to directly set `flags' than adding */
  2730. /* a parameter to FT_CMap_New */
  2731. ((TT_CMap)ttcmap)->flags = (FT_Int)error;
  2732. }
  2733. }
  2734. else
  2735. {
  2736. FT_TRACE0(( "tt_face_build_cmaps:"
  2737. " broken cmap sub-table ignored\n" ));
  2738. }
  2739. break;
  2740. }
  2741. }
  2742. if ( *pclazz == NULL )
  2743. {
  2744. FT_TRACE0(( "tt_face_build_cmaps:"
  2745. " unsupported cmap sub-table ignored\n" ));
  2746. }
  2747. }
  2748. }
  2749. return SFNT_Err_Ok;
  2750. }
  2751. FT_LOCAL( FT_Error )
  2752. tt_get_cmap_info( FT_CharMap charmap,
  2753. TT_CMapInfo *cmap_info )
  2754. {
  2755. FT_CMap cmap = (FT_CMap)charmap;
  2756. TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz;
  2757. return clazz->get_cmap_info( charmap, cmap_info );
  2758. }
  2759. /* END */