PageRenderTime 53ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/compiler/android-ndk/jni/freetype/src/sfnt/ttcmap.c

http://ftk.googlecode.com/
C | 1984 lines | 1185 code | 394 blank | 405 comment | 246 complexity | 7c7214514b591e716568a24ee856cd4d MD5 | raw file
Possible License(s): LGPL-3.0
  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 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 c