hb-ot-layout.hh 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. /*
  2. * Copyright © 2007,2008,2009 Red Hat, Inc.
  3. * Copyright © 2012,2013 Google, Inc.
  4. *
  5. * This is part of HarfBuzz, a text shaping library.
  6. *
  7. * Permission is hereby granted, without written agreement and without
  8. * license or royalty fees, to use, copy, modify, and distribute this
  9. * software and its documentation for any purpose, provided that the
  10. * above copyright notice and the following two paragraphs appear in
  11. * all copies of this software.
  12. *
  13. * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  14. * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  15. * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
  16. * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  17. * DAMAGE.
  18. *
  19. * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
  20. * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  21. * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
  22. * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  23. * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  24. *
  25. * Red Hat Author(s): Behdad Esfahbod
  26. * Google Author(s): Behdad Esfahbod
  27. */
  28. #ifndef HB_OT_LAYOUT_HH
  29. #define HB_OT_LAYOUT_HH
  30. #include "hb.hh"
  31. #include "hb-font.hh"
  32. #include "hb-buffer.hh"
  33. #include "hb-open-type.hh"
  34. #include "hb-ot-shape.hh"
  35. #include "hb-set-digest.hh"
  36. struct hb_ot_shape_plan_t;
  37. /*
  38. * kern
  39. */
  40. HB_INTERNAL bool
  41. hb_ot_layout_has_kerning (hb_face_t *face);
  42. HB_INTERNAL bool
  43. hb_ot_layout_has_machine_kerning (hb_face_t *face);
  44. HB_INTERNAL bool
  45. hb_ot_layout_has_cross_kerning (hb_face_t *face);
  46. HB_INTERNAL void
  47. hb_ot_layout_kern (const hb_ot_shape_plan_t *plan,
  48. hb_font_t *font,
  49. hb_buffer_t *buffer);
  50. /* Private API corresponding to hb-ot-layout.h: */
  51. HB_INTERNAL bool
  52. hb_ot_layout_table_find_feature (hb_face_t *face,
  53. hb_tag_t table_tag,
  54. hb_tag_t feature_tag,
  55. unsigned int *feature_index);
  56. /*
  57. * GDEF
  58. */
  59. enum hb_ot_layout_glyph_props_flags_t
  60. {
  61. /* The following three match LookupFlags::Ignore* numbers. */
  62. HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 0x02u,
  63. HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 0x04u,
  64. HB_OT_LAYOUT_GLYPH_PROPS_MARK = 0x08u,
  65. /* The following are used internally; not derived from GDEF. */
  66. HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED = 0x10u,
  67. HB_OT_LAYOUT_GLYPH_PROPS_LIGATED = 0x20u,
  68. HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED = 0x40u,
  69. HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
  70. HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
  71. HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED
  72. };
  73. HB_MARK_AS_FLAG_T (hb_ot_layout_glyph_props_flags_t);
  74. /*
  75. * GSUB/GPOS
  76. */
  77. /* Should be called before all the substitute_lookup's are done. */
  78. HB_INTERNAL void
  79. hb_ot_layout_substitute_start (hb_font_t *font,
  80. hb_buffer_t *buffer);
  81. namespace OT {
  82. struct hb_ot_apply_context_t;
  83. struct hb_ot_layout_lookup_accelerator_t;
  84. namespace Layout {
  85. namespace GSUB_impl {
  86. struct SubstLookup;
  87. }
  88. }
  89. }
  90. HB_INTERNAL void
  91. hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
  92. const OT::Layout::GSUB_impl::SubstLookup &lookup,
  93. const OT::hb_ot_layout_lookup_accelerator_t &accel);
  94. /* Should be called before all the position_lookup's are done. */
  95. HB_INTERNAL void
  96. hb_ot_layout_position_start (hb_font_t *font,
  97. hb_buffer_t *buffer);
  98. /* Should be called after all the position_lookup's are done, to fini advances. */
  99. HB_INTERNAL void
  100. hb_ot_layout_position_finish_advances (hb_font_t *font,
  101. hb_buffer_t *buffer);
  102. /* Should be called after hb_ot_layout_position_finish_advances, to fini offsets. */
  103. HB_INTERNAL void
  104. hb_ot_layout_position_finish_offsets (hb_font_t *font,
  105. hb_buffer_t *buffer);
  106. /*
  107. * Buffer var routines.
  108. */
  109. /* buffer var allocations, used during the entire shaping process */
  110. #define unicode_props() var2.u16[0]
  111. /* buffer var allocations, used during the GSUB/GPOS processing */
  112. #define glyph_props() var1.u16[0] /* GDEF glyph properties */
  113. #define lig_props() var1.u8[2] /* GSUB/GPOS ligature tracking */
  114. #define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */
  115. /* Loop over syllables. Based on foreach_cluster(). */
  116. #define foreach_syllable(buffer, start, end) \
  117. for (unsigned int \
  118. _count = buffer->len, \
  119. start = 0, end = _count ? _hb_next_syllable (buffer, 0) : 0; \
  120. start < _count; \
  121. start = end, end = _hb_next_syllable (buffer, start))
  122. static inline unsigned int
  123. _hb_next_syllable (hb_buffer_t *buffer, unsigned int start)
  124. {
  125. hb_glyph_info_t *info = buffer->info;
  126. unsigned int count = buffer->len;
  127. unsigned int syllable = info[start].syllable();
  128. while (++start < count && syllable == info[start].syllable())
  129. ;
  130. return start;
  131. }
  132. /* unicode_props */
  133. /* Design:
  134. * unicode_props() is a two-byte number. The low byte includes:
  135. * - General_Category: 5 bits.
  136. * - A bit each for:
  137. * * Is it Default_Ignorable(); we have a modified Default_Ignorable().
  138. * * Whether it's one of the four Mongolian Free Variation Selectors,
  139. * CGJ, or other characters that are hidden but should not be ignored
  140. * like most other Default_Ignorable()s do during matching.
  141. * * Whether it's a grapheme continuation.
  142. *
  143. * The high-byte has different meanings, switched by the Gen-Cat:
  144. * - For Mn,Mc,Me: the modified Combining_Class.
  145. * - For Cf: whether it's ZWJ, ZWNJ, or something else.
  146. * - For Ws: index of which space character this is, if space fallback
  147. * is needed, ie. we don't set this by default, only if asked to.
  148. */
  149. enum hb_unicode_props_flags_t {
  150. UPROPS_MASK_GEN_CAT = 0x001Fu,
  151. UPROPS_MASK_IGNORABLE = 0x0020u,
  152. UPROPS_MASK_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..4, or TAG characters */
  153. UPROPS_MASK_CONTINUATION=0x0080u,
  154. /* If GEN_CAT=FORMAT, top byte masks: */
  155. UPROPS_MASK_Cf_ZWJ = 0x0100u,
  156. UPROPS_MASK_Cf_ZWNJ = 0x0200u
  157. };
  158. HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t);
  159. static inline void
  160. _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
  161. {
  162. hb_unicode_funcs_t *unicode = buffer->unicode;
  163. unsigned int u = info->codepoint;
  164. unsigned int gen_cat = (unsigned int) unicode->general_category (u);
  165. unsigned int props = gen_cat;
  166. if (u >= 0x80u)
  167. {
  168. buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII;
  169. if (unlikely (unicode->is_default_ignorable (u)))
  170. {
  171. buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES;
  172. props |= UPROPS_MASK_IGNORABLE;
  173. if (u == 0x200Cu) props |= UPROPS_MASK_Cf_ZWNJ;
  174. else if (u == 0x200Du) props |= UPROPS_MASK_Cf_ZWJ;
  175. /* Mongolian Free Variation Selectors need to be remembered
  176. * because although we need to hide them like default-ignorables,
  177. * they need to non-ignorable during shaping. This is similar to
  178. * what we do for joiners in Indic-like shapers, but since the
  179. * FVSes are GC=Mn, we have use a separate bit to remember them.
  180. * Fixes:
  181. * https://github.com/harfbuzz/harfbuzz/issues/234 */
  182. else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0x180Bu, 0x180Du, 0x180Fu, 0x180Fu))) props |= UPROPS_MASK_HIDDEN;
  183. /* TAG characters need similar treatment. Fixes:
  184. * https://github.com/harfbuzz/harfbuzz/issues/463 */
  185. else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xE0020u, 0xE007Fu))) props |= UPROPS_MASK_HIDDEN;
  186. /* COMBINING GRAPHEME JOINER should not be skipped; at least some times.
  187. * https://github.com/harfbuzz/harfbuzz/issues/554 */
  188. else if (unlikely (u == 0x034Fu))
  189. {
  190. buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CGJ;
  191. props |= UPROPS_MASK_HIDDEN;
  192. }
  193. }
  194. if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat)))
  195. {
  196. props |= UPROPS_MASK_CONTINUATION;
  197. props |= unicode->modified_combining_class (u)<<8;
  198. }
  199. }
  200. info->unicode_props() = props;
  201. }
  202. static inline void
  203. _hb_glyph_info_set_general_category (hb_glyph_info_t *info,
  204. hb_unicode_general_category_t gen_cat)
  205. {
  206. /* Clears top-byte. */
  207. info->unicode_props() = (unsigned int) gen_cat | (info->unicode_props() & (0xFF & ~UPROPS_MASK_GEN_CAT));
  208. }
  209. static inline hb_unicode_general_category_t
  210. _hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
  211. {
  212. return (hb_unicode_general_category_t) (info->unicode_props() & UPROPS_MASK_GEN_CAT);
  213. }
  214. static inline bool
  215. _hb_glyph_info_is_unicode_mark (const hb_glyph_info_t *info)
  216. {
  217. return HB_UNICODE_GENERAL_CATEGORY_IS_MARK (info->unicode_props() & UPROPS_MASK_GEN_CAT);
  218. }
  219. static inline void
  220. _hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info,
  221. unsigned int modified_class)
  222. {
  223. if (unlikely (!_hb_glyph_info_is_unicode_mark (info)))
  224. return;
  225. info->unicode_props() = (modified_class<<8) | (info->unicode_props() & 0xFF);
  226. }
  227. static inline unsigned int
  228. _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
  229. {
  230. return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0;
  231. }
  232. #define info_cc(info) (_hb_glyph_info_get_modified_combining_class (&(info)))
  233. static inline bool
  234. _hb_glyph_info_is_unicode_space (const hb_glyph_info_t *info)
  235. {
  236. return _hb_glyph_info_get_general_category (info) ==
  237. HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR;
  238. }
  239. static inline void
  240. _hb_glyph_info_set_unicode_space_fallback_type (hb_glyph_info_t *info, hb_unicode_funcs_t::space_t s)
  241. {
  242. if (unlikely (!_hb_glyph_info_is_unicode_space (info)))
  243. return;
  244. info->unicode_props() = (((unsigned int) s)<<8) | (info->unicode_props() & 0xFF);
  245. }
  246. static inline hb_unicode_funcs_t::space_t
  247. _hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info)
  248. {
  249. return _hb_glyph_info_is_unicode_space (info) ?
  250. (hb_unicode_funcs_t::space_t) (info->unicode_props()>>8) :
  251. hb_unicode_funcs_t::NOT_SPACE;
  252. }
  253. static inline bool _hb_glyph_info_substituted (const hb_glyph_info_t *info);
  254. static inline bool
  255. _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
  256. {
  257. return (info->unicode_props() & UPROPS_MASK_IGNORABLE) &&
  258. !_hb_glyph_info_substituted (info);
  259. }
  260. static inline bool
  261. _hb_glyph_info_is_default_ignorable_and_not_hidden (const hb_glyph_info_t *info)
  262. {
  263. return ((info->unicode_props() & (UPROPS_MASK_IGNORABLE|UPROPS_MASK_HIDDEN))
  264. == UPROPS_MASK_IGNORABLE) &&
  265. !_hb_glyph_info_substituted (info);
  266. }
  267. static inline void
  268. _hb_glyph_info_unhide (hb_glyph_info_t *info)
  269. {
  270. info->unicode_props() &= ~ UPROPS_MASK_HIDDEN;
  271. }
  272. static inline void
  273. _hb_glyph_info_set_continuation (hb_glyph_info_t *info)
  274. {
  275. info->unicode_props() |= UPROPS_MASK_CONTINUATION;
  276. }
  277. static inline void
  278. _hb_glyph_info_reset_continuation (hb_glyph_info_t *info)
  279. {
  280. info->unicode_props() &= ~ UPROPS_MASK_CONTINUATION;
  281. }
  282. static inline bool
  283. _hb_glyph_info_is_continuation (const hb_glyph_info_t *info)
  284. {
  285. return info->unicode_props() & UPROPS_MASK_CONTINUATION;
  286. }
  287. static inline bool
  288. _hb_grapheme_group_func (const hb_glyph_info_t& a HB_UNUSED,
  289. const hb_glyph_info_t& b)
  290. { return _hb_glyph_info_is_continuation (&b); }
  291. #define foreach_grapheme(buffer, start, end) \
  292. foreach_group (buffer, start, end, _hb_grapheme_group_func)
  293. static inline void
  294. _hb_ot_layout_reverse_graphemes (hb_buffer_t *buffer)
  295. {
  296. buffer->reverse_groups (_hb_grapheme_group_func,
  297. buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
  298. }
  299. static inline bool
  300. _hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info)
  301. {
  302. return _hb_glyph_info_get_general_category (info) ==
  303. HB_UNICODE_GENERAL_CATEGORY_FORMAT;
  304. }
  305. static inline bool
  306. _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
  307. {
  308. return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWNJ);
  309. }
  310. static inline bool
  311. _hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
  312. {
  313. return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWJ);
  314. }
  315. static inline bool
  316. _hb_glyph_info_is_joiner (const hb_glyph_info_t *info)
  317. {
  318. return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & (UPROPS_MASK_Cf_ZWNJ|UPROPS_MASK_Cf_ZWJ));
  319. }
  320. static inline void
  321. _hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
  322. {
  323. if (!_hb_glyph_info_is_unicode_format (info))
  324. return;
  325. info->unicode_props() ^= UPROPS_MASK_Cf_ZWNJ | UPROPS_MASK_Cf_ZWJ;
  326. }
  327. /* lig_props: aka lig_id / lig_comp
  328. *
  329. * When a ligature is formed:
  330. *
  331. * - The ligature glyph and any marks in between all the same newly allocated
  332. * lig_id,
  333. * - The ligature glyph will get lig_num_comps set to the number of components
  334. * - The marks get lig_comp > 0, reflecting which component of the ligature
  335. * they were applied to.
  336. * - This is used in GPOS to attach marks to the right component of a ligature
  337. * in MarkLigPos,
  338. * - Note that when marks are ligated together, much of the above is skipped
  339. * and the current lig_id reused.
  340. *
  341. * When a multiple-substitution is done:
  342. *
  343. * - All resulting glyphs will have lig_id = 0,
  344. * - The resulting glyphs will have lig_comp = 0, 1, 2, ... respectively.
  345. * - This is used in GPOS to attach marks to the first component of a
  346. * multiple substitution in MarkBasePos.
  347. *
  348. * The numbers are also used in GPOS to do mark-to-mark positioning only
  349. * to marks that belong to the same component of the same ligature.
  350. */
  351. static inline void
  352. _hb_glyph_info_clear_lig_props (hb_glyph_info_t *info)
  353. {
  354. info->lig_props() = 0;
  355. }
  356. #define IS_LIG_BASE 0x10
  357. static inline void
  358. _hb_glyph_info_set_lig_props_for_ligature (hb_glyph_info_t *info,
  359. unsigned int lig_id,
  360. unsigned int lig_num_comps)
  361. {
  362. info->lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F);
  363. }
  364. static inline void
  365. _hb_glyph_info_set_lig_props_for_mark (hb_glyph_info_t *info,
  366. unsigned int lig_id,
  367. unsigned int lig_comp)
  368. {
  369. info->lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
  370. }
  371. static inline void
  372. _hb_glyph_info_set_lig_props_for_component (hb_glyph_info_t *info, unsigned int comp)
  373. {
  374. _hb_glyph_info_set_lig_props_for_mark (info, 0, comp);
  375. }
  376. static inline unsigned int
  377. _hb_glyph_info_get_lig_id (const hb_glyph_info_t *info)
  378. {
  379. return info->lig_props() >> 5;
  380. }
  381. static inline bool
  382. _hb_glyph_info_ligated_internal (const hb_glyph_info_t *info)
  383. {
  384. return !!(info->lig_props() & IS_LIG_BASE);
  385. }
  386. static inline unsigned int
  387. _hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info)
  388. {
  389. if (_hb_glyph_info_ligated_internal (info))
  390. return 0;
  391. else
  392. return info->lig_props() & 0x0F;
  393. }
  394. static inline unsigned int
  395. _hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
  396. {
  397. if ((info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) &&
  398. _hb_glyph_info_ligated_internal (info))
  399. return info->lig_props() & 0x0F;
  400. else
  401. return 1;
  402. }
  403. static inline uint8_t
  404. _hb_allocate_lig_id (hb_buffer_t *buffer)
  405. {
  406. uint8_t lig_id = buffer->next_serial () & 0x07;
  407. if (unlikely (!lig_id))
  408. lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
  409. return lig_id;
  410. }
  411. /* glyph_props: */
  412. static inline void
  413. _hb_glyph_info_set_glyph_props (hb_glyph_info_t *info, unsigned int props)
  414. {
  415. info->glyph_props() = props;
  416. }
  417. static inline unsigned int
  418. _hb_glyph_info_get_glyph_props (const hb_glyph_info_t *info)
  419. {
  420. return info->glyph_props();
  421. }
  422. static inline bool
  423. _hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info)
  424. {
  425. return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
  426. }
  427. static inline bool
  428. _hb_glyph_info_is_ligature (const hb_glyph_info_t *info)
  429. {
  430. return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE);
  431. }
  432. static inline bool
  433. _hb_glyph_info_is_mark (const hb_glyph_info_t *info)
  434. {
  435. return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
  436. }
  437. static inline bool
  438. _hb_glyph_info_substituted (const hb_glyph_info_t *info)
  439. {
  440. return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
  441. }
  442. static inline bool
  443. _hb_glyph_info_ligated (const hb_glyph_info_t *info)
  444. {
  445. return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
  446. }
  447. static inline bool
  448. _hb_glyph_info_multiplied (const hb_glyph_info_t *info)
  449. {
  450. return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
  451. }
  452. static inline bool
  453. _hb_glyph_info_ligated_and_didnt_multiply (const hb_glyph_info_t *info)
  454. {
  455. return _hb_glyph_info_ligated (info) && !_hb_glyph_info_multiplied (info);
  456. }
  457. static inline void
  458. _hb_glyph_info_clear_ligated_and_multiplied (hb_glyph_info_t *info)
  459. {
  460. info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
  461. HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
  462. }
  463. static inline void
  464. _hb_glyph_info_clear_substituted (hb_glyph_info_t *info)
  465. {
  466. info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
  467. }
  468. static inline bool
  469. _hb_clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
  470. hb_font_t *font HB_UNUSED,
  471. hb_buffer_t *buffer)
  472. {
  473. hb_glyph_info_t *info = buffer->info;
  474. unsigned int count = buffer->len;
  475. for (unsigned int i = 0; i < count; i++)
  476. _hb_glyph_info_clear_substituted (&info[i]);
  477. return false;
  478. }
  479. /* Allocation / deallocation. */
  480. static inline void
  481. _hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer)
  482. {
  483. HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props);
  484. }
  485. static inline void
  486. _hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer)
  487. {
  488. HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props);
  489. }
  490. static inline void
  491. _hb_buffer_assert_unicode_vars (hb_buffer_t *buffer)
  492. {
  493. HB_BUFFER_ASSERT_VAR (buffer, unicode_props);
  494. }
  495. static inline void
  496. _hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer)
  497. {
  498. HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
  499. HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
  500. }
  501. static inline void
  502. _hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer)
  503. {
  504. HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
  505. HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
  506. }
  507. static inline void
  508. _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer)
  509. {
  510. HB_BUFFER_ASSERT_VAR (buffer, glyph_props);
  511. HB_BUFFER_ASSERT_VAR (buffer, lig_props);
  512. }
  513. /* Make sure no one directly touches our props... */
  514. #undef unicode_props0
  515. #undef unicode_props1
  516. #undef lig_props
  517. #undef glyph_props
  518. #endif /* HB_OT_LAYOUT_HH */