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 <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2011-11-26 17:54:56 +01:00
parent 9e2c14a7ca
commit 264fff909e

View File

@ -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;