[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
pull/980/merge
Behdad Esfahbod 6 years ago
parent f90bab8560
commit 54998befc4
  1. 2
      src/hb-cache.hh
  2. 35
      src/hb-ft.cc

@ -36,7 +36,7 @@ template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bit
struct hb_cache_t struct hb_cache_t
{ {
static_assert ((key_bits >= cache_bits), ""); static_assert ((key_bits >= 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 init (void) { clear (); }
inline void fini (void) {} inline void fini (void) {}

@ -69,6 +69,7 @@ struct hb_ft_font_t
int load_flags; int load_flags;
bool symbol; /* Whether selected cmap is symbol cmap. */ bool symbol; /* Whether selected cmap is symbol cmap. */
bool unref; /* Whether to destroy ft_face when done. */ bool unref; /* Whether to destroy ft_face when done. */
mutable hb_advance_cache_t advance_cache;
}; };
static hb_ft_font_t * 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->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
ft_font->advance_cache.init ();
return ft_font; return ft_font;
} }
@ -99,6 +102,8 @@ _hb_ft_font_destroy (void *data)
{ {
hb_ft_font_t *ft_font = (hb_ft_font_t *) data; hb_ft_font_t *ft_font = (hb_ft_font_t *) data;
ft_font->advance_cache.fini ();
if (ft_font->unref) if (ft_font->unref)
_hb_ft_face_destroy (ft_font->ft_face); _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; const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
FT_Face ft_face = ft_font->ft_face; 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; int mult = font->x_scale < 0 ? -1 : +1;
unsigned int i = 0; for (unsigned int i = 0; i < count; i++)
load_flags = ft_font->load_flags | FT_ADVANCE_FLAG_FAST_ONLY;
for (; i < count; i++)
{ {
FT_Fixed v = 0; FT_Fixed v = 0;
if (unlikely (FT_Get_Advance (ft_face, *first_glyph, load_flags, &v))) hb_codepoint_t glyph = *first_glyph;
goto slow;
*first_advance = (v * mult + (1<<9)) >> 10;
first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
}
return;
slow: unsigned int cv;
/* TODO Prepare and use cache. */ if (ft_font->advance_cache.get (glyph, &cv))
load_flags = ft_font->load_flags;// & ~FT_ADVANCE_FLAG_FAST_ONLY; v = cv;
for (; i < count; i++) else
{ {
FT_Fixed v = 0; FT_Get_Advance (ft_face, glyph, load_flags, &v);
FT_Get_Advance (ft_face, *first_glyph, load_flags, &v); ft_font->advance_cache.set (glyph, v);
}
*first_advance = (v * mult + (1<<9)) >> 10; *first_advance = (v * mult + (1<<9)) >> 10;
first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride); first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);

Loading…
Cancel
Save