[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,
{
#define HB_FONT_FUNC_IMPLEMENT(name) 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
},
nullptr,
nullptr,
{
{
#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 = {
HB_OBJECT_HEADER_STATIC,
{
#define HB_FONT_FUNC_IMPLEMENT(name) 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
},
nullptr,
nullptr,
{
{
#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;
#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
ffuncs->destroy.name (ffuncs->user_data.name);
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
if (ffuncs->destroy)
{
#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
}
hb_free (ffuncs->destroy);
hb_free (ffuncs->user_data);
hb_free (ffuncs);
}
@ -841,24 +831,42 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
hb_destroy_func_t destroy) \
{ \
if (hb_object_is_immutable (ffuncs)) \
{ \
if (destroy) \
destroy (user_data); \
return; \
} \
goto fail; \
\
if (ffuncs->destroy.name) \
ffuncs->destroy.name (ffuncs->user_data.name); \
if (ffuncs->destroy && ffuncs->destroy->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) { \
ffuncs->get.f.name = func; \
ffuncs->user_data.name = user_data; \
ffuncs->destroy.name = destroy; \
if (ffuncs->user_data) \
ffuncs->user_data->name = user_data; \
if (ffuncs->destroy) \
ffuncs->destroy->name = destroy; \
} else { \
ffuncs->get.f.name = hb_font_get_##name##_default; \
ffuncs->user_data.name = nullptr; \
ffuncs->destroy.name = nullptr; \
if (ffuncs->user_data) \
ffuncs->user_data->name = nullptr; \
if (ffuncs->destroy) \
ffuncs->destroy->name = nullptr; \
} \
return; \
\
fail: \
if (destroy) \
destroy (user_data); \
}
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS

View File

@ -68,13 +68,13 @@ struct hb_font_funcs_t
#define HB_FONT_FUNC_IMPLEMENT(name) void *name;
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
} user_data;
} *user_data;
struct {
#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
} destroy;
} *destroy;
/* Don't access these directly. Call font->get_*() instead. */
union get_t {
@ -207,14 +207,14 @@ struct hb_font_t
memset (extents, 0, sizeof (*extents));
return klass->get.f.font_h_extents (this, user_data,
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)
{
memset (extents, 0, sizeof (*extents));
return klass->get.f.font_v_extents (this, user_data,
extents,
klass->user_data.font_v_extents);
!klass->user_data ? nullptr : klass->user_data->font_v_extents);
}
bool has_glyph (hb_codepoint_t unicode)
@ -230,7 +230,7 @@ struct hb_font_t
*glyph = not_found;
return klass->get.f.nominal_glyph (this, user_data,
unicode, glyph,
klass->user_data.nominal_glyph);
!klass->user_data ? nullptr : klass->user_data->nominal_glyph);
}
unsigned int get_nominal_glyphs (unsigned int count,
const hb_codepoint_t *first_unicode,
@ -242,7 +242,7 @@ struct hb_font_t
count,
first_unicode, unicode_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,
@ -252,21 +252,21 @@ struct hb_font_t
*glyph = not_found;
return klass->get.f.variation_glyph (this, user_data,
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)
{
return klass->get.f.glyph_h_advance (this, user_data,
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)
{
return klass->get.f.glyph_v_advance (this, user_data,
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,
@ -279,7 +279,7 @@ struct hb_font_t
count,
first_glyph, glyph_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,
@ -292,7 +292,7 @@ struct hb_font_t
count,
first_glyph, glyph_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,
@ -301,7 +301,7 @@ struct hb_font_t
*x = *y = 0;
return klass->get.f.glyph_h_origin (this, user_data,
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,
@ -310,7 +310,7 @@ struct hb_font_t
*x = *y = 0;
return klass->get.f.glyph_v_origin (this, user_data,
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,
@ -321,7 +321,7 @@ struct hb_font_t
#else
return klass->get.f.glyph_h_kerning (this, user_data,
left_glyph, right_glyph,
klass->user_data.glyph_h_kerning);
!klass->user_data ? nullptr : klass->user_data->glyph_h_kerning);
#endif
}
@ -333,7 +333,7 @@ struct hb_font_t
#else
return klass->get.f.glyph_v_kerning (this, user_data,
top_glyph, bottom_glyph,
klass->user_data.glyph_v_kerning);
!klass->user_data ? nullptr : klass->user_data->glyph_v_kerning);
#endif
}
@ -344,7 +344,7 @@ struct hb_font_t
return klass->get.f.glyph_extents (this, user_data,
glyph,
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,
@ -354,7 +354,7 @@ struct hb_font_t
return klass->get.f.glyph_contour_point (this, user_data,
glyph, point_index,
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,
@ -364,7 +364,7 @@ struct hb_font_t
return klass->get.f.glyph_name (this, user_data,
glyph,
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 */
@ -375,7 +375,7 @@ struct hb_font_t
return klass->get.f.glyph_from_name (this, user_data,
name, len,
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,
@ -384,7 +384,7 @@ struct hb_font_t
klass->get.f.glyph_shape (this, user_data,
glyph,
draw_funcs, draw_data,
klass->user_data.glyph_shape);
!klass->user_data ? nullptr : klass->user_data->glyph_shape);
}