From 5a405b310e617c1ee87491401c98f70dff2e2a51 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2024 10:03:47 -0600 Subject: [PATCH] [aat] First sketch at using hb_set_digest_t They are not cached in an accelerator yet. --- src/hb-aat-layout-common.hh | 100 ++++++++++++++++++++++++++++++-- src/hb-aat-layout-kerx-table.hh | 25 +++++++- 2 files changed, 118 insertions(+), 7 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 3b8e5ddec..916a812b5 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -95,6 +95,13 @@ struct LookupFormat0 return &arrayZ[glyph_id]; } + template + void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const + { + for (unsigned int i = 0; i < num_glyphs; i++) + glyphs.add (i); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -123,6 +130,12 @@ struct LookupSegmentSingle int cmp (hb_codepoint_t g) const { return g < first ? -1 : g <= last ? 0 : +1 ; } + template + void collect_glyphs (set_t &glyphs) const + { + glyphs.add_range (first, last); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -153,6 +166,14 @@ struct LookupFormat2 return v ? &v->value : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + unsigned count = segments.get_length (); + for (unsigned int i = 0; i < count; i++) + segments[i].collect_glyphs (glyphs); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -184,6 +205,12 @@ struct LookupSegmentArray return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + glyphs.add_range (first, last); + } + int cmp (hb_codepoint_t g) const { return g < first ? -1 : g <= last ? 0 : +1; } @@ -226,6 +253,14 @@ struct LookupFormat4 return v ? v->get_value (glyph_id, this) : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + unsigned count = segments.get_length (); + for (unsigned i = 0; i < count; i++) + segments[i].collect_glyphs (glyphs); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -254,6 +289,12 @@ struct LookupSingle int cmp (hb_codepoint_t g) const { return glyph.cmp (g); } + template + void collect_glyphs (set_t &glyphs) const + { + glyphs.add (glyph); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -283,6 +324,14 @@ struct LookupFormat6 return v ? &v->value : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + unsigned count = entries.get_length (); + for (unsigned i = 0; i < count; i++) + entries[i].collect_glyphs (glyphs); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -314,6 +363,14 @@ struct LookupFormat8 &valueArrayZ[glyph_id - firstGlyph] : nullptr; } + template + void collect_glyphs (set_t &glyphs) const + { + if (unlikely (!glyphCount)) + return; + glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -406,6 +463,19 @@ struct Lookup } } + template + void collect_glyphs (set_t &glyphs, unsigned int num_glyphs) const + { + switch (u.format) { + case 0: u.format0.collect_glyphs (glyphs, num_glyphs); return; + case 2: u.format2.collect_glyphs (glyphs); return; + case 4: u.format4.collect_glyphs (glyphs); return; + case 6: u.format6.collect_glyphs (glyphs); return; + case 8: u.format8.collect_glyphs (glyphs); return; + default:return; + } + } + typename T::type get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs, unsigned int outOfRange) const @@ -535,9 +605,19 @@ struct StateTable int new_state (unsigned int newState) const { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; } - unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + template + void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const + { + (this+classTable).collect_glyphs (glyphs, num_glyphs); + } + + template + unsigned int get_class (hb_codepoint_t glyph_id, + unsigned int num_glyphs, + const set_t &glyphs) const { if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH; + if (!glyphs[glyph_id]) return CLASS_OUT_OF_BOUNDS; return (this+classTable).get_class (glyph_id, num_glyphs, 1); } @@ -690,6 +770,14 @@ struct ClassTable { return get_class (glyph_id, outOfRange); } + + template + void collect_glyphs (set_t &glyphs, HB_UNUSED unsigned num_glyphs) const + { + for (unsigned int i = 0; i < classArray.len; i++) + glyphs.add (i + firstGlyph); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -815,9 +903,12 @@ struct StateTableDriver hb_face_t *face_) : machine (machine_), buffer (buffer_), - num_glyphs (face_->get_num_glyphs ()) {} + num_glyphs (face_->get_num_glyphs ()) + { + machine.collect_glyphs (glyph_set, num_glyphs); + } - template + template void drive (context_t *c, hb_aat_apply_context_t *ac) { if (!c->in_place) @@ -855,7 +946,7 @@ struct StateTableDriver } unsigned int klass = buffer->idx < buffer->len ? - machine.get_class (buffer->cur().codepoint, num_glyphs) : + machine.get_class (buffer->cur().codepoint, num_glyphs, glyph_set) : (unsigned) StateTableT::CLASS_END_OF_TEXT; DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); const EntryT &entry = machine.get_entry (state, klass); @@ -946,6 +1037,7 @@ struct StateTableDriver const StateTableT &machine; hb_buffer_t *buffer; unsigned int num_glyphs; + hb_set_digest_t glyph_set; }; diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 72480e072..9774d9642 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -30,6 +30,7 @@ #include "hb-kern.hh" #include "hb-aat-layout-ankr-table.hh" +#include "hb-set-digest.hh" /* * kerx -- Extended Kerning @@ -82,7 +83,7 @@ struct KernPair return_trace (c->check_struct (this)); } - protected: + public: HBGlyphID16 left; HBGlyphID16 right; FWORD value; @@ -122,13 +123,31 @@ struct KerxSubTableFormat0 { const KerxSubTableFormat0 &table; hb_aat_apply_context_t *c; + hb_set_digest_t left_set, right_set; + + template + void collect_glyphs (set_t &left, set_t &right) + { + for (const KernPair& pair : table.pairs) + { + left_set.add (pair.left); + right_set.add (pair.right); + } + } accelerator_t (const KerxSubTableFormat0 &table_, hb_aat_apply_context_t *c_) : - table (table_), c (c_) {} + table (table_), c (c_) + { + collect_glyphs (left_set, right_set); + } int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return table.get_kerning (left, right, c); } + { + if (!left_set[left] || !right_set[right]) + return 0; + return table.get_kerning (left, right, c); + } };