diff options
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh | 478 |
1 files changed, 261 insertions, 217 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh index fd75c5425a..b08a59138e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh @@ -29,6 +29,8 @@ #ifndef HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH #define HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH +#include "hb-private.hh" +#include "hb-debug.hh" #include "hb-buffer-private.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-set-private.hh" @@ -37,15 +39,6 @@ namespace OT { -#ifndef HB_DEBUG_CLOSURE -#define HB_DEBUG_CLOSURE (HB_DEBUG+0) -#endif - -#define TRACE_CLOSURE(this) \ - hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \ - (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - ""); - struct hb_closure_context_t : hb_dispatch_context_t<hb_closure_context_t, hb_void_t, HB_DEBUG_CLOSURE> { @@ -77,7 +70,7 @@ struct hb_closure_context_t : unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), glyphs (glyphs_), - recurse_func (NULL), + recurse_func (nullptr), nesting_level_left (nesting_level_left_), debug_depth (0) {} @@ -85,16 +78,6 @@ struct hb_closure_context_t : }; - -#ifndef HB_DEBUG_WOULD_APPLY -#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0) -#endif - -#define TRACE_WOULD_APPLY(this) \ - hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \ - (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - "%d glyphs", c->len); - struct hb_would_apply_context_t : hb_dispatch_context_t<hb_would_apply_context_t, bool, HB_DEBUG_WOULD_APPLY> { @@ -122,16 +105,6 @@ struct hb_would_apply_context_t : }; - -#ifndef HB_DEBUG_COLLECT_GLYPHS -#define HB_DEBUG_COLLECT_GLYPHS (HB_DEBUG+0) -#endif - -#define TRACE_COLLECT_GLYPHS(this) \ - hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \ - (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - ""); - struct hb_collect_glyphs_context_t : hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, HB_DEBUG_COLLECT_GLYPHS> { @@ -146,7 +119,7 @@ struct hb_collect_glyphs_context_t : if (unlikely (nesting_level_left == 0 || !recurse_func)) return default_return_value (); - /* Note that GPOS sets recurse_func to NULL already, so it doesn't get + /* Note that GPOS sets recurse_func to nullptr already, so it doesn't get * past the previous check. For GSUB, we only want to collect the output * glyphs in the recursion. If output is not requested, we can go home now. * @@ -160,7 +133,7 @@ struct hb_collect_glyphs_context_t : return HB_VOID; /* Return if new lookup was recursed to before. */ - if (recursed_lookups.has (lookup_index)) + if (recursed_lookups->has (lookup_index)) return HB_VOID; hb_set_t *old_before = before; @@ -176,7 +149,7 @@ struct hb_collect_glyphs_context_t : input = old_input; after = old_after; - recursed_lookups.add (lookup_index); + recursed_lookups->add (lookup_index); return HB_VOID; } @@ -187,31 +160,31 @@ struct hb_collect_glyphs_context_t : hb_set_t *after; hb_set_t *output; recurse_func_t recurse_func; - hb_set_t recursed_lookups; + hb_set_t *recursed_lookups; unsigned int nesting_level_left; unsigned int debug_depth; hb_collect_glyphs_context_t (hb_face_t *face_, - hb_set_t *glyphs_before, /* OUT. May be NULL */ - hb_set_t *glyphs_input, /* OUT. May be NULL */ - hb_set_t *glyphs_after, /* OUT. May be NULL */ - hb_set_t *glyphs_output, /* OUT. May be NULL */ + hb_set_t *glyphs_before, /* OUT. May be nullptr */ + hb_set_t *glyphs_input, /* OUT. May be nullptr */ + hb_set_t *glyphs_after, /* OUT. May be nullptr */ + hb_set_t *glyphs_output, /* OUT. May be nullptr */ unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), before (glyphs_before ? glyphs_before : hb_set_get_empty ()), input (glyphs_input ? glyphs_input : hb_set_get_empty ()), after (glyphs_after ? glyphs_after : hb_set_get_empty ()), output (glyphs_output ? glyphs_output : hb_set_get_empty ()), - recurse_func (NULL), - recursed_lookups (), + recurse_func (nullptr), + recursed_lookups (nullptr), nesting_level_left (nesting_level_left_), debug_depth (0) { - recursed_lookups.init (); + recursed_lookups = hb_set_create (); } ~hb_collect_glyphs_context_t (void) { - recursed_lookups.fini (); + hb_set_destroy (recursed_lookups); } void set_recurse_func (recurse_func_t func) { recurse_func = func; } @@ -219,10 +192,6 @@ struct hb_collect_glyphs_context_t : -#ifndef HB_DEBUG_GET_COVERAGE -#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0) -#endif - /* XXX Can we remove this? */ template <typename set_t> @@ -249,17 +218,6 @@ struct hb_add_coverage_context_t : }; - -#ifndef HB_DEBUG_APPLY -#define HB_DEBUG_APPLY (HB_DEBUG+0) -#endif - -#define TRACE_APPLY(this) \ - hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \ - (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - "idx %d gid %u lookup %d", \ - c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index); - struct hb_apply_context_t : hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY> { @@ -273,10 +231,10 @@ struct hb_apply_context_t : #define arg1(arg) (arg) /* Remove the macro to see why it's needed! */ syllable arg1(0), #undef arg1 - match_func (NULL), - match_data (NULL) {}; + match_func (nullptr), + match_data (nullptr) {}; - typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data); + typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const UINT16 &value, const void *data); inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } @@ -294,7 +252,7 @@ struct hb_apply_context_t : }; inline may_match_t may_match (const hb_glyph_info_t &info, - const USHORT *glyph_data) const + const UINT16 *glyph_data) const { if (!(info.mask & mask) || (syllable && syllable != info.syllable ())) @@ -319,7 +277,7 @@ struct hb_apply_context_t : if (!c->check_glyph_property (&info, lookup_props)) return SKIP_YES; - if (unlikely (_hb_glyph_info_is_default_ignorable_and_not_fvs (&info) && + if (unlikely (_hb_glyph_info_is_default_ignorable_and_not_hidden (&info) && (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && (ignore_zwj || !_hb_glyph_info_is_zwj (&info)))) return SKIP_MAYBE; @@ -342,13 +300,13 @@ struct hb_apply_context_t : inline void init (hb_apply_context_t *c_, bool context_match = false) { c = c_; - match_glyph_data = NULL, - matcher.set_match_func (NULL, NULL); + match_glyph_data = nullptr; + matcher.set_match_func (nullptr, nullptr); matcher.set_lookup_props (c->lookup_props); /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ - matcher.set_ignore_zwnj (context_match || c->table_index == 1); + matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj)); /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ - matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); + matcher.set_ignore_zwj (c->table_index == 1 || (context_match || c->auto_zwj)); matcher.set_mask (context_match ? -1 : c->lookup_mask); } inline void set_lookup_props (unsigned int lookup_props) @@ -357,7 +315,7 @@ struct hb_apply_context_t : } inline void set_match_func (matcher_t::match_func_t match_func_, const void *match_data_, - const USHORT glyph_data[]) + const UINT16 glyph_data[]) { matcher.set_match_func (match_func_, match_data_); match_glyph_data = glyph_data; @@ -374,6 +332,13 @@ struct hb_apply_context_t : inline void reject (void) { num_items++; match_glyph_data--; } + inline matcher_t::may_skip_t + may_skip (const hb_apply_context_t *c, + const hb_glyph_info_t &info) const + { + return matcher.may_skip (c, info); + } + inline bool next (void) { assert (num_items > 0); @@ -433,7 +398,7 @@ struct hb_apply_context_t : protected: hb_apply_context_t *c; matcher_t matcher; - const USHORT *match_glyph_data; + const UINT16 *match_glyph_data; unsigned int num_items; unsigned int end; @@ -448,7 +413,7 @@ struct hb_apply_context_t : bool stop_sublookup_iteration (return_t r) const { return r; } return_t recurse (unsigned int lookup_index) { - if (unlikely (nesting_level_left == 0 || !recurse_func)) + if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0)) return default_return_value (); nesting_level_left--; @@ -457,45 +422,50 @@ struct hb_apply_context_t : return ret; } - unsigned int table_index; /* GSUB/GPOS */ + skipping_iterator_t iter_input, iter_context; + hb_font_t *font; hb_face_t *face; hb_buffer_t *buffer; - hb_direction_t direction; - hb_mask_t lookup_mask; - bool auto_zwj; recurse_func_t recurse_func; - unsigned int nesting_level_left; - unsigned int lookup_props; const GDEF &gdef; - bool has_glyph_classes; const VariationStore &var_store; - skipping_iterator_t iter_input, iter_context; + + hb_direction_t direction; + hb_mask_t lookup_mask; + unsigned int table_index; /* GSUB/GPOS */ unsigned int lookup_index; + unsigned int lookup_props; + unsigned int nesting_level_left; unsigned int debug_depth; + bool auto_zwnj; + bool auto_zwj; + bool has_glyph_classes; + hb_apply_context_t (unsigned int table_index_, hb_font_t *font_, hb_buffer_t *buffer_) : - table_index (table_index_), + iter_input (), iter_context (), font (font_), face (font->face), buffer (buffer_), - direction (buffer_->props.direction), - lookup_mask (1), - auto_zwj (true), - recurse_func (NULL), - nesting_level_left (HB_MAX_NESTING_LEVEL), - lookup_props (0), + recurse_func (nullptr), gdef (*hb_ot_layout_from_face (face)->gdef), - has_glyph_classes (gdef.has_glyph_classes ()), var_store (gdef.get_var_store ()), - iter_input (), - iter_context (), + direction (buffer_->props.direction), + lookup_mask (1), + table_index (table_index_), lookup_index ((unsigned int) -1), - debug_depth (0) {} + lookup_props (0), + nesting_level_left (HB_MAX_NESTING_LEVEL), + debug_depth (0), + auto_zwnj (true), + auto_zwj (true), + has_glyph_classes (gdef.has_glyph_classes ()) {} inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } + inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; } inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; } inline void set_lookup_props (unsigned int lookup_props_) @@ -598,9 +568,9 @@ struct hb_apply_context_t : -typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data); -typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data); -typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data); +typedef bool (*intersects_func_t) (hb_set_t *glyphs, const UINT16 &value, const void *data); +typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const UINT16 &value, const void *data); +typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const UINT16 &value, const void *data); struct ContextClosureFuncs { @@ -616,16 +586,16 @@ struct ContextApplyFuncs }; -static inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED) +static inline bool intersects_glyph (hb_set_t *glyphs, const UINT16 &value, const void *data HB_UNUSED) { return glyphs->has (value); } -static inline bool intersects_class (hb_set_t *glyphs, const USHORT &value, const void *data) +static inline bool intersects_class (hb_set_t *glyphs, const UINT16 &value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); return class_def.intersects_class (glyphs, value); } -static inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, const void *data) +static inline bool intersects_coverage (hb_set_t *glyphs, const UINT16 &value, const void *data) { const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; return (data+coverage).intersects (glyphs); @@ -633,7 +603,7 @@ static inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, c static inline bool intersects_array (hb_closure_context_t *c, unsigned int count, - const USHORT values[], + const UINT16 values[], intersects_func_t intersects_func, const void *intersects_data) { @@ -644,16 +614,16 @@ static inline bool intersects_array (hb_closure_context_t *c, } -static inline void collect_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED) +static inline void collect_glyph (hb_set_t *glyphs, const UINT16 &value, const void *data HB_UNUSED) { glyphs->add (value); } -static inline void collect_class (hb_set_t *glyphs, const USHORT &value, const void *data) +static inline void collect_class (hb_set_t *glyphs, const UINT16 &value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); class_def.add_class (glyphs, value); } -static inline void collect_coverage (hb_set_t *glyphs, const USHORT &value, const void *data) +static inline void collect_coverage (hb_set_t *glyphs, const UINT16 &value, const void *data) { const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; (data+coverage).add_coverage (glyphs); @@ -661,7 +631,7 @@ static inline void collect_coverage (hb_set_t *glyphs, const USHORT &value, cons static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, hb_set_t *glyphs, unsigned int count, - const USHORT values[], + const UINT16 values[], collect_glyphs_func_t collect_func, const void *collect_data) { @@ -670,16 +640,16 @@ static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, } -static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, const void *data HB_UNUSED) +static inline bool match_glyph (hb_codepoint_t glyph_id, const UINT16 &value, const void *data HB_UNUSED) { return glyph_id == value; } -static inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, const void *data) +static inline bool match_class (hb_codepoint_t glyph_id, const UINT16 &value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); return class_def.get_class (glyph_id) == value; } -static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value, const void *data) +static inline bool match_coverage (hb_codepoint_t glyph_id, const UINT16 &value, const void *data) { const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; @@ -687,7 +657,7 @@ static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value, static inline bool would_match_input (hb_would_apply_context_t *c, unsigned int count, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const UINT16 input[], /* Array of input values--start with second glyph */ match_func_t match_func, const void *match_data) { @@ -702,15 +672,15 @@ static inline bool would_match_input (hb_would_apply_context_t *c, } static inline bool match_input (hb_apply_context_t *c, unsigned int count, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const UINT16 input[], /* Array of input values--start with second glyph */ match_func_t match_func, const void *match_data, unsigned int *end_offset, unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], - bool *p_is_mark_ligature = NULL, - unsigned int *p_total_component_count = NULL) + bool *p_is_mark_ligature = nullptr, + unsigned int *p_total_component_count = nullptr) { - TRACE_APPLY (NULL); + TRACE_APPLY (nullptr); if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false); @@ -731,11 +701,17 @@ static inline bool match_input (hb_apply_context_t *c, * - Ligatures cannot be formed across glyphs attached to different components * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother. - * However, it would be wrong to ligate that SHADDA,FATHA sequence.o - * There is an exception to this: If a ligature tries ligating with marks that - * belong to it itself, go ahead, assuming that the font designer knows what - * they are doing (otherwise it can break Indic stuff when a matra wants to - * ligate with a conjunct...) + * However, it would be wrong to ligate that SHADDA,FATHA sequence. + * There are a couple of exceptions to this: + * + * o If a ligature tries ligating with marks that belong to it itself, go ahead, + * assuming that the font designer knows what they are doing (otherwise it can + * break Indic stuff when a matra wants to ligate with a conjunct, + * + * o If two marks want to ligate and they belong to different components of the + * same ligature glyph, and said ligature glyph is to be ignored according to + * mark-filtering rules, then allow. + * https://github.com/harfbuzz/harfbuzz/issues/545 */ bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur()); @@ -746,6 +722,12 @@ static inline bool match_input (hb_apply_context_t *c, unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); + enum { + LIGBASE_NOT_CHECKED, + LIGBASE_MAY_NOT_SKIP, + LIGBASE_MAY_SKIP + } ligbase = LIGBASE_NOT_CHECKED; + match_positions[0] = buffer->idx; for (unsigned int i = 1; i < count; i++) { @@ -756,13 +738,43 @@ static inline bool match_input (hb_apply_context_t *c, unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]); unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]); - if (first_lig_id && first_lig_comp) { + if (first_lig_id && first_lig_comp) + { /* If first component was attached to a previous ligature component, * all subsequent components should be attached to the same ligature - * component, otherwise we shouldn't ligate them. */ + * component, otherwise we shouldn't ligate them... */ if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp) - return_trace (false); - } else { + { + /* ...unless, we are attached to a base ligature and that base + * ligature is ignorable. */ + if (ligbase == LIGBASE_NOT_CHECKED) + { + bool found = false; + const hb_glyph_info_t *out = buffer->out_info; + unsigned int j = buffer->out_len; + while (j && _hb_glyph_info_get_lig_id (&out[j - 1]) == first_lig_id) + { + if (_hb_glyph_info_get_lig_comp (&out[j - 1]) == 0) + { + j--; + found = true; + break; + } + j--; + } + + if (found && skippy_iter.may_skip (c, out[j]) == hb_apply_context_t::matcher_t::SKIP_YES) + ligbase = LIGBASE_MAY_SKIP; + else + ligbase = LIGBASE_MAY_NOT_SKIP; + } + + if (ligbase == LIGBASE_MAY_NOT_SKIP) + return_trace (false); + } + } + else + { /* If first component was NOT attached to a previous ligature component, * all subsequent components should also NOT be attached to any ligature * component, unless they are attached to the first component itself! */ @@ -792,7 +804,7 @@ static inline bool ligate_input (hb_apply_context_t *c, bool is_mark_ligature, unsigned int total_component_count) { - TRACE_APPLY (NULL); + TRACE_APPLY (nullptr); hb_buffer_t *buffer = c->buffer; @@ -884,11 +896,12 @@ static inline bool ligate_input (hb_apply_context_t *c, static inline bool match_backtrack (hb_apply_context_t *c, unsigned int count, - const USHORT backtrack[], + const UINT16 backtrack[], match_func_t match_func, - const void *match_data) + const void *match_data, + unsigned int *match_start) { - TRACE_APPLY (NULL); + TRACE_APPLY (nullptr); hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->backtrack_len (), count); @@ -898,17 +911,20 @@ static inline bool match_backtrack (hb_apply_context_t *c, if (!skippy_iter.prev ()) return_trace (false); + *match_start = skippy_iter.idx; + return_trace (true); } static inline bool match_lookahead (hb_apply_context_t *c, unsigned int count, - const USHORT lookahead[], + const UINT16 lookahead[], match_func_t match_func, const void *match_data, - unsigned int offset) + unsigned int offset, + unsigned int *end_index) { - TRACE_APPLY (NULL); + TRACE_APPLY (nullptr); hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->idx + offset - 1, count); @@ -918,6 +934,8 @@ static inline bool match_lookahead (hb_apply_context_t *c, if (!skippy_iter.next ()) return_trace (false); + *end_index = skippy_iter.idx + 1; + return_trace (true); } @@ -931,9 +949,9 @@ struct LookupRecord return_trace (c->check_struct (this)); } - USHORT sequenceIndex; /* Index into current glyph + UINT16 sequenceIndex; /* Index into current glyph * sequence--first glyph = 0 */ - USHORT lookupListIndex; /* Lookup to apply to that + UINT16 lookupListIndex; /* Lookup to apply to that * position--zero--based */ public: DEFINE_SIZE_STATIC (4); @@ -956,10 +974,10 @@ static inline bool apply_lookup (hb_apply_context_t *c, const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ unsigned int match_length) { - TRACE_APPLY (NULL); + TRACE_APPLY (nullptr); hb_buffer_t *buffer = c->buffer; - unsigned int end; + int end; /* All positions are distance from beginning of *output* buffer. * Adjust. */ @@ -984,7 +1002,11 @@ static inline bool apply_lookup (hb_apply_context_t *c, if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index) continue; - buffer->move_to (match_positions[idx]); + if (unlikely (!buffer->move_to (match_positions[idx]))) + break; + + if (unlikely (buffer->max_ops <= 0)) + break; unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); if (!c->recurse (lookupRecord[i].lookupListIndex)) @@ -996,10 +1018,32 @@ static inline bool apply_lookup (hb_apply_context_t *c, if (!delta) continue; - /* Recursed lookup changed buffer len. Adjust. */ + /* Recursed lookup changed buffer len. Adjust. + * + * TODO: + * + * Right now, if buffer length increased by n, we assume n new glyphs + * were added right after the current position, and if buffer length + * was decreased by n, we assume n match positions after the current + * one where removed. The former (buffer length increased) case is + * fine, but the decrease case can be improved in at least two ways, + * both of which are significant: + * + * - If recursed-to lookup is MultipleSubst and buffer length + * decreased, then it's current match position that was deleted, + * NOT the one after it. + * + * - If buffer length was decreased by n, it does not necessarily + * mean that n match positions where removed, as there might + * have been marks and default-ignorables in the sequence. We + * should instead drop match positions between current-position + * and current-position + n instead. + * + * It should be possible to construct tests for both of these cases. + */ - end = int (end) + delta; - if (end <= match_positions[idx]) + end += delta; + if (end <= int (match_positions[idx])) { /* End might end up being smaller than match_positions[idx] if the recursed * lookup ended up removing many items, more than we have had matched. @@ -1068,7 +1112,7 @@ struct ContextApplyLookupContext static inline void context_closure_lookup (hb_closure_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const UINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], ContextClosureLookupContext &lookup_context) @@ -1082,7 +1126,7 @@ static inline void context_closure_lookup (hb_closure_context_t *c, static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const UINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], ContextCollectGlyphsLookupContext &lookup_context) @@ -1096,7 +1140,7 @@ static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const UINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookupCount HB_UNUSED, const LookupRecord lookupRecord[] HB_UNUSED, ContextApplyLookupContext &lookup_context) @@ -1107,7 +1151,7 @@ static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, } static inline bool context_apply_lookup (hb_apply_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const UINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], ContextApplyLookupContext &lookup_context) @@ -1118,10 +1162,11 @@ static inline bool context_apply_lookup (hb_apply_context_t *c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data, &match_length, match_positions) - && apply_lookup (c, + && (c->buffer->unsafe_to_break (c->buffer->idx, c->buffer->idx + match_length), + apply_lookup (c, inputCount, match_positions, lookupCount, lookupRecord, - match_length); + match_length)); } struct Rule @@ -1164,19 +1209,19 @@ struct Rule inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return inputCount.sanitize (c) - && lookupCount.sanitize (c) - && c->check_range (inputZ, - inputZ[0].static_size * inputCount - + lookupRecordX[0].static_size * lookupCount); + return_trace (inputCount.sanitize (c) && + lookupCount.sanitize (c) && + c->check_range (inputZ, + inputZ[0].static_size * inputCount + + lookupRecordX[0].static_size * lookupCount)); } protected: - USHORT inputCount; /* Total number of glyphs in input + UINT16 inputCount; /* Total number of glyphs in input * glyph sequence--includes the first * glyph */ - USHORT lookupCount; /* Number of LookupRecords */ - USHORT inputZ[VAR]; /* Array of match inputs--start with + UINT16 lookupCount; /* Number of LookupRecords */ + UINT16 inputZ[VAR]; /* Array of match inputs--start with * second glyph */ LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in * design order */ @@ -1251,7 +1296,7 @@ struct ContextFormat1 struct ContextClosureLookupContext lookup_context = { {intersects_glyph}, - NULL + nullptr }; unsigned int count = ruleSet.len; @@ -1269,7 +1314,7 @@ struct ContextFormat1 struct ContextCollectGlyphsLookupContext lookup_context = { {collect_glyph}, - NULL + nullptr }; unsigned int count = ruleSet.len; @@ -1284,7 +1329,7 @@ struct ContextFormat1 const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])]; struct ContextApplyLookupContext lookup_context = { {match_glyph}, - NULL + nullptr }; return_trace (rule_set.would_apply (c, lookup_context)); } @@ -1304,7 +1349,7 @@ struct ContextFormat1 const RuleSet &rule_set = this+ruleSet[index]; struct ContextApplyLookupContext lookup_context = { {match_glyph}, - NULL + nullptr }; return_trace (rule_set.apply (c, lookup_context)); } @@ -1316,7 +1361,7 @@ struct ContextFormat1 } protected: - USHORT format; /* Format identifier--format = 1 */ + UINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ @@ -1409,7 +1454,7 @@ struct ContextFormat2 } protected: - USHORT format; /* Format identifier--format = 2 */ + UINT16 format; /* Format identifier--format = 2 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ @@ -1438,7 +1483,7 @@ struct ContextFormat3 this }; context_closure_lookup (c, - glyphCount, (const USHORT *) (coverageZ + 1), + glyphCount, (const UINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context); } @@ -1455,7 +1500,7 @@ struct ContextFormat3 }; context_collect_glyphs_lookup (c, - glyphCount, (const USHORT *) (coverageZ + 1), + glyphCount, (const UINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context); } @@ -1469,7 +1514,7 @@ struct ContextFormat3 {match_coverage}, this }; - return_trace (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); + return_trace (context_would_apply_lookup (c, glyphCount, (const UINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); } inline const Coverage &get_coverage (void) const @@ -1488,7 +1533,7 @@ struct ContextFormat3 {match_coverage}, this }; - return_trace (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); + return_trace (context_apply_lookup (c, glyphCount, (const UINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -1505,10 +1550,10 @@ struct ContextFormat3 } protected: - USHORT format; /* Format identifier--format = 3 */ - USHORT glyphCount; /* Number of glyphs in the input glyph + UINT16 format; /* Format identifier--format = 3 */ + UINT16 glyphCount; /* Number of glyphs in the input glyph * sequence */ - USHORT lookupCount; /* Number of LookupRecords */ + UINT16 lookupCount; /* Number of LookupRecords */ OffsetTo<Coverage> coverageZ[VAR]; /* Array of offsets to Coverage * table in glyph sequence order */ @@ -1535,7 +1580,7 @@ struct Context protected: union { - USHORT format; /* Format identifier */ + UINT16 format; /* Format identifier */ ContextFormat1 format1; ContextFormat2 format2; ContextFormat3 format3; @@ -1565,11 +1610,11 @@ struct ChainContextApplyLookupContext static inline void chain_context_closure_lookup (hb_closure_context_t *c, unsigned int backtrackCount, - const USHORT backtrack[], + const UINT16 backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const UINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const USHORT lookahead[], + const UINT16 lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], ChainContextClosureLookupContext &lookup_context) @@ -1589,11 +1634,11 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c, static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, unsigned int backtrackCount, - const USHORT backtrack[], + const UINT16 backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const UINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const USHORT lookahead[], + const UINT16 lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], ChainContextCollectGlyphsLookupContext &lookup_context) @@ -1613,11 +1658,11 @@ static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_contex static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c, unsigned int backtrackCount, - const USHORT backtrack[] HB_UNUSED, + const UINT16 backtrack[] HB_UNUSED, unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const UINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const USHORT lookahead[] HB_UNUSED, + const UINT16 lookahead[] HB_UNUSED, unsigned int lookupCount HB_UNUSED, const LookupRecord lookupRecord[] HB_UNUSED, ChainContextApplyLookupContext &lookup_context) @@ -1630,16 +1675,16 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c static inline bool chain_context_apply_lookup (hb_apply_context_t *c, unsigned int backtrackCount, - const USHORT backtrack[], + const UINT16 backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const UINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const USHORT lookahead[], + const UINT16 lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], ChainContextApplyLookupContext &lookup_context) { - unsigned int match_length = 0; + unsigned int start_index = 0, match_length = 0, end_index = 0; unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; return match_input (c, inputCount, input, @@ -1647,15 +1692,17 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c, &match_length, match_positions) && match_backtrack (c, backtrackCount, backtrack, - lookup_context.funcs.match, lookup_context.match_data[0]) + lookup_context.funcs.match, lookup_context.match_data[0], + &start_index) && match_lookahead (c, lookaheadCount, lookahead, lookup_context.funcs.match, lookup_context.match_data[2], - match_length) - && apply_lookup (c, + match_length, &end_index) + && (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index), + apply_lookup (c, inputCount, match_positions, lookupCount, lookupRecord, - match_length); + match_length)); } struct ChainRule @@ -1663,8 +1710,8 @@ struct ChainRule inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const { TRACE_CLOSURE (this); - const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); - const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); + const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack); + const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); chain_context_closure_lookup (c, backtrack.len, backtrack.array, @@ -1677,8 +1724,8 @@ struct ChainRule inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const { TRACE_COLLECT_GLYPHS (this); - const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); - const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); + const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack); + const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); chain_context_collect_glyphs_lookup (c, backtrack.len, backtrack.array, @@ -1691,8 +1738,8 @@ struct ChainRule inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const { TRACE_WOULD_APPLY (this); - const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); - const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); + const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack); + const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (chain_context_would_apply_lookup (c, backtrack.len, backtrack.array, @@ -1704,8 +1751,8 @@ struct ChainRule inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); - const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); - const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); + const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack); + const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (chain_context_apply_lookup (c, backtrack.len, backtrack.array, @@ -1718,23 +1765,23 @@ struct ChainRule { TRACE_SANITIZE (this); if (!backtrack.sanitize (c)) return_trace (false); - const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); + const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack); if (!input.sanitize (c)) return_trace (false); - const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); + const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input); if (!lookahead.sanitize (c)) return_trace (false); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (lookup.sanitize (c)); } protected: - ArrayOf<USHORT> + ArrayOf<UINT16> backtrack; /* Array of backtracking values * (to be matched before the input * sequence) */ - HeadlessArrayOf<USHORT> + HeadlessArrayOf<UINT16> inputX; /* Array of input values (start with * second glyph) */ - ArrayOf<USHORT> + ArrayOf<UINT16> lookaheadX; /* Array of lookahead values's (to be * matched after the input sequence) */ ArrayOf<LookupRecord> @@ -1807,7 +1854,7 @@ struct ChainContextFormat1 struct ChainContextClosureLookupContext lookup_context = { {intersects_glyph}, - {NULL, NULL, NULL} + {nullptr, nullptr, nullptr} }; unsigned int count = ruleSet.len; @@ -1825,7 +1872,7 @@ struct ChainContextFormat1 struct ChainContextCollectGlyphsLookupContext lookup_context = { {collect_glyph}, - {NULL, NULL, NULL} + {nullptr, nullptr, nullptr} }; unsigned int count = ruleSet.len; @@ -1840,7 +1887,7 @@ struct ChainContextFormat1 const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])]; struct ChainContextApplyLookupContext lookup_context = { {match_glyph}, - {NULL, NULL, NULL} + {nullptr, nullptr, nullptr} }; return_trace (rule_set.would_apply (c, lookup_context)); } @@ -1859,7 +1906,7 @@ struct ChainContextFormat1 const ChainRuleSet &rule_set = this+ruleSet[index]; struct ChainContextApplyLookupContext lookup_context = { {match_glyph}, - {NULL, NULL, NULL} + {nullptr, nullptr, nullptr} }; return_trace (rule_set.apply (c, lookup_context)); } @@ -1871,7 +1918,7 @@ struct ChainContextFormat1 } protected: - USHORT format; /* Format identifier--format = 1 */ + UINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ @@ -1986,7 +2033,7 @@ struct ChainContextFormat2 } protected: - USHORT format; /* Format identifier--format = 2 */ + UINT16 format; /* Format identifier--format = 2 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ @@ -2026,9 +2073,9 @@ struct ChainContextFormat3 {this, this, this} }; chain_context_closure_lookup (c, - backtrack.len, (const USHORT *) backtrack.array, - input.len, (const USHORT *) input.array + 1, - lookahead.len, (const USHORT *) lookahead.array, + backtrack.len, (const UINT16 *) backtrack.array, + input.len, (const UINT16 *) input.array + 1, + lookahead.len, (const UINT16 *) lookahead.array, lookup.len, lookup.array, lookup_context); } @@ -2047,9 +2094,9 @@ struct ChainContextFormat3 {this, this, this} }; chain_context_collect_glyphs_lookup (c, - backtrack.len, (const USHORT *) backtrack.array, - input.len, (const USHORT *) input.array + 1, - lookahead.len, (const USHORT *) lookahead.array, + backtrack.len, (const UINT16 *) backtrack.array, + input.len, (const UINT16 *) input.array + 1, + lookahead.len, (const UINT16 *) lookahead.array, lookup.len, lookup.array, lookup_context); } @@ -2066,9 +2113,9 @@ struct ChainContextFormat3 {this, this, this} }; return_trace (chain_context_would_apply_lookup (c, - backtrack.len, (const USHORT *) backtrack.array, - input.len, (const USHORT *) input.array + 1, - lookahead.len, (const USHORT *) lookahead.array, + backtrack.len, (const UINT16 *) backtrack.array, + input.len, (const UINT16 *) input.array + 1, + lookahead.len, (const UINT16 *) lookahead.array, lookup.len, lookup.array, lookup_context)); } @@ -2093,9 +2140,9 @@ struct ChainContextFormat3 {this, this, this} }; return_trace (chain_context_apply_lookup (c, - backtrack.len, (const USHORT *) backtrack.array, - input.len, (const USHORT *) input.array + 1, - lookahead.len, (const USHORT *) lookahead.array, + backtrack.len, (const UINT16 *) backtrack.array, + input.len, (const UINT16 *) input.array + 1, + lookahead.len, (const UINT16 *) lookahead.array, lookup.len, lookup.array, lookup_context)); } @@ -2113,7 +2160,7 @@ struct ChainContextFormat3 } protected: - USHORT format; /* Format identifier--format = 3 */ + UINT16 format; /* Format identifier--format = 3 */ OffsetArrayOf<Coverage> backtrack; /* Array of coverage tables * in backtracking sequence, in glyph @@ -2150,7 +2197,7 @@ struct ChainContext protected: union { - USHORT format; /* Format identifier */ + UINT16 format; /* Format identifier */ ChainContextFormat1 format1; ChainContextFormat2 format2; ChainContextFormat3 format3; @@ -2187,11 +2234,11 @@ struct ExtensionFormat1 } protected: - USHORT format; /* Format identifier. Set to 1. */ - USHORT extensionLookupType; /* Lookup type of subtable referenced + UINT16 format; /* Format identifier. Set to 1. */ + UINT16 extensionLookupType; /* Lookup type of subtable referenced * by ExtensionOffset (i.e. the * extension subtable). */ - ULONG extensionOffset; /* Offset to the extension subtable, + UINT32 extensionOffset; /* Offset to the extension subtable, * of lookup type subtable. */ public: DEFINE_SIZE_STATIC (8); @@ -2229,7 +2276,7 @@ struct Extension protected: union { - USHORT format; /* Format identifier */ + UINT16 format; /* Format identifier */ ExtensionFormat1<T> format1; } u; }; @@ -2241,9 +2288,6 @@ struct Extension struct GSUBGPOS { - static const hb_tag_t GSUBTag = HB_OT_TAG_GSUB; - static const hb_tag_t GPOSTag = HB_OT_TAG_GPOS; - inline unsigned int get_script_count (void) const { return (this+scriptList).len; } inline const Tag& get_script_tag (unsigned int i) const @@ -2313,7 +2357,7 @@ struct GSUBGPOS featureList; /* FeatureList table */ OffsetTo<LookupList> lookupList; /* LookupList table */ - OffsetTo<FeatureVariations, ULONG> + LOffsetTo<FeatureVariations> featureVars; /* Offset to Feature Variations table--from beginning of table * (may be NULL). Introduced |