summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2007-02-23 11:23:55 +0000
committerChris Wilson <cpwilson@src.gnome.org>2007-02-23 11:23:55 +0000
commit7e2654510c7fe848162021a698ddba2b90cf7d59 (patch)
tree9fb71782d78a56018f25753278c5e9cffb113286
parent4074098e6fc909d6ae0dfe027303ac9887a10809 (diff)
downloadvte-7e2654510c7fe848162021a698ddba2b90cf7d59.tar.gz
Cache the font metrics on the vte_xft_font, avoids having to remeasure
2007-02-23 Chris Wilson <chris@chris-wilson.co.uk> Cache the font metrics on the vte_xft_font, avoids having to remeasure when opening a new terminal. * src/vtexft.c: (_vte_xft_font_open), (_vte_xft_set_text_font): svn path=/trunk/; revision=1727
-rw-r--r--ChangeLog7
-rw-r--r--src/vtexft.c173
2 files changed, 102 insertions, 78 deletions
diff --git a/ChangeLog b/ChangeLog
index 86de7eb4..13db6b8e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2007-02-23 Chris Wilson <chris@chris-wilson.co.uk>
+ Cache the font metrics on the vte_xft_font, avoids having to remeasure
+ when opening a new terminal.
+
+ * src/vtexft.c: (_vte_xft_font_open), (_vte_xft_set_text_font):
+
+2007-02-23 Chris Wilson <chris@chris-wilson.co.uk>
+
Share XftFonts between terminal backends and preserve faces from the
previous draw - helps prevents font cache thrashing inside libXft.
diff --git a/src/vtexft.c b/src/vtexft.c
index fa4b6c29..a5782406 100644
--- a/src/vtexft.c
+++ b/src/vtexft.c
@@ -49,6 +49,9 @@ struct _vte_xft_font {
VteTree *fontmap;
VteTree *widths;
guint last_pattern;
+
+ gint width, height, ascent;
+ gboolean have_metrics;
};
struct _vte_xft_data {
@@ -143,6 +146,7 @@ _vte_xft_font_open (GtkWidget *widget, const PangoFontDescription *fontdesc,
font->display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget));
font->patterns = patterns;
font->last_pattern = 0;
+ font->have_metrics = FALSE;
if (font_cache == NULL) {
font_cache = g_hash_table_new (
@@ -586,15 +590,8 @@ _vte_xft_set_text_font (struct _vte_draw *draw,
const PangoFontDescription *fontdesc,
VteTerminalAntiAlias antialias)
{
- struct _vte_xft_font *ft;
- XftFont *font, *prev_font;
- XGlyphInfo extents;
struct _vte_xft_data *data;
- gunichar wide_chars[] = {VTE_DRAW_DOUBLE_WIDE_CHARACTERS};
- guint i;
- gint n, width, height, min = G_MAXINT, max = G_MININT;
- FcChar32 c;
- GPtrArray *locked_fonts;
+ struct _vte_xft_font *ft;
data = (struct _vte_xft_data*) draw->impl_data;
@@ -610,86 +607,106 @@ _vte_xft_set_text_font (struct _vte_draw *draw,
return;
}
- gdk_error_trap_push ();
data->locked_fonts[0] = ptr_array_zeroed_new (data->font->patterns->len);
data->locked_fonts[1] = ptr_array_zeroed_new (data->font->patterns->len);
- locked_fonts = data->locked_fonts [data->cur_locked_fonts&1];
-
- draw->width = 1;
- draw->height = 1;
- draw->ascent = 1;
-
- n = width = height = 0;
- /* Estimate a typical cell width by looking at single-width
- * characters. */
- for (i = 0; i < sizeof (VTE_DRAW_SINGLE_WIDE_CHARACTERS) - 1; i++) {
- c = VTE_DRAW_SINGLE_WIDE_CHARACTERS[i];
- font = _vte_xft_font_for_char (data->font, c, locked_fonts);
- if (font != NULL) {
- memset (&extents, 0, sizeof (extents));
- _vte_xft_text_extents (data->font, font, c, &extents);
- n++;
- width += extents.xOff;
- if (extents.xOff < min) {
- min = extents.xOff;
- }
- if (extents.xOff > max) {
- max = extents.xOff;
- }
- if (extents.height > height) {
- height = extents.height;
+
+ if (data->font->have_metrics) {
+ draw->width = data->font->width;
+ draw->height = data->font->height;
+ draw->ascent = data->font->ascent;
+ } else {
+ XftFont *font, *prev_font;
+ XGlyphInfo extents;
+ gunichar wide_chars[] = {VTE_DRAW_DOUBLE_WIDE_CHARACTERS};
+ guint i;
+ gint n, width, height, min = G_MAXINT, max = G_MININT;
+ FcChar32 c;
+ GPtrArray *locked_fonts;
+
+ draw->width = 1;
+ draw->height = 1;
+ draw->ascent = 1;
+
+ locked_fonts = data->locked_fonts [data->cur_locked_fonts&1];
+
+ gdk_error_trap_push ();
+ n = width = height = 0;
+ /* Estimate a typical cell width by looking at single-width
+ * characters. */
+ for (i = 0; i < sizeof (VTE_DRAW_SINGLE_WIDE_CHARACTERS) - 1; i++) {
+ c = VTE_DRAW_SINGLE_WIDE_CHARACTERS[i];
+ font = _vte_xft_font_for_char (data->font, c, locked_fonts);
+ if (font != NULL) {
+ memset (&extents, 0, sizeof (extents));
+ _vte_xft_text_extents (data->font, font, c, &extents);
+ n++;
+ width += extents.xOff;
+ if (extents.xOff < min) {
+ min = extents.xOff;
+ }
+ if (extents.xOff > max) {
+ max = extents.xOff;
+ }
+ if (extents.height > height) {
+ height = extents.height;
+ }
}
}
- }
- if (n > 0) {
- draw->width = howmany (width, n);
- draw->height = (font != NULL) ?
- font->ascent + font->descent : height;
- draw->ascent = (font != NULL) ?
- font->ascent : height;
- }
- /* Estimate a typical cell width by looking at double-width
- * characters, and if it's the same as the single width, assume the
- * single-width stuff is broken. */
- n = width = 0;
- prev_font = NULL;
- for (i = 0; i < G_N_ELEMENTS (wide_chars); i++) {
- c = wide_chars[i];
- font = _vte_xft_font_for_char (data->font, c, locked_fonts);
- if (font != NULL) {
- if (n && prev_font != font) {/* font change */
- width = howmany (width, n);
- if (width >= draw->width -1 &&
- width <= draw->width + 1){
- /* add 1 to round up when dividing by 2 */
- draw->width = (draw->width + 1) / 2;
- break;
+ if (n > 0) {
+ draw->width = howmany (width, n);
+ draw->height = (font != NULL) ?
+ font->ascent + font->descent : height;
+ draw->ascent = (font != NULL) ?
+ font->ascent : height;
+ }
+ /* Estimate a typical cell width by looking at double-width
+ * characters, and if it's the same as the single width, assume the
+ * single-width stuff is broken. */
+ n = width = 0;
+ prev_font = NULL;
+ for (i = 0; i < G_N_ELEMENTS (wide_chars); i++) {
+ c = wide_chars[i];
+ font = _vte_xft_font_for_char (data->font, c, locked_fonts);
+ if (font != NULL) {
+ if (n && prev_font != font) {/* font change */
+ width = howmany (width, n);
+ if (width >= draw->width -1 &&
+ width <= draw->width + 1){
+ /* add 1 to round up when dividing by 2 */
+ draw->width = (draw->width + 1) / 2;
+ break;
+ }
+ n = width = 0;
}
- n = width = 0;
+ memset (&extents, 0, sizeof (extents));
+ _vte_xft_text_extents (data->font, font, c, &extents);
+ n++;
+ width += extents.xOff;
+ prev_font = font;
}
- memset (&extents, 0, sizeof (extents));
- _vte_xft_text_extents (data->font, font, c, &extents);
- n++;
- width += extents.xOff;
- prev_font = font;
}
- }
- if (n > 0) {
- width = howmany (width, n);
- if (width >= draw->width -1 &&
- width <= draw->width + 1){
- /* add 1 to round up when dividing by 2 */
- draw->width = (draw->width + 1) / 2;
+ if (n > 0) {
+ width = howmany (width, n);
+ if (width >= draw->width -1 &&
+ width <= draw->width + 1){
+ /* add 1 to round up when dividing by 2 */
+ draw->width = (draw->width + 1) / 2;
+ }
}
- }
- gdk_error_trap_pop ();
+ gdk_error_trap_pop ();
- _vte_debug_print (VTE_DEBUG_MISC,
- "VteXft font metrics = %dx%d (%d),"
- " width range [%d, %d].\n",
- draw->width, draw->height, draw->ascent,
- min, max);
+ data->font->width = draw->width;
+ data->font->height = draw->height;
+ data->font->ascent = draw->ascent;
+ data->font->have_metrics = TRUE;
+
+ _vte_debug_print (VTE_DEBUG_MISC,
+ "VteXft font metrics = %dx%d (%d),"
+ " width range [%d, %d].\n",
+ draw->width, draw->height, draw->ascent,
+ min, max);
+ }
}
static int