166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod/* 22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2007,2008,2009,2010 Red Hat, Inc. 35b93e8d94fb4c2474816304ae3f52e1c704882deBehdad Esfahbod * Copyright © 2010,2012 Google, Inc. 466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * 5c755cb3e3ac55156d0d2ec05adea7a650b97cc41Behdad Esfahbod * This is part of HarfBuzz, a text shaping library. 666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * 766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * Permission is hereby granted, without written agreement and without 866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * software and its documentation for any purpose, provided that the 1066bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * above copyright notice and the following two paragraphs appear in 1166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * all copies of this software. 1266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * 1366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 1466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 1566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 1666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 1766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * DAMAGE. 1866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * 1966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 2066bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 2166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 2266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 2366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 2466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * 2566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * Red Hat Author(s): Behdad Esfahbod 2698370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod * Google Author(s): Behdad Esfahbod 2766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod */ 2866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 295f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#ifndef HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH 305f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#define HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH 3166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 3240ec3bbb55b8af1668bb3d5f6232a85b15cff136Behdad Esfahbod#include "hb-private.hh" 3340ec3bbb55b8af1668bb3d5f6232a85b15cff136Behdad Esfahbod#include "hb-debug.hh" 3422da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod#include "hb-buffer-private.hh" 357a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#include "hb-ot-layout-gdef-table.hh" 361336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod#include "hb-set-private.hh" 37f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 3866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 397c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodnamespace OT { 407c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 41acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 4277a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbodstruct hb_closure_context_t : 4377a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbod hb_dispatch_context_t<hb_closure_context_t, hb_void_t, HB_DEBUG_CLOSURE> 44f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod{ 45a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod inline const char *get_name (void) { return "CLOSURE"; } 4644fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); 4744fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod template <typename T> 489c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; } 49130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod static return_t default_return_value (void) { return HB_VOID; } 507b912c1936c3e8a7df27a30782ca127d0a83822dBehdad Esfahbod bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } 5144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod return_t recurse (unsigned int lookup_index) 5244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 539b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod if (unlikely (nesting_level_left == 0 || !recurse_func)) 542005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod return default_return_value (); 5544fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 5644fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod nesting_level_left--; 5744fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod recurse_func (this, lookup_index); 5844fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod nesting_level_left++; 59130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod return HB_VOID; 6044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 6144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 62f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod hb_face_t *face; 636a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod hb_set_t *glyphs; 6444fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod recurse_func_t recurse_func; 65f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod unsigned int nesting_level_left; 66f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod unsigned int debug_depth; 67f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 68f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod hb_closure_context_t (hb_face_t *face_, 696a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod hb_set_t *glyphs_, 705ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : 71e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod face (face_), 72e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod glyphs (glyphs_), 73dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod recurse_func (nullptr), 74f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod nesting_level_left (nesting_level_left_), 75f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod debug_depth (0) {} 769b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod 779b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod void set_recurse_func (recurse_func_t func) { recurse_func = func; } 78f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod}; 79f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 80f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 8177a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbodstruct hb_would_apply_context_t : 8277a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbod hb_dispatch_context_t<hb_would_apply_context_t, bool, HB_DEBUG_WOULD_APPLY> 83e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod{ 84a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod inline const char *get_name (void) { return "WOULD_APPLY"; } 851d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod template <typename T> 869c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline return_t dispatch (const T &obj) { return obj.would_apply (this); } 871d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod static return_t default_return_value (void) { return false; } 887b912c1936c3e8a7df27a30782ca127d0a83822dBehdad Esfahbod bool stop_sublookup_iteration (return_t r) const { return r; } 891d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod 90e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod hb_face_t *face; 91472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod const hb_codepoint_t *glyphs; 92e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int len; 93d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod bool zero_context; 94e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int debug_depth; 95e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 96e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod hb_would_apply_context_t (hb_face_t *face_, 97472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod const hb_codepoint_t *glyphs_, 98472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod unsigned int len_, 992bd9fe359839a653f7caae534bf768af1735f155Behdad Esfahbod bool zero_context_) : 100e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod face (face_), 101472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod glyphs (glyphs_), 102472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod len (len_), 103d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod zero_context (zero_context_), 104a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod debug_depth (0) {} 105e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod}; 106e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 107e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 10877a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbodstruct hb_collect_glyphs_context_t : 10977a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbod hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, HB_DEBUG_COLLECT_GLYPHS> 110e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod{ 111a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod inline const char *get_name (void) { return "COLLECT_GLYPHS"; } 11226514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); 1131d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod template <typename T> 1149c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; } 115130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod static return_t default_return_value (void) { return HB_VOID; } 1167b912c1936c3e8a7df27a30782ca127d0a83822dBehdad Esfahbod bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } 1171d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod return_t recurse (unsigned int lookup_index) 1181d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod { 11926514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod if (unlikely (nesting_level_left == 0 || !recurse_func)) 12026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod return default_return_value (); 12126514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 122dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod /* Note that GPOS sets recurse_func to nullptr already, so it doesn't get 1231bcfa06d1173f219809542a7380ce77f1c907becBehdad Esfahbod * past the previous check. For GSUB, we only want to collect the output 12476ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod * glyphs in the recursion. If output is not requested, we can go home now. 12576ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod * 12676ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod * Note further, that the above is not exactly correct. A recursed lookup 12776ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod * is allowed to match input that is not matched in the context, but that's 12876ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod * not how most fonts are built. It's possible to relax that and recurse 12976ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod * with all sets here if it proves to be an issue. 13076ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod */ 1314a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod 1324a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod if (output == hb_set_get_empty ()) 133130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod return HB_VOID; 1344a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod 135fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod /* Return if new lookup was recursed to before. */ 1368b9d9b71b04c9d5698ec146658b31381060c700dBehdad Esfahbod if (recursed_lookups->has (lookup_index)) 137fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod return HB_VOID; 138fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod 1394a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod hb_set_t *old_before = before; 1404a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod hb_set_t *old_input = input; 1414a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod hb_set_t *old_after = after; 1424a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod before = input = after = hb_set_get_empty (); 1431bcfa06d1173f219809542a7380ce77f1c907becBehdad Esfahbod 14426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod nesting_level_left--; 1454a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod recurse_func (this, lookup_index); 14626514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod nesting_level_left++; 1474a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod 1484a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod before = old_before; 1494a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod input = old_input; 1504a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod after = old_after; 1514a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod 1528b9d9b71b04c9d5698ec146658b31381060c700dBehdad Esfahbod recursed_lookups->add (lookup_index); 153fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod 154130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod return HB_VOID; 1551d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod } 1561d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod 157e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_face_t *face; 1588303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod hb_set_t *before; 1598303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod hb_set_t *input; 1608303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod hb_set_t *after; 1618303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod hb_set_t *output; 16226514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod recurse_func_t recurse_func; 1638b9d9b71b04c9d5698ec146658b31381060c700dBehdad Esfahbod hb_set_t *recursed_lookups; 16426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod unsigned int nesting_level_left; 165e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod unsigned int debug_depth; 166e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 167e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_collect_glyphs_context_t (hb_face_t *face_, 168dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod hb_set_t *glyphs_before, /* OUT. May be nullptr */ 169dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod hb_set_t *glyphs_input, /* OUT. May be nullptr */ 170dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod hb_set_t *glyphs_after, /* OUT. May be nullptr */ 171dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod hb_set_t *glyphs_output, /* OUT. May be nullptr */ 1725ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : 173e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod face (face_), 1748303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod before (glyphs_before ? glyphs_before : hb_set_get_empty ()), 1758303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod input (glyphs_input ? glyphs_input : hb_set_get_empty ()), 1768303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod after (glyphs_after ? glyphs_after : hb_set_get_empty ()), 1778303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod output (glyphs_output ? glyphs_output : hb_set_get_empty ()), 178dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod recurse_func (nullptr), 1798b9d9b71b04c9d5698ec146658b31381060c700dBehdad Esfahbod recursed_lookups (nullptr), 18026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod nesting_level_left (nesting_level_left_), 181fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod debug_depth (0) 182fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod { 1838b9d9b71b04c9d5698ec146658b31381060c700dBehdad Esfahbod recursed_lookups = hb_set_create (); 184fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod } 185fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod ~hb_collect_glyphs_context_t (void) 186fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod { 1878b9d9b71b04c9d5698ec146658b31381060c700dBehdad Esfahbod hb_set_destroy (recursed_lookups); 188fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod } 18926514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 19026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod void set_recurse_func (recurse_func_t func) { recurse_func = func; } 191e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod}; 192e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 193e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 194e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 19577a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbod/* XXX Can we remove this? */ 19677a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbod 1978e36ccfd4f076888076ca176c055c18104af03b6Behdad Esfahbodtemplate <typename set_t> 19877a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbodstruct hb_add_coverage_context_t : 19977a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbod hb_dispatch_context_t<hb_add_coverage_context_t<set_t>, const Coverage &, HB_DEBUG_GET_COVERAGE> 2002005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod{ 201a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod inline const char *get_name (void) { return "GET_COVERAGE"; } 2022005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod typedef const Coverage &return_t; 2032005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod template <typename T> 2049c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline return_t dispatch (const T &obj) { return obj.get_coverage (); } 205a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod static return_t default_return_value (void) { return Null(Coverage); } 2068e36ccfd4f076888076ca176c055c18104af03b6Behdad Esfahbod bool stop_sublookup_iteration (return_t r) const 2078e36ccfd4f076888076ca176c055c18104af03b6Behdad Esfahbod { 2088e36ccfd4f076888076ca176c055c18104af03b6Behdad Esfahbod r.add_coverage (set); 2098e36ccfd4f076888076ca176c055c18104af03b6Behdad Esfahbod return false; 2108e36ccfd4f076888076ca176c055c18104af03b6Behdad Esfahbod } 2111d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod 2128e36ccfd4f076888076ca176c055c18104af03b6Behdad Esfahbod hb_add_coverage_context_t (set_t *set_) : 2138e36ccfd4f076888076ca176c055c18104af03b6Behdad Esfahbod set (set_), 214a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod debug_depth (0) {} 215a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod 2168e36ccfd4f076888076ca176c055c18104af03b6Behdad Esfahbod set_t *set; 217a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod unsigned int debug_depth; 2182005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod}; 2192005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod 2202005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod 22177a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbodstruct hb_apply_context_t : 22277a1a2bc18e7b04d4e352a8777ccce345b2f8659Behdad Esfahbod hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY> 2231376fb7bf9ef07970f0ba13dc64d6a8ab8252762Behdad Esfahbod{ 224607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod struct matcher_t 2254ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 226607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline matcher_t (void) : 227607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod lookup_props (0), 228cfc507c5432e6327e8484b07b9e091212653bc92Behdad Esfahbod ignore_zwnj (false), 229cfc507c5432e6327e8484b07b9e091212653bc92Behdad Esfahbod ignore_zwj (false), 230607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod mask (-1), 231607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */ 232607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod syllable arg1(0), 233607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod#undef arg1 234dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod match_func (nullptr), 235dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod match_data (nullptr) {}; 236607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 2376f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const UINT16 &value, const void *data); 238607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 239607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } 2400b45479198d61d5135dad771e9c68408eb13f930Behdad Esfahbod inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } 241607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } 242607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_mask (hb_mask_t mask_) { mask = mask_; } 243607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_syllable (uint8_t syllable_) { syllable = syllable_; } 244607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_match_func (match_func_t match_func_, 245607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const void *match_data_) 246607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod { match_func = match_func_; match_data = match_data_; } 247607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 2482b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod enum may_match_t { 2492b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod MATCH_NO, 2502b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod MATCH_YES, 2512b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod MATCH_MAYBE 2522b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod }; 2532b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod 2542b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod inline may_match_t may_match (const hb_glyph_info_t &info, 2556f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 *glyph_data) const 2564ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 2572b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod if (!(info.mask & mask) || 2582b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod (syllable && syllable != info.syllable ())) 2592b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod return MATCH_NO; 2602b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod 2612b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod if (match_func) 2622b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO; 2632b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod 2642b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod return MATCH_MAYBE; 2654ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod } 266607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 267607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod enum may_skip_t { 268607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod SKIP_NO, 269607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod SKIP_YES, 270607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod SKIP_MAYBE 271607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod }; 272607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 273607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline may_skip_t 274607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod may_skip (const hb_apply_context_t *c, 275607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const hb_glyph_info_t &info) const 276c074ebc466dcc9bcc0d8a5dd7e942dea974ff718Behdad Esfahbod { 277b98c5db32d15fcfb27ce2f6737203ce1ad124319Behdad Esfahbod if (!c->check_glyph_property (&info, lookup_props)) 278607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return SKIP_YES; 279607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 28006cfe3f7369684fc05fa16da7f6778350f8bcba5Khaled Hosny if (unlikely (_hb_glyph_info_is_default_ignorable_and_not_hidden (&info) && 2810b45479198d61d5135dad771e9c68408eb13f930Behdad Esfahbod (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && 2824ba796b26ee62de0d2830a550f3aa3b4aecf6f59Behdad Esfahbod (ignore_zwj || !_hb_glyph_info_is_zwj (&info)))) 283607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return SKIP_MAYBE; 284607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 285607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return SKIP_NO; 286c074ebc466dcc9bcc0d8a5dd7e942dea974ff718Behdad Esfahbod } 287607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 288607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod protected: 289607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod unsigned int lookup_props; 290607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod bool ignore_zwnj; 2910b45479198d61d5135dad771e9c68408eb13f930Behdad Esfahbod bool ignore_zwj; 292607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod hb_mask_t mask; 293607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod uint8_t syllable; 294607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_func_t match_func; 295607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const void *match_data; 296607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod }; 297607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 298696266981df5ef6c62ad0115133dad1d6c1d9accBehdad Esfahbod struct skipping_iterator_t 299607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod { 300514564f5444b8ad2f210b1e3d7d66378f7275317Behdad Esfahbod inline void init (hb_apply_context_t *c_, bool context_match = false) 3014ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 302514564f5444b8ad2f210b1e3d7d66378f7275317Behdad Esfahbod c = c_; 303dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod match_glyph_data = nullptr; 304dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod matcher.set_match_func (nullptr, nullptr); 305607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod matcher.set_lookup_props (c->lookup_props); 306a8cf7b43fa795150ae3d42d64424bb6e0373d0b2Behdad Esfahbod /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ 307cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj)); 308a8cf7b43fa795150ae3d42d64424bb6e0373d0b2Behdad Esfahbod /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ 309cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod matcher.set_ignore_zwj (c->table_index == 1 || (context_match || c->auto_zwj)); 310514564f5444b8ad2f210b1e3d7d66378f7275317Behdad Esfahbod matcher.set_mask (context_match ? -1 : c->lookup_mask); 311514564f5444b8ad2f210b1e3d7d66378f7275317Behdad Esfahbod } 312514564f5444b8ad2f210b1e3d7d66378f7275317Behdad Esfahbod inline void set_lookup_props (unsigned int lookup_props) 313514564f5444b8ad2f210b1e3d7d66378f7275317Behdad Esfahbod { 314514564f5444b8ad2f210b1e3d7d66378f7275317Behdad Esfahbod matcher.set_lookup_props (lookup_props); 3154ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod } 3164a6b1eedbb0044b57505eea65a329d2dc4f9f917Behdad Esfahbod inline void set_match_func (matcher_t::match_func_t match_func_, 3174a6b1eedbb0044b57505eea65a329d2dc4f9f917Behdad Esfahbod const void *match_data_, 3186f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 glyph_data[]) 3197b84c536c10ab90ed96a033d88e9ad232d46c5b8Behdad Esfahbod { 3204a6b1eedbb0044b57505eea65a329d2dc4f9f917Behdad Esfahbod matcher.set_match_func (match_func_, match_data_); 321607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_glyph_data = glyph_data; 3227b84c536c10ab90ed96a033d88e9ad232d46c5b8Behdad Esfahbod } 323607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 324b051be542a8945ec14b0192bbc285f3e1a78c8f1Behdad Esfahbod inline void reset (unsigned int start_index_, 325b051be542a8945ec14b0192bbc285f3e1a78c8f1Behdad Esfahbod unsigned int num_items_) 326b051be542a8945ec14b0192bbc285f3e1a78c8f1Behdad Esfahbod { 327b051be542a8945ec14b0192bbc285f3e1a78c8f1Behdad Esfahbod idx = start_index_; 328b051be542a8945ec14b0192bbc285f3e1a78c8f1Behdad Esfahbod num_items = num_items_; 329b051be542a8945ec14b0192bbc285f3e1a78c8f1Behdad Esfahbod end = c->buffer->len; 330b051be542a8945ec14b0192bbc285f3e1a78c8f1Behdad Esfahbod matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); 331b051be542a8945ec14b0192bbc285f3e1a78c8f1Behdad Esfahbod } 332b051be542a8945ec14b0192bbc285f3e1a78c8f1Behdad Esfahbod 333607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void reject (void) { num_items++; match_glyph_data--; } 334696266981df5ef6c62ad0115133dad1d6c1d9accBehdad Esfahbod 3358b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod inline matcher_t::may_skip_t 3368b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod may_skip (const hb_apply_context_t *c, 3378b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod const hb_glyph_info_t &info) const 3388b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod { 3398b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod return matcher.may_skip (c, info); 3408b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod } 3418b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod 342c074ebc466dcc9bcc0d8a5dd7e942dea974ff718Behdad Esfahbod inline bool next (void) 3434ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 344506ffeb8e77a668fa305139582d215c32e46bb03Behdad Esfahbod assert (num_items > 0); 34537d13acd8d414a4b53fac0152addfadecf755cd4Behdad Esfahbod while (idx + num_items < end) 3464ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 347a4a48fe6d4f884a37e720430347d10dbe3562a79Behdad Esfahbod idx++; 348607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const hb_glyph_info_t &info = c->buffer->info[idx]; 349607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 350ff93ac8cb24cbc3d9dc1a2bfb0faa88950f4a507Behdad Esfahbod matcher_t::may_skip_t skip = matcher.may_skip (c, info); 351607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod if (unlikely (skip == matcher_t::SKIP_YES)) 352607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod continue; 353607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 3542b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); 355722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod if (match == matcher_t::MATCH_YES || 356722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod (match == matcher_t::MATCH_MAYBE && 357722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod skip == matcher_t::SKIP_NO)) 358607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod { 359607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod num_items--; 360607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_glyph_data++; 361607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return true; 362607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod } 363607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 364607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod if (skip == matcher_t::SKIP_NO) 365722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod return false; 366607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod } 367607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return false; 3684ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod } 369c074ebc466dcc9bcc0d8a5dd7e942dea974ff718Behdad Esfahbod inline bool prev (void) 3704ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 371506ffeb8e77a668fa305139582d215c32e46bb03Behdad Esfahbod assert (num_items > 0); 37237d13acd8d414a4b53fac0152addfadecf755cd4Behdad Esfahbod while (idx >= num_items) 3734ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 3744ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod idx--; 375607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const hb_glyph_info_t &info = c->buffer->out_info[idx]; 376607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 377ff93ac8cb24cbc3d9dc1a2bfb0faa88950f4a507Behdad Esfahbod matcher_t::may_skip_t skip = matcher.may_skip (c, info); 378607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod if (unlikely (skip == matcher_t::SKIP_YES)) 379607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod continue; 380607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 3812b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); 382722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod if (match == matcher_t::MATCH_YES || 383722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod (match == matcher_t::MATCH_MAYBE && 384722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod skip == matcher_t::SKIP_NO)) 385607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod { 386607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod num_items--; 387607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_glyph_data++; 388607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return true; 389607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod } 390607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 391607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod if (skip == matcher_t::SKIP_NO) 392722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod return false; 393607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod } 394607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return false; 3954ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod } 3964ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod 3974ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod unsigned int idx; 398ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 3994ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod hb_apply_context_t *c; 400607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod matcher_t matcher; 4016f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 *match_glyph_data; 402607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 4034ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod unsigned int num_items; 404696266981df5ef6c62ad0115133dad1d6c1d9accBehdad Esfahbod unsigned int end; 4054ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod }; 4064ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod 4072cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod 4082cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod inline const char *get_name (void) { return "APPLY"; } 4092cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index); 4102cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod template <typename T> 4112cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod inline return_t dispatch (const T &obj) { return obj.apply (this); } 4122cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod static return_t default_return_value (void) { return false; } 4132cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod bool stop_sublookup_iteration (return_t r) const { return r; } 4142cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod return_t recurse (unsigned int lookup_index) 4152cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod { 416baf7779d2d6e4810168a8f036bbf8f9e6493dd1aBehdad Esfahbod if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0)) 4172cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod return default_return_value (); 4182cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod 4192cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod nesting_level_left--; 4202cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod bool ret = recurse_func (this, lookup_index); 4212cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod nesting_level_left++; 4222cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod return ret; 4232cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod } 4242cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod 425cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod skipping_iterator_t iter_input, iter_context; 426cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod 4272cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod hb_font_t *font; 4282cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod hb_face_t *face; 4292cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod hb_buffer_t *buffer; 4302cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod recurse_func_t recurse_func; 4312cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod const GDEF &gdef; 432cf3de4d8f79fc6e8413957cdef034e975343ce30Behdad Esfahbod const VariationStore &var_store; 433cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod 434cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod hb_direction_t direction; 435cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod hb_mask_t lookup_mask; 436cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod unsigned int table_index; /* GSUB/GPOS */ 4372c8b3b2e5312c9858584f568b1528c57e5bb8a10Behdad Esfahbod unsigned int lookup_index; 438cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod unsigned int lookup_props; 439cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod unsigned int nesting_level_left; 4402cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod unsigned int debug_depth; 4412cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod 442cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod bool auto_zwnj; 443cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod bool auto_zwj; 444cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod bool has_glyph_classes; 445cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod 4462cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod 4472cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod hb_apply_context_t (unsigned int table_index_, 4482cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod hb_font_t *font_, 4492cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod hb_buffer_t *buffer_) : 450cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod iter_input (), iter_context (), 4512cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod font (font_), face (font->face), buffer (buffer_), 452dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod recurse_func (nullptr), 4532cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod gdef (*hb_ot_layout_from_face (face)->gdef), 454151d93de8a595924a8dcb00fcba648b4b3df0bf5Behdad Esfahbod var_store (gdef.get_var_store ()), 455cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod direction (buffer_->props.direction), 456cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod lookup_mask (1), 457cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod table_index (table_index_), 4582c8b3b2e5312c9858584f568b1528c57e5bb8a10Behdad Esfahbod lookup_index ((unsigned int) -1), 459cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod lookup_props (0), 460cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod nesting_level_left (HB_MAX_NESTING_LEVEL), 461cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod debug_depth (0), 462cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod auto_zwnj (true), 463cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod auto_zwj (true), 464cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod has_glyph_classes (gdef.has_glyph_classes ()) {} 4652cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod 4662cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } 4672cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } 468cdf1fd0627c5517c948ca05d2e9427c3e441adf9Behdad Esfahbod inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; } 4692cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } 4702c8b3b2e5312c9858584f568b1528c57e5bb8a10Behdad Esfahbod inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; } 471365576d246949f9d587e90cf0539dc0381e4d0a3Behdad Esfahbod inline void set_lookup_props (unsigned int lookup_props_) 472365576d246949f9d587e90cf0539dc0381e4d0a3Behdad Esfahbod { 473365576d246949f9d587e90cf0539dc0381e4d0a3Behdad Esfahbod lookup_props = lookup_props_; 474365576d246949f9d587e90cf0539dc0381e4d0a3Behdad Esfahbod iter_input.init (this, false); 475365576d246949f9d587e90cf0539dc0381e4d0a3Behdad Esfahbod iter_context.init (this, true); 476365576d246949f9d587e90cf0539dc0381e4d0a3Behdad Esfahbod } 4772cecc38c7cf49b2cf697efa7e974ceee7055f2c5Behdad Esfahbod 47803f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod inline bool 47903f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod match_properties_mark (hb_codepoint_t glyph, 48003f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod unsigned int glyph_props, 481b931e0b0ceeab0e4819d9c4b838c1a1eb87b52e4Behdad Esfahbod unsigned int match_props) const 48203f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod { 48303f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod /* If using mark filtering sets, the high short of 484b931e0b0ceeab0e4819d9c4b838c1a1eb87b52e4Behdad Esfahbod * match_props has the set index. 48503f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod */ 486b931e0b0ceeab0e4819d9c4b838c1a1eb87b52e4Behdad Esfahbod if (match_props & LookupFlag::UseMarkFilteringSet) 487b931e0b0ceeab0e4819d9c4b838c1a1eb87b52e4Behdad Esfahbod return gdef.mark_set_covers (match_props >> 16, glyph); 48803f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod 489b931e0b0ceeab0e4819d9c4b838c1a1eb87b52e4Behdad Esfahbod /* The second byte of match_props has the meaning 49003f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod * "ignore marks of attachment type different than 49103f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod * the attachment type specified." 49203f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod */ 493b931e0b0ceeab0e4819d9c4b838c1a1eb87b52e4Behdad Esfahbod if (match_props & LookupFlag::MarkAttachmentType) 494b931e0b0ceeab0e4819d9c4b838c1a1eb87b52e4Behdad Esfahbod return (match_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType); 49503f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod 49603f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod return true; 49703f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod } 49803f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod 49903f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod inline bool 500b98c5db32d15fcfb27ce2f6737203ce1ad124319Behdad Esfahbod check_glyph_property (const hb_glyph_info_t *info, 501b931e0b0ceeab0e4819d9c4b838c1a1eb87b52e4Behdad Esfahbod unsigned int match_props) const 50203f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod { 503b98c5db32d15fcfb27ce2f6737203ce1ad124319Behdad Esfahbod hb_codepoint_t glyph = info->codepoint; 504b98c5db32d15fcfb27ce2f6737203ce1ad124319Behdad Esfahbod unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info); 505b98c5db32d15fcfb27ce2f6737203ce1ad124319Behdad Esfahbod 50603f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod /* Not covered, if, for example, glyph class is ligature and 507b931e0b0ceeab0e4819d9c4b838c1a1eb87b52e4Behdad Esfahbod * match_props includes LookupFlags::IgnoreLigatures 50803f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod */ 509b931e0b0ceeab0e4819d9c4b838c1a1eb87b52e4Behdad Esfahbod if (glyph_props & match_props & LookupFlag::IgnoreFlags) 51003f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod return false; 51103f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod 5125a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbod if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) 513b931e0b0ceeab0e4819d9c4b838c1a1eb87b52e4Behdad Esfahbod return match_properties_mark (glyph, glyph_props, match_props); 51403f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod 51503f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod return true; 51603f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod } 51703f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod 518a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod inline void _set_glyph_props (hb_codepoint_t glyph_index, 51971b4c999a511bf018acaf48a45e070470c0daf12Behdad Esfahbod unsigned int class_guess = 0, 520832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod bool ligature = false, 521832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod bool component = false) const 52260da763dfac96a7931d6e6bdef8b9973bd5209abBehdad Esfahbod { 52309675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) & 52409675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE; 52509675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED; 52609675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod if (ligature) 527832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod { 52809675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED; 529832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod /* In the only place that the MULTIPLIED bit is used, Uniscribe 530832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod * seems to only care about the "last" transformation between 531832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod * Ligature and Multiple substitions. Ie. if you ligate, expand, 532832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod * and ligate again, it forgives the multiplication and acts as 533832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod * if only ligation happened. As such, clear MULTIPLIED bit. 534832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod */ 535832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod add_in &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED; 536832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod } 537832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod if (component) 538832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod add_in |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED; 5392fca1426ca06cabbe8f027f2dc9dee9c27560c76Behdad Esfahbod if (likely (has_glyph_classes)) 54005ad6b50ac0a1b9a8da10d2ee2238068b7811e7dBehdad Esfahbod _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index)); 54105bd1b63426e07d1df7a1b40bf845dc94ab995a8Behdad Esfahbod else if (class_guess) 54209675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess); 54360da763dfac96a7931d6e6bdef8b9973bd5209abBehdad Esfahbod } 5444ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod 545a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod inline void replace_glyph (hb_codepoint_t glyph_index) const 5463ec77d6ae0510dc2c0ec64382c4948bc6e109844Behdad Esfahbod { 547a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod _set_glyph_props (glyph_index); 548a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod buffer->replace_glyph (glyph_index); 5493ec77d6ae0510dc2c0ec64382c4948bc6e109844Behdad Esfahbod } 550a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod inline void replace_glyph_inplace (hb_codepoint_t glyph_index) const 55198370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod { 552a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod _set_glyph_props (glyph_index); 553a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod buffer->cur().codepoint = glyph_index; 554a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod } 555a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod inline void replace_glyph_with_ligature (hb_codepoint_t glyph_index, 556a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod unsigned int class_guess) const 557a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod { 55809675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod _set_glyph_props (glyph_index, class_guess, true); 55998370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod buffer->replace_glyph (glyph_index); 56098370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod } 561832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod inline void output_glyph_for_component (hb_codepoint_t glyph_index, 562832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod unsigned int class_guess) const 5637fbbf86efe675e4c038dfc5985c24bbc544620cdBehdad Esfahbod { 564832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod _set_glyph_props (glyph_index, class_guess, false, true); 565a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod buffer->output_glyph (glyph_index); 5667fbbf86efe675e4c038dfc5985c24bbc544620cdBehdad Esfahbod } 5671376fb7bf9ef07970f0ba13dc64d6a8ab8252762Behdad Esfahbod}; 5681376fb7bf9ef07970f0ba13dc64d6a8ab8252762Behdad Esfahbod 56966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 57094a23aaeca39c662614037ef887412249bdc8d49Behdad Esfahbod 5716f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodtypedef bool (*intersects_func_t) (hb_set_t *glyphs, const UINT16 &value, const void *data); 5726f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodtypedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const UINT16 &value, const void *data); 5736f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodtypedef bool (*match_func_t) (hb_codepoint_t glyph_id, const UINT16 &value, const void *data); 57466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 57531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstruct ContextClosureFuncs 57631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 57731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod intersects_func_t intersects; 57831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod}; 579d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodstruct ContextCollectGlyphsFuncs 580d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 581d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod collect_glyphs_func_t collect; 582d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod}; 58331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstruct ContextApplyFuncs 58460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 58548f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod match_func_t match; 58666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 58766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 588d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 5896f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodstatic inline bool intersects_glyph (hb_set_t *glyphs, const UINT16 &value, const void *data HB_UNUSED) 59031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 59131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return glyphs->has (value); 59231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 5936f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodstatic inline bool intersects_class (hb_set_t *glyphs, const UINT16 &value, const void *data) 59431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 59531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); 59631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return class_def.intersects_class (glyphs, value); 59731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 5986f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodstatic inline bool intersects_coverage (hb_set_t *glyphs, const UINT16 &value, const void *data) 59931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 60031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; 60131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return (data+coverage).intersects (glyphs); 60231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 60331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 60431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstatic inline bool intersects_array (hb_closure_context_t *c, 60531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count, 6066f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 values[], 60731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod intersects_func_t intersects_func, 60831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const void *intersects_data) 60931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 61031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 61131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (likely (!intersects_func (c->glyphs, values[i], intersects_data))) 61231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 61331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 61431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 61531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 616f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 6176f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodstatic inline void collect_glyph (hb_set_t *glyphs, const UINT16 &value, const void *data HB_UNUSED) 618d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 619d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod glyphs->add (value); 620d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod} 6216f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodstatic inline void collect_class (hb_set_t *glyphs, const UINT16 &value, const void *data) 622d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 623d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); 62471e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod class_def.add_class (glyphs, value); 625d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod} 6266f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodstatic inline void collect_coverage (hb_set_t *glyphs, const UINT16 &value, const void *data) 627d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 628d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; 629d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod (data+coverage).add_coverage (glyphs); 630d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod} 6310beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbodstatic inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, 632f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod hb_set_t *glyphs, 633d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int count, 6346f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 values[], 635d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod collect_glyphs_func_t collect_func, 636d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const void *collect_data) 637d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 638d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 639f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod collect_func (glyphs, values[i], collect_data); 640d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod} 641d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 642d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 6436f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodstatic inline bool match_glyph (hb_codepoint_t glyph_id, const UINT16 &value, const void *data HB_UNUSED) 64460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 64548f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod return glyph_id == value; 64648f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod} 6476f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodstatic inline bool match_class (hb_codepoint_t glyph_id, const UINT16 &value, const void *data) 64860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 6492b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); 65048f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod return class_def.get_class (glyph_id) == value; 65148f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod} 6526f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodstatic inline bool match_coverage (hb_codepoint_t glyph_id, const UINT16 &value, const void *data) 65360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 6546b54c5d0446b514fbb6521e7e9e614d153435f0eBehdad Esfahbod const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; 65531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; 65648f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod} 65748f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod 658e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbodstatic inline bool would_match_input (hb_would_apply_context_t *c, 659e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int count, /* Including the first glyph (not matched) */ 6606f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 input[], /* Array of input values--start with second glyph */ 661e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod match_func_t match_func, 662e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const void *match_data) 663e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod{ 664e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod if (count != c->len) 665e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return false; 666e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 667e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod for (unsigned int i = 1; i < count; i++) 668472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod if (likely (!match_func (c->glyphs[i], input[i - 1], match_data))) 669e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return false; 670e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 671e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return true; 672e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod} 673d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbodstatic inline bool match_input (hb_apply_context_t *c, 674d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod unsigned int count, /* Including the first glyph (not matched) */ 6756f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 input[], /* Array of input values--start with second glyph */ 676d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod match_func_t match_func, 67740cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod const void *match_data, 6786cc136f7531a45e71ea08a7dc8a2187172cb813dBehdad Esfahbod unsigned int *end_offset, 6795ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], 680dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod bool *p_is_mark_ligature = nullptr, 681dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod unsigned int *p_total_component_count = nullptr) 682d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod{ 683dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod TRACE_APPLY (nullptr); 68493814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 6855ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false); 6866b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod 6873c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod hb_buffer_t *buffer = c->buffer; 6883c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod 689365576d246949f9d587e90cf0539dc0381e4d0a3Behdad Esfahbod hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; 690b051be542a8945ec14b0192bbc285f3e1a78c8f1Behdad Esfahbod skippy_iter.reset (buffer->idx, count - 1); 691607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod skippy_iter.set_match_func (match_func, match_data, input); 69293814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 693191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod /* 694191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * This is perhaps the trickiest part of OpenType... Remarks: 695191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * 696191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * - If all components of the ligature were marks, we call this a mark ligature. 697191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * 698191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * - If there is no GDEF, and the ligature is NOT a mark ligature, we categorize 699191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * it as a ligature glyph. 700191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * 701191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * - Ligatures cannot be formed across glyphs attached to different components 702191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and 703191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother. 7048b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod * However, it would be wrong to ligate that SHADDA,FATHA sequence. 7058b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod * There are a couple of exceptions to this: 7068b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod * 7078b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod * o If a ligature tries ligating with marks that belong to it itself, go ahead, 7088b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod * assuming that the font designer knows what they are doing (otherwise it can 7098b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod * break Indic stuff when a matra wants to ligate with a conjunct, 7108b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod * 7118b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod * o If two marks want to ligate and they belong to different components of the 7128b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod * same ligature glyph, and said ligature glyph is to be ignored according to 7138b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod * mark-filtering rules, then allow. 7147c6937e7c7b62602fef10ac4b2e164d0c67c932bebraminio * https://github.com/harfbuzz/harfbuzz/issues/545 715191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod */ 716191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod 717101303dbf7cf15d044bf2518f14b3aec65970feaBehdad Esfahbod bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur()); 71893814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 71993814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod unsigned int total_component_count = 0; 7203ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur()); 72193814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 7223ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); 7233ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); 724d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod 725621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod enum { 726621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod LIGBASE_NOT_CHECKED, 727621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod LIGBASE_MAY_NOT_SKIP, 728621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod LIGBASE_MAY_SKIP 729621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod } ligbase = LIGBASE_NOT_CHECKED; 730621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod 7313c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod match_positions[0] = buffer->idx; 732370f03e9c69d98d735eafb7e72b13b17f42cbaa9Behdad Esfahbod for (unsigned int i = 1; i < count; i++) 73360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 734b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!skippy_iter.next ()) return_trace (false); 7356cc136f7531a45e71ea08a7dc8a2187172cb813dBehdad Esfahbod 7366cc136f7531a45e71ea08a7dc8a2187172cb813dBehdad Esfahbod match_positions[i] = skippy_iter.idx; 73793814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 7383ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]); 7393ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]); 74093814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 7418b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod if (first_lig_id && first_lig_comp) 7428b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod { 74393814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod /* If first component was attached to a previous ligature component, 74493814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod * all subsequent components should be attached to the same ligature 7458b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod * component, otherwise we shouldn't ligate them... */ 74693814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp) 7478b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod { 7488b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod /* ...unless, we are attached to a base ligature and that base 7498b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod * ligature is ignorable. */ 750621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod if (ligbase == LIGBASE_NOT_CHECKED) 7518b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod { 752621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod bool found = false; 753621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod const hb_glyph_info_t *out = buffer->out_info; 754621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod unsigned int j = buffer->out_len; 755621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod while (j && _hb_glyph_info_get_lig_id (&out[j - 1]) == first_lig_id) 7568b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod { 757621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod if (_hb_glyph_info_get_lig_comp (&out[j - 1]) == 0) 758621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod { 759621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod j--; 760621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod found = true; 761621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod break; 762621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod } 7638b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod j--; 7648b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod } 7658b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod 766621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod if (found && skippy_iter.may_skip (c, out[j]) == hb_apply_context_t::matcher_t::SKIP_YES) 767621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod ligbase = LIGBASE_MAY_SKIP; 768621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod else 769621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod ligbase = LIGBASE_MAY_NOT_SKIP; 770621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod } 7718b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod 772621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod if (ligbase == LIGBASE_MAY_NOT_SKIP) 7738b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod return_trace (false); 7748b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod } 7758b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod } 7768b2c94c43fd335b944d5e5487265706b8e0f9041Behdad Esfahbod else 777621c49cb8657a79ee6897c4d313d0e825b2b228fBehdad Esfahbod { 77893814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod /* If first component was NOT attached to a previous ligature component, 77993814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod * all subsequent components should also NOT be attached to any ligature 78093814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod * component, unless they are attached to the first component itself! */ 78193814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id)) 782b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 78393814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod } 78493814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 785101303dbf7cf15d044bf2518f14b3aec65970feaBehdad Esfahbod is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]); 7863ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]); 787d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod } 788d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod 7893c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod *end_offset = skippy_iter.idx - buffer->idx + 1; 790d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod 791191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod if (p_is_mark_ligature) 792191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod *p_is_mark_ligature = is_mark_ligature; 793191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod 794191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod if (p_total_component_count) 795191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod *p_total_component_count = total_component_count; 796191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod 797b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 798d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod} 799b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbodstatic inline bool ligate_input (hb_apply_context_t *c, 800e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod unsigned int count, /* Including the first glyph */ 8015ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ 802e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod unsigned int match_length, 803a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod hb_codepoint_t lig_glyph, 804a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod bool is_mark_ligature, 805a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod unsigned int total_component_count) 806a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod{ 807dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod TRACE_APPLY (nullptr); 808e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod 8093c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod hb_buffer_t *buffer = c->buffer; 8103c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod 8113c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod buffer->merge_clusters (buffer->idx, buffer->idx + match_length); 812607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 813a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod /* 814a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * - If it *is* a mark ligature, we don't allocate a new ligature id, and leave 815a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * the ligature to keep its old ligature id. This will allow it to attach to 816a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HEH, 817a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a 818a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * ligature id and component value of 2. Then if SHADDA,FATHA form a ligature 819a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * later, we don't want them to lose their ligature id/component, otherwise 820a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * GPOS will fail to correctly position the mark ligature on top of the 821a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * LAM,LAM,HEH ligature. See: 822a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * https://bugzilla.gnome.org/show_bug.cgi?id=676343 823a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * 824a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * - If a ligature is formed of components that some of which are also ligatures 825a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * themselves, and those ligature components had marks attached to *their* 826a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * components, we have to attach the marks to the new ligature component 827a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * positions! Now *that*'s tricky! And these marks may be following the 828a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * last component of the whole sequence, so we should loop forward looking 829a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * for them and update them. 830a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * 831a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * Eg. the sequence is LAM,LAM,SHADDA,FATHA,HEH, and the font first forms a 832a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * 'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature 833a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * id and component == 1. Now, during 'liga', the LAM and the LAM-HEH ligature 834a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * form a LAM-LAM-HEH ligature. We need to reassign the SHADDA and FATHA to 835a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * the new ligature with a component value of 2. 836a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * 837a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * This in fact happened to a font... See: 838a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * https://bugzilla.gnome.org/show_bug.cgi?id=437633 839a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod */ 840a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod 8415a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbod unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; 8423ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer); 8433ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); 8443ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); 845a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod unsigned int components_so_far = last_num_components; 846a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod 847a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod if (!is_mark_ligature) 8487e08f1258da229dfaf7e1c4b5c41e5bb83906cb0Behdad Esfahbod { 8493ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count); 8503c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) 8513d436d325edccc0f3dd820e06e3d529cc8f3eca4Behdad Esfahbod { 8528259669fbd1b070fc02287325894caf1bc4d590eBehdad Esfahbod _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER); 8533d436d325edccc0f3dd820e06e3d529cc8f3eca4Behdad Esfahbod } 8547e08f1258da229dfaf7e1c4b5c41e5bb83906cb0Behdad Esfahbod } 855a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod c->replace_glyph_with_ligature (lig_glyph, klass); 856a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod 857a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod for (unsigned int i = 1; i < count; i++) 858a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod { 859abadc1717d997b69f987fdf1be9e12156d2d13d6Behdad Esfahbod while (buffer->idx < match_positions[i] && !buffer->in_error) 860a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod { 861a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod if (!is_mark_ligature) { 8622f02fc79a5018e3348fccf366c470803554e1e58Behdad Esfahbod unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); 8632f02fc79a5018e3348fccf366c470803554e1e58Behdad Esfahbod if (this_comp == 0) 864100fbeaf196515774c985ee839d0fa0695f9a6faBehdad Esfahbod this_comp = last_num_components; 865a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod unsigned int new_lig_comp = components_so_far - last_num_components + 8662f02fc79a5018e3348fccf366c470803554e1e58Behdad Esfahbod MIN (this_comp, last_num_components); 8672f02fc79a5018e3348fccf366c470803554e1e58Behdad Esfahbod _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); 868a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod } 8693c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod buffer->next_glyph (); 870a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod } 871a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod 8723ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); 8733ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); 874a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod components_so_far += last_num_components; 875a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod 876a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod /* Skip the base glyph */ 8773c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod buffer->idx++; 878a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod } 879a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod 880a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod if (!is_mark_ligature && last_lig_id) { 881a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod /* Re-adjust components for any marks following. */ 8823c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod for (unsigned int i = buffer->idx; i < buffer->len; i++) { 8833ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) { 8842f02fc79a5018e3348fccf366c470803554e1e58Behdad Esfahbod unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]); 8852f02fc79a5018e3348fccf366c470803554e1e58Behdad Esfahbod if (!this_comp) 8862f02fc79a5018e3348fccf366c470803554e1e58Behdad Esfahbod break; 887a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod unsigned int new_lig_comp = components_so_far - last_num_components + 8882f02fc79a5018e3348fccf366c470803554e1e58Behdad Esfahbod MIN (this_comp, last_num_components); 8893ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); 890a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod } else 891a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod break; 892a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod } 893a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod } 894b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 895a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod} 896d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod 897d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbodstatic inline bool match_backtrack (hb_apply_context_t *c, 898e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod unsigned int count, 8996f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 backtrack[], 900e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod match_func_t match_func, 90140bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod const void *match_data, 90240bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod unsigned int *match_start) 903e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod{ 904dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod TRACE_APPLY (nullptr); 90593814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 906365576d246949f9d587e90cf0539dc0381e4d0a3Behdad Esfahbod hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; 907b051be542a8945ec14b0192bbc285f3e1a78c8f1Behdad Esfahbod skippy_iter.reset (c->buffer->backtrack_len (), count); 908607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod skippy_iter.set_match_func (match_func, match_data, backtrack); 909e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod 9104d3aeb8cb2bc1ca7cdd03ba28ba8c334f12d4c03Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 9114ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod if (!skippy_iter.prev ()) 912b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 913e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod 91440bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod *match_start = skippy_iter.idx; 91540bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod 916b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 917e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod} 918e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod 919d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbodstatic inline bool match_lookahead (hb_apply_context_t *c, 920d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod unsigned int count, 9216f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 lookahead[], 922d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod match_func_t match_func, 92340cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod const void *match_data, 92440bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod unsigned int offset, 92540bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod unsigned int *end_index) 926f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod{ 927dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod TRACE_APPLY (nullptr); 92893814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 929365576d246949f9d587e90cf0539dc0381e4d0a3Behdad Esfahbod hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; 930b051be542a8945ec14b0192bbc285f3e1a78c8f1Behdad Esfahbod skippy_iter.reset (c->buffer->idx + offset - 1, count); 931607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod skippy_iter.set_match_func (match_func, match_data, lookahead); 93266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 933370f03e9c69d98d735eafb7e72b13b17f42cbaa9Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 9344ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod if (!skippy_iter.next ()) 935b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 93666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 93740bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod *end_index = skippy_iter.idx + 1; 93840bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod 939b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 940f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod} 941f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 942acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 943f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 94460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct LookupRecord 94560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 946de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 947de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 948be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 949b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this)); 950cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 951cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 9526f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 sequenceIndex; /* Index into current glyph 953f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod * sequence--first glyph = 0 */ 9546f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 lookupListIndex; /* Lookup to apply to that 955f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod * position--zero--based */ 956569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 957569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod DEFINE_SIZE_STATIC (4); 958f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod}; 959f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 960acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 961d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodtemplate <typename context_t> 962d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodstatic inline void recurse_lookups (context_t *c, 963d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int lookupCount, 964d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */) 96531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 96631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < lookupCount; i++) 96786522e493d071f395b5abf64289232bf8867ac29Behdad Esfahbod c->recurse (lookupRecord[i].lookupListIndex); 96831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 969acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 970d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbodstatic inline bool apply_lookup (hb_apply_context_t *c, 971e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod unsigned int count, /* Including the first glyph */ 9725ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ 973e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod unsigned int lookupCount, 9746b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ 9756b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int match_length) 976f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod{ 977dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod TRACE_APPLY (nullptr); 978902cc8aca0b3ff25eeee50b3a84d729e31731ef3Behdad Esfahbod 9796b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod hb_buffer_t *buffer = c->buffer; 98044f7d6ecde9bf7427a05cbe73ed5d668b8a72b2ajfkthame int end; 98152e9a71d578c5171bbb0f4bfc1b70841c3270328Behdad Esfahbod 9826b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod /* All positions are distance from beginning of *output* buffer. 9836b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod * Adjust. */ 9846b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod { 9856b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int bl = buffer->backtrack_len (); 9866b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod end = bl + match_length; 987607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 9886b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod int delta = bl - buffer->idx; 9896b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod /* Convert positions to new indexing. */ 9906b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod for (unsigned int j = 0; j < count; j++) 9916b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod match_positions[j] += delta; 9926b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod } 993607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 994b87e36f6f119fac80b8fd55f3abae563c2c5b798Behdad Esfahbod for (unsigned int i = 0; i < lookupCount && !buffer->in_error; i++) 99560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 9966b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int idx = lookupRecord[i].sequenceIndex; 9976b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod if (idx >= count) 9986b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod continue; 9998751de50831338ce550601c34c17d152ad89c1fdBehdad Esfahbod 10009cc1ed4fa68075b3b142a2737438109772dd0002Behdad Esfahbod /* Don't recurse to ourself at same position. 10019cc1ed4fa68075b3b142a2737438109772dd0002Behdad Esfahbod * Note that this test is too naive, it doesn't catch longer loops. */ 10029cc1ed4fa68075b3b142a2737438109772dd0002Behdad Esfahbod if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index) 10039cc1ed4fa68075b3b142a2737438109772dd0002Behdad Esfahbod continue; 10049cc1ed4fa68075b3b142a2737438109772dd0002Behdad Esfahbod 1005e5930722d485207ca158612a2b08816337fed7e8Behdad Esfahbod if (unlikely (!buffer->move_to (match_positions[idx]))) 1006e5930722d485207ca158612a2b08816337fed7e8Behdad Esfahbod break; 10078820bb235b1f63e4d93c8a2f5c08b44d89e06b78Behdad Esfahbod 1008baf7779d2d6e4810168a8f036bbf8f9e6493dd1aBehdad Esfahbod if (unlikely (buffer->max_ops <= 0)) 1009baf7779d2d6e4810168a8f036bbf8f9e6493dd1aBehdad Esfahbod break; 1010baf7779d2d6e4810168a8f036bbf8f9e6493dd1aBehdad Esfahbod 10116b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); 10126b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod if (!c->recurse (lookupRecord[i].lookupListIndex)) 10136b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod continue; 10148820bb235b1f63e4d93c8a2f5c08b44d89e06b78Behdad Esfahbod 10156b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len (); 10166b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod int delta = new_len - orig_len; 1017e73a0c2a903112ce9a35b95e14e10ab8ea2dc337Behdad Esfahbod 10186b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod if (!delta) 10196b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod continue; 10208751de50831338ce550601c34c17d152ad89c1fdBehdad Esfahbod 10219ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod /* Recursed lookup changed buffer len. Adjust. 10229ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * 10239ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * TODO: 10249ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * 10259ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * Right now, if buffer length increased by n, we assume n new glyphs 10269ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * were added right after the current position, and if buffer length 10279ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * was decreased by n, we assume n match positions after the current 10289ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * one where removed. The former (buffer length increased) case is 10299ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * fine, but the decrease case can be improved in at least two ways, 10309ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * both of which are significant: 10319ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * 10329ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * - If recursed-to lookup is MultipleSubst and buffer length 10339ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * decreased, then it's current match position that was deleted, 10349ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * NOT the one after it. 10359ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * 10369ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * - If buffer length was decreased by n, it does not necessarily 10379ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * mean that n match positions where removed, as there might 10389ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * have been marks and default-ignorables in the sequence. We 10399ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * should instead drop match positions between current-position 10409ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * and current-position + n instead. 10419ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * 10429ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod * It should be possible to construct tests for both of these cases. 10439ac9af725c781f4597e8db46cf330d595c072739Behdad Esfahbod */ 104466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 104544f7d6ecde9bf7427a05cbe73ed5d668b8a72b2ajfkthame end += delta; 104647e7a1800fba9b8bf042a1f4976a15ab012ebfc7Behdad Esfahbod if (end <= int (match_positions[idx])) 1047359dead960c825edeb4587915a511d323f1c1f2aBehdad Esfahbod { 10484b4a1b9f235598b04ce9ae1f9670fc978ab7620dBehdad Esfahbod /* End might end up being smaller than match_positions[idx] if the recursed 104947e7a1800fba9b8bf042a1f4976a15ab012ebfc7Behdad Esfahbod * lookup ended up removing many items, more than we have had matched. 10504b4a1b9f235598b04ce9ae1f9670fc978ab7620dBehdad Esfahbod * Just never rewind end back and get out of here. 10514b4a1b9f235598b04ce9ae1f9670fc978ab7620dBehdad Esfahbod * https://bugs.chromium.org/p/chromium/issues/detail?id=659496 */ 10524b4a1b9f235598b04ce9ae1f9670fc978ab7620dBehdad Esfahbod end = match_positions[idx]; 105347e7a1800fba9b8bf042a1f4976a15ab012ebfc7Behdad Esfahbod /* There can't be any further changes. */ 1054359dead960c825edeb4587915a511d323f1c1f2aBehdad Esfahbod break; 1055359dead960c825edeb4587915a511d323f1c1f2aBehdad Esfahbod } 105666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 10576b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */ 10586b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod 10596b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod if (delta > 0) 10606b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod { 10615ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH)) 10626b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod break; 106366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 106466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod else 106566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod { 106647e7a1800fba9b8bf042a1f4976a15ab012ebfc7Behdad Esfahbod /* NOTE: delta is negative. */ 10676b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod delta = MAX (delta, (int) next - (int) count); 10686b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod next -= delta; 106966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 10706b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod 10716b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod /* Shift! */ 10726b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod memmove (match_positions + next + delta, match_positions + next, 10736b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod (count - next) * sizeof (match_positions[0])); 10746b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod next += delta; 10756b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod count += delta; 10766b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod 10776b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod /* Fill in new entries. */ 10786b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod for (unsigned int j = idx + 1; j < next; j++) 10796b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod match_positions[j] = match_positions[j - 1] + 1; 10806b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod 10816b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod /* And fixup the rest. */ 10826b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod for (; next < count; next++) 10836b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod match_positions[next] += delta; 108466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 108566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 10866b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod buffer->move_to (end); 10876b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod 1088b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 108966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod} 109048f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod 1091acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 1092f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 1093f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod/* Contextual lookups */ 1094f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 109531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstruct ContextClosureLookupContext 109631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 109731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ContextClosureFuncs funcs; 109831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const void *intersects_data; 109931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod}; 110031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1101d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodstruct ContextCollectGlyphsLookupContext 1102d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 1103d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod ContextCollectGlyphsFuncs funcs; 1104d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const void *collect_data; 1105d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod}; 1106d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 110731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstruct ContextApplyLookupContext 110860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 110931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ContextApplyFuncs funcs; 111040cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod const void *match_data; 1111f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod}; 1112f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 11135caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbodstatic inline void context_closure_lookup (hb_closure_context_t *c, 111431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 11156f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 input[], /* Array of input values--start with second glyph */ 111631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int lookupCount, 111731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const LookupRecord lookupRecord[], 111831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ContextClosureLookupContext &lookup_context) 111931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 11205caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod if (intersects_array (c, 11215caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inputCount ? inputCount - 1 : 0, input, 11225caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context.funcs.intersects, lookup_context.intersects_data)) 1123d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod recurse_lookups (c, 1124d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookupCount, lookupRecord); 112531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 112631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1127d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodstatic inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, 1128d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 11296f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 input[], /* Array of input values--start with second glyph */ 1130d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int lookupCount, 1131d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const LookupRecord lookupRecord[], 1132d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod ContextCollectGlyphsLookupContext &lookup_context) 1133d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 11348303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod collect_array (c, c->input, 1135d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod inputCount ? inputCount - 1 : 0, input, 1136d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookup_context.funcs.collect, lookup_context.collect_data); 1137d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod recurse_lookups (c, 1138d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookupCount, lookupRecord); 1139d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod} 114031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1141e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbodstatic inline bool context_would_apply_lookup (hb_would_apply_context_t *c, 1142e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 11436f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 input[], /* Array of input values--start with second glyph */ 11440beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod unsigned int lookupCount HB_UNUSED, 11450beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod const LookupRecord lookupRecord[] HB_UNUSED, 1146e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod ContextApplyLookupContext &lookup_context) 1147e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod{ 1148e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return would_match_input (c, 1149e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inputCount, input, 1150e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod lookup_context.funcs.match, lookup_context.match_data); 1151e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod} 115231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstatic inline bool context_apply_lookup (hb_apply_context_t *c, 115331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 11546f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 input[], /* Array of input values--start with second glyph */ 115531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int lookupCount, 115631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const LookupRecord lookupRecord[], 115731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ContextApplyLookupContext &lookup_context) 1158f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod{ 11596b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int match_length = 0; 11605ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; 1161d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod return match_input (c, 11624169710911450e0f9bc045fe279bfc8ba9e8457cBehdad Esfahbod inputCount, input, 11636b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod lookup_context.funcs.match, lookup_context.match_data, 11646b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod &match_length, match_positions) 116540bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod && (c->buffer->unsafe_to_break (c->buffer->idx, c->buffer->idx + match_length), 116640bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod apply_lookup (c, 11676b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod inputCount, match_positions, 11686b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod lookupCount, lookupRecord, 116940bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod match_length)); 1170f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod} 1171f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 117260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Rule 117360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 11745caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const 117531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod { 1176be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 1177093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); 11785caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod context_closure_lookup (c, 1179093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod inputCount, inputZ, 11805caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookupCount, lookupRecord, 11815caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context); 118231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 118331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1184d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const 1185d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod { 1186d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 1187093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); 1188d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod context_collect_glyphs_lookup (c, 1189093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod inputCount, inputZ, 1190d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookupCount, lookupRecord, 1191d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookup_context); 1192d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod } 1193d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1194e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 1195e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1196be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1197093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); 1198b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); 1199e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1200e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 120131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 120260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1203be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 1204093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); 1205b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); 120666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 120766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 120870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod public: 1209de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1210de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1211be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 12125aad81943329df199501e9473e2cc39f9d4421a1Behdad Esfahbod return_trace (inputCount.sanitize (c) && 12135aad81943329df199501e9473e2cc39f9d4421a1Behdad Esfahbod lookupCount.sanitize (c) && 12145aad81943329df199501e9473e2cc39f9d4421a1Behdad Esfahbod c->check_range (inputZ, 12155aad81943329df199501e9473e2cc39f9d4421a1Behdad Esfahbod inputZ[0].static_size * inputCount + 12165aad81943329df199501e9473e2cc39f9d4421a1Behdad Esfahbod lookupRecordX[0].static_size * lookupCount)); 121770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 121870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1219ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 12206f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 inputCount; /* Total number of glyphs in input 122131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod * glyph sequence--includes the first 122266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * glyph */ 12236f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 lookupCount; /* Number of LookupRecords */ 12246f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 inputZ[VAR]; /* Array of match inputs--start with 122566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * second glyph */ 1226d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in 122766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * design order */ 1228569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 1229093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod DEFINE_SIZE_ARRAY2 (4, inputZ, lookupRecordX); 123066bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 123166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 123260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct RuleSet 123360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 12345caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const 123531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod { 1236be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 123731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int num_rules = rule.len; 123831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 12395caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod (this+rule[i]).closure (c, lookup_context); 124031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 124131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1242d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const 1243d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod { 1244d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 1245d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int num_rules = rule.len; 1246d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 1247d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod (this+rule[i]).collect_glyphs (c, lookup_context); 1248d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod } 1249d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1250e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 1251e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1252be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1253e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int num_rules = rule.len; 1254e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 1255e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1256e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod if ((this+rule[i]).would_apply (c, lookup_context)) 1257b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 1258e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1259b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 1260e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1261e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 126231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 126360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1264be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 126566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod unsigned int num_rules = rule.len; 126660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 126760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1268d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod if ((this+rule[i]).apply (c, lookup_context)) 1269b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 127066bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 1271b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 127266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 127366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1274de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1275de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1276be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1277b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rule.sanitize (c, this)); 127870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 127970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1280ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 128166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod OffsetArrayOf<Rule> 128248f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod rule; /* Array of Rule tables 128366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * ordered by preference */ 1284ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod public: 12850eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (2, rule); 128666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 128766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 128866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 128960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ContextFormat1 129060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 129144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline void closure (hb_closure_context_t *c) const 1292f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 1293be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 129431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 129531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const Coverage &cov = (this+coverage); 129631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 129731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ContextClosureLookupContext lookup_context = { 129844fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod {intersects_glyph}, 1299dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod nullptr 130031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod }; 130131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 130231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = ruleSet.len; 130331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 130431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (cov.intersects_coverage (c->glyphs, i)) { 130531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const RuleSet &rule_set = this+ruleSet[i]; 13065caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod rule_set.closure (c, lookup_context); 130731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 1308f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 1309f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 131026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 131126514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 1312d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 13138303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+coverage).add_coverage (c->input); 1314d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1315d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod struct ContextCollectGlyphsLookupContext lookup_context = { 1316d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod {collect_glyph}, 1317dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod nullptr 1318d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod }; 1319d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1320d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int count = ruleSet.len; 1321d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1322f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod (this+ruleSet[i]).collect_glyphs (c, lookup_context); 132326514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 132426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 1325e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 1326e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1327be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1328e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1329b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])]; 1330e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod struct ContextApplyLookupContext lookup_context = { 1331ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_glyph}, 1332dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod nullptr 1333e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod }; 1334b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rule_set.would_apply (c, lookup_context)); 1335e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1336e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 133744fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline const Coverage &get_coverage (void) const 133844fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 133944fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod return this+coverage; 134044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 134144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 1342ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 134360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1344be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 1345b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 134664d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (likely (index == NOT_COVERED)) 1347b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 1348aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 134966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod const RuleSet &rule_set = this+ruleSet[index]; 135031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ContextApplyLookupContext lookup_context = { 1351ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_glyph}, 1352dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod nullptr 135366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod }; 1354b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rule_set.apply (c, lookup_context)); 135566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 135666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1357de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1358de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1359be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1360b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); 136170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 136270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1363ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 13646f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier--format = 1 */ 136566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod OffsetTo<Coverage> 136666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod coverage; /* Offset to Coverage table--from 136766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * beginning of table */ 136866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod OffsetArrayOf<RuleSet> 136966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod ruleSet; /* Array of RuleSet tables 137066bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * ordered by Coverage Index */ 1371b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 13720eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, ruleSet); 137366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 137466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 137566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 137660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ContextFormat2 137760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 137844fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline void closure (hb_closure_context_t *c) const 1379f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 1380be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 138131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (!(this+coverage).intersects (c->glyphs)) 13825caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod return; 138331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 138431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ClassDef &class_def = this+classDef; 138531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 138631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ContextClosureLookupContext lookup_context = { 138744fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod {intersects_class}, 138811fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod &class_def 138931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod }; 139031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 139131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = ruleSet.len; 139231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 139331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (class_def.intersects_class (c->glyphs, i)) { 139431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const RuleSet &rule_set = this+ruleSet[i]; 13955caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod rule_set.closure (c, lookup_context); 139631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 1397f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 1398f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 139926514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 140026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 1401d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 14028303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+coverage).add_coverage (c->input); 1403d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 140411fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod const ClassDef &class_def = this+classDef; 1405d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod struct ContextCollectGlyphsLookupContext lookup_context = { 1406d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod {collect_class}, 140711fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod &class_def 1408d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod }; 1409d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1410d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int count = ruleSet.len; 1411d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1412f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod (this+ruleSet[i]).collect_glyphs (c, lookup_context); 141326514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 141426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 1415e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 1416e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1417be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1418e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1419e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const ClassDef &class_def = this+classDef; 14202dc1141d7d0a9f5818862b09d6b9cfe0a27f1fc1Behdad Esfahbod unsigned int index = class_def.get_class (c->glyphs[0]); 1421e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const RuleSet &rule_set = this+ruleSet[index]; 1422e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod struct ContextApplyLookupContext lookup_context = { 1423ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_class}, 1424e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod &class_def 1425e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod }; 1426b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rule_set.would_apply (c, lookup_context)); 1427e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1428e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 142944fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline const Coverage &get_coverage (void) const 143044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 143144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod return this+coverage; 143244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 143344fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 1434ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 143560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1436be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 1437b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 1438b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (likely (index == NOT_COVERED)) return_trace (false); 1439aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 1440aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod const ClassDef &class_def = this+classDef; 14412dc1141d7d0a9f5818862b09d6b9cfe0a27f1fc1Behdad Esfahbod index = class_def.get_class (c->buffer->cur().codepoint); 144266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod const RuleSet &rule_set = this+ruleSet[index]; 144331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ContextApplyLookupContext lookup_context = { 1444ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_class}, 144540cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod &class_def 144666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod }; 1447b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rule_set.apply (c, lookup_context)); 144866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 144966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1450de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1451de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1452be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1453b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this)); 145470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 145570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1456ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 14576f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier--format = 2 */ 145866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod OffsetTo<Coverage> 145966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod coverage; /* Offset to Coverage table--from 146066bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * beginning of table */ 146166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod OffsetTo<ClassDef> 146266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod classDef; /* Offset to glyph ClassDef table--from 146366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * beginning of table */ 146466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod OffsetArrayOf<RuleSet> 146566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod ruleSet; /* Array of RuleSet tables 146666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * ordered by class */ 1467b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 14680eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (8, ruleSet); 146966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 147066bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 147166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 147260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ContextFormat3 147360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 147444fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline void closure (hb_closure_context_t *c) const 1475f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 1476be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 1477093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod if (!(this+coverageZ[0]).intersects (c->glyphs)) 14785caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod return; 147931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1480093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); 148131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ContextClosureLookupContext lookup_context = { 148244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod {intersects_coverage}, 148331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod this 148431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod }; 14855caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod context_closure_lookup (c, 14866f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod glyphCount, (const UINT16 *) (coverageZ + 1), 14875caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookupCount, lookupRecord, 14885caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context); 1489f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 1490f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 149126514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 149226514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 1493d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 1494093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod (this+coverageZ[0]).add_coverage (c->input); 1495d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1496093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); 1497d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod struct ContextCollectGlyphsLookupContext lookup_context = { 1498d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod {collect_coverage}, 1499e75943de803f571b7ad2cf2f777119753a209656Behdad Esfahbod this 1500d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod }; 1501d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1502d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod context_collect_glyphs_lookup (c, 15036f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod glyphCount, (const UINT16 *) (coverageZ + 1), 1504d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookupCount, lookupRecord, 1505d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookup_context); 150626514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 150726514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 1508e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 1509e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1510be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1511e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1512093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); 1513e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod struct ContextApplyLookupContext lookup_context = { 1514ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_coverage}, 1515e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod this 1516e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod }; 15176f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod return_trace (context_would_apply_lookup (c, glyphCount, (const UINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); 1518e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1519e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 152044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline const Coverage &get_coverage (void) const 152144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 1522093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod return this+coverageZ[0]; 152344fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 152444fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 1525ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 152660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1527be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 1528093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); 1529b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (likely (index == NOT_COVERED)) return_trace (false); 153066bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1531093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); 153231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ContextApplyLookupContext lookup_context = { 1533ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_coverage}, 153440cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod this 153566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod }; 15366f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod return_trace (context_apply_lookup (c, glyphCount, (const UINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); 153766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 153866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1539de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1540de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1541be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1542b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!c->check_struct (this)) return_trace (false); 154370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod unsigned int count = glyphCount; 1544b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */ 1545b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return_trace (false); 154670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1547b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!coverageZ[i].sanitize (c, this)) return_trace (false); 1548de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count); 1549b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); 155070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 155170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1552ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 15536f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier--format = 3 */ 15546f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 glyphCount; /* Number of glyphs in the input glyph 155566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * sequence */ 15566f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 lookupCount; /* Number of LookupRecords */ 1557aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetTo<Coverage> 1558093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod coverageZ[VAR]; /* Array of offsets to Coverage 1559aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod * table in glyph sequence order */ 1560d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in 156166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * design order */ 1562569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 1563093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod DEFINE_SIZE_ARRAY2 (6, coverageZ, lookupRecordX); 156466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 156566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 156660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Context 156760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 156844fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod template <typename context_t> 15699c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 1570e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 157100f6a8e334ec4c586e4e633a95b411ccb50306d3Behdad Esfahbod TRACE_DISPATCH (this, u.format); 1572f396fbb000dc1c8acddbf6a16e193b328c5e551eBehdad Esfahbod if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); 1573e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod switch (u.format) { 1574b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 1: return_trace (c->dispatch (u.format1)); 1575b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 2: return_trace (c->dispatch (u.format2)); 1576b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 3: return_trace (c->dispatch (u.format3)); 1577b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod default:return_trace (c->default_return_value ()); 1578e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1579e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1580e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1581ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 158266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod union { 15836f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier */ 1584dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ContextFormat1 format1; 1585dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ContextFormat2 format2; 1586dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ContextFormat3 format3; 158766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } u; 158866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 158966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1590ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 1591ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod/* Chaining Contextual lookups */ 1592ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 159331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstruct ChainContextClosureLookupContext 159460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 159531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ContextClosureFuncs funcs; 159631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const void *intersects_data[3]; 159731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod}; 159831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1599f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbodstruct ChainContextCollectGlyphsLookupContext 1600f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod{ 1601f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod ContextCollectGlyphsFuncs funcs; 1602f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const void *collect_data[3]; 1603f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod}; 1604f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 160531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstruct ChainContextApplyLookupContext 160631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 160731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ContextApplyFuncs funcs; 160840cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod const void *match_data[3]; 160948f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod}; 161048f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod 16115caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbodstatic inline void chain_context_closure_lookup (hb_closure_context_t *c, 161231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int backtrackCount, 16136f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 backtrack[], 161431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 16156f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 input[], /* Array of input values--start with second glyph */ 161631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int lookaheadCount, 16176f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 lookahead[], 161831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int lookupCount, 161931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const LookupRecord lookupRecord[], 162031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ChainContextClosureLookupContext &lookup_context) 162131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 16225caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod if (intersects_array (c, 16235caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod backtrackCount, backtrack, 16245caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context.funcs.intersects, lookup_context.intersects_data[0]) 16255caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod && intersects_array (c, 16265caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inputCount ? inputCount - 1 : 0, input, 16275caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context.funcs.intersects, lookup_context.intersects_data[1]) 162874439d0aa10184451adc6c6469f5119be352ecbbBehdad Esfahbod && intersects_array (c, 16295caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookaheadCount, lookahead, 16305caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context.funcs.intersects, lookup_context.intersects_data[2])) 1631d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod recurse_lookups (c, 1632d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookupCount, lookupRecord); 163331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 163431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1635f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbodstatic inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, 1636f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int backtrackCount, 16376f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 backtrack[], 1638f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 16396f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 input[], /* Array of input values--start with second glyph */ 1640f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int lookaheadCount, 16416f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 lookahead[], 1642f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int lookupCount, 1643f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const LookupRecord lookupRecord[], 1644f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod ChainContextCollectGlyphsLookupContext &lookup_context) 1645f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod{ 16468303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod collect_array (c, c->before, 1647f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod backtrackCount, backtrack, 1648f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup_context.funcs.collect, lookup_context.collect_data[0]); 16498303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod collect_array (c, c->input, 1650f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod inputCount ? inputCount - 1 : 0, input, 1651f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup_context.funcs.collect, lookup_context.collect_data[1]); 16528303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod collect_array (c, c->after, 1653f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookaheadCount, lookahead, 1654f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup_context.funcs.collect, lookup_context.collect_data[2]); 1655f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod recurse_lookups (c, 1656f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookupCount, lookupRecord); 1657f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod} 1658f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 1659e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbodstatic inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c, 1660e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int backtrackCount, 16616f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 backtrack[] HB_UNUSED, 1662e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 16636f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 input[], /* Array of input values--start with second glyph */ 1664e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int lookaheadCount, 16656f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 lookahead[] HB_UNUSED, 16660beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod unsigned int lookupCount HB_UNUSED, 16670beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod const LookupRecord lookupRecord[] HB_UNUSED, 1668e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod ChainContextApplyLookupContext &lookup_context) 1669e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod{ 1670d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod return (c->zero_context ? !backtrackCount && !lookaheadCount : true) 16711f2bb172fe9a173ecfd61054f1fdd850943ef059Behdad Esfahbod && would_match_input (c, 1672e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inputCount, input, 1673e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod lookup_context.funcs.match, lookup_context.match_data[1]); 1674e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod} 1675e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 167631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstatic inline bool chain_context_apply_lookup (hb_apply_context_t *c, 167731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int backtrackCount, 16786f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 backtrack[], 167931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 16806f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 input[], /* Array of input values--start with second glyph */ 168131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int lookaheadCount, 16826f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 lookahead[], 168331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int lookupCount, 168431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const LookupRecord lookupRecord[], 168531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ChainContextApplyLookupContext &lookup_context) 168602e1e5c63fa4f896053fa3c21e495239e1e9caa2Behdad Esfahbod{ 168740bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod unsigned int start_index = 0, match_length = 0, end_index = 0; 16885ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; 1689f19e0b0099ec73b8fedccacff4902403f5eabc42Behdad Esfahbod return match_input (c, 16904169710911450e0f9bc045fe279bfc8ba9e8457cBehdad Esfahbod inputCount, input, 16914169710911450e0f9bc045fe279bfc8ba9e8457cBehdad Esfahbod lookup_context.funcs.match, lookup_context.match_data[1], 16926b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod &match_length, match_positions) 1693f19e0b0099ec73b8fedccacff4902403f5eabc42Behdad Esfahbod && match_backtrack (c, 1694f19e0b0099ec73b8fedccacff4902403f5eabc42Behdad Esfahbod backtrackCount, backtrack, 169540bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod lookup_context.funcs.match, lookup_context.match_data[0], 169640bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod &start_index) 1697d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod && match_lookahead (c, 16984169710911450e0f9bc045fe279bfc8ba9e8457cBehdad Esfahbod lookaheadCount, lookahead, 16994169710911450e0f9bc045fe279bfc8ba9e8457cBehdad Esfahbod lookup_context.funcs.match, lookup_context.match_data[2], 170040bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod match_length, &end_index) 170140bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod && (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index), 170240bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod apply_lookup (c, 17036b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod inputCount, match_positions, 17046b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod lookupCount, lookupRecord, 170540bd7e9a1cf422b17f15d0f66547bde9098e6ef3Behdad Esfahbod match_length)); 170602e1e5c63fa4f896053fa3c21e495239e1e9caa2Behdad Esfahbod} 170748f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod 170860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ChainRule 170960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 17105caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const 171131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod { 1712be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 17136f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack); 17146f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input); 171531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 17165caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod chain_context_closure_lookup (c, 17175caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod backtrack.len, backtrack.array, 17185caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod input.len, input.array, 17195caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookahead.len, lookahead.array, 17205caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup.len, lookup.array, 17215caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context); 172231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 172331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1724f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const 1725f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod { 1726f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 17276f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack); 17286f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input); 1729f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 1730f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod chain_context_collect_glyphs_lookup (c, 1731f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod backtrack.len, backtrack.array, 1732f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod input.len, input.array, 1733f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookahead.len, lookahead.array, 1734f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup.len, lookup.array, 1735f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup_context); 1736f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod } 1737f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 1738e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 1739e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1740be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 17416f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack); 17426f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input); 1743e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 1744b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (chain_context_would_apply_lookup (c, 1745b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod backtrack.len, backtrack.array, 1746b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod input.len, input.array, 1747b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod lookahead.len, lookahead.array, lookup.len, 1748b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod lookup.array, lookup_context)); 1749e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1750e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 175131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 175260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1753be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 17546f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack); 17556f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input); 1756e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 1757b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (chain_context_apply_lookup (c, 1758b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod backtrack.len, backtrack.array, 1759b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod input.len, input.array, 1760b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod lookahead.len, lookahead.array, lookup.len, 1761b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod lookup.array, lookup_context)); 1762aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod } 1763aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 1764de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1765de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1766be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1767b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!backtrack.sanitize (c)) return_trace (false); 17686f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack); 1769b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!input.sanitize (c)) return_trace (false); 17706f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input); 1771b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!lookahead.sanitize (c)) return_trace (false); 1772de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 1773b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (lookup.sanitize (c)); 177470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 1775ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 1776ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 17776f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod ArrayOf<UINT16> 1778dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod backtrack; /* Array of backtracking values 1779ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * (to be matched before the input 1780ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * sequence) */ 17816f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod HeadlessArrayOf<UINT16> 1782e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod inputX; /* Array of input values (start with 1783ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * second glyph) */ 17846f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod ArrayOf<UINT16> 1785dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod lookaheadX; /* Array of lookahead values's (to be 178648f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod * matched after the input sequence) */ 1787dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod ArrayOf<LookupRecord> 178802e1e5c63fa4f896053fa3c21e495239e1e9caa2Behdad Esfahbod lookupX; /* Array of LookupRecords--in 1789ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * design order) */ 1790b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 1791bea34c7cbb583cf7660776e95cab3171590b8427Behdad Esfahbod DEFINE_SIZE_MIN (8); 1792ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 1793ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 179460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ChainRuleSet 179560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 17965caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const 179731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod { 1798be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 179931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int num_rules = rule.len; 180031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 18015caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod (this+rule[i]).closure (c, lookup_context); 180231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 180331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1804f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const 1805f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod { 1806f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 1807f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int num_rules = rule.len; 1808f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 1809f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod (this+rule[i]).collect_glyphs (c, lookup_context); 1810f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod } 1811f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 1812e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 1813e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1814be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1815e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int num_rules = rule.len; 1816e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 1817e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod if ((this+rule[i]).would_apply (c, lookup_context)) 1818b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 1819e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1820b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 1821e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1822e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 182331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 182460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1825be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 182648f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod unsigned int num_rules = rule.len; 182760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 1828d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod if ((this+rule[i]).apply (c, lookup_context)) 1829b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 183048f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod 1831b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 183248f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod } 1833ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 1834de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1835de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1836be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1837b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rule.sanitize (c, this)); 183870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 183970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1840ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 184148f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod OffsetArrayOf<ChainRule> 184248f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod rule; /* Array of ChainRule tables 184348f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod * ordered by preference */ 1844b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 18450eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (2, rule); 1846ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 1847ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 184860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ChainContextFormat1 184960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 185044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline void closure (hb_closure_context_t *c) const 1851f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 1852be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 185331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const Coverage &cov = (this+coverage); 185431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 185531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ChainContextClosureLookupContext lookup_context = { 185644fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod {intersects_glyph}, 1857dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod {nullptr, nullptr, nullptr} 185831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod }; 185931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 186031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = ruleSet.len; 186131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 186231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (cov.intersects_coverage (c->glyphs, i)) { 186331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ChainRuleSet &rule_set = this+ruleSet[i]; 18645caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod rule_set.closure (c, lookup_context); 186531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 1866f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 1867f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 186826514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 186926514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 1870f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 18718303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+coverage).add_coverage (c->input); 1872f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 1873f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod struct ChainContextCollectGlyphsLookupContext lookup_context = { 1874f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod {collect_glyph}, 1875dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod {nullptr, nullptr, nullptr} 1876f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod }; 1877f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 1878f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int count = ruleSet.len; 1879f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1880f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod (this+ruleSet[i]).collect_glyphs (c, lookup_context); 188126514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 188226514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 1883e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 1884e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1885be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1886e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1887b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])]; 1888e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod struct ChainContextApplyLookupContext lookup_context = { 1889ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_glyph}, 1890dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod {nullptr, nullptr, nullptr} 1891e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod }; 1892b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rule_set.would_apply (c, lookup_context)); 1893e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1894e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 189544fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline const Coverage &get_coverage (void) const 189644fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 189744fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod return this+coverage; 189844fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 189944fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 1900ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 190160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1902be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 1903b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 1904b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (likely (index == NOT_COVERED)) return_trace (false); 1905ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 1906aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod const ChainRuleSet &rule_set = this+ruleSet[index]; 190731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ChainContextApplyLookupContext lookup_context = { 1908ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_glyph}, 1909dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod {nullptr, nullptr, nullptr} 1910aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod }; 1911b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rule_set.apply (c, lookup_context)); 1912aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod } 191370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1914de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1915de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1916be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1917b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); 191870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 191970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1920ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 19216f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier--format = 1 */ 192248f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod OffsetTo<Coverage> 192348f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod coverage; /* Offset to Coverage table--from 1924ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * beginning of table */ 1925aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetArrayOf<ChainRuleSet> 1926aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod ruleSet; /* Array of ChainRuleSet tables 1927aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod * ordered by Coverage Index */ 1928b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 19290eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, ruleSet); 1930ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 1931ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 193260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ChainContextFormat2 193360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 193444fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline void closure (hb_closure_context_t *c) const 1935f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 1936be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 193731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (!(this+coverage).intersects (c->glyphs)) 19385caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod return; 193931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 194031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ClassDef &backtrack_class_def = this+backtrackClassDef; 194131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ClassDef &input_class_def = this+inputClassDef; 194231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ClassDef &lookahead_class_def = this+lookaheadClassDef; 194331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 194431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ChainContextClosureLookupContext lookup_context = { 194544fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod {intersects_class}, 194631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod {&backtrack_class_def, 194731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod &input_class_def, 194831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod &lookahead_class_def} 194931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod }; 195031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 195131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = ruleSet.len; 195231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 195331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (input_class_def.intersects_class (c->glyphs, i)) { 195431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ChainRuleSet &rule_set = this+ruleSet[i]; 19555caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod rule_set.closure (c, lookup_context); 195631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 1957f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 1958f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 195926514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 196026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 1961f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 19628303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+coverage).add_coverage (c->input); 1963f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 196411fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod const ClassDef &backtrack_class_def = this+backtrackClassDef; 196511fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod const ClassDef &input_class_def = this+inputClassDef; 196611fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod const ClassDef &lookahead_class_def = this+lookaheadClassDef; 196711fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod 1968f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod struct ChainContextCollectGlyphsLookupContext lookup_context = { 1969f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod {collect_class}, 197011fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod {&backtrack_class_def, 197111fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod &input_class_def, 197211fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod &lookahead_class_def} 1973f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod }; 1974f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 1975f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int count = ruleSet.len; 1976f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1977f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod (this+ruleSet[i]).collect_glyphs (c, lookup_context); 197826514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 197926514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 1980e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 1981e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1982be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1983e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 198411fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod const ClassDef &backtrack_class_def = this+backtrackClassDef; 1985e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const ClassDef &input_class_def = this+inputClassDef; 198611fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod const ClassDef &lookahead_class_def = this+lookaheadClassDef; 1987e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 19882dc1141d7d0a9f5818862b09d6b9cfe0a27f1fc1Behdad Esfahbod unsigned int index = input_class_def.get_class (c->glyphs[0]); 1989e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const ChainRuleSet &rule_set = this+ruleSet[index]; 1990e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod struct ChainContextApplyLookupContext lookup_context = { 1991ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_class}, 199211fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod {&backtrack_class_def, 199311fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod &input_class_def, 199411fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod &lookahead_class_def} 1995e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod }; 1996b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rule_set.would_apply (c, lookup_context)); 1997e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1998e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 199944fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline const Coverage &get_coverage (void) const 200044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 200144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod return this+coverage; 200244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 200344fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 2004ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 200560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 2006be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 2007b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 2008b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (likely (index == NOT_COVERED)) return_trace (false); 2009aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 2010aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod const ClassDef &backtrack_class_def = this+backtrackClassDef; 2011aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod const ClassDef &input_class_def = this+inputClassDef; 2012aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod const ClassDef &lookahead_class_def = this+lookaheadClassDef; 2013aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 20142dc1141d7d0a9f5818862b09d6b9cfe0a27f1fc1Behdad Esfahbod index = input_class_def.get_class (c->buffer->cur().codepoint); 2015aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod const ChainRuleSet &rule_set = this+ruleSet[index]; 201631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ChainContextApplyLookupContext lookup_context = { 2017ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_class}, 201840cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod {&backtrack_class_def, 201940cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod &input_class_def, 202040cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod &lookahead_class_def} 2021aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod }; 2022b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rule_set.apply (c, lookup_context)); 2023ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod } 2024ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 2025de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 2026de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 2027be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 2028b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (coverage.sanitize (c, this) && 2029b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod backtrackClassDef.sanitize (c, this) && 2030b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod inputClassDef.sanitize (c, this) && 2031b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod lookaheadClassDef.sanitize (c, this) && 2032b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod ruleSet.sanitize (c, this)); 203370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 203470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 2035ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 20366f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier--format = 2 */ 2037aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetTo<Coverage> 2038aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod coverage; /* Offset to Coverage table--from 2039ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * beginning of table */ 2040aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetTo<ClassDef> 2041aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod backtrackClassDef; /* Offset to glyph ClassDef table 2042ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * containing backtrack sequence 2043ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * data--from beginning of table */ 2044aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetTo<ClassDef> 2045aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod inputClassDef; /* Offset to glyph ClassDef 2046ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * table containing input sequence 2047ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * data--from beginning of table */ 2048aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetTo<ClassDef> 2049aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod lookaheadClassDef; /* Offset to glyph ClassDef table 2050ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * containing lookahead sequence 2051ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * data--from beginning of table */ 2052aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetArrayOf<ChainRuleSet> 2053aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod ruleSet; /* Array of ChainRuleSet tables 2054aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod * ordered by class */ 2055b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 20560eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (12, ruleSet); 2057ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 2058ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 205960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ChainContextFormat3 206060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 206144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline void closure (hb_closure_context_t *c) const 2062f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 2063be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 20645caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20655caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod 20665caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod if (!(this+input[0]).intersects (c->glyphs)) 20675caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod return; 20685caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod 20695caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 20705caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 20715caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod struct ChainContextClosureLookupContext lookup_context = { 207244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod {intersects_coverage}, 20735caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod {this, this, this} 20745caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod }; 20755caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod chain_context_closure_lookup (c, 20766f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod backtrack.len, (const UINT16 *) backtrack.array, 20776f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod input.len, (const UINT16 *) input.array + 1, 20786f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod lookahead.len, (const UINT16 *) lookahead.array, 20795caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup.len, lookup.array, 20805caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context); 2081f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 2082f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 208326514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 208426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 2085f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 2086f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 2087f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 20888303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+input[0]).add_coverage (c->input); 2089f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 2090f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 2091f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 2092f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod struct ChainContextCollectGlyphsLookupContext lookup_context = { 2093f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod {collect_coverage}, 2094f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod {this, this, this} 2095f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod }; 2096f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod chain_context_collect_glyphs_lookup (c, 20976f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod backtrack.len, (const UINT16 *) backtrack.array, 20986f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod input.len, (const UINT16 *) input.array + 1, 20996f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod lookahead.len, (const UINT16 *) lookahead.array, 2100f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup.len, lookup.array, 2101f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup_context); 210226514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 210326514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 2104e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 2105e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 2106be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 2107e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 2108e6f7479fe34fb4a7cada61d84c2ed70d1fd565c8Behdad Esfahbod const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 2109e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 2110e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 2111e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod struct ChainContextApplyLookupContext lookup_context = { 2112ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_coverage}, 2113e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod {this, this, this} 2114e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod }; 2115b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (chain_context_would_apply_lookup (c, 21166f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod backtrack.len, (const UINT16 *) backtrack.array, 21176f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod input.len, (const UINT16 *) input.array + 1, 21186f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod lookahead.len, (const UINT16 *) lookahead.array, 2119b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod lookup.len, lookup.array, lookup_context)); 2120e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 2121e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 212244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline const Coverage &get_coverage (void) const 212344fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 212444fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 212544fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod return this+input[0]; 212644fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 212744fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 2128ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 212960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 2130be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 2131e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 213202e1e5c63fa4f896053fa3c21e495239e1e9caa2Behdad Esfahbod 2133b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); 2134b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (likely (index == NOT_COVERED)) return_trace (false); 213502e1e5c63fa4f896053fa3c21e495239e1e9caa2Behdad Esfahbod 2136e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 2137e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 213831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ChainContextApplyLookupContext lookup_context = { 2139ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_coverage}, 214040cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod {this, this, this} 2141aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod }; 2142b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (chain_context_apply_lookup (c, 21436f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod backtrack.len, (const UINT16 *) backtrack.array, 21446f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod input.len, (const UINT16 *) input.array + 1, 21456f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod lookahead.len, (const UINT16 *) lookahead.array, 2146b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod lookup.len, lookup.array, lookup_context)); 2147aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod } 2148aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 2149de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 2150de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 2151be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 2152b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!backtrack.sanitize (c, this)) return_trace (false); 2153de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 2154b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!input.sanitize (c, this)) return_trace (false); 2155b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!input.len) return_trace (false); /* To be consistent with Context. */ 2156de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 2157b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!lookahead.sanitize (c, this)) return_trace (false); 2158de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 2159b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (lookup.sanitize (c)); 216070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 216170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 2162ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 21636f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier--format = 3 */ 2164dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod OffsetArrayOf<Coverage> 216513ed4405c558e445b052360f1ed8ee27ecf48e6eBehdad Esfahbod backtrack; /* Array of coverage tables 2166ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * in backtracking sequence, in glyph 2167ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * sequence order */ 2168dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod OffsetArrayOf<Coverage> 216913ed4405c558e445b052360f1ed8ee27ecf48e6eBehdad Esfahbod inputX ; /* Array of coverage 2170ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * tables in input sequence, in glyph 2171ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * sequence order */ 2172dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod OffsetArrayOf<Coverage> 217313ed4405c558e445b052360f1ed8ee27ecf48e6eBehdad Esfahbod lookaheadX; /* Array of coverage tables 2174ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * in lookahead sequence, in glyph 2175ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * sequence order */ 2176dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod ArrayOf<LookupRecord> 217702e1e5c63fa4f896053fa3c21e495239e1e9caa2Behdad Esfahbod lookupX; /* Array of LookupRecords--in 2178dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod * design order) */ 2179b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 2180bea34c7cbb583cf7660776e95cab3171590b8427Behdad Esfahbod DEFINE_SIZE_MIN (10); 2181ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 2182ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 218360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ChainContext 218460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 218544fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod template <typename context_t> 21869c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 2187e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 218800f6a8e334ec4c586e4e633a95b411ccb50306d3Behdad Esfahbod TRACE_DISPATCH (this, u.format); 2189f396fbb000dc1c8acddbf6a16e193b328c5e551eBehdad Esfahbod if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); 2190e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod switch (u.format) { 2191b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 1: return_trace (c->dispatch (u.format1)); 2192b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 2: return_trace (c->dispatch (u.format2)); 2193b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 3: return_trace (c->dispatch (u.format3)); 2194b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod default:return_trace (c->default_return_value ()); 2195e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 2196e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 2197e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 2198ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 2199ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod union { 22006f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier */ 2201dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ChainContextFormat1 format1; 2202dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ChainContextFormat2 format2; 2203dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ChainContextFormat3 format3; 2204ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod } u; 2205ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 2206ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 2207ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 2208095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbodtemplate <typename T> 2209d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbodstruct ExtensionFormat1 2210d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod{ 2211d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod inline unsigned int get_type (void) const { return extensionLookupType; } 2212d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod 2213095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod template <typename X> 2214095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod inline const X& get_subtable (void) const 2215095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod { 2216095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod unsigned int offset = extensionOffset; 2217095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod if (unlikely (!offset)) return Null(typename T::LookupSubTable); 2218095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod return StructAtOffset<typename T::LookupSubTable> (this, offset); 2219095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod } 2220095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod 2221095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod template <typename context_t> 2222095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 2223095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod { 2224095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod TRACE_DISPATCH (this, format); 2225f396fbb000dc1c8acddbf6a16e193b328c5e551eBehdad Esfahbod if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ()); 2226b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ())); 2227095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod } 2228095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod 2229095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod /* This is called from may_dispatch() above with hb_sanitize_context_t. */ 2230de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 2231de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 2232be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 2233b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && extensionOffset != 0); 223470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 223570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 2236ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 22376f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier. Set to 1. */ 22386f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 extensionLookupType; /* Lookup type of subtable referenced 2239d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod * by ExtensionOffset (i.e. the 2240d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod * extension subtable). */ 22416f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT32 extensionOffset; /* Offset to the extension subtable, 224281f2af40f9afd5bb9695018e6baddcd4aa3361c1Behdad Esfahbod * of lookup type subtable. */ 2243b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 2244b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod DEFINE_SIZE_STATIC (8); 2245d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod}; 2246d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod 2247653eeb26450053b731b46346606931f5ae88db72Behdad Esfahbodtemplate <typename T> 2248d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbodstruct Extension 2249d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod{ 2250d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod inline unsigned int get_type (void) const 2251d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod { 2252d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod switch (u.format) { 2253dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 1: return u.format1.get_type (); 2254d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod default:return 0; 2255d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod } 2256d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod } 22577dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod template <typename X> 22587dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod inline const X& get_subtable (void) const 22597dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod { 2260095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod switch (u.format) { 2261095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod case 1: return u.format1.template get_subtable<typename T::LookupSubTable> (); 2262095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod default:return Null(typename T::LookupSubTable); 2263095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod } 22647dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod } 22657dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod 2266653eeb26450053b731b46346606931f5ae88db72Behdad Esfahbod template <typename context_t> 22679c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 2268653eeb26450053b731b46346606931f5ae88db72Behdad Esfahbod { 2269095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod TRACE_DISPATCH (this, u.format); 2270f396fbb000dc1c8acddbf6a16e193b328c5e551eBehdad Esfahbod if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); 227170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 2272b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 1: return_trace (u.format1.dispatch (c)); 2273b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod default:return_trace (c->default_return_value ()); 227470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 227570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 227670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 2277ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 2278d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod union { 22796f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier */ 2280095a1257cc3cc56b044b4cd842a92f0d0f933a50Behdad Esfahbod ExtensionFormat1<T> format1; 2281d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod } u; 2282d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod}; 2283d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod 2284d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod 2285f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod/* 2286f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod * GSUB/GPOS Common 2287f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod */ 2288f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod 228960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct GSUBGPOS 229060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 2291bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_script_count (void) const 2292bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+scriptList).len; } 2293bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Tag& get_script_tag (unsigned int i) const 2294bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+scriptList).get_tag (i); } 2295e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_script_tags (unsigned int start_offset, 2296e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *script_count /* IN/OUT */, 2297e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod hb_tag_t *script_tags /* OUT */) const 2298e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return (this+scriptList).get_tags (start_offset, script_count, script_tags); } 2299bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Script& get_script (unsigned int i) const 2300bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+scriptList)[i]; } 2301bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline bool find_script_index (hb_tag_t tag, unsigned int *index) const 2302bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+scriptList).find_index (tag, index); } 2303bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 2304bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_feature_count (void) const 2305bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+featureList).len; } 2306da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew inline hb_tag_t get_feature_tag (unsigned int i) const 2307da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew { return i == Index::NOT_FOUND_INDEX ? HB_TAG_NONE : (this+featureList).get_tag (i); } 2308e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_feature_tags (unsigned int start_offset, 2309e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 2310e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod hb_tag_t *feature_tags /* OUT */) const 2311e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return (this+featureList).get_tags (start_offset, feature_count, feature_tags); } 2312bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Feature& get_feature (unsigned int i) const 2313bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+featureList)[i]; } 2314bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const 2315bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+featureList).find_index (tag, index); } 2316bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 2317bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_lookup_count (void) const 2318bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+lookupList).len; } 2319bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Lookup& get_lookup (unsigned int i) const 2320bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+lookupList)[i]; } 2321f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod 232230c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod inline bool find_variations_index (const int *coords, unsigned int num_coords, 232330c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod unsigned int *index) const 232459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations)) 232530c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod .find_index (coords, num_coords, index); } 2326ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod inline const Feature& get_feature_variation (unsigned int feature_index, 2327ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod unsigned int variations_index) const 2328ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod { 2329ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod if (FeatureVariations::NOT_FOUND_INDEX != variations_index && 2330ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod version.to_int () >= 0x00010001u) 2331ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod { 23324ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod const Feature *feature = (this+featureVars).find_substitute (variations_index, 23334ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod feature_index); 2334ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod if (feature) 2335ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod return *feature; 2336ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod } 2337ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod return get_feature (feature_index); 2338ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod } 233959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 2340de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 2341de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 2342be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 2343b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (version.sanitize (c) && 2344b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod likely (version.major == 1) && 2345b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod scriptList.sanitize (c, this) && 2346b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod featureList.sanitize (c, this) && 234759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod lookupList.sanitize (c, this) && 234859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod (version.to_int () < 0x00010001u || featureVars.sanitize (c, this))); 2349cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 2350cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 2351212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod protected: 23529a13ed453ef96822a47d6e6f58332b87f38d5c59Behdad Esfahbod FixedVersion<>version; /* Version of the GSUB/GPOS table--initially set 23537627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod * to 0x00010000u */ 2354f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod OffsetTo<ScriptList> 2355f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod scriptList; /* ScriptList table */ 2356f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod OffsetTo<FeatureList> 2357f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod featureList; /* FeatureList table */ 2358f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod OffsetTo<LookupList> 2359f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod lookupList; /* LookupList table */ 23605e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod LOffsetTo<FeatureVariations> 236159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod featureVars; /* Offset to Feature Variations 236259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod table--from beginning of table 236359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod * (may be NULL). Introduced 236459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod * in version 0x00010001. */ 2365b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 236659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_MIN (10); 2367f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod}; 236866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 23696f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 23707d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod} /* namespace OT */ 23717c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 2372acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 23735f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ 2374