From bbb4db90dd2f24b237c3bbcf6ab24389f970d1b8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 21 Jul 2022 12:34:46 -0600 Subject: [PATCH] [Coverage/SingleSubst] Move hand-written loop to Coverage --- src/OT/Layout/Common/CoverageFormat2.hh | 35 +++++++++++++++++++---- src/OT/Layout/GSUB/SingleSubstFormat1.hh | 36 ++++-------------------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/OT/Layout/Common/CoverageFormat2.hh b/src/OT/Layout/Common/CoverageFormat2.hh index 675a552cd..7548f0b47 100644 --- a/src/OT/Layout/Common/CoverageFormat2.hh +++ b/src/OT/Layout/Common/CoverageFormat2.hh @@ -142,12 +142,37 @@ struct CoverageFormat2_4 hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))> void intersect_set (const hb_set_t &glyphs, IterableOut &intersect_glyphs) const { - for (const auto& range : rangeRecord) + /* Why the second branch is >2x faster I have no idea, but it seems to be. */ + if (0) { - hb_codepoint_t last = range.last; - for (hb_codepoint_t g = range.first - 1; - glyphs.next (&g) && g <= last;) - intersect_glyphs << g; + for (const auto& range : rangeRecord) + { + hb_codepoint_t last = range.last; + for (hb_codepoint_t g = range.first - 1; + glyphs.next (&g) && g <= last;) + intersect_glyphs << g; + } + } + else + { + iter_t c_iter; + c_iter.init (*this); + auto s_iter = hb_iter (glyphs); + while (c_iter.__more__ () && s_iter) + { + hb_codepoint_t cv = c_iter.get_glyph (); + hb_codepoint_t sv = *s_iter; + if (cv == sv) + { + intersect_glyphs << cv; + c_iter.__next__ (); + s_iter++; + } + else if (cv < sv) + c_iter.__next__ (); + else + s_iter++; + } } } diff --git a/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/src/OT/Layout/GSUB/SingleSubstFormat1.hh index f47e03d3b..dd4459574 100644 --- a/src/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/src/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -42,37 +42,13 @@ struct SingleSubstFormat1_3 hb_codepoint_t d = deltaGlyphID; hb_codepoint_t mask = get_mask (); - if (1) - { - /* Somehow this branch is much faster. Can't understand why. */ - auto c_iter = hb_iter (this+coverage); - auto s_iter = hb_iter (c->parent_active_glyphs ()); - while (c_iter && s_iter) - { - hb_codepoint_t cv = *c_iter; - hb_codepoint_t sv = *s_iter; - if (cv == sv) - { - c->output->add ((cv + d) & mask); - c_iter++; - s_iter++; - } - else if (cv < sv) - c_iter++; - else - s_iter++; - } - } - else - { - hb_set_t intersection; - (this+coverage).intersect_set (c->parent_active_glyphs (), intersection); + hb_set_t intersection; + (this+coverage).intersect_set (c->parent_active_glyphs (), intersection); - + hb_iter (intersection) - | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; }) - | hb_sink (c->output) - ; - } + + hb_iter (intersection) + | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; }) + | hb_sink (c->output) + ; } void closure_lookups (hb_closure_lookups_context_t *c) const {}