summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2007-02-27 00:55:44 +0000
committerChris Wilson <cpwilson@src.gnome.org>2007-02-27 00:55:44 +0000
commit854cc5c5038cdabf73e8898a5c0b25364b01a03a (patch)
tree0751d4e0d72e35b23350010cc54795b26448dfbd
parent106d4ffedb96b12ebd7fee050796c858773d0669 (diff)
downloadvte-854cc5c5038cdabf73e8898a5c0b25364b01a03a.tar.gz
Avoid some computations whilst drawing text.
2007-02-27 Chris Wilson <chris@chris-wilson.co.uk> * src/vtexft.c (_vte_xft_open_font_for_char), (_vte_xft_font_for_char), (_vte_xft_compute_char_width), (_vte_xft_char_width), (_vte_xft_start), (_vte_xft_get_char_width), (_vte_xft_draw_text): Avoid some computations whilst drawing text. svn path=/trunk/; revision=1766
-rw-r--r--ChangeLog8
-rw-r--r--src/vtexft.c148
2 files changed, 90 insertions, 66 deletions
diff --git a/ChangeLog b/ChangeLog
index 68f624f1..c54018a8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-02-27 Chris Wilson <chris@chris-wilson.co.uk>
+
+ * src/vtexft.c (_vte_xft_open_font_for_char),
+ (_vte_xft_font_for_char), (_vte_xft_compute_char_width),
+ (_vte_xft_char_width), (_vte_xft_start), (_vte_xft_get_char_width),
+ (_vte_xft_draw_text):
+ Avoid some computations whilst drawing text.
+
2007-02-26 Behdad Esfahbod <behdad@gnome.org>
Released vte-0.15.4.
diff --git a/src/vtexft.c b/src/vtexft.c
index 4c973a76..65cf1440 100644
--- a/src/vtexft.c
+++ b/src/vtexft.c
@@ -210,29 +210,11 @@ _vte_xft_font_close (struct _vte_xft_font *font)
}
static XftFont *
-_vte_xft_font_for_char (struct _vte_xft_font *font, gunichar c, GPtrArray *locked_fonts)
+_vte_xft_open_font_for_char (struct _vte_xft_font *font, gunichar c, GPtrArray *locked_fonts)
{
+ gpointer p = GINT_TO_POINTER (c);
guint i, j;
XftFont *ftfont;
- gpointer p = GINT_TO_POINTER (c);
-
- /* Check if we have a char-to-font entry for it. */
- i = GPOINTER_TO_INT (_vte_tree_lookup (font->fontmap, p));
- if (i != 0) {
- switch (i) {
- /* Checked before, no luck. */
- case -FONT_INDEX_FUDGE:
- return NULL;
- /* Matched before. */
- default:
- ftfont = g_ptr_array_index (font->fonts, i);
- if (g_ptr_array_index (locked_fonts, i) == NULL) {
- XftLockFace (ftfont);
- g_ptr_array_index (locked_fonts, i) = ftfont;
- }
- return ftfont;
- }
- }
/* Look the character up in the fonts we have. */
for (i = 1; i < font->fonts->len; i++) {
@@ -277,38 +259,71 @@ _vte_xft_font_for_char (struct _vte_xft_font *font, gunichar c, GPtrArray *locke
g_warning (_ ("Can not find appropiate font for character U+%04x.\n"), c);
return NULL;
}
-
-static int
-_vte_xft_char_width (struct _vte_xft_font *font, XftFont *ftfont, gunichar c)
+static inline XftFont *
+_vte_xft_font_for_char (struct _vte_xft_font *font, gunichar c, GPtrArray *locked_fonts)
{
- XGlyphInfo extents;
- gpointer p = GINT_TO_POINTER (c);
- gint i;
+ guint i;
+ XftFont *ftfont;
- /* Check if we have a char-to-width entry for it. */
- i = GPOINTER_TO_INT (_vte_tree_lookup (font->widths, p));
- if (i != 0) {
+ /* Check if we have a char-to-font entry for it. */
+ i = GPOINTER_TO_INT (_vte_tree_lookup (
+ font->fontmap, GINT_TO_POINTER (c)));
+ if (G_LIKELY (i != 0)) {
switch (i) {
- case -CHAR_WIDTH_FUDGE:
- return 0;
+ /* Checked before, no luck. */
+ case -FONT_INDEX_FUDGE:
+ return NULL;
+ /* Matched before. */
default:
- return i;
+ ftfont = g_ptr_array_index (font->fonts, i);
+ if (g_ptr_array_index (locked_fonts, i) == NULL) {
+ XftLockFace (ftfont);
+ g_ptr_array_index (locked_fonts, i) = ftfont;
+ }
+ return ftfont;
}
- }
+ } else
+ return _vte_xft_open_font_for_char (font, c, locked_fonts);
+}
+
+static gint _vte_xft_compute_char_width (struct _vte_xft_font *font, XftFont *ftfont, gunichar c, int columns)
+{
+ XGlyphInfo extents;
+ gint width;
/* Compute and store the width. */
memset (&extents, 0, sizeof (extents));
if (ftfont != NULL) {
_vte_xft_text_extents (font, ftfont, c, &extents);
}
- if (extents.xOff == 0) {
- i = -CHAR_WIDTH_FUDGE;
+ if (extents.xOff == 0 || extents.xOff == font->width * columns) {
+ width = -CHAR_WIDTH_FUDGE;
} else {
- i = extents.xOff;
+ width = extents.xOff;
}
- _vte_tree_insert (font->widths, p, GINT_TO_POINTER (i));
+ _vte_tree_insert (font->widths,
+ GINT_TO_POINTER (c), GINT_TO_POINTER (width));
return extents.xOff;
}
+static inline gint
+_vte_xft_char_width (struct _vte_xft_font *font, XftFont *ftfont, gunichar c, int columns)
+{
+ gint width;
+
+ /* Check if we have a char-to-width entry for it. */
+ width = GPOINTER_TO_INT (_vte_tree_lookup (
+ font->widths, GINT_TO_POINTER (c)));
+ if (G_LIKELY (width != 0)) {
+ switch (width) {
+ case -CHAR_WIDTH_FUDGE:
+ return 0;
+ default:
+ return width;
+ }
+ } else
+ return _vte_xft_compute_char_width (font, ftfont, c, columns);
+
+}
static gboolean
_vte_xft_check (struct _vte_draw *draw, GtkWidget *widget)
@@ -400,6 +415,8 @@ _vte_xft_start (struct _vte_draw *draw)
gcolormap = gdk_drawable_get_colormap (drawable);
data->colormap = gdk_x11_colormap_get_xcolormap (gcolormap);
+ g_assert (data->display == data->font->display);
+
gdk_error_trap_push ();
if (data->draw != NULL) {
@@ -708,19 +725,19 @@ _vte_xft_set_text_font (struct _vte_draw *draw,
}
}
-static int
+static inline int
_vte_xft_get_text_width (struct _vte_draw *draw)
{
return draw->width;
}
-static int
+static inline int
_vte_xft_get_text_height (struct _vte_draw *draw)
{
return draw->height;
}
-static int
+static inline int
_vte_xft_get_text_ascent (struct _vte_draw *draw)
{
return draw->ascent;
@@ -731,17 +748,20 @@ _vte_xft_get_char_width (struct _vte_draw *draw, gunichar c, int columns)
{
struct _vte_xft_data *data;
XftFont *ftfont;
+ int width;
data = (struct _vte_xft_data*) draw->impl_data;
- if (data->font == NULL) {
- return _vte_xft_get_text_width (draw) * columns;
- }
- ftfont = _vte_xft_font_for_char (data->font, c,
- data->locked_fonts[data->cur_locked_fonts&1]);
- if (ftfont == NULL) {
- return _vte_xft_get_text_width (draw) * columns;
+ if (data->font != NULL) {
+ ftfont = _vte_xft_font_for_char (data->font, c,
+ data->locked_fonts[data->cur_locked_fonts&1]);
+ if (ftfont != NULL) {
+ width = _vte_xft_char_width (data->font, ftfont, c, columns);
+ if (width != 0) {
+ return width;
+ }
+ }
}
- return _vte_xft_char_width (data->font, ftfont, c);
+ return _vte_xft_get_text_width (draw) * columns;
}
static gboolean
@@ -760,7 +780,7 @@ _vte_xft_draw_text (struct _vte_draw *draw,
XftColor ftcolor;
struct _vte_xft_data *data;
gsize i, j;
- gint width, pad;
+ gint width, y_off, x_off;
XftFont *font, *ft;
GPtrArray *locked_fonts;
@@ -798,28 +818,27 @@ _vte_xft_draw_text (struct _vte_draw *draw,
* "We need to break down the draw request into runs which use the same
* font, to work around a bug which appears to be in Xft and which I
* haven't pinned down yet." */
+ x_off = -data->x_offs;
+ y_off = draw->ascent - data->y_offs;
do {
j = 0;
do {
glyphs[j].glyph = XftCharIndex (data->display,
font, requests[i].c);
- if (G_LIKELY (glyphs[j].glyph != 0)) {
- glyphs[j].x = requests[i].x - data->x_offs;
- width = _vte_xft_char_width (data->font,
- font, requests[i].c);
- if (width != 0) {
- pad = requests[i].columns * draw->width - width;
- pad = CLAMP (pad / 2, 0, draw->width);
- glyphs[j].x += pad;
- }
- glyphs[j].y = requests[i].y - data->y_offs + draw->ascent;
- j++;
+ glyphs[j].x = requests[i].x + x_off;
+ width = _vte_xft_char_width (data->font,
+ font, requests[i].c, requests[i].columns);
+ if (G_UNLIKELY (width != 0)) {
+ width = requests[i].columns * draw->width - width;
+ width = CLAMP (width / 2, 0, draw->width);
+ glyphs[j].x += width;
}
- i++;
+ glyphs[j].y = requests[i].y + y_off;
+ j++;
/* find the next displayable character ... */
ft = NULL;
- for (; i < n_requests; i++) {
+ while (++i < n_requests) {
ft = _vte_xft_font_for_char (data->font,
requests[i].c, locked_fonts);
if (G_UNLIKELY (ft == NULL)) {
@@ -828,10 +847,7 @@ _vte_xft_draw_text (struct _vte_draw *draw,
break;
}
} while (j < VTE_DRAW_MAX_LENGTH && ft == font);
- if (j > 0) {
- XftDrawGlyphSpec (data->draw,
- &ftcolor, font, glyphs, j);
- }
+ XftDrawGlyphSpec (data->draw, &ftcolor, font, glyphs, j);
font = ft;
} while (i < n_requests);
XftColorFree (data->display, data->visual,