vte r2335 - in trunk: . src



Author: behdad
Date: Mon Dec  8 20:17:00 2008
New Revision: 2335
URL: http://svn.gnome.org/viewvc/vte?rev=2335&view=rev

Log:
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.



Modified:
   trunk/ChangeLog
   trunk/src/vte.c
   trunk/src/vtedraw.c
   trunk/src/vtedraw.h
   trunk/src/vtepangocairo.c
   trunk/src/vteskel.c

Modified: trunk/src/vte.c
==============================================================================
--- trunk/src/vte.c	(original)
+++ trunk/src/vte.c	Mon Dec  8 20:17:00 2008
@@ -10759,15 +10759,15 @@
 	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 @@
 	pvt->scroll_background = scroll;
 
         g_object_notify (G_OBJECT (terminal), "scroll-background");
+
+        vte_terminal_queue_background_update(terminal);
 }
 
 /**
@@ -12362,8 +12364,7 @@
 			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. */

Modified: trunk/src/vtedraw.c
==============================================================================
--- trunk/src/vtedraw.c	(original)
+++ trunk/src/vtedraw.c	Mon Dec  8 20:17:00 2008
@@ -107,14 +107,6 @@
 }
 
 
-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 @@
 	/* 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 @@
 		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 @@
 }
 
 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 @@
 			        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 @@
 		}
 	}
 }
-
-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;
-}

Modified: trunk/src/vtedraw.h
==============================================================================
--- trunk/src/vtedraw.h	(original)
+++ trunk/src/vtedraw.h	Mon Dec  8 20:17:00 2008
@@ -68,12 +68,17 @@
 	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 @@
 
 	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 @@
 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 @@
 			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 @@
 			      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

Modified: trunk/src/vtepangocairo.c
==============================================================================
--- trunk/src/vtepangocairo.c	(original)
+++ trunk/src/vtepangocairo.c	Mon Dec  8 20:17:00 2008
@@ -750,27 +750,12 @@
 
 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 @@
 {
 	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 @@
 }
 
 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 @@
 {
 	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 @@
 {
 	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 @@
 }
 
 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 @@
 	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,

Modified: trunk/src/vteskel.c
==============================================================================
--- trunk/src/vteskel.c	(original)
+++ trunk/src/vteskel.c	Mon Dec  8 20:17:00 2008
@@ -69,7 +69,9 @@
 	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,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]