[ot-font] Add a cmap cache
Speeds up Roboto shaping by 7%, for 1kb per face.
This commit is contained in:
parent
1b53ed3c41
commit
f8a744d9d5
|
@ -1901,20 +1901,37 @@ struct cmap
|
||||||
if (unlikely (!this->get_glyph_funcZ)) return false;
|
if (unlikely (!this->get_glyph_funcZ)) return false;
|
||||||
return this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph);
|
return this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename cache_t = void>
|
||||||
|
inline bool _cached_get (hb_codepoint_t unicode,
|
||||||
|
hb_codepoint_t *glyph,
|
||||||
|
cache_t *cache) const
|
||||||
|
{
|
||||||
|
unsigned v;
|
||||||
|
if (cache && cache->get (unicode, &v))
|
||||||
|
{
|
||||||
|
*glyph = v;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool ret = this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph);
|
||||||
|
if (cache && ret)
|
||||||
|
cache->set (unicode, *glyph);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename cache_t = void>
|
||||||
unsigned int get_nominal_glyphs (unsigned int count,
|
unsigned int get_nominal_glyphs (unsigned int count,
|
||||||
const hb_codepoint_t *first_unicode,
|
const hb_codepoint_t *first_unicode,
|
||||||
unsigned int unicode_stride,
|
unsigned int unicode_stride,
|
||||||
hb_codepoint_t *first_glyph,
|
hb_codepoint_t *first_glyph,
|
||||||
unsigned int glyph_stride) const
|
unsigned int glyph_stride,
|
||||||
|
cache_t *cache = nullptr) const
|
||||||
{
|
{
|
||||||
if (unlikely (!this->get_glyph_funcZ)) return 0;
|
if (unlikely (!this->get_glyph_funcZ)) return 0;
|
||||||
|
|
||||||
hb_cmap_get_glyph_func_t get_glyph_funcZ = this->get_glyph_funcZ;
|
|
||||||
const void *get_glyph_data = this->get_glyph_data;
|
|
||||||
|
|
||||||
unsigned int done;
|
unsigned int done;
|
||||||
for (done = 0;
|
for (done = 0;
|
||||||
done < count && get_glyph_funcZ (get_glyph_data, *first_unicode, first_glyph);
|
done < count && _cached_get (*first_unicode, first_glyph, cache);
|
||||||
done++)
|
done++)
|
||||||
{
|
{
|
||||||
first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride);
|
first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride);
|
||||||
|
|
|
@ -60,12 +60,17 @@
|
||||||
* never need to call these functions directly.
|
* never need to call these functions directly.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
using hb_ot_font_cmap_cache_t = hb_cache_t<21, 16, 8, true>;
|
||||||
using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>;
|
using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>;
|
||||||
|
|
||||||
|
static hb_user_data_key_t hb_ot_font_cmap_cache_user_data_key;
|
||||||
|
|
||||||
struct hb_ot_font_t
|
struct hb_ot_font_t
|
||||||
{
|
{
|
||||||
const hb_ot_face_t *ot_face;
|
const hb_ot_face_t *ot_face;
|
||||||
|
|
||||||
|
hb_ot_font_cmap_cache_t *cmap_cache;
|
||||||
|
|
||||||
/* h_advance caching */
|
/* h_advance caching */
|
||||||
mutable hb_atomic_int_t cached_coords_serial;
|
mutable hb_atomic_int_t cached_coords_serial;
|
||||||
mutable hb_atomic_ptr_t<hb_ot_font_advance_cache_t> advance_cache;
|
mutable hb_atomic_ptr_t<hb_ot_font_advance_cache_t> advance_cache;
|
||||||
|
@ -80,6 +85,31 @@ _hb_ot_font_create (hb_font_t *font)
|
||||||
|
|
||||||
ot_font->ot_face = &font->face->table;
|
ot_font->ot_face = &font->face->table;
|
||||||
|
|
||||||
|
auto *cmap_cache = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face,
|
||||||
|
&hb_ot_font_cmap_cache_user_data_key);
|
||||||
|
if (!cmap_cache)
|
||||||
|
{
|
||||||
|
cmap_cache = (hb_ot_font_cmap_cache_t *) hb_malloc (sizeof (hb_ot_font_cmap_cache_t));
|
||||||
|
if (unlikely (!cmap_cache)) goto out;
|
||||||
|
cmap_cache->init ();
|
||||||
|
if (!hb_face_set_user_data (font->face,
|
||||||
|
&hb_ot_font_cmap_cache_user_data_key,
|
||||||
|
cmap_cache,
|
||||||
|
hb_free,
|
||||||
|
false))
|
||||||
|
{
|
||||||
|
/* Normally we would retry after this, but that would
|
||||||
|
* infinite-loop if the face is the empty-face.
|
||||||
|
* Just let it go and this font will be uncached if it
|
||||||
|
* happened to collide with anothe thread creating the
|
||||||
|
* cache at the same time. */
|
||||||
|
hb_free (cmap_cache);
|
||||||
|
cmap_cache = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
ot_font->cmap_cache = cmap_cache;
|
||||||
|
|
||||||
return ot_font;
|
return ot_font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +151,8 @@ hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
|
||||||
const hb_ot_face_t *ot_face = ot_font->ot_face;
|
const hb_ot_face_t *ot_face = ot_font->ot_face;
|
||||||
return ot_face->cmap->get_nominal_glyphs (count,
|
return ot_face->cmap->get_nominal_glyphs (count,
|
||||||
first_unicode, unicode_stride,
|
first_unicode, unicode_stride,
|
||||||
first_glyph, glyph_stride);
|
first_glyph, glyph_stride,
|
||||||
|
ot_font->cmap_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_bool_t
|
static hb_bool_t
|
||||||
|
|
Loading…
Reference in New Issue