rpms/libgnomecanvas/devel libgnomecanvas-2.19.2-avoid-tearing.patch, NONE, 1.1 libgnomecanvas.spec, 1.40, 1.41

Ray Strode (rstrode) fedora-extras-commits at redhat.com
Sat Aug 25 17:08:24 UTC 2007


Author: rstrode

Update of /cvs/pkgs/rpms/libgnomecanvas/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv16363

Modified Files:
	libgnomecanvas.spec 
Added Files:
	libgnomecanvas-2.19.2-avoid-tearing.patch 
Log Message:
- Apply patch from Federico Mena Quintero to avoid
  tearing during scrolls and such
  (See http://mail.gnome.org/archives/desktop-devel-list/2007-August/msg00159.html)


libgnomecanvas-2.19.2-avoid-tearing.patch:

--- NEW FILE libgnomecanvas-2.19.2-avoid-tearing.patch ---
diff -up libgnomecanvas-2.19.2/libgnomecanvas/gnome-canvas.c.avoid-tearing libgnomecanvas-2.19.2/libgnomecanvas/gnome-canvas.c
--- libgnomecanvas-2.19.2/libgnomecanvas/gnome-canvas.c.avoid-tearing	2007-08-01 09:56:16.000000000 -0400
+++ libgnomecanvas-2.19.2/libgnomecanvas/gnome-canvas.c	2007-08-25 13:03:36.000000000 -0400
@@ -2904,11 +2904,7 @@ gnome_canvas_focus_out (GtkWidget *widge
 		return FALSE;
 }
 
-#define IMAGE_WIDTH 512
-#define IMAGE_HEIGHT 512
-
-#define IMAGE_WIDTH_AA 256
-#define IMAGE_HEIGHT_AA 64
+#define REDRAW_QUANTUM_SIZE 512
 
 static void
 gnome_canvas_paint_rect (GnomeCanvas *canvas, gint x0, gint y0, gint x1, gint y1)
@@ -2916,9 +2912,7 @@ gnome_canvas_paint_rect (GnomeCanvas *ca
 	GtkWidget *widget;
 	gint draw_x1, draw_y1;
 	gint draw_x2, draw_y2;
-	gint xblock, yblock;
-	guchar *px;
-	GdkPixmap *pixmap;
+	gint draw_width, draw_height;
 
 	g_return_if_fail (!canvas->need_update);
 
@@ -2929,94 +2923,91 @@ gnome_canvas_paint_rect (GnomeCanvas *ca
 	draw_x2 = MIN (draw_x1 + GTK_WIDGET (canvas)->allocation.width, x1);
 	draw_y2 = MIN (draw_y1 + GTK_WIDGET (canvas)->allocation.height, y1);
 
-	/* As we can come from expose, we have to tile here */
-	xblock = (canvas->aa) ? IMAGE_WIDTH_AA : IMAGE_WIDTH;
-	yblock = (canvas->aa) ? IMAGE_HEIGHT_AA : IMAGE_HEIGHT;
-
-	px = NULL;
-	pixmap = NULL;
-
-	for (y0 = draw_y1; y0 < draw_y2; y0 += yblock) {
-		y1 = MIN (y0 + yblock, draw_y2);
-		for (x0 = draw_x1; x0 < draw_x2; x0 += xblock) {
-			x1 = MIN (x0 + xblock, draw_x2);
-
-			canvas->redraw_x1 = x0;
-			canvas->redraw_y1 = y0;
-			canvas->redraw_x2 = x1;
-			canvas->redraw_y2 = y1;
-			canvas->draw_xofs = x0;
-			canvas->draw_yofs = y0;
-
-			if (canvas->aa) {
-				GnomeCanvasBuf buf;
-				GdkColor *color;
-
-				if (!px) px = g_new (guchar, IMAGE_WIDTH_AA * IMAGE_HEIGHT_AA * 3);
-
-				buf.buf = px;
-				buf.buf_rowstride = IMAGE_WIDTH_AA * 3;
-				buf.rect.x0 = x0;
-				buf.rect.y0 = y0;
-				buf.rect.x1 = x1;
-				buf.rect.y1 = y1;
-				color = &widget->style->bg[GTK_STATE_NORMAL];
-				buf.bg_color = (((color->red & 0xff00) << 8) | (color->green & 0xff00) | (color->blue >> 8));
-				buf.is_bg = 1;
-				buf.is_buf = 0;
-
-				g_signal_emit (G_OBJECT (canvas), canvas_signals[RENDER_BACKGROUND], 0, &buf);
-
-				if (canvas->root->object.flags & GNOME_CANVAS_ITEM_VISIBLE)
-					(* GNOME_CANVAS_ITEM_GET_CLASS (canvas->root)->render) (canvas->root, &buf);
-
-				if (buf.is_bg) {
-					gdk_rgb_gc_set_foreground (canvas->pixmap_gc, buf.bg_color);
-					gdk_draw_rectangle (canvas->layout.bin_window,
-							    canvas->pixmap_gc,
-							    TRUE,
-							    (x0 + canvas->zoom_xofs),
-							    (y0 + canvas->zoom_yofs),
-							    x1 - x0, y1 - y0);
-				} else {
-					gdk_draw_rgb_image_dithalign (canvas->layout.bin_window,
-								      canvas->pixmap_gc,
-								      (x0 + canvas->zoom_xofs),
-								      (y0 + canvas->zoom_yofs),
-								      x1 - x0, y1 - y0,
-								      canvas->dither,
-								      buf.buf,
-								      IMAGE_WIDTH_AA * 3,
-								      x0, y0);
-				}
-			} else {
-				if (!pixmap) pixmap = gdk_pixmap_new (canvas->layout.bin_window, IMAGE_WIDTH, IMAGE_HEIGHT,
-								      gtk_widget_get_visual (widget)->depth);
-
-				g_signal_emit (G_OBJECT (canvas), canvas_signals[DRAW_BACKGROUND], 0, pixmap,
-					       x0, y0, x1 - x0, y1 - y0);
-
-				if (canvas->root->object.flags & GNOME_CANVAS_ITEM_VISIBLE)
-					(* GNOME_CANVAS_ITEM_GET_CLASS (
-						canvas->root)->draw) (
-							canvas->root, pixmap,
-							x0, y0,
-							x1 - x0, y1 - y0);
-				/* Copy the pixmap to the window and clean up */
-
-				gdk_draw_pixmap (canvas->layout.bin_window,
-						 canvas->pixmap_gc,
-						 pixmap,
-						 0, 0,
-						 x0 + canvas->zoom_xofs,
-						 y0 + canvas->zoom_yofs,
-						 x1 - x0, y1 - y0);
-			}
+	draw_width = draw_x2 - draw_x1;
+	draw_height = draw_y2 - draw_y1;
+
+	if (draw_width < 1 || draw_height < 1)
+		return;
+
+	canvas->redraw_x1 = draw_x1;
+	canvas->redraw_y1 = draw_y1;
+	canvas->redraw_x2 = draw_x2;
+	canvas->redraw_y2 = draw_y2;
+	canvas->draw_xofs = draw_x1;
+	canvas->draw_yofs = draw_y1;
+
+	if (canvas->aa) {
+		GnomeCanvasBuf buf;
+		guchar *px;
+		GdkColor *color;
+
+		px = g_new (guchar, draw_width * 3 * draw_height);
+
+		buf.buf = px;
+		buf.buf_rowstride = draw_width * 3;
+		buf.rect.x0 = draw_x1;
+		buf.rect.y0 = draw_y1;
+		buf.rect.x1 = draw_x2;
+		buf.rect.y1 = draw_y2;
+		color = &widget->style->bg[GTK_STATE_NORMAL];
+		buf.bg_color = (((color->red & 0xff00) << 8) | (color->green & 0xff00) | (color->blue >> 8));
+		buf.is_bg = 1;
+		buf.is_buf = 0;
+
+		g_signal_emit (G_OBJECT (canvas), canvas_signals[RENDER_BACKGROUND], 0, &buf);
+
+		if (canvas->root->object.flags & GNOME_CANVAS_ITEM_VISIBLE)
+			(* GNOME_CANVAS_ITEM_GET_CLASS (canvas->root)->render) (canvas->root, &buf);
+
+		if (buf.is_bg) {
+			gdk_rgb_gc_set_foreground (canvas->pixmap_gc, buf.bg_color);
+			gdk_draw_rectangle (canvas->layout.bin_window,
+					    canvas->pixmap_gc,
+					    TRUE,
+					    (draw_x1 + canvas->zoom_xofs),
+					    (draw_y1 + canvas->zoom_yofs),
+					    draw_width, draw_height);
+		} else {
+			gdk_draw_rgb_image_dithalign (canvas->layout.bin_window,
+						      canvas->pixmap_gc,
+						      (draw_x1 + canvas->zoom_xofs),
+						      (draw_y1 + canvas->zoom_yofs),
+						      draw_width, draw_height,
+						      canvas->dither,
+						      buf.buf,
+						      buf.buf_rowstride,
+						      draw_x1, draw_y1);
 		}
-	}
 
-	if (px) g_free (px);
-	if (pixmap) gdk_pixmap_unref (pixmap);
+		g_free (px);
+	} else {
+		GdkPixmap *pixmap;
+
+		pixmap = gdk_pixmap_new (canvas->layout.bin_window,
+					 draw_width, draw_height,
+					 gtk_widget_get_visual (widget)->depth);
+
+		g_signal_emit (G_OBJECT (canvas), canvas_signals[DRAW_BACKGROUND], 0, pixmap,
+			       draw_x1, draw_y1, draw_width, draw_height);
+
+		if (canvas->root->object.flags & GNOME_CANVAS_ITEM_VISIBLE)
+			(* GNOME_CANVAS_ITEM_GET_CLASS (canvas->root)->draw) (
+				canvas->root, pixmap,
+				draw_x1, draw_y1,
+				draw_width, draw_height);
+
+		/* Copy the pixmap to the window and clean up */
+
+		gdk_draw_pixmap (canvas->layout.bin_window,
+				 canvas->pixmap_gc,
+				 pixmap,
+				 0, 0,
+				 draw_x1 + canvas->zoom_xofs,
+				 draw_y1 + canvas->zoom_yofs,
+				 draw_width, draw_height);
+
+		gdk_pixmap_unref (pixmap);
+	}
 }
 
 /* Expose handler for the canvas */
@@ -3074,48 +3065,68 @@ paint (GnomeCanvas *canvas)
 {
 	ArtIRect *rects;
 	gint n_rects, i;
-
-	if (canvas->aa)
-		rects = art_rect_list_from_uta (canvas->redraw_area,
-						IMAGE_WIDTH_AA, IMAGE_HEIGHT_AA,
-						&n_rects);
-	else
-		rects = art_rect_list_from_uta (canvas->redraw_area,
-						IMAGE_WIDTH, IMAGE_HEIGHT,
-						&n_rects);
+	ArtIRect visible_rect;
+	GdkRegion *region;
+	GdkEventExpose expose_event;
+	GdkRectangle region_area;
+
+	/* Extract big rectangles from the microtile array */
+
+	rects = art_rect_list_from_uta (canvas->redraw_area,
+					REDRAW_QUANTUM_SIZE, REDRAW_QUANTUM_SIZE,
+					&n_rects);
 
 	art_uta_free (canvas->redraw_area);
 	canvas->redraw_area = NULL;
 	canvas->need_redraw = FALSE;
 
-	/* Send synthetic expose events */
+	/* Turn those rectangles into a GdkRegion for exposing */
+
+	visible_rect.x0 = canvas->layout.hadjustment->value;
+	visible_rect.y0 = canvas->layout.vadjustment->value;
+	visible_rect.x1 = visible_rect.x0 + GTK_WIDGET (canvas)->allocation.width;
+	visible_rect.y1 = visible_rect.y0 + GTK_WIDGET (canvas)->allocation.height;
+
+	region = gdk_region_new ();
+
 	for (i = 0; i < n_rects; i++) {
-		GdkEventExpose ex;
-		gint x0, y0, x1, y1;
+		ArtIRect clipped;
 
-		x0 = MAX (canvas->layout.hadjustment->value - canvas->zoom_xofs, rects[i].x0);
-		y0 = MAX (canvas->layout.vadjustment->value - canvas->zoom_yofs, rects[i].y0);
-		x1 = MIN (x0 + GTK_WIDGET (canvas)->allocation.width, rects[i].x1);
-		y1 = MIN (y0 + GTK_WIDGET (canvas)->allocation.height, rects[i].y1);
-
-		if ((x0 < x1) && (y0 < y1)) {
-			/* Here we are - whatever type is canvas, we have to send synthetic expose to layout (Lauris) */
-			ex.type = GDK_EXPOSE;
-			ex.window = canvas->layout.bin_window;
-			ex.send_event = TRUE;
-			ex.area.x = x0 + canvas->zoom_xofs;
-			ex.area.y = y0 + canvas->zoom_yofs;
-			ex.area.width = x1 - x0;
-			ex.area.height = y1 - y0;
-			ex.region = gdk_region_rectangle (&ex.area);
-			ex.count = 0;
-			gtk_widget_send_expose (GTK_WIDGET (canvas), (GdkEvent *) &ex);
-			gdk_region_destroy (ex.region);
+		art_irect_intersect (&clipped, &visible_rect, rects + i);
+		if (!art_irect_empty (&clipped)) {
+			GdkRectangle gdkrect;
+
+			gdkrect.x = clipped.x0;
+			gdkrect.y = clipped.y0;
+			gdkrect.width = clipped.x1 - clipped.x0;
+			gdkrect.height = clipped.y1 - clipped.y0;
+
+			gdk_region_union_with_rect (region, &gdkrect);
 		}
 	}
 
 	art_free (rects);
 
+	/* Expose! */
+
+	gdk_region_get_clipbox (region, &region_area);
+
+	expose_event.type = GDK_EXPOSE;
+	expose_event.window = canvas->layout.bin_window;
+	expose_event.send_event = TRUE;
+	expose_event.area.x = region_area.x;
+	expose_event.area.y = region_area.y;
+	expose_event.area.width = region_area.width;
+	expose_event.area.height = region_area.height;
+	expose_event.region = region;
+	expose_event.count = 0;
+
+	gdk_window_begin_paint_region (canvas->layout.bin_window, region);
+	gtk_widget_send_expose (GTK_WIDGET (canvas), (GdkEvent *) &expose_event);
+	gdk_window_end_paint (canvas->layout.bin_window);
+
+	gdk_region_destroy (region);
+
 	canvas->redraw_x1 = 0;
 	canvas->redraw_y1 = 0;
 	canvas->redraw_x2 = 0;


Index: libgnomecanvas.spec
===================================================================
RCS file: /cvs/pkgs/rpms/libgnomecanvas/devel/libgnomecanvas.spec,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- libgnomecanvas.spec	15 Aug 2007 02:53:45 -0000	1.40
+++ libgnomecanvas.spec	25 Aug 2007 17:07:50 -0000	1.41
@@ -8,7 +8,7 @@
 Summary: GnomeCanvas widget
 Name: libgnomecanvas
 Version: 2.19.2
-Release: 1%{?dist}
+Release: 2%{?dist}
 URL: http://www.gnome.org/
 Source0: http://download.gnome.org/sources/libgnomecanvas/2.19/%{name}-%{version}.tar.bz2
 License: LGPLv2+
@@ -22,6 +22,9 @@
 BuildRequires: libtool gettext
 BuildRequires: perl(XML::Parser)
 
+# http://mail.gnome.org/archives/desktop-devel-list/2007-August/msg00159.html
+Patch0: libgnomecanvas-2.19.2-avoid-tearing.patch
+
 %description
 The canvas widget allows you to create custom displays using stock items 
 such as circles, lines, text, and so on. It was originally a port of the 
@@ -47,6 +50,7 @@
 
 %prep
 %setup -q
+%patch0 -p1 -b .avoid-tearing
 
 %build
 export CFLAGS=$(echo $RPM_OPT_FLAGS |sed -e 's/O2/O1/g')
@@ -87,6 +91,11 @@
 %{_datadir}/gtk-doc/html/libgnomecanvas
 
 %changelog
+* Sat Aug 25 2007 Ray Strode <rstrode at redhat.com> - 2.19.2-2
+- Apply patch from Federico Mena Quintero to avoid
+  tearing during scrolls and such
+  (See http://mail.gnome.org/archives/desktop-devel-list/2007-August/msg00159.html)
+
 * Tue Aug 14 2007 Matthias Clasen <mclasen at redhat.com> - 2.19.2-1
 - Update to 2.19.2
 




More information about the fedora-extras-commits mailing list