[font-funcs] Optimize user-data/destroy storage
Fixes https://github.com/harfbuzz/harfbuzz/issues/2427
This commit is contained in:
parent
e421613e8f
commit
88ccbd2c43
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue