From 1c2b1740296d14f6108dd9549c386f42f697e68a Mon Sep 17 00:00:00 2001 From: eugeni Date: Fri, 20 Apr 2007 23:09:48 +0000 Subject: Move outline glyph generation to a separate function, using outline glyph cache. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@23039 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libass/ass_render.c | 94 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 34 deletions(-) (limited to 'libass/ass_render.c') diff --git a/libass/ass_render.c b/libass/ass_render.c index 61a24cd0eb..b62ba5ac06 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -253,6 +253,7 @@ ass_renderer_t* ass_renderer_init(ass_library_t* library) ass_font_cache_init(); ass_bitmap_cache_init(); + ass_glyph_cache_init(); text_info.glyphs = calloc(MAX_GLYPHS, sizeof(glyph_info_t)); @@ -267,6 +268,7 @@ void ass_renderer_done(ass_renderer_t* priv) { ass_font_cache_done(); ass_bitmap_cache_done(); + ass_glyph_cache_done(); if (render_context.stroker) { FT_Stroker_Done(render_context.stroker); render_context.stroker = 0; @@ -1222,6 +1224,53 @@ static void free_render_context(void) { } +static int get_outline_glyph(int symbol, glyph_info_t* info, FT_Vector* advance) +{ + int error; + glyph_hash_val_t* val; + glyph_hash_key_t key; + key.font = render_context.font; + key.size = render_context.font_size; + key.ch = symbol; + key.scale_x = (render_context.scale_x * 0xFFFF); + key.scale_y = (render_context.scale_y * 0xFFFF); + key.advance = *advance; + key.bold = render_context.bold; + key.italic = render_context.italic; + + info->glyph = info->outline_glyph = 0; + + val = cache_find_glyph(&key); + if (val) { + FT_Glyph_Copy(val->glyph, &info->glyph); + info->bbox = val->bbox_scaled; + info->advance.x = val->advance.x; + info->advance.y = val->advance.y; + } else { + glyph_hash_val_t v; + info->glyph = ass_font_get_glyph(frame_context.ass_priv->fontconfig_priv, render_context.font, symbol); + if (!info->glyph) + return 0; + info->advance.x = d16_to_d6(info->glyph->advance.x); + info->advance.y = d16_to_d6(info->glyph->advance.y); + FT_Glyph_Get_CBox( info->glyph, FT_GLYPH_BBOX_PIXELS, &info->bbox); + + FT_Glyph_Copy(info->glyph, &v.glyph); + v.advance = info->advance; + v.bbox_scaled = info->bbox; + cache_add_glyph(&key, &v); + } + + if (render_context.stroker) { + info->outline_glyph = info->glyph; + error = FT_Glyph_StrokeBorder( &(info->outline_glyph), render_context.stroker, 0 , 0 ); // don't destroy original + if (error) { + mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FT_Glyph_Stroke_Error, error); + } + } + return 0; +} + /** * \brief Get normal and outline glyphs from cache (if possible) or font face * \param index face glyph index @@ -1230,7 +1279,7 @@ static void free_render_context(void) * \param advance advance vector of the extracted glyph * \return 0 on success */ -static void get_glyph(int symbol, glyph_info_t* info, FT_Vector* advance) +static int get_bitmap_glyph(int symbol, glyph_info_t* info, FT_Vector* advance) { int error; bitmap_hash_val_t* val; @@ -1254,39 +1303,16 @@ static void get_glyph(int symbol, glyph_info_t* info, FT_Vector* advance) /* val = 0; */ if (val) { - info->glyph = info->outline_glyph = 0; info->bm = val->bm; info->bm_o = val->bm_o; info->bm_s = val->bm_s; info->bbox = val->bbox_scaled; info->advance.x = val->advance.x; info->advance.y = val->advance.y; + } else + info->bm = info->bm_o = info->bm_s = 0; - return; - } - - // not found, get a new outline glyph from face -// mp_msg(MSGT_ASS, MSGL_INFO, "miss, index = %d, symbol = %c, adv = (%d, %d)\n", index, symbol, advance->x, advance->y); - - info->outline_glyph = 0; - info->bm = info->bm_o = info->bm_s = 0; - info->bbox.xMin = info->bbox.xMax = info->bbox.yMin = info->bbox.yMax = 0; - info->advance.x = info->advance.y = 0; - - info->glyph = ass_font_get_glyph(frame_context.ass_priv->fontconfig_priv, render_context.font, symbol); - if (!info->glyph) - return; - - info->advance.x = d16_to_d6(info->glyph->advance.x); - info->advance.y = d16_to_d6(info->glyph->advance.y); - - if (render_context.stroker) { - info->outline_glyph = info->glyph; - error = FT_Glyph_StrokeBorder( &(info->outline_glyph), render_context.stroker, 0 , 0 ); // don't destroy original - if (error) { - mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FT_Glyph_Stroke_Error, error); - } - } + return 0; } /** @@ -1740,8 +1766,13 @@ static int ass_render_event(ass_event_t* event, event_images_t* event_images) ass_font_set_transform(render_context.font, &matrix, &shift ); } - - get_glyph(code, text_info.glyphs + text_info.length, &shift); + + error = get_outline_glyph(code, text_info.glyphs + text_info.length, &shift); + error |= get_bitmap_glyph(code, text_info.glyphs + text_info.length, &shift); + + if (error) { + continue; + } text_info.glyphs[text_info.length].pos.x = pen.x >> 6; text_info.glyphs[text_info.length].pos.y = pen.y >> 6; @@ -1750,11 +1781,6 @@ static int ass_render_event(ass_event_t* event, event_images_t* event_images) pen.x += double_to_d6(render_context.hspacing); pen.y += text_info.glyphs[text_info.length].advance.y; - // if it's an outline glyph, we still need to fill the bbox - if (text_info.glyphs[text_info.length].glyph) { - FT_Glyph_Get_CBox( text_info.glyphs[text_info.length].glyph, FT_GLYPH_BBOX_PIXELS, &(text_info.glyphs[text_info.length].bbox) ); - } - previous = code; text_info.glyphs[text_info.length].symbol = code; -- cgit v1.2.3