[font-funcs] Optimize user-data/destroy storage

Fixes https://github.com/harfbuzz/harfbuzz/issues/2427
This commit is contained in:
Behdad Esfahbod 2022-06-01 08:44:07 -06:00
parent e421613e8f
commit 88ccbd2c43
2 changed files with 62 additions and 54 deletions

View File

@ -636,16 +636,8 @@ DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
{ {
HB_OBJECT_HEADER_STATIC, HB_OBJECT_HEADER_STATIC,
{ nullptr,
#define HB_FONT_FUNC_IMPLEMENT(name) nullptr, nullptr,
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
},
{
#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
},
{ {
{ {
#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
@ -658,16 +650,8 @@ DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
static const hb_font_funcs_t _hb_font_funcs_default = { static const hb_font_funcs_t _hb_font_funcs_default = {
HB_OBJECT_HEADER_STATIC, HB_OBJECT_HEADER_STATIC,
{ nullptr,
#define HB_FONT_FUNC_IMPLEMENT(name) nullptr, nullptr,
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
},
{
#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
},
{ {
{ {
#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default, #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default,
@ -746,10 +730,16 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
{ {
if (!hb_object_destroy (ffuncs)) return; if (!hb_object_destroy (ffuncs)) return;
#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \ if (ffuncs->destroy)
ffuncs->destroy.name (ffuncs->user_data.name); {
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy->name) \
ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name);
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT #undef HB_FONT_FUNC_IMPLEMENT
}
hb_free (ffuncs->destroy);
hb_free (ffuncs->user_data);
hb_free (ffuncs); hb_free (ffuncs);
} }
@ -841,24 +831,42 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
hb_destroy_func_t destroy) \ hb_destroy_func_t destroy) \
{ \ { \
if (hb_object_is_immutable (ffuncs)) \ if (hb_object_is_immutable (ffuncs)) \
{ \ goto fail; \
if (destroy) \
destroy (user_data); \
return; \
} \
\ \
if (ffuncs->destroy.name) \ if (ffuncs->destroy && ffuncs->destroy->name) \
ffuncs->destroy.name (ffuncs->user_data.name); \ ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); \
\
if (user_data && !ffuncs->user_data) \
{ \
ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data)); \
if (unlikely (!ffuncs->user_data)) \
goto fail; \
} \
if (destroy && !ffuncs->destroy) \
{ \
ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy)); \
if (unlikely (!ffuncs->destroy)) \
goto fail; \
} \
\ \
if (func) { \ if (func) { \
ffuncs->get.f.name = func; \ ffuncs->get.f.name = func; \
ffuncs->user_data.name = user_data; \ if (ffuncs->user_data) \
ffuncs->destroy.name = destroy; \ ffuncs->user_data->name = user_data; \
if (ffuncs->destroy) \
ffuncs->destroy->name = destroy; \
} else { \ } else { \
ffuncs->get.f.name = hb_font_get_##name##_default; \ ffuncs->get.f.name = hb_font_get_##name##_default; \
ffuncs->user_data.name = nullptr; \ if (ffuncs->user_data) \
ffuncs->destroy.name = nullptr; \ ffuncs->user_data->name = nullptr; \
if (ffuncs->destroy) \
ffuncs->destroy->name = nullptr; \
} \ } \
return; \
\
fail: \
if (destroy) \
destroy (user_data); \
} }
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS HB_FONT_FUNCS_IMPLEMENT_CALLBACKS

View File

@ -68,13 +68,13 @@ struct hb_font_funcs_t
#define HB_FONT_FUNC_IMPLEMENT(name) void *name; #define HB_FONT_FUNC_IMPLEMENT(name) void *name;
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT #undef HB_FONT_FUNC_IMPLEMENT
} user_data; } *user_data;
struct { struct {
#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name; #define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT #undef HB_FONT_FUNC_IMPLEMENT
} destroy; } *destroy;
/* Don't access these directly. Call font->get_*() instead. */ /* Don't access these directly. Call font->get_*() instead. */
union get_t { union get_t {
@ -207,14 +207,14 @@ struct hb_font_t
memset (extents, 0, sizeof (*extents)); memset (extents, 0, sizeof (*extents));
return klass->get.f.font_h_extents (this, user_data, return klass->get.f.font_h_extents (this, user_data,
extents, extents,
klass->user_data.font_h_extents); !klass->user_data ? nullptr : klass->user_data->font_h_extents);
} }
hb_bool_t get_font_v_extents (hb_font_extents_t *extents) hb_bool_t get_font_v_extents (hb_font_extents_t *extents)
{ {
memset (extents, 0, sizeof (*extents)); memset (extents, 0, sizeof (*extents));
return klass->get.f.font_v_extents (this, user_data, return klass->get.f.font_v_extents (this, user_data,
extents, extents,
klass->user_data.font_v_extents); !klass->user_data ? nullptr : klass->user_data->font_v_extents);
} }
bool has_glyph (hb_codepoint_t unicode) bool has_glyph (hb_codepoint_t unicode)
@ -230,7 +230,7 @@ struct hb_font_t
*glyph = not_found; *glyph = not_found;
return klass->get.f.nominal_glyph (this, user_data, return klass->get.f.nominal_glyph (this, user_data,
unicode, glyph, unicode, glyph,
klass->user_data.nominal_glyph); !klass->user_data ? nullptr : klass->user_data->nominal_glyph);
} }
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,
@ -242,7 +242,7 @@ struct hb_font_t
count, count,
first_unicode, unicode_stride, first_unicode, unicode_stride,
first_glyph, glyph_stride, first_glyph, glyph_stride,
klass->user_data.nominal_glyphs); !klass->user_data ? nullptr : klass->user_data->nominal_glyphs);
} }
hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
@ -252,21 +252,21 @@ struct hb_font_t
*glyph = not_found; *glyph = not_found;
return klass->get.f.variation_glyph (this, user_data, return klass->get.f.variation_glyph (this, user_data,
unicode, variation_selector, glyph, unicode, variation_selector, glyph,
klass->user_data.variation_glyph); !klass->user_data ? nullptr : klass->user_data->variation_glyph);
} }
hb_position_t get_glyph_h_advance (hb_codepoint_t glyph) hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
{ {
return klass->get.f.glyph_h_advance (this, user_data, return klass->get.f.glyph_h_advance (this, user_data,
glyph, glyph,
klass->user_data.glyph_h_advance); !klass->user_data ? nullptr : klass->user_data->glyph_h_advance);
} }
hb_position_t get_glyph_v_advance (hb_codepoint_t glyph) hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
{ {
return klass->get.f.glyph_v_advance (this, user_data, return klass->get.f.glyph_v_advance (this, user_data,
glyph, glyph,
klass->user_data.glyph_v_advance); !klass->user_data ? nullptr : klass->user_data->glyph_v_advance);
} }
void get_glyph_h_advances (unsigned int count, void get_glyph_h_advances (unsigned int count,
@ -279,7 +279,7 @@ struct hb_font_t
count, count,
first_glyph, glyph_stride, first_glyph, glyph_stride,
first_advance, advance_stride, first_advance, advance_stride,
klass->user_data.glyph_h_advances); !klass->user_data ? nullptr : klass->user_data->glyph_h_advances);
} }
void get_glyph_v_advances (unsigned int count, void get_glyph_v_advances (unsigned int count,
@ -292,7 +292,7 @@ struct hb_font_t
count, count,
first_glyph, glyph_stride, first_glyph, glyph_stride,
first_advance, advance_stride, first_advance, advance_stride,
klass->user_data.glyph_v_advances); !klass->user_data ? nullptr : klass->user_data->glyph_v_advances);
} }
hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
@ -301,7 +301,7 @@ struct hb_font_t
*x = *y = 0; *x = *y = 0;
return klass->get.f.glyph_h_origin (this, user_data, return klass->get.f.glyph_h_origin (this, user_data,
glyph, x, y, glyph, x, y,
klass->user_data.glyph_h_origin); !klass->user_data ? nullptr : klass->user_data->glyph_h_origin);
} }
hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph, hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
@ -310,7 +310,7 @@ struct hb_font_t
*x = *y = 0; *x = *y = 0;
return klass->get.f.glyph_v_origin (this, user_data, return klass->get.f.glyph_v_origin (this, user_data,
glyph, x, y, glyph, x, y,
klass->user_data.glyph_v_origin); !klass->user_data ? nullptr : klass->user_data->glyph_v_origin);
} }
hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph,
@ -321,7 +321,7 @@ struct hb_font_t
#else #else
return klass->get.f.glyph_h_kerning (this, user_data, return klass->get.f.glyph_h_kerning (this, user_data,
left_glyph, right_glyph, left_glyph, right_glyph,
klass->user_data.glyph_h_kerning); !klass->user_data ? nullptr : klass->user_data->glyph_h_kerning);
#endif #endif
} }
@ -333,7 +333,7 @@ struct hb_font_t
#else #else
return klass->get.f.glyph_v_kerning (this, user_data, return klass->get.f.glyph_v_kerning (this, user_data,
top_glyph, bottom_glyph, top_glyph, bottom_glyph,
klass->user_data.glyph_v_kerning); !klass->user_data ? nullptr : klass->user_data->glyph_v_kerning);
#endif #endif
} }
@ -344,7 +344,7 @@ struct hb_font_t
return klass->get.f.glyph_extents (this, user_data, return klass->get.f.glyph_extents (this, user_data,
glyph, glyph,
extents, extents,
klass->user_data.glyph_extents); !klass->user_data ? nullptr : klass->user_data->glyph_extents);
} }
hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index, hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
@ -354,7 +354,7 @@ struct hb_font_t
return klass->get.f.glyph_contour_point (this, user_data, return klass->get.f.glyph_contour_point (this, user_data,
glyph, point_index, glyph, point_index,
x, y, x, y,
klass->user_data.glyph_contour_point); !klass->user_data ? nullptr : klass->user_data->glyph_contour_point);
} }
hb_bool_t get_glyph_name (hb_codepoint_t glyph, hb_bool_t get_glyph_name (hb_codepoint_t glyph,
@ -364,7 +364,7 @@ struct hb_font_t
return klass->get.f.glyph_name (this, user_data, return klass->get.f.glyph_name (this, user_data,
glyph, glyph,
name, size, name, size,
klass->user_data.glyph_name); !klass->user_data ? nullptr : klass->user_data->glyph_name);
} }
hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */ hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
@ -375,7 +375,7 @@ struct hb_font_t
return klass->get.f.glyph_from_name (this, user_data, return klass->get.f.glyph_from_name (this, user_data,
name, len, name, len,
glyph, glyph,
klass->user_data.glyph_from_name); !klass->user_data ? nullptr : klass->user_data->glyph_from_name);
} }
void get_glyph_shape (hb_codepoint_t glyph, void get_glyph_shape (hb_codepoint_t glyph,
@ -384,7 +384,7 @@ struct hb_font_t
klass->get.f.glyph_shape (this, user_data, klass->get.f.glyph_shape (this, user_data,
glyph, glyph,
draw_funcs, draw_data, draw_funcs, draw_data,
klass->user_data.glyph_shape); !klass->user_data ? nullptr : klass->user_data->glyph_shape);
} }