15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2007,2008,2009,2010 Red Hat, Inc. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2010,2012 Google, Inc. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is part of HarfBuzz, a text shaping library. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, without written agreement and without 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * license or royalty fees, to use, copy, modify, and distribute this 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * software and its documentation for any purpose, provided that the 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * above copyright notice and the following two paragraphs appear in 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all copies of this software. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DAMAGE. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Red Hat Author(s): Behdad Esfahbod 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Google Author(s): Behdad Esfahbod 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-buffer-private.hh" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-ot-layout-gdef-table.hh" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-set-private.hh" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace OT { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_DISPATCH(this) \ 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \ 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ""); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_DEBUG_CLOSURE 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_DEBUG_CLOSURE (HB_DEBUG+0) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_CLOSURE(this) \ 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \ 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ""); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_closure_context_t 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const char *get_name (void) { return "CLOSURE"; } 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef hb_void_t return_t; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename T> 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; } 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static return_t default_return_value (void) { return HB_VOID; } 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return_t recurse (unsigned int lookup_index) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (nesting_level_left == 0 || !recurse_func)) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return default_return_value (); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left--; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func (this, lookup_index); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left++; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return HB_VOID; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_face_t *face; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_set_t *glyphs; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func_t recurse_func; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int nesting_level_left; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int debug_depth; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_closure_context_t (hb_face_t *face_, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_set_t *glyphs_, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) face (face_), 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphs (glyphs_), 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func (NULL), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nesting_level_left (nesting_level_left_), 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_depth (0) {} 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_recurse_func (recurse_func_t func) { recurse_func = func; } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_DEBUG_WOULD_APPLY 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_WOULD_APPLY(this) \ 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \ 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "%d glyphs", c->len); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_would_apply_context_t 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const char *get_name (void) { return "WOULD_APPLY"; } 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef bool return_t; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename T> 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline return_t dispatch (const T &obj) { return obj.would_apply (this); } 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static return_t default_return_value (void) { return false; } 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool stop_sublookup_iteration (return_t r) const { return r; } 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_face_t *face; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_codepoint_t *glyphs; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool zero_context; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int debug_depth; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_would_apply_context_t (hb_face_t *face_, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_codepoint_t *glyphs_, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len_, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool zero_context_) : 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) face (face_), 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphs (glyphs_), 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len (len_), 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zero_context (zero_context_), 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_depth (0) {} 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef HB_DEBUG_COLLECT_GLYPHS 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define HB_DEBUG_COLLECT_GLYPHS (HB_DEBUG+0) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_COLLECT_GLYPHS(this) \ 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \ 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ""); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct hb_collect_glyphs_context_t 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const char *get_name (void) { return "COLLECT_GLYPHS"; } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef hb_void_t return_t; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename T> 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; } 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static return_t default_return_value (void) { return HB_VOID; } 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return_t recurse (unsigned int lookup_index) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (nesting_level_left == 0 || !recurse_func)) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return default_return_value (); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Note that GPOS sets recurse_func to NULL already, so it doesn't get 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * past the previous check. For GSUB, we only want to collect the output 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * glyphs in the recursion. If output is not requested, we can go home now. 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Note further, that the above is not exactly correct. A recursed lookup 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * is allowed to match input that is not matched in the context, but that's 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * not how most fonts are built. It's possible to relax that and recurse 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * with all sets here if it proves to be an issue. 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (output == hb_set_get_empty ()) 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return HB_VOID; 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *old_before = before; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *old_input = input; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *old_after = after; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) before = input = after = hb_set_get_empty (); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left--; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func (this, lookup_index); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left++; 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) before = old_before; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) input = old_input; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) after = old_after; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return HB_VOID; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_face_t *face; 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *before; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *input; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *after; 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *output; 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func_t recurse_func; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int nesting_level_left; 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int debug_depth; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_collect_glyphs_context_t (hb_face_t *face_, 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *glyphs_before, /* OUT. May be NULL */ 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *glyphs_input, /* OUT. May be NULL */ 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *glyphs_after, /* OUT. May be NULL */ 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *glyphs_output, /* OUT. May be NULL */ 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) face (face_), 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) before (glyphs_before ? glyphs_before : hb_set_get_empty ()), 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) input (glyphs_input ? glyphs_input : hb_set_get_empty ()), 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) after (glyphs_after ? glyphs_after : hb_set_get_empty ()), 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output (glyphs_output ? glyphs_output : hb_set_get_empty ()), 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func (NULL), 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left (nesting_level_left_), 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_depth (0) {} 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_recurse_func (recurse_func_t func) { recurse_func = func; } 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct hb_get_coverage_context_t 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const char *get_name (void) { return "GET_COVERAGE"; } 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const unsigned int max_debug_depth = 0; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef const Coverage &return_t; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename T> 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline return_t dispatch (const T &obj) { return obj.get_coverage (); } 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static return_t default_return_value (void) { return Null(Coverage); } 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_get_coverage_context_t (void) : 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_depth (0) {} 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int debug_depth; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_DEBUG_APPLY 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_DEBUG_APPLY (HB_DEBUG+0) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_APPLY(this) \ 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \ 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_apply_context_t 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const char *get_name (void) { return "APPLY"; } 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const unsigned int max_debug_depth = HB_DEBUG_APPLY; 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef bool return_t; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename T> 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline return_t dispatch (const T &obj) { return obj.apply (this); } 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static return_t default_return_value (void) { return false; } 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool stop_sublookup_iteration (return_t r) const { return r; } 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return_t recurse (unsigned int lookup_index) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (nesting_level_left == 0 || !recurse_func)) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return default_return_value (); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left--; 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ret = recurse_func (this, lookup_index); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left++; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ret; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int table_index; /* GSUB/GPOS */ 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_font_t *font; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_face_t *face; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_buffer_t *buffer; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_direction_t direction; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_mask_t lookup_mask; 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool auto_zwj; 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func_t recurse_func; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int nesting_level_left; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookup_props; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GDEF &gdef; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_glyph_classes; 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int debug_depth; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_apply_context_t (unsigned int table_index_, 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_font_t *font_, 280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer_) : 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) table_index (table_index_), 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) font (font_), face (font->face), buffer (buffer_), 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) direction (buffer_->props.direction), 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) lookup_mask (1), 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) auto_zwj (true), 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func (NULL), 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nesting_level_left (MAX_NESTING_LEVEL), 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) lookup_props (0), 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdef (*hb_ot_layout_from_face (face)->gdef), 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_glyph_classes (gdef.has_glyph_classes ()), 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_depth (0) {} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); } 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct matcher_t 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline matcher_t (void) : 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) lookup_props (0), 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ignore_zwnj (false), 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ignore_zwj (false), 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mask (-1), 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */ 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) syllable arg1(0), 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#undef arg1 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_func (NULL), 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_data (NULL) {}; 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data); 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_mask (hb_mask_t mask_) { mask = mask_; } 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_syllable (uint8_t syllable_) { syllable = syllable_; } 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_match_func (match_func_t match_func_, 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const void *match_data_) 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { match_func = match_func_; match_data = match_data_; } 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) enum may_match_t { 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MATCH_NO, 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MATCH_YES, 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MATCH_MAYBE 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline may_match_t may_match (const hb_glyph_info_t &info, 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const USHORT *glyph_data) const 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!(info.mask & mask) || 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (syllable && syllable != info.syllable ())) 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return MATCH_NO; 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (match_func) 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO; 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return MATCH_MAYBE; 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) enum may_skip_t { 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SKIP_NO, 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SKIP_YES, 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SKIP_MAYBE 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline may_skip_t 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) may_skip (const hb_apply_context_t *c, 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const hb_glyph_info_t &info) const 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int property; 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) property = _hb_glyph_info_get_glyph_props (&info); 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!c->match_properties (info.codepoint, property, lookup_props)) 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SKIP_YES; 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) !_hb_glyph_info_ligated (&info))) 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SKIP_MAYBE; 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SKIP_NO; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int lookup_props; 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool ignore_zwnj; 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool ignore_zwj; 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_mask_t mask; 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint8_t syllable; 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_func_t match_func; 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const void *match_data; 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct skipping_forward_iterator_t 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline skipping_forward_iterator_t (hb_apply_context_t *c_, 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int start_index_, 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int num_items_, 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool context_match = false) : 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) idx (start_index_), 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) c (c_), 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_glyph_data (NULL), 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) num_items (num_items_), 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) end (c->buffer->len) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_lookup_props (c->lookup_props); 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_ignore_zwnj (context_match || c->table_index == 1); 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!context_match) 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_mask (c->lookup_mask); 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); } 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); } 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_match_func (matcher_t::match_func_t match_func, 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const void *match_data, 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const USHORT glyph_data[]) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_match_func (match_func, match_data); 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_glyph_data = glyph_data; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline bool has_no_chance (void) const { return unlikely (num_items && idx + num_items >= end); } 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void reject (void) { num_items++; match_glyph_data--; } 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline bool next (void) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert (num_items > 0); 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (!has_no_chance ()) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idx++; 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const hb_glyph_info_t &info = c->buffer->info[idx]; 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher_t::may_skip_t skip = matcher.may_skip (c, info); 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (unlikely (skip == matcher_t::SKIP_YES)) 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (match == matcher_t::MATCH_YES || 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (match == matcher_t::MATCH_MAYBE && 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skip == matcher_t::SKIP_NO)) 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) num_items--; 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_glyph_data++; 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (skip == matcher_t::SKIP_NO) 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int idx; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_apply_context_t *c; 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher_t matcher; 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const USHORT *match_glyph_data; 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_items; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int end; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct skipping_backward_iterator_t 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline skipping_backward_iterator_t (hb_apply_context_t *c_, 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int start_index_, 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int num_items_, 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool context_match = false) : 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) idx (start_index_), 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) c (c_), 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_glyph_data (NULL), 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) num_items (num_items_) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_lookup_props (c->lookup_props); 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_ignore_zwnj (context_match || c->table_index == 1); 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!context_match) 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_mask (c->lookup_mask); 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); } 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); } 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_match_func (matcher_t::match_func_t match_func, 472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const void *match_data, 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const USHORT glyph_data[]) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_match_func (match_func, match_data); 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_glyph_data = glyph_data; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline bool has_no_chance (void) const { return unlikely (idx < num_items); } 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void reject (void) { num_items++; } 481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline bool prev (void) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert (num_items > 0); 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (!has_no_chance ()) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idx--; 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const hb_glyph_info_t &info = c->buffer->out_info[idx]; 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher_t::may_skip_t skip = matcher.may_skip (c, info); 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (unlikely (skip == matcher_t::SKIP_YES)) 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (match == matcher_t::MATCH_YES || 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (match == matcher_t::MATCH_MAYBE && 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skip == matcher_t::SKIP_NO)) 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) num_items--; 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_glyph_data++; 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (skip == matcher_t::SKIP_NO) 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int idx; 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_apply_context_t *c; 513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher_t matcher; 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const USHORT *match_glyph_data; 515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_items; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_properties_mark (hb_codepoint_t glyph, 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int glyph_props, 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookup_props) const 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If using mark filtering sets, the high short of 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * lookup_props has the set index. 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lookup_props & LookupFlag::UseMarkFilteringSet) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gdef.mark_set_covers (lookup_props >> 16, glyph); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The second byte of lookup_props has the meaning 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "ignore marks of attachment type different than 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the attachment type specified." 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lookup_props & LookupFlag::MarkAttachmentType) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_properties (hb_codepoint_t glyph, 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int glyph_props, 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookup_props) const 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Not covered, if, for example, glyph class is ligature and 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * lookup_props includes LookupFlags::IgnoreLigatures 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glyph_props & lookup_props & LookupFlag::IgnoreFlags) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return match_properties_mark (glyph, glyph_props, lookup_props); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) check_glyph_property (hb_glyph_info_t *info, 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int lookup_props) const 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int property; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) property = _hb_glyph_info_get_glyph_props (info); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return match_properties (info->codepoint, property, lookup_props); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inline void _set_glyph_props (hb_codepoint_t glyph_index, 569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int class_guess = 0, 570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool ligature = false) const 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) & 573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE; 574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED; 575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ligature) 576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED; 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (has_glyph_classes)) 578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index)); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (class_guess) 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inline void replace_glyph (hb_codepoint_t glyph_index) const 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _set_glyph_props (glyph_index); 586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->replace_glyph (glyph_index); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inline void replace_glyph_inplace (hb_codepoint_t glyph_index) const 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _set_glyph_props (glyph_index); 591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->cur().codepoint = glyph_index; 592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inline void replace_glyph_with_ligature (hb_codepoint_t glyph_index, 594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int class_guess) const 595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _set_glyph_props (glyph_index, class_guess, true); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->replace_glyph (glyph_index); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inline void output_glyph (hb_codepoint_t glyph_index, 600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int class_guess) const 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _set_glyph_props (glyph_index, class_guess); 603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->output_glyph (glyph_index); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data); 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextClosureFuncs 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) intersects_func_t intersects; 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ContextCollectGlyphsFuncs 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_glyphs_func_t collect; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextApplyFuncs 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_func_t match; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return glyphs->has (value); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool intersects_class (hb_set_t *glyphs, const USHORT &value, const void *data) 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return class_def.intersects_class (glyphs, value); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, const void *data) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (data+coverage).intersects (glyphs); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool intersects_array (hb_closure_context_t *c, 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT values[], 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) intersects_func_t intersects_func, 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *intersects_data) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (!intersects_func (c->glyphs, values[i], intersects_data))) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void collect_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED) 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) glyphs->add (value); 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void collect_class (hb_set_t *glyphs, const USHORT &value, const void *data) 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class_def.add_class (glyphs, value); 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void collect_coverage (hb_set_t *glyphs, const USHORT &value, const void *data) 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (data+coverage).add_coverage (glyphs); 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *glyphs, 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count, 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT values[], 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_glyphs_func_t collect_func, 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void *collect_data) 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_func (glyphs, values[i], collect_data); 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, const void *data HB_UNUSED) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return glyph_id == value; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, const void *data) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return class_def.get_class (glyph_id) == value; 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value, const void *data) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool would_match_input (hb_would_apply_context_t *c, 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, /* Including the first glyph (not matched) */ 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_func_t match_func, 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *match_data) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (count != c->len) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 1; i < count; i++) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (!match_func (c->glyphs[i], input[i - 1], match_data))) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool match_input (hb_apply_context_t *c, 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, /* Including the first glyph (not matched) */ 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_func_t match_func, 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *match_data, 716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int *end_offset, 717f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int match_positions[MAX_CONTEXT_LENGTH], 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool *p_is_mark_ligature = NULL, 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *p_total_component_count = NULL) 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (NULL); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false); 724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 727f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, count - 1); 728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_match_func (match_func, match_data, input); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is perhaps the trickiest part of OpenType... Remarks: 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If all components of the ligature were marks, we call this a mark ligature. 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If there is no GDEF, and the ligature is NOT a mark ligature, we categorize 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it as a ligature glyph. 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - Ligatures cannot be formed across glyphs attached to different components 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother. 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * However, it would be wrong to ligate that SHADDA,FATHA sequence.o 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * There is an exception to this: If a ligature tries ligating with marks that 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * belong to it itself, go ahead, assuming that the font designer knows what 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * they are doing (otherwise it can break Indic stuff when a matra wants to 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ligate with a conjunct...) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur()); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int total_component_count = 0; 752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur()); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 754f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); 755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) match_positions[0] = buffer->idx; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 1; i < count; i++) 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!skippy_iter.next ()) return TRACE_RETURN (false); 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) match_positions[i] = skippy_iter.idx; 763f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 764f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]); 765f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_lig_id && first_lig_comp) { 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If first component was attached to a previous ligature component, 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all subsequent components should be attached to the same ligature 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * component, otherwise we shouldn't ligate them. */ 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If first component was NOT attached to a previous ligature component, 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all subsequent components should also NOT be attached to any ligature 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * component, unless they are attached to the first component itself! */ 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id)) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 781f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]); 782f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]); 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *end_offset = skippy_iter.idx - buffer->idx + 1; 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p_is_mark_ligature) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *p_is_mark_ligature = is_mark_ligature; 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p_total_component_count) 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *p_total_component_count = total_component_count; 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void ligate_input (hb_apply_context_t *c, 796f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int count, /* Including the first glyph */ 797f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ 798f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int match_length, 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_codepoint_t lig_glyph, 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_mark_ligature, 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int total_component_count) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 803f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TRACE_APPLY (NULL); 804f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 806f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 807f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->merge_clusters (buffer->idx, buffer->idx + match_length); 808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If it *is* a mark ligature, we don't allocate a new ligature id, and leave 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the ligature to keep its old ligature id. This will allow it to attach to 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HEH, 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ligature id and component value of 2. Then if SHADDA,FATHA form a ligature 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * later, we don't want them to lose their ligature id/component, otherwise 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * GPOS will fail to correctly position the mark ligature on top of the 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LAM,LAM,HEH ligature. See: 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * https://bugzilla.gnome.org/show_bug.cgi?id=676343 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If a ligature is formed of components that some of which are also ligatures 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * themselves, and those ligature components had marks attached to *their* 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * components, we have to attach the marks to the new ligature component 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * positions! Now *that*'s tricky! And these marks may be following the 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * last component of the whole sequence, so we should loop forward looking 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for them and update them. 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Eg. the sequence is LAM,LAM,SHADDA,FATHA,HEH, and the font first forms a 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * id and component == 1. Now, during 'liga', the LAM and the LAM-HEH ligature 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * form a LAM-LAM-HEH ligature. We need to reassign the SHADDA and FATHA to 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the new ligature with a component value of 2. 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This in fact happened to a font... See: 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * https://bugzilla.gnome.org/show_bug.cgi?id=437633 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; 838f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer); 839f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); 840f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int components_so_far = last_num_components; 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_mark_ligature) 844f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 845f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count); 846f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) 847f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 848f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER); 849f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0); 850f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 851f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 852f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) c->replace_glyph_with_ligature (lig_glyph, klass); 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 1; i < count; i++) 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 856f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) while (buffer->idx < match_positions[i]) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_mark_ligature) { 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int new_lig_comp = components_so_far - last_num_components + 860f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->cur()), 1u), last_num_components); 861f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 863f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->next_glyph (); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 866f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); 867f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) components_so_far += last_num_components; 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Skip the base glyph */ 871f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->idx++; 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_mark_ligature && last_lig_id) { 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Re-adjust components for any marks following. */ 876f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (unsigned int i = buffer->idx; i < buffer->len; i++) { 877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) { 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int new_lig_comp = components_so_far - last_num_components + 879f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->info[i]), 1u), last_num_components); 880f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool match_backtrack (hb_apply_context_t *c, 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT backtrack[], 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_func_t match_func, 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *match_data) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (NULL); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count, true); 896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_match_func (match_func, match_data, backtrack); 897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!skippy_iter.prev ()) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool match_lookahead (hb_apply_context_t *c, 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT lookahead[], 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_func_t match_func, 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *match_data, 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int offset) 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (NULL); 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true); 916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_match_func (match_func, match_data, lookahead); 917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!skippy_iter.next ()) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct LookupRecord 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this)); 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT sequenceIndex; /* Index into current glyph 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sequence--first glyph = 0 */ 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT lookupListIndex; /* Lookup to apply to that 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * position--zero--based */ 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (4); 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename context_t> 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void recurse_lookups (context_t *c, 9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookupCount, 9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < lookupCount; i++) 950f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) c->recurse (lookupRecord[i].lookupListIndex); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool apply_lookup (hb_apply_context_t *c, 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, /* Including the first glyph */ 955f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookupCount, 957f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ 958f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int match_length) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (NULL); 9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_buffer_t *buffer = c->buffer; 963f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int end; 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* All positions are distance from beginning of *output* buffer. 966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Adjust. */ 967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 968f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int bl = buffer->backtrack_len (); 969f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) end = bl + match_length; 970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int delta = bl - buffer->idx; 972f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Convert positions to new indexing. */ 973f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (unsigned int j = 0; j < count; j++) 974f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) match_positions[j] += delta; 975f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 977f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (unsigned int i = 0; i < lookupCount; i++) 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 979f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int idx = lookupRecord[i].sequenceIndex; 980f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (idx >= count) 981f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->move_to (match_positions[idx]); 984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 985f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); 986f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!c->recurse (lookupRecord[i].lookupListIndex)) 987f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 989f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len (); 990f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int delta = new_len - orig_len; 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 992f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!delta) 993f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Recursed lookup changed buffer len. Adjust. */ 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 997f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* end can't go back past the current match position. */ 998f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) end = MAX ((int) match_positions[idx] + 1, int (end) + delta); 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1000f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */ 1001f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1002f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (delta > 0) 1003f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 1004f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (unlikely (delta + count > MAX_CONTEXT_LENGTH)) 1005f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1009f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* NOTE: delta is negative. */ 1010f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delta = MAX (delta, (int) next - (int) count); 1011f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next -= delta; 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1014f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Shift! */ 1015f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memmove (match_positions + next + delta, match_positions + next, 1016f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (count - next) * sizeof (match_positions[0])); 1017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next += delta; 1018f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) count += delta; 1019f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1020f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Fill in new entries. */ 1021f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (unsigned int j = idx + 1; j < next; j++) 1022f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) match_positions[j] = match_positions[j - 1] + 1; 1023f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1024f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* And fixup the rest. */ 1025f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (; next < count; next++) 1026f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) match_positions[next] += delta; 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1029f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer->move_to (end); 1030f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Contextual lookups */ 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextClosureLookupContext 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextClosureFuncs funcs; 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *intersects_data; 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ContextCollectGlyphsLookupContext 10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContextCollectGlyphsFuncs funcs; 10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void *collect_data; 10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextApplyLookupContext 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextApplyFuncs funcs; 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *match_data; 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void context_closure_lookup (hb_closure_context_t *c, 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookupCount, 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord lookupRecord[], 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextClosureLookupContext &lookup_context) 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (intersects_array (c, 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount ? inputCount - 1 : 0, input, 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.intersects, lookup_context.intersects_data)) 10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_lookups (c, 10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord); 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, 10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookupCount, 10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord lookupRecord[], 10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContextCollectGlyphsLookupContext &lookup_context) 10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_array (c, c->input, 10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inputCount ? inputCount - 1 : 0, input, 10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context.funcs.collect, lookup_context.collect_data); 10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_lookups (c, 10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord); 10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookupCount HB_UNUSED, 10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord lookupRecord[] HB_UNUSED, 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextApplyLookupContext &lookup_context) 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return would_match_input (c, 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount, input, 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool context_apply_lookup (hb_apply_context_t *c, 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookupCount, 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord lookupRecord[], 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextApplyLookupContext &lookup_context) 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int match_length = 0; 1103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int match_positions[MAX_CONTEXT_LENGTH]; 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return match_input (c, 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount, input, 1106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data, 1107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &match_length, match_positions) 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && apply_lookup (c, 1109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inputCount, match_positions, 1110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) lookupCount, lookupRecord, 1111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) match_length); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Rule 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0)); 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_closure_lookup (c, 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount, input, 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupCount, lookupRecord, 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context); 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const 11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0)); 11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_collect_glyphs_lookup (c, 11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inputCount, input, 11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord, 11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context); 11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0)); 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (context_would_apply_lookup (c, inputCount, input, lookupCount, lookupRecord, lookup_context)); 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0)); 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (context_apply_lookup (c, inputCount, input, lookupCount, lookupRecord, lookup_context)); 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return inputCount.sanitize (c) 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && lookupCount.sanitize (c) 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && c->check_range (input, 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input[0].static_size * inputCount 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + lookupRecordX[0].static_size * lookupCount); 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT inputCount; /* Total number of glyphs in input 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * glyph sequence--includes the first 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * glyph */ 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT lookupCount; /* Number of LookupRecords */ 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT input[VAR]; /* Array of match inputs--start with 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * second glyph */ 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * design order */ 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY2 (4, input, lookupRecordX); 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct RuleSet 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_rules = rule.len; 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (this+rule[i]).closure (c, lookup_context); 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const 11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int num_rules = rule.len; 11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+rule[i]).collect_glyphs (c, lookup_context); 11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_rules = rule.len; 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((this+rule[i]).would_apply (c, lookup_context)) 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_rules = rule.len; 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((this+rule[i]).apply (c, lookup_context)) 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule.sanitize (c, this)); 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<Rule> 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule; /* Array of Rule tables 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by preference */ 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (2, rule); 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextFormat1 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void closure (hb_closure_context_t *c) const 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Coverage &cov = (this+coverage); 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextClosureLookupContext lookup_context = { 12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {intersects_glyph}, 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = ruleSet.len; 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cov.intersects_coverage (c->glyphs, i)) { 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RuleSet &rule_set = this+ruleSet[i]; 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule_set.closure (c, lookup_context); 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct ContextCollectGlyphsLookupContext lookup_context = { 12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {collect_glyph}, 12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL 12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = ruleSet.len; 12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+ruleSet[i]).collect_glyphs (c, lookup_context); 12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c) const 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])]; 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextApplyLookupContext lookup_context = { 12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_glyph}, 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const Coverage &get_coverage (void) const 12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this+coverage; 12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RuleSet &rule_set = this+ruleSet[index]; 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextApplyLookupContext lookup_context = { 12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_glyph}, 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.apply (c, lookup_context)); 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of table */ 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<RuleSet> 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleSet; /* Array of RuleSet tables 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by Coverage Index */ 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (6, ruleSet); 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextFormat2 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void closure (hb_closure_context_t *c) const 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(this+coverage).intersects (c->glyphs)) 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &class_def = this+classDef; 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextClosureLookupContext lookup_context = { 13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {intersects_class}, 13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &class_def 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = ruleSet.len; 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (class_def.intersects_class (c->glyphs, i)) { 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RuleSet &rule_set = this+ruleSet[i]; 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule_set.closure (c, lookup_context); 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &class_def = this+classDef; 13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct ContextCollectGlyphsLookupContext lookup_context = { 13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {collect_class}, 13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &class_def 13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = ruleSet.len; 13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+ruleSet[i]).collect_glyphs (c, lookup_context); 13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c) const 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &class_def = this+classDef; 13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = class_def.get_class (c->glyphs[0]); 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RuleSet &rule_set = this+ruleSet[index]; 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextApplyLookupContext lookup_context = { 13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_class}, 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &class_def 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const Coverage &get_coverage (void) const 13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this+coverage; 13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &class_def = this+classDef; 13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) index = class_def.get_class (c->buffer->cur().codepoint); 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RuleSet &rule_set = this+ruleSet[index]; 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextApplyLookupContext lookup_context = { 13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_class}, 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &class_def 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.apply (c, lookup_context)); 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this)); 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 2 */ 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of table */ 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ClassDef> 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) classDef; /* Offset to glyph ClassDef table--from 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of table */ 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<RuleSet> 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleSet; /* Array of RuleSet tables 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by class */ 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (8, ruleSet); 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextFormat3 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void closure (hb_closure_context_t *c) const 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(this+coverage[0]).intersects (c->glyphs)) 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount); 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextClosureLookupContext lookup_context = { 14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {intersects_coverage}, 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_closure_lookup (c, 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphCount, (const USHORT *) (coverage + 1), 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupCount, lookupRecord, 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context); 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage[0]).add_coverage (c->input); 14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount); 14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct ContextCollectGlyphsLookupContext lookup_context = { 14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {collect_coverage}, 14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this 14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_collect_glyphs_lookup (c, 14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) glyphCount, (const USHORT *) (coverage + 1), 14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord, 14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context); 14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c) const 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount); 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextApplyLookupContext lookup_context = { 14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_coverage}, 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverage + 1), lookupCount, lookupRecord, lookup_context)); 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const Coverage &get_coverage (void) const 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this+coverage[0]; 14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = (this+coverage[0]).get_coverage (c->buffer->cur().codepoint); 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount); 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextApplyLookupContext lookup_context = { 14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_coverage}, 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (coverage + 1), lookupCount, lookupRecord, lookup_context)); 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!c->check_struct (this)) return TRACE_RETURN (false); 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = glyphCount; 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!c->check_array (coverage, coverage[0].static_size, count)) return TRACE_RETURN (false); 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!coverage[i].sanitize (c, this)) return TRACE_RETURN (false); 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * count); 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 3 */ 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT glyphCount; /* Number of glyphs in the input glyph 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sequence */ 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT lookupCount; /* Number of LookupRecords */ 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage[VAR]; /* Array of offsets to Coverage 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table in glyph sequence order */ 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * design order */ 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY2 (6, coverage, lookupRecordX); 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Context 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 1505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 1509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 1510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 2: return TRACE_RETURN (c->dispatch (u.format2)); 1511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 3: return TRACE_RETURN (c->dispatch (u.format3)); 15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.sanitize (c)); 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: return TRACE_RETURN (u.format3.sanitize (c)); 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextFormat1 format1; 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextFormat2 format2; 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextFormat3 format3; 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Chaining Contextual lookups */ 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainContextClosureLookupContext 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextClosureFuncs funcs; 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *intersects_data[3]; 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ChainContextCollectGlyphsLookupContext 15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContextCollectGlyphsFuncs funcs; 15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void *collect_data[3]; 15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainContextApplyLookupContext 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextApplyFuncs funcs; 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *match_data[3]; 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void chain_context_closure_lookup (hb_closure_context_t *c, 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int backtrackCount, 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT backtrack[], 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookaheadCount, 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT lookahead[], 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookupCount, 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord lookupRecord[], 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextClosureLookupContext &lookup_context) 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (intersects_array (c, 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrackCount, backtrack, 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.intersects, lookup_context.intersects_data[0]) 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && intersects_array (c, 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount ? inputCount - 1 : 0, input, 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.intersects, lookup_context.intersects_data[1]) 1574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) && intersects_array (c, 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookaheadCount, lookahead, 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.intersects, lookup_context.intersects_data[2])) 15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_lookups (c, 15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord); 15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 15802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, 15822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int backtrackCount, 15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT backtrack[], 15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 15862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookaheadCount, 15872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT lookahead[], 15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookupCount, 15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord lookupRecord[], 15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChainContextCollectGlyphsLookupContext &lookup_context) 15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_array (c, c->before, 15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backtrackCount, backtrack, 15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context.funcs.collect, lookup_context.collect_data[0]); 15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_array (c, c->input, 15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inputCount ? inputCount - 1 : 0, input, 15972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context.funcs.collect, lookup_context.collect_data[1]); 15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_array (c, c->after, 15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookaheadCount, lookahead, 16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context.funcs.collect, lookup_context.collect_data[2]); 16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_lookups (c, 16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord); 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c, 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int backtrackCount, 16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT backtrack[] HB_UNUSED, 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookaheadCount, 16112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT lookahead[] HB_UNUSED, 16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookupCount HB_UNUSED, 16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord lookupRecord[] HB_UNUSED, 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextApplyLookupContext &lookup_context) 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (c->zero_context ? !backtrackCount && !lookaheadCount : true) 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && would_match_input (c, 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount, input, 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data[1]); 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool chain_context_apply_lookup (hb_apply_context_t *c, 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int backtrackCount, 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT backtrack[], 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookaheadCount, 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT lookahead[], 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookupCount, 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord lookupRecord[], 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextApplyLookupContext &lookup_context) 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int match_length = 0; 1634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int match_positions[MAX_CONTEXT_LENGTH]; 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return match_input (c, 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount, input, 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data[1], 1638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &match_length, match_positions) 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && match_backtrack (c, 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrackCount, backtrack, 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data[0]) 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && match_lookahead (c, 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookaheadCount, lookahead, 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data[2], 1645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) match_length) 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && apply_lookup (c, 1647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inputCount, match_positions, 1648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) lookupCount, lookupRecord, 1649f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) match_length); 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainRule 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chain_context_closure_lookup (c, 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack.len, backtrack.array, 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.len, input.array, 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead.len, lookahead.array, 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup.len, lookup.array, 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context); 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const 16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 16702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 16712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 16732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chain_context_collect_glyphs_lookup (c, 16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backtrack.len, backtrack.array, 16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) input.len, input.array, 16772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookahead.len, lookahead.array, 16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup.len, lookup.array, 16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context); 16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (chain_context_would_apply_lookup (c, 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack.len, backtrack.array, 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.len, input.array, 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead.len, lookahead.array, lookup.len, 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup.array, lookup_context)); 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (chain_context_apply_lookup (c, 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack.len, backtrack.array, 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.len, input.array, 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead.len, lookahead.array, lookup.len, 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup.array, lookup_context)); 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 17092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!backtrack.sanitize (c)) return TRACE_RETURN (false); 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!input.sanitize (c)) return TRACE_RETURN (false); 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!lookahead.sanitize (c)) return TRACE_RETURN (false); 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (lookup.sanitize (c)); 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<USHORT> 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack; /* Array of backtracking values 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (to be matched before the input 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sequence) */ 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeadlessArrayOf<USHORT> 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputX; /* Array of input values (start with 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * second glyph) */ 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<USHORT> 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookaheadX; /* Array of lookahead values's (to be 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * matched after the input sequence) */ 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<LookupRecord> 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupX; /* Array of LookupRecords--in 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * design order) */ 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_MIN (8); 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainRuleSet 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_rules = rule.len; 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (this+rule[i]).closure (c, lookup_context); 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const 17482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 17492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 17502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int num_rules = rule.len; 17512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 17522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+rule[i]).collect_glyphs (c, lookup_context); 17532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 17542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_rules = rule.len; 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((this+rule[i]).would_apply (c, lookup_context)) 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_rules = rule.len; 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((this+rule[i]).apply (c, lookup_context)) 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 17782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule.sanitize (c, this)); 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<ChainRule> 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule; /* Array of ChainRule tables 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by preference */ 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (2, rule); 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainContextFormat1 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void closure (hb_closure_context_t *c) const 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Coverage &cov = (this+coverage); 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextClosureLookupContext lookup_context = { 17982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {intersects_glyph}, 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {NULL, NULL, NULL} 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = ruleSet.len; 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cov.intersects_coverage (c->glyphs, i)) { 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ChainRuleSet &rule_set = this+ruleSet[i]; 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule_set.closure (c, lookup_context); 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 18112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct ChainContextCollectGlyphsLookupContext lookup_context = { 18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {collect_glyph}, 18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {NULL, NULL, NULL} 18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = ruleSet.len; 18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+ruleSet[i]).collect_glyphs (c, lookup_context); 18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 18242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c) const 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])]; 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextApplyLookupContext lookup_context = { 18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_glyph}, 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {NULL, NULL, NULL} 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const Coverage &get_coverage (void) const 18382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this+coverage; 18402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 18452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ChainRuleSet &rule_set = this+ruleSet[index]; 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextApplyLookupContext lookup_context = { 18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_glyph}, 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {NULL, NULL, NULL} 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.apply (c, lookup_context)); 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 18572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of table */ 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<ChainRuleSet> 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleSet; /* Array of ChainRuleSet tables 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by Coverage Index */ 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (6, ruleSet); 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainContextFormat2 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void closure (hb_closure_context_t *c) const 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(this+coverage).intersects (c->glyphs)) 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &backtrack_class_def = this+backtrackClassDef; 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &input_class_def = this+inputClassDef; 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &lookahead_class_def = this+lookaheadClassDef; 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextClosureLookupContext lookup_context = { 18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {intersects_class}, 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {&backtrack_class_def, 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &input_class_def, 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &lookahead_class_def} 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = ruleSet.len; 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (input_class_def.intersects_class (c->glyphs, i)) { 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ChainRuleSet &rule_set = this+ruleSet[i]; 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule_set.closure (c, lookup_context); 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 19032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &backtrack_class_def = this+backtrackClassDef; 19062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &input_class_def = this+inputClassDef; 19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &lookahead_class_def = this+lookaheadClassDef; 19082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct ChainContextCollectGlyphsLookupContext lookup_context = { 19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {collect_class}, 19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {&backtrack_class_def, 19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &input_class_def, 19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &lookahead_class_def} 19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 19152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = ruleSet.len; 19172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 19182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+ruleSet[i]).collect_glyphs (c, lookup_context); 19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 19202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c) const 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &backtrack_class_def = this+backtrackClassDef; 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &input_class_def = this+inputClassDef; 19272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &lookahead_class_def = this+lookaheadClassDef; 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = input_class_def.get_class (c->glyphs[0]); 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ChainRuleSet &rule_set = this+ruleSet[index]; 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextApplyLookupContext lookup_context = { 19322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_class}, 19332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {&backtrack_class_def, 19342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &input_class_def, 19352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &lookahead_class_def} 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const Coverage &get_coverage (void) const 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this+coverage; 19432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 19442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 19462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 19472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 19482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &backtrack_class_def = this+backtrackClassDef; 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &input_class_def = this+inputClassDef; 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &lookahead_class_def = this+lookaheadClassDef; 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) index = input_class_def.get_class (c->buffer->cur().codepoint); 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ChainRuleSet &rule_set = this+ruleSet[index]; 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextApplyLookupContext lookup_context = { 19582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_class}, 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {&backtrack_class_def, 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &input_class_def, 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &lookahead_class_def} 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.apply (c, lookup_context)); 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 19672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) && 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) && 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleSet.sanitize (c, this)); 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 2 */ 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of table */ 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ClassDef> 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrackClassDef; /* Offset to glyph ClassDef table 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * containing backtrack sequence 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * data--from beginning of table */ 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ClassDef> 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputClassDef; /* Offset to glyph ClassDef 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table containing input sequence 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * data--from beginning of table */ 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ClassDef> 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookaheadClassDef; /* Offset to glyph ClassDef table 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * containing lookahead sequence 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * data--from beginning of table */ 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<ChainRuleSet> 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleSet; /* Array of ChainRuleSet tables 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by class */ 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (12, ruleSet); 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainContextFormat3 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 19992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void closure (hb_closure_context_t *c) const 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(this+input[0]).intersects (c->glyphs)) 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextClosureLookupContext lookup_context = { 20102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {intersects_coverage}, 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {this, this, this} 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chain_context_closure_lookup (c, 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack.len, (const USHORT *) backtrack.array, 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.len, (const USHORT *) input.array + 1, 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead.len, (const USHORT *) lookahead.array, 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup.len, lookup.array, 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context); 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+input[0]).add_coverage (c->input); 20272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 20292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 20302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct ChainContextCollectGlyphsLookupContext lookup_context = { 20312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {collect_coverage}, 20322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {this, this, this} 20332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 20342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chain_context_collect_glyphs_lookup (c, 20352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backtrack.len, (const USHORT *) backtrack.array, 20362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) input.len, (const USHORT *) input.array + 1, 20372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookahead.len, (const USHORT *) lookahead.array, 20382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup.len, lookup.array, 20392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context); 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c) const 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextApplyLookupContext lookup_context = { 20502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_coverage}, 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {this, this, this} 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (chain_context_would_apply_lookup (c, 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack.len, (const USHORT *) backtrack.array, 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.len, (const USHORT *) input.array + 1, 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead.len, (const USHORT *) lookahead.array, 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup.len, lookup.array, lookup_context)); 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const Coverage &get_coverage (void) const 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this+input[0]; 20642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 20672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 20682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 20692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextApplyLookupContext lookup_context = { 20772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_coverage}, 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {this, this, this} 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (chain_context_apply_lookup (c, 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack.len, (const USHORT *) backtrack.array, 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.len, (const USHORT *) input.array + 1, 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead.len, (const USHORT *) lookahead.array, 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup.len, lookup.array, lookup_context)); 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 20882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false); 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!input.sanitize (c, this)) return TRACE_RETURN (false); 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false); 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (lookup.sanitize (c)); 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 3 */ 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<Coverage> 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack; /* Array of coverage tables 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in backtracking sequence, in glyph 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sequence order */ 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<Coverage> 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputX ; /* Array of coverage 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tables in input sequence, in glyph 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sequence order */ 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<Coverage> 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookaheadX; /* Array of coverage tables 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in lookahead sequence, in glyph 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sequence order */ 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<LookupRecord> 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupX; /* Array of LookupRecords--in 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * design order) */ 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_MIN (10); 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainContext 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 21212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 2122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 2126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 2127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 2: return TRACE_RETURN (c->dispatch (u.format2)); 2128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 3: return TRACE_RETURN (c->dispatch (u.format3)); 21292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 21342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.sanitize (c)); 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: return TRACE_RETURN (u.format3.sanitize (c)); 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextFormat1 format1; 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextFormat2 format2; 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextFormat3 format3; 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ExtensionFormat1 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_type (void) const { return extensionLookupType; } 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_offset (void) const { return extensionOffset; } 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 21602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this)); 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier. Set to 1. */ 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT extensionLookupType; /* Lookup type of subtable referenced 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * by ExtensionOffset (i.e. the 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extension subtable). */ 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG extensionOffset; /* Offset to the extension subtable, 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of lookup type subtable. */ 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (8); 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename T> 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Extension 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_type (void) const 21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return u.format1.get_type (); 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return 0; 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_offset (void) const 21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return u.format1.get_offset (); 21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return 0; 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename X> 21942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const X& get_subtable (void) const 21952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 21962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int offset = get_offset (); 21972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (!offset)) return Null(typename T::LookupSubTable); 21982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return StructAtOffset<typename T::LookupSubTable> (this, offset); 21992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 22002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 2202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 22032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 2204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()); 22052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 22062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool sanitize_self (hb_sanitize_context_t *c) { 22082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 22172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 22182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!sanitize_self (c)) return TRACE_RETURN (false); 22192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int offset = get_offset (); 22202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (!offset)) return TRACE_RETURN (true); 22212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (StructAtOffset<typename T::LookupSubTable> (this, offset).sanitize (c, get_type ())); 22222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 22232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionFormat1 format1; 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * GSUB/GPOS Common 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GSUBGPOS 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const hb_tag_t GSUBTag = HB_OT_TAG_GSUB; 22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const hb_tag_t GPOSTag = HB_OT_TAG_GPOS; 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_script_count (void) const 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+scriptList).len; } 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Tag& get_script_tag (unsigned int i) const 22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+scriptList).get_tag (i); } 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_script_tags (unsigned int start_offset, 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *script_count /* IN/OUT */, 22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_tag_t *script_tags /* OUT */) const 22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+scriptList).get_tags (start_offset, script_count, script_tags); } 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Script& get_script (unsigned int i) const 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+scriptList)[i]; } 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool find_script_index (hb_tag_t tag, unsigned int *index) const 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+scriptList).find_index (tag, index); } 22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_feature_count (void) const 22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+featureList).len; } 22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Tag& get_feature_tag (unsigned int i) const 22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+featureList).get_tag (i); } 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_feature_tags (unsigned int start_offset, 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *feature_count /* IN/OUT */, 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_tag_t *feature_tags /* OUT */) const 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+featureList).get_tags (start_offset, feature_count, feature_tags); } 22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Feature& get_feature (unsigned int i) const 22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+featureList)[i]; } 22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const 22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+featureList).find_index (tag, index); } 22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_lookup_count (void) const 22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+lookupList).len; } 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Lookup& get_lookup (unsigned int i) const 22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+lookupList)[i]; } 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 22732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scriptList.sanitize (c, this) && 22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) featureList.sanitize (c, this) && 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupList.sanitize (c, this)); 22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixedVersion version; /* Version of the GSUB/GPOS table--initially set 22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to 0x00010000 */ 22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ScriptList> 22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scriptList; /* ScriptList table */ 22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<FeatureList> 22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) featureList; /* FeatureList table */ 22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<LookupList> 22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupList; /* LookupList table */ 22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (10); 22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} /* namespace OT */ 22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ 2298