diff options
author | Benjamin Otte <otte@redhat.com> | 2010-10-17 21:53:05 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2010-10-30 01:50:02 +0800 |
commit | 3e97227202f38a8cf44732abbb5bf708c12072ef (patch) | |
tree | 485018616c03c2cd15b48f3f5a3ffee8deed90eb /libgnomecanvas | |
parent | 186100f9afd831bb783f199b044b5051b1cb10bf (diff) | |
download | gsoc2013-evolution-3e97227202f38a8cf44732abbb5bf708c12072ef.tar.gz gsoc2013-evolution-3e97227202f38a8cf44732abbb5bf708c12072ef.tar.zst gsoc2013-evolution-3e97227202f38a8cf44732abbb5bf708c12072ef.zip |
gnome-canvas: Simplify updating code
Instead of keeping oour own invalid area, trust GDK to do the right
thing.
Diffstat (limited to 'libgnomecanvas')
-rw-r--r-- | libgnomecanvas/gnome-canvas.c | 344 | ||||
-rw-r--r-- | libgnomecanvas/gnome-canvas.h | 16 |
2 files changed, 34 insertions, 326 deletions
diff --git a/libgnomecanvas/gnome-canvas.c b/libgnomecanvas/gnome-canvas.c index d467d8f545..34e8c0b272 100644 --- a/libgnomecanvas/gnome-canvas.c +++ b/libgnomecanvas/gnome-canvas.c @@ -88,10 +88,6 @@ #include "gnome-canvas.h" #include "gnome-canvas-i18n.h" #include "gnome-canvas-util.h" -#include <libart_lgpl/art_rect.h> -#include <libart_lgpl/art_rect_uta.h> -#include <libart_lgpl/art_uta_rect.h> - #include "gnome-canvas-marshal.h" #include "gnome-canvas-marshal.c" @@ -1864,8 +1860,6 @@ gnome_canvas_init (GnomeCanvas *canvas) gtk_widget_set_can_focus (GTK_WIDGET (canvas), TRUE); canvas->need_update = FALSE; - canvas->need_redraw = FALSE; - canvas->redraw_area = NULL; canvas->idle_id = 0; canvas->scroll_x1 = 0.0; @@ -1918,21 +1912,6 @@ remove_idle (GnomeCanvas *canvas) static void shutdown_transients (GnomeCanvas *canvas) { - /* We turn off the need_redraw flag, since if the canvas is mapped again - * it will request a redraw anyways. We do not turn off the need_update - * flag, though, because updates are not queued when the canvas remaps - * itself. - */ - if (canvas->need_redraw) { - canvas->need_redraw = FALSE; - art_uta_free (canvas->redraw_area); - canvas->redraw_area = NULL; - canvas->redraw_x1 = 0; - canvas->redraw_y1 = 0; - canvas->redraw_x2 = 0; - canvas->redraw_y2 = 0; - } - if (canvas->grabbed_item) { canvas->grabbed_item = NULL; gdk_pointer_ungrab (GDK_CURRENT_TIME); @@ -2796,22 +2775,24 @@ gnome_canvas_expose (GtkWidget *widget, GdkEventExpose *event) gdk_region_get_rectangles (event->region, &rects, &n_rects); for (i = 0; i < n_rects; i++) { - ArtIRect rect; - - rect.x0 = rects[i].x - canvas->zoom_xofs; - rect.y0 = rects[i].y - canvas->zoom_yofs; - rect.x1 = rects[i].x + rects[i].width - canvas->zoom_xofs; - rect.y1 = rects[i].y + rects[i].height - canvas->zoom_yofs; - - if (canvas->need_update || canvas->need_redraw) { - ArtUta *uta; - - /* Update or drawing is scheduled, so just mark exposed area as dirty */ - uta = art_uta_from_irect (&rect); - gnome_canvas_request_redraw_uta (canvas, uta); + GdkRectangle rect; + + rect.x = rects[i].x - canvas->zoom_xofs; + rect.y = rects[i].y - canvas->zoom_yofs; + rect.width = rects[i].width; + rect.height = rects[i].height; + + if (canvas->need_update) { + gnome_canvas_request_redraw (canvas, + rect.x, rect.y, + rect.x + rect.width, + rect.y + rect.height); } else { /* No pending updates, draw exposed area immediately */ - gnome_canvas_paint_rect (canvas, rect.x0, rect.y0, rect.x1, rect.y1); + gnome_canvas_paint_rect (canvas, + rect.x, rect.y, + rect.x + rect.width, + rect.y + rect.height); /* And call expose on parent container class */ if (GTK_WIDGET_CLASS (canvas_parent_class)->expose_event) @@ -2825,77 +2806,6 @@ gnome_canvas_expose (GtkWidget *widget, GdkEventExpose *event) return FALSE; } -/* Repaints the areas in the canvas that need it */ -static void -paint (GnomeCanvas *canvas) -{ - GtkWidget *widget; - GtkLayout *layout; - GdkWindow *bin_window; - GtkAllocation allocation; - GtkAdjustment *hadjustment; - GtkAdjustment *vadjustment; - ArtIRect *rects; - gint n_rects, i; - ArtIRect visible_rect; - GdkRegion *region; - gdouble hadjustment_value; - gdouble vadjustment_value; - - widget = GTK_WIDGET (canvas); - gtk_widget_get_allocation (widget, &allocation); - - layout = GTK_LAYOUT (canvas); - bin_window = gtk_layout_get_bin_window (layout); - hadjustment = gtk_layout_get_hadjustment (layout); - vadjustment = gtk_layout_get_vadjustment (layout); - - hadjustment_value = gtk_adjustment_get_value (hadjustment); - vadjustment_value = gtk_adjustment_get_value (vadjustment); - - /* 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; - - /* Turn those rectangles into a GdkRegion for exposing */ - - visible_rect.x0 = hadjustment_value - canvas->zoom_xofs; - visible_rect.y0 = vadjustment_value - canvas->zoom_yofs; - visible_rect.x1 = visible_rect.x0 + allocation.width; - visible_rect.y1 = visible_rect.y0 + allocation.height; - - for (i = 0; i < n_rects; i++) { - ArtIRect clipped; - - art_irect_intersect (&clipped, &visible_rect, rects + i); - if (!art_irect_empty (&clipped)) { - GdkRectangle gdkrect; - - gdkrect.x = clipped.x0 + canvas->zoom_xofs; - gdkrect.y = clipped.y0 + canvas->zoom_yofs; - gdkrect.width = clipped.x1 - clipped.x0; - gdkrect.height = clipped.y1 - clipped.y0; - - region = gdk_region_rectangle (&gdkrect); - gdk_window_invalidate_region (bin_window, region, FALSE); - gdk_region_destroy (region); - } - } - - art_free (rects); - - canvas->redraw_x1 = 0; - canvas->redraw_y1 = 0; - canvas->redraw_x2 = 0; - canvas->redraw_y2 = 0; -} - static void gnome_canvas_draw_background (GnomeCanvas *canvas, GdkDrawable *drawable, gint x, gint y, gint width, gint height) @@ -2946,11 +2856,6 @@ update_again: if (canvas->need_update) { goto update_again; } - - /* Paint if able to */ - - if (gtk_widget_is_drawable (GTK_WIDGET (canvas)) && canvas->need_redraw) - paint (canvas); } /* Idle handler for the canvas. It deals with pending updates and redraws. */ @@ -2977,7 +2882,7 @@ idle_handler (gpointer data) static void add_idle (GnomeCanvas *canvas) { - g_assert (canvas->need_update || canvas->need_redraw); + g_assert (canvas->need_update); if (!canvas->idle_id) canvas->idle_id = g_idle_add_full (CANVAS_IDLE_PRIORITY, @@ -3321,127 +3226,8 @@ gnome_canvas_request_update_real (GnomeCanvas *canvas) add_idle (canvas); } -/* Computes the union of two microtile arrays while clipping the result to the - * specified rectangle. Any of the specified utas can be NULL, in which case it - * is taken to be an empty region. - */ -static ArtUta * -uta_union_clip (ArtUta *uta1, ArtUta *uta2, ArtIRect *clip) -{ - ArtUta *uta; - ArtUtaBbox *utiles; - gint clip_x1, clip_y1, clip_x2, clip_y2; - gint union_x1, union_y1, union_x2, union_y2; - gint new_x1, new_y1, new_x2, new_y2; - gint x, y; - gint ofs, ofs1, ofs2; - - g_assert (clip != NULL); - - /* Compute the tile indices for the clipping rectangle */ - - clip_x1 = clip->x0 >> ART_UTILE_SHIFT; - clip_y1 = clip->y0 >> ART_UTILE_SHIFT; - clip_x2 = (clip->x1 >> ART_UTILE_SHIFT) + 1; - clip_y2 = (clip->y1 >> ART_UTILE_SHIFT) + 1; - - /* Get the union of the bounds of both utas */ - - if (!uta1) { - if (!uta2) - return art_uta_new (clip_x1, clip_y1, clip_x1 + 1, clip_y1 + 1); - - union_x1 = uta2->x0; - union_y1 = uta2->y0; - union_x2 = uta2->x0 + uta2->width; - union_y2 = uta2->y0 + uta2->height; - } else { - if (!uta2) { - union_x1 = uta1->x0; - union_y1 = uta1->y0; - union_x2 = uta1->x0 + uta1->width; - union_y2 = uta1->y0 + uta1->height; - } else { - union_x1 = MIN (uta1->x0, uta2->x0); - union_y1 = MIN (uta1->y0, uta2->y0); - union_x2 = MAX (uta1->x0 + uta1->width, uta2->x0 + uta2->width); - union_y2 = MAX (uta1->y0 + uta1->height, uta2->y0 + uta2->height); - } - } - - /* Clip the union of the bounds */ - - new_x1 = MAX (clip_x1, union_x1); - new_y1 = MAX (clip_y1, union_y1); - new_x2 = MIN (clip_x2, union_x2); - new_y2 = MIN (clip_y2, union_y2); - - if (new_x1 >= new_x2 || new_y1 >= new_y2) - return art_uta_new (clip_x1, clip_y1, clip_x1 + 1, clip_y1 + 1); - - /* Make the new clipped union */ - - uta = art_new (ArtUta, 1); - uta->x0 = new_x1; - uta->y0 = new_y1; - uta->width = new_x2 - new_x1; - uta->height = new_y2 - new_y1; - uta->utiles = utiles = art_new (ArtUtaBbox, uta->width * uta->height); - - ofs = 0; - ofs1 = ofs2 = 0; - - for (y = new_y1; y < new_y2; y++) { - if (uta1) - ofs1 = (y - uta1->y0) * uta1->width + new_x1 - uta1->x0; - - if (uta2) - ofs2 = (y - uta2->y0) * uta2->width + new_x1 - uta2->x0; - - for (x = new_x1; x < new_x2; x++) { - ArtUtaBbox bb1, bb2, bb; - - if (!uta1 - || x < uta1->x0 || y < uta1->y0 - || x >= uta1->x0 + uta1->width || y >= uta1->y0 + uta1->height) - bb1 = 0; - else - bb1 = uta1->utiles[ofs1]; - - if (!uta2 - || x < uta2->x0 || y < uta2->y0 - || x >= uta2->x0 + uta2->width || y >= uta2->y0 + uta2->height) - bb2 = 0; - else - bb2 = uta2->utiles[ofs2]; - - if (bb1 == 0) - bb = bb2; - else if (bb2 == 0) - bb = bb1; - else - bb = ART_UTA_BBOX_CONS (MIN (ART_UTA_BBOX_X0 (bb1), - ART_UTA_BBOX_X0 (bb2)), - MIN (ART_UTA_BBOX_Y0 (bb1), - ART_UTA_BBOX_Y0 (bb2)), - MAX (ART_UTA_BBOX_X1 (bb1), - ART_UTA_BBOX_X1 (bb2)), - MAX (ART_UTA_BBOX_Y1 (bb1), - ART_UTA_BBOX_Y1 (bb2))); - - utiles[ofs] = bb; - - ofs++; - ofs1++; - ofs2++; - } - } - - return uta; -} - static inline void -get_visible_region (GnomeCanvas *canvas, ArtIRect *visible) +get_visible_rect (GnomeCanvas *canvas, GdkRectangle *visible) { GtkLayout *layout; GtkAllocation allocation; @@ -3459,66 +3245,10 @@ get_visible_region (GnomeCanvas *canvas, ArtIRect *visible) hadjustment_value = gtk_adjustment_get_value (hadjustment); vadjustment_value = gtk_adjustment_get_value (vadjustment); - visible->x0 = hadjustment_value - canvas->zoom_xofs; - visible->y0 = vadjustment_value - canvas->zoom_yofs; - visible->x1 = visible->x0 + allocation.width; - visible->y1 = visible->y0 + allocation.height; -} - -/** - * gnome_canvas_request_redraw_uta: - * @canvas: A canvas. - * @uta: Microtile array that specifies the area to be redrawn. It will - * be freed by this function, so the argument you pass will be invalid - * after you call this function. - * - * Informs a canvas that the specified area, given as a microtile array, needs - * to be repainted. To be used only by item implementations. - **/ -void -gnome_canvas_request_redraw_uta (GnomeCanvas *canvas, - ArtUta *uta) -{ - ArtIRect visible; - - g_return_if_fail (GNOME_IS_CANVAS (canvas)); - g_return_if_fail (uta != NULL); - - if (!gtk_widget_is_drawable (GTK_WIDGET (canvas))) { - art_uta_free (uta); - return; - } - - get_visible_region (canvas, &visible); - - if (canvas->need_redraw) { - ArtUta *new_uta; - - g_assert (canvas->redraw_area != NULL); - /* ALEX: This can fail if e.g. redraw_uta is called by an item - update function and we're called from update_now -> do_update - because update_now sets idle_id == 0. There is also some way - to get it from the expose handler (see bug #102811). - g_assert (canvas->idle_id != 0); */ - - new_uta = uta_union_clip (canvas->redraw_area, uta, &visible); - art_uta_free (canvas->redraw_area); - art_uta_free (uta); - canvas->redraw_area = new_uta; - if (canvas->idle_id == 0) - add_idle (canvas); - } else { - ArtUta *new_uta; - - g_assert (canvas->redraw_area == NULL); - - new_uta = uta_union_clip (uta, NULL, &visible); - art_uta_free (uta); - canvas->redraw_area = new_uta; - - canvas->need_redraw = TRUE; - add_idle (canvas); - } + visible->x = hadjustment_value - canvas->zoom_xofs; + visible->y = vadjustment_value - canvas->zoom_yofs; + visible->width = allocation.width; + visible->height = allocation.height; } /** @@ -3530,36 +3260,30 @@ gnome_canvas_request_redraw_uta (GnomeCanvas *canvas, * @y2: Lower coordinate of the rectangle to be redrawn, plus 1. * * Convenience function that informs a canvas that the specified rectangle needs - * to be repainted. This function converts the rectangle to a microtile array - * and feeds it to gnome_canvas_request_redraw_uta(). The rectangle includes - * @x1 and @y1, but not @x2 and @y2. To be used only by item implementations. + * to be repainted. The rectangle includes @x1 and @y1, but not @x2 and @y2. To + * be used only by item implementations. **/ void gnome_canvas_request_redraw (GnomeCanvas *canvas, gint x1, gint y1, gint x2, gint y2) { - ArtUta *uta; - ArtIRect bbox; - ArtIRect visible; - ArtIRect clip; + GdkRectangle area, clip; g_return_if_fail (GNOME_IS_CANVAS (canvas)); if (!gtk_widget_is_drawable (GTK_WIDGET (canvas)) || (x1 >= x2) || (y1 >= y2)) return; - bbox.x0 = x1; - bbox.y0 = y1; - bbox.x1 = x2; - bbox.y1 = y2; + area.x = x1; + area.y = y1; + area.width = x2 - x1; + area.height = y2 - y1; - get_visible_region (canvas, &visible); + get_visible_rect (canvas, &clip); + if (!gdk_rectangle_intersect (&area, &clip, &area)) + return; - art_irect_intersect (&clip, &bbox, &visible); - - if (!art_irect_empty (&clip)) { - uta = art_uta_from_irect (&clip); - gnome_canvas_request_redraw_uta (canvas, uta); - } + gdk_window_invalidate_rect (gtk_layout_get_bin_window (GTK_LAYOUT (canvas)), + &area, FALSE); } /** diff --git a/libgnomecanvas/gnome-canvas.h b/libgnomecanvas/gnome-canvas.h index b940f67748..5ef653aa67 100644 --- a/libgnomecanvas/gnome-canvas.h +++ b/libgnomecanvas/gnome-canvas.h @@ -39,10 +39,6 @@ #include <gtk/gtk.h> #include <stdarg.h> -#include <libart_lgpl/art_misc.h> -#include <libart_lgpl/art_rect.h> -#include <libart_lgpl/art_svp.h> -#include <libart_lgpl/art_uta.h> G_BEGIN_DECLS @@ -358,9 +354,6 @@ struct _GnomeCanvas { /* Root canvas group */ GnomeCanvasItem *root; - /* Area that needs redrawing, stored as a microtile array */ - ArtUta *redraw_area; - /* The item containing the mouse pointer, or NULL if none */ GnomeCanvasItem *current_item; @@ -415,9 +408,6 @@ struct _GnomeCanvas { /* Whether items need update at next idle loop iteration */ guint need_update : 1; - /* Whether the canvas needs redrawing at the next idle loop iteration */ - guint need_redraw : 1; - /* Whether current item will be repicked at next idle loop iteration */ guint need_repick : 1; @@ -489,12 +479,6 @@ void gnome_canvas_get_scroll_offsets (GnomeCanvas *canvas, gint *cx, gint *cy); */ GnomeCanvasItem *gnome_canvas_get_item_at (GnomeCanvas *canvas, gdouble x, gdouble y); -/* For use only by item type implementations. Request that the canvas eventually - * redraw the specified region. The region is specified as a microtile - * array. This function takes over responsibility for freeing the uta argument. - */ -void gnome_canvas_request_redraw_uta (GnomeCanvas *canvas, ArtUta *uta); - /* For use only by item type implementations. Request that the canvas * eventually redraw the specified region, specified in canvas pixel * coordinates. The region contains (x1, y1) but not (x2, y2). |