1a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod/* 22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2007,2008,2009,2010 Red Hat, Inc. 32e0c44f4bedd3e24c731c0e9e23358e9a4891a35Behdad Esfahbod * Copyright © 2010,2012,2013 Google, Inc. 4a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * 5c755cb3e3ac55156d0d2ec05adea7a650b97cc41Behdad Esfahbod * This is part of HarfBuzz, a text shaping library. 6a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * 7a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * Permission is hereby granted, without written agreement and without 8a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 9a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * software and its documentation for any purpose, provided that the 10a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 11a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * all copies of this software. 12a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * 13a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * DAMAGE. 18a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * 19a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * 25a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * Red Hat Author(s): Behdad Esfahbod 2698370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod * Google Author(s): Behdad Esfahbod 27a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod */ 28a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 297a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#ifndef HB_OT_LAYOUT_GSUB_TABLE_HH 307a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#define HB_OT_LAYOUT_GSUB_TABLE_HH 31a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 325f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#include "hb-ot-layout-gsubgpos-private.hh" 33a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 34acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 357c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodnamespace OT { 367c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 376f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 384c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct SingleSubstFormat1 394c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 405caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c) const 41f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 42be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 43c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod Coverage::Iter iter; 44c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (iter.init (this+coverage); iter.more (); iter.next ()) { 45c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod hb_codepoint_t glyph_id = iter.get_glyph (); 46c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod if (c->glyphs->has (glyph_id)) 477627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFFu); 48c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 49f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 50f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 51e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 52e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 5326514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod TRACE_COLLECT_GLYPHS (this); 54e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod Coverage::Iter iter; 55e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod for (iter.init (this+coverage); iter.more (); iter.next ()) { 56e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_codepoint_t glyph_id = iter.get_glyph (); 578303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod c->input->add (glyph_id); 587627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu); 59e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 60e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 61e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 620b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod inline const Coverage &get_coverage (void) const 630b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod { 640b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod return this+coverage; 650b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod } 660b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod 672005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 682005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod { 69be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 70b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); 712005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod } 722005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod 73d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 744c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod { 75be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 7699c2695759a6af855d565f4994bbdf220570bb48Behdad Esfahbod hb_codepoint_t glyph_id = c->buffer->cur().codepoint; 77b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (glyph_id); 78acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 7930bd763fa2fa4aceee51433ec9fc8dc28480b5d7Behdad Esfahbod 8052ebdff49d13f239efc886de935d47be9860f6e5Behdad Esfahbod /* According to the Adobe Annotated OpenType Suite, result is always 8152ebdff49d13f239efc886de935d47be9860f6e5Behdad Esfahbod * limited to 16bit. */ 827627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu; 8398370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod c->replace_glyph (glyph_id); 8430bd763fa2fa4aceee51433ec9fc8dc28480b5d7Behdad Esfahbod 85acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (true); 865a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod } 8730bd763fa2fa4aceee51433ec9fc8dc28480b5d7Behdad Esfahbod 88bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 89a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 90bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod unsigned int num_glyphs, 911b38b4e817d871b9549be65af6030bd0eea7f775Behdad Esfahbod int delta) 92bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod { 93be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 94bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 95abcc5ac1fde1c493e4055dd2f27b8aade7713156Behdad Esfahbod if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); 964912030dfba740c822e200d33cbb5c6dbbeaf79eBehdad Esfahbod deltaGlyphID.set (delta); /* TODO(serilaize) overflow? */ 97bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod return TRACE_RETURN (true); 98bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod } 99bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 100d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 101be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1020ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c)); 10370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 10470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 105ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 106f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod USHORT format; /* Format identifier--format = 1 */ 107238c855fcd4f0ef97a94a8662d2a2f2bb5c21ecbBehdad Esfahbod OffsetTo<Coverage> 108238c855fcd4f0ef97a94a8662d2a2f2bb5c21ecbBehdad Esfahbod coverage; /* Offset to Coverage table--from 109a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * beginning of Substitution table */ 110a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod SHORT deltaGlyphID; /* Add to original GlyphID to get 111a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * substitute GlyphID */ 112b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 113b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod DEFINE_SIZE_STATIC (6); 114a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod}; 115a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 1164c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct SingleSubstFormat2 1174c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 1185caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c) const 119f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 120be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 121c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod Coverage::Iter iter; 122c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (iter.init (this+coverage); iter.more (); iter.next ()) { 123c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod if (c->glyphs->has (iter.get_glyph ())) 1245caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod c->glyphs->add (substitute[iter.get_coverage ()]); 125c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 126f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 127f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 128e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 129e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 13026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod TRACE_COLLECT_GLYPHS (this); 131e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod Coverage::Iter iter; 132e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod for (iter.init (this+coverage); iter.more (); iter.next ()) { 1338303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod c->input->add (iter.get_glyph ()); 1348303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod c->output->add (substitute[iter.get_coverage ()]); 135e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 136e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 137e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 1380b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod inline const Coverage &get_coverage (void) const 1390b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod { 1400b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod return this+coverage; 1410b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod } 1420b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod 1432005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 1442005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod { 145be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 146b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); 1472005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod } 1482005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod 149d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 1504c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod { 151be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 15299c2695759a6af855d565f4994bbdf220570bb48Behdad Esfahbod hb_codepoint_t glyph_id = c->buffer->cur().codepoint; 153b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (glyph_id); 154acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 1555a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 156acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (unlikely (index >= substitute.len)) return TRACE_RETURN (false); 1575a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 1585a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod glyph_id = substitute[index]; 15998370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod c->replace_glyph (glyph_id); 1604c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod 161acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (true); 1625a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod } 163a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 164c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 165a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 166a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &substitutes, 167c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod unsigned int num_glyphs) 168c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod { 169be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 170c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 171c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod if (unlikely (!substitute.serialize (c, substitutes, num_glyphs))) return TRACE_RETURN (false); 172fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); 173c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod return TRACE_RETURN (true); 174c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod } 175c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod 176d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 177be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1780ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (coverage.sanitize (c, this) && substitute.sanitize (c)); 17970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 18070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 181ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 182f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod USHORT format; /* Format identifier--format = 2 */ 183238c855fcd4f0ef97a94a8662d2a2f2bb5c21ecbBehdad Esfahbod OffsetTo<Coverage> 184238c855fcd4f0ef97a94a8662d2a2f2bb5c21ecbBehdad Esfahbod coverage; /* Offset to Coverage table--from 185a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * beginning of Substitution table */ 186c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod ArrayOf<GlyphID> 187c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod substitute; /* Array of substitute 188c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod * GlyphIDs--ordered by Coverage Index */ 189b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 1900eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, substitute); 191a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod}; 192a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 1934c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct SingleSubst 1944c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 195c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 196a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 197a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &substitutes, 198c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod unsigned int num_glyphs) 199c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod { 200be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 201c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); 202c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod unsigned int format = 2; 2031b38b4e817d871b9549be65af6030bd0eea7f775Behdad Esfahbod int delta; 204c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod if (num_glyphs) { 205c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod format = 1; 2064912030dfba740c822e200d33cbb5c6dbbeaf79eBehdad Esfahbod /* TODO(serialize) check for wrap-around */ 207c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod delta = substitutes[0] - glyphs[0]; 208c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod for (unsigned int i = 1; i < num_glyphs; i++) 209c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod if (delta != substitutes[i] - glyphs[i]) { 210c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod format = 2; 211c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod break; 212c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod } 213c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod } 214c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod u.format.set (format); 215c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod switch (u.format) { 216c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs, delta)); 217c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, substitutes, num_glyphs)); 218c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod default:return TRACE_RETURN (false); 219c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod } 220c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod } 221c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod 222ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod template <typename context_t> 223ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 224ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod { 225ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod TRACE_DISPATCH (this); 226ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod switch (u.format) { 227ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod case 1: return TRACE_RETURN (c->dispatch (u.format1)); 228ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod case 2: return TRACE_RETURN (c->dispatch (u.format2)); 229ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod default:return TRACE_RETURN (c->default_return_value ()); 230ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod } 231ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod } 232ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod 233d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 234be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 2350ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!u.format.sanitize (c)) return TRACE_RETURN (false); 23670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 2370ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 1: return TRACE_RETURN (u.format1.sanitize (c)); 2380ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 2: return TRACE_RETURN (u.format2.sanitize (c)); 2390ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod default:return TRACE_RETURN (true); 24070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 24170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 24270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 243ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 2445a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod union { 245f8dc67b3c24dfc805da756a73cb217b36e16b4b8Behdad Esfahbod USHORT format; /* Format identifier */ 246dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod SingleSubstFormat1 format1; 247dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod SingleSubstFormat2 format2; 2485a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod } u; 249a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod}; 2505a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 251a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 2524c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct Sequence 2534c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 2545caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c) const 255f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 256be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 257c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod unsigned int count = substitute.len; 258c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 2595caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod c->glyphs->add (substitute[i]); 260f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 261f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 262e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 263e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 26426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod TRACE_COLLECT_GLYPHS (this); 265e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod unsigned int count = substitute.len; 266e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 2678303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod c->output->add (substitute[i]); 268e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 269e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 270d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 2714c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod { 272be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 273aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod unsigned int count = substitute.len; 274b6b304f12be917b7449b3ac9409069fcd4a27d95Behdad Esfahbod 275b6b304f12be917b7449b3ac9409069fcd4a27d95Behdad Esfahbod /* TODO: 276b6b304f12be917b7449b3ac9409069fcd4a27d95Behdad Esfahbod * Testing shows that Uniscribe actually allows zero-len susbstitute, 277b6b304f12be917b7449b3ac9409069fcd4a27d95Behdad Esfahbod * which essentially deletes a glyph. We don't allow for now. It 278b6b304f12be917b7449b3ac9409069fcd4a27d95Behdad Esfahbod * can be confusing to the client since the cluster from the deleted 279b6b304f12be917b7449b3ac9409069fcd4a27d95Behdad Esfahbod * glyph won't be merged with any output cluster... Also, currently 280b6b304f12be917b7449b3ac9409069fcd4a27d95Behdad Esfahbod * buffer->move_to() makes assumptions about this too. Perhaps fix 281b6b304f12be917b7449b3ac9409069fcd4a27d95Behdad Esfahbod * in the future after figuring out what to do with the clusters. 282b6b304f12be917b7449b3ac9409069fcd4a27d95Behdad Esfahbod */ 283aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod if (unlikely (!count)) return TRACE_RETURN (false); 284c9c6a78aec2b16ac06dfca8cbfaf28a77a10bae2Behdad Esfahbod 285aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod /* Special-case to make it in-place and not consider this 286aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod * as a "multiplied" substitution. */ 287aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod if (unlikely (count == 1)) 2885d59f999204aedfc433ab4989664d875f96b0364Behdad Esfahbod { 2895d59f999204aedfc433ab4989664d875f96b0364Behdad Esfahbod c->replace_glyph (substitute.array[0]); 290aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod return TRACE_RETURN (true); 2915d59f999204aedfc433ab4989664d875f96b0364Behdad Esfahbod } 292aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod 293aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? 294aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; 295aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod 296aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod for (unsigned int i = 0; i < count; i++) { 297aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); 298832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod c->output_glyph_for_component (substitute.array[i], klass); 299ec57e0c5655ced5109c4638bf802772d336448fdBehdad Esfahbod } 300aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod c->buffer->skip_glyph (); 301c9c6a78aec2b16ac06dfca8cbfaf28a77a10bae2Behdad Esfahbod 302acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (true); 303c9c6a78aec2b16ac06dfca8cbfaf28a77a10bae2Behdad Esfahbod } 304c9c6a78aec2b16ac06dfca8cbfaf28a77a10bae2Behdad Esfahbod 3051f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 306a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 3071f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod unsigned int num_glyphs) 3081f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod { 309be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 3101f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 3111f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod if (unlikely (!substitute.serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); 3121f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod return TRACE_RETURN (true); 3131f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod } 3141f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod 315d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 316be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 3170ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (substitute.sanitize (c)); 31870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 31970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 320ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 321c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod ArrayOf<GlyphID> 322c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod substitute; /* String of GlyphIDs to substitute */ 323b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 3240eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (2, substitute); 325a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod}; 326a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 3274c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct MultipleSubstFormat1 3284c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 3295caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c) const 330f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 331be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 332c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod Coverage::Iter iter; 333c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (iter.init (this+coverage); iter.more (); iter.next ()) { 334c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod if (c->glyphs->has (iter.get_glyph ())) 3355caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod (this+sequence[iter.get_coverage ()]).closure (c); 336c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 337f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 338f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 339e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 340e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 34126514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod TRACE_COLLECT_GLYPHS (this); 3428303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+coverage).add_coverage (c->input); 343e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod unsigned int count = sequence.len; 344e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 345e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod (this+sequence[i]).collect_glyphs (c); 346e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 347e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 3480b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod inline const Coverage &get_coverage (void) const 3490b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod { 3500b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod return this+coverage; 3510b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod } 3520b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod 3532005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 3542005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod { 355be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 356b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); 3572005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod } 3582005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod 359d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 3604c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod { 361be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 3625a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 363b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 364acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 365aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 366acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN ((this+sequence[index]).apply (c)); 3675a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod } 368a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 3691f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 370a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 371a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<unsigned int> &substitute_len_list, 3721f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod unsigned int num_glyphs, 373a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &substitute_glyphs_list) 3741f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod { 375be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 3761f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 3771f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod if (unlikely (!sequence.serialize (c, num_glyphs))) return TRACE_RETURN (false); 378a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod for (unsigned int i = 0; i < num_glyphs; i++) 379a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod if (unlikely (!sequence[i].serialize (c, this).serialize (c, 380a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod substitute_glyphs_list, 381a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod substitute_len_list[i]))) return TRACE_RETURN (false); 382a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod substitute_len_list.advance (num_glyphs); 383fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); 3841f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod return TRACE_RETURN (true); 3851f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod } 3861f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod 387d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 388be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 3890ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (coverage.sanitize (c, this) && sequence.sanitize (c, this)); 39070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 39170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 392ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 393f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod USHORT format; /* Format identifier--format = 1 */ 394238c855fcd4f0ef97a94a8662d2a2f2bb5c21ecbBehdad Esfahbod OffsetTo<Coverage> 395238c855fcd4f0ef97a94a8662d2a2f2bb5c21ecbBehdad Esfahbod coverage; /* Offset to Coverage table--from 396a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * beginning of Substitution table */ 397c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod OffsetArrayOf<Sequence> 398c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod sequence; /* Array of Sequence tables 399c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod * ordered by Coverage Index */ 400b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 4010eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, sequence); 402a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod}; 4035a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 4044c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct MultipleSubst 4054c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 4061f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 407a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 408a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<unsigned int> &substitute_len_list, 4091f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod unsigned int num_glyphs, 410a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &substitute_glyphs_list) 4111f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod { 412be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 4131f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); 4141f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod unsigned int format = 1; 4151f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod u.format.set (format); 4161f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod switch (u.format) { 4171f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, substitute_len_list, num_glyphs, substitute_glyphs_list)); 4181f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod default:return TRACE_RETURN (false); 4191f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod } 4201f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod } 4211f07e3382a1608b054cbf88b89fef74f6c485434Behdad Esfahbod 422ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod template <typename context_t> 423ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 424ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod { 425ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod TRACE_DISPATCH (this); 426ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod switch (u.format) { 427ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod case 1: return TRACE_RETURN (c->dispatch (u.format1)); 428ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod default:return TRACE_RETURN (c->default_return_value ()); 429ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod } 430ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod } 431ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod 432d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 433be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 4340ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!u.format.sanitize (c)) return TRACE_RETURN (false); 43570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 4360ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 1: return TRACE_RETURN (u.format1.sanitize (c)); 4370ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod default:return TRACE_RETURN (true); 43870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 43970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 44070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 441ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 4425a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod union { 443f8dc67b3c24dfc805da756a73cb217b36e16b4b8Behdad Esfahbod USHORT format; /* Format identifier */ 444dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod MultipleSubstFormat1 format1; 4455a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod } u; 4465a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod}; 4475a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 448a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 449c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbodtypedef ArrayOf<GlyphID> AlternateSet; /* Array of alternate GlyphIDs--in 450a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * arbitrary order */ 451a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 4524c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct AlternateSubstFormat1 4534c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 4545caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c) const 455f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 456be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 457c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod Coverage::Iter iter; 458c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (iter.init (this+coverage); iter.more (); iter.next ()) { 459c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod if (c->glyphs->has (iter.get_glyph ())) { 460c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()]; 461c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod unsigned int count = alt_set.len; 462c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 4635caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod c->glyphs->add (alt_set[i]); 464c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 465c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 466f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 467f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 468e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 469e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 47026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod TRACE_COLLECT_GLYPHS (this); 471e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod Coverage::Iter iter; 472e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod for (iter.init (this+coverage); iter.more (); iter.next ()) { 4738303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod c->input->add (iter.get_glyph ()); 474e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()]; 475e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod unsigned int count = alt_set.len; 476e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 4778303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod c->output->add (alt_set[i]); 478e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 479e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 480e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 4810b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod inline const Coverage &get_coverage (void) const 4820b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod { 4830b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod return this+coverage; 4840b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod } 4850b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod 4862005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 4872005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod { 488be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 489b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); 4902005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod } 4912005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod 492d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 4934c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod { 494be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 49599c2695759a6af855d565f4994bbdf220570bb48Behdad Esfahbod hb_codepoint_t glyph_id = c->buffer->cur().codepoint; 49652886ca56b24a8335614b1df16a33dd4e2d7ae56Behdad Esfahbod 497b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (glyph_id); 498acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 499aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 500c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod const AlternateSet &alt_set = this+alternateSet[index]; 50152886ca56b24a8335614b1df16a33dd4e2d7ae56Behdad Esfahbod 502acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (unlikely (!alt_set.len)) return TRACE_RETURN (false); 50352886ca56b24a8335614b1df16a33dd4e2d7ae56Behdad Esfahbod 50499c2695759a6af855d565f4994bbdf220570bb48Behdad Esfahbod hb_mask_t glyph_mask = c->buffer->cur().mask; 50536608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod hb_mask_t lookup_mask = c->lookup_mask; 50636608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod 507dd22a8f7bfd424a69286e90f79d2a23af6e89ec1Behdad Esfahbod /* Note: This breaks badly if two features enabled this lookup together. */ 508f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod unsigned int shift = _hb_ctz (lookup_mask); 5091cdbfd944eecb58587461f57f037e47a44f39990Behdad Esfahbod unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift); 51052886ca56b24a8335614b1df16a33dd4e2d7ae56Behdad Esfahbod 511acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (unlikely (alt_index > alt_set.len || alt_index == 0)) return TRACE_RETURN (false); 51252886ca56b24a8335614b1df16a33dd4e2d7ae56Behdad Esfahbod 5131cdbfd944eecb58587461f57f037e47a44f39990Behdad Esfahbod glyph_id = alt_set[alt_index - 1]; 51452886ca56b24a8335614b1df16a33dd4e2d7ae56Behdad Esfahbod 51598370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod c->replace_glyph (glyph_id); 51652886ca56b24a8335614b1df16a33dd4e2d7ae56Behdad Esfahbod 517acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (true); 51852886ca56b24a8335614b1df16a33dd4e2d7ae56Behdad Esfahbod } 519a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 52029416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 521a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 522a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<unsigned int> &alternate_len_list, 52329416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod unsigned int num_glyphs, 524a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &alternate_glyphs_list) 52529416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod { 526be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 52729416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 52829416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod if (unlikely (!alternateSet.serialize (c, num_glyphs))) return TRACE_RETURN (false); 529a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod for (unsigned int i = 0; i < num_glyphs; i++) 530a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod if (unlikely (!alternateSet[i].serialize (c, this).serialize (c, 531a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod alternate_glyphs_list, 532a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod alternate_len_list[i]))) return TRACE_RETURN (false); 533a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod alternate_len_list.advance (num_glyphs); 534fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); 53529416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod return TRACE_RETURN (true); 53629416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod } 53729416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod 538d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 539be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 5400ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (coverage.sanitize (c, this) && alternateSet.sanitize (c, this)); 54170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 54270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 543ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 544f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod USHORT format; /* Format identifier--format = 1 */ 545238c855fcd4f0ef97a94a8662d2a2f2bb5c21ecbBehdad Esfahbod OffsetTo<Coverage> 546238c855fcd4f0ef97a94a8662d2a2f2bb5c21ecbBehdad Esfahbod coverage; /* Offset to Coverage table--from 547a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * beginning of Substitution table */ 548c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod OffsetArrayOf<AlternateSet> 549c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod alternateSet; /* Array of AlternateSet tables 550c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod * ordered by Coverage Index */ 551b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 5520eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, alternateSet); 553a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod}; 5545a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 5554c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct AlternateSubst 5564c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 55729416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 558a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 559a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<unsigned int> &alternate_len_list, 56029416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod unsigned int num_glyphs, 561a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &alternate_glyphs_list) 56229416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod { 563be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 56429416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); 56529416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod unsigned int format = 1; 56629416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod u.format.set (format); 56729416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod switch (u.format) { 56829416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, alternate_len_list, num_glyphs, alternate_glyphs_list)); 56929416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod default:return TRACE_RETURN (false); 57029416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod } 57129416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod } 57229416833584d7831ece84aaeada6f5ebba7828c0Behdad Esfahbod 573ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod template <typename context_t> 574ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 575ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod { 576ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod TRACE_DISPATCH (this); 577ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod switch (u.format) { 578ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod case 1: return TRACE_RETURN (c->dispatch (u.format1)); 579ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod default:return TRACE_RETURN (c->default_return_value ()); 580ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod } 581ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod } 582ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod 583d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 584be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 5850ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!u.format.sanitize (c)) return TRACE_RETURN (false); 58670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 5870ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 1: return TRACE_RETURN (u.format1.sanitize (c)); 5880ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod default:return TRACE_RETURN (true); 58970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 59070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 59170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 592ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 59352886ca56b24a8335614b1df16a33dd4e2d7ae56Behdad Esfahbod union { 594f8dc67b3c24dfc805da756a73cb217b36e16b4b8Behdad Esfahbod USHORT format; /* Format identifier */ 595dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod AlternateSubstFormat1 format1; 59652886ca56b24a8335614b1df16a33dd4e2d7ae56Behdad Esfahbod } u; 59752886ca56b24a8335614b1df16a33dd4e2d7ae56Behdad Esfahbod}; 59852886ca56b24a8335614b1df16a33dd4e2d7ae56Behdad Esfahbod 5995a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 6004c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct Ligature 6014c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 6025caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c) const 603f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 604be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 605c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod unsigned int count = component.len; 606c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (unsigned int i = 1; i < count; i++) 607c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod if (!c->glyphs->has (component[i])) 6085caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod return; 6095caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod c->glyphs->add (ligGlyph); 610f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 611f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 612e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 613e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 61426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod TRACE_COLLECT_GLYPHS (this); 615e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod unsigned int count = component.len; 616e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod for (unsigned int i = 1; i < count; i++) 6178303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod c->input->add (component[i]); 6188303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod c->output->add (ligGlyph); 619e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 620e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 621e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 62236608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod { 623be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 624472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod if (c->len != component.len) 6252005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod return TRACE_RETURN (false); 626472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod 627472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod for (unsigned int i = 1; i < c->len; i++) 628472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod if (likely (c->glyphs[i] != component[i])) 6292005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod return TRACE_RETURN (false); 630472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod 6312005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod return TRACE_RETURN (true); 63236608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod } 63336608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod 63498370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 6354c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod { 636be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 637e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod unsigned int count = component.len; 638aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod 639aae69451dfbf2e3671c555c234f788c194302818Behdad Esfahbod if (unlikely (!count)) return TRACE_RETURN (false); 6404ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod 641b5be2317201774c84470167767ad83c8637cad5bBehdad Esfahbod /* Special-case to make it in-place and not consider this 642b5be2317201774c84470167767ad83c8637cad5bBehdad Esfahbod * as a "ligated" substitution. */ 643b5be2317201774c84470167767ad83c8637cad5bBehdad Esfahbod if (unlikely (count == 1)) 644b5be2317201774c84470167767ad83c8637cad5bBehdad Esfahbod { 645b5be2317201774c84470167767ad83c8637cad5bBehdad Esfahbod c->replace_glyph (ligGlyph); 646b5be2317201774c84470167767ad83c8637cad5bBehdad Esfahbod return TRACE_RETURN (true); 647b5be2317201774c84470167767ad83c8637cad5bBehdad Esfahbod } 648b5be2317201774c84470167767ad83c8637cad5bBehdad Esfahbod 649c779d82b2fc801eec0d349a106c0e860448fcf4eBehdad Esfahbod bool is_mark_ligature = false; 650c779d82b2fc801eec0d349a106c0e860448fcf4eBehdad Esfahbod unsigned int total_component_count = 0; 651191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod 652e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod unsigned int match_length = 0; 653e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod unsigned int match_positions[MAX_CONTEXT_LENGTH]; 654e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod 655191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod if (likely (!match_input (c, count, 656191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod &component[1], 657191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod match_glyph, 658191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod NULL, 659e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod &match_length, 660e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod match_positions, 661191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod &is_mark_ligature, 662191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod &total_component_count))) 663191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod return TRACE_RETURN (false); 664cb3d34063154bf164c61eeba41c6166b0bd304fbBehdad Esfahbod 665a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod ligate_input (c, 666a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod count, 667e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod match_positions, 668e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod match_length, 669607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod ligGlyph, 670a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod is_mark_ligature, 671a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod total_component_count); 672bb3899a579b00134b24df8891b69bf1621a8190fBehdad Esfahbod 673acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (true); 674bb3899a579b00134b24df8891b69bf1621a8190fBehdad Esfahbod } 6755a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 676a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 677a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod GlyphID ligature, 678a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &components, /* Starting from second */ 679a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod unsigned int num_components /* Including first component */) 680a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod { 681be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 682a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 683fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod ligGlyph = ligature; 684a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod if (unlikely (!component.serialize (c, components, num_components))) return TRACE_RETURN (false); 685a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod return TRACE_RETURN (true); 686a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod } 687a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod 68870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod public: 689d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 690be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 6910ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (ligGlyph.sanitize (c) && component.sanitize (c)); 69270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 69370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 694ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 6955a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod GlyphID ligGlyph; /* GlyphID of ligature to substitute */ 696e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod HeadlessArrayOf<GlyphID> 697e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod component; /* Array of component GlyphIDs--start 6985a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod * with the second component--ordered 6995a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod * in writing direction */ 700b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 7010eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, component); 7025a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod}; 703a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 7044c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct LigatureSet 7054c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 7065caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c) const 707f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 708be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 709c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod unsigned int num_ligs = ligature.len; 710c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (unsigned int i = 0; i < num_ligs; i++) 7115caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod (this+ligature[i]).closure (c); 712f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 713f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 714e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 715e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 71626514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod TRACE_COLLECT_GLYPHS (this); 717e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod unsigned int num_ligs = ligature.len; 718e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod for (unsigned int i = 0; i < num_ligs; i++) 719e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod (this+ligature[i]).collect_glyphs (c); 720e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 721e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 722e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 72336608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod { 724be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 72536608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod unsigned int num_ligs = ligature.len; 72636608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod for (unsigned int i = 0; i < num_ligs; i++) 72736608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod { 72836608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod const Ligature &lig = this+ligature[i]; 729e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod if (lig.would_apply (c)) 7302005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod return TRACE_RETURN (true); 73136608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod } 7322005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod return TRACE_RETURN (false); 73336608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod } 73436608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod 73598370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 7364c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod { 737be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 738c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod unsigned int num_ligs = ligature.len; 7394c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod for (unsigned int i = 0; i < num_ligs; i++) 7404c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod { 741c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod const Ligature &lig = this+ligature[i]; 742acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (lig.apply (c)) return TRACE_RETURN (true); 743bb3899a579b00134b24df8891b69bf1621a8190fBehdad Esfahbod } 744bb3899a579b00134b24df8891b69bf1621a8190fBehdad Esfahbod 745acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (false); 746bb3899a579b00134b24df8891b69bf1621a8190fBehdad Esfahbod } 747a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 748a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 749a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &ligatures, 750a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<unsigned int> &component_count_list, 751a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod unsigned int num_ligatures, 752a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &component_list /* Starting from second for each ligature */) 753a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod { 754be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 755a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 756a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod if (unlikely (!ligature.serialize (c, num_ligatures))) return TRACE_RETURN (false); 757a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod for (unsigned int i = 0; i < num_ligatures; i++) 758a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod if (unlikely (!ligature[i].serialize (c, this).serialize (c, 759a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod ligatures[i], 760a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod component_list, 761a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod component_count_list[i]))) return TRACE_RETURN (false); 762fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod ligatures.advance (num_ligatures); 763a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod component_count_list.advance (num_ligatures); 764a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod return TRACE_RETURN (true); 765a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod } 766a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod 767d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 768be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 7690ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (ligature.sanitize (c, this)); 77070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 77170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 772ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 773c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod OffsetArrayOf<Ligature> 774c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod ligature; /* Array LigatureSet tables 775c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod * ordered by preference */ 776b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 7770eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (2, ligature); 778a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod}; 779a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 7804c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct LigatureSubstFormat1 7814c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 7825caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c) const 783f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 784be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 785c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod Coverage::Iter iter; 786c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (iter.init (this+coverage); iter.more (); iter.next ()) { 787c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod if (c->glyphs->has (iter.get_glyph ())) 7885caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod (this+ligatureSet[iter.get_coverage ()]).closure (c); 789c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 790f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 791f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 792e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 793e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 79426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod TRACE_COLLECT_GLYPHS (this); 795e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod Coverage::Iter iter; 796e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod for (iter.init (this+coverage); iter.more (); iter.next ()) { 7978303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod c->input->add (iter.get_glyph ()); 798e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod (this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c); 799e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 800e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 801e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 8020b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod inline const Coverage &get_coverage (void) const 8030b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod { 8040b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod return this+coverage; 8050b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod } 8060b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod 807e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 80836608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod { 809be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 810b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (c->glyphs[0]); 8112005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 8122005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod 8132005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod const LigatureSet &lig_set = this+ligatureSet[index]; 8142005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod return TRACE_RETURN (lig_set.would_apply (c)); 81536608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod } 81636608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod 817d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 8184c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod { 819be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 82099c2695759a6af855d565f4994bbdf220570bb48Behdad Esfahbod hb_codepoint_t glyph_id = c->buffer->cur().codepoint; 821a84e71ad11a72feff47ead16772a8c4bcf4f69d5Behdad Esfahbod 822b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (glyph_id); 823acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 824aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 825c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod const LigatureSet &lig_set = this+ligatureSet[index]; 826acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (lig_set.apply (c)); 827a84e71ad11a72feff47ead16772a8c4bcf4f69d5Behdad Esfahbod } 828a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 829a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 830a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &first_glyphs, 831a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<unsigned int> &ligature_per_first_glyph_count_list, 832a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod unsigned int num_first_glyphs, 833a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &ligatures_list, 834a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<unsigned int> &component_count_list, 835a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &component_list /* Starting from second for each ligature */) 836a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod { 837be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 838a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 839a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return TRACE_RETURN (false); 840a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod for (unsigned int i = 0; i < num_first_glyphs; i++) 841a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod if (unlikely (!ligatureSet[i].serialize (c, this).serialize (c, 842a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod ligatures_list, 843a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod component_count_list, 844a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod ligature_per_first_glyph_count_list[i], 845a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod component_list))) return TRACE_RETURN (false); 846a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod ligature_per_first_glyph_count_list.advance (num_first_glyphs); 847fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return TRACE_RETURN (false); 848a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod return TRACE_RETURN (true); 849a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod } 850a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod 851d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 852be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 8530ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this)); 85470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 85570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 856ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 857f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod USHORT format; /* Format identifier--format = 1 */ 858238c855fcd4f0ef97a94a8662d2a2f2bb5c21ecbBehdad Esfahbod OffsetTo<Coverage> 859238c855fcd4f0ef97a94a8662d2a2f2bb5c21ecbBehdad Esfahbod coverage; /* Offset to Coverage table--from 8605a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod * beginning of Substitution table */ 861d79cae0b4eef8c2694ada791bb8e427c1202875eBehdad Esfahbod OffsetArrayOf<LigatureSet> 862c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod ligatureSet; /* Array LigatureSet tables 863c9a7cbe9cb52264af9954e5ce9ac7a45d7e310cdBehdad Esfahbod * ordered by Coverage Index */ 864b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 8650eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, ligatureSet); 866a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod}; 8675a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 8684c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct LigatureSubst 8694c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 870a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 871a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &first_glyphs, 872a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<unsigned int> &ligature_per_first_glyph_count_list, 873a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod unsigned int num_first_glyphs, 874a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &ligatures_list, 875a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<unsigned int> &component_count_list, 876a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &component_list /* Starting from second for each ligature */) 877a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod { 878be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 879a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); 880a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod unsigned int format = 1; 881a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod u.format.set (format); 882a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod switch (u.format) { 883a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod case 1: return TRACE_RETURN (u.format1.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs, 884a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod ligatures_list, component_count_list, component_list)); 885a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod default:return TRACE_RETURN (false); 886a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod } 887a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod } 888a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod 889ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod template <typename context_t> 890ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 891ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod { 892ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod TRACE_DISPATCH (this); 893ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod switch (u.format) { 894ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod case 1: return TRACE_RETURN (c->dispatch (u.format1)); 895ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod default:return TRACE_RETURN (c->default_return_value ()); 896ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod } 897ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod } 898ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod 899d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 900be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 9010ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!u.format.sanitize (c)) return TRACE_RETURN (false); 90270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 9030ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 1: return TRACE_RETURN (u.format1.sanitize (c)); 9040ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod default:return TRACE_RETURN (true); 90570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 90670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 90770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 908ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 909a84e71ad11a72feff47ead16772a8c4bcf4f69d5Behdad Esfahbod union { 910f8dc67b3c24dfc805da756a73cb217b36e16b4b8Behdad Esfahbod USHORT format; /* Format identifier */ 911dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod LigatureSubstFormat1 format1; 912a84e71ad11a72feff47ead16772a8c4bcf4f69d5Behdad Esfahbod } u; 913a84e71ad11a72feff47ead16772a8c4bcf4f69d5Behdad Esfahbod}; 914a84e71ad11a72feff47ead16772a8c4bcf4f69d5Behdad Esfahbod 915a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 91608f1eede1bbc01ece2adf89847614a0670e50443Behdad Esfahbodstruct ContextSubst : Context {}; 9179f721cf380954d67415dbfd0404a983cdd75b7dfBehdad Esfahbod 91808f1eede1bbc01ece2adf89847614a0670e50443Behdad Esfahbodstruct ChainContextSubst : ChainContext {}; 9194f27ce7e0213ac5ba356f0fd2ec0a175ffd002e6Behdad Esfahbod 920653eeb26450053b731b46346606931f5ae88db72Behdad Esfahbodstruct ExtensionSubst : Extension<ExtensionSubst> 9214c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 9227dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod typedef struct SubstLookupSubTable LookupSubTable; 92370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 924a065f471b3bc23d33ef75217308efeaed4ffd033Behdad Esfahbod inline bool is_reverse (void) const; 9254f27ce7e0213ac5ba356f0fd2ec0a175ffd002e6Behdad Esfahbod}; 9264f27ce7e0213ac5ba356f0fd2ec0a175ffd002e6Behdad Esfahbod 9274f27ce7e0213ac5ba356f0fd2ec0a175ffd002e6Behdad Esfahbod 9284c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct ReverseChainSingleSubstFormat1 9294c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 9305caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c) const 931f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 932be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 933c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 934c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod 935c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod unsigned int count; 936c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod 937c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod count = backtrack.len; 938c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 939c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod if (!(this+backtrack[i]).intersects (c->glyphs)) 9405caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod return; 941c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod 942c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod count = lookahead.len; 943c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 944c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod if (!(this+lookahead[i]).intersects (c->glyphs)) 9455caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod return; 946c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod 947c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); 948c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod Coverage::Iter iter; 949c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (iter.init (this+coverage); iter.more (); iter.next ()) { 950c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod if (c->glyphs->has (iter.get_glyph ())) 9515caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod c->glyphs->add (substitute[iter.get_coverage ()]); 952c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 953f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 954f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 955e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 956e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 95726514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod TRACE_COLLECT_GLYPHS (this); 95826514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 959e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 960e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 961e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod unsigned int count; 962e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 9638303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+coverage).add_coverage (c->input); 964e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 965e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod count = backtrack.len; 966e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 9678303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+backtrack[i]).add_coverage (c->before); 968e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 969e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod count = lookahead.len; 970e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 9718303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+lookahead[i]).add_coverage (c->after); 972e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 973e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); 974e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod count = substitute.len; 975e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 9768303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod c->output->add (substitute[i]); 977e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod } 978e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 9790b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod inline const Coverage &get_coverage (void) const 9800b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod { 9810b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod return this+coverage; 9820b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod } 9830b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod 9842005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 9852005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod { 986be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 987b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); 9882005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod } 9892005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod 990d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 9914c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod { 992be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 9935df809b655bb1318115651fd87d4555cdd9b41cbBehdad Esfahbod if (unlikely (c->nesting_level_left != MAX_NESTING_LEVEL)) 9945df809b655bb1318115651fd87d4555cdd9b41cbBehdad Esfahbod return TRACE_RETURN (false); /* No chaining to this type */ 995969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod 996b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 997acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 998969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod 999e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 1000e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); 1001969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod 1002d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod if (match_backtrack (c, 1003b961518b9611471ff7060e97686e5625974847ebBehdad Esfahbod backtrack.len, (USHORT *) backtrack.array, 100440cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod match_coverage, this) && 1005d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod match_lookahead (c, 1006b961518b9611471ff7060e97686e5625974847ebBehdad Esfahbod lookahead.len, (USHORT *) lookahead.array, 100740cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod match_coverage, this, 1008969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod 1)) 1009969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod { 10107fbbf86efe675e4c038dfc5985c24bbc544620cdBehdad Esfahbod c->replace_glyph_inplace (substitute[index]); 101149901862e36e1c153835877a9f1183729333bbbeBehdad Esfahbod /* Note: We DON'T decrease buffer->idx. The main loop does it 101249901862e36e1c153835877a9f1183729333bbbeBehdad Esfahbod * for us. This is useful for preventing surprises if someone 101349901862e36e1c153835877a9f1183729333bbbeBehdad Esfahbod * calls us through a Context lookup. */ 1014acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (true); 1015969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod } 1016969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod 1017acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (false); 1018ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod } 1019a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 1020d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1021be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 10220ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) 10230ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (false); 1024e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 1025d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod if (!lookahead.sanitize (c, this)) 10260ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (false); 1027e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); 10280ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (substitute.sanitize (c)); 102970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 103070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1031ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 1032f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod USHORT format; /* Format identifier--format = 1 */ 1033969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod OffsetTo<Coverage> 1034969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod coverage; /* Offset to Coverage table--from 1035969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod * beginning of table */ 1036969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod OffsetArrayOf<Coverage> 1037969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod backtrack; /* Array of coverage tables 1038a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * in backtracking sequence, in glyph 1039a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * sequence order */ 1040969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod OffsetArrayOf<Coverage> 1041969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod lookaheadX; /* Array of coverage tables 1042969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod * in lookahead sequence, in glyph 1043a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod * sequence order */ 1044969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod ArrayOf<GlyphID> 1045969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod substituteX; /* Array of substitute 1046969afd706e9b52adc79f6210c0088b2c6bbae9bcBehdad Esfahbod * GlyphIDs--ordered by Coverage Index */ 1047b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 1048bea34c7cbb583cf7660776e95cab3171590b8427Behdad Esfahbod DEFINE_SIZE_MIN (10); 1049a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod}; 1050a16ecbf0564a6e2576da22c12827f3c0719da549Behdad Esfahbod 10514c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct ReverseChainSingleSubst 10524c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 105344fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod template <typename context_t> 10549c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 1055e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 10569c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod TRACE_DISPATCH (this); 1057e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod switch (u.format) { 10589c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case 1: return TRACE_RETURN (c->dispatch (u.format1)); 1059f48ec0e83432c038b50d9715a38ba1469e82e1e4Behdad Esfahbod default:return TRACE_RETURN (c->default_return_value ()); 10600b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod } 10610b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod } 10620b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod 1063d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1064be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 10650ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!u.format.sanitize (c)) return TRACE_RETURN (false); 106670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 10670ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 1: return TRACE_RETURN (u.format1.sanitize (c)); 10680ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod default:return TRACE_RETURN (true); 106970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 107070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 107170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1072ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 1073ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod union { 1074ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod USHORT format; /* Format identifier */ 1075dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ReverseChainSingleSubstFormat1 format1; 1076ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod } u; 1077ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 1078ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 1079ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 1080ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 10817586089c6fa8185cad8387869d3703c637e5cbb1Behdad Esfahbod/* 10822d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod * SubstLookup 10832d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod */ 10842d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 10854c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct SubstLookupSubTable 10864c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 10872d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod friend struct SubstLookup; 10882d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 1089c6035cf802c60f0526f421f39a55886061df94eeBehdad Esfahbod enum Type { 1090ff05d257dd43221b7c8ebead188e78495daa8edaBehdad Esfahbod Single = 1, 1091ff05d257dd43221b7c8ebead188e78495daa8edaBehdad Esfahbod Multiple = 2, 1092ff05d257dd43221b7c8ebead188e78495daa8edaBehdad Esfahbod Alternate = 3, 1093ff05d257dd43221b7c8ebead188e78495daa8edaBehdad Esfahbod Ligature = 4, 1094ff05d257dd43221b7c8ebead188e78495daa8edaBehdad Esfahbod Context = 5, 1095ff05d257dd43221b7c8ebead188e78495daa8edaBehdad Esfahbod ChainContext = 6, 1096ff05d257dd43221b7c8ebead188e78495daa8edaBehdad Esfahbod Extension = 7, 10978f034d5849627ee95a5889fa34c9ba294fff13caBehdad Esfahbod ReverseChainSingle = 8 1098ff05d257dd43221b7c8ebead188e78495daa8edaBehdad Esfahbod }; 1099ff05d257dd43221b7c8ebead188e78495daa8edaBehdad Esfahbod 110044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod template <typename context_t> 11019c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const 1102f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 11039c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod TRACE_DISPATCH (this); 1104f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod switch (lookup_type) { 11059c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case Single: return TRACE_RETURN (u.single.dispatch (c)); 11069c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case Multiple: return TRACE_RETURN (u.multiple.dispatch (c)); 11079c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case Alternate: return TRACE_RETURN (u.alternate.dispatch (c)); 11089c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case Ligature: return TRACE_RETURN (u.ligature.dispatch (c)); 11099c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case Context: return TRACE_RETURN (u.context.dispatch (c)); 11109c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c)); 11119c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case Extension: return TRACE_RETURN (u.extension.dispatch (c)); 11129c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.dispatch (c)); 1113f48ec0e83432c038b50d9715a38ba1469e82e1e4Behdad Esfahbod default: return TRACE_RETURN (c->default_return_value ()); 1114e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1115e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1116e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1117d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { 1118be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 11190b99429ead05ae32b3c210cb499af401b02770a9Behdad Esfahbod if (!u.header.sub_format.sanitize (c)) 1120faf0f20253d954cc4cfa4c967ece7573a5ddae3bBehdad Esfahbod return TRACE_RETURN (false); 1121fe9bc070e1d545b0df2ea548eebf5a1fc4c92ddcBehdad Esfahbod switch (lookup_type) { 11220ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case Single: return TRACE_RETURN (u.single.sanitize (c)); 11230ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case Multiple: return TRACE_RETURN (u.multiple.sanitize (c)); 11240ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case Alternate: return TRACE_RETURN (u.alternate.sanitize (c)); 11250ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case Ligature: return TRACE_RETURN (u.ligature.sanitize (c)); 1126e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod case Context: return TRACE_RETURN (u.context.sanitize (c)); 11270ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c)); 11280ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case Extension: return TRACE_RETURN (u.extension.sanitize (c)); 11290ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.sanitize (c)); 11300ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod default: return TRACE_RETURN (true); 113170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 113270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 113370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1134ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 11352d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod union { 1136993c51915f503f74ee00eee646b67bf2e3f73596Behdad Esfahbod struct { 1137993c51915f503f74ee00eee646b67bf2e3f73596Behdad Esfahbod USHORT sub_format; 1138993c51915f503f74ee00eee646b67bf2e3f73596Behdad Esfahbod } header; 1139dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod SingleSubst single; 1140dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod MultipleSubst multiple; 1141dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod AlternateSubst alternate; 1142dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod LigatureSubst ligature; 1143e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod ContextSubst context; 1144dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ChainContextSubst chainContext; 1145dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ExtensionSubst extension; 1146dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ReverseChainSingleSubst reverseChainContextSingle; 11472d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod } u; 1148ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod public: 1149993c51915f503f74ee00eee646b67bf2e3f73596Behdad Esfahbod DEFINE_SIZE_UNION (2, header.sub_format); 11502d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod}; 11512d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 11524f27ce7e0213ac5ba356f0fd2ec0a175ffd002e6Behdad Esfahbod 11534c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct SubstLookup : Lookup 11544c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 11556d08c7f1b3601095f9a12630045331dd0fe75380Behdad Esfahbod inline const SubstLookupSubTable& get_subtable (unsigned int i) const 11566d08c7f1b3601095f9a12630045331dd0fe75380Behdad Esfahbod { return this+CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i]; } 11572d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 1158a065f471b3bc23d33ef75217308efeaed4ffd033Behdad Esfahbod inline static bool lookup_type_is_reverse (unsigned int lookup_type) 11596d08c7f1b3601095f9a12630045331dd0fe75380Behdad Esfahbod { return lookup_type == SubstLookupSubTable::ReverseChainSingle; } 1160a065f471b3bc23d33ef75217308efeaed4ffd033Behdad Esfahbod 1161a065f471b3bc23d33ef75217308efeaed4ffd033Behdad Esfahbod inline bool is_reverse (void) const 11624c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod { 11632d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod unsigned int type = get_type (); 11646d08c7f1b3601095f9a12630045331dd0fe75380Behdad Esfahbod if (unlikely (type == SubstLookupSubTable::Extension)) 1165187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbod return CastR<ExtensionSubst> (get_subtable(0)).is_reverse (); 1166a065f471b3bc23d33ef75217308efeaed4ffd033Behdad Esfahbod return lookup_type_is_reverse (type); 11672d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod } 11682e0c44f4bedd3e24c731c0e9e23358e9a4891a35Behdad Esfahbod 11699b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const 11709b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod { 117126514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod TRACE_CLOSURE (this); 11729c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>); 11739c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod return TRACE_RETURN (dispatch (c)); 117426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 117526514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 1176780cd930a974165d76dbf7a87701d11b7f15db06Behdad Esfahbod inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const 117726514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 117826514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod TRACE_COLLECT_GLYPHS (this); 11799c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>); 11809c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod return TRACE_RETURN (dispatch (c)); 11819b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod } 11829b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod 1183a878c58a8fc1500986d713b2bcedfeb90a0087b0Behdad Esfahbod template <typename set_t> 1184a878c58a8fc1500986d713b2bcedfeb90a0087b0Behdad Esfahbod inline void add_coverage (set_t *glyphs) const 1185a878c58a8fc1500986d713b2bcedfeb90a0087b0Behdad Esfahbod { 11862005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod hb_get_coverage_context_t c; 1187a878c58a8fc1500986d713b2bcedfeb90a0087b0Behdad Esfahbod const Coverage *last = NULL; 1188a878c58a8fc1500986d713b2bcedfeb90a0087b0Behdad Esfahbod unsigned int count = get_subtable_count (); 1189a878c58a8fc1500986d713b2bcedfeb90a0087b0Behdad Esfahbod for (unsigned int i = 0; i < count; i++) { 11909c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ()); 11912005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod if (coverage != last) { 11922005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod coverage->add_coverage (glyphs); 11932005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod last = coverage; 1194a878c58a8fc1500986d713b2bcedfeb90a0087b0Behdad Esfahbod } 1195a878c58a8fc1500986d713b2bcedfeb90a0087b0Behdad Esfahbod } 1196a878c58a8fc1500986d713b2bcedfeb90a0087b0Behdad Esfahbod } 1197a878c58a8fc1500986d713b2bcedfeb90a0087b0Behdad Esfahbod 11982bd9fe359839a653f7caae534bf768af1735f155Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c, const hb_set_digest_t *digest) const 119936608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod { 1200be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 12012005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod if (unlikely (!c->len)) return TRACE_RETURN (false); 12022005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod if (!digest->may_have (c->glyphs[0])) return TRACE_RETURN (false); 12039c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod return TRACE_RETURN (dispatch (c)); 120436608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod } 120536608941f3cc530fea57282fa175e4cc3b4c66c6Behdad Esfahbod 120641ae674f6871f43d0a6e4ca67a747074d63ae576Behdad Esfahbod inline bool apply_once (hb_apply_context_t *c) const 12074c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod { 120826514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod TRACE_APPLY (this); 1209407fc12466ef460d0edf11b89f0d04c4d724875fBehdad Esfahbod if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) 121026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod return TRACE_RETURN (false); 12119c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod return TRACE_RETURN (dispatch (c)); 12122d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod } 12135a0b791184cf6ef39eae0570e14aca21abc32845Behdad Esfahbod 1214ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); 121529d8644a315ebe6976f15db2fe96069376d9b8cdBehdad Esfahbod 1216b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c, 1217b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod unsigned int i) 1218b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod { return CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i].serialize (c, this); } 1219b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod 1220b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod inline bool serialize_single (hb_serialize_context_t *c, 1221b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod uint32_t lookup_props, 1222b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<GlyphID> &glyphs, 1223b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<GlyphID> &substitutes, 1224b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod unsigned int num_glyphs) 1225b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod { 1226be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 1227b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Single, lookup_props, 1))) return TRACE_RETURN (false); 1228b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod return TRACE_RETURN (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes, num_glyphs)); 1229b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod } 1230b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod 1231b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod inline bool serialize_multiple (hb_serialize_context_t *c, 1232b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod uint32_t lookup_props, 1233b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<GlyphID> &glyphs, 1234b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<unsigned int> &substitute_len_list, 1235b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod unsigned int num_glyphs, 1236b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<GlyphID> &substitute_glyphs_list) 1237b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod { 1238be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 1239b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Multiple, lookup_props, 1))) return TRACE_RETURN (false); 1240b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod return TRACE_RETURN (serialize_subtable (c, 0).u.multiple.serialize (c, glyphs, substitute_len_list, num_glyphs, 1241b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod substitute_glyphs_list)); 1242b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod } 1243b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod 1244b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod inline bool serialize_alternate (hb_serialize_context_t *c, 1245b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod uint32_t lookup_props, 1246b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<GlyphID> &glyphs, 1247b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<unsigned int> &alternate_len_list, 1248b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod unsigned int num_glyphs, 1249b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<GlyphID> &alternate_glyphs_list) 1250b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod { 1251be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 1252b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Alternate, lookup_props, 1))) return TRACE_RETURN (false); 1253b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod return TRACE_RETURN (serialize_subtable (c, 0).u.alternate.serialize (c, glyphs, alternate_len_list, num_glyphs, 1254b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod alternate_glyphs_list)); 1255b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod } 1256b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod 1257b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod inline bool serialize_ligature (hb_serialize_context_t *c, 1258b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod uint32_t lookup_props, 1259b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<GlyphID> &first_glyphs, 1260b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<unsigned int> &ligature_per_first_glyph_count_list, 1261b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod unsigned int num_first_glyphs, 1262b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<GlyphID> &ligatures_list, 1263b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<unsigned int> &component_count_list, 1264b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod Supplier<GlyphID> &component_list /* Starting from second for each ligature */) 1265b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod { 1266be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 1267b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Ligature, lookup_props, 1))) return TRACE_RETURN (false); 1268b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod return TRACE_RETURN (serialize_subtable (c, 0).u.ligature.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs, 1269b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod ligatures_list, component_count_list, component_list)); 1270b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod } 1271b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod 1272ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod template <typename context_t> 1273ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); 1274ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod 1275ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod template <typename context_t> 1276ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 1277ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod { 1278ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod TRACE_DISPATCH (this); 1279ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod unsigned int lookup_type = get_type (); 1280ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod unsigned int count = get_subtable_count (); 1281ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod for (unsigned int i = 0; i < count; i++) { 1282ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type); 1283ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod if (c->stop_sublookup_iteration (r)) 1284ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod return TRACE_RETURN (r); 1285ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod } 1286ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod return TRACE_RETURN (c->default_return_value ()); 1287ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod } 1288ee5464d17fa4c59f5adaaa13dde70dd5264dbc64Behdad Esfahbod 1289b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) 1290b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod { 1291be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 12920ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); 12936d08c7f1b3601095f9a12630045331dd0fe75380Behdad Esfahbod OffsetArrayOf<SubstLookupSubTable> &list = CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable); 1294338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod if (unlikely (!list.sanitize (c, this, get_type ()))) return TRACE_RETURN (false); 1295338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod 1296338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod if (unlikely (get_type () == SubstLookupSubTable::Extension)) 1297338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod { 1298338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod /* The spec says all subtables of an Extension lookup should 1299338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod * have the same type. This is specially important if one has 130099fa9ea020f26ed2697f38a7690ee1e1b5d946c4Behdad Esfahbod * a reverse type! */ 1301338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod unsigned int type = get_subtable (0).u.extension.get_type (); 1302338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod unsigned int count = get_subtable_count (); 1303338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod for (unsigned int i = 1; i < count; i++) 1304338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod if (get_subtable (i).u.extension.get_type () != type) 1305338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod return TRACE_RETURN (false); 1306338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod } 1307338fe662b50f9309bf0050dd99becb644874195bBehdad Esfahbod return TRACE_RETURN (true); 130829d8644a315ebe6976f15db2fe96069376d9b8cdBehdad Esfahbod } 13092d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod}; 13102d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 131129d8644a315ebe6976f15db2fe96069376d9b8cdBehdad Esfahbodtypedef OffsetListOf<SubstLookup> SubstLookupList; 1312c43562b2a7587fa3f9ef4c1c4338e4eda77368b5Behdad Esfahbod 13132d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod/* 1314ae9877dea6a1aed3566d9b87a75ede84259deacaBehdad Esfahbod * GSUB -- The Glyph Substitution Table 13157586089c6fa8185cad8387869d3703c637e5cbb1Behdad Esfahbod */ 13167586089c6fa8185cad8387869d3703c637e5cbb1Behdad Esfahbod 13174c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbodstruct GSUB : GSUBGPOS 13184c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 13196c48f20eea22c6e686416ab4ec8388be3e8cd0b5Behdad Esfahbod static const hb_tag_t tableTag = HB_OT_TAG_GSUB; 13207586089c6fa8185cad8387869d3703c637e5cbb1Behdad Esfahbod 13214c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod inline const SubstLookup& get_lookup (unsigned int i) const 1322187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbod { return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); } 13232d15e72c75931398db5e027e660f1320bb979117Behdad Esfahbod 1324afbcc24be01a64bdb5c05c63880269145fa1d3c8Behdad Esfahbod static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer); 1325afbcc24be01a64bdb5c05c63880269145fa1d3c8Behdad Esfahbod static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer); 1326a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 1327d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1328be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 13290ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); 1330187454c595559ce48d072fee6bccb51f3de283d4Behdad Esfahbod OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList); 13310ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (list.sanitize (c, this)); 133229d8644a315ebe6976f15db2fe96069376d9b8cdBehdad Esfahbod } 1333b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 1334b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod DEFINE_SIZE_STATIC (10); 13357586089c6fa8185cad8387869d3703c637e5cbb1Behdad Esfahbod}; 1336c43562b2a7587fa3f9ef4c1c4338e4eda77368b5Behdad Esfahbod 1337c43562b2a7587fa3f9ef4c1c4338e4eda77368b5Behdad Esfahbod 1338a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbodvoid 1339afbcc24be01a64bdb5c05c63880269145fa1d3c8Behdad EsfahbodGSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer) 1340a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod{ 1341101303dbf7cf15d044bf2518f14b3aec65970feaBehdad Esfahbod _hb_buffer_allocate_gsubgpos_vars (buffer); 1342b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod 1343afbcc24be01a64bdb5c05c63880269145fa1d3c8Behdad Esfahbod const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef; 1344a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod unsigned int count = buffer->len; 1345101303dbf7cf15d044bf2518f14b3aec65970feaBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 1346101303dbf7cf15d044bf2518f14b3aec65970feaBehdad Esfahbod { 134791689de2603e4151e2a2d3a3852c61667f0c6264Behdad Esfahbod _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint)); 1348101303dbf7cf15d044bf2518f14b3aec65970feaBehdad Esfahbod _hb_glyph_info_clear_lig_props (&buffer->info[i]); 1349101303dbf7cf15d044bf2518f14b3aec65970feaBehdad Esfahbod buffer->info[i].syllable() = 0; 135005bd1b63426e07d1df7a1b40bf845dc94ab995a8Behdad Esfahbod } 1351a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod} 1352a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 1353a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbodvoid 1354afbcc24be01a64bdb5c05c63880269145fa1d3c8Behdad EsfahbodGSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED) 1355a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod{ 1356a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod} 1357a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 1358a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod 1359887c4b44165eeb8ac7fb09bc4474d11720b94a9eBehdad Esfahbod/* Out-of-class implementation for methods recursing */ 1360c43562b2a7587fa3f9ef4c1c4338e4eda77368b5Behdad Esfahbod 13616faff8e4132197ba06f0e685b82efe35b546cf64Behdad Esfahbod/*static*/ inline bool ExtensionSubst::is_reverse (void) const 1362a065f471b3bc23d33ef75217308efeaed4ffd033Behdad Esfahbod{ 1363a065f471b3bc23d33ef75217308efeaed4ffd033Behdad Esfahbod unsigned int type = get_type (); 13646d08c7f1b3601095f9a12630045331dd0fe75380Behdad Esfahbod if (unlikely (type == SubstLookupSubTable::Extension)) 13657dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod return CastR<ExtensionSubst> (get_subtable<SubstLookupSubTable>()).is_reverse (); 1366a065f471b3bc23d33ef75217308efeaed4ffd033Behdad Esfahbod return SubstLookup::lookup_type_is_reverse (type); 1367a065f471b3bc23d33ef75217308efeaed4ffd033Behdad Esfahbod} 1368a065f471b3bc23d33ef75217308efeaed4ffd033Behdad Esfahbod 1369c6fb843f2a1c26322c6f4c85d1589f01a9e7a2efBehdad Esfahbodtemplate <typename context_t> 13706faff8e4132197ba06f0e685b82efe35b546cf64Behdad Esfahbod/*static*/ inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) 13719b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod{ 13729b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub); 13739b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod const SubstLookup &l = gsub.get_lookup (lookup_index); 13749c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod return l.dispatch (c); 13759b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod} 13769b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod 13776faff8e4132197ba06f0e685b82efe35b546cf64Behdad Esfahbod/*static*/ inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index) 13784c44d830d79431fcb143df2b5a29cdc8e8fccef3Behdad Esfahbod{ 1379ea278d3895fe0c92801d692cd71d8d9f1de7c048Behdad Esfahbod const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub); 1380a1625528cd5ed94bc8f18903da3300e823ee5b54Behdad Esfahbod const SubstLookup &l = gsub.get_lookup (lookup_index); 13814c4e8f0e754b79ac6190d21878eaaf0b790c7579Behdad Esfahbod unsigned int saved_lookup_props = c->lookup_props; 1382ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod c->set_lookup (l); 13834c4e8f0e754b79ac6190d21878eaaf0b790c7579Behdad Esfahbod bool ret = l.apply_once (c); 13844c4e8f0e754b79ac6190d21878eaaf0b790c7579Behdad Esfahbod c->lookup_props = saved_lookup_props; 13854c4e8f0e754b79ac6190d21878eaaf0b790c7579Behdad Esfahbod return ret; 1386c43562b2a7587fa3f9ef4c1c4338e4eda77368b5Behdad Esfahbod} 1387c43562b2a7587fa3f9ef4c1c4338e4eda77368b5Behdad Esfahbod 1388c43562b2a7587fa3f9ef4c1c4338e4eda77368b5Behdad Esfahbod 13897d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod} /* namespace OT */ 13907c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 1391acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 13927a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#endif /* HB_OT_LAYOUT_GSUB_TABLE_HH */ 1393