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 3222da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod#include "hb-buffer-private.hh" 337a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#include "hb-ot-layout-gdef-table.hh" 341336ecdf8e4e9879b96b26ecfbf5c9ba6c49e2b9Behdad Esfahbod#include "hb-set-private.hh" 35f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 3666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 377c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodnamespace OT { 387c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 39acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 40902cc8aca0b3ff25eeee50b3a84d729e31731ef3Behdad Esfahbod 4100f6a8e334ec4c586e4e633a95b411ccb50306d3Behdad Esfahbod#define TRACE_DISPATCH(this, format) \ 42a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \ 43a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 4400f6a8e334ec4c586e4e633a95b411ccb50306d3Behdad Esfahbod "format %d", (int) format); 45a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod 46f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod#ifndef HB_DEBUG_CLOSURE 47f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod#define HB_DEBUG_CLOSURE (HB_DEBUG+0) 48f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod#endif 49f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 50be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod#define TRACE_CLOSURE(this) \ 51130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \ 522c53bd3c3ec4f81eff126c5bf84b7f2ddf2f0fefBehdad Esfahbod (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 53902cc8aca0b3ff25eeee50b3a84d729e31731ef3Behdad Esfahbod ""); 54f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 55f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbodstruct hb_closure_context_t 56f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod{ 57a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod inline const char *get_name (void) { return "CLOSURE"; } 58a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE; 59130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod typedef hb_void_t return_t; 6044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); 6144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod template <typename T> 629c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; } 63130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod static return_t default_return_value (void) { return HB_VOID; } 647b912c1936c3e8a7df27a30782ca127d0a83822dBehdad Esfahbod bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } 6544fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod return_t recurse (unsigned int lookup_index) 6644fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 679b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod if (unlikely (nesting_level_left == 0 || !recurse_func)) 682005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod return default_return_value (); 6944fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 7044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod nesting_level_left--; 7144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod recurse_func (this, lookup_index); 7244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod nesting_level_left++; 73130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod return HB_VOID; 7444fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 7544fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 76f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod hb_face_t *face; 776a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod hb_set_t *glyphs; 7844fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod recurse_func_t recurse_func; 79f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod unsigned int nesting_level_left; 80f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod unsigned int debug_depth; 81f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 82f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod hb_closure_context_t (hb_face_t *face_, 836a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod hb_set_t *glyphs_, 84f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : 85e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod face (face_), 86e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod glyphs (glyphs_), 879b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod recurse_func (NULL), 88f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod nesting_level_left (nesting_level_left_), 89f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod debug_depth (0) {} 909b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod 919b34677f362fb0ef5a7cb8a284a9e06d1a4cc03bBehdad Esfahbod void set_recurse_func (recurse_func_t func) { recurse_func = func; } 92f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod}; 93f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 94f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 95f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 96472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod#ifndef HB_DEBUG_WOULD_APPLY 97472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0) 98472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod#endif 99472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod 100be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod#define TRACE_WOULD_APPLY(this) \ 101902cc8aca0b3ff25eeee50b3a84d729e31731ef3Behdad Esfahbod hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \ 1022c53bd3c3ec4f81eff126c5bf84b7f2ddf2f0fefBehdad Esfahbod (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 103902cc8aca0b3ff25eeee50b3a84d729e31731ef3Behdad Esfahbod "%d glyphs", c->len); 104e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 105e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbodstruct hb_would_apply_context_t 106e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod{ 107a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod inline const char *get_name (void) { return "WOULD_APPLY"; } 108a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY; 1091d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod typedef bool return_t; 1101d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod template <typename T> 1119c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline return_t dispatch (const T &obj) { return obj.would_apply (this); } 1121d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod static return_t default_return_value (void) { return false; } 1137b912c1936c3e8a7df27a30782ca127d0a83822dBehdad Esfahbod bool stop_sublookup_iteration (return_t r) const { return r; } 1141d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod 115e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod hb_face_t *face; 116472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod const hb_codepoint_t *glyphs; 117e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int len; 118d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod bool zero_context; 119e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int debug_depth; 120e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 121e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod hb_would_apply_context_t (hb_face_t *face_, 122472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod const hb_codepoint_t *glyphs_, 123472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod unsigned int len_, 1242bd9fe359839a653f7caae534bf768af1735f155Behdad Esfahbod bool zero_context_) : 125e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod face (face_), 126472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod glyphs (glyphs_), 127472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod len (len_), 128d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod zero_context (zero_context_), 129a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod debug_depth (0) {} 130e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod}; 131e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 132e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 133e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 134e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod#ifndef HB_DEBUG_COLLECT_GLYPHS 135e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod#define HB_DEBUG_COLLECT_GLYPHS (HB_DEBUG+0) 136e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod#endif 137e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 138be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod#define TRACE_COLLECT_GLYPHS(this) \ 139130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \ 1402c53bd3c3ec4f81eff126c5bf84b7f2ddf2f0fefBehdad Esfahbod (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 141902cc8aca0b3ff25eeee50b3a84d729e31731ef3Behdad Esfahbod ""); 142e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 143e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbodstruct hb_collect_glyphs_context_t 144e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod{ 145a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod inline const char *get_name (void) { return "COLLECT_GLYPHS"; } 146a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS; 147130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod typedef hb_void_t return_t; 14826514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); 1491d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod template <typename T> 1509c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; } 151130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod static return_t default_return_value (void) { return HB_VOID; } 1527b912c1936c3e8a7df27a30782ca127d0a83822dBehdad Esfahbod bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } 1531d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod return_t recurse (unsigned int lookup_index) 1541d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod { 15526514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod if (unlikely (nesting_level_left == 0 || !recurse_func)) 15626514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod return default_return_value (); 15726514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 1581bcfa06d1173f219809542a7380ce77f1c907becBehdad Esfahbod /* Note that GPOS sets recurse_func to NULL already, so it doesn't get 1591bcfa06d1173f219809542a7380ce77f1c907becBehdad Esfahbod * past the previous check. For GSUB, we only want to collect the output 16076ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod * glyphs in the recursion. If output is not requested, we can go home now. 16176ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod * 16276ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod * Note further, that the above is not exactly correct. A recursed lookup 16376ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod * is allowed to match input that is not matched in the context, but that's 16476ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod * not how most fonts are built. It's possible to relax that and recurse 16576ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod * with all sets here if it proves to be an issue. 16676ea563673d24ae1673a5aa3a21da6014479d433Behdad Esfahbod */ 1674a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod 1684a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod if (output == hb_set_get_empty ()) 169130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod return HB_VOID; 1704a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod 171fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod /* Return if new lookup was recursed to before. */ 172fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod if (recursed_lookups.has (lookup_index)) 173fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod return HB_VOID; 174fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod 1754a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod hb_set_t *old_before = before; 1764a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod hb_set_t *old_input = input; 1774a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod hb_set_t *old_after = after; 1784a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod before = input = after = hb_set_get_empty (); 1791bcfa06d1173f219809542a7380ce77f1c907becBehdad Esfahbod 18026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod nesting_level_left--; 1814a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod recurse_func (this, lookup_index); 18226514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod nesting_level_left++; 1834a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod 1844a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod before = old_before; 1854a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod input = old_input; 1864a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod after = old_after; 1874a350d0eb25db60d95638664c892d4c8dacf050bBehdad Esfahbod 188fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod recursed_lookups.add (lookup_index); 189fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod 190130bb3f6144afe5c88bb5b4e4c98e7cba03b1e26Behdad Esfahbod return HB_VOID; 1911d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod } 1921d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod 193e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_face_t *face; 1948303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod hb_set_t *before; 1958303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod hb_set_t *input; 1968303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod hb_set_t *after; 1978303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod hb_set_t *output; 19826514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod recurse_func_t recurse_func; 199fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod hb_set_t recursed_lookups; 20026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod unsigned int nesting_level_left; 201e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod unsigned int debug_depth; 202e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 203e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_collect_glyphs_context_t (hb_face_t *face_, 204e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_set_t *glyphs_before, /* OUT. May be NULL */ 205e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_set_t *glyphs_input, /* OUT. May be NULL */ 206e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod hb_set_t *glyphs_after, /* OUT. May be NULL */ 20726514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod hb_set_t *glyphs_output, /* OUT. May be NULL */ 20826514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : 209e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod face (face_), 2108303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod before (glyphs_before ? glyphs_before : hb_set_get_empty ()), 2118303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod input (glyphs_input ? glyphs_input : hb_set_get_empty ()), 2128303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod after (glyphs_after ? glyphs_after : hb_set_get_empty ()), 2138303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod output (glyphs_output ? glyphs_output : hb_set_get_empty ()), 21426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod recurse_func (NULL), 215fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod recursed_lookups (), 21626514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod nesting_level_left (nesting_level_left_), 217fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod debug_depth (0) 218fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod { 219fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod recursed_lookups.init (); 220fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod } 221fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod ~hb_collect_glyphs_context_t (void) 222fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod { 223fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod recursed_lookups.fini (); 224fde3e4a423871463c883cb969e99c29cb6f69f6bBehdad Esfahbod } 22526514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 22626514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod void set_recurse_func (recurse_func_t func) { recurse_func = func; } 227e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod}; 228e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 229e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 230e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod 231295ef1dd5229f47d8e0eb5b4eb48c90a6b470073Behdad Esfahbod#ifndef HB_DEBUG_GET_COVERAGE 232295ef1dd5229f47d8e0eb5b4eb48c90a6b470073Behdad Esfahbod#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0) 233295ef1dd5229f47d8e0eb5b4eb48c90a6b470073Behdad Esfahbod#endif 234295ef1dd5229f47d8e0eb5b4eb48c90a6b470073Behdad Esfahbod 2352005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbodstruct hb_get_coverage_context_t 2362005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod{ 237a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod inline const char *get_name (void) { return "GET_COVERAGE"; } 238295ef1dd5229f47d8e0eb5b4eb48c90a6b470073Behdad Esfahbod static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE; 2392005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod typedef const Coverage &return_t; 2402005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod template <typename T> 2419c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline return_t dispatch (const T &obj) { return obj.get_coverage (); } 242a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod static return_t default_return_value (void) { return Null(Coverage); } 2431d67ef980f35ae30d4f8975f65ee07b8cc5deeeaBehdad Esfahbod 244a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod hb_get_coverage_context_t (void) : 245a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod debug_depth (0) {} 246a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod 247a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod unsigned int debug_depth; 2482005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod}; 2492005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod 2502005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod 2512005fa5340fc528c32dc2af945ad2431964a47d2Behdad Esfahbod 2520535b50f436f3dac85e6df1761957f86c2bd7213Behdad Esfahbod#ifndef HB_DEBUG_APPLY 25311e3ec444a85fc72541823c2e98cc92c4ceb19afBehdad Esfahbod#define HB_DEBUG_APPLY (HB_DEBUG+0) 2540535b50f436f3dac85e6df1761957f86c2bd7213Behdad Esfahbod#endif 2550535b50f436f3dac85e6df1761957f86c2bd7213Behdad Esfahbod 256be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod#define TRACE_APPLY(this) \ 257902cc8aca0b3ff25eeee50b3a84d729e31731ef3Behdad Esfahbod hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \ 2582c53bd3c3ec4f81eff126c5bf84b7f2ddf2f0fefBehdad Esfahbod (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 259902cc8aca0b3ff25eeee50b3a84d729e31731ef3Behdad Esfahbod "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint); 2600535b50f436f3dac85e6df1761957f86c2bd7213Behdad Esfahbod 2611376fb7bf9ef07970f0ba13dc64d6a8ab8252762Behdad Esfahbodstruct hb_apply_context_t 2621376fb7bf9ef07970f0ba13dc64d6a8ab8252762Behdad Esfahbod{ 263a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod inline const char *get_name (void) { return "APPLY"; } 264a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod static const unsigned int max_debug_depth = HB_DEBUG_APPLY; 265ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod typedef bool return_t; 266ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index); 267ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod template <typename T> 2689c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline return_t dispatch (const T &obj) { return obj.apply (this); } 269dabe698fcbeb02911128b17aa8e3b2d864795960Behdad Esfahbod static return_t default_return_value (void) { return false; } 2707b912c1936c3e8a7df27a30782ca127d0a83822dBehdad Esfahbod bool stop_sublookup_iteration (return_t r) const { return r; } 271ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod return_t recurse (unsigned int lookup_index) 272ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod { 273ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod if (unlikely (nesting_level_left == 0 || !recurse_func)) 274ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod return default_return_value (); 275ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod 2764c4e8f0e754b79ac6190d21878eaaf0b790c7579Behdad Esfahbod nesting_level_left--; 277f18ff5a84d9fe859c40a7a0c9a207cb40df0e84aBehdad Esfahbod bool ret = recurse_func (this, lookup_index); 2784c4e8f0e754b79ac6190d21878eaaf0b790c7579Behdad Esfahbod nesting_level_left++; 279f18ff5a84d9fe859c40a7a0c9a207cb40df0e84aBehdad Esfahbod return ret; 280ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod } 281ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod 2826880f7e19d44c50e45ecb86d26381aad956d9acbBehdad Esfahbod unsigned int table_index; /* GSUB/GPOS */ 283abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod hb_font_t *font; 284abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod hb_face_t *face; 28594a23aaeca39c662614037ef887412249bdc8d49Behdad Esfahbod hb_buffer_t *buffer; 286744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod hb_direction_t direction; 287f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod hb_mask_t lookup_mask; 288a8cf7b43fa795150ae3d42d64424bb6e0373d0b2Behdad Esfahbod bool auto_zwj; 289ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod recurse_func_t recurse_func; 2901376fb7bf9ef07970f0ba13dc64d6a8ab8252762Behdad Esfahbod unsigned int nesting_level_left; 2918c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod unsigned int lookup_props; 29205bd1b63426e07d1df7a1b40bf845dc94ab995a8Behdad Esfahbod const GDEF &gdef; 293300c7307eb7943ba7416b672345506be1e27c6baBehdad Esfahbod bool has_glyph_classes; 294a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod unsigned int debug_depth; 29598370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod 29641ae674f6871f43d0a6e4ca67a747074d63ae576Behdad Esfahbod 2976880f7e19d44c50e45ecb86d26381aad956d9acbBehdad Esfahbod hb_apply_context_t (unsigned int table_index_, 2986880f7e19d44c50e45ecb86d26381aad956d9acbBehdad Esfahbod hb_font_t *font_, 299bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod hb_buffer_t *buffer_) : 3006880f7e19d44c50e45ecb86d26381aad956d9acbBehdad Esfahbod table_index (table_index_), 301afbcc24be01a64bdb5c05c63880269145fa1d3c8Behdad Esfahbod font (font_), face (font->face), buffer (buffer_), 30241ae674f6871f43d0a6e4ca67a747074d63ae576Behdad Esfahbod direction (buffer_->props.direction), 303bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod lookup_mask (1), 304bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod auto_zwj (true), 305ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod recurse_func (NULL), 3066736f3c5b09af6a71935afc04248b033e171a9b2Behdad Esfahbod nesting_level_left (MAX_NESTING_LEVEL), 307407fc12466ef460d0edf11b89f0d04c4d724875fBehdad Esfahbod lookup_props (0), 308afbcc24be01a64bdb5c05c63880269145fa1d3c8Behdad Esfahbod gdef (*hb_ot_layout_from_face (face)->gdef), 309a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod has_glyph_classes (gdef.has_glyph_classes ()), 310a1733db1c6ff40aae71fa142a12b1fea7b53dd37Behdad Esfahbod debug_depth (0) {} 31141ae674f6871f43d0a6e4ca67a747074d63ae576Behdad Esfahbod 312bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } 313bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7Behdad Esfahbod inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } 314c074ebc466dcc9bcc0d8a5dd7e942dea974ff718Behdad Esfahbod inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } 315c074ebc466dcc9bcc0d8a5dd7e942dea974ff718Behdad Esfahbod inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } 316c074ebc466dcc9bcc0d8a5dd7e942dea974ff718Behdad Esfahbod inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); } 31741ae674f6871f43d0a6e4ca67a747074d63ae576Behdad Esfahbod 318607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod struct matcher_t 3194ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 320607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline matcher_t (void) : 321607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod lookup_props (0), 322cfc507c5432e6327e8484b07b9e091212653bc92Behdad Esfahbod ignore_zwnj (false), 323cfc507c5432e6327e8484b07b9e091212653bc92Behdad Esfahbod ignore_zwj (false), 324607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod mask (-1), 325607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */ 326607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod syllable arg1(0), 327607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod#undef arg1 328607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_func (NULL), 329607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_data (NULL) {}; 330607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 331607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data); 332607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 333607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } 3340b45479198d61d5135dad771e9c68408eb13f930Behdad Esfahbod inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } 335607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } 336607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_mask (hb_mask_t mask_) { mask = mask_; } 337607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_syllable (uint8_t syllable_) { syllable = syllable_; } 338607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_match_func (match_func_t match_func_, 339607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const void *match_data_) 340607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod { match_func = match_func_; match_data = match_data_; } 341607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 3422b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod enum may_match_t { 3432b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod MATCH_NO, 3442b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod MATCH_YES, 3452b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod MATCH_MAYBE 3462b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod }; 3472b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod 3482b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod inline may_match_t may_match (const hb_glyph_info_t &info, 3492b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod const USHORT *glyph_data) const 3504ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 3512b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod if (!(info.mask & mask) || 3522b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod (syllable && syllable != info.syllable ())) 3532b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod return MATCH_NO; 3542b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod 3552b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod if (match_func) 3562b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO; 3572b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod 3582b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod return MATCH_MAYBE; 3594ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod } 360607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 361607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod enum may_skip_t { 362607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod SKIP_NO, 363607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod SKIP_YES, 364607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod SKIP_MAYBE 365607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod }; 366607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 367607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline may_skip_t 368607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod may_skip (const hb_apply_context_t *c, 369607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const hb_glyph_info_t &info) const 370c074ebc466dcc9bcc0d8a5dd7e942dea974ff718Behdad Esfahbod { 371b98c5db32d15fcfb27ce2f6737203ce1ad124319Behdad Esfahbod if (!c->check_glyph_property (&info, lookup_props)) 372607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return SKIP_YES; 373607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 3740b45479198d61d5135dad771e9c68408eb13f930Behdad Esfahbod if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && 3750b45479198d61d5135dad771e9c68408eb13f930Behdad Esfahbod (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && 3760b45479198d61d5135dad771e9c68408eb13f930Behdad Esfahbod (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && 377a1f7b2856184959e965c9c2b80363f9f46d486a7Behdad Esfahbod !_hb_glyph_info_ligated (&info))) 378607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return SKIP_MAYBE; 379607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 380607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return SKIP_NO; 381c074ebc466dcc9bcc0d8a5dd7e942dea974ff718Behdad Esfahbod } 382607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 383607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod protected: 384607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod unsigned int lookup_props; 385607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod bool ignore_zwnj; 3860b45479198d61d5135dad771e9c68408eb13f930Behdad Esfahbod bool ignore_zwj; 387607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod hb_mask_t mask; 388607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod uint8_t syllable; 389607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_func_t match_func; 390607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const void *match_data; 391607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod }; 392607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 393607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod struct skipping_forward_iterator_t 394607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod { 395607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline skipping_forward_iterator_t (hb_apply_context_t *c_, 396607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod unsigned int start_index_, 397607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod unsigned int num_items_, 398607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod bool context_match = false) : 399607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod idx (start_index_), 400607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod c (c_), 401607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_glyph_data (NULL), 402607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod num_items (num_items_), 403607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod end (c->buffer->len) 4044ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 405607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod matcher.set_lookup_props (c->lookup_props); 406a8cf7b43fa795150ae3d42d64424bb6e0373d0b2Behdad Esfahbod /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ 407a8cf7b43fa795150ae3d42d64424bb6e0373d0b2Behdad Esfahbod matcher.set_ignore_zwnj (context_match || c->table_index == 1); 408a8cf7b43fa795150ae3d42d64424bb6e0373d0b2Behdad Esfahbod /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ 409a8cf7b43fa795150ae3d42d64424bb6e0373d0b2Behdad Esfahbod matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); 410607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod if (!context_match) 411cfc507c5432e6327e8484b07b9e091212653bc92Behdad Esfahbod matcher.set_mask (c->lookup_mask); 412cb90b1bbe6d27ca6968b70d2dbfea7ab7fb73293Behdad Esfahbod matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); 4134ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod } 414607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); } 415607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); } 416607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_match_func (matcher_t::match_func_t match_func, 417607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const void *match_data, 418607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const USHORT glyph_data[]) 4197b84c536c10ab90ed96a033d88e9ad232d46c5b8Behdad Esfahbod { 420607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod matcher.set_match_func (match_func, match_data); 421607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_glyph_data = glyph_data; 4227b84c536c10ab90ed96a033d88e9ad232d46c5b8Behdad Esfahbod } 423607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 424607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline bool has_no_chance (void) const { return unlikely (num_items && idx + num_items >= end); } 425607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void reject (void) { num_items++; match_glyph_data--; } 426c074ebc466dcc9bcc0d8a5dd7e942dea974ff718Behdad Esfahbod inline bool next (void) 4274ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 428506ffeb8e77a668fa305139582d215c32e46bb03Behdad Esfahbod assert (num_items > 0); 429607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod while (!has_no_chance ()) 4304ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 431a4a48fe6d4f884a37e720430347d10dbe3562a79Behdad Esfahbod idx++; 432607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const hb_glyph_info_t &info = c->buffer->info[idx]; 433607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 434ff93ac8cb24cbc3d9dc1a2bfb0faa88950f4a507Behdad Esfahbod matcher_t::may_skip_t skip = matcher.may_skip (c, info); 435607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod if (unlikely (skip == matcher_t::SKIP_YES)) 436607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod continue; 437607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 4382b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); 439722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod if (match == matcher_t::MATCH_YES || 440722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod (match == matcher_t::MATCH_MAYBE && 441722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod skip == matcher_t::SKIP_NO)) 442607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod { 443607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod num_items--; 444607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_glyph_data++; 445607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return true; 446607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod } 447607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 448607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod if (skip == matcher_t::SKIP_NO) 449722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod return false; 450607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod } 451607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return false; 4524ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod } 4534ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod 4544ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod unsigned int idx; 455ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 4564ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod hb_apply_context_t *c; 457607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod matcher_t matcher; 458607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const USHORT *match_glyph_data; 459607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 4604ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod unsigned int num_items; 4614ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod unsigned int end; 4624ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod }; 4634ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod 4649082efc4aacb34de8574d6a4a3c037987df58bd8Behdad Esfahbod struct skipping_backward_iterator_t 4654ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 4669082efc4aacb34de8574d6a4a3c037987df58bd8Behdad Esfahbod inline skipping_backward_iterator_t (hb_apply_context_t *c_, 4679082efc4aacb34de8574d6a4a3c037987df58bd8Behdad Esfahbod unsigned int start_index_, 4689082efc4aacb34de8574d6a4a3c037987df58bd8Behdad Esfahbod unsigned int num_items_, 469607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod bool context_match = false) : 470607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod idx (start_index_), 471607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod c (c_), 472607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_glyph_data (NULL), 473607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod num_items (num_items_) 474c074ebc466dcc9bcc0d8a5dd7e942dea974ff718Behdad Esfahbod { 475607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod matcher.set_lookup_props (c->lookup_props); 476a8cf7b43fa795150ae3d42d64424bb6e0373d0b2Behdad Esfahbod /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ 477a8cf7b43fa795150ae3d42d64424bb6e0373d0b2Behdad Esfahbod matcher.set_ignore_zwnj (context_match || c->table_index == 1); 478a8cf7b43fa795150ae3d42d64424bb6e0373d0b2Behdad Esfahbod /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ 479a8cf7b43fa795150ae3d42d64424bb6e0373d0b2Behdad Esfahbod matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); 480607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod if (!context_match) 481cfc507c5432e6327e8484b07b9e091212653bc92Behdad Esfahbod matcher.set_mask (c->lookup_mask); 482cb90b1bbe6d27ca6968b70d2dbfea7ab7fb73293Behdad Esfahbod matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); 4834ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod } 484607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); } 485607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); } 486607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void set_match_func (matcher_t::match_func_t match_func, 487607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const void *match_data, 488607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const USHORT glyph_data[]) 4897b84c536c10ab90ed96a033d88e9ad232d46c5b8Behdad Esfahbod { 490607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod matcher.set_match_func (match_func, match_data); 491607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_glyph_data = glyph_data; 4927b84c536c10ab90ed96a033d88e9ad232d46c5b8Behdad Esfahbod } 493607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 494607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline bool has_no_chance (void) const { return unlikely (idx < num_items); } 495607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod inline void reject (void) { num_items++; } 496c074ebc466dcc9bcc0d8a5dd7e942dea974ff718Behdad Esfahbod inline bool prev (void) 4974ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 498506ffeb8e77a668fa305139582d215c32e46bb03Behdad Esfahbod assert (num_items > 0); 499607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod while (!has_no_chance ()) 5004ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod { 5014ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod idx--; 502607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const hb_glyph_info_t &info = c->buffer->out_info[idx]; 503607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 504ff93ac8cb24cbc3d9dc1a2bfb0faa88950f4a507Behdad Esfahbod matcher_t::may_skip_t skip = matcher.may_skip (c, info); 505607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod if (unlikely (skip == matcher_t::SKIP_YES)) 506607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod continue; 507607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 5082b2a6e8944144755ab641f2842e36d9a847719f3Behdad Esfahbod matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); 509722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod if (match == matcher_t::MATCH_YES || 510722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod (match == matcher_t::MATCH_MAYBE && 511722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod skip == matcher_t::SKIP_NO)) 512607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod { 513607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod num_items--; 514607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod match_glyph_data++; 515607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return true; 516607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod } 517607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 518607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod if (skip == matcher_t::SKIP_NO) 519722e8b857eafc52e07dee5d9b253b88ed5c5c8edBehdad Esfahbod return false; 520607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod } 521607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod return false; 5224ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod } 5234ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod 5244ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod unsigned int idx; 525ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 5264ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod hb_apply_context_t *c; 527607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod matcher_t matcher; 528607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod const USHORT *match_glyph_data; 529607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 5304ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod unsigned int num_items; 5314ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod }; 5324ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod 53303f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod inline bool 53403f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod match_properties_mark (hb_codepoint_t glyph, 53503f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod unsigned int glyph_props, 53603f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod unsigned int lookup_props) const 53703f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod { 53803f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod /* If using mark filtering sets, the high short of 53903f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod * lookup_props has the set index. 54003f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod */ 54103f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod if (lookup_props & LookupFlag::UseMarkFilteringSet) 54203f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod return gdef.mark_set_covers (lookup_props >> 16, glyph); 54303f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod 54403f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod /* The second byte of lookup_props has the meaning 54503f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod * "ignore marks of attachment type different than 54603f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod * the attachment type specified." 54703f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod */ 54803f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod if (lookup_props & LookupFlag::MarkAttachmentType) 54903f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType); 55003f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod 55103f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod return true; 55203f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod } 55303f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod 55403f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod inline bool 555b98c5db32d15fcfb27ce2f6737203ce1ad124319Behdad Esfahbod check_glyph_property (const hb_glyph_info_t *info, 556b98c5db32d15fcfb27ce2f6737203ce1ad124319Behdad Esfahbod unsigned int lookup_props) const 55703f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod { 558b98c5db32d15fcfb27ce2f6737203ce1ad124319Behdad Esfahbod hb_codepoint_t glyph = info->codepoint; 559b98c5db32d15fcfb27ce2f6737203ce1ad124319Behdad Esfahbod unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info); 560b98c5db32d15fcfb27ce2f6737203ce1ad124319Behdad Esfahbod 56103f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod /* Not covered, if, for example, glyph class is ligature and 56203f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod * lookup_props includes LookupFlags::IgnoreLigatures 56303f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod */ 56403f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod if (glyph_props & lookup_props & LookupFlag::IgnoreFlags) 56503f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod return false; 56603f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod 5675a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbod if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) 56803f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod return match_properties_mark (glyph, glyph_props, lookup_props); 56903f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod 57003f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod return true; 57103f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod } 57203f67bc012f42131b36083a23efc78e1b04b828cBehdad Esfahbod 573a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod inline void _set_glyph_props (hb_codepoint_t glyph_index, 57471b4c999a511bf018acaf48a45e070470c0daf12Behdad Esfahbod unsigned int class_guess = 0, 575832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod bool ligature = false, 576832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod bool component = false) const 57760da763dfac96a7931d6e6bdef8b9973bd5209abBehdad Esfahbod { 57809675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) & 57909675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE; 58009675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED; 58109675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod if (ligature) 582832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod { 58309675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED; 584832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod /* In the only place that the MULTIPLIED bit is used, Uniscribe 585832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod * seems to only care about the "last" transformation between 586832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod * Ligature and Multiple substitions. Ie. if you ligate, expand, 587832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod * and ligate again, it forgives the multiplication and acts as 588832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod * if only ligation happened. As such, clear MULTIPLIED bit. 589832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod */ 590832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod add_in &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED; 591832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod } 592832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod if (component) 593832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod add_in |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED; 5942fca1426ca06cabbe8f027f2dc9dee9c27560c76Behdad Esfahbod if (likely (has_glyph_classes)) 59505ad6b50ac0a1b9a8da10d2ee2238068b7811e7dBehdad Esfahbod _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index)); 59605bd1b63426e07d1df7a1b40bf845dc94ab995a8Behdad Esfahbod else if (class_guess) 59709675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess); 59860da763dfac96a7931d6e6bdef8b9973bd5209abBehdad Esfahbod } 5994ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod 600a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod inline void replace_glyph (hb_codepoint_t glyph_index) const 6013ec77d6ae0510dc2c0ec64382c4948bc6e109844Behdad Esfahbod { 602a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod _set_glyph_props (glyph_index); 603a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod buffer->replace_glyph (glyph_index); 6043ec77d6ae0510dc2c0ec64382c4948bc6e109844Behdad Esfahbod } 605a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod inline void replace_glyph_inplace (hb_codepoint_t glyph_index) const 60698370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod { 607a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod _set_glyph_props (glyph_index); 608a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod buffer->cur().codepoint = glyph_index; 609a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod } 610a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod inline void replace_glyph_with_ligature (hb_codepoint_t glyph_index, 611a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod unsigned int class_guess) const 612a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod { 61309675a8115b9d77261c33940401aa919cede8662Behdad Esfahbod _set_glyph_props (glyph_index, class_guess, true); 61498370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod buffer->replace_glyph (glyph_index); 61598370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod } 616832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod inline void output_glyph_for_component (hb_codepoint_t glyph_index, 617832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod unsigned int class_guess) const 6187fbbf86efe675e4c038dfc5985c24bbc544620cdBehdad Esfahbod { 619832a6f99b34f334b1e82b8e3a7ad137e823d203cBehdad Esfahbod _set_glyph_props (glyph_index, class_guess, false, true); 620a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod buffer->output_glyph (glyph_index); 6217fbbf86efe675e4c038dfc5985c24bbc544620cdBehdad Esfahbod } 6221376fb7bf9ef07970f0ba13dc64d6a8ab8252762Behdad Esfahbod}; 6231376fb7bf9ef07970f0ba13dc64d6a8ab8252762Behdad Esfahbod 62466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 62594a23aaeca39c662614037ef887412249bdc8d49Behdad Esfahbod 6266a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbodtypedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data); 627d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodtypedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data); 62840cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbodtypedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data); 62966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 63031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstruct ContextClosureFuncs 63131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 63231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod intersects_func_t intersects; 63331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod}; 634d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodstruct ContextCollectGlyphsFuncs 635d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 636d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod collect_glyphs_func_t collect; 637d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod}; 63831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstruct ContextApplyFuncs 63960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 64048f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod match_func_t match; 64166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 64266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 643d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 6446a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbodstatic inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED) 64531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 64631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return glyphs->has (value); 64731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 6486a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbodstatic inline bool intersects_class (hb_set_t *glyphs, const USHORT &value, const void *data) 64931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 65031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); 65131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return class_def.intersects_class (glyphs, value); 65231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 6536a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbodstatic inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, const void *data) 65431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 65531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; 65631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return (data+coverage).intersects (glyphs); 65731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 65831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 65931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstatic inline bool intersects_array (hb_closure_context_t *c, 66031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count, 66131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const USHORT values[], 66231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod intersects_func_t intersects_func, 66331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const void *intersects_data) 66431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 66531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 66631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (likely (!intersects_func (c->glyphs, values[i], intersects_data))) 66731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 66831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 66931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 67031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 671f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 672d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodstatic inline void collect_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED) 673d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 674d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod glyphs->add (value); 675d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod} 676d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodstatic inline void collect_class (hb_set_t *glyphs, const USHORT &value, const void *data) 677d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 678d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); 679d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod class_def.add_class (glyphs, value); 680d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod} 681d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodstatic inline void collect_coverage (hb_set_t *glyphs, const USHORT &value, const void *data) 682d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 683d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; 684d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod (data+coverage).add_coverage (glyphs); 685d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod} 6860beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbodstatic inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, 687f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod hb_set_t *glyphs, 688d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int count, 689d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const USHORT values[], 690d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod collect_glyphs_func_t collect_func, 691d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const void *collect_data) 692d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 693d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 694f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod collect_func (glyphs, values[i], collect_data); 695d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod} 696d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 697d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 69840cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbodstatic inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, const void *data HB_UNUSED) 69960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 70048f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod return glyph_id == value; 70148f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod} 70240cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbodstatic inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, const void *data) 70360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 7042b5a59c277f4c5bf7aac9a9005054763e322e02dBehdad Esfahbod const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); 70548f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod return class_def.get_class (glyph_id) == value; 70648f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod} 70740cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbodstatic inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value, const void *data) 70860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 7096b54c5d0446b514fbb6521e7e9e614d153435f0eBehdad Esfahbod const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; 71031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; 71148f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod} 71248f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod 713e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbodstatic inline bool would_match_input (hb_would_apply_context_t *c, 714e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int count, /* Including the first glyph (not matched) */ 715e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const USHORT input[], /* Array of input values--start with second glyph */ 716e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod match_func_t match_func, 717e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const void *match_data) 718e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod{ 719e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod if (count != c->len) 720e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return false; 721e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 722e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod for (unsigned int i = 1; i < count; i++) 723472f229a63f0d1bb21b02179ef430b7698df8f12Behdad Esfahbod if (likely (!match_func (c->glyphs[i], input[i - 1], match_data))) 724e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return false; 725e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 726e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return true; 727e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod} 728d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbodstatic inline bool match_input (hb_apply_context_t *c, 729d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod unsigned int count, /* Including the first glyph (not matched) */ 730d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod const USHORT input[], /* Array of input values--start with second glyph */ 731d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod match_func_t match_func, 73240cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod const void *match_data, 7336cc136f7531a45e71ea08a7dc8a2187172cb813dBehdad Esfahbod unsigned int *end_offset, 7346cc136f7531a45e71ea08a7dc8a2187172cb813dBehdad Esfahbod unsigned int match_positions[MAX_CONTEXT_LENGTH], 735191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod bool *p_is_mark_ligature = NULL, 736191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod unsigned int *p_total_component_count = NULL) 737d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod{ 73873c18ae1b982a4e65086afe5177afa79e721e2c0Behdad Esfahbod TRACE_APPLY (NULL); 73993814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 7406b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false); 7416b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod 7423c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod hb_buffer_t *buffer = c->buffer; 7433c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod 7443c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, count - 1); 745607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod skippy_iter.set_match_func (match_func, match_data, input); 74693814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 74793814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 748191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod /* 749191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * This is perhaps the trickiest part of OpenType... Remarks: 750191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * 751191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * - If all components of the ligature were marks, we call this a mark ligature. 752191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * 753191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * - If there is no GDEF, and the ligature is NOT a mark ligature, we categorize 754191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * it as a ligature glyph. 755191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * 756191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * - Ligatures cannot be formed across glyphs attached to different components 757191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and 758191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother. 759191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * However, it would be wrong to ligate that SHADDA,FATHA sequence.o 760191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * There is an exception to this: If a ligature tries ligating with marks that 761191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * belong to it itself, go ahead, assuming that the font designer knows what 762191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * they are doing (otherwise it can break Indic stuff when a matra wants to 763191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod * ligate with a conjunct...) 764191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod */ 765191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod 766101303dbf7cf15d044bf2518f14b3aec65970feaBehdad Esfahbod bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur()); 76793814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 76893814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod unsigned int total_component_count = 0; 7693ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur()); 77093814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 7713ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); 7723ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); 773d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod 7743c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod match_positions[0] = buffer->idx; 775370f03e9c69d98d735eafb7e72b13b17f42cbaa9Behdad Esfahbod for (unsigned int i = 1; i < count; i++) 77660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 777407fc12466ef460d0edf11b89f0d04c4d724875fBehdad Esfahbod if (!skippy_iter.next ()) return TRACE_RETURN (false); 7786cc136f7531a45e71ea08a7dc8a2187172cb813dBehdad Esfahbod 7796cc136f7531a45e71ea08a7dc8a2187172cb813dBehdad Esfahbod match_positions[i] = skippy_iter.idx; 78093814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 7813ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]); 7823ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]); 78393814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 78493814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod if (first_lig_id && first_lig_comp) { 78593814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod /* If first component was attached to a previous ligature component, 78693814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod * all subsequent components should be attached to the same ligature 78793814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod * component, otherwise we shouldn't ligate them. */ 78893814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp) 78993814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod return TRACE_RETURN (false); 79093814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod } else { 79193814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod /* If first component was NOT attached to a previous ligature component, 79293814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod * all subsequent components should also NOT be attached to any ligature 79393814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod * component, unless they are attached to the first component itself! */ 79493814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id)) 79593814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod return TRACE_RETURN (false); 79693814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod } 79793814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 798101303dbf7cf15d044bf2518f14b3aec65970feaBehdad Esfahbod is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]); 7993ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]); 800d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod } 801d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod 8023c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod *end_offset = skippy_iter.idx - buffer->idx + 1; 803d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod 804191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod if (p_is_mark_ligature) 805191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod *p_is_mark_ligature = is_mark_ligature; 806191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod 807191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod if (p_total_component_count) 808191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod *p_total_component_count = total_component_count; 809191fa885d9e0a2dce92dd8727cddd18495e62409Behdad Esfahbod 810bc513add7999baf32f126ceebbd318105ee66985Behdad Esfahbod return TRACE_RETURN (true); 811d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod} 812a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbodstatic inline void ligate_input (hb_apply_context_t *c, 813e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod unsigned int count, /* Including the first glyph */ 814e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ 815e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod unsigned int match_length, 816a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod hb_codepoint_t lig_glyph, 817a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod bool is_mark_ligature, 818a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod unsigned int total_component_count) 819a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod{ 820e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod TRACE_APPLY (NULL); 821e714fe6d6a2633494cb1fa7170a32ca2638cbb51Behdad Esfahbod 8223c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod hb_buffer_t *buffer = c->buffer; 8233c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod 8243c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod buffer->merge_clusters (buffer->idx, buffer->idx + match_length); 825607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 826a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod /* 827a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * - If it *is* a mark ligature, we don't allocate a new ligature id, and leave 828a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * the ligature to keep its old ligature id. This will allow it to attach to 829a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HEH, 830a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a 831a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * ligature id and component value of 2. Then if SHADDA,FATHA form a ligature 832a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * later, we don't want them to lose their ligature id/component, otherwise 833a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * GPOS will fail to correctly position the mark ligature on top of the 834a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * LAM,LAM,HEH ligature. See: 835a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * https://bugzilla.gnome.org/show_bug.cgi?id=676343 836a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * 837a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * - If a ligature is formed of components that some of which are also ligatures 838a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * themselves, and those ligature components had marks attached to *their* 839a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * components, we have to attach the marks to the new ligature component 840a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * positions! Now *that*'s tricky! And these marks may be following the 841a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * last component of the whole sequence, so we should loop forward looking 842a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * for them and update them. 843a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * 844a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * Eg. the sequence is LAM,LAM,SHADDA,FATHA,HEH, and the font first forms a 845a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * 'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature 846a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * id and component == 1. Now, during 'liga', the LAM and the LAM-HEH ligature 847a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * form a LAM-LAM-HEH ligature. We need to reassign the SHADDA and FATHA to 848a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * the new ligature with a component value of 2. 849a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * 850a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * This in fact happened to a font... See: 851a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod * https://bugzilla.gnome.org/show_bug.cgi?id=437633 852a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod */ 853a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod 8545a08ecf9200a6ac9b4ebb7ec5c13dcb42d8820ceBehdad Esfahbod unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; 8553ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer); 8563ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); 8573ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); 858a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod unsigned int components_so_far = last_num_components; 859a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod 860a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod if (!is_mark_ligature) 8617e08f1258da229dfaf7e1c4b5c41e5bb83906cb0Behdad Esfahbod { 8623ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count); 8633c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) 8643d436d325edccc0f3dd820e06e3d529cc8f3eca4Behdad Esfahbod { 8653c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER); 8663d436d325edccc0f3dd820e06e3d529cc8f3eca4Behdad Esfahbod _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0); 8673d436d325edccc0f3dd820e06e3d529cc8f3eca4Behdad Esfahbod } 8687e08f1258da229dfaf7e1c4b5c41e5bb83906cb0Behdad Esfahbod } 869a0161746589934e93c3b115814bbd81f56ab962fBehdad Esfahbod c->replace_glyph_with_ligature (lig_glyph, klass); 870a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod 871a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod for (unsigned int i = 1; i < count; i++) 872a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod { 8733c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod while (buffer->idx < match_positions[i]) 874a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod { 875a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod if (!is_mark_ligature) { 876a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod unsigned int new_lig_comp = components_so_far - last_num_components + 8773ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->cur()), 1u), last_num_components); 8783ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); 879a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod } 8803c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod buffer->next_glyph (); 881a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod } 882a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod 8833ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); 8843ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); 885a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod components_so_far += last_num_components; 886a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod 887a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod /* Skip the base glyph */ 8883c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod buffer->idx++; 889a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod } 890a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod 891a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod if (!is_mark_ligature && last_lig_id) { 892a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod /* Re-adjust components for any marks following. */ 8933c3df9cba13fec2c35e0e7ae587d9699ac0c37f5Behdad Esfahbod for (unsigned int i = buffer->idx; i < buffer->len; i++) { 8943ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) { 895a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod unsigned int new_lig_comp = components_so_far - last_num_components + 8963ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->info[i]), 1u), last_num_components); 8973ddf892b5328b74afb6e7d9da727d8771ca5d288Behdad Esfahbod _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); 898a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod } else 899a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod break; 900a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod } 901a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod } 90204d894e89795041b2055dc172744a018644f2bcaBehdad Esfahbod TRACE_RETURN (true); 903a177d027d1d0ad9539e30ed75d8652e0e8da20ffBehdad Esfahbod} 904d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod 905d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbodstatic inline bool match_backtrack (hb_apply_context_t *c, 906e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod unsigned int count, 907e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod const USHORT backtrack[], 908e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod match_func_t match_func, 90940cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod const void *match_data) 910e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod{ 91173c18ae1b982a4e65086afe5177afa79e721e2c0Behdad Esfahbod TRACE_APPLY (NULL); 91293814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 9139082efc4aacb34de8574d6a4a3c037987df58bd8Behdad Esfahbod hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count, true); 914607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod skippy_iter.set_match_func (match_func, match_data, backtrack); 915607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 916e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod 9174d3aeb8cb2bc1ca7cdd03ba28ba8c334f12d4c03Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 9184ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod if (!skippy_iter.prev ()) 91993814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod return TRACE_RETURN (false); 920e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod 92193814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod return TRACE_RETURN (true); 922e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod} 923e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod 924d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbodstatic inline bool match_lookahead (hb_apply_context_t *c, 925d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod unsigned int count, 926d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod const USHORT lookahead[], 927d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod match_func_t match_func, 92840cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod const void *match_data, 929d0ba0557007798db2c60ddd0b7a5a0624cd1698dBehdad Esfahbod unsigned int offset) 930f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod{ 93173c18ae1b982a4e65086afe5177afa79e721e2c0Behdad Esfahbod TRACE_APPLY (NULL); 93293814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod 9339082efc4aacb34de8574d6a4a3c037987df58bd8Behdad Esfahbod hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true); 934607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod skippy_iter.set_match_func (match_func, match_data, lookahead); 935607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 93666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 937370f03e9c69d98d735eafb7e72b13b17f42cbaa9Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 9384ab97311541225906f6b737a2b47de252224cc09Behdad Esfahbod if (!skippy_iter.next ()) 93993814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod return TRACE_RETURN (false); 94066bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 94193814ca7dc2a7251f861c1c47ba155ba6e6bdf19Behdad Esfahbod return TRACE_RETURN (true); 942f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod} 943f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 944acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 945f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 94660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct LookupRecord 94760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 948d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 949be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 9500ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (c->check_struct (this)); 951cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 952cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 953f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod USHORT sequenceIndex; /* Index into current glyph 954f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod * sequence--first glyph = 0 */ 955f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod USHORT lookupListIndex; /* Lookup to apply to that 956f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod * position--zero--based */ 957569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 958569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod DEFINE_SIZE_STATIC (4); 959f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod}; 960f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 961acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 962d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodtemplate <typename context_t> 963d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodstatic inline void recurse_lookups (context_t *c, 964d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int lookupCount, 965d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */) 96631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 96731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < lookupCount; i++) 96886522e493d071f395b5abf64289232bf8867ac29Behdad Esfahbod c->recurse (lookupRecord[i].lookupListIndex); 96931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 970acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 971d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbodstatic inline bool apply_lookup (hb_apply_context_t *c, 972e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod unsigned int count, /* Including the first glyph */ 9736b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ 974e072c24e79f0e7c1e078a87c782ab5dd8f21dcdaBehdad Esfahbod unsigned int lookupCount, 9756b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ 9766b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int match_length) 977f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod{ 97873c18ae1b982a4e65086afe5177afa79e721e2c0Behdad Esfahbod TRACE_APPLY (NULL); 979902cc8aca0b3ff25eeee50b3a84d729e31731ef3Behdad Esfahbod 9806b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod hb_buffer_t *buffer = c->buffer; 9816b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int end; 98252e9a71d578c5171bbb0f4bfc1b70841c3270328Behdad Esfahbod 9836b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod /* All positions are distance from beginning of *output* buffer. 9846b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod * Adjust. */ 9856b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod { 9866b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int bl = buffer->backtrack_len (); 9876b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod end = bl + match_length; 988607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 9896b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod int delta = bl - buffer->idx; 9906b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod /* Convert positions to new indexing. */ 9916b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod for (unsigned int j = 0; j < count; j++) 9926b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod match_positions[j] += delta; 9936b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod } 994607feb7cff0e50f8738d2e49ca463fc9d7d494deBehdad Esfahbod 9956b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod for (unsigned int i = 0; i < lookupCount; i++) 99660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 9976b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int idx = lookupRecord[i].sequenceIndex; 9986b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod if (idx >= count) 9996b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod continue; 10008751de50831338ce550601c34c17d152ad89c1fdBehdad Esfahbod 10016b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod buffer->move_to (match_positions[idx]); 10028820bb235b1f63e4d93c8a2f5c08b44d89e06b78Behdad Esfahbod 10036b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); 10046b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod if (!c->recurse (lookupRecord[i].lookupListIndex)) 10056b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod continue; 10068820bb235b1f63e4d93c8a2f5c08b44d89e06b78Behdad Esfahbod 10076b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len (); 10086b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod int delta = new_len - orig_len; 1009e73a0c2a903112ce9a35b95e14e10ab8ea2dc337Behdad Esfahbod 10106b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod if (!delta) 10116b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod continue; 10128751de50831338ce550601c34c17d152ad89c1fdBehdad Esfahbod 10136b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod /* Recursed lookup changed buffer len. Adjust. */ 101466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1015b6b304f12be917b7449b3ac9409069fcd4a27d95Behdad Esfahbod /* end can't go back past the current match position. 1016b6b304f12be917b7449b3ac9409069fcd4a27d95Behdad Esfahbod * Note: this is only true because we do NOT allow MultipleSubst 1017b6b304f12be917b7449b3ac9409069fcd4a27d95Behdad Esfahbod * with zero sequence len. */ 1018da72042c52ed3cc0ee19d3eabb8db7c7dd34d3edBehdad Esfahbod end = MAX ((int) match_positions[idx] + 1, int (end) + delta); 101966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 10206b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */ 10216b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod 10226b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod if (delta > 0) 10236b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod { 10246b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod if (unlikely (delta + count > MAX_CONTEXT_LENGTH)) 10256b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod break; 102666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 102766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod else 102866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod { 10296b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod /* NOTE: delta is negative. */ 10306b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod delta = MAX (delta, (int) next - (int) count); 10316b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod next -= delta; 103266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 10336b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod 10346b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod /* Shift! */ 10356b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod memmove (match_positions + next + delta, match_positions + next, 10366b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod (count - next) * sizeof (match_positions[0])); 10376b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod next += delta; 10386b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod count += delta; 10396b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod 10406b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod /* Fill in new entries. */ 10416b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod for (unsigned int j = idx + 1; j < next; j++) 10426b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod match_positions[j] = match_positions[j - 1] + 1; 10436b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod 10446b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod /* And fixup the rest. */ 10456b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod for (; next < count; next++) 10466b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod match_positions[next] += delta; 104766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 104866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 10496b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod buffer->move_to (end); 10506b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod 10512616689d159024d2b1cb1e68f9936b2129bf9be6Behdad Esfahbod return TRACE_RETURN (true); 105266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod} 105348f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod 1054acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 1055f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 1056f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod/* Contextual lookups */ 1057f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 105831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstruct ContextClosureLookupContext 105931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 106031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ContextClosureFuncs funcs; 106131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const void *intersects_data; 106231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod}; 106331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1064d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodstruct ContextCollectGlyphsLookupContext 1065d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 1066d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod ContextCollectGlyphsFuncs funcs; 1067d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const void *collect_data; 1068d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod}; 1069d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 107031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstruct ContextApplyLookupContext 107160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 107231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ContextApplyFuncs funcs; 107340cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod const void *match_data; 1074f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod}; 1075f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 10765caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbodstatic inline void context_closure_lookup (hb_closure_context_t *c, 107731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 107831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const USHORT input[], /* Array of input values--start with second glyph */ 107931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int lookupCount, 108031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const LookupRecord lookupRecord[], 108131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ContextClosureLookupContext &lookup_context) 108231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 10835caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod if (intersects_array (c, 10845caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inputCount ? inputCount - 1 : 0, input, 10855caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context.funcs.intersects, lookup_context.intersects_data)) 1086d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod recurse_lookups (c, 1087d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookupCount, lookupRecord); 108831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 108931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1090d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbodstatic inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, 1091d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 1092d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const USHORT input[], /* Array of input values--start with second glyph */ 1093d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int lookupCount, 1094d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod const LookupRecord lookupRecord[], 1095d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod ContextCollectGlyphsLookupContext &lookup_context) 1096d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod{ 10978303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod collect_array (c, c->input, 1098d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod inputCount ? inputCount - 1 : 0, input, 1099d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookup_context.funcs.collect, lookup_context.collect_data); 1100d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod recurse_lookups (c, 1101d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookupCount, lookupRecord); 1102d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod} 110331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1104e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbodstatic inline bool context_would_apply_lookup (hb_would_apply_context_t *c, 1105e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 1106e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const USHORT input[], /* Array of input values--start with second glyph */ 11070beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod unsigned int lookupCount HB_UNUSED, 11080beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod const LookupRecord lookupRecord[] HB_UNUSED, 1109e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod ContextApplyLookupContext &lookup_context) 1110e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod{ 1111e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return would_match_input (c, 1112e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inputCount, input, 1113e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod lookup_context.funcs.match, lookup_context.match_data); 1114e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod} 111531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstatic inline bool context_apply_lookup (hb_apply_context_t *c, 111631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 111731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const USHORT input[], /* Array of input values--start with second glyph */ 111831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int lookupCount, 111931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const LookupRecord lookupRecord[], 112031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ContextApplyLookupContext &lookup_context) 1121f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod{ 11226b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int match_length = 0; 11236b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int match_positions[MAX_CONTEXT_LENGTH]; 1124d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod return match_input (c, 11254169710911450e0f9bc045fe279bfc8ba9e8457cBehdad Esfahbod inputCount, input, 11266b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod lookup_context.funcs.match, lookup_context.match_data, 11276b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod &match_length, match_positions) 11285df809b655bb1318115651fd87d4555cdd9b41cbBehdad Esfahbod && apply_lookup (c, 11296b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod inputCount, match_positions, 11306b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod lookupCount, lookupRecord, 11316b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod match_length); 1132f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod} 1133f14c2b7acfba75b8a6880f41ceec758f9a56abceBehdad Esfahbod 113460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Rule 113560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 11365caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const 113731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod { 1138be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 1139093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); 11405caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod context_closure_lookup (c, 1141093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod inputCount, inputZ, 11425caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookupCount, lookupRecord, 11435caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context); 114431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 114531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1146d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const 1147d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod { 1148d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 1149093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); 1150d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod context_collect_glyphs_lookup (c, 1151093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod inputCount, inputZ, 1152d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookupCount, lookupRecord, 1153d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookup_context); 1154d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod } 1155d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1156e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 1157e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1158be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1159093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); 1160093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod return TRACE_RETURN (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); 1161e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1162e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 116331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 116460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1165be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 1166093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); 1167093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod return TRACE_RETURN (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); 116866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 116966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 117070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod public: 1171d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1172be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1173d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod return inputCount.sanitize (c) 1174d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod && lookupCount.sanitize (c) 1175093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod && c->check_range (inputZ, 1176093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod inputZ[0].static_size * inputCount 1177f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod + lookupRecordX[0].static_size * lookupCount); 117870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 117970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1180ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 118148f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod USHORT inputCount; /* Total number of glyphs in input 118231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod * glyph sequence--includes the first 118366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * glyph */ 118448f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod USHORT lookupCount; /* Number of LookupRecords */ 1185093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod USHORT inputZ[VAR]; /* Array of match inputs--start with 118666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * second glyph */ 1187d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in 118866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * design order */ 1189569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 1190093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod DEFINE_SIZE_ARRAY2 (4, inputZ, lookupRecordX); 119166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 119266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 119360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct RuleSet 119460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 11955caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const 119631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod { 1197be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 119831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int num_rules = rule.len; 119931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 12005caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod (this+rule[i]).closure (c, lookup_context); 120131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 120231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1203d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const 1204d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod { 1205d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 1206d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int num_rules = rule.len; 1207d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 1208d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod (this+rule[i]).collect_glyphs (c, lookup_context); 1209d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod } 1210d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1211e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 1212e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1213be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1214e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int num_rules = rule.len; 1215e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 1216e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1217e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod if ((this+rule[i]).would_apply (c, lookup_context)) 1218e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return TRACE_RETURN (true); 1219e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1220e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return TRACE_RETURN (false); 1221e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1222e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 122331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 122460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1225be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 122666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod unsigned int num_rules = rule.len; 122760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 122860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1229d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod if ((this+rule[i]).apply (c, lookup_context)) 1230acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (true); 123166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 1232acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (false); 123366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 123466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1235d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1236be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 12370ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (rule.sanitize (c, this)); 123870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 123970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1240ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 124166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod OffsetArrayOf<Rule> 124248f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod rule; /* Array of Rule tables 124366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * ordered by preference */ 1244ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod public: 12450eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (2, rule); 124666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 124766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 124866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 124960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ContextFormat1 125060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 125144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline void closure (hb_closure_context_t *c) const 1252f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 1253be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 125431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 125531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const Coverage &cov = (this+coverage); 125631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 125731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ContextClosureLookupContext lookup_context = { 125844fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod {intersects_glyph}, 125931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod NULL 126031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod }; 126131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 126231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = ruleSet.len; 126331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 126431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (cov.intersects_coverage (c->glyphs, i)) { 126531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const RuleSet &rule_set = this+ruleSet[i]; 12665caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod rule_set.closure (c, lookup_context); 126731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 1268f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 1269f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 127026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 127126514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 1272d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 12738303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+coverage).add_coverage (c->input); 1274d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1275d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod struct ContextCollectGlyphsLookupContext lookup_context = { 1276d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod {collect_glyph}, 1277d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod NULL 1278d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod }; 1279d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1280d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int count = ruleSet.len; 1281d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1282f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod (this+ruleSet[i]).collect_glyphs (c, lookup_context); 128326514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 128426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 1285e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 1286e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1287be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1288e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1289b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])]; 1290e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod struct ContextApplyLookupContext lookup_context = { 1291ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_glyph}, 1292e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod NULL 1293e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod }; 1294e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); 1295e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1296e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 129744fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline const Coverage &get_coverage (void) const 129844fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 129944fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod return this+coverage; 130044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 130144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 1302ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 130360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1304be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 1305b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 130664d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (likely (index == NOT_COVERED)) 1307acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (false); 1308aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 130966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod const RuleSet &rule_set = this+ruleSet[index]; 131031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ContextApplyLookupContext lookup_context = { 1311ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_glyph}, 131248f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod NULL 131366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod }; 1314acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (rule_set.apply (c, lookup_context)); 131566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 131666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1317d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1318be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 13190ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); 132070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 132170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1322ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 132366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod USHORT format; /* Format identifier--format = 1 */ 132466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod OffsetTo<Coverage> 132566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod coverage; /* Offset to Coverage table--from 132666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * beginning of table */ 132766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod OffsetArrayOf<RuleSet> 132866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod ruleSet; /* Array of RuleSet tables 132966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * ordered by Coverage Index */ 1330b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 13310eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, ruleSet); 133266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 133366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 133466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 133560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ContextFormat2 133660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 133744fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline void closure (hb_closure_context_t *c) const 1338f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 1339be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 134031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (!(this+coverage).intersects (c->glyphs)) 13415caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod return; 134231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 134331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ClassDef &class_def = this+classDef; 134431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 134531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ContextClosureLookupContext lookup_context = { 134644fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod {intersects_class}, 134711fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod &class_def 134831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod }; 134931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 135031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = ruleSet.len; 135131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 135231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (class_def.intersects_class (c->glyphs, i)) { 135331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const RuleSet &rule_set = this+ruleSet[i]; 13545caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod rule_set.closure (c, lookup_context); 135531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 1356f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 1357f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 135826514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 135926514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 1360d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 13618303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+coverage).add_coverage (c->input); 1362d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 136311fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod const ClassDef &class_def = this+classDef; 1364d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod struct ContextCollectGlyphsLookupContext lookup_context = { 1365d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod {collect_class}, 136611fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod &class_def 1367d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod }; 1368d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1369d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod unsigned int count = ruleSet.len; 1370d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1371f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod (this+ruleSet[i]).collect_glyphs (c, lookup_context); 137226514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 137326514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 1374e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 1375e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1376be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1377e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1378e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const ClassDef &class_def = this+classDef; 13792dc1141d7d0a9f5818862b09d6b9cfe0a27f1fc1Behdad Esfahbod unsigned int index = class_def.get_class (c->glyphs[0]); 1380e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const RuleSet &rule_set = this+ruleSet[index]; 1381e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod struct ContextApplyLookupContext lookup_context = { 1382ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_class}, 1383e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod &class_def 1384e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod }; 1385e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); 1386e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1387e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 138844fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline const Coverage &get_coverage (void) const 138944fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 139044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod return this+coverage; 139144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 139244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 1393ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 139460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1395be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 1396b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 1397acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 1398aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 1399aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod const ClassDef &class_def = this+classDef; 14002dc1141d7d0a9f5818862b09d6b9cfe0a27f1fc1Behdad Esfahbod index = class_def.get_class (c->buffer->cur().codepoint); 140166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod const RuleSet &rule_set = this+ruleSet[index]; 140231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ContextApplyLookupContext lookup_context = { 1403ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_class}, 140440cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod &class_def 140566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod }; 1406acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (rule_set.apply (c, lookup_context)); 140766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 140866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1409d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1410be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 14110ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this)); 141270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 141370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1414ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 141566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod USHORT format; /* Format identifier--format = 2 */ 141666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod OffsetTo<Coverage> 141766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod coverage; /* Offset to Coverage table--from 141866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * beginning of table */ 141966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod OffsetTo<ClassDef> 142066bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod classDef; /* Offset to glyph ClassDef table--from 142166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * beginning of table */ 142266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod OffsetArrayOf<RuleSet> 142366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod ruleSet; /* Array of RuleSet tables 142466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * ordered by class */ 1425b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 14260eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (8, ruleSet); 142766bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 142866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 142966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 143060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ContextFormat3 143160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 143244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline void closure (hb_closure_context_t *c) const 1433f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 1434be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 1435093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod if (!(this+coverageZ[0]).intersects (c->glyphs)) 14365caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod return; 143731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1438093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); 143931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ContextClosureLookupContext lookup_context = { 144044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod {intersects_coverage}, 144131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod this 144231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod }; 14435caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod context_closure_lookup (c, 1444093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod glyphCount, (const USHORT *) (coverageZ + 1), 14455caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookupCount, lookupRecord, 14465caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context); 1447f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 1448f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 144926514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 145026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 1451d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 1452093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod (this+coverageZ[0]).add_coverage (c->input); 1453d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1454093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); 1455d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod struct ContextCollectGlyphsLookupContext lookup_context = { 1456d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod {collect_coverage}, 1457e75943de803f571b7ad2cf2f777119753a209656Behdad Esfahbod this 1458d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod }; 1459d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod 1460d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod context_collect_glyphs_lookup (c, 1461093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod glyphCount, (const USHORT *) (coverageZ + 1), 1462d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookupCount, lookupRecord, 1463d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookup_context); 146426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 146526514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 1466e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 1467e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1468be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1469e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1470093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); 1471e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod struct ContextApplyLookupContext lookup_context = { 1472ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_coverage}, 1473e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod this 1474e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod }; 1475093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod return TRACE_RETURN (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); 1476e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1477e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 147844fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline const Coverage &get_coverage (void) const 147944fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 1480093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod return this+coverageZ[0]; 148144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 148244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 1483ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 148460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1485be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 1486093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); 1487acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 148866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1489093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); 149031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ContextApplyLookupContext lookup_context = { 1491ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_coverage}, 149240cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod this 149366bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod }; 1494093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); 149566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } 149666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1497d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1498be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 14990ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!c->check_struct (this)) return TRACE_RETURN (false); 150070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod unsigned int count = glyphCount; 1501093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod if (!count) return TRACE_RETURN (false); /* We want to access coverageZ[0] freely. */ 1502093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return TRACE_RETURN (false); 150370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1504093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod if (!coverageZ[i].sanitize (c, this)) return TRACE_RETURN (false); 1505093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count); 15060ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); 150770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 150870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1509ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 151066bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod USHORT format; /* Format identifier--format = 3 */ 151166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod USHORT glyphCount; /* Number of glyphs in the input glyph 151266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * sequence */ 151348f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod USHORT lookupCount; /* Number of LookupRecords */ 1514aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetTo<Coverage> 1515093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod coverageZ[VAR]; /* Array of offsets to Coverage 1516aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod * table in glyph sequence order */ 1517d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in 151866bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod * design order */ 1519569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 1520093c520de506aec74f3fb1e195c0ca85813424ddBehdad Esfahbod DEFINE_SIZE_ARRAY2 (6, coverageZ, lookupRecordX); 152166bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 152266bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 152360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Context 152460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 152544fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod template <typename context_t> 15269c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 1527e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 152800f6a8e334ec4c586e4e633a95b411ccb50306d3Behdad Esfahbod TRACE_DISPATCH (this, u.format); 1529e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod switch (u.format) { 15309c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case 1: return TRACE_RETURN (c->dispatch (u.format1)); 15319c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case 2: return TRACE_RETURN (c->dispatch (u.format2)); 15329c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case 3: return TRACE_RETURN (c->dispatch (u.format3)); 1533f48ec0e83432c038b50d9715a38ba1469e82e1e4Behdad Esfahbod default:return TRACE_RETURN (c->default_return_value ()); 1534e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1535e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1536e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1537d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1538be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 15390ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!u.format.sanitize (c)) return TRACE_RETURN (false); 154070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 15410ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 1: return TRACE_RETURN (u.format1.sanitize (c)); 15420ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 2: return TRACE_RETURN (u.format2.sanitize (c)); 15430ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 3: return TRACE_RETURN (u.format3.sanitize (c)); 15440ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod default:return TRACE_RETURN (true); 154570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 154670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 154770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1548ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 154966bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod union { 1550f8dc67b3c24dfc805da756a73cb217b36e16b4b8Behdad Esfahbod USHORT format; /* Format identifier */ 1551dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ContextFormat1 format1; 1552dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ContextFormat2 format2; 1553dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ContextFormat3 format3; 155466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod } u; 155566bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod}; 155666bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 1557ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 1558ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod/* Chaining Contextual lookups */ 1559ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 156031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstruct ChainContextClosureLookupContext 156160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 156231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ContextClosureFuncs funcs; 156331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const void *intersects_data[3]; 156431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod}; 156531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1566f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbodstruct ChainContextCollectGlyphsLookupContext 1567f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod{ 1568f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod ContextCollectGlyphsFuncs funcs; 1569f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const void *collect_data[3]; 1570f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod}; 1571f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 157231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstruct ChainContextApplyLookupContext 157331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 157431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ContextApplyFuncs funcs; 157540cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod const void *match_data[3]; 157648f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod}; 157748f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod 15785caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbodstatic inline void chain_context_closure_lookup (hb_closure_context_t *c, 157931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int backtrackCount, 158031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const USHORT backtrack[], 158131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 158231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const USHORT input[], /* Array of input values--start with second glyph */ 158331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int lookaheadCount, 158431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const USHORT lookahead[], 158531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int lookupCount, 158631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const LookupRecord lookupRecord[], 158731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ChainContextClosureLookupContext &lookup_context) 158831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod{ 15895caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod if (intersects_array (c, 15905caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod backtrackCount, backtrack, 15915caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context.funcs.intersects, lookup_context.intersects_data[0]) 15925caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod && intersects_array (c, 15935caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inputCount ? inputCount - 1 : 0, input, 15945caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context.funcs.intersects, lookup_context.intersects_data[1]) 159574439d0aa10184451adc6c6469f5119be352ecbbBehdad Esfahbod && intersects_array (c, 15965caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookaheadCount, lookahead, 15975caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context.funcs.intersects, lookup_context.intersects_data[2])) 1598d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod recurse_lookups (c, 1599d0a5233785eb327c4080432f597fe470a1046af3Behdad Esfahbod lookupCount, lookupRecord); 160031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod} 160131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1602f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbodstatic inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, 1603f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int backtrackCount, 1604f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const USHORT backtrack[], 1605f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 1606f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const USHORT input[], /* Array of input values--start with second glyph */ 1607f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int lookaheadCount, 1608f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const USHORT lookahead[], 1609f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int lookupCount, 1610f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const LookupRecord lookupRecord[], 1611f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod ChainContextCollectGlyphsLookupContext &lookup_context) 1612f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod{ 16138303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod collect_array (c, c->before, 1614f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod backtrackCount, backtrack, 1615f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup_context.funcs.collect, lookup_context.collect_data[0]); 16168303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod collect_array (c, c->input, 1617f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod inputCount ? inputCount - 1 : 0, input, 1618f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup_context.funcs.collect, lookup_context.collect_data[1]); 16198303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod collect_array (c, c->after, 1620f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookaheadCount, lookahead, 1621f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup_context.funcs.collect, lookup_context.collect_data[2]); 1622f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod recurse_lookups (c, 1623f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookupCount, lookupRecord); 1624f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod} 1625f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 1626e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbodstatic inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c, 1627e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int backtrackCount, 16280beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod const USHORT backtrack[] HB_UNUSED, 1629e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 1630e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const USHORT input[], /* Array of input values--start with second glyph */ 1631e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int lookaheadCount, 16320beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod const USHORT lookahead[] HB_UNUSED, 16330beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod unsigned int lookupCount HB_UNUSED, 16340beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbod const LookupRecord lookupRecord[] HB_UNUSED, 1635e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod ChainContextApplyLookupContext &lookup_context) 1636e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod{ 1637d9b204d3d24cde165167714728bf380267903d6aBehdad Esfahbod return (c->zero_context ? !backtrackCount && !lookaheadCount : true) 16381f2bb172fe9a173ecfd61054f1fdd850943ef059Behdad Esfahbod && would_match_input (c, 1639e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inputCount, input, 1640e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod lookup_context.funcs.match, lookup_context.match_data[1]); 1641e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod} 1642e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 164331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbodstatic inline bool chain_context_apply_lookup (hb_apply_context_t *c, 164431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int backtrackCount, 164531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const USHORT backtrack[], 164631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int inputCount, /* Including the first glyph (not matched) */ 164731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const USHORT input[], /* Array of input values--start with second glyph */ 164831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int lookaheadCount, 164931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const USHORT lookahead[], 165031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int lookupCount, 165131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const LookupRecord lookupRecord[], 165231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod ChainContextApplyLookupContext &lookup_context) 165302e1e5c63fa4f896053fa3c21e495239e1e9caa2Behdad Esfahbod{ 16546b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int match_length = 0; 16556b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod unsigned int match_positions[MAX_CONTEXT_LENGTH]; 1656f19e0b0099ec73b8fedccacff4902403f5eabc42Behdad Esfahbod return match_input (c, 16574169710911450e0f9bc045fe279bfc8ba9e8457cBehdad Esfahbod inputCount, input, 16584169710911450e0f9bc045fe279bfc8ba9e8457cBehdad Esfahbod lookup_context.funcs.match, lookup_context.match_data[1], 16596b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod &match_length, match_positions) 1660f19e0b0099ec73b8fedccacff4902403f5eabc42Behdad Esfahbod && match_backtrack (c, 1661f19e0b0099ec73b8fedccacff4902403f5eabc42Behdad Esfahbod backtrackCount, backtrack, 1662f19e0b0099ec73b8fedccacff4902403f5eabc42Behdad Esfahbod lookup_context.funcs.match, lookup_context.match_data[0]) 1663d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod && match_lookahead (c, 16644169710911450e0f9bc045fe279bfc8ba9e8457cBehdad Esfahbod lookaheadCount, lookahead, 16654169710911450e0f9bc045fe279bfc8ba9e8457cBehdad Esfahbod lookup_context.funcs.match, lookup_context.match_data[2], 16666b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod match_length) 16675df809b655bb1318115651fd87d4555cdd9b41cbBehdad Esfahbod && apply_lookup (c, 16686b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod inputCount, match_positions, 16696b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod lookupCount, lookupRecord, 16706b65a76b40522a4f57a6fedcbdfc5a4d736f1d3cBehdad Esfahbod match_length); 167102e1e5c63fa4f896053fa3c21e495239e1e9caa2Behdad Esfahbod} 167248f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod 167360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ChainRule 167460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 16755caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const 167631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod { 1677be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 167831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 167931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 168031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 16815caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod chain_context_closure_lookup (c, 16825caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod backtrack.len, backtrack.array, 16835caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod input.len, input.array, 16845caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookahead.len, lookahead.array, 16855caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup.len, lookup.array, 16865caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context); 168731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 168831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1689f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const 1690f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod { 1691f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 1692f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 1693f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 1694f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 1695f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod chain_context_collect_glyphs_lookup (c, 1696f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod backtrack.len, backtrack.array, 1697f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod input.len, input.array, 1698f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookahead.len, lookahead.array, 1699f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup.len, lookup.array, 1700f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup_context); 1701f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod } 1702f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 1703e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 1704e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1705be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1706e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 1707e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 1708e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 1709e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return TRACE_RETURN (chain_context_would_apply_lookup (c, 1710e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod backtrack.len, backtrack.array, 1711e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod input.len, input.array, 1712e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod lookahead.len, lookahead.array, lookup.len, 1713e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod lookup.array, lookup_context)); 1714e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1715e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 171631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 171760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1718be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 1719e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 1720e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 1721e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 1722acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (chain_context_apply_lookup (c, 1723acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod backtrack.len, backtrack.array, 1724acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod input.len, input.array, 1725acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod lookahead.len, lookahead.array, lookup.len, 1726acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod lookup.array, lookup_context)); 1727aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod } 1728aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 1729d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1730be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 17310ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!backtrack.sanitize (c)) return TRACE_RETURN (false); 1732e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 17330ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!input.sanitize (c)) return TRACE_RETURN (false); 1734e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 17350ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!lookahead.sanitize (c)) return TRACE_RETURN (false); 1736e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 17370ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (lookup.sanitize (c)); 173870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 1739ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 1740ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 1741dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod ArrayOf<USHORT> 1742dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod backtrack; /* Array of backtracking values 1743ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * (to be matched before the input 1744ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * sequence) */ 1745e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod HeadlessArrayOf<USHORT> 1746e8cbaaf6d538036ff9b880b018db402e0895ed01Behdad Esfahbod inputX; /* Array of input values (start with 1747ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * second glyph) */ 1748dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod ArrayOf<USHORT> 1749dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod lookaheadX; /* Array of lookahead values's (to be 175048f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod * matched after the input sequence) */ 1751dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod ArrayOf<LookupRecord> 175202e1e5c63fa4f896053fa3c21e495239e1e9caa2Behdad Esfahbod lookupX; /* Array of LookupRecords--in 1753ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * design order) */ 1754b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 1755bea34c7cbb583cf7660776e95cab3171590b8427Behdad Esfahbod DEFINE_SIZE_MIN (8); 1756ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 1757ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 175860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ChainRuleSet 175960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 17605caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const 176131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod { 1762be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 176331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int num_rules = rule.len; 176431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 17655caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod (this+rule[i]).closure (c, lookup_context); 176631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 176731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1768f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const 1769f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod { 1770f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 1771f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int num_rules = rule.len; 1772f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 1773f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod (this+rule[i]).collect_glyphs (c, lookup_context); 1774f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod } 1775f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 1776e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 1777e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1778be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1779e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod unsigned int num_rules = rule.len; 1780e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 1781e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod if ((this+rule[i]).would_apply (c, lookup_context)) 1782e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return TRACE_RETURN (true); 1783e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1784e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return TRACE_RETURN (false); 1785e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1786e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 178731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 178860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1789be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 179048f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod unsigned int num_rules = rule.len; 179160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod for (unsigned int i = 0; i < num_rules; i++) 1792d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod if ((this+rule[i]).apply (c, lookup_context)) 1793acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (true); 179448f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod 1795acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (false); 179648f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod } 1797ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 1798d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1799be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 18000ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (rule.sanitize (c, this)); 180170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 180270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1803ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 180448f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod OffsetArrayOf<ChainRule> 180548f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod rule; /* Array of ChainRule tables 180648f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod * ordered by preference */ 1807b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 18080eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (2, rule); 1809ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 1810ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 181160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ChainContextFormat1 181260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 181344fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline void closure (hb_closure_context_t *c) const 1814f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 1815be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 181631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const Coverage &cov = (this+coverage); 181731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 181831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ChainContextClosureLookupContext lookup_context = { 181944fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod {intersects_glyph}, 182031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod {NULL, NULL, NULL} 182131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod }; 182231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 182331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = ruleSet.len; 182431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 182531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (cov.intersects_coverage (c->glyphs, i)) { 182631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ChainRuleSet &rule_set = this+ruleSet[i]; 18275caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod rule_set.closure (c, lookup_context); 182831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 1829f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 1830f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 183126514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 183226514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 1833f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 18348303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+coverage).add_coverage (c->input); 1835f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 1836f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod struct ChainContextCollectGlyphsLookupContext lookup_context = { 1837f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod {collect_glyph}, 1838f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod {NULL, NULL, NULL} 1839f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod }; 1840f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 1841f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int count = ruleSet.len; 1842f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1843f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod (this+ruleSet[i]).collect_glyphs (c, lookup_context); 184426514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 184526514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 1846e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 1847e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1848be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1849e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 1850b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])]; 1851e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod struct ChainContextApplyLookupContext lookup_context = { 1852ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_glyph}, 1853e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod {NULL, NULL, NULL} 1854e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod }; 1855e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); 1856e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1857e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 185844fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline const Coverage &get_coverage (void) const 185944fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 186044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod return this+coverage; 186144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 186244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 1863ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 186460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1865be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 1866b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 1867acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 1868ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 1869aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod const ChainRuleSet &rule_set = this+ruleSet[index]; 187031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ChainContextApplyLookupContext lookup_context = { 1871ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_glyph}, 1872aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod {NULL, NULL, NULL} 1873aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod }; 1874acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (rule_set.apply (c, lookup_context)); 1875aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod } 187670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1877d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1878be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 18790ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); 188070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 188170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1882ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 1883ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod USHORT format; /* Format identifier--format = 1 */ 188448f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod OffsetTo<Coverage> 188548f16ed96ac7041b511d9e0864623d2aa09c6da3Behdad Esfahbod coverage; /* Offset to Coverage table--from 1886ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * beginning of table */ 1887aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetArrayOf<ChainRuleSet> 1888aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod ruleSet; /* Array of ChainRuleSet tables 1889aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod * ordered by Coverage Index */ 1890b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 18910eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, ruleSet); 1892ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 1893ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 189460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ChainContextFormat2 189560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 189644fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline void closure (hb_closure_context_t *c) const 1897f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 1898be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 189931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (!(this+coverage).intersects (c->glyphs)) 19005caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod return; 190131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 190231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ClassDef &backtrack_class_def = this+backtrackClassDef; 190331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ClassDef &input_class_def = this+inputClassDef; 190431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ClassDef &lookahead_class_def = this+lookaheadClassDef; 190531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 190631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ChainContextClosureLookupContext lookup_context = { 190744fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod {intersects_class}, 190831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod {&backtrack_class_def, 190931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod &input_class_def, 191031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod &lookahead_class_def} 191131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod }; 191231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 191331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = ruleSet.len; 191431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 191531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (input_class_def.intersects_class (c->glyphs, i)) { 191631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const ChainRuleSet &rule_set = this+ruleSet[i]; 19175caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod rule_set.closure (c, lookup_context); 191831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 1919f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 1920f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 192126514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 192226514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 1923f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 19248303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+coverage).add_coverage (c->input); 1925f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 192611fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod const ClassDef &backtrack_class_def = this+backtrackClassDef; 192711fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod const ClassDef &input_class_def = this+inputClassDef; 192811fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod const ClassDef &lookahead_class_def = this+lookaheadClassDef; 192911fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod 1930f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod struct ChainContextCollectGlyphsLookupContext lookup_context = { 1931f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod {collect_class}, 193211fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod {&backtrack_class_def, 193311fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod &input_class_def, 193411fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod &lookahead_class_def} 1935f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod }; 1936f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 1937f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod unsigned int count = ruleSet.len; 1938f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1939f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod (this+ruleSet[i]).collect_glyphs (c, lookup_context); 194026514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 194126514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 1942e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 1943e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 1944be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 1945e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 194611fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod const ClassDef &backtrack_class_def = this+backtrackClassDef; 1947e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const ClassDef &input_class_def = this+inputClassDef; 194811fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod const ClassDef &lookahead_class_def = this+lookaheadClassDef; 1949e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 19502dc1141d7d0a9f5818862b09d6b9cfe0a27f1fc1Behdad Esfahbod unsigned int index = input_class_def.get_class (c->glyphs[0]); 1951e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const ChainRuleSet &rule_set = this+ruleSet[index]; 1952e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod struct ChainContextApplyLookupContext lookup_context = { 1953ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_class}, 195411fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod {&backtrack_class_def, 195511fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod &input_class_def, 195611fba79ee9383eb995ddf7eb924dd64c67e2df63Behdad Esfahbod &lookahead_class_def} 1957e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod }; 1958e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); 1959e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 1960e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 196144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline const Coverage &get_coverage (void) const 196244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 196344fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod return this+coverage; 196444fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 196544fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 1966ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 196760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1968be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 1969b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 1970acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 1971aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 1972aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod const ClassDef &backtrack_class_def = this+backtrackClassDef; 1973aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod const ClassDef &input_class_def = this+inputClassDef; 1974aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod const ClassDef &lookahead_class_def = this+lookaheadClassDef; 1975aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 19762dc1141d7d0a9f5818862b09d6b9cfe0a27f1fc1Behdad Esfahbod index = input_class_def.get_class (c->buffer->cur().codepoint); 1977aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod const ChainRuleSet &rule_set = this+ruleSet[index]; 197831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ChainContextApplyLookupContext lookup_context = { 1979ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_class}, 198040cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod {&backtrack_class_def, 198140cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod &input_class_def, 198240cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod &lookahead_class_def} 1983aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod }; 1984acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (rule_set.apply (c, lookup_context)); 1985ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod } 1986ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 1987d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1988be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 19890ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) && 19900ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) && 19910ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod ruleSet.sanitize (c, this)); 199270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 199370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 1994ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 1995ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod USHORT format; /* Format identifier--format = 2 */ 1996aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetTo<Coverage> 1997aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod coverage; /* Offset to Coverage table--from 1998ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * beginning of table */ 1999aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetTo<ClassDef> 2000aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod backtrackClassDef; /* Offset to glyph ClassDef table 2001ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * containing backtrack sequence 2002ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * data--from beginning of table */ 2003aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetTo<ClassDef> 2004aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod inputClassDef; /* Offset to glyph ClassDef 2005ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * table containing input sequence 2006ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * data--from beginning of table */ 2007aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetTo<ClassDef> 2008aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod lookaheadClassDef; /* Offset to glyph ClassDef table 2009ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * containing lookahead sequence 2010ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * data--from beginning of table */ 2011aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod OffsetArrayOf<ChainRuleSet> 2012aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod ruleSet; /* Array of ChainRuleSet tables 2013aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod * ordered by class */ 2014b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 20150eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (12, ruleSet); 2016ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 2017ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 201860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ChainContextFormat3 201960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 202044fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline void closure (hb_closure_context_t *c) const 2021f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod { 2022be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_CLOSURE (this); 20235caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20245caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod 20255caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod if (!(this+input[0]).intersects (c->glyphs)) 20265caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod return; 20275caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod 20285caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 20295caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 20305caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod struct ChainContextClosureLookupContext lookup_context = { 203144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod {intersects_coverage}, 20325caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod {this, this, this} 20335caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod }; 20345caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod chain_context_closure_lookup (c, 20355caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod backtrack.len, (const USHORT *) backtrack.array, 20365caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod input.len, (const USHORT *) input.array + 1, 20375caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookahead.len, (const USHORT *) lookahead.array, 20385caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup.len, lookup.array, 20395caece67ab9eee322bdcdf6f4b607eadde297e56Behdad Esfahbod lookup_context); 2040f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod } 2041f94b0aa64609654497ced9c00312c9643eb69053Behdad Esfahbod 204226514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 204326514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod { 2044f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod TRACE_COLLECT_GLYPHS (this); 2045f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 2046f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 20478303593ba1db06e402eab52df47f21f13049112dBehdad Esfahbod (this+input[0]).add_coverage (c->input); 2048f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod 2049f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 2050f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 2051f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod struct ChainContextCollectGlyphsLookupContext lookup_context = { 2052f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod {collect_coverage}, 2053f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod {this, this, this} 2054f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod }; 2055f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod chain_context_collect_glyphs_lookup (c, 2056f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod backtrack.len, (const USHORT *) backtrack.array, 2057f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod input.len, (const USHORT *) input.array + 1, 2058f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookahead.len, (const USHORT *) lookahead.array, 2059f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup.len, lookup.array, 2060f1b12781d279a73b5754afee31e930b5cd87aac6Behdad Esfahbod lookup_context); 206126514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod } 206226514d51b6669f092d9ccb7523443a5ece74169aBehdad Esfahbod 2063e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod inline bool would_apply (hb_would_apply_context_t *c) const 2064e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod { 2065be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_WOULD_APPLY (this); 2066e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 2067e6f7479fe34fb4a7cada61d84c2ed70d1fd565c8Behdad Esfahbod const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 2068e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 2069e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 2070e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod struct ChainContextApplyLookupContext lookup_context = { 2071ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_coverage}, 2072e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod {this, this, this} 2073e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod }; 2074e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod return TRACE_RETURN (chain_context_would_apply_lookup (c, 2075e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod backtrack.len, (const USHORT *) backtrack.array, 2076e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod input.len, (const USHORT *) input.array + 1, 2077e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod lookahead.len, (const USHORT *) lookahead.array, 2078e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod lookup.len, lookup.array, lookup_context)); 2079e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 2080e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 208144fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod inline const Coverage &get_coverage (void) const 208244fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod { 208344fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 208444fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod return this+input[0]; 208544fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod } 208644fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod 2087ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod inline bool apply (hb_apply_context_t *c) const 208860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 2089be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_APPLY (this); 2090e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 209102e1e5c63fa4f896053fa3c21e495239e1e9caa2Behdad Esfahbod 2092b67881b171a7cf865af58df146da52fc1e27b160Behdad Esfahbod unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); 2093acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 209402e1e5c63fa4f896053fa3c21e495239e1e9caa2Behdad Esfahbod 2095e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 2096e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 209731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod struct ChainContextApplyLookupContext lookup_context = { 2098ec35a72a44301934b8f123ab2833f59d8c875a09Behdad Esfahbod {match_coverage}, 209940cbefe858192531ed64dd51d402f7ca7b8153a3Behdad Esfahbod {this, this, this} 2100aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod }; 2101acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod return TRACE_RETURN (chain_context_apply_lookup (c, 2102acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod backtrack.len, (const USHORT *) backtrack.array, 2103acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod input.len, (const USHORT *) input.array + 1, 2104acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod lookahead.len, (const USHORT *) lookahead.array, 2105acea183e986dd378c6f95120fe0feb0586a8ef36Behdad Esfahbod lookup.len, lookup.array, lookup_context)); 2106aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod } 2107aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 2108d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 2109be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 21100ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false); 2111e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 21120ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!input.sanitize (c, this)) return TRACE_RETURN (false); 21139df0a520306a491f973d42965597bfda6023e508Behdad Esfahbod if (!input.len) return TRACE_RETURN (false); /* To be consistent with Context. */ 2114e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 21150ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false); 2116e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 21170ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (lookup.sanitize (c)); 211870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 211970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 2120ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 2121ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod USHORT format; /* Format identifier--format = 3 */ 2122dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod OffsetArrayOf<Coverage> 212313ed4405c558e445b052360f1ed8ee27ecf48e6eBehdad Esfahbod backtrack; /* Array of coverage tables 2124ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * in backtracking sequence, in glyph 2125ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * sequence order */ 2126dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod OffsetArrayOf<Coverage> 212713ed4405c558e445b052360f1ed8ee27ecf48e6eBehdad Esfahbod inputX ; /* Array of coverage 2128ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * tables in input sequence, in glyph 2129ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * sequence order */ 2130dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod OffsetArrayOf<Coverage> 213113ed4405c558e445b052360f1ed8ee27ecf48e6eBehdad Esfahbod lookaheadX; /* Array of coverage tables 2132ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * in lookahead sequence, in glyph 2133ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod * sequence order */ 2134dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod ArrayOf<LookupRecord> 213502e1e5c63fa4f896053fa3c21e495239e1e9caa2Behdad Esfahbod lookupX; /* Array of LookupRecords--in 2136dcb6b60254951a2831c03f3196962d229f7e556cBehdad Esfahbod * design order) */ 2137b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 2138bea34c7cbb583cf7660776e95cab3171590b8427Behdad Esfahbod DEFINE_SIZE_MIN (10); 2139ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 2140ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 214160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ChainContext 214260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 214344fc237b53ebfbaf8a539de16ad735d2c6afc52bBehdad Esfahbod template <typename context_t> 21449c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 2145e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod { 214600f6a8e334ec4c586e4e633a95b411ccb50306d3Behdad Esfahbod TRACE_DISPATCH (this, u.format); 2147e8cfdd7fa8d0fb66e0a261f3547e5824897e5131Behdad Esfahbod switch (u.format) { 21489c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case 1: return TRACE_RETURN (c->dispatch (u.format1)); 21499c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case 2: return TRACE_RETURN (c->dispatch (u.format2)); 21509c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod case 3: return TRACE_RETURN (c->dispatch (u.format3)); 2151f48ec0e83432c038b50d9715a38ba1469e82e1e4Behdad Esfahbod default:return TRACE_RETURN (c->default_return_value ()); 2152e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 2153e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod } 2154e72b360ac6381b549249b8836fa3e70b909d3437Behdad Esfahbod 2155d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 2156be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 21570ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!u.format.sanitize (c)) return TRACE_RETURN (false); 215870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 21590ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 1: return TRACE_RETURN (u.format1.sanitize (c)); 21600ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 2: return TRACE_RETURN (u.format2.sanitize (c)); 21610ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 3: return TRACE_RETURN (u.format3.sanitize (c)); 21620ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod default:return TRACE_RETURN (true); 216370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 216470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 216570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 2166ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 2167ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod union { 2168ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod USHORT format; /* Format identifier */ 2169dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ChainContextFormat1 format1; 2170dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ChainContextFormat2 format2; 2171dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ChainContextFormat3 format3; 2172ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod } u; 2173ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod}; 2174ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 2175ca5290f4994e1b2db4dac03f7a22b7071441ba06Behdad Esfahbod 2176d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbodstruct ExtensionFormat1 2177d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod{ 2178d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod inline unsigned int get_type (void) const { return extensionLookupType; } 21793b2c2df41b90f2a1d9e33b3dc15a92cff58a689aBehdad Esfahbod inline unsigned int get_offset (void) const { return extensionOffset; } 2180d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod 2181d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 2182be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 21830ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (c->check_struct (this)); 218470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 218570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 2186ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 2187d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod USHORT format; /* Format identifier. Set to 1. */ 2188d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod USHORT extensionLookupType; /* Lookup type of subtable referenced 2189d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod * by ExtensionOffset (i.e. the 2190d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod * extension subtable). */ 219181f2af40f9afd5bb9695018e6baddcd4aa3361c1Behdad Esfahbod ULONG extensionOffset; /* Offset to the extension subtable, 219281f2af40f9afd5bb9695018e6baddcd4aa3361c1Behdad Esfahbod * of lookup type subtable. */ 2193b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 2194b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod DEFINE_SIZE_STATIC (8); 2195d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod}; 2196d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod 2197653eeb26450053b731b46346606931f5ae88db72Behdad Esfahbodtemplate <typename T> 2198d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbodstruct Extension 2199d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod{ 2200d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod inline unsigned int get_type (void) const 2201d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod { 2202d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod switch (u.format) { 2203dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 1: return u.format1.get_type (); 2204d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod default:return 0; 2205d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod } 2206d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod } 22073b2c2df41b90f2a1d9e33b3dc15a92cff58a689aBehdad Esfahbod inline unsigned int get_offset (void) const 2208d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod { 2209d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod switch (u.format) { 2210dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 1: return u.format1.get_offset (); 22113b2c2df41b90f2a1d9e33b3dc15a92cff58a689aBehdad Esfahbod default:return 0; 2212d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod } 2213d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod } 2214d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod 22157dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod template <typename X> 22167dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod inline const X& get_subtable (void) const 22177dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod { 22187dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod unsigned int offset = get_offset (); 22197dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod if (unlikely (!offset)) return Null(typename T::LookupSubTable); 22207dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod return StructAtOffset<typename T::LookupSubTable> (this, offset); 22217dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod } 22227dddd4e72bc35be962d93dc1b76c7e26c63aaa6dBehdad Esfahbod 2223653eeb26450053b731b46346606931f5ae88db72Behdad Esfahbod template <typename context_t> 22249c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 2225653eeb26450053b731b46346606931f5ae88db72Behdad Esfahbod { 22269c5a9ee967120c8a968a1160c420e03620d46c24Behdad Esfahbod return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()); 2227653eeb26450053b731b46346606931f5ae88db72Behdad Esfahbod } 2228653eeb26450053b731b46346606931f5ae88db72Behdad Esfahbod 2229ed2e13594479c6ed7909401509962ea2f03f9a6eBehdad Esfahbod inline bool sanitize_self (hb_sanitize_context_t *c) { 2230be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 22310ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!u.format.sanitize (c)) return TRACE_RETURN (false); 223270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 22330ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 1: return TRACE_RETURN (u.format1.sanitize (c)); 22340ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod default:return TRACE_RETURN (true); 223570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 223670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 223770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 2238ed2e13594479c6ed7909401509962ea2f03f9a6eBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 2239ed2e13594479c6ed7909401509962ea2f03f9a6eBehdad Esfahbod TRACE_SANITIZE (this); 2240ed2e13594479c6ed7909401509962ea2f03f9a6eBehdad Esfahbod if (!sanitize_self (c)) return TRACE_RETURN (false); 2241ed2e13594479c6ed7909401509962ea2f03f9a6eBehdad Esfahbod unsigned int offset = get_offset (); 2242ed2e13594479c6ed7909401509962ea2f03f9a6eBehdad Esfahbod if (unlikely (!offset)) return TRACE_RETURN (true); 2243ed2e13594479c6ed7909401509962ea2f03f9a6eBehdad Esfahbod return TRACE_RETURN (StructAtOffset<typename T::LookupSubTable> (this, offset).sanitize (c, get_type ())); 2244ed2e13594479c6ed7909401509962ea2f03f9a6eBehdad Esfahbod } 2245ed2e13594479c6ed7909401509962ea2f03f9a6eBehdad Esfahbod 2246ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 2247d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod union { 2248d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod USHORT format; /* Format identifier */ 22496d08c7f1b3601095f9a12630045331dd0fe75380Behdad Esfahbod ExtensionFormat1 format1; 2250d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod } u; 2251d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod}; 2252d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod 2253d468f9af5b9fdc2713b0b86f28129e4190ee5053Behdad Esfahbod 2254f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod/* 2255f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod * GSUB/GPOS Common 2256f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod */ 2257f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod 225860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct GSUBGPOS 225960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 2260a328d66e6a8122f7d4d71941449d4d0136203e08Behdad Esfahbod static const hb_tag_t GSUBTag = HB_OT_TAG_GSUB; 2261a328d66e6a8122f7d4d71941449d4d0136203e08Behdad Esfahbod static const hb_tag_t GPOSTag = HB_OT_TAG_GPOS; 2262f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod 2263bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_script_count (void) const 2264bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+scriptList).len; } 2265bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Tag& get_script_tag (unsigned int i) const 2266bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+scriptList).get_tag (i); } 2267e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_script_tags (unsigned int start_offset, 2268e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *script_count /* IN/OUT */, 2269e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod hb_tag_t *script_tags /* OUT */) const 2270e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return (this+scriptList).get_tags (start_offset, script_count, script_tags); } 2271bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Script& get_script (unsigned int i) const 2272bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+scriptList)[i]; } 2273bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline bool find_script_index (hb_tag_t tag, unsigned int *index) const 2274bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+scriptList).find_index (tag, index); } 2275bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 2276bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_feature_count (void) const 2277bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+featureList).len; } 2278da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew inline hb_tag_t get_feature_tag (unsigned int i) const 2279da132937989acb4d8ca9bd41c79f98750e7dda30Jonathan Kew { return i == Index::NOT_FOUND_INDEX ? HB_TAG_NONE : (this+featureList).get_tag (i); } 2280e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_feature_tags (unsigned int start_offset, 2281e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 2282e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod hb_tag_t *feature_tags /* OUT */) const 2283e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return (this+featureList).get_tags (start_offset, feature_count, feature_tags); } 2284bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Feature& get_feature (unsigned int i) const 2285bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+featureList)[i]; } 2286bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const 2287bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+featureList).find_index (tag, index); } 2288bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 2289bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_lookup_count (void) const 2290bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+lookupList).len; } 2291bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Lookup& get_lookup (unsigned int i) const 2292bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return (this+lookupList)[i]; } 2293f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod 2294d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 2295be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 22960ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && 22970ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod scriptList.sanitize (c, this) && 22980ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod featureList.sanitize (c, this) && 22990ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod lookupList.sanitize (c, this)); 2300cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 2301cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 2302212aba6189d7aaac0bab169b77ae6bdab16800a5Behdad Esfahbod protected: 230387fcdcbe3644da10154688765db2d62eb9ac079aBehdad Esfahbod FixedVersion version; /* Version of the GSUB/GPOS table--initially set 23047627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod * to 0x00010000u */ 2305f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod OffsetTo<ScriptList> 2306f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod scriptList; /* ScriptList table */ 2307f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod OffsetTo<FeatureList> 2308f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod featureList; /* FeatureList table */ 2309f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod OffsetTo<LookupList> 2310f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod lookupList; /* LookupList table */ 2311b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 2312b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod DEFINE_SIZE_STATIC (10); 2313f45107fe0904414f1266648a6c42849c494fe611Behdad Esfahbod}; 231466bf7ce4e3135535c110a917178b84c4a2b1d11fBehdad Esfahbod 23156f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 23167d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod} /* namespace OT */ 23177c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 2318acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 23195f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ 2320