From 54998befc43ef38e47b74b3153380adbcf6279d4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 11 Sep 2018 14:35:26 +0200 Subject: [PATCH] [ft] Cache advances I decided to always use the cache, instead of my previous sketch direction that was to only allocate and use cache if fast advances are not available. The cache is a mere 1kb, so just use it... TODO: Invalidate cache on font size change. Fixes https://github.com/harfbuzz/harfbuzz/issues/651 Fixes https://github.com/harfbuzz/harfbuzz/pull/1082 --- src/hb-cache.hh | 2 +- src/hb-ft.cc | 37 +++++++++++++++++-------------------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/hb-cache.hh b/src/hb-cache.hh index 0858e11bf..f8581b4de 100644 --- a/src/hb-cache.hh +++ b/src/hb-cache.hh @@ -36,7 +36,7 @@ template = cache_bits), ""); - static_assert ((key_bits + value_bits - cache_bits < 8 * sizeof (unsigned int)), ""); + static_assert ((key_bits + value_bits - cache_bits <= 8 * sizeof (unsigned int)), ""); inline void init (void) { clear (); } inline void fini (void) {} diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 856a9f79b..121b7159f 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -69,6 +69,7 @@ struct hb_ft_font_t int load_flags; bool symbol; /* Whether selected cmap is symbol cmap. */ bool unref; /* Whether to destroy ft_face when done. */ + mutable hb_advance_cache_t advance_cache; }; static hb_ft_font_t * @@ -85,6 +86,8 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; + ft_font->advance_cache.init (); + return ft_font; } @@ -99,6 +102,8 @@ _hb_ft_font_destroy (void *data) { hb_ft_font_t *ft_font = (hb_ft_font_t *) data; + ft_font->advance_cache.fini (); + if (ft_font->unref) _hb_ft_face_destroy (ft_font->ft_face); @@ -239,31 +244,23 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; FT_Face ft_face = ft_font->ft_face; - int load_flags; - + int load_flags = ft_font->load_flags; int mult = font->x_scale < 0 ? -1 : +1; - unsigned int i = 0; - - load_flags = ft_font->load_flags | FT_ADVANCE_FLAG_FAST_ONLY; - for (; i < count; i++) + for (unsigned int i = 0; i < count; i++) { FT_Fixed v = 0; - if (unlikely (FT_Get_Advance (ft_face, *first_glyph, load_flags, &v))) - goto slow; - *first_advance = (v * mult + (1<<9)) >> 10; - first_glyph = &StructAtOffset (first_glyph, glyph_stride); - first_advance = &StructAtOffset (first_advance, advance_stride); - } - return; + hb_codepoint_t glyph = *first_glyph; + + unsigned int cv; + if (ft_font->advance_cache.get (glyph, &cv)) + v = cv; + else + { + FT_Get_Advance (ft_face, glyph, load_flags, &v); + ft_font->advance_cache.set (glyph, v); + } -slow: - /* TODO Prepare and use cache. */ - load_flags = ft_font->load_flags;// & ~FT_ADVANCE_FLAG_FAST_ONLY; - for (; i < count; i++) - { - FT_Fixed v = 0; - FT_Get_Advance (ft_face, *first_glyph, load_flags, &v); *first_advance = (v * mult + (1<<9)) >> 10; first_glyph = &StructAtOffset (first_glyph, glyph_stride); first_advance = &StructAtOffset (first_advance, advance_stride);