summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@gnome.org>2008-12-08 20:17:00 +0000
committerBehdad Esfahbod <behdad@src.gnome.org>2008-12-08 20:17:00 +0000
commit63b25ac4c6669ffd33cfd0dac8913e3a029251d3 (patch)
tree094a33a020fd109fd15e4aece17b5d2c45fc299b
parentd849a02007d2dffdf78c55afea4bf1ffcc526a31 (diff)
downloadvte-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--ChangeLog23
-rw-r--r--src/vte.c17
-rw-r--r--src/vtedraw.c55
-rw-r--r--src/vtedraw.h32
-rw-r--r--src/vtepangocairo.c127
-rw-r--r--src/vteskel.c2
6 files changed, 152 insertions, 104 deletions
diff --git a/ChangeLog b/ChangeLog
index e30b5bf5..cf5f6e61 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/src/vte.c b/src/vte.c
index 7783607a..42751edf 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -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,