From 22ce8a7111f9e814e92754eec9cf521d9586fb08 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Mon, 22 Feb 2010 16:40:49 +0000 Subject: [PATCH] cogl-pango-glyph-cache: Don't put zero-sized glyphs in the cache It now avoids trying to reserve space for zero-sized glyphs. That happens for example when the layout contains a space. This was causing the regular glyph cache to be used because the global atlas does not support zero-sized images. That would then break up the batching. Instead it now still reserves an entry in the cache but leaves the texture as COGL_INVALID_HANDLE. --- clutter/cogl/pango/cogl-pango-glyph-cache.c | 39 +++++++++++++-------- clutter/cogl/pango/cogl-pango-render.c | 7 +++- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/clutter/cogl/pango/cogl-pango-glyph-cache.c b/clutter/cogl/pango/cogl-pango-glyph-cache.c index b1fbd9285..3c6ec5a59 100644 --- a/clutter/cogl/pango/cogl-pango-glyph-cache.c +++ b/clutter/cogl/pango/cogl-pango-glyph-cache.c @@ -70,7 +70,8 @@ struct _CoglPangoGlyphCacheKey static void cogl_pango_glyph_cache_value_free (CoglPangoGlyphCacheValue *value) { - cogl_handle_unref (value->texture); + if (value->texture) + cogl_handle_unref (value->texture); g_slice_free (CoglPangoGlyphCacheValue, value); } @@ -307,7 +308,6 @@ cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache, value = g_slice_new (CoglPangoGlyphCacheValue); value->texture = COGL_INVALID_HANDLE; - value->dirty = TRUE; pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL); pango_extents_to_pixels (&ink_rect, NULL); @@ -317,18 +317,29 @@ cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache, value->draw_width = ink_rect.width; value->draw_height = ink_rect.height; - /* Try adding the glyph to the global atlas... */ - if (!cogl_pango_glyph_cache_add_to_global_atlas (cache, - font, - glyph, - value) && - !cogl_pango_glyph_cache_add_to_local_atlas (cache, - font, - glyph, - value)) + /* If the glyph is zero-sized then we don't need to reserve any + space for it and we can just avoid painting anything */ + if (ink_rect.width < 1 || ink_rect.height < 1) + value->dirty = FALSE; + else { - cogl_pango_glyph_cache_value_free (value); - return NULL; + /* Try adding the glyph to the global atlas... */ + if (!cogl_pango_glyph_cache_add_to_global_atlas (cache, + font, + glyph, + value) && + /* If it fails try the local atlas */ + !cogl_pango_glyph_cache_add_to_local_atlas (cache, + font, + glyph, + value)) + { + cogl_pango_glyph_cache_value_free (value); + return NULL; + } + + value->dirty = TRUE; + cache->has_dirty_glyphs = TRUE; } key = g_slice_new (CoglPangoGlyphCacheKey); @@ -336,8 +347,6 @@ cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache, key->glyph = glyph; g_hash_table_insert (cache->hash_table, key, value); - - cache->has_dirty_glyphs = TRUE; } return value; diff --git a/clutter/cogl/pango/cogl-pango-render.c b/clutter/cogl/pango/cogl-pango-render.c index 0d6f477e0..597f7898c 100644 --- a/clutter/cogl/pango/cogl-pango-render.c +++ b/clutter/cogl/pango/cogl-pango-render.c @@ -501,6 +501,11 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font, COGL_NOTE (PANGO, "redrawing glyph %i", glyph); + /* Glyphs that don't take up any space will end up without a + texture. These should never become dirty so they shouldn't end up + here */ + g_return_if_fail (value->texture != COGL_INVALID_HANDLE); + surface = cairo_image_surface_create (CAIRO_FORMAT_A8, value->draw_width, value->draw_height); @@ -824,7 +829,7 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer, PANGO_UNKNOWN_GLYPH_WIDTH, PANGO_UNKNOWN_GLYPH_HEIGHT); } - else + else if (cache_value->texture) { x += (float)(cache_value->draw_x); y += (float)(cache_value->draw_y);