From d109947672f1c32bef0f1953663ce5f990e34ec6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 4 Feb 2025 17:12:23 +0000 Subject: [PATCH 1/7] Revert "[aat] Remove unused macro" This reverts commit 2ddcccd26ea4962a97ba6858952a5a71d032e6c1. --- src/hb-aat-layout-common.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 9081de7dd..0b7ab48ff 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -40,6 +40,8 @@ namespace AAT { using namespace OT; +#define HB_AAT_BUFFER_DIGEST_THRESHOLD 32 + struct ankr; using hb_aat_class_cache_t = hb_cache_t<15, 8, 7>; From 7d23e642a2cb271ff67664a53fd4b518be06830f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 4 Feb 2025 17:11:13 +0000 Subject: [PATCH 2/7] Revert "[aat] Remove dead code" This reverts commit bf36f5c3a4ff0003d330e2c2fc410c0cde911cba. --- src/hb-aat-layout-common.hh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 0b7ab48ff..6f8aae773 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -935,6 +935,14 @@ struct StateTableDriver machine (machine_), num_glyphs (face_->get_num_glyphs ()) {} + template + bool is_idempotent_on_all_out_of_bounds (context_t *c, hb_aat_apply_context_t *ac) + { + const auto entry = machine.get_entry (StateTableT::STATE_START_OF_TEXT, CLASS_OUT_OF_BOUNDS); + return !c->is_actionable (ac->buffer, this, entry) && + machine.new_state (entry.newState) == StateTableT::STATE_START_OF_TEXT; + } + template void drive (context_t *c, hb_aat_apply_context_t *ac) { From 359d163d25bbaa97b9a8d9647598b949e9ad789d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 4 Feb 2025 17:11:46 +0000 Subject: [PATCH 3/7] Revert "[aat] Remove buffer-digest stuff" This reverts commit 7642366593826c0e04ad58df83fa63ec53960486. --- src/hb-aat-layout-common.hh | 1 + src/hb-aat-layout-kerx-table.hh | 5 +++++ src/hb-aat-layout-morx-table.hh | 10 ++++++++++ 3 files changed, 16 insertions(+) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 6f8aae773..121c25f18 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -65,6 +65,7 @@ struct hb_aat_apply_context_t : const ankr *ankr_table; const OT::GDEF *gdef_table; const hb_sorted_vector_t *range_flags = nullptr; + hb_set_digest_t buffer_digest = hb_set_digest_t::full (); const hb_set_t *left_set = nullptr; const hb_set_t *right_set = nullptr; hb_aat_class_cache_t *machine_class_cache = nullptr; diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index fe8684cbd..72d696212 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -967,6 +967,11 @@ struct KerxTable { c->buffer->unsafe_to_concat (); + if (c->buffer->len < HB_AAT_BUFFER_DIGEST_THRESHOLD) + c->buffer_digest = c->buffer->digest (); + else + c->buffer_digest = hb_set_digest_t::full (); + typedef typename T::SubTable SubTable; bool ret = false; diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 58f9dd921..d05737a89 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -268,6 +268,7 @@ struct ContextualSubtable { buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len)); buffer->info[mark].codepoint = *replacement; + c->buffer_digest.add (*replacement); if (has_glyph_classes) _hb_glyph_info_set_glyph_props (&buffer->info[mark], gdef.get_glyph_props (*replacement)); @@ -297,6 +298,7 @@ struct ContextualSubtable if (replacement) { buffer->info[idx].codepoint = *replacement; + c->buffer_digest.add (*replacement); if (has_glyph_classes) _hb_glyph_info_set_glyph_props (&buffer->info[idx], gdef.get_glyph_props (*replacement)); @@ -657,6 +659,7 @@ struct NoncontextualSubtable if (replacement) { info[i].codepoint = *replacement; + c->buffer_digest.add (*replacement); if (has_glyph_classes) _hb_glyph_info_set_glyph_props (&info[i], gdef.get_glyph_props (*replacement)); @@ -791,6 +794,8 @@ struct InsertionSubtable if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; + for (unsigned int i = 0; i < count; i++) + c->buffer_digest.add (glyphs[i]); ret = true; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); @@ -1368,6 +1373,11 @@ struct mortmorx c->buffer->unsafe_to_concat (); + if (c->buffer->len < HB_AAT_BUFFER_DIGEST_THRESHOLD) + c->buffer_digest = c->buffer->digest (); + else + c->buffer_digest = hb_set_digest_t::full (); + c->set_lookup_index (0); const Chain *chain = &firstChain; unsigned int count = chainCount; From e1cb3b155a219e03fffac1355140a24b6f856cc8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 4 Feb 2025 17:28:29 +0000 Subject: [PATCH 4/7] Revert "[aat] Remove set-digest" This reverts commit 832f199607292a41b4621b87a646c30cddc00124. --- src/hb-aat-layout-common.hh | 3 ++- src/hb-aat-layout-morx-table.hh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 121c25f18..37d919a17 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -68,6 +68,7 @@ struct hb_aat_apply_context_t : hb_set_digest_t buffer_digest = hb_set_digest_t::full (); const hb_set_t *left_set = nullptr; const hb_set_t *right_set = nullptr; + hb_set_digest_t machine_glyph_set = hb_set_digest_t::full (); hb_aat_class_cache_t *machine_class_cache = nullptr; hb_mask_t subtable_flags = 0; @@ -941,7 +942,7 @@ struct StateTableDriver { const auto entry = machine.get_entry (StateTableT::STATE_START_OF_TEXT, CLASS_OUT_OF_BOUNDS); return !c->is_actionable (ac->buffer, this, entry) && - machine.new_state (entry.newState) == StateTableT::STATE_START_OF_TEXT; + machine.new_state (entry.newState) == StateTableT::STATE_START_OF_TEXT; } template diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index d05737a89..1b836944e 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -171,6 +171,10 @@ struct RearrangementSubtable StateTableDriver driver (machine, c->face); + if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && + !c->buffer_digest.may_have (c->machine_glyph_set)) + return_trace (false); + driver.drive (&dc, c); return_trace (dc.ret); @@ -332,6 +336,10 @@ struct ContextualSubtable StateTableDriver driver (machine, c->face); + if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && + !c->buffer_digest.may_have (c->machine_glyph_set)) + return_trace (false); + driver.drive (&dc, c); return_trace (dc.ret); @@ -591,6 +599,10 @@ struct LigatureSubtable StateTableDriver driver (machine, c->face); + if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && + !c->buffer_digest.may_have (c->machine_glyph_set)) + return_trace (false); + driver.drive (&dc, c); return_trace (dc.ret); @@ -863,6 +875,10 @@ struct InsertionSubtable StateTableDriver driver (machine, c->face); + if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && + !c->buffer_digest.may_have (c->machine_glyph_set)) + return_trace (false); + driver.drive (&dc, c); return_trace (dc.ret); @@ -919,11 +935,25 @@ struct hb_accelerate_subtables_context_t : friend struct hb_aat_layout_lookup_accelerator_t; public: + hb_set_digest_t digest; mutable hb_aat_class_cache_t class_cache; + template + auto init_ (const T &obj_, unsigned num_glyphs, hb_priority<1>) HB_AUTO_RETURN + ( + obj_.machine.collect_glyphs (this->digest, num_glyphs) + ) + + template + void init_ (const T &obj_, unsigned num_glyphs, hb_priority<0>) + { + digest = digest.full (); + } + template void init (const T &obj_, unsigned num_glyphs) { + init_ (obj_, num_glyphs, hb_prioritize); class_cache.clear (); } @@ -1143,6 +1173,7 @@ struct Chain hb_map ([subtable_flags] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable_flags & (_.flags); }))) goto skip; c->subtable_flags = subtable_flags; + c->machine_glyph_set = accel ? accel->subtables[i].digest : hb_set_digest_t::full (); c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; if (!(subtable->get_coverage() & ChainSubtable::AllDirections) && From 3a1d7ee7e8471c3a9e59ab74551d99eba93410a9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 4 Feb 2025 17:33:42 +0000 Subject: [PATCH 5/7] [aat] Remove the buffer-digest threshold This can help us skip entire subchains, eg. when they are for different scripts. Speeds up LucidaGrande with ASCII text by 20%. --- src/hb-aat-layout-common.hh | 2 -- src/hb-aat-layout-kerx-table.hh | 5 +---- src/hb-aat-layout-morx-table.hh | 5 +---- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 37d919a17..5db0d1212 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -40,8 +40,6 @@ namespace AAT { using namespace OT; -#define HB_AAT_BUFFER_DIGEST_THRESHOLD 32 - struct ankr; using hb_aat_class_cache_t = hb_cache_t<15, 8, 7>; diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 72d696212..d5f46c66e 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -967,10 +967,7 @@ struct KerxTable { c->buffer->unsafe_to_concat (); - if (c->buffer->len < HB_AAT_BUFFER_DIGEST_THRESHOLD) - c->buffer_digest = c->buffer->digest (); - else - c->buffer_digest = hb_set_digest_t::full (); + c->buffer_digest = c->buffer->digest (); typedef typename T::SubTable SubTable; diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 1b836944e..65ad91303 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -1404,10 +1404,7 @@ struct mortmorx c->buffer->unsafe_to_concat (); - if (c->buffer->len < HB_AAT_BUFFER_DIGEST_THRESHOLD) - c->buffer_digest = c->buffer->digest (); - else - c->buffer_digest = hb_set_digest_t::full (); + c->buffer_digest = c->buffer->digest (); c->set_lookup_index (0); const Chain *chain = &firstChain; From 449c7f2a0d2db2a5533f2e44c00fec64ec4e012c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 4 Feb 2025 17:56:22 +0000 Subject: [PATCH 6/7] [aat] Add some tracing --- src/hb-aat-layout-morx-table.hh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 65ad91303..8e782ac2b 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -173,7 +173,10 @@ struct RearrangementSubtable if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && !c->buffer_digest.may_have (c->machine_glyph_set)) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); return_trace (false); + } driver.drive (&dc, c); @@ -338,7 +341,10 @@ struct ContextualSubtable if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && !c->buffer_digest.may_have (c->machine_glyph_set)) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); return_trace (false); + } driver.drive (&dc, c); @@ -601,7 +607,10 @@ struct LigatureSubtable if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && !c->buffer_digest.may_have (c->machine_glyph_set)) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); return_trace (false); + } driver.drive (&dc, c); @@ -877,7 +886,10 @@ struct InsertionSubtable if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && !c->buffer_digest.may_have (c->machine_glyph_set)) + { + (void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches"); return_trace (false); + } driver.drive (&dc, c); From 722ab54868145b72db77ced3ed0265f2db19b341 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 4 Feb 2025 17:59:39 +0000 Subject: [PATCH 7/7] [kerx] Don't compute buffer digest We don't use it in kerx --- src/hb-aat-layout-kerx-table.hh | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index d5f46c66e..fe8684cbd 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -967,8 +967,6 @@ struct KerxTable { c->buffer->unsafe_to_concat (); - c->buffer_digest = c->buffer->digest (); - typedef typename T::SubTable SubTable; bool ret = false;