summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
diff options
context:
space:
mode:
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.hh91
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);
};