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 | 91 |
1 files changed, 67 insertions, 24 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 230b3b6851..fd75c5425a 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 @@ -74,7 +74,7 @@ struct hb_closure_context_t : hb_closure_context_t (hb_face_t *face_, hb_set_t *glyphs_, - unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : + unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), glyphs (glyphs_), recurse_func (NULL), @@ -196,7 +196,7 @@ struct hb_collect_glyphs_context_t : 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 */ - unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : + 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 ()), @@ -319,7 +319,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 (&info) && + if (unlikely (_hb_glyph_info_is_default_ignorable_and_not_fvs (&info) && (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && (ignore_zwj || !_hb_glyph_info_is_zwj (&info)))) return SKIP_MAYBE; @@ -469,6 +469,7 @@ struct hb_apply_context_t : unsigned int lookup_props; const GDEF &gdef; bool has_glyph_classes; + const VariationStore &var_store; skipping_iterator_t iter_input, iter_context; unsigned int lookup_index; unsigned int debug_depth; @@ -483,10 +484,11 @@ struct hb_apply_context_t : lookup_mask (1), auto_zwj (true), recurse_func (NULL), - nesting_level_left (MAX_NESTING_LEVEL), + nesting_level_left (HB_MAX_NESTING_LEVEL), lookup_props (0), 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 (), lookup_index ((unsigned int) -1), @@ -704,13 +706,13 @@ static inline bool match_input (hb_apply_context_t *c, match_func_t match_func, const void *match_data, unsigned int *end_offset, - unsigned int match_positions[MAX_CONTEXT_LENGTH], + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], bool *p_is_mark_ligature = NULL, unsigned int *p_total_component_count = NULL) { TRACE_APPLY (NULL); - if (unlikely (count > MAX_CONTEXT_LENGTH)) return_trace (false); + if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false); hb_buffer_t *buffer = c->buffer; @@ -784,7 +786,7 @@ static inline bool match_input (hb_apply_context_t *c, } static inline bool ligate_input (hb_apply_context_t *c, unsigned int count, /* Including the first glyph */ - unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ unsigned int match_length, hb_codepoint_t lig_glyph, bool is_mark_ligature, @@ -836,19 +838,21 @@ static inline bool ligate_input (hb_apply_context_t *c, if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) { _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER); - _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0); } } c->replace_glyph_with_ligature (lig_glyph, klass); for (unsigned int i = 1; i < count; i++) { - while (buffer->idx < match_positions[i]) + while (buffer->idx < match_positions[i] && !buffer->in_error) { if (!is_mark_ligature) { + unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); + if (this_comp == 0) + this_comp = last_num_components; unsigned int new_lig_comp = components_so_far - last_num_components + - MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->cur()), 1u), last_num_components); - _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); + MIN (this_comp, last_num_components); + _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); } buffer->next_glyph (); } @@ -865,8 +869,11 @@ static inline bool ligate_input (hb_apply_context_t *c, /* Re-adjust components for any marks following. */ for (unsigned int i = buffer->idx; i < buffer->len; i++) { if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) { + unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]); + if (!this_comp) + break; unsigned int new_lig_comp = components_so_far - last_num_components + - MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->info[i]), 1u), last_num_components); + MIN (this_comp, last_num_components); _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); } else break; @@ -944,7 +951,7 @@ static inline void recurse_lookups (context_t *c, static inline bool apply_lookup (hb_apply_context_t *c, unsigned int count, /* Including the first glyph */ - unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ unsigned int match_length) @@ -966,12 +973,17 @@ static inline bool apply_lookup (hb_apply_context_t *c, match_positions[j] += delta; } - for (unsigned int i = 0; i < lookupCount; i++) + for (unsigned int i = 0; i < lookupCount && !buffer->in_error; i++) { unsigned int idx = lookupRecord[i].sequenceIndex; if (idx >= count) continue; + /* Don't recurse to ourself at same position. + * Note that this test is too naive, it doesn't catch longer loops. */ + if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index) + continue; + buffer->move_to (match_positions[idx]); unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); @@ -986,16 +998,23 @@ static inline bool apply_lookup (hb_apply_context_t *c, /* Recursed lookup changed buffer len. Adjust. */ - /* end can't go back past the current match position. - * Note: this is only true because we do NOT allow MultipleSubst - * with zero sequence len. */ - end = MAX ((int) match_positions[idx] + 1, int (end) + delta); + end = int (end) + delta; + if (end <= 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. + * Just never rewind end back and get out of here. + * https://bugs.chromium.org/p/chromium/issues/detail?id=659496 */ + end = match_positions[idx]; + /* There can't be any further changes. */ + break; + } unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */ if (delta > 0) { - if (unlikely (delta + count > MAX_CONTEXT_LENGTH)) + if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH)) break; } else @@ -1094,7 +1113,7 @@ static inline bool context_apply_lookup (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) { unsigned int match_length = 0; - unsigned int match_positions[MAX_CONTEXT_LENGTH]; + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; return match_input (c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data, @@ -1621,7 +1640,7 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) { unsigned int match_length = 0; - unsigned int match_positions[MAX_CONTEXT_LENGTH]; + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; return match_input (c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data[1], @@ -2256,6 +2275,24 @@ struct GSUBGPOS inline const Lookup& get_lookup (unsigned int i) const { return (this+lookupList)[i]; } + inline bool find_variations_index (const int *coords, unsigned int num_coords, + unsigned int *index) const + { return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations)) + .find_index (coords, num_coords, index); } + inline const Feature& get_feature_variation (unsigned int feature_index, + unsigned int variations_index) const + { + if (FeatureVariations::NOT_FOUND_INDEX != variations_index && + version.to_int () >= 0x00010001u) + { + const Feature *feature = (this+featureVars).find_substitute (variations_index, + feature_index); + if (feature) + return *feature; + } + return get_feature (feature_index); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -2263,11 +2300,12 @@ struct GSUBGPOS likely (version.major == 1) && scriptList.sanitize (c, this) && featureList.sanitize (c, this) && - lookupList.sanitize (c, this)); + lookupList.sanitize (c, this) && + (version.to_int () < 0x00010001u || featureVars.sanitize (c, this))); } protected: - FixedVersion version; /* Version of the GSUB/GPOS table--initially set + FixedVersion<>version; /* Version of the GSUB/GPOS table--initially set * to 0x00010000u */ OffsetTo<ScriptList> scriptList; /* ScriptList table */ @@ -2275,8 +2313,13 @@ struct GSUBGPOS featureList; /* FeatureList table */ OffsetTo<LookupList> lookupList; /* LookupList table */ + OffsetTo<FeatureVariations, ULONG> + featureVars; /* Offset to Feature Variations + table--from beginning of table + * (may be NULL). Introduced + * in version 0x00010001. */ public: - DEFINE_SIZE_STATIC (10); + DEFINE_SIZE_MIN (10); }; |