[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)) \
return; \
\
if (dfuncs->destroy.name) \
dfuncs->destroy.name (dfuncs->user_data.name); \
\
if (func) { \
dfuncs->func.name = func; \
dfuncs->user_data.name = user_data; \
dfuncs->destroy.name = destroy; \
} else { \
dfuncs->func.name = hb_draw_##name##_nil; \
dfuncs->user_data.name = nullptr; \
dfuncs->destroy.name = nullptr; \
} \
if (dfuncs->destroy && dfuncs->destroy->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) { \
dfuncs->func.name = func; \
if (dfuncs->user_data) \
dfuncs->user_data->name = user_data; \
if (dfuncs->destroy) \
dfuncs->destroy->name = destroy; \
} else { \
dfuncs->func.name = hb_draw_##name##_nil; \
if (dfuncs->user_data) \
dfuncs->user_data->name = nullptr; \
if (dfuncs->destroy) \
dfuncs->destroy->name = nullptr; \
} \
\
fail: \
if (destroy) \
destroy (user_data); \
}
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 (dfuncs->destroy)
{
#define HB_DRAW_FUNC_IMPLEMENT(name) \
if (dfuncs->destroy.name) dfuncs->destroy.name (dfuncs->user_data.name);
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
if (dfuncs->destroy->name) dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name);
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_DRAW_FUNC_IMPLEMENT
}
hb_free (dfuncs);
}

View File

@ -54,31 +54,31 @@ struct hb_draw_funcs_t
#define HB_DRAW_FUNC_IMPLEMENT(name) void *name;
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_DRAW_FUNC_IMPLEMENT
} user_data;
} *user_data;
struct {
#define HB_DRAW_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_DRAW_FUNC_IMPLEMENT
} destroy;
} *destroy;
void emit_move_to (void *draw_data, hb_draw_state_t &st,
float to_x, float to_y)
{ func.move_to (this, draw_data, &st,
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,
float to_x, float to_y)
{ func.line_to (this, draw_data, &st,
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,
float control_x, float control_y,
float to_x, float to_y)
{ func.quadratic_to (this, draw_data, &st,
control_x, control_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,
float control1_x, float control1_y,
float control2_x, float control2_y,
@ -87,10 +87,10 @@ struct hb_draw_funcs_t
control1_x, control1_y,
control2_x, control2_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)
{ 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,