diff options
author | Behdad Esfahbod <behdad@gnome.org> | 2008-12-08 20:17:00 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2008-12-08 20:17:00 +0000 |
commit | 63b25ac4c6669ffd33cfd0dac8913e3a029251d3 (patch) | |
tree | 094a33a020fd109fd15e4aece17b5d2c45fc299b | |
parent | d849a02007d2dffdf78c55afea4bf1ffcc526a31 (diff) | |
download | vte-63b25ac4c6669ffd33cfd0dac8913e3a029251d3.tar.gz |
Bug 563752 – pangocairo backend recreates cairo_surface_t for background
2008-12-08 Behdad Esfahbod <behdad@gnome.org>
Bug 563752 – pangocairo backend recreates cairo_surface_t for
background drawing
* src/vte.c (vte_terminal_paint),
(vte_terminal_set_scroll_background),
(vte_terminal_background_update):
* src/vtedraw.c (_vte_draw_new), (_vte_draw_set_background_solid),
(_vte_draw_set_background_image),
(_vte_draw_set_background_scroll), (_vte_draw_draw_rectangle):
* src/vtedraw.h:
* src/vtepangocairo.c (_vte_pangocairo_destroy),
(_vte_pangocairo_set_background_solid),
(_vte_pangocairo_set_background_image),
(_vte_pangocairo_set_background_scroll), (_vte_pangocairo_clear),
(_vte_pangocairo_clip), (set_source_color_alpha):
* src/vteskel.c:
Cleanup vte_draw background API. Use a cached cairo_pattern_t in
pangocairo backend.
Also, queue background update on scroll_background change.
svn path=/trunk/; revision=2335
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | src/vte.c | 17 | ||||
-rw-r--r-- | src/vtedraw.c | 55 | ||||
-rw-r--r-- | src/vtedraw.h | 32 | ||||
-rw-r--r-- | src/vtepangocairo.c | 127 | ||||
-rw-r--r-- | src/vteskel.c | 2 |
6 files changed, 152 insertions, 104 deletions
@@ -1,3 +1,26 @@ +2008-12-08 Behdad Esfahbod <behdad@gnome.org> + + Bug 563752 – pangocairo backend recreates cairo_surface_t for + background drawing + + * src/vte.c (vte_terminal_paint), + (vte_terminal_set_scroll_background), + (vte_terminal_background_update): + * src/vtedraw.c (_vte_draw_new), (_vte_draw_set_background_solid), + (_vte_draw_set_background_image), + (_vte_draw_set_background_scroll), (_vte_draw_draw_rectangle): + * src/vtedraw.h: + * src/vtepangocairo.c (_vte_pangocairo_destroy), + (_vte_pangocairo_set_background_solid), + (_vte_pangocairo_set_background_image), + (_vte_pangocairo_set_background_scroll), (_vte_pangocairo_clear), + (_vte_pangocairo_clip), (set_source_color_alpha): + * src/vteskel.c: + Cleanup vte_draw background API. Use a cached cairo_pattern_t in + pangocairo backend. + + Also, queue background update on scroll_background change. + 2008-12-07 Behdad Esfahbod <behdad@gnome.org> Bug 163213 – Cursor should remain visible when selected @@ -10759,15 +10759,15 @@ vte_terminal_paint(GtkWidget *widget, GdkRegion *region) if (terminal->pvt->bg_transparent) { int x, y; gdk_window_get_origin(widget->window, &x, &y); - _vte_draw_set_scroll(terminal->pvt->draw, x, y); + _vte_draw_set_background_scroll(terminal->pvt->draw, x, y); } else { if (terminal->pvt->scroll_background) { - _vte_draw_set_scroll(terminal->pvt->draw, - 0, - terminal->pvt->screen->scroll_delta * - terminal->char_height); + _vte_draw_set_background_scroll(terminal->pvt->draw, + 0, + terminal->pvt->screen->scroll_delta * + terminal->char_height); } else { - _vte_draw_set_scroll(terminal->pvt->draw, 0, 0); + _vte_draw_set_background_scroll(terminal->pvt->draw, 0, 0); } } @@ -12175,6 +12175,8 @@ vte_terminal_set_scroll_background(VteTerminal *terminal, gboolean scroll) pvt->scroll_background = scroll; g_object_notify (G_OBJECT (terminal), "scroll-background"); + + vte_terminal_queue_background_update(terminal); } /** @@ -12362,8 +12364,7 @@ vte_terminal_background_update(VteTerminal *terminal) bgcolor.red, bgcolor.green, bgcolor.blue, bgcolor.pixel); gdk_window_set_background(terminal->widget.window, &bgcolor); - _vte_draw_set_background_color (terminal->pvt->draw, &bgcolor); - _vte_draw_set_background_opacity (terminal->pvt->draw, terminal->pvt->bg_opacity); + _vte_draw_set_background_solid (terminal->pvt->draw, &bgcolor, terminal->pvt->bg_opacity); /* If we're transparent, and either have no root image or are being * told to update it, get a new copy of the root window. */ diff --git a/src/vtedraw.c b/src/vtedraw.c index 6ad9cc11..76628ace 100644 --- a/src/vtedraw.c +++ b/src/vtedraw.c @@ -107,14 +107,6 @@ _vte_draw_init_default (struct _vte_draw *draw) } -static void -_vte_draw_update_requires_clear (struct _vte_draw *draw) -{ - draw->requires_clear = draw->impl->always_requires_clear - || draw->bg_type != VTE_BG_SOURCE_NONE - || draw->bg_opacity != 0xFFFF; -} - struct _vte_draw * _vte_draw_new (GtkWidget *widget) { @@ -123,8 +115,6 @@ _vte_draw_new (GtkWidget *widget) /* Create the structure. */ draw = g_slice_new0 (struct _vte_draw); draw->widget = g_object_ref (widget); - draw->bg_type = VTE_BG_SOURCE_NONE; - draw->bg_opacity = 0xffff; /* Allow the user to specify her preferred backends */ if (!_vte_draw_init_user (draw) && @@ -135,7 +125,7 @@ _vte_draw_new (GtkWidget *widget) draw->impl = &_vte_draw_skel; } - _vte_draw_update_requires_clear (draw); + draw->requires_clear = draw->impl->always_requires_clear; _vte_debug_print (VTE_DEBUG_DRAW, "draw_new (%s)\n", draw->impl->name); @@ -225,18 +215,14 @@ _vte_draw_end (struct _vte_draw *draw) } void -_vte_draw_set_background_opacity (struct _vte_draw *draw, - guint16 opacity) +_vte_draw_set_background_solid(struct _vte_draw *draw, + GdkColor *color, + guint16 opacity) { - draw->bg_opacity = opacity; - _vte_draw_update_requires_clear (draw); -} + draw->requires_clear = draw->impl->always_requires_clear || opacity != 0xFFFF; -void -_vte_draw_set_background_color (struct _vte_draw *draw, - GdkColor *color) -{ - draw->bg_color = *color; + if (draw->impl->set_background_solid) + draw->impl->set_background_solid (draw, color, opacity); } void @@ -247,14 +233,26 @@ _vte_draw_set_background_image (struct _vte_draw *draw, const GdkColor *color, double saturation) { - draw->bg_type = type; - _vte_draw_update_requires_clear (draw); + if (type != VTE_BG_SOURCE_NONE) + draw->requires_clear = TRUE; if (draw->impl->set_background_image) draw->impl->set_background_image (draw, type, pixbuf, filename, color, saturation); } +void +_vte_draw_set_background_scroll (struct _vte_draw *draw, + gint x, gint y) +{ + _vte_debug_print (VTE_DEBUG_DRAW, + "draw_set_scroll (%d, %d)\n", + x, y); + + if (draw->impl->set_background_scroll) + draw->impl->set_background_scroll (draw, x, y); +} + gboolean _vte_draw_requires_clear (struct _vte_draw *draw) { @@ -427,14 +425,3 @@ _vte_draw_draw_rectangle (struct _vte_draw *draw, } } } - -void -_vte_draw_set_scroll (struct _vte_draw *draw, gint x, gint y) -{ - _vte_debug_print (VTE_DEBUG_DRAW, - "draw_set_scroll (%d, %d)\n", - x, y); - - draw->scrollx = x; - draw->scrolly = y; -} diff --git a/src/vtedraw.h b/src/vtedraw.h index c8d863f2..dbf29261 100644 --- a/src/vtedraw.h +++ b/src/vtedraw.h @@ -68,12 +68,17 @@ struct _vte_draw_impl { GdkColormap* (*get_colormap)(struct _vte_draw *draw); void (*start)(struct _vte_draw *draw); void (*end)(struct _vte_draw *draw); + void (*set_background_solid)(struct _vte_draw *, + GdkColor *color, + guint16 opacity); void (*set_background_image)(struct _vte_draw *, enum VteBgSourceType type, GdkPixbuf *pixbuf, const char *file, const GdkColor *color, double saturation); + void (*set_background_scroll)(struct _vte_draw *, + gint, gint); void (*clip)(struct _vte_draw *, GdkRegion *); gboolean always_requires_clear; void (*clear)(struct _vte_draw *, gint, gint, gint, gint); @@ -99,12 +104,6 @@ struct _vte_draw { gboolean started; - guint16 bg_opacity; - GdkColor bg_color; - enum VteBgSourceType bg_type; - - gint scrollx, scrolly; - gboolean requires_clear; const struct _vte_draw_impl *impl; @@ -129,33 +128,30 @@ GdkColormap *_vte_draw_get_colormap(struct _vte_draw *draw, void _vte_draw_start(struct _vte_draw *draw); void _vte_draw_end(struct _vte_draw *draw); -/* Set the background color, a background pixbuf (if you want transparency, - you'll have to do that yourself), and clear an area to the default. */ -void _vte_draw_set_background_opacity(struct _vte_draw *draw, - guint16 opacity); -void _vte_draw_set_background_color(struct _vte_draw *draw, - GdkColor *color); +void _vte_draw_set_background_solid(struct _vte_draw *draw, + GdkColor *color, + guint16 opacity); void _vte_draw_set_background_image(struct _vte_draw *draw, enum VteBgSourceType type, GdkPixbuf *pixbuf, const char *file, const GdkColor *color, double saturation); -gboolean _vte_draw_requires_clear (struct _vte_draw *draw); +void _vte_draw_set_background_scroll(struct _vte_draw *draw, + gint x, gint y); + gboolean _vte_draw_clip(struct _vte_draw *draw, GdkRegion *region); +gboolean _vte_draw_requires_clear (struct _vte_draw *draw); void _vte_draw_clear(struct _vte_draw *draw, gint x, gint y, gint width, gint height); -/* Set the font which will be used to draw text. */ void _vte_draw_set_text_font(struct _vte_draw *draw, const PangoFontDescription *fontdesc, VteTerminalAntiAlias anti_alias); -/* Read font metrics. */ void _vte_draw_get_text_metrics(struct _vte_draw *draw, gint *width, gint *height, gint *ascent); int _vte_draw_get_char_width(struct _vte_draw *draw, gunichar c, int columns); -/* Draw text or rectangles. */ void _vte_draw_text(struct _vte_draw *draw, struct _vte_draw_text_request *requests, gsize n_requests, GdkColor *color, guchar alpha); @@ -163,6 +159,7 @@ gboolean _vte_draw_char(struct _vte_draw *draw, struct _vte_draw_text_request *request, GdkColor *color, guchar alpha); gboolean _vte_draw_has_char(struct _vte_draw *draw, gunichar c); + void _vte_draw_fill_rectangle(struct _vte_draw *draw, gint x, gint y, gint width, gint height, GdkColor *color, guchar alpha); @@ -170,9 +167,6 @@ void _vte_draw_draw_rectangle(struct _vte_draw *draw, gint x, gint y, gint width, gint height, GdkColor *color, guchar alpha); -/* Set the scrolling offset for painting in a pixbuf background. */ -void _vte_draw_set_scroll(struct _vte_draw *draw, gint x, gint y); - G_END_DECLS #endif diff --git a/src/vtepangocairo.c b/src/vtepangocairo.c index 221bf3b0..5e78fa16 100644 --- a/src/vtepangocairo.c +++ b/src/vtepangocairo.c @@ -750,27 +750,12 @@ font_info_get_unichar_info (struct font_info *info, struct _vte_pangocairo_data { struct font_info *font; + cairo_pattern_t *bg_pattern; cairo_t *cr; - - GdkPixmap *pixmap; - gint pixmapw, pixmaph; }; static void -set_source_color_alpha (cairo_t *cr, - const GdkColor *color, - guchar alpha) -{ - cairo_set_source_rgba (cr, - color->red / 65535., - color->green / 65535., - color->blue / 65535., - alpha / 255.); -} - - -static void _vte_pangocairo_create (struct _vte_draw *draw, GtkWidget *widget) { struct _vte_pangocairo_data *data; @@ -784,9 +769,9 @@ _vte_pangocairo_destroy (struct _vte_draw *draw) { struct _vte_pangocairo_data *data = draw->impl_data; - if (data->pixmap != NULL) { - g_object_unref (data->pixmap); - data->pixmap = NULL; + if (data->bg_pattern != NULL) { + cairo_pattern_destroy (data->bg_pattern); + data->bg_pattern = NULL; } if (data->font != NULL) { @@ -817,6 +802,22 @@ _vte_pangocairo_end (struct _vte_draw *draw) } static void +_vte_pangocairo_set_background_solid(struct _vte_draw *draw, + GdkColor *color, + guint16 opacity) +{ + struct _vte_pangocairo_data *data = draw->impl_data; + + if (data->bg_pattern) + cairo_pattern_destroy (data->bg_pattern); + + data->bg_pattern = cairo_pattern_create_rgba (color->red / 65535., + color->green / 65535., + color->blue / 65535., + opacity / 65535.); +} + +static void _vte_pangocairo_set_background_image (struct _vte_draw *draw, enum VteBgSourceType type, GdkPixbuf *pixbuf, @@ -826,34 +827,56 @@ _vte_pangocairo_set_background_image (struct _vte_draw *draw, { struct _vte_pangocairo_data *data = draw->impl_data; GdkPixmap *pixmap; - GdkScreen *screen; - if (data->pixmap != NULL) { - g_object_unref(data->pixmap); + if (type == VTE_BG_SOURCE_NONE) + return; + + if (data->bg_pattern) { + cairo_pattern_destroy (data->bg_pattern); + data->bg_pattern = NULL; } - screen = gtk_widget_get_screen(draw->widget); - pixmap = vte_bg_get_pixmap(vte_bg_get_for_screen(screen), - type, pixbuf, file, - color, saturation, - _vte_draw_get_colormap(draw, TRUE)); + pixmap = vte_bg_get_pixmap (vte_bg_get_for_screen (gtk_widget_get_screen (draw->widget)), + type, pixbuf, file, + color, saturation, + _vte_draw_get_colormap(draw, TRUE)); - data->pixmap = NULL; - data->pixmapw = data->pixmaph = 0; if (pixmap) { - gdk_drawable_get_size(pixmap, &data->pixmapw, &data->pixmaph); - data->pixmap = pixmap; + + /* Ugh... We need to create a dummy cairo_t */ + cairo_surface_t *surface; + cairo_t *cr; + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0); + cr = cairo_create (surface); + + gdk_cairo_set_source_pixmap (cr, pixmap, 0, 0); + data->bg_pattern = cairo_pattern_reference (cairo_get_source (cr)); + + cairo_destroy (cr); + cairo_surface_destroy (surface); + + /* Transfer the pixmap ownership to the pattern */ + cairo_pattern_set_user_data (data->bg_pattern, + (cairo_user_data_key_t *) data, + pixmap, + (cairo_destroy_func_t) g_object_unref); + + cairo_pattern_set_extend (data->bg_pattern, CAIRO_EXTEND_REPEAT); } } static void -_vte_pangocairo_clip (struct _vte_draw *draw, - GdkRegion *region) +_vte_pangocairo_set_background_scroll (struct _vte_draw *draw, + gint x, gint y) { struct _vte_pangocairo_data *data = draw->impl_data; + cairo_matrix_t matrix; - gdk_cairo_region(data->cr, region); - cairo_clip (data->cr); + g_return_if_fail (data->bg_pattern != NULL); + + cairo_matrix_init_translate (&matrix, x, y); + cairo_pattern_set_matrix (data->bg_pattern, &matrix); } static void @@ -862,18 +885,22 @@ _vte_pangocairo_clear (struct _vte_draw *draw, { struct _vte_pangocairo_data *data = draw->impl_data; + g_return_if_fail (data->bg_pattern != NULL); + cairo_rectangle (data->cr, x, y, width, height); cairo_set_operator (data->cr, CAIRO_OPERATOR_SOURCE); + cairo_set_source (data->cr, data->bg_pattern); + cairo_fill (data->cr); +} - if (data->pixmap == NULL) { - set_source_color_alpha (data->cr, &draw->bg_color, draw->bg_opacity >> 8); - } else { - gdk_cairo_set_source_pixmap (data->cr, data->pixmap, - -draw->scrollx, -draw->scrolly); - cairo_pattern_set_extend (cairo_get_source (data->cr), CAIRO_EXTEND_REPEAT); - } +static void +_vte_pangocairo_clip (struct _vte_draw *draw, + GdkRegion *region) +{ + struct _vte_pangocairo_data *data = draw->impl_data; - cairo_fill (data->cr); + gdk_cairo_region(data->cr, region); + cairo_clip (data->cr); } static void @@ -914,6 +941,18 @@ _vte_pangocairo_get_char_width (struct _vte_draw *draw, gunichar c, int columns) } static void +set_source_color_alpha (cairo_t *cr, + const GdkColor *color, + guchar alpha) +{ + cairo_set_source_rgba (cr, + color->red / 65535., + color->green / 65535., + color->blue / 65535., + alpha / 255.); +} + +static void _vte_pangocairo_draw_text (struct _vte_draw *draw, struct _vte_draw_text_request *requests, gsize n_requests, GdkColor *color, guchar alpha) @@ -1027,7 +1066,9 @@ const struct _vte_draw_impl _vte_draw_pangocairo = { NULL, /* get_colormap */ _vte_pangocairo_start, _vte_pangocairo_end, + _vte_pangocairo_set_background_solid, _vte_pangocairo_set_background_image, + _vte_pangocairo_set_background_scroll, _vte_pangocairo_clip, FALSE, /* always_requires_clear */ _vte_pangocairo_clear, diff --git a/src/vteskel.c b/src/vteskel.c index 53e8bcb7..107842f6 100644 --- a/src/vteskel.c +++ b/src/vteskel.c @@ -69,7 +69,9 @@ const struct _vte_draw_impl _vte_draw_skel = { NULL, /* get_colormap */ NULL, /* start */ NULL, /* end */ + NULL, /* set_background_solid */ NULL, /* set_background_image */ + NULL, /* set_background_scroll */ NULL, /* clip */ TRUE, /* always_requires_clear */ _vte_skel_clear, |