From 4785892febea2fbb127e9ec174035991c06dea95 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Mon, 9 Aug 2010 02:55:30 +0200 Subject: Fix drawing leakage: delay glyph allocation Delay allocation of the "faux" glyph until a drawing is parsed. This helps with fixing a (pretty bad) memory leak and also reduces frame overhead a little. --- libass/ass_drawing.c | 16 ++++++++-------- libass/ass_drawing.h | 6 ++++-- libass/ass_parse.c | 7 ++++--- libass/ass_render.c | 3 +-- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/libass/ass_drawing.c b/libass/ass_drawing.c index 7833c10..93cc458 100644 --- a/libass/ass_drawing.c +++ b/libass/ass_drawing.c @@ -34,13 +34,13 @@ * \brief Get and prepare a FreeType glyph */ static void drawing_make_glyph(ASS_Drawing *drawing, void *fontconfig_priv, - ASS_Font *font, ASS_Hinting hint) + ASS_Font *font) { FT_OutlineGlyph glyph; // This is hacky... glyph = (FT_OutlineGlyph) ass_font_get_glyph(fontconfig_priv, font, - (uint32_t) ' ', hint, 0); + (uint32_t) ' ', 0, 0); if (glyph) { FT_Outline_Done(drawing->ftlibrary, &glyph->outline); FT_Outline_New(drawing->ftlibrary, GLYPH_INITIAL_POINTS, @@ -355,7 +355,7 @@ static void drawing_evaluate_curve(ASS_Drawing *drawing, * \brief Create and initialize a new drawing and return it */ ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font, - ASS_Hinting hint, FT_Library lib) + FT_Library lib) { ASS_Drawing *drawing; @@ -364,12 +364,10 @@ ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font, drawing->size = DRAWING_INITIAL_SIZE; drawing->cbox.xMin = drawing->cbox.yMin = INT_MAX; drawing->cbox.xMax = drawing->cbox.yMax = INT_MIN; - + drawing->fontconfig_priv = fontconfig_priv; + drawing->font = font; drawing->ftlibrary = lib; - if (font) { - drawing->library = font->library; - drawing_make_glyph(drawing, fontconfig_priv, font, hint); - } + drawing->library = font->library; drawing->scale_x = 1.; drawing->scale_y = 1.; @@ -422,6 +420,8 @@ FT_OutlineGlyph *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode) ASS_DrawingToken *token; FT_Vector pen = {0, 0}; + if (drawing->font) + drawing_make_glyph(drawing, drawing->fontconfig_priv, drawing->font); if (!drawing->glyph) return NULL; diff --git a/libass/ass_drawing.h b/libass/ass_drawing.h index 0223271..f677fcd 100644 --- a/libass/ass_drawing.h +++ b/libass/ass_drawing.h @@ -57,7 +57,9 @@ typedef struct { int hash; // hash value (for caching) // private - FT_Library ftlibrary; // FT library instance, needed for font ops + FT_Library ftlibrary; // needed for font ops + ASS_Font *font; // dito + void *fontconfig_priv; // dito ASS_Library *library; int size; // current buffer size ASS_DrawingToken *tokens; // tokenized drawing @@ -69,7 +71,7 @@ typedef struct { } ASS_Drawing; ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font, - ASS_Hinting hint, FT_Library lib); + FT_Library lib); void ass_drawing_free(ASS_Drawing* drawing); void ass_drawing_add_char(ASS_Drawing* drawing, char symbol); void ass_drawing_hash(ASS_Drawing* drawing); diff --git a/libass/ass_parse.c b/libass/ass_parse.c index 654fa7f..cac5760 100644 --- a/libass/ass_parse.c +++ b/libass/ass_parse.c @@ -214,13 +214,14 @@ static char *parse_vector_clip(ASS_Renderer *render_priv, char *p) { int scale = 1; int res = 0; - ASS_Drawing *drawing; + ASS_Drawing *drawing = render_priv->state.clip_drawing; - ass_drawing_free(render_priv->state.clip_drawing); + if (drawing && drawing->glyph) + FT_Done_Glyph((FT_Glyph) drawing->glyph); + ass_drawing_free(drawing); render_priv->state.clip_drawing = ass_drawing_new( render_priv->fontconfig_priv, render_priv->state.font, - render_priv->settings.hinting, render_priv->ftlibrary); drawing = render_priv->state.clip_drawing; skipopt('('); diff --git a/libass/ass_render.c b/libass/ass_render.c index 3e241c1..caea6b9 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -911,9 +911,9 @@ init_render_context(ASS_Renderer *render_priv, ASS_Event *event) render_priv->state.effect_type = EF_NONE; render_priv->state.effect_timing = 0; render_priv->state.effect_skip_timing = 0; + ass_drawing_free(render_priv->state.drawing); render_priv->state.drawing = ass_drawing_new(render_priv->fontconfig_priv, render_priv->state.font, - render_priv->settings.hinting, render_priv->ftlibrary); apply_transition_effects(render_priv, event); @@ -1900,7 +1900,6 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event, drawing = render_priv->state.drawing = ass_drawing_new(render_priv->fontconfig_priv, render_priv->state.font, - render_priv->settings.hinting, render_priv->ftlibrary); } } -- cgit v1.2.3