In trampoline implementation of get_glyph(), don't destroy user data twice!

This commit is contained in:
Behdad Esfahbod 2016-02-25 09:16:05 +09:00
parent 23335deaad
commit c335fd7986
1 changed files with 27 additions and 14 deletions

View File

@ -1546,6 +1546,7 @@ struct hb_trampoline_closure_t
{
void *user_data;
hb_destroy_func_t destroy;
unsigned int ref_count;
};
template <typename FuncType>
@ -1566,23 +1567,30 @@ trampoline_create (FuncType func,
trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t));
if (unlikely (!trampoline))
{
if (destroy)
destroy (user_data);
return NULL;
}
trampoline->closure.user_data = user_data;
trampoline->closure.destroy = destroy;
trampoline->closure.ref_count = 1;
trampoline->func = func;
return trampoline;
}
static void
trampoline_reference (hb_trampoline_closure_t *closure)
{
closure->ref_count++;
}
static void
trampoline_destroy (void *user_data)
{
hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data;
if (--closure->ref_count)
return;
if (closure->destroy)
closure->destroy (closure->user_data);
free (closure);
@ -1634,16 +1642,21 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_trampoline_t *trampoline;
trampoline = trampoline_create (func, user_data, destroy);
if (likely (trampoline))
hb_font_funcs_set_nominal_glyph_func (ffuncs,
hb_font_get_nominal_glyph_trampoline,
if (unlikely (!trampoline))
{
if (destroy)
destroy (user_data);
return;
}
hb_font_funcs_set_nominal_glyph_func (ffuncs,
hb_font_get_nominal_glyph_trampoline,
trampoline,
trampoline_destroy);
trampoline_reference (&trampoline->closure);
hb_font_funcs_set_variation_glyph_func (ffuncs,
hb_font_get_variation_glyph_trampoline,
trampoline,
trampoline_destroy);
trampoline = trampoline_create (func, user_data, destroy);
if (likely (trampoline))
hb_font_funcs_set_variation_glyph_func (ffuncs,
hb_font_get_variation_glyph_trampoline,
trampoline,
trampoline_destroy);
}