- 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)
f38
Ray Strode 18 years ago
parent 484e0e26b7
commit 6944c71d20

@ -0,0 +1,304 @@
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;

@ -8,7 +8,7 @@
Summary: GnomeCanvas widget Summary: GnomeCanvas widget
Name: libgnomecanvas Name: libgnomecanvas
Version: 2.19.2 Version: 2.19.2
Release: 1%{?dist} Release: 2%{?dist}
URL: http://www.gnome.org/ URL: http://www.gnome.org/
Source0: http://download.gnome.org/sources/libgnomecanvas/2.19/%{name}-%{version}.tar.bz2 Source0: http://download.gnome.org/sources/libgnomecanvas/2.19/%{name}-%{version}.tar.bz2
License: LGPLv2+ License: LGPLv2+
@ -22,6 +22,9 @@ BuildRequires: gail-devel >= %{gail_version}
BuildRequires: libtool gettext BuildRequires: libtool gettext
BuildRequires: perl(XML::Parser) 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 %description
The canvas widget allows you to create custom displays using stock items 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 such as circles, lines, text, and so on. It was originally a port of the
@ -47,6 +50,7 @@ Tk canvas widget but has evolved quite a bit over time.
%prep %prep
%setup -q %setup -q
%patch0 -p1 -b .avoid-tearing
%build %build
export CFLAGS=$(echo $RPM_OPT_FLAGS |sed -e 's/O2/O1/g') export CFLAGS=$(echo $RPM_OPT_FLAGS |sed -e 's/O2/O1/g')
@ -87,6 +91,11 @@ rm -rf %{buildroot}
%{_datadir}/gtk-doc/html/libgnomecanvas %{_datadir}/gtk-doc/html/libgnomecanvas
%changelog %changelog
* Sat Aug 25 2007 Ray Strode <rstrode@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@redhat.com> - 2.19.2-1 * Tue Aug 14 2007 Matthias Clasen <mclasen@redhat.com> - 2.19.2-1
- Update to 2.19.2 - Update to 2.19.2

Loading…
Cancel
Save