aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2023-05-04 16:28:11 -0600
committerBehdad Esfahbod <behdad@behdad.org>2023-05-04 16:28:11 -0600
commit7a715d74e06720c17d28ba7b4c3da0b583f8d1d3 (patch)
treee8278ee662c0d59c3d2321e2af1d9ac55816d456
parent975980d36867728da42908a9a3c95373a32b3d30 (diff)
downloadharfbuzz_ng-7a715d74e06720c17d28ba7b4c3da0b583f8d1d3.tar.gz
[layout] Cache subtable coverages in hb_map_t
Proof-of-concept. Going to revert. Memory consumption is more than I like. It does speed up Roboto shaping another 15% though. Perhaps if we could add logic to choose which subtables to cache, this might be a useful approach.
-rw-r--r--src/OT/Layout/GPOS/CursivePosFormat1.hh4
-rw-r--r--src/OT/Layout/GPOS/MarkBasePosFormat1.hh5
-rw-r--r--src/OT/Layout/GPOS/MarkLigPosFormat1.hh5
-rw-r--r--src/OT/Layout/GPOS/MarkMarkPosFormat1.hh5
-rw-r--r--src/OT/Layout/GPOS/PairPosFormat1.hh6
-rw-r--r--src/OT/Layout/GPOS/PairPosFormat2.hh4
-rw-r--r--src/OT/Layout/GPOS/PosLookup.hh4
-rw-r--r--src/OT/Layout/GPOS/SinglePosFormat1.hh4
-rw-r--r--src/OT/Layout/GPOS/SinglePosFormat2.hh8
-rw-r--r--src/OT/Layout/GSUB/AlternateSubstFormat1.hh8
-rw-r--r--src/OT/Layout/GSUB/LigatureSubstFormat1.hh8
-rw-r--r--src/OT/Layout/GSUB/MultipleSubstFormat1.hh8
-rw-r--r--src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh9
-rw-r--r--src/OT/Layout/GSUB/SingleSubstFormat1.hh4
-rw-r--r--src/OT/Layout/GSUB/SingleSubstFormat2.hh8
-rw-r--r--src/OT/Layout/GSUB/SubstLookup.hh4
-rw-r--r--src/hb-ot-layout-gsubgpos.hh70
17 files changed, 65 insertions, 99 deletions
diff --git a/src/OT/Layout/GPOS/CursivePosFormat1.hh b/src/OT/Layout/GPOS/CursivePosFormat1.hh
index b8773ba0a..0c97f1dfc 100644
--- a/src/OT/Layout/GPOS/CursivePosFormat1.hh
+++ b/src/OT/Layout/GPOS/CursivePosFormat1.hh
@@ -113,12 +113,12 @@ struct CursivePosFormat1
const Coverage &get_coverage () const { return this+coverage; }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
- const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)];
+ const EntryExitRecord &this_record = entryExitRecord[coverage_index];
if (!this_record.entryAnchor) return_trace (false);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
diff --git a/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
index eb4712049..c48875d8a 100644
--- a/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
+++ b/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
@@ -109,12 +109,11 @@ struct MarkBasePosFormat1_2
);
}
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
- unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
- if (likely (mark_index == NOT_COVERED)) return_trace (false);
+ unsigned int mark_index = coverage_index;
/* Now we search backwards for a non-mark glyph.
* We don't use skippy_iter.prev() to avoid O(n^2) behavior. */
diff --git a/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
index 92e83a0e9..899000484 100644
--- a/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
+++ b/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
@@ -92,12 +92,11 @@ struct MarkLigPosFormat1_2
const Coverage &get_coverage () const { return this+markCoverage; }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
- unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
- if (likely (mark_index == NOT_COVERED)) return_trace (false);
+ unsigned int mark_index = coverage_index;
/* Now we search backwards for a non-mark glyph */
diff --git a/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
index 9dae5ce5d..ecdfb71e4 100644
--- a/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
+++ b/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
@@ -91,12 +91,11 @@ struct MarkMarkPosFormat1_2
const Coverage &get_coverage () const { return this+mark1Coverage; }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
- unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint);
- if (likely (mark1_index == NOT_COVERED)) return_trace (false);
+ unsigned int mark1_index = coverage_index;
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
diff --git a/src/OT/Layout/GPOS/PairPosFormat1.hh b/src/OT/Layout/GPOS/PairPosFormat1.hh
index 714b4bec7..60d0135ec 100644
--- a/src/OT/Layout/GPOS/PairPosFormat1.hh
+++ b/src/OT/Layout/GPOS/PairPosFormat1.hh
@@ -102,12 +102,10 @@ struct PairPosFormat1_3
const Coverage &get_coverage () const { return this+coverage; }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset_fast (buffer->idx, 1);
@@ -118,7 +116,7 @@ struct PairPosFormat1_3
return_trace (false);
}
- return_trace ((this+pairSet[index]).apply (c, valueFormat, skippy_iter.idx));
+ return_trace ((this+pairSet[coverage_index]).apply (c, valueFormat, skippy_iter.idx));
}
bool subset (hb_subset_context_t *c) const
diff --git a/src/OT/Layout/GPOS/PairPosFormat2.hh b/src/OT/Layout/GPOS/PairPosFormat2.hh
index 31329dfcb..76f5309fe 100644
--- a/src/OT/Layout/GPOS/PairPosFormat2.hh
+++ b/src/OT/Layout/GPOS/PairPosFormat2.hh
@@ -122,12 +122,10 @@ struct PairPosFormat2_4
const Coverage &get_coverage () const { return this+coverage; }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset_fast (buffer->idx, 1);
diff --git a/src/OT/Layout/GPOS/PosLookup.hh b/src/OT/Layout/GPOS/PosLookup.hh
index c4e57bb54..4aef08075 100644
--- a/src/OT/Layout/GPOS/PosLookup.hh
+++ b/src/OT/Layout/GPOS/PosLookup.hh
@@ -20,10 +20,10 @@ struct PosLookup : Lookup
return false;
}
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
- return_trace (dispatch (c));
+ return_trace (dispatch (c, coverage_index));
}
bool intersects (const hb_set_t *glyphs) const
diff --git a/src/OT/Layout/GPOS/SinglePosFormat1.hh b/src/OT/Layout/GPOS/SinglePosFormat1.hh
index 623e4e66b..5c3e105eb 100644
--- a/src/OT/Layout/GPOS/SinglePosFormat1.hh
+++ b/src/OT/Layout/GPOS/SinglePosFormat1.hh
@@ -61,12 +61,10 @@ struct SinglePosFormat1
ValueFormat get_value_format () const { return valueFormat; }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
{
diff --git a/src/OT/Layout/GPOS/SinglePosFormat2.hh b/src/OT/Layout/GPOS/SinglePosFormat2.hh
index e8f2d7c2c..3b82b9b05 100644
--- a/src/OT/Layout/GPOS/SinglePosFormat2.hh
+++ b/src/OT/Layout/GPOS/SinglePosFormat2.hh
@@ -61,14 +61,12 @@ struct SinglePosFormat2
ValueFormat get_value_format () const { return valueFormat; }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
- if (unlikely (index >= valueCount)) return_trace (false);
+ if (unlikely (coverage_index >= valueCount)) return_trace (false);
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
{
@@ -78,7 +76,7 @@ struct SinglePosFormat2
}
valueFormat.apply_value (c, this,
- &values[index * valueFormat.get_len ()],
+ &values[coverage_index * valueFormat.get_len ()],
buffer->cur_pos());
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
diff --git a/src/OT/Layout/GSUB/AlternateSubstFormat1.hh b/src/OT/Layout/GSUB/AlternateSubstFormat1.hh
index adec65d58..94d123244 100644
--- a/src/OT/Layout/GSUB/AlternateSubstFormat1.hh
+++ b/src/OT/Layout/GSUB/AlternateSubstFormat1.hh
@@ -69,14 +69,10 @@ struct AlternateSubstFormat1_2
{ return (this+alternateSet[(this+coverage).get_coverage (gid)])
.get_alternates (start_offset, alternate_count, alternate_glyphs); }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
-
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- return_trace ((this+alternateSet[index]).apply (c));
+ return_trace ((this+alternateSet[coverage_index]).apply (c));
}
bool serialize (hb_serialize_context_t *c,
diff --git a/src/OT/Layout/GSUB/LigatureSubstFormat1.hh b/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
index 5c7df97d1..a36212fe6 100644
--- a/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
+++ b/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
@@ -78,14 +78,10 @@ struct LigatureSubstFormat1_2
return lig_set.would_apply (c);
}
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
-
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- const auto &lig_set = this+ligatureSet[index];
+ const auto &lig_set = this+ligatureSet[coverage_index];
return_trace (lig_set.apply (c));
}
diff --git a/src/OT/Layout/GSUB/MultipleSubstFormat1.hh b/src/OT/Layout/GSUB/MultipleSubstFormat1.hh
index 3b4bd1169..0c4eff367 100644
--- a/src/OT/Layout/GSUB/MultipleSubstFormat1.hh
+++ b/src/OT/Layout/GSUB/MultipleSubstFormat1.hh
@@ -61,14 +61,10 @@ struct MultipleSubstFormat1_2
bool would_apply (hb_would_apply_context_t *c) const
{ return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
-
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- return_trace ((this+sequence[index]).apply (c));
+ return_trace ((this+sequence[coverage_index]).apply (c));
}
template<typename Iterator,
diff --git a/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
index 2c2e1aa44..f07ed0333 100644
--- a/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
+++ b/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
@@ -106,19 +106,16 @@ struct ReverseChainSingleSubstFormat1
bool would_apply (hb_would_apply_context_t *c) const
{ return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL))
return_trace (false); /* No chaining to this type */
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
- if (unlikely (index >= substitute.len)) return_trace (false);
+ if (unlikely (coverage_index >= substitute.len)) return_trace (false);
unsigned int start_index = 0, end_index = 0;
if (match_backtrack (c,
@@ -139,7 +136,7 @@ struct ReverseChainSingleSubstFormat1
c->buffer->idx);
}
- c->replace_glyph_inplace (substitute[index]);
+ c->replace_glyph_inplace (substitute[coverage_index]);
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
{
diff --git a/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/src/OT/Layout/GSUB/SingleSubstFormat1.hh
index 850be86c0..622f8dce1 100644
--- a/src/OT/Layout/GSUB/SingleSubstFormat1.hh
+++ b/src/OT/Layout/GSUB/SingleSubstFormat1.hh
@@ -123,12 +123,10 @@ struct SingleSubstFormat1_3
return 1;
}
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
- unsigned int index = (this+coverage).get_coverage (glyph_id);
- if (likely (index == NOT_COVERED)) return_trace (false);
hb_codepoint_t d = deltaGlyphID;
hb_codepoint_t mask = get_mask ();
diff --git a/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/src/OT/Layout/GSUB/SingleSubstFormat2.hh
index 9c651abe7..2429d9d5b 100644
--- a/src/OT/Layout/GSUB/SingleSubstFormat2.hh
+++ b/src/OT/Layout/GSUB/SingleSubstFormat2.hh
@@ -100,13 +100,11 @@ struct SingleSubstFormat2_4
return 1;
}
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
- if (unlikely (index >= substitute.len)) return_trace (false);
+ if (unlikely (coverage_index >= substitute.len)) return_trace (false);
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
{
@@ -116,7 +114,7 @@ struct SingleSubstFormat2_4
c->buffer->idx);
}
- c->replace_glyph (substitute[index]);
+ c->replace_glyph (substitute[coverage_index]);
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
{
diff --git a/src/OT/Layout/GSUB/SubstLookup.hh b/src/OT/Layout/GSUB/SubstLookup.hh
index d49dcc0e0..75d969756 100644
--- a/src/OT/Layout/GSUB/SubstLookup.hh
+++ b/src/OT/Layout/GSUB/SubstLookup.hh
@@ -35,10 +35,10 @@ struct SubstLookup : Lookup
return dispatch (&c);
}
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
- return_trace (dispatch (c));
+ return_trace (dispatch (c, coverage_index));
}
bool intersects (const hb_set_t *glyphs) const
diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh
index 8e5be92d1..4ddd802da 100644
--- a/src/hb-ot-layout-gsubgpos.hh
+++ b/src/hb-ot-layout-gsubgpos.hh
@@ -680,7 +680,7 @@ struct hb_ot_apply_context_t :
const char *get_name () { return "APPLY"; }
typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index);
template <typename T>
- return_t dispatch (const T &obj) { return obj.apply (this); }
+ return_t dispatch (const T &obj, unsigned coverage_index) { return obj.apply (this, coverage_index); }
static return_t default_return_value () { return false; }
bool stop_sublookup_iteration (return_t r) const { return r; }
return_t recurse (unsigned int sub_lookup_index)
@@ -893,22 +893,24 @@ struct hb_accelerate_subtables_context_t :
hb_dispatch_context_t<hb_accelerate_subtables_context_t>
{
template <typename Type>
- static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c)
+ static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c, unsigned coverage_index)
{
const Type *typed_obj = (const Type *) obj;
- return typed_obj->apply (c);
+ return typed_obj->apply (c, coverage_index);
}
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
template <typename T>
- static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply_cached (c) )
+ static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, unsigned coverage_index, hb_priority<1>)
+ HB_RETURN (bool, obj->apply_cached (c, coverage_index) )
template <typename T>
- static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
+ static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, unsigned coverage_index, hb_priority<0>)
+ HB_RETURN (bool, obj->apply (c, coverage_index) )
template <typename Type>
- static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c)
+ static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c, unsigned coverage_index)
{
const Type *typed_obj = (const Type *) obj;
- return apply_cached_ (typed_obj, c, hb_prioritize);
+ return apply_cached_ (typed_obj, c, coverage_index, hb_prioritize);
}
template <typename T>
@@ -923,7 +925,7 @@ struct hb_accelerate_subtables_context_t :
}
#endif
- typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c);
+ typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c, unsigned coverage_index);
typedef bool (*hb_cache_func_t) (const void *obj, hb_ot_apply_context_t *c, bool enter);
struct hb_applicable_t
@@ -948,16 +950,22 @@ struct hb_accelerate_subtables_context_t :
#endif
digest.init ();
obj_.get_coverage ().collect_coverage (&digest);
+ coverage_map.init ();
+ auto &coverage = obj_.get_coverage ();
+ for (hb_codepoint_t g : hb_iter (coverage))
+ coverage_map.set (g, coverage.get_coverage (g));
}
bool apply (hb_ot_apply_context_t *c) const
{
- return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c);
+ unsigned *v;
+ return coverage_map.has (c->buffer->cur().codepoint, &v) && apply_func (obj, c, *v);
}
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
bool apply_cached (hb_ot_apply_context_t *c) const
{
- return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c);
+ unsigned *v;
+ return coverage_map.has (c->buffer->cur().codepoint, &v) && apply_cached_func (obj, c, *v);
}
bool cache_enter (hb_ot_apply_context_t *c) const
{
@@ -977,6 +985,7 @@ struct hb_accelerate_subtables_context_t :
hb_cache_func_t cache_func;
#endif
hb_set_digest_t digest;
+ hb_map_t coverage_map;
};
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
@@ -2233,14 +2242,11 @@ struct ContextFormat1_4
const Coverage &get_coverage () const { return this+coverage; }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED))
- return_trace (false);
- const RuleSet &rule_set = this+ruleSet[index];
+ const RuleSet &rule_set = this+ruleSet[coverage_index];
struct ContextApplyLookupContext lookup_context = {
{match_glyph},
nullptr
@@ -2451,13 +2457,11 @@ struct ContextFormat2_5
}
}
- bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
- bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
- bool _apply (hb_ot_apply_context_t *c, bool cached) const
+ bool apply_cached (hb_ot_apply_context_t *c, unsigned coverage_index) const { return _apply (c, coverage_index, true); }
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const { return _apply (c, coverage_index, false); }
+ bool _apply (hb_ot_apply_context_t *c, unsigned coverage_index, bool cached) const
{
TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
const ClassDef &class_def = this+classDef;
@@ -2466,6 +2470,7 @@ struct ContextFormat2_5
&class_def
};
+ unsigned index;
if (cached && c->buffer->cur().syllable() < 255)
index = c->buffer->cur().syllable ();
else
@@ -2643,11 +2648,9 @@ struct ContextFormat3
const Coverage &get_coverage () const { return this+coverageZ[0]; }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
- unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
struct ContextApplyLookupContext lookup_context = {
@@ -3317,13 +3320,11 @@ struct ChainContextFormat1_4
const Coverage &get_coverage () const { return this+coverage; }
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
- const ChainRuleSet &rule_set = this+ruleSet[index];
+ const ChainRuleSet &rule_set = this+ruleSet[coverage_index];
struct ChainContextApplyLookupContext lookup_context = {
{{match_glyph, match_glyph, match_glyph}},
{nullptr, nullptr, nullptr}
@@ -3556,13 +3557,11 @@ struct ChainContextFormat2_5
}
}
- bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
- bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
- bool _apply (hb_ot_apply_context_t *c, bool cached) const
+ bool apply_cached (hb_ot_apply_context_t *c, unsigned coverage_index) const { return _apply (c, coverage_index, true); }
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const { return _apply (c, coverage_index, false); }
+ bool _apply (hb_ot_apply_context_t *c, unsigned coverage_index, bool cached) const
{
TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
const ClassDef &backtrack_class_def = this+backtrackClassDef;
const ClassDef &input_class_def = this+inputClassDef;
@@ -3587,7 +3586,7 @@ struct ChainContextFormat2_5
&lookahead_class_def}
};
- index = input_class_def.get_class (c->buffer->cur().codepoint);
+ unsigned index = input_class_def.get_class (c->buffer->cur().codepoint);
const ChainRuleSet &rule_set = this+ruleSet[index];
return_trace (rule_set.apply (c, lookup_context));
}
@@ -3805,14 +3804,11 @@ struct ChainContextFormat3
return this+input[0];
}
- bool apply (hb_ot_apply_context_t *c) const
+ bool apply (hb_ot_apply_context_t *c, unsigned coverage_index) const
{
TRACE_APPLY (this);
const auto &input = StructAfter<decltype (inputX)> (backtrack);
- unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
struct ChainContextApplyLookupContext lookup_context = {