[gimp/soc-2011-seamless-clone2] app: simplify gimp_display_shell_canvas_draw_image() a lot



commit 739b2c2f93d10877ab30f225fca8e9e8c47e556e
Author: Michael Natterer <mitch gimp org>
Date:   Fri Apr 19 02:08:10 2013 +0200

    app: simplify gimp_display_shell_canvas_draw_image() a lot
    
    by not manually intersecting and subtracting regions at all. Simply
    clip the cairo_t to the area we want to render, it will automatically
    intersect with the clip region from the expose event, and check if the
    clip is empty before actually drawing anything.

 app/display/gimpdisplayshell-callbacks.c |  106 ++++++++++-------------------
 1 files changed, 37 insertions(+), 69 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c
index 2481286..2b20cfa 100644
--- a/app/display/gimpdisplayshell-callbacks.c
+++ b/app/display/gimpdisplayshell-callbacks.c
@@ -454,82 +454,54 @@ static void
 gimp_display_shell_canvas_draw_image (GimpDisplayShell *shell,
                                       cairo_t          *cr)
 {
-  cairo_rectangle_list_t *clip_rectangles;
-  cairo_region_t         *clear_region;
-  cairo_region_t         *image_region;
-  cairo_region_t         *tmp_region;
-  cairo_rectangle_int_t   image_rect;
-  gint                    n_rects;
-  gint                    i;
-
-  /*  first, clear the exposed part of the region that is outside the
-   *  image, which is the exposed region minus the image rectangle
-   */
-
-  clear_region = cairo_region_create ();
-
-  clip_rectangles = cairo_copy_clip_rectangle_list (cr);
-
-  for (i = 0; i < clip_rectangles->num_rectangles; i++)
-    {
-      cairo_rectangle_int_t rect;
-
-      rect.x      = floor (clip_rectangles->rectangles[i].x);
-      rect.y      = floor (clip_rectangles->rectangles[i].y);
-      rect.width  = ceil (clip_rectangles->rectangles[i].width);
-      rect.height = ceil (clip_rectangles->rectangles[i].height);
-
-      cairo_region_union_rectangle (clear_region, &rect);
-    }
-
-  cairo_rectangle_list_destroy (clip_rectangles);
-
-  tmp_region = cairo_region_copy (clear_region);
+  cairo_rectangle_int_t image_rect;
 
   image_rect.x = - shell->offset_x;
   image_rect.y = - shell->offset_y;
   gimp_display_shell_scale_get_image_size (shell,
                                            &image_rect.width,
                                            &image_rect.height);
-  image_region = cairo_region_create_rectangle (&image_rect);
 
-  cairo_region_subtract (clear_region, image_region);
-  cairo_region_destroy (image_region);
 
-  if (! cairo_region_is_empty (clear_region))
-    {
-      cairo_save (cr);
+  /*  first, clear the exposed part of the region that is outside the
+   *  image, which is the exposed region minus the image rectangle
+   */
 
-      n_rects = cairo_region_num_rectangles (clear_region);
+  cairo_save (cr);
 
-      for (i = 0; i < n_rects; i++)
-        {
-          cairo_rectangle_int_t rect;
+  cairo_rectangle (cr,
+                   image_rect.x,
+                   image_rect.y,
+                   image_rect.width,
+                   image_rect.height);
 
-          cairo_region_get_rectangle (clear_region, i, &rect);
+  cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+  cairo_clip (cr);
 
-          cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height);
-        }
+  if (gdk_cairo_get_clip_rectangle (cr, NULL))
+    gimp_display_shell_draw_background (shell, cr);
 
-      cairo_clip (cr);
-      gimp_display_shell_draw_background (shell, cr);
+  cairo_restore (cr);
 
-      cairo_restore (cr);
-    }
 
   /*  then, draw the exposed part of the region that is inside the
-   *  image, which is the exposed region minus the region used for
-   *  clearing above
+   *  image
    */
 
-  image_region = tmp_region;
-  tmp_region = NULL;
+  cairo_save (cr);
 
-  cairo_region_subtract (image_region, clear_region);
-  cairo_region_destroy (clear_region);
+  cairo_rectangle (cr,
+                   image_rect.x,
+                   image_rect.y,
+                   image_rect.width,
+                   image_rect.height);
+  cairo_clip (cr);
 
-  if (! cairo_region_is_empty (image_region))
+  if (gdk_cairo_get_clip_rectangle (cr, NULL))
     {
+      cairo_rectangle_list_t *clip_rectangles;
+      gint                    i;
+
       cairo_save (cr);
       gimp_display_shell_draw_checkerboard (shell, cr,
                                             image_rect.x,
@@ -538,28 +510,24 @@ gimp_display_shell_canvas_draw_image (GimpDisplayShell *shell,
                                             image_rect.height);
       cairo_restore (cr);
 
+      clip_rectangles = cairo_copy_clip_rectangle_list (cr);
 
-      cairo_save (cr);
-
-      n_rects = cairo_region_num_rectangles (image_region);
-
-      for (i = 0; i < n_rects; i++)
+      for (i = 0; i < clip_rectangles->num_rectangles; i++)
         {
-          cairo_rectangle_int_t rect;
-
-          cairo_region_get_rectangle (image_region, i, &rect);
+          cairo_rectangle_t rect = clip_rectangles->rectangles[i];
 
           gimp_display_shell_draw_image (shell, cr,
-                                         rect.x,
-                                         rect.y,
-                                         rect.width,
-                                         rect.height);
+                                         floor (rect.x),
+                                         floor (rect.y),
+                                         ceil (rect.width),
+                                         ceil (rect.height));
         }
 
-      cairo_restore (cr);
+      cairo_rectangle_list_destroy (clip_rectangles);
     }
 
-  cairo_region_destroy (image_region);
+  cairo_restore (cr);
+
 
   /*  finally, draw all the remaining image window stuff on top
    */


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