From ec84460e46fdaa5f8a3c16c8d48dabe2b0c869da Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 9 Oct 2018 15:07:04 -0400 Subject: [PATCH] [ot/ft] Implement get_nominal_glyphs() callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some more measurable speedup. The recent commits' speedups are as follows: Testing with Roboto, ****when disabling kern and liga****: Before: FT --features=-kern,-liga user↦ 0m0.521s OT --features=-liga,-kern user↦ 0m0.568s After: FT --features=-liga,-kern user↦ 0m0.428s OT --features=-liga,-kern user↦ 0m0.470s So, 17% speedup. Note that FT callbacks are faster than OT these days since we added an advance cache to FT. I don't think the difference is enough to justify adding a cache to OT. When not disabling kern, the thing is three times slower, so the speedups are three times less impressive... Still, 5% not bad for a codebase that I otherwise thought is optimized out. Note that, because of this and other optimiztions in our main shaper, disabling kern and liga, the OT shaper is now *faster* than the fallback shaper. So, that's my recommendation to clients that need the absolute fastest... --- src/hb-ft.cc | 26 ++++++++++++++++++++++++++ src/hb-ot-font.cc | 24 ++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 79ce8f49a..d293693cd 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -200,6 +200,31 @@ hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED, return true; } +static unsigned int +hb_ft_get_nominal_glyphs (hb_font_t *font HB_UNUSED, + void *font_data, + unsigned int count, + const hb_codepoint_t *first_unicode, + unsigned int unicode_stride, + hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + void *user_data HB_UNUSED) +{ + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + unsigned int done; + for (done = 0; + done < count && (*first_glyph = FT_Get_Char_Index (ft_font->ft_face, *first_unicode)); + done++) + { + first_unicode = &StructAtOffset (first_unicode, unicode_stride); + first_glyph = &StructAtOffset (first_glyph, glyph_stride); + } + /* We don't need to do ft_font->symbol dance here, since HB calls the singular + * nominal_glyph() for what we don't handle here. */ + return done; +} + + static hb_bool_t hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED, void *font_data, @@ -444,6 +469,7 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_tcmap.get_relaxed()->get_nominal_glyph (unicode, glyph); } +static unsigned int +hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED, + void *font_data, + unsigned int count, + const hb_codepoint_t *first_unicode, + unsigned int unicode_stride, + hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + void *user_data HB_UNUSED) +{ + const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const OT::cmap_accelerator_t &cmap = *ot_face->cmap.get_relaxed (); + unsigned int done; + for (done = 0; + done < count && cmap.get_nominal_glyph (*first_unicode, first_glyph); + done++) + { + first_unicode = &StructAtOffset (first_unicode, unicode_stride); + first_glyph = &StructAtOffset (first_glyph, glyph_stride); + } + return done; +} + static hb_bool_t hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED, void *font_data, @@ -187,6 +210,7 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t