summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2016-02-25 09:16:05 +0900
committerBehdad Esfahbod <behdad@behdad.org>2016-02-25 09:16:05 +0900
commitc335fd7986fe360ab8e1c032c9b988d0d30511eb (patch)
treefb1d2235922bf33ff44bc508c1a36bdea6af10c7
parent23335deaad9d4d9824ff41343264514d3f9f7e37 (diff)
In trampoline implementation of get_glyph(), don't destroy user data twice!
-rw-r--r--src/hb-font.cc41
1 files changed, 27 insertions, 14 deletions
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 6742b499..4953d00f 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -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);
}