[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,
|
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);
|
{
|
||||||
|
#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
|
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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue