From 264fff909e21bb912e46a164a20c5630755c5ea7 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 26 Nov 2011 17:54:56 +0100 Subject: [PATCH] Support glyph string caching To avoid redrawing the whole layout every time, we now support caching a single glyph-string if it consists of only one run. This should speed up drawing considerably. We still support drawing the whole layout as fall-back method. Signed-off-by: David Herrmann --- src/console_char.c | 48 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/console_char.c b/src/console_char.c index 079117e..9a87df9 100644 --- a/src/console_char.c +++ b/src/console_char.c @@ -42,6 +42,7 @@ struct kmscon_char { enum glyph_type { GLYPH_NONE, GLYPH_LAYOUT, + GLYPH_STR, }; struct kmscon_glyph { @@ -54,6 +55,11 @@ struct kmscon_glyph { struct layout { PangoLayout *layout; } layout; + struct str { + PangoFont *font; + PangoGlyphString *str; + uint32_t ascent; + } str; } src; }; @@ -274,6 +280,10 @@ static void kmscon_glyph_reset(struct kmscon_glyph *glyph) case GLYPH_LAYOUT: g_object_unref(glyph->src.layout.layout); break; + case GLYPH_STR: + g_object_unref(glyph->src.str.font); + pango_glyph_string_free(glyph->src.str.str); + break; } glyph->type = GLYPH_NONE; @@ -310,6 +320,9 @@ static int kmscon_glyph_set(struct kmscon_glyph *glyph, struct kmscon_font *font) { PangoLayout *layout; + PangoLayoutLine *line; + PangoGlyphItem *tmp; + PangoGlyphString *str; if (!glyph || !font) return -EINVAL; @@ -319,10 +332,31 @@ static int kmscon_glyph_set(struct kmscon_glyph *glyph, return -EINVAL; pango_layout_set_text(layout, glyph->ch->buf, glyph->ch->len); + line = pango_layout_get_line_readonly(layout, 0); - kmscon_glyph_reset(glyph); - glyph->type = GLYPH_LAYOUT; - glyph->src.layout.layout = layout; + if (!line || !line->runs || line->runs->next) { + kmscon_glyph_reset(glyph); + glyph->type = GLYPH_LAYOUT; + glyph->src.layout.layout = layout; + } else { + tmp = line->runs->data; + str = pango_glyph_string_copy(tmp->glyphs); + if (!str) { + g_object_unref(layout); + return -ENOMEM; + } + + kmscon_glyph_reset(glyph); + glyph->type = GLYPH_STR; + + glyph->src.str.str = str; + glyph->src.str.font = + g_object_ref(tmp->item->analysis.font); + glyph->src.str.ascent = + PANGO_PIXELS_CEIL(pango_layout_get_baseline(layout)); + + g_object_unref(layout); + } return 0; } @@ -492,13 +526,17 @@ int kmscon_font_draw(struct kmscon_font *font, const struct kmscon_char *ch, if (ret) return ret; - cairo_move_to(cr, x, y); - switch (glyph->type) { case GLYPH_LAYOUT: + cairo_move_to(cr, x, y); pango_cairo_update_layout(cr, glyph->src.layout.layout); pango_cairo_show_layout(cr, glyph->src.layout.layout); break; + case GLYPH_STR: + cairo_move_to(cr, x, y + glyph->src.str.ascent); + pango_cairo_show_glyph_string(cr, glyph->src.str.font, + glyph->src.str.str); + break; default: ret = -EFAULT; break;