otlgsub.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. #include "otlgsub.h"
  2. #include "otlcommn.h"
  3. /************************************************************************/
  4. /************************************************************************/
  5. /***** *****/
  6. /***** GSUB LOOKUP TYPE 1 *****/
  7. /***** *****/
  8. /************************************************************************/
  9. /************************************************************************/
  10. /*
  11. * 1: Single Substitution - Table format(s)
  12. *
  13. * This table is used to substiture individual glyph indices
  14. * with another one. There are only two sub-formats:
  15. *
  16. * Name Offset Size Description
  17. * ------------------------------------------
  18. * format 0 2 sub-table format (1)
  19. * offset 2 2 offset to coverage table
  20. * delta 4 2 16-bit delta to apply on all
  21. * covered glyph indices
  22. *
  23. * Name Offset Size Description
  24. * ------------------------------------------
  25. * format 0 2 sub-table format (2)
  26. * offset 2 2 offset to coverage table
  27. * count 4 2 coverage table count
  28. * substs[] 6 2*count substituted glyph indices,
  29. *
  30. */
  31. static void
  32. otl_gsub_lookup1_validate( OTL_Bytes table,
  33. OTL_Validator valid )
  34. {
  35. OTL_Bytes p = table;
  36. OTL_UInt format;
  37. OTL_CHECK( 2 );
  38. format = OTL_NEXT_USHORT( p );
  39. switch ( format )
  40. {
  41. case 1:
  42. {
  43. OTL_UInt coverage;
  44. OTL_CHECK( 4 );
  45. coverage = OTL_NEXT_USHORT( p );
  46. otl_coverage_validate( table + coverage, valid );
  47. }
  48. break;
  49. case 2:
  50. {
  51. OTL_UInt coverage, count;
  52. OTL_CHECK( 4 );
  53. coverage = OTL_NEXT_USHORT( p );
  54. count = OTL_NEXT_USHORT( p );
  55. otl_coverage_validate( table + coverage, valid );
  56. OTL_CHECK( 2*count );
  57. /* NB: we don't check that there are at most 'count' */
  58. /* elements in the coverage table. This is delayed */
  59. /* to the lookup function... */
  60. }
  61. break;
  62. default:
  63. OTL_INVALID_DATA;
  64. }
  65. }
  66. static OTL_Bool
  67. otl_gsub_lookup1_apply( OTL_Bytes table,
  68. OTL_Parser parser )
  69. {
  70. OTL_Bytes p = table;
  71. OTL_Bytes coverage;
  72. OTL_UInt format, gindex, property;
  73. OTL_Int index;
  74. OTL_Bool subst = 0;
  75. if ( parser->context_len != 0xFFFF && parser->context_len < 1 )
  76. goto Exit;
  77. gindex = otl_parser_get_gindex( parser );
  78. if ( !otl_parser_check_property( parser, gindex, &property ) )
  79. goto Exit;
  80. format = OTL_NEXT_USHORT(p);
  81. coverage = table + OTL_NEXT_USHORT(p);
  82. index = otl_coverage_lookup( coverage, gindex );
  83. if ( index >= 0 )
  84. {
  85. switch ( format )
  86. {
  87. case 1:
  88. {
  89. OTL_Int delta = OTL_NEXT_SHORT(p);
  90. gindex = ( gindex + delta ) & 0xFFFF;
  91. otl_parser_replace_1( parser, gindex );
  92. subst = 1;
  93. }
  94. break;
  95. case 2:
  96. {
  97. OTL_UInt count = OTL_NEXT_USHORT(p);
  98. if ( (OTL_UInt) index < count )
  99. {
  100. p += index*2;
  101. otl_parser_replace_1( parser, OTL_PEEK_USHORT(p) );
  102. subst = 1;
  103. }
  104. }
  105. break;
  106. default:
  107. ;
  108. }
  109. }
  110. Exit:
  111. return subst;
  112. }
  113. /************************************************************************/
  114. /************************************************************************/
  115. /***** *****/
  116. /***** GSUB LOOKUP TYPE 2 *****/
  117. /***** *****/
  118. /************************************************************************/
  119. /************************************************************************/
  120. /*
  121. * 2: Multiple Substitution - Table format(s)
  122. *
  123. * Replaces a single glyph with one or more glyphs.
  124. *
  125. * Name Offset Size Description
  126. * -----------------------------------------------------------
  127. * format 0 2 sub-table format (1)
  128. * offset 2 2 offset to coverage table
  129. * count 4 2 coverage table count
  130. * sequencess[] 6 2*count offsets to sequence items
  131. *
  132. * each sequence item has the following format:
  133. *
  134. * Name Offset Size Description
  135. * -----------------------------------------------------------
  136. * count 0 2 number of replacement glyphs
  137. * gindices[] 2 2*count string of glyph indices
  138. */
  139. static void
  140. otl_seq_validate( OTL_Bytes table,
  141. OTL_Validator valid )
  142. {
  143. OTL_Bytes p = table;
  144. OTL_UInt count;
  145. OTL_CHECK( 2 );
  146. count = OTL_NEXT_USHORT( p );
  147. /* XXX: according to the spec, 'count' should be > 0 */
  148. /* we can deal with these cases pretty well however */
  149. OTL_CHECK( 2*count );
  150. /* check glyph indices */
  151. }
  152. static void
  153. otl_gsub_lookup2_validate( OTL_Bytes table,
  154. OTL_Validator valid )
  155. {
  156. OTL_Bytes p = table;
  157. OTL_UInt format, coverage;
  158. OTL_CHECK( 2 );
  159. format = OTL_NEXT_USHORT( p );
  160. switch ( format )
  161. {
  162. case 1:
  163. {
  164. OTL_UInt coverage, seq_count;
  165. OTL_CHECK( 4 );
  166. coverage = OTL_NEXT_USHORT( p );
  167. seq_count = OTL_NEXT_USHORT( p );
  168. otl_coverage_validate( table + coverage, valid );
  169. OTL_CHECK( seq_count*2 );
  170. for ( ; seq_count > 0; seq_count-- )
  171. otl_seq_validate( table + OTL_NEXT_USHORT( p ), valid );
  172. }
  173. break;
  174. default:
  175. OTL_INVALID_DATA;
  176. }
  177. }
  178. static OTL_Bool
  179. otl_gsub_lookup2_apply( OTL_Bytes table,
  180. OTL_Parser parser )
  181. {
  182. OTL_Bytes p = table;
  183. OTL_Bytes coverage, sequence;
  184. OTL_UInt format, gindex, index, property;
  185. OTL_Int index;
  186. OTL_Bool subst = 0;
  187. if ( context_len != 0xFFFF && context_len < 1 )
  188. goto Exit;
  189. gindex = otl_parser_get_gindex( parser );
  190. if ( !otl_parser_check_property( parser, gindex, &property ) )
  191. goto Exit;
  192. p += 2; /* skip format */
  193. coverage = table + OTL_NEXT_USHORT(p);
  194. seq_count = OTL_NEXT_USHORT(p);
  195. index = otl_coverage_lookup( coverage, gindex );
  196. if ( (OTL_UInt) index >= seq_count )
  197. goto Exit;
  198. p += index*2;
  199. sequence = table + OTL_PEEK_USHORT(p);
  200. p = sequence;
  201. count = OTL_NEXT_USHORT(p);
  202. otl_parser_replace_n( parser, count, p );
  203. subst = 1;
  204. Exit:
  205. return subst;
  206. }
  207. /************************************************************************/
  208. /************************************************************************/
  209. /***** *****/
  210. /***** GSUB LOOKUP TYPE 3 *****/
  211. /***** *****/
  212. /************************************************************************/
  213. /************************************************************************/
  214. /*
  215. * 3: Alternate Substitution - Table format(s)
  216. *
  217. * Replaces a single glyph by another one taken liberally
  218. * in a list of alternatives
  219. *
  220. * Name Offset Size Description
  221. * -----------------------------------------------------------
  222. * format 0 2 sub-table format (1)
  223. * offset 2 2 offset to coverage table
  224. * count 4 2 coverage table count
  225. * alternates[] 6 2*count offsets to alternate items
  226. *
  227. * each alternate item has the following format:
  228. *
  229. * Name Offset Size Description
  230. * -----------------------------------------------------------
  231. * count 0 2 number of replacement glyphs
  232. * gindices[] 2 2*count string of glyph indices, each one
  233. * is a valid alternative
  234. */
  235. static void
  236. otl_alternate_set_validate( OTL_Bytes table,
  237. OTL_Validator valid )
  238. {
  239. OTL_Bytes p = table;
  240. OTL_UInt count;
  241. OTL_CHECK( 2 );
  242. count = OTL_NEXT_USHORT( p );
  243. OTL_CHECK( 2*count );
  244. /* XXX: check glyph indices */
  245. }
  246. static void
  247. otl_gsub_lookup3_validate( OTL_Bytes table,
  248. OTL_Validator valid )
  249. {
  250. OTL_Bytes p = table;
  251. OTL_UInt format, coverage;
  252. OTL_CHECK( 2 );
  253. format = OTL_NEXT_USHORT( p );
  254. switch ( format )
  255. {
  256. case 1:
  257. {
  258. OTL_UInt coverage, count;
  259. OTL_CHECK( 4 );
  260. coverage = OTL_NEXT_USHORT( p );
  261. count = OTL_NEXT_USHORT( p );
  262. otl_coverage_validate( table + coverage, valid );
  263. OTL_CHECK( 2*count );
  264. for ( ; count > 0; count-- )
  265. otl_alternate_set_validate( table + OTL_NEXT_USHORT( p ), valid );
  266. }
  267. break;
  268. default:
  269. OTL_INVALID_DATA;
  270. }
  271. }
  272. static OTL_Bool
  273. otl_gsub_lookup3_apply( OTL_Bytes table,
  274. OTL_Parser parser )
  275. {
  276. OTL_Bytes p = table;
  277. OTL_Bytes coverage, alternates;
  278. OTL_UInt format, gindex, index, property;
  279. OTL_Int index;
  280. OTL_Bool subst = 0;
  281. OTL_GSUB_Alternate alternate = parser->alternate;
  282. if ( context_len != 0xFFFF && context_len < 1 )
  283. goto Exit;
  284. if ( alternate == NULL )
  285. goto Exit;
  286. gindex = otl_parser_get_gindex( parser );
  287. if ( !otl_parser_check_property( parser, gindex, &property ) )
  288. goto Exit;
  289. p += 2; /* skip format */
  290. coverage = table + OTL_NEXT_USHORT(p);
  291. seq_count = OTL_NEXT_USHORT(p);
  292. index = otl_coverage_lookup( coverage, gindex );
  293. if ( (OTL_UInt) index >= seq_count )
  294. goto Exit;
  295. p += index*2;
  296. alternates = table + OTL_PEEK_USHORT(p);
  297. p = alternates;
  298. count = OTL_NEXT_USHORT(p);
  299. gindex = alternate->handler_func(
  300. gindex, count, p, alternate->handler_data );
  301. otl_parser_replace_1( parser, gindex );
  302. subst = 1;
  303. Exit:
  304. return subst;
  305. }
  306. /************************************************************************/
  307. /************************************************************************/
  308. /***** *****/
  309. /***** GSUB LOOKUP TYPE 4 *****/
  310. /***** *****/
  311. /************************************************************************/
  312. /************************************************************************/
  313. static void
  314. otl_ligature_validate( OTL_Bytes table,
  315. OTL_Validator valid )
  316. {
  317. OTL_UInt glyph_id, count;
  318. OTL_CHECK( 4 );
  319. glyph_id = OTL_NEXT_USHORT( p );
  320. count = OTL_NEXT_USHORT( p );
  321. if ( count == 0 )
  322. OTL_INVALID_DATA;
  323. OTL_CHECK( 2*(count-1) );
  324. /* XXX: check glyph indices */
  325. }
  326. static void
  327. otl_ligature_set_validate( OTL_Bytes table,
  328. OTL_Validator valid )
  329. {
  330. OTL_Bytes p = table;
  331. OTL_UInt count;
  332. OTL_CHECK( 2 );
  333. count = OTL_NEXT_USHORT( p );
  334. OTL_CHECK( 2*count );
  335. for ( ; count > 0; count-- )
  336. otl_ligature_validate( table + OTL_NEXT_USHORT( p ), valid );
  337. }
  338. static void
  339. otl_gsub_lookup4_validate( OTL_Bytes table,
  340. OTL_Validator valid )
  341. {
  342. OTL_Bytes p = table;
  343. OTL_UInt format, coverage;
  344. OTL_CHECK( 2 );
  345. format = OTL_NEXT_USHORT( p );
  346. switch ( format )
  347. {
  348. case 1:
  349. {
  350. OTL_UInt coverage, count;
  351. OTL_CHECK( 4 );
  352. coverage = OTL_NEXT_USHORT( p );
  353. count = OTL_NEXT_USHORT( p );
  354. otl_coverage_validate( table + coverage, valid );
  355. OTL_CHECK( 2*count );
  356. for ( ; count > 0; count-- )
  357. otl_ligature_set_validate( table + OTL_NEXT_USHORT( p ), valid );
  358. }
  359. break;
  360. default:
  361. OTL_INVALID_DATA;
  362. }
  363. }
  364. /************************************************************************/
  365. /************************************************************************/
  366. /***** *****/
  367. /***** GSUB LOOKUP TYPE 5 *****/
  368. /***** *****/
  369. /************************************************************************/
  370. /************************************************************************/
  371. static void
  372. otl_sub_rule_validate( OTL_Bytes table,
  373. OTL_Validator valid )
  374. {
  375. OTL_Bytes p = table;
  376. OTL_UInt glyph_count, subst_count;
  377. OTL_CHECK( 4 );
  378. glyph_count = OTL_NEXT_USHORT( p );
  379. subst_count = OTL_NEXT_USHORT( p );
  380. if ( glyph_count == 0 )
  381. OTL_INVALID_DATA;
  382. OTL_CHECK( (glyph_count-1)*2 + substcount*4 );
  383. /* XXX: check glyph indices and subst lookups */
  384. }
  385. static void
  386. otl_sub_rule_set_validate( OTL_Bytes table,
  387. OTL_Validator valid )
  388. {
  389. OTL_Bytes p = table;
  390. OTL_UInt count;
  391. OTL_CHECK( 2 );
  392. count = OTL_NEXT_USHORT( p );
  393. OTL_CHECK( 2*count );
  394. for ( ; count > 0; count-- )
  395. otl_sub_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
  396. }
  397. static void
  398. otl_sub_class_rule_validate( OTL_Bytes table,
  399. OTL_Validator valid )
  400. {
  401. OTL_UInt glyph_count, subst_count;
  402. OTL_CHECK( 4 );
  403. glyph_count = OTL_NEXT_USHORT( p );
  404. subst_count = OTL_NEXT_USHORT( p );
  405. if ( glyph_count == 0 )
  406. OTL_INVALID_DATA;
  407. OTL_CHECK( (glyph_count-1)*2 + substcount*4 );
  408. /* XXX: check glyph indices and subst lookups */
  409. }
  410. static void
  411. otl_sub_class_rule_set_validate( OTL_Bytes table,
  412. OTL_Validator valid )
  413. {
  414. OTL_Bytes p = table;
  415. OTL_UInt count;
  416. OTL_CHECK( 2 );
  417. count = OTL_NEXT_USHORT( p );
  418. OTL_CHECK( 2*count );
  419. for ( ; count > 0; count-- )
  420. otl_sub_class_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
  421. }
  422. static void
  423. otl_gsub_lookup5_validate( OTL_Bytes table,
  424. OTL_Validator valid )
  425. {
  426. OTL_Bytes p = table;
  427. OTL_UInt format, coverage;
  428. OTL_CHECK( 2 );
  429. format = OTL_NEXT_USHORT( p );
  430. switch ( format )
  431. {
  432. case 1:
  433. {
  434. OTL_UInt coverage, count;
  435. OTL_CHECK( 4 );
  436. coverage = OTL_NEXT_USHORT( p );
  437. count = OTL_NEXT_USHORT( p );
  438. otl_coverage_validate( table + coverage, valid );
  439. OTL_CHECK( 2*count );
  440. for ( ; count > 0; count-- )
  441. otl_sub_rule_set_validate( table + coverage, valid );
  442. }
  443. break;
  444. case 2:
  445. {
  446. OTL_UInt coverage, class_def, count;
  447. OTL_CHECK( 6 );
  448. coverage = OTL_NEXT_USHORT( p );
  449. class_def = OTL_NEXT_USHORT( p );
  450. count = OTL_NEXT_USHORT( p );
  451. otl_coverage_validate ( table + coverage, valid );
  452. otl_class_definition_validate( table + class_def, valid );
  453. OTL_CHECK( 2*count );
  454. for ( ; count > 0; count-- )
  455. otl_sub_class_rule_set_validate( table + coveragen valid );
  456. }
  457. break;
  458. case 3:
  459. {
  460. OTL_UInt glyph_count, subst_count, count;
  461. OTL_CHECK( 4 );
  462. glyph_count = OTL_NEXT_USHORT( p );
  463. subst_count = OTL_NEXT_USHORT( p );
  464. OTL_CHECK( 2*glyph_count + 4*subst_count );
  465. for ( count = glyph_count; count > 0; count-- )
  466. otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
  467. }
  468. break;
  469. default:
  470. OTL_INVALID_DATA;
  471. }
  472. }
  473. /************************************************************************/
  474. /************************************************************************/
  475. /***** *****/
  476. /***** GSUB LOOKUP TYPE 6 *****/
  477. /***** *****/
  478. /************************************************************************/
  479. /************************************************************************/
  480. static void
  481. otl_chain_sub_rule_validate( OTL_Bytes table,
  482. OTL_Validator valid )
  483. {
  484. OTL_Bytes p = table;
  485. OTL_UInt back_count, input_count, ahead_count, subst_count, count;
  486. OTL_CHECK( 2 );
  487. back_count = OTL_NEXT_USHORT( p );
  488. OTL_CHECK( 2*back_count+2 );
  489. p += 2*back_count;
  490. input_count = OTL_NEXT_USHORT( p );
  491. if ( input_count == 0 )
  492. OTL_INVALID_DATA;
  493. OTL_CHECK( 2*input_count );
  494. p += 2*(input_count-1);
  495. ahead_count = OTL_NEXT_USHORT( p );
  496. OTL_CHECK( 2*ahead_count + 2 );
  497. p += 2*ahead_count;
  498. count = OTL_NEXT_USHORT( p );
  499. OTL_CHECK( 4*count );
  500. /* XXX: check glyph indices and subst lookups */
  501. }
  502. static void
  503. otl_chain_sub_rule_set_validate( OTL_Bytes table,
  504. OTL_Validator valid )
  505. {
  506. OTL_Bytes p = table;
  507. OTL_UInt count;
  508. OTL_CHECK( 2 );
  509. count = OTL_NEXT_USHORT( p );
  510. OTL_CHECK( 2*count );
  511. for ( ; count > 0; count-- )
  512. otl_chain_sub_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
  513. }
  514. static void
  515. otl_chain_sub_class_rule_validate( OTL_Bytes table,
  516. OTL_Validator valid )
  517. {
  518. OTL_Bytes p = table;
  519. OTL_UInt back_count, input_count, ahead_count, subst_count, count;
  520. OTL_CHECK( 2 );
  521. back_count = OTL_NEXT_USHORT( p );
  522. OTL_CHECK( 2*back_count+2 );
  523. p += 2*back_count;
  524. input_count = OTL_NEXT_USHORT( p );
  525. if ( input_count == 0 )
  526. OTL_INVALID_DATA;
  527. OTL_CHECK( 2*input_count );
  528. p += 2*(input_count-1);
  529. ahead_count = OTL_NEXT_USHORT( p );
  530. OTL_CHECK( 2*ahead_count + 2 );
  531. p += 2*ahead_count;
  532. count = OTL_NEXT_USHORT( p );
  533. OTL_CHECK( 4*count );
  534. /* XXX: check class indices and subst lookups */
  535. }
  536. static void
  537. otl_chain_sub_class_set_validate( OTL_Bytes table,
  538. OTL_Validator valid )
  539. {
  540. OTL_Bytes p = table;
  541. OTL_UInt count;
  542. OTL_CHECK( 2 );
  543. count = OTL_NEXT_USHORT( p );
  544. OTL_CHECK( 2*count );
  545. for ( ; count > 0; count-- )
  546. otl_chain_sub_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
  547. }
  548. static void
  549. otl_gsub_lookup6_validate( OTL_Bytes table,
  550. OTL_Validator valid )
  551. {
  552. OTL_Bytes p = table;
  553. OTL_UInt format, coverage;
  554. OTL_CHECK( 2 );
  555. format = OTL_NEXT_USHORT( p );
  556. switch ( format )
  557. {
  558. case 1:
  559. {
  560. OTL_UInt coverage, count;
  561. OTL_CHECK( 4 );
  562. coverage = OTL_NEXT_USHORT( p );
  563. count = OTL_NEXT_USHORT( p );
  564. otl_coverage_validate( table + coverage, valid );
  565. OTL_CHECK( 2*count );
  566. for ( ; count > 0; count-- )
  567. otl_chain_sub_rule_set_validate( table + coverage, valid );
  568. }
  569. break;
  570. case 2:
  571. {
  572. OTL_UInt coverage, back_class, input_class, ahead_class, count;
  573. OTL_CHECK( 10 );
  574. coverage = OTL_NEXT_USHORT( p );
  575. back_class = OTL_NEXT_USHORT( p );
  576. input_class = OTL_NEXT_USHORT( p );
  577. ahead_class = OTL_NEXT_USHORT( p );
  578. count = OTL_NEXT_USHORT( p );
  579. otl_coverage_validate( table + coverage, valid );
  580. otl_class_definition_validate( table + back_class, valid );
  581. otl_class_definition_validate( table + input_class, valid );
  582. otl_class_definition_validate( table + ahead_class, valid );
  583. OTL_CHECK( 2*count );
  584. for ( ; count > 0; count-- )
  585. otl_chain_sub_class_set( table + OTL_NEXT_USHORT( p ), valid );
  586. }
  587. break;
  588. case 3:
  589. {
  590. OTL_UInt back_count, input_count, ahead_count, subst_count, count;
  591. OTL_CHECK( 2 );
  592. back_count = OTL_NEXT_USHORT( p );
  593. OTL_CHECK( 2*back_count+2 );
  594. for ( count = back_count; count > 0; count-- )
  595. otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
  596. input_count = OTL_NEXT_USHORT( p );
  597. OTL_CHECK( 2*input_count+2 );
  598. for ( count = input_count; count > 0; count-- )
  599. otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
  600. ahead_count = OTL_NEXT_USHORT( p );
  601. OTL_CHECK( 2*ahead_count+2 );
  602. for ( count = ahead_count; count > 0; count-- )
  603. otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
  604. subst_count = OTL_NEXT_USHORT( p );
  605. OTL_CHECK( subst_count*4 );
  606. }
  607. break;
  608. default:
  609. OTL_INVALID_DATA;
  610. }
  611. }
  612. /************************************************************************/
  613. /************************************************************************/
  614. /***** *****/
  615. /***** GSUB LOOKUP TYPE 6 *****/
  616. /***** *****/
  617. /************************************************************************/
  618. /************************************************************************/
  619. static void
  620. otl_gsub_lookup7_validate( OTL_Bytes table,
  621. OTL_Validator valid )
  622. {
  623. OTL_Bytes p = table;
  624. OTL_UInt format, coverage;
  625. OTL_CHECK( 2 );
  626. format = OTL_NEXT_USHORT( p );
  627. switch ( format )
  628. {
  629. case 1:
  630. {
  631. OTL_UInt lookup_type, lookup_offset;
  632. OTL_ValidateFunc validate;
  633. OTL_CHECK( 6 );
  634. lookup_type = OTL_NEXT_USHORT( p );
  635. lookup_offset = OTL_NEXT_ULONG( p );
  636. if ( lookup_type == 0 || lookup_type >= 7 )
  637. OTL_INVALID_DATA;
  638. validate = otl_gsub_validate_funcs[ lookup_type-1 ];
  639. validate( table + lookup_offset, valid );
  640. }
  641. break;
  642. default:
  643. OTL_INVALID_DATA;
  644. }
  645. }
  646. static const OTL_ValidateFunc otl_gsub_validate_funcs[ 7 ] =
  647. {
  648. otl_gsub_lookup1_validate,
  649. otl_gsub_lookup2_validate,
  650. otl_gsub_lookup3_validate,
  651. otl_gsub_lookup4_validate,
  652. otl_gsub_lookup5_validate,
  653. otl_gsub_lookup6_validate
  654. };
  655. /************************************************************************/
  656. /************************************************************************/
  657. /***** *****/
  658. /***** GSUB TABLE *****/
  659. /***** *****/
  660. /************************************************************************/
  661. /************************************************************************/
  662. OTL_LOCALDEF( void )
  663. otl_gsub_validate( OTL_Bytes table,
  664. OTL_Validator valid )
  665. {
  666. OTL_Bytes p = table;
  667. OTL_UInt scripts, features, lookups;
  668. OTL_CHECK( 10 );
  669. if ( OTL_NEXT_USHORT( p ) != 0x10000UL )
  670. OTL_INVALID_DATA;
  671. scripts = OTL_NEXT_USHORT( p );
  672. features = OTL_NEXT_USHORT( p );
  673. lookups = OTL_NEXT_USHORT( p );
  674. otl_script_list_validate ( table + scripts, valid );
  675. otl_feature_list_validate( table + features, valid );
  676. otl_lookup_list_validate( table + lookups, 7, otl_gsub_validate_funcs,
  677. valid );
  678. }