hb-ot-layout-gsubgpos-private.hh revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_DEBUG_CLOSURE 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_DEBUG_CLOSURE (HB_DEBUG+0) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_CLOSURE(this) \ 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \ 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ""); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_closure_context_t 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const char *get_name (void) { return "CLOSURE"; } 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef hb_void_t return_t; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename T> 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; } 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static return_t default_return_value (void) { return HB_VOID; } 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return_t recurse (unsigned int lookup_index) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (nesting_level_left == 0 || !recurse_func)) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return default_return_value (); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left--; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func (this, lookup_index); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left++; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return HB_VOID; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_face_t *face; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_set_t *glyphs; 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func_t recurse_func; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int nesting_level_left; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int debug_depth; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_closure_context_t (hb_face_t *face_, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_set_t *glyphs_, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) face (face_), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphs (glyphs_), 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func (NULL), 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nesting_level_left (nesting_level_left_), 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_depth (0) {} 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_recurse_func (recurse_func_t func) { recurse_func = func; } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_DEBUG_WOULD_APPLY 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_WOULD_APPLY(this) \ 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \ 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "%d glyphs", c->len); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_would_apply_context_t 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const char *get_name (void) { return "WOULD_APPLY"; } 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef bool return_t; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename T> 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline return_t dispatch (const T &obj) { return obj.would_apply (this); } 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static return_t default_return_value (void) { return false; } 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool stop_sublookup_iteration (return_t r) const { return r; } 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_face_t *face; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_codepoint_t *glyphs; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool zero_context; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int debug_depth; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_would_apply_context_t (hb_face_t *face_, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_codepoint_t *glyphs_, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len_, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool zero_context_) : 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) face (face_), 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphs (glyphs_), 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len (len_), 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zero_context (zero_context_), 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_depth (0) {} 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef HB_DEBUG_COLLECT_GLYPHS 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define HB_DEBUG_COLLECT_GLYPHS (HB_DEBUG+0) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_COLLECT_GLYPHS(this) \ 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \ 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ""); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct hb_collect_glyphs_context_t 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const char *get_name (void) { return "COLLECT_GLYPHS"; } 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef hb_void_t return_t; 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename T> 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; } 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static return_t default_return_value (void) { return HB_VOID; } 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return_t recurse (unsigned int lookup_index) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (nesting_level_left == 0 || !recurse_func)) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return default_return_value (); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Note that GPOS sets recurse_func to NULL already, so it doesn't get 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * past the previous check. For GSUB, we only want to collect the output 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * glyphs in the recursion. If output is not requested, we can go home now. */ 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (output == hb_set_get_empty ()) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return HB_VOID; 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *old_before = before; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *old_input = input; 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *old_after = after; 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) before = input = after = hb_set_get_empty (); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left--; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func (this, lookup_index); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left++; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) before = old_before; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) input = old_input; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) after = old_after; 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return HB_VOID; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_face_t *face; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *before; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *input; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *after; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *output; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func_t recurse_func; 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int nesting_level_left; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int debug_depth; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_collect_glyphs_context_t (hb_face_t *face_, 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *glyphs_before, /* OUT. May be NULL */ 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *glyphs_input, /* OUT. May be NULL */ 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *glyphs_after, /* OUT. May be NULL */ 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *glyphs_output, /* OUT. May be NULL */ 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) face (face_), 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) before (glyphs_before ? glyphs_before : hb_set_get_empty ()), 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) input (glyphs_input ? glyphs_input : hb_set_get_empty ()), 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) after (glyphs_after ? glyphs_after : hb_set_get_empty ()), 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output (glyphs_output ? glyphs_output : hb_set_get_empty ()), 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func (NULL), 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left (nesting_level_left_), 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_depth (0) {} 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_recurse_func (recurse_func_t func) { recurse_func = func; } 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct hb_get_coverage_context_t 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const char *get_name (void) { return "GET_COVERAGE"; } 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const unsigned int max_debug_depth = 0; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef const Coverage &return_t; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename T> 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline return_t dispatch (const T &obj) { return obj.get_coverage (); } 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static return_t default_return_value (void) { return Null(Coverage); } 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_get_coverage_context_t (void) : 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_depth (0) {} 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int debug_depth; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_DEBUG_APPLY 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_DEBUG_APPLY (HB_DEBUG+0) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_APPLY(this) \ 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \ 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_apply_context_t 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const char *get_name (void) { return "APPLY"; } 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const unsigned int max_debug_depth = HB_DEBUG_APPLY; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef bool return_t; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename T> 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline return_t dispatch (const T &obj) { return obj.apply (this); } 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static return_t default_return_value (void) { return false; } 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool stop_sublookup_iteration (return_t r) const { return r; } 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return_t recurse (unsigned int lookup_index) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (nesting_level_left == 0 || !recurse_func)) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return default_return_value (); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left--; 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ret = recurse_func (this, lookup_index); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) nesting_level_left++; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ret; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int table_index; /* GSUB/GPOS */ 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_font_t *font; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_face_t *face; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_buffer_t *buffer; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_direction_t direction; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_mask_t lookup_mask; 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool auto_zwj; 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func_t recurse_func; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int nesting_level_left; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookup_props; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GDEF &gdef; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_glyph_classes; 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int debug_depth; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_apply_context_t (unsigned int table_index_, 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_font_t *font_, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_buffer_t *buffer_, 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_mask_t lookup_mask_, 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool auto_zwj_) : 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) table_index (table_index_), 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) font (font_), face (font->face), buffer (buffer_), 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) direction (buffer_->props.direction), 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_mask (lookup_mask_), 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auto_zwj (auto_zwj_), 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_func (NULL), 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nesting_level_left (MAX_NESTING_LEVEL), 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) lookup_props (0), 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdef (*hb_ot_layout_from_face (face)->gdef), 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_glyph_classes (gdef.has_glyph_classes ()), 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_depth (0) {} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); } 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct matcher_t 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline matcher_t (void) : 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) lookup_props (0), 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ignore_zwnj (false), 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ignore_zwj (false), 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mask (-1), 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */ 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) syllable arg1(0), 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#undef arg1 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_func (NULL), 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_data (NULL) {}; 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data); 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_mask (hb_mask_t mask_) { mask = mask_; } 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_syllable (uint8_t syllable_) { syllable = syllable_; } 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_match_func (match_func_t match_func_, 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const void *match_data_) 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { match_func = match_func_; match_data = match_data_; } 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) enum may_match_t { 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MATCH_NO, 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MATCH_YES, 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MATCH_MAYBE 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline may_match_t may_match (const hb_glyph_info_t &info, 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const USHORT *glyph_data) const 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!(info.mask & mask) || 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (syllable && syllable != info.syllable ())) 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return MATCH_NO; 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (match_func) 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO; 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return MATCH_MAYBE; 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) enum may_skip_t { 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SKIP_NO, 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SKIP_YES, 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SKIP_MAYBE 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline may_skip_t 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) may_skip (const hb_apply_context_t *c, 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const hb_glyph_info_t &info) const 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int property; 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) property = info.glyph_props(); 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!c->match_properties (info.codepoint, property, lookup_props)) 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SKIP_YES; 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !is_a_ligature (info))) 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SKIP_MAYBE; 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SKIP_NO; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int lookup_props; 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool ignore_zwnj; 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool ignore_zwj; 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_mask_t mask; 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint8_t syllable; 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_func_t match_func; 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const void *match_data; 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct skipping_forward_iterator_t 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline skipping_forward_iterator_t (hb_apply_context_t *c_, 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int start_index_, 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int num_items_, 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool context_match = false) : 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) idx (start_index_), 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) c (c_), 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_glyph_data (NULL), 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) num_items (num_items_), 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) end (c->buffer->len) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_lookup_props (c->lookup_props); 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_ignore_zwnj (context_match || c->table_index == 1); 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!context_match) 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_mask (c->lookup_mask); 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); } 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); } 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_match_func (matcher_t::match_func_t match_func, 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const void *match_data, 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const USHORT glyph_data[]) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_match_func (match_func, match_data); 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_glyph_data = glyph_data; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline bool has_no_chance (void) const { return unlikely (num_items && idx + num_items >= end); } 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void reject (void) { num_items++; match_glyph_data--; } 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline bool next (void) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert (num_items > 0); 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (!has_no_chance ()) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idx++; 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const hb_glyph_info_t &info = c->buffer->info[idx]; 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher_t::may_skip_t skip = matcher.may_skip (c, info); 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (unlikely (skip == matcher_t::SKIP_YES)) 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (match == matcher_t::MATCH_YES || 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (match == matcher_t::MATCH_MAYBE && 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skip == matcher_t::SKIP_NO)) 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) num_items--; 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_glyph_data++; 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (skip == matcher_t::SKIP_NO) 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int idx; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_apply_context_t *c; 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher_t matcher; 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const USHORT *match_glyph_data; 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_items; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int end; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct skipping_backward_iterator_t 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline skipping_backward_iterator_t (hb_apply_context_t *c_, 447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int start_index_, 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int num_items_, 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool context_match = false) : 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) idx (start_index_), 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) c (c_), 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_glyph_data (NULL), 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) num_items (num_items_) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_lookup_props (c->lookup_props); 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_ignore_zwnj (context_match || c->table_index == 1); 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!context_match) 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_mask (c->lookup_mask); 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); } 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); } 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void set_match_func (matcher_t::match_func_t match_func, 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const void *match_data, 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const USHORT glyph_data[]) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher.set_match_func (match_func, match_data); 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_glyph_data = glyph_data; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline bool has_no_chance (void) const { return unlikely (idx < num_items); } 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline void reject (void) { num_items++; } 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline bool prev (void) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert (num_items > 0); 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (!has_no_chance ()) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idx--; 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const hb_glyph_info_t &info = c->buffer->out_info[idx]; 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher_t::may_skip_t skip = matcher.may_skip (c, info); 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (unlikely (skip == matcher_t::SKIP_YES)) 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (match == matcher_t::MATCH_YES || 491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (match == matcher_t::MATCH_MAYBE && 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skip == matcher_t::SKIP_NO)) 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) num_items--; 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_glyph_data++; 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (skip == matcher_t::SKIP_NO) 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int idx; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_apply_context_t *c; 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matcher_t matcher; 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const USHORT *match_glyph_data; 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_items; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_properties_mark (hb_codepoint_t glyph, 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int glyph_props, 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookup_props) const 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If using mark filtering sets, the high short of 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * lookup_props has the set index. 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lookup_props & LookupFlag::UseMarkFilteringSet) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gdef.mark_set_covers (lookup_props >> 16, glyph); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The second byte of lookup_props has the meaning 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "ignore marks of attachment type different than 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the attachment type specified." 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lookup_props & LookupFlag::MarkAttachmentType) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_properties (hb_codepoint_t glyph, 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int glyph_props, 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookup_props) const 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Not covered, if, for example, glyph class is ligature and 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * lookup_props includes LookupFlags::IgnoreLigatures 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glyph_props & lookup_props & LookupFlag::IgnoreFlags) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return match_properties_mark (glyph, glyph_props, lookup_props); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) check_glyph_property (hb_glyph_info_t *info, 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int lookup_props) const 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int property; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) property = info->glyph_props(); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return match_properties (info->codepoint, property, lookup_props); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (has_glyph_classes)) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (class_guess) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->cur().glyph_props() = class_guess; 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void output_glyph (hb_codepoint_t glyph_index, 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int class_guess = 0) const 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_class (glyph_index, class_guess); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->output_glyph (glyph_index); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void replace_glyph (hb_codepoint_t glyph_index, 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int class_guess = 0) const 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_class (glyph_index, class_guess); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->replace_glyph (glyph_index); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void replace_glyph_inplace (hb_codepoint_t glyph_index, 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int class_guess = 0) const 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_class (glyph_index, class_guess); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->cur().codepoint = glyph_index; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data); 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextClosureFuncs 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) intersects_func_t intersects; 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ContextCollectGlyphsFuncs 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_glyphs_func_t collect; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextApplyFuncs 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_func_t match; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return glyphs->has (value); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool intersects_class (hb_set_t *glyphs, const USHORT &value, const void *data) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return class_def.intersects_class (glyphs, value); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, const void *data) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (data+coverage).intersects (glyphs); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool intersects_array (hb_closure_context_t *c, 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT values[], 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) intersects_func_t intersects_func, 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *intersects_data) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (!intersects_func (c->glyphs, values[i], intersects_data))) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void collect_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED) 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) glyphs->add (value); 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void collect_class (hb_set_t *glyphs, const USHORT &value, const void *data) 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class_def.add_class (glyphs, value); 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void collect_coverage (hb_set_t *glyphs, const USHORT &value, const void *data) 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (data+coverage).add_coverage (glyphs); 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_t *glyphs, 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count, 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT values[], 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_glyphs_func_t collect_func, 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void *collect_data) 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_func (glyphs, values[i], collect_data); 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, const void *data HB_UNUSED) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return glyph_id == value; 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, const void *data) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return class_def.get_class (glyph_id) == value; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value, const void *data) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool would_match_input (hb_would_apply_context_t *c, 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, /* Including the first glyph (not matched) */ 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_func_t match_func, 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *match_data) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (count != c->len) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 1; i < count; i++) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (!match_func (c->glyphs[i], input[i - 1], match_data))) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool match_input (hb_apply_context_t *c, 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, /* Including the first glyph (not matched) */ 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_func_t match_func, 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *match_data, 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *end_offset = NULL, 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool *p_is_mark_ligature = NULL, 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *p_total_component_count = NULL) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (NULL); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1); 707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_match_func (match_func, match_data, input); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is perhaps the trickiest part of OpenType... Remarks: 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If all components of the ligature were marks, we call this a mark ligature. 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If there is no GDEF, and the ligature is NOT a mark ligature, we categorize 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it as a ligature glyph. 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - Ligatures cannot be formed across glyphs attached to different components 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother. 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * However, it would be wrong to ligate that SHADDA,FATHA sequence.o 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * There is an exception to this: If a ligature tries ligating with marks that 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * belong to it itself, go ahead, assuming that the font designer knows what 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * they are doing (otherwise it can break Indic stuff when a matra wants to 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ligate with a conjunct...) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_mark_ligature = !!(c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int total_component_count = 0; 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_component_count += get_lig_num_comps (c->buffer->cur()); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int first_lig_id = get_lig_id (c->buffer->cur()); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int first_lig_comp = get_lig_comp (c->buffer->cur()); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 1; i < count; i++) 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!skippy_iter.next ()) return TRACE_RETURN (false); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_lig_id && first_lig_comp) { 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If first component was attached to a previous ligature component, 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all subsequent components should be attached to the same ligature 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * component, otherwise we shouldn't ligate them. */ 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp) 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If first component was NOT attached to a previous ligature component, 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all subsequent components should also NOT be attached to any ligature 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * component, unless they are attached to the first component itself! */ 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id)) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) is_mark_ligature = is_mark_ligature && (c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK); 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx]); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (end_offset) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *end_offset = skippy_iter.idx - c->buffer->idx + 1; 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p_is_mark_ligature) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *p_is_mark_ligature = is_mark_ligature; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p_total_component_count) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *p_total_component_count = total_component_count; 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void ligate_input (hb_apply_context_t *c, 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, /* Including the first glyph (not matched) */ 774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_func_t match_func, 776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const void *match_data, 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_codepoint_t lig_glyph, 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_mark_ligature, 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int total_component_count) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1); 782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_match_func (match_func, match_data, input); 783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (skippy_iter.has_no_chance ()) return; 784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If it *is* a mark ligature, we don't allocate a new ligature id, and leave 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the ligature to keep its old ligature id. This will allow it to attach to 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HEH, 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ligature id and component value of 2. Then if SHADDA,FATHA form a ligature 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * later, we don't want them to lose their ligature id/component, otherwise 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * GPOS will fail to correctly position the mark ligature on top of the 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * LAM,LAM,HEH ligature. See: 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * https://bugzilla.gnome.org/show_bug.cgi?id=676343 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If a ligature is formed of components that some of which are also ligatures 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * themselves, and those ligature components had marks attached to *their* 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * components, we have to attach the marks to the new ligature component 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * positions! Now *that*'s tricky! And these marks may be following the 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * last component of the whole sequence, so we should loop forward looking 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for them and update them. 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Eg. the sequence is LAM,LAM,SHADDA,FATHA,HEH, and the font first forms a 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * id and component == 1. Now, during 'liga', the LAM and the LAM-HEH ligature 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * form a LAM-LAM-HEH ligature. We need to reassign the SHADDA and FATHA to 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the new ligature with a component value of 2. 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This in fact happened to a font... See: 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * https://bugzilla.gnome.org/show_bug.cgi?id=437633 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lig_id = is_mark_ligature ? 0 : allocate_lig_id (c->buffer); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int last_lig_id = get_lig_id (c->buffer->cur()); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int last_num_components = get_lig_num_comps (c->buffer->cur()); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int components_so_far = last_num_components; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_mark_ligature) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->replace_glyph (lig_glyph, klass); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 1; i < count; i++) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!skippy_iter.next ()) return; 826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (c->buffer->idx < skippy_iter.idx) 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_mark_ligature) { 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int new_lig_comp = components_so_far - last_num_components + 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MIN (MAX (get_lig_comp (c->buffer->cur()), 1u), last_num_components); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_lig_props_for_mark (c->buffer->cur(), lig_id, new_lig_comp); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->buffer->next_glyph (); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_lig_id = get_lig_id (c->buffer->cur()); 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_num_components = get_lig_num_comps (c->buffer->cur()); 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) components_so_far += last_num_components; 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Skip the base glyph */ 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->buffer->idx++; 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_mark_ligature && last_lig_id) { 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Re-adjust components for any marks following. */ 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = c->buffer->idx; i < c->buffer->len; i++) { 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_lig_id == get_lig_id (c->buffer->info[i])) { 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int new_lig_comp = components_so_far - last_num_components + 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MIN (MAX (get_lig_comp (c->buffer->info[i]), 1u), last_num_components); 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_lig_props_for_mark (c->buffer->info[i], lig_id, new_lig_comp); 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool match_backtrack (hb_apply_context_t *c, 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT backtrack[], 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_func_t match_func, 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *match_data) 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (NULL); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count, true); 867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_match_func (match_func, match_data, backtrack); 868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!skippy_iter.prev ()) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool match_lookahead (hb_apply_context_t *c, 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT lookahead[], 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_func_t match_func, 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *match_data, 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int offset) 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (NULL); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true); 887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_match_func (match_func, match_data, lookahead); 888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!skippy_iter.next ()) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct LookupRecord 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this)); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT sequenceIndex; /* Index into current glyph 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sequence--first glyph = 0 */ 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT lookupListIndex; /* Lookup to apply to that 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * position--zero--based */ 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (4); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename context_t> 9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void recurse_lookups (context_t *c, 9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookupCount, 9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < lookupCount; i++) 9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) c->recurse (lookupRecord->lookupListIndex); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool apply_lookup (hb_apply_context_t *c, 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count, /* Including the first glyph */ 926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) match_func_t match_func, 928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const void *match_data, 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookupCount, 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */) 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (NULL); 9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int end = c->buffer->len; 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (count == 0 || c->buffer->idx + count > end)) 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO We don't support lookupRecord arrays that are not increasing: 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Should be easy for in_place ones at least. */ 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Note: If sublookup is reverse, it will underflow after the first loop 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and we jump out of it. Not entirely disastrous. So we don't check 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for reverse lookup here. 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1); 947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter.set_match_func (match_func, match_data, input); 948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint8_t syllable = c->buffer->cur().syllable(); 949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int i = 0; 951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (lookupCount && 0 == lookupRecord->sequenceIndex) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned int old_pos = c->buffer->idx; 954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Apply a lookup */ 956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool done = c->recurse (lookupRecord->lookupListIndex); 957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) lookupRecord++; 959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) lookupCount--; 960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Err, this is wrong if the lookup jumped over some glyphs */ 961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i += c->buffer->idx - old_pos; 962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!done) 964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) goto not_applied; 965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Reinitialize iterator. */ 968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i); 969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) tmp.set_syllable (syllable); 970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter = tmp; 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) not_applied: 976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* No lookup applied for this index */ 977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) c->buffer->next_glyph (); 978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i++; 979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (i < count) 981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!skippy_iter.next ()) return TRACE_RETURN (true); 983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (c->buffer->idx < skippy_iter.idx) 984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) c->buffer->next_glyph (); 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lookupCount && i == lookupRecord->sequenceIndex) 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int old_pos = c->buffer->idx; 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Apply a lookup */ 9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool done = c->recurse (lookupRecord->lookupListIndex); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupRecord++; 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupCount--; 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Err, this is wrong if the lookup jumped over some glyphs */ 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i += c->buffer->idx - old_pos; 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!done) 999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) goto not_applied2; 1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 1001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Reinitialize iterator. */ 1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i); 1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) tmp.set_syllable (syllable); 1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) skippy_iter = tmp; 1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) not_applied2: 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No lookup applied for this index */ 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c->buffer->next_glyph (); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i++; 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Contextual lookups */ 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextClosureLookupContext 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextClosureFuncs funcs; 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *intersects_data; 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ContextCollectGlyphsLookupContext 10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContextCollectGlyphsFuncs funcs; 10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void *collect_data; 10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextApplyLookupContext 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextApplyFuncs funcs; 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *match_data; 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void context_closure_lookup (hb_closure_context_t *c, 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookupCount, 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord lookupRecord[], 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextClosureLookupContext &lookup_context) 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (intersects_array (c, 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount ? inputCount - 1 : 0, input, 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.intersects, lookup_context.intersects_data)) 10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_lookups (c, 10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, 10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookupCount, 10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord lookupRecord[], 10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContextCollectGlyphsLookupContext &lookup_context) 10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_array (c, c->input, 10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inputCount ? inputCount - 1 : 0, input, 10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context.funcs.collect, lookup_context.collect_data); 10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_lookups (c, 10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord); 10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookupCount HB_UNUSED, 10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord lookupRecord[] HB_UNUSED, 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextApplyLookupContext &lookup_context) 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return would_match_input (c, 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount, input, 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data); 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool context_apply_lookup (hb_apply_context_t *c, 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookupCount, 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord lookupRecord[], 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextApplyLookupContext &lookup_context) 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return match_input (c, 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount, input, 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data) 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && apply_lookup (c, 1092c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inputCount, input, 1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data, 10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord); 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Rule 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0)); 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_closure_lookup (c, 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount, input, 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupCount, lookupRecord, 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context); 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const 11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0)); 11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_collect_glyphs_lookup (c, 11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inputCount, input, 11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord, 11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context); 11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0)); 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (context_would_apply_lookup (c, inputCount, input, lookupCount, lookupRecord, lookup_context)); 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0)); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (context_apply_lookup (c, inputCount, input, lookupCount, lookupRecord, lookup_context)); 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return inputCount.sanitize (c) 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && lookupCount.sanitize (c) 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && c->check_range (input, 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input[0].static_size * inputCount 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + lookupRecordX[0].static_size * lookupCount); 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT inputCount; /* Total number of glyphs in input 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * glyph sequence--includes the first 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * glyph */ 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT lookupCount; /* Number of LookupRecords */ 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT input[VAR]; /* Array of match inputs--start with 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * second glyph */ 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * design order */ 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY2 (4, input, lookupRecordX); 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct RuleSet 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_rules = rule.len; 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (this+rule[i]).closure (c, lookup_context); 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const 11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int num_rules = rule.len; 11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+rule[i]).collect_glyphs (c, lookup_context); 11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_rules = rule.len; 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((this+rule[i]).would_apply (c, lookup_context)) 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_rules = rule.len; 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((this+rule[i]).apply (c, lookup_context)) 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule.sanitize (c, this)); 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<Rule> 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule; /* Array of Rule tables 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by preference */ 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (2, rule); 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextFormat1 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void closure (hb_closure_context_t *c) const 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Coverage &cov = (this+coverage); 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextClosureLookupContext lookup_context = { 12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {intersects_glyph}, 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = ruleSet.len; 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cov.intersects_coverage (c->glyphs, i)) { 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RuleSet &rule_set = this+ruleSet[i]; 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule_set.closure (c, lookup_context); 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct ContextCollectGlyphsLookupContext lookup_context = { 12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {collect_glyph}, 12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL 12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = ruleSet.len; 12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+ruleSet[i]).collect_glyphs (c, lookup_context); 12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c) const 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])]; 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextApplyLookupContext lookup_context = { 12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_glyph}, 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const Coverage &get_coverage (void) const 12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this+coverage; 12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RuleSet &rule_set = this+ruleSet[index]; 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextApplyLookupContext lookup_context = { 12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_glyph}, 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.apply (c, lookup_context)); 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of table */ 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<RuleSet> 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleSet; /* Array of RuleSet tables 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by Coverage Index */ 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (6, ruleSet); 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextFormat2 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void closure (hb_closure_context_t *c) const 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(this+coverage).intersects (c->glyphs)) 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &class_def = this+classDef; 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextClosureLookupContext lookup_context = { 13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {intersects_class}, 13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &class_def 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = ruleSet.len; 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (class_def.intersects_class (c->glyphs, i)) { 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RuleSet &rule_set = this+ruleSet[i]; 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule_set.closure (c, lookup_context); 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &class_def = this+classDef; 13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct ContextCollectGlyphsLookupContext lookup_context = { 13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {collect_class}, 13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &class_def 13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = ruleSet.len; 13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+ruleSet[i]).collect_glyphs (c, lookup_context); 13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c) const 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &class_def = this+classDef; 13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = class_def.get_class (c->glyphs[0]); 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RuleSet &rule_set = this+ruleSet[index]; 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextApplyLookupContext lookup_context = { 13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_class}, 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &class_def 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const Coverage &get_coverage (void) const 13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this+coverage; 13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &class_def = this+classDef; 13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) index = class_def.get_class (c->buffer->cur().codepoint); 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RuleSet &rule_set = this+ruleSet[index]; 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextApplyLookupContext lookup_context = { 13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_class}, 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &class_def 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.apply (c, lookup_context)); 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this)); 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 2 */ 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of table */ 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ClassDef> 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) classDef; /* Offset to glyph ClassDef table--from 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of table */ 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<RuleSet> 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleSet; /* Array of RuleSet tables 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by class */ 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (8, ruleSet); 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ContextFormat3 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void closure (hb_closure_context_t *c) const 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(this+coverage[0]).intersects (c->glyphs)) 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount); 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextClosureLookupContext lookup_context = { 14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {intersects_coverage}, 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_closure_lookup (c, 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphCount, (const USHORT *) (coverage + 1), 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupCount, lookupRecord, 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context); 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage[0]).add_coverage (c->input); 14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount); 14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct ContextCollectGlyphsLookupContext lookup_context = { 14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {collect_coverage}, 14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this 14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_collect_glyphs_lookup (c, 14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) glyphCount, (const USHORT *) (coverage + 1), 14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord, 14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context); 14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c) const 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount); 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextApplyLookupContext lookup_context = { 14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_coverage}, 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverage + 1), lookupCount, lookupRecord, lookup_context)); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const Coverage &get_coverage (void) const 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this+coverage[0]; 14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = (this+coverage[0]).get_coverage (c->buffer->cur().codepoint); 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount); 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ContextApplyLookupContext lookup_context = { 14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_coverage}, 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (coverage + 1), lookupCount, lookupRecord, lookup_context)); 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!c->check_struct (this)) return TRACE_RETURN (false); 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = glyphCount; 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!c->check_array (coverage, coverage[0].static_size, count)) return TRACE_RETURN (false); 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!coverage[i].sanitize (c, this)) return TRACE_RETURN (false); 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * count); 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 3 */ 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT glyphCount; /* Number of glyphs in the input glyph 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sequence */ 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT lookupCount; /* Number of LookupRecords */ 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage[VAR]; /* Array of offsets to Coverage 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table in glyph sequence order */ 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * design order */ 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY2 (6, coverage, lookupRecordX); 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Context 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 1488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 1492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 1493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 2: return TRACE_RETURN (c->dispatch (u.format2)); 1494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 3: return TRACE_RETURN (c->dispatch (u.format3)); 14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.sanitize (c)); 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: return TRACE_RETURN (u.format3.sanitize (c)); 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextFormat1 format1; 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextFormat2 format2; 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextFormat3 format3; 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Chaining Contextual lookups */ 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainContextClosureLookupContext 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextClosureFuncs funcs; 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *intersects_data[3]; 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ChainContextCollectGlyphsLookupContext 15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContextCollectGlyphsFuncs funcs; 15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void *collect_data[3]; 15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainContextApplyLookupContext 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextApplyFuncs funcs; 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *match_data[3]; 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void chain_context_closure_lookup (hb_closure_context_t *c, 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int backtrackCount, 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT backtrack[], 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookaheadCount, 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT lookahead[], 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookupCount, 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord lookupRecord[], 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextClosureLookupContext &lookup_context) 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (intersects_array (c, 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrackCount, backtrack, 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.intersects, lookup_context.intersects_data[0]) 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && intersects_array (c, 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount ? inputCount - 1 : 0, input, 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.intersects, lookup_context.intersects_data[1]) 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && intersects_array (c, 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookaheadCount, lookahead, 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.intersects, lookup_context.intersects_data[2])) 15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_lookups (c, 15612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord); 15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, 15652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int backtrackCount, 15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT backtrack[], 15672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 15692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookaheadCount, 15702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT lookahead[], 15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookupCount, 15722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord lookupRecord[], 15732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChainContextCollectGlyphsLookupContext &lookup_context) 15742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 15752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_array (c, c->before, 15762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backtrackCount, backtrack, 15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context.funcs.collect, lookup_context.collect_data[0]); 15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_array (c, c->input, 15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inputCount ? inputCount - 1 : 0, input, 15802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context.funcs.collect, lookup_context.collect_data[1]); 15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collect_array (c, c->after, 15822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookaheadCount, lookahead, 15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context.funcs.collect, lookup_context.collect_data[2]); 15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recurse_lookups (c, 15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord); 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c, 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int backtrackCount, 15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT backtrack[] HB_UNUSED, 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int inputCount, /* Including the first glyph (not matched) */ 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT input[], /* Array of input values--start with second glyph */ 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookaheadCount, 15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const USHORT lookahead[] HB_UNUSED, 15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookupCount HB_UNUSED, 15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LookupRecord lookupRecord[] HB_UNUSED, 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextApplyLookupContext &lookup_context) 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (c->zero_context ? !backtrackCount && !lookaheadCount : true) 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && would_match_input (c, 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount, input, 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data[1]); 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool chain_context_apply_lookup (hb_apply_context_t *c, 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int backtrackCount, 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT backtrack[], 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, 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT lookahead[], 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookupCount, 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LookupRecord lookupRecord[], 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextApplyLookupContext &lookup_context) 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int lookahead_offset = 0; 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return match_input (c, 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputCount, input, 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data[1], 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &lookahead_offset) 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && match_backtrack (c, 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrackCount, backtrack, 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data[0]) 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && match_lookahead (c, 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookaheadCount, lookahead, 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data[2], 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead_offset) 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && apply_lookup (c, 1629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inputCount, input, 1630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) lookup_context.funcs.match, lookup_context.match_data[1], 16312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookupCount, lookupRecord); 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainRule 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chain_context_closure_lookup (c, 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack.len, backtrack.array, 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.len, input.array, 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead.len, lookahead.array, 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup.len, lookup.array, 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context); 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const 16512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 16522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chain_context_collect_glyphs_lookup (c, 16572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backtrack.len, backtrack.array, 16582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) input.len, input.array, 16592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookahead.len, lookahead.array, 16602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup.len, lookup.array, 16612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context); 16622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 16632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (chain_context_would_apply_lookup (c, 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack.len, backtrack.array, 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.len, input.array, 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead.len, lookahead.array, lookup.len, 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup.array, lookup_context)); 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (chain_context_apply_lookup (c, 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack.len, backtrack.array, 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.len, input.array, 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead.len, lookahead.array, lookup.len, 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup.array, lookup_context)); 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 16912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!backtrack.sanitize (c)) return TRACE_RETURN (false); 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!input.sanitize (c)) return TRACE_RETURN (false); 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!lookahead.sanitize (c)) return TRACE_RETURN (false); 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (lookup.sanitize (c)); 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<USHORT> 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack; /* Array of backtracking values 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (to be matched before the input 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sequence) */ 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HeadlessArrayOf<USHORT> 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputX; /* Array of input values (start with 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * second glyph) */ 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<USHORT> 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookaheadX; /* Array of lookahead values's (to be 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * matched after the input sequence) */ 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<LookupRecord> 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupX; /* Array of LookupRecords--in 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * design order) */ 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_MIN (8); 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainRuleSet 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_rules = rule.len; 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (this+rule[i]).closure (c, lookup_context); 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const 17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 17312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int num_rules = rule.len; 17332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 17342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+rule[i]).collect_glyphs (c, lookup_context); 17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 17362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_rules = rule.len; 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((this+rule[i]).would_apply (c, lookup_context)) 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_rules = rule.len; 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_rules; i++) 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((this+rule[i]).apply (c, lookup_context)) 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (false); 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 17602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule.sanitize (c, this)); 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<ChainRule> 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule; /* Array of ChainRule tables 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by preference */ 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (2, rule); 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainContextFormat1 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void closure (hb_closure_context_t *c) const 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 17762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Coverage &cov = (this+coverage); 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextClosureLookupContext lookup_context = { 17802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {intersects_glyph}, 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {NULL, NULL, NULL} 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = ruleSet.len; 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cov.intersects_coverage (c->glyphs, i)) { 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ChainRuleSet &rule_set = this+ruleSet[i]; 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule_set.closure (c, lookup_context); 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 17932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 17952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 17962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct ChainContextCollectGlyphsLookupContext lookup_context = { 17982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {collect_glyph}, 17992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {NULL, NULL, NULL} 18002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 18012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = ruleSet.len; 18032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 18042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+ruleSet[i]).collect_glyphs (c, lookup_context); 18052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 18062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c) const 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])]; 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextApplyLookupContext lookup_context = { 18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_glyph}, 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {NULL, NULL, NULL} 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const Coverage &get_coverage (void) const 18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this+coverage; 18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ChainRuleSet &rule_set = this+ruleSet[index]; 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextApplyLookupContext lookup_context = { 18322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_glyph}, 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {NULL, NULL, NULL} 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.apply (c, lookup_context)); 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 1 */ 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of table */ 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<ChainRuleSet> 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleSet; /* Array of ChainRuleSet tables 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by Coverage Index */ 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (6, ruleSet); 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainContextFormat2 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 18572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void closure (hb_closure_context_t *c) const 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 18592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(this+coverage).intersects (c->glyphs)) 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &backtrack_class_def = this+backtrackClassDef; 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &input_class_def = this+inputClassDef; 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &lookahead_class_def = this+lookaheadClassDef; 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextClosureLookupContext lookup_context = { 18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {intersects_class}, 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {&backtrack_class_def, 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &input_class_def, 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &lookahead_class_def} 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = ruleSet.len; 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (input_class_def.intersects_class (c->glyphs, i)) { 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ChainRuleSet &rule_set = this+ruleSet[i]; 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule_set.closure (c, lookup_context); 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+coverage).add_coverage (c->input); 18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &backtrack_class_def = this+backtrackClassDef; 18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &input_class_def = this+inputClassDef; 18892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &lookahead_class_def = this+lookaheadClassDef; 18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct ChainContextCollectGlyphsLookupContext lookup_context = { 18922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {collect_class}, 18932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {&backtrack_class_def, 18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &input_class_def, 18952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &lookahead_class_def} 18962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 18972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = ruleSet.len; 18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+ruleSet[i]).collect_glyphs (c, lookup_context); 19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c) const 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &backtrack_class_def = this+backtrackClassDef; 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &input_class_def = this+inputClassDef; 19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ClassDef &lookahead_class_def = this+lookaheadClassDef; 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = input_class_def.get_class (c->glyphs[0]); 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ChainRuleSet &rule_set = this+ruleSet[index]; 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextApplyLookupContext lookup_context = { 19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_class}, 19152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {&backtrack_class_def, 19162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &input_class_def, 19172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &lookahead_class_def} 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const Coverage &get_coverage (void) const 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this+coverage; 19252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 19262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 19282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 19292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 19302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &backtrack_class_def = this+backtrackClassDef; 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &input_class_def = this+inputClassDef; 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClassDef &lookahead_class_def = this+lookaheadClassDef; 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) index = input_class_def.get_class (c->buffer->cur().codepoint); 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ChainRuleSet &rule_set = this+ruleSet[index]; 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextApplyLookupContext lookup_context = { 19402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_class}, 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {&backtrack_class_def, 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &input_class_def, 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &lookahead_class_def} 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rule_set.apply (c, lookup_context)); 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 19492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) && 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) && 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleSet.sanitize (c, this)); 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 2 */ 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Coverage> 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage; /* Offset to Coverage table--from 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of table */ 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ClassDef> 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrackClassDef; /* Offset to glyph ClassDef table 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * containing backtrack sequence 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * data--from beginning of table */ 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ClassDef> 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputClassDef; /* Offset to glyph ClassDef 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * table containing input sequence 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * data--from beginning of table */ 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ClassDef> 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookaheadClassDef; /* Offset to glyph ClassDef table 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * containing lookahead sequence 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * data--from beginning of table */ 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<ChainRuleSet> 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleSet; /* Array of ChainRuleSet tables 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ordered by class */ 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (12, ruleSet); 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainContextFormat3 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 19812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void closure (hb_closure_context_t *c) const 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 19832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_CLOSURE (this); 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(this+input[0]).intersects (c->glyphs)) 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextClosureLookupContext lookup_context = { 19922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {intersects_coverage}, 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {this, this, this} 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chain_context_closure_lookup (c, 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack.len, (const USHORT *) backtrack.array, 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.len, (const USHORT *) input.array + 1, 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead.len, (const USHORT *) lookahead.array, 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup.len, lookup.array, 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_context); 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void collect_glyphs (hb_collect_glyphs_context_t *c) const 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COLLECT_GLYPHS (this); 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (this+input[0]).add_coverage (c->input); 20092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 20112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 20122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct ChainContextCollectGlyphsLookupContext lookup_context = { 20132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {collect_coverage}, 20142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {this, this, this} 20152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 20162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chain_context_collect_glyphs_lookup (c, 20172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backtrack.len, (const USHORT *) backtrack.array, 20182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) input.len, (const USHORT *) input.array + 1, 20192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookahead.len, (const USHORT *) lookahead.array, 20202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup.len, lookup.array, 20212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_context); 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool would_apply (hb_would_apply_context_t *c) const 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_WOULD_APPLY (this); 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextApplyLookupContext lookup_context = { 20322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_coverage}, 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {this, this, this} 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (chain_context_would_apply_lookup (c, 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack.len, (const USHORT *) backtrack.array, 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.len, (const USHORT *) input.array + 1, 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead.len, (const USHORT *) lookahead.array, 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup.len, lookup.array, lookup_context)); 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const Coverage &get_coverage (void) const 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return this+input[0]; 20462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool apply (hb_apply_context_t *c) const 20492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 20502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_APPLY (this); 20512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChainContextApplyLookupContext lookup_context = { 20592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {match_coverage}, 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {this, this, this} 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (chain_context_apply_lookup (c, 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack.len, (const USHORT *) backtrack.array, 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input.len, (const USHORT *) input.array + 1, 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookahead.len, (const USHORT *) lookahead.array, 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup.len, lookup.array, lookup_context)); 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 20702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false); 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!input.sanitize (c, this)) return TRACE_RETURN (false); 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false); 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (lookup.sanitize (c)); 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier--format = 3 */ 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<Coverage> 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backtrack; /* Array of coverage tables 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in backtracking sequence, in glyph 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sequence order */ 20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<Coverage> 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inputX ; /* Array of coverage 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tables in input sequence, in glyph 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sequence order */ 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetArrayOf<Coverage> 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookaheadX; /* Array of coverage tables 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in lookahead sequence, in glyph 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sequence order */ 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<LookupRecord> 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupX; /* Array of LookupRecords--in 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * design order) */ 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_MIN (10); 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChainContext 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 21032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 2104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_DISPATCH (this); 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 2108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: return TRACE_RETURN (c->dispatch (u.format1)); 2109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 2: return TRACE_RETURN (c->dispatch (u.format2)); 2110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 3: return TRACE_RETURN (c->dispatch (u.format3)); 21112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return TRACE_RETURN (c->default_return_value ()); 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 21162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.sanitize (c)); 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: return TRACE_RETURN (u.format3.sanitize (c)); 21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextFormat1 format1; 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextFormat2 format2; 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainContextFormat3 format3; 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ExtensionFormat1 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_type (void) const { return extensionLookupType; } 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_offset (void) const { return extensionOffset; } 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 21422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this)); 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier. Set to 1. */ 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT extensionLookupType; /* Lookup type of subtable referenced 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * by ExtensionOffset (i.e. the 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extension subtable). */ 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG extensionOffset; /* Offset to the extension subtable, 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of lookup type subtable. */ 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (8); 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename T> 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Extension 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_type (void) const 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return u.format1.get_type (); 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return 0; 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_offset (void) const 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return u.format1.get_offset (); 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return 0; 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename X> 21762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const X& get_subtable (void) const 21772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 21782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int offset = get_offset (); 21792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (!offset)) return Null(typename T::LookupSubTable); 21802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return StructAtOffset<typename T::LookupSubTable> (this, offset); 21812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 21822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename context_t> 2184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) inline typename context_t::return_t dispatch (context_t *c) const 21852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 2186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()); 21872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 21882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool sanitize_self (hb_sanitize_context_t *c) { 21902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 21992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 22002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!sanitize_self (c)) return TRACE_RETURN (false); 22012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int offset = get_offset (); 22022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (!offset)) return TRACE_RETURN (true); 22032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (StructAtOffset<typename T::LookupSubTable> (this, offset).sanitize (c, get_type ())); 22042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 22052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionFormat1 format1; 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * GSUB/GPOS Common 22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GSUBGPOS 22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const hb_tag_t GSUBTag = HB_OT_TAG_GSUB; 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const hb_tag_t GPOSTag = HB_OT_TAG_GPOS; 22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_script_count (void) const 22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+scriptList).len; } 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Tag& get_script_tag (unsigned int i) const 22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+scriptList).get_tag (i); } 22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_script_tags (unsigned int start_offset, 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *script_count /* IN/OUT */, 22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_tag_t *script_tags /* OUT */) const 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+scriptList).get_tags (start_offset, script_count, script_tags); } 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Script& get_script (unsigned int i) const 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+scriptList)[i]; } 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool find_script_index (hb_tag_t tag, unsigned int *index) const 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+scriptList).find_index (tag, index); } 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_feature_count (void) const 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+featureList).len; } 22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Tag& get_feature_tag (unsigned int i) const 22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+featureList).get_tag (i); } 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_feature_tags (unsigned int start_offset, 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *feature_count /* IN/OUT */, 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_tag_t *feature_tags /* OUT */) const 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+featureList).get_tags (start_offset, feature_count, feature_tags); } 22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Feature& get_feature (unsigned int i) const 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+featureList)[i]; } 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const 22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+featureList).find_index (tag, index); } 22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_lookup_count (void) const 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+lookupList).len; } 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Lookup& get_lookup (unsigned int i) const 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return (this+lookupList)[i]; } 22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 22552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && 22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scriptList.sanitize (c, this) && 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) featureList.sanitize (c, this) && 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupList.sanitize (c, this)); 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixedVersion version; /* Version of the GSUB/GPOS table--initially set 22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to 0x00010000 */ 22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<ScriptList> 22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scriptList; /* ScriptList table */ 22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<FeatureList> 22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) featureList; /* FeatureList table */ 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<LookupList> 22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupList; /* LookupList table */ 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (10); 22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} /* namespace OT */ 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ 2280