[gimp] app: port the image and wilber drawing code away from GdkRegion



commit fd6c5dd5769d34a5cb167c4f6e45a28c84cb41c8
Author: Michael Natterer <mitch gimp org>
Date:   Thu Apr 18 11:56:43 2013 +0200

    app: port the image and wilber drawing code away from GdkRegion
    
    the changes are simply copied from the gtk3-port branch, reducing the
    number of diffs, and enabling hacking on drawing stuff in master while
    keeping the branch easily rebasable.

 app/display/gimpdisplayshell-callbacks.c | 130 +++++++++++++++++--------------
 app/display/gimpdisplayshell-draw.c      |  17 ++++
 app/display/gimpdisplayshell-draw.h      |   2 +
 3 files changed, 91 insertions(+), 58 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c
index b1de990..c258b0b 100644
--- a/app/display/gimpdisplayshell-callbacks.c
+++ b/app/display/gimpdisplayshell-callbacks.c
@@ -62,11 +62,9 @@ static gboolean   gimp_display_shell_hscrollbar_change_value  (GtkRange
                                                                gdouble           value,
                                                                GimpDisplayShell *shell);
 
-static void       gimp_display_shell_canvas_expose_image      (GimpDisplayShell *shell,
-                                                               GdkEventExpose   *eevent,
+static void       gimp_display_shell_canvas_draw_image        (GimpDisplayShell *shell,
                                                                cairo_t          *cr);
-static void       gimp_display_shell_canvas_expose_drop_zone  (GimpDisplayShell *shell,
-                                                               GdkEventExpose   *eevent,
+static void       gimp_display_shell_canvas_draw_drop_zone    (GimpDisplayShell *shell,
                                                                cairo_t          *cr);
 
 
@@ -259,11 +257,11 @@ gimp_display_shell_canvas_expose (GtkWidget        *widget,
 
       if (gimp_display_get_image (shell->display))
         {
-          gimp_display_shell_canvas_expose_image (shell, eevent, cr);
+          gimp_display_shell_canvas_draw_image (shell, cr);
         }
       else
         {
-          gimp_display_shell_canvas_expose_drop_zone (shell, eevent, cr);
+          gimp_display_shell_canvas_draw_drop_zone (shell, cr);
         }
 
       cairo_destroy (cr);
@@ -452,45 +450,70 @@ gimp_display_shell_vscrollbar_change_value (GtkRange         *range,
 }
 
 static void
-gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
-                                        GdkEventExpose   *eevent,
-                                        cairo_t          *cr)
+gimp_display_shell_canvas_draw_image (GimpDisplayShell *shell,
+                                      cairo_t          *cr)
 {
-  GdkRegion    *clear_region;
-  GdkRegion    *image_region;
-  GdkRectangle  image_rect;
-  GdkRectangle *rects;
-  gint          n_rects;
-  gint          i;
+  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 = gdk_region_copy (eevent->region);
+  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);
 
   image_rect.x = - shell->offset_x;
   image_rect.y = - shell->offset_y;
   gimp_display_shell_draw_get_scaled_image_size (shell,
                                                  &image_rect.width,
                                                  &image_rect.height);
-  image_region = gdk_region_rectangle (&image_rect);
+  image_region = cairo_region_create_rectangle (&image_rect);
 
-  gdk_region_subtract (clear_region, image_region);
-  gdk_region_destroy (image_region);
+  cairo_region_subtract (clear_region, image_region);
+  cairo_region_destroy (image_region);
 
-  if (! gdk_region_empty (clear_region))
+  if (! cairo_region_is_empty (clear_region))
     {
-      gdk_region_get_rectangles (clear_region, &rects, &n_rects);
+      cairo_save (cr);
+
+      n_rects = cairo_region_num_rectangles (clear_region);
 
       for (i = 0; i < n_rects; i++)
-        gdk_window_clear_area (gtk_widget_get_window (shell->canvas),
-                               rects[i].x,
-                               rects[i].y,
-                               rects[i].width,
-                               rects[i].height);
+        {
+          cairo_rectangle_int_t rect;
+
+          cairo_region_get_rectangle (clear_region, i, &rect);
+
+          cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height);
+        }
+
+      cairo_clip (cr);
+      gimp_display_shell_draw_background (shell, cr);
 
-      g_free (rects);
+      cairo_restore (cr);
     }
 
   /*  then, draw the exposed part of the region that is inside the
@@ -498,12 +521,13 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
    *  clearing above
    */
 
-  image_region = gdk_region_copy (eevent->region);
+  image_region = tmp_region;
+  tmp_region = NULL;
 
-  gdk_region_subtract (image_region, clear_region);
-  gdk_region_destroy (clear_region);
+  cairo_region_subtract (image_region, clear_region);
+  cairo_region_destroy (clear_region);
 
-  if (! gdk_region_empty (image_region))
+  if (! cairo_region_is_empty (image_region))
     {
       cairo_save (cr);
       gimp_display_shell_draw_checkerboard (shell, cr,
@@ -515,20 +539,26 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
 
 
       cairo_save (cr);
-      gdk_region_get_rectangles (image_region, &rects, &n_rects);
+
+      n_rects = cairo_region_num_rectangles (image_region);
 
       for (i = 0; i < n_rects; i++)
-        gimp_display_shell_draw_image (shell, cr,
-                                       rects[i].x,
-                                       rects[i].y,
-                                       rects[i].width,
-                                       rects[i].height);
+        {
+          cairo_rectangle_int_t rect;
+
+          cairo_region_get_rectangle (image_region, i, &rect);
+
+          gimp_display_shell_draw_image (shell, cr,
+                                         rect.x,
+                                         rect.y,
+                                         rect.width,
+                                         rect.height);
+        }
 
-      g_free (rects);
       cairo_restore (cr);
     }
 
-  gdk_region_destroy (image_region);
+  cairo_region_destroy (image_region);
 
   /*  finally, draw all the remaining image window stuff on top
    */
@@ -541,26 +571,10 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
 }
 
 static void
-gimp_display_shell_canvas_expose_drop_zone (GimpDisplayShell *shell,
-                                            GdkEventExpose   *eevent,
-                                            cairo_t          *cr)
+gimp_display_shell_canvas_draw_drop_zone (GimpDisplayShell *shell,
+                                          cairo_t          *cr)
 {
-  GdkRectangle *rects;
-  gint          n_rects;
-  gint          i;
-
-  gdk_region_get_rectangles (eevent->region, &rects, &n_rects);
-
-  for (i = 0; i < n_rects; i++)
-    {
-      gdk_window_clear_area (gtk_widget_get_window (shell->canvas),
-                             rects[i].x,
-                             rects[i].y,
-                             rects[i].width,
-                             rects[i].height);
-    }
-
-  g_free (rects);
+  gimp_display_shell_draw_background (shell, cr);
 
   gimp_cairo_draw_drop_wilber (shell->canvas, cr);
 }
diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c
index 358f424..c3afb37 100644
--- a/app/display/gimpdisplayshell-draw.c
+++ b/app/display/gimpdisplayshell-draw.c
@@ -138,6 +138,23 @@ gimp_display_shell_draw_selection_in (GimpDisplayShell   *shell,
 }
 
 void
+gimp_display_shell_draw_background (GimpDisplayShell *shell,
+                                    cairo_t          *cr)
+{
+  GdkWindow       *window;
+  cairo_pattern_t *bg_pattern;
+
+  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+  g_return_if_fail (cr != NULL);
+
+  window     = gtk_widget_get_window (shell->canvas);
+  bg_pattern = gdk_window_get_background_pattern (window);
+
+  cairo_set_source (cr, bg_pattern);
+  cairo_paint (cr);
+}
+
+void
 gimp_display_shell_draw_image (GimpDisplayShell *shell,
                                cairo_t          *cr,
                                gint              x,
diff --git a/app/display/gimpdisplayshell-draw.h b/app/display/gimpdisplayshell-draw.h
index 09aecbc..206894e 100644
--- a/app/display/gimpdisplayshell-draw.h
+++ b/app/display/gimpdisplayshell-draw.h
@@ -37,6 +37,8 @@ void   gimp_display_shell_draw_selection_in          (GimpDisplayShell   *shell,
                                                       cairo_pattern_t    *mask,
                                                       gint                index);
 
+void   gimp_display_shell_draw_background            (GimpDisplayShell   *shell,
+                                                      cairo_t            *cr);
 void   gimp_display_shell_draw_image                 (GimpDisplayShell   *shell,
                                                       cairo_t            *cr,
                                                       gint                x,


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