[gimp] app/display: draw the crop highlight using cairo



commit eb5bb6363e4a01383d6b9707fe2856a8112f475e
Author: Sven Neumann <sven gimp org>
Date:   Tue Sep 28 22:04:07 2010 +0200

    app/display: draw the crop highlight using cairo
    
    Instead of dimming the actual pixels, apply a translucent fill to
    the area outside the highlight rectangle.

 app/display/gimpdisplayshell-callbacks.c |   14 +++-
 app/display/gimpdisplayshell-draw.c      |   45 +++++++++----
 app/display/gimpdisplayshell-draw.h      |    6 ++
 app/display/gimpdisplayshell-render.c    |  111 +++--------------------------
 app/display/gimpdisplayshell-render.h    |   19 +++---
 5 files changed, 71 insertions(+), 124 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c
index 6192689..12a304f 100644
--- a/app/display/gimpdisplayshell-callbacks.c
+++ b/app/display/gimpdisplayshell-callbacks.c
@@ -2293,9 +2293,9 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
                                             image_rect.height);
       cairo_restore (cr);
 
-      gdk_region_get_rectangles (image_region, &rects, &n_rects);
 
       cairo_save (cr);
+      gdk_region_get_rectangles (image_region, &rects, &n_rects);
 
       for (i = 0; i < n_rects; i++)
         gimp_display_shell_draw_area (shell, cr,
@@ -2304,9 +2304,19 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
                                       rects[i].width,
                                       rects[i].height);
 
+      g_free (rects);
       cairo_restore (cr);
 
-      g_free (rects);
+      if (shell->highlight)
+        {
+          cairo_save (cr);
+          gimp_display_shell_draw_highlight (shell, cr,
+                                             image_rect.x,
+                                             image_rect.y,
+                                             image_rect.width,
+                                             image_rect.height);
+          cairo_restore (cr);
+        }
     }
 
   gdk_region_destroy (image_region);
diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c
index 8131898..b1cf61c 100644
--- a/app/display/gimpdisplayshell-draw.c
+++ b/app/display/gimpdisplayshell-draw.c
@@ -707,9 +707,8 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell,
                               gint              w,
                               gint              h)
 {
-  GdkRectangle  rect;
-  gint          x2, y2;
-  gint          i, j;
+  gint x2, y2;
+  gint i, j;
 
   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
   g_return_if_fail (gimp_display_get_image (shell->display));
@@ -718,14 +717,6 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell,
   x2 = x + w;
   y2 = y + h;
 
-  if (shell->highlight)
-    {
-      rect.x      = ceil  (shell->scale_x * shell->highlight->x);
-      rect.y      = ceil  (shell->scale_y * shell->highlight->y);
-      rect.width  = floor (shell->scale_x * shell->highlight->width);
-      rect.height = floor (shell->scale_y * shell->highlight->height);
-    }
-
   /*  display the image in RENDER_BUF_WIDTH x RENDER_BUF_HEIGHT
    *  sized chunks
    */
@@ -746,8 +737,7 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell,
           gimp_display_shell_render (shell, cr,
                                      j - disp_xoffset,
                                      i - disp_yoffset,
-                                     dx, dy,
-                                     shell->highlight ? &rect : NULL);
+                                     dx, dy);
         }
     }
 }
@@ -792,7 +782,36 @@ gimp_display_shell_draw_checkerboard (GimpDisplayShell *shell,
 
   cairo_rectangle (cr, x, y, w, h);
   cairo_clip (cr);
+
   cairo_translate (cr, - shell->offset_x, - shell->offset_y);
   cairo_set_source (cr, shell->checkerboard);
   cairo_paint (cr);
 }
+
+void
+gimp_display_shell_draw_highlight (GimpDisplayShell *shell,
+                                   cairo_t          *cr,
+                                   gint              x,
+                                   gint              y,
+                                   gint              w,
+                                   gint              h)
+{
+  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+  g_return_if_fail (shell->highlight != NULL);
+  g_return_if_fail (cr != NULL);
+
+  cairo_rectangle (cr, x, y, w, h);
+
+  cairo_translate (cr, - shell->offset_x, - shell->offset_y);
+  cairo_scale (cr, shell->scale_x, shell->scale_y);
+  cairo_rectangle (cr,
+                   shell->highlight->x, shell->highlight->y,
+                   shell->highlight->width, shell->highlight->height);
+
+  cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+  cairo_clip (cr);
+
+  /*  FIXME: make this configurable or at least use gimpdisplayshell-style.c  */
+  cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
+  cairo_paint (cr);
+}
diff --git a/app/display/gimpdisplayshell-draw.h b/app/display/gimpdisplayshell-draw.h
index 8561458..a1d0c2d 100644
--- a/app/display/gimpdisplayshell-draw.h
+++ b/app/display/gimpdisplayshell-draw.h
@@ -77,6 +77,12 @@ void   gimp_display_shell_draw_checkerboard          (GimpDisplayShell   *shell,
                                                       gint                y,
                                                       gint                w,
                                                       gint                h);
+void   gimp_display_shell_draw_highlight             (GimpDisplayShell   *shell,
+                                                      cairo_t            *cr,
+                                                      gint                x,
+                                                      gint                y,
+                                                      gint                w,
+                                                      gint                h);
 
 
 #endif /* __GIMP_DISPLAY_SHELL_DRAW_H__ */
diff --git a/app/display/gimpdisplayshell-render.c b/app/display/gimpdisplayshell-render.c
index 26c8d66..b6edb9b 100644
--- a/app/display/gimpdisplayshell-render.c
+++ b/app/display/gimpdisplayshell-render.c
@@ -95,11 +95,11 @@ struct _RenderInfo
   gint64            dy;
 };
 
-static void  gimp_display_shell_render_info_scale   (RenderInfo       *info,
-                                                     GimpDisplayShell *shell,
-                                                     TileManager      *tiles,
-                                                     gint              level,
-                                                     gboolean          is_premult);
+static void  gimp_display_shell_render_info_scale (RenderInfo       *info,
+                                                   GimpDisplayShell *shell,
+                                                   TileManager      *tiles,
+                                                   gint              level,
+                                                   gboolean          is_premult);
 
 static guchar *tile_buf = NULL;
 
@@ -129,21 +129,14 @@ gimp_display_shell_render_exit (Gimp *gimp)
 
 /*  Render Image functions  */
 
-static void           render_image_rgb_a         (RenderInfo         *info);
-static void           render_image_gray_a        (RenderInfo         *info);
+static void           render_image_rgb_a      (RenderInfo       *info);
+static void           render_image_gray_a     (RenderInfo       *info);
 
-static const guchar * render_image_tile_fault    (RenderInfo         *info);
+static const guchar * render_image_tile_fault (RenderInfo       *info);
 
 
-static void  gimp_display_shell_render_highlight (GimpDisplayShell   *shell,
-                                                  RenderInfo         *info,
-                                                  gint                x,
-                                                  gint                y,
-                                                  gint                w,
-                                                  gint                h,
-                                                  const GdkRectangle *highlight);
-static void  gimp_display_shell_render_mask      (GimpDisplayShell   *shell,
-                                                  RenderInfo         *info);
+static void  gimp_display_shell_render_mask   (GimpDisplayShell *shell,
+                                               RenderInfo       *info);
 
 
 /*****************************************************************/
@@ -159,8 +152,7 @@ gimp_display_shell_render (GimpDisplayShell   *shell,
                            gint                x,
                            gint                y,
                            gint                w,
-                           gint                h,
-                           const GdkRectangle *highlight)
+                           gint                h)
 {
   GimpProjection *projection;
   GimpImage      *image;
@@ -245,12 +237,7 @@ gimp_display_shell_render (GimpDisplayShell   *shell,
 #endif
 
 #if 0
-  /*  dim pixels outside the highlighted rectangle  */
-  if (highlight)
-    {
-      gimp_display_shell_render_highlight (shell, &info, x, y, w, h, highlight);
-    }
-  else if (shell->mask)
+  if (shell->mask)
     {
       TileManager *tiles = gimp_drawable_get_tiles (shell->mask);
 
@@ -288,80 +275,6 @@ gimp_display_shell_render (GimpDisplayShell   *shell,
 #define CAIRO_RGB24_BLUE_PIXEL  3
 #endif
 
-#define GIMP_DISPLAY_SHELL_DIM_PIXEL(buf,x) \
-{ \
-  buf[4 * (x) + CAIRO_RGB24_RED_PIXEL]   >>= 1; \
-  buf[4 * (x) + CAIRO_RGB24_GREEN_PIXEL] >>= 1; \
-  buf[4 * (x) + CAIRO_RGB24_BLUE_PIXEL]  >>= 1; \
-}
-
-/*  This function highlights the given area by dimming all pixels outside. */
-
-static void
-gimp_display_shell_render_highlight (GimpDisplayShell   *shell,
-                                     RenderInfo         *info,
-                                     gint                x,
-                                     gint                y,
-                                     gint                w,
-                                     gint                h,
-                                     const GdkRectangle *highlight)
-{
-  guchar       *buf = cairo_image_surface_get_data (shell->render_surface);
-  GdkRectangle  rect;
-  gint          offset_x;
-  gint          offset_y;
-
-  gimp_display_shell_scroll_get_render_start_offset (shell,
-						     &offset_x, &offset_y);
-
-  rect.x      = x + offset_x;
-  rect.y      = y + offset_y;
-  rect.width  = w;
-  rect.height = h;
-
-  if (gdk_rectangle_intersect (highlight, &rect, &rect))
-    {
-      rect.x -= x + offset_x;
-      rect.y -= y + offset_y;
-
-      for (y = 0; y < rect.y; y++)
-        {
-          for (x = 0; x < w; x++)
-            GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
-
-          buf += info->dest_bpl;
-        }
-
-      for ( ; y < rect.y + rect.height; y++)
-        {
-          for (x = 0; x < rect.x; x++)
-            GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
-
-          for (x += rect.width; x < w; x++)
-            GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
-
-          buf += info->dest_bpl;
-        }
-
-      for ( ; y < h; y++)
-        {
-          for (x = 0; x < w; x++)
-            GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
-
-          buf += info->dest_bpl;
-        }
-    }
-  else
-    {
-      for (y = 0; y < h; y++)
-        {
-          for (x = 0; x < w; x++)
-            GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
-
-          buf += info->dest_bpl;
-        }
-    }
-}
 
 static void
 gimp_display_shell_render_mask (GimpDisplayShell *shell,
diff --git a/app/display/gimpdisplayshell-render.h b/app/display/gimpdisplayshell-render.h
index f60ff65..48a5ccf 100644
--- a/app/display/gimpdisplayshell-render.h
+++ b/app/display/gimpdisplayshell-render.h
@@ -23,16 +23,15 @@
 #define GIMP_DISPLAY_RENDER_BUF_HEIGHT 256
 
 
-void   gimp_display_shell_render_init (Gimp               *gimp);
-void   gimp_display_shell_render_exit (Gimp               *gimp);
-
-void   gimp_display_shell_render      (GimpDisplayShell   *shell,
-                                       cairo_t            *cr,
-                                       gint                x,
-                                       gint                y,
-                                       gint                w,
-                                       gint                h,
-                                       const GdkRectangle *highlight);
+void   gimp_display_shell_render_init (Gimp             *gimp);
+void   gimp_display_shell_render_exit (Gimp             *gimp);
+
+void   gimp_display_shell_render      (GimpDisplayShell *shell,
+                                       cairo_t          *cr,
+                                       gint              x,
+                                       gint              y,
+                                       gint              w,
+                                       gint              h);
 
 
 #endif  /*  __GIMP_DISPLAY_SHELL_RENDER_H__  */



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