[draw] Lazy-allocate user-data/destroy callback vector

This commit is contained in:
Behdad Esfahbod 2022-06-16 13:24:02 -06:00
parent 823f32a0e2
commit e0a5231657
2 changed files with 45 additions and 22 deletions

View File

@ -89,18 +89,39 @@ hb_draw_funcs_set_##name##_func (hb_draw_funcs_t *dfuncs, \
if (hb_object_is_immutable (dfuncs)) \ if (hb_object_is_immutable (dfuncs)) \
return; \ return; \
\ \
if (dfuncs->destroy.name) \ if (dfuncs->destroy && dfuncs->destroy->name) \
dfuncs->destroy.name (dfuncs->user_data.name); \ dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name); \
\
if (user_data && !dfuncs->user_data) \
{ \
dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data)); \
if (unlikely (!dfuncs->user_data)) \
goto fail; \
} \
if (destroy && !dfuncs->destroy) \
{ \
dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy)); \
if (unlikely (!dfuncs->destroy)) \
goto fail; \
} \
\ \
if (func) { \ if (func) { \
dfuncs->func.name = func; \ dfuncs->func.name = func; \
dfuncs->user_data.name = user_data; \ if (dfuncs->user_data) \
dfuncs->destroy.name = destroy; \ dfuncs->user_data->name = user_data; \
if (dfuncs->destroy) \
dfuncs->destroy->name = destroy; \
} else { \ } else { \
dfuncs->func.name = hb_draw_##name##_nil; \ dfuncs->func.name = hb_draw_##name##_nil; \
dfuncs->user_data.name = nullptr; \ if (dfuncs->user_data) \
dfuncs->destroy.name = nullptr; \ dfuncs->user_data->name = nullptr; \
if (dfuncs->destroy) \
dfuncs->destroy->name = nullptr; \
} \ } \
\
fail: \
if (destroy) \
destroy (user_data); \
} }
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
@ -177,11 +198,13 @@ hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs)
{ {
if (!hb_object_destroy (dfuncs)) return; if (!hb_object_destroy (dfuncs)) return;
if (dfuncs->destroy)
{
#define HB_DRAW_FUNC_IMPLEMENT(name) \ #define HB_DRAW_FUNC_IMPLEMENT(name) \
if (dfuncs->destroy.name) dfuncs->destroy.name (dfuncs->user_data.name); if (dfuncs->destroy->name) dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name);
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_DRAW_FUNC_IMPLEMENT #undef HB_DRAW_FUNC_IMPLEMENT
}
hb_free (dfuncs); hb_free (dfuncs);
} }

View File

@ -54,31 +54,31 @@ struct hb_draw_funcs_t
#define HB_DRAW_FUNC_IMPLEMENT(name) void *name; #define HB_DRAW_FUNC_IMPLEMENT(name) void *name;
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_DRAW_FUNC_IMPLEMENT #undef HB_DRAW_FUNC_IMPLEMENT
} user_data; } *user_data;
struct { struct {
#define HB_DRAW_FUNC_IMPLEMENT(name) hb_destroy_func_t name; #define HB_DRAW_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_DRAW_FUNC_IMPLEMENT #undef HB_DRAW_FUNC_IMPLEMENT
} destroy; } *destroy;
void emit_move_to (void *draw_data, hb_draw_state_t &st, void emit_move_to (void *draw_data, hb_draw_state_t &st,
float to_x, float to_y) float to_x, float to_y)
{ func.move_to (this, draw_data, &st, { func.move_to (this, draw_data, &st,
to_x, to_y, to_x, to_y,
user_data.move_to); } !user_data ? nullptr : user_data->move_to); }
void emit_line_to (void *draw_data, hb_draw_state_t &st, void emit_line_to (void *draw_data, hb_draw_state_t &st,
float to_x, float to_y) float to_x, float to_y)
{ func.line_to (this, draw_data, &st, { func.line_to (this, draw_data, &st,
to_x, to_y, to_x, to_y,
user_data.line_to); } !user_data ? nullptr : user_data->line_to); }
void emit_quadratic_to (void *draw_data, hb_draw_state_t &st, void emit_quadratic_to (void *draw_data, hb_draw_state_t &st,
float control_x, float control_y, float control_x, float control_y,
float to_x, float to_y) float to_x, float to_y)
{ func.quadratic_to (this, draw_data, &st, { func.quadratic_to (this, draw_data, &st,
control_x, control_y, control_x, control_y,
to_x, to_y, to_x, to_y,
user_data.quadratic_to); } !user_data ? nullptr : user_data->quadratic_to); }
void emit_cubic_to (void *draw_data, hb_draw_state_t &st, void emit_cubic_to (void *draw_data, hb_draw_state_t &st,
float control1_x, float control1_y, float control1_x, float control1_y,
float control2_x, float control2_y, float control2_x, float control2_y,
@ -87,10 +87,10 @@ struct hb_draw_funcs_t
control1_x, control1_y, control1_x, control1_y,
control2_x, control2_y, control2_x, control2_y,
to_x, to_y, to_x, to_y,
user_data.cubic_to); } !user_data ? nullptr : user_data->cubic_to); }
void emit_close_path (void *draw_data, hb_draw_state_t &st) void emit_close_path (void *draw_data, hb_draw_state_t &st)
{ func.close_path (this, draw_data, &st, { func.close_path (this, draw_data, &st,
user_data.close_path); } !user_data ? nullptr : user_data->close_path); }
void move_to (void *draw_data, hb_draw_state_t &st, void move_to (void *draw_data, hb_draw_state_t &st,