From 88ccbd2c4356b70107c212a81b5a99d08d2d3dd0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 1 Jun 2022 08:44:07 -0600 Subject: [PATCH] [font-funcs] Optimize user-data/destroy storage Fixes https://github.com/harfbuzz/harfbuzz/issues/2427 --- src/hb-font.cc | 76 ++++++++++++++++++++++++++++---------------------- src/hb-font.hh | 40 +++++++++++++------------- 2 files changed, 62 insertions(+), 54 deletions(-) diff --git a/src/hb-font.cc b/src/hb-font.cc index 62a06d918..fb2631db8 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -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 diff --git a/src/hb-font.hh b/src/hb-font.hh index abc8bb3ba..e7f3eccd4 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -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); }