struct hb_cache_t
{
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 fini (void) {}
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 *
ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
+ ft_font->advance_cache.init ();
+
return ft_font;
}
{
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);
{
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<hb_codepoint_t> (first_glyph, glyph_stride);
- first_advance = &StructAtOffset<hb_position_t> (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<hb_codepoint_t> (first_glyph, glyph_stride);
first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);