diff options
author | Behdad Esfahbod <behdad@behdad.org> | 2023-05-04 16:28:11 -0600 |
---|---|---|
committer | Behdad Esfahbod <behdad@behdad.org> | 2023-05-04 16:28:11 -0600 |
commit | 7a715d74e06720c17d28ba7b4c3da0b583f8d1d3 (patch) | |
tree | e8278ee662c0d59c3d2321e2af1d9ac55816d456 | |
parent | 975980d36867728da42908a9a3c95373a32b3d30 (diff) | |
download | harfbuzz_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.hh | 4 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/MarkBasePosFormat1.hh | 5 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/MarkLigPosFormat1.hh | 5 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/MarkMarkPosFormat1.hh | 5 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/PairPosFormat1.hh | 6 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/PairPosFormat2.hh | 4 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/PosLookup.hh | 4 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/SinglePosFormat1.hh | 4 | ||||
-rw-r--r-- | src/OT/Layout/GPOS/SinglePosFormat2.hh | 8 | ||||
-rw-r--r-- | src/OT/Layout/GSUB/AlternateSubstFormat1.hh | 8 | ||||
-rw-r--r-- | src/OT/Layout/GSUB/LigatureSubstFormat1.hh | 8 | ||||
-rw-r--r-- | src/OT/Layout/GSUB/MultipleSubstFormat1.hh | 8 | ||||
-rw-r--r-- | src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh | 9 | ||||
-rw-r--r-- | src/OT/Layout/GSUB/SingleSubstFormat1.hh | 4 | ||||
-rw-r--r-- | src/OT/Layout/GSUB/SingleSubstFormat2.hh | 8 | ||||
-rw-r--r-- | src/OT/Layout/GSUB/SubstLookup.hh | 4 | ||||
-rw-r--r-- | src/hb-ot-layout-gsubgpos.hh | 70 |
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 = { |