[gimp] app: port GimpDisplayShell guide drawing to cairo



commit 922c330bec7bac517b94d6d91b0e8ce4feb76e47
Author: Michael Natterer <mitch gimp org>
Date:   Thu Aug 12 00:51:58 2010 +0200

    app: port GimpDisplayShell guide drawing to cairo
    
    The cairo_t code in GimpMoveTool is still disgusting. This probably
    needs some GimpTool API that creates a cairo_t for tools.

 app/display/gimpcanvas.c                 |   22 -----
 app/display/gimpcanvas.h                 |    2 -
 app/display/gimpdisplayshell-callbacks.c |    4 +-
 app/display/gimpdisplayshell-draw.c      |   65 ++++++--------
 app/display/gimpdisplayshell-draw.h      |    4 +-
 app/display/gimpdisplayshell-style.c     |  139 ++++++++++++++++++++---------
 app/display/gimpdisplayshell-style.h     |    9 ++-
 app/tools/gimpmovetool.c                 |   38 +++++++--
 8 files changed, 166 insertions(+), 117 deletions(-)
---
diff --git a/app/display/gimpcanvas.c b/app/display/gimpcanvas.c
index 22cd987..46d9662 100644
--- a/app/display/gimpcanvas.c
+++ b/app/display/gimpcanvas.c
@@ -402,8 +402,6 @@ gimp_canvas_gc_new (GimpCanvas      *canvas,
     case GIMP_CANVAS_STYLE_SELECTION_OUT:
     case GIMP_CANVAS_STYLE_LAYER_BOUNDARY:
     case GIMP_CANVAS_STYLE_LAYER_GROUP_BOUNDARY:
-    case GIMP_CANVAS_STYLE_GUIDE_NORMAL:
-    case GIMP_CANVAS_STYLE_GUIDE_ACTIVE:
     case GIMP_CANVAS_STYLE_LAYER_MASK_ACTIVE:
       mask |= GDK_GC_CAP_STYLE | GDK_GC_FILL | GDK_GC_STIPPLE;
       values.cap_style = GDK_CAP_NOT_LAST;
@@ -482,26 +480,6 @@ gimp_canvas_gc_new (GimpCanvas      *canvas,
       bg.blue  = 0xffff;
       break;
 
-    case GIMP_CANVAS_STYLE_GUIDE_NORMAL:
-      fg.red   = 0x0;
-      fg.green = 0x0;
-      fg.blue  = 0x0;
-
-      bg.red   = 0x0;
-      bg.green = 0x7f7f;
-      bg.blue  = 0xffff;
-      break;
-
-    case GIMP_CANVAS_STYLE_GUIDE_ACTIVE:
-      fg.red   = 0x0;
-      fg.green = 0x0;
-      fg.blue  = 0x0;
-
-      bg.red   = 0xffff;
-      bg.green = 0x0;
-      bg.blue  = 0x0;
-      break;
-
     case GIMP_CANVAS_STYLE_LAYER_MASK_ACTIVE:
       fg.red   = 0x0;
       fg.green = 0x0;
diff --git a/app/display/gimpcanvas.h b/app/display/gimpcanvas.h
index 06f5b1c..1bb1bda 100644
--- a/app/display/gimpcanvas.h
+++ b/app/display/gimpcanvas.h
@@ -34,8 +34,6 @@ typedef enum
   GIMP_CANVAS_STYLE_SELECTION_OUT,
   GIMP_CANVAS_STYLE_LAYER_BOUNDARY,
   GIMP_CANVAS_STYLE_LAYER_GROUP_BOUNDARY,
-  GIMP_CANVAS_STYLE_GUIDE_NORMAL,
-  GIMP_CANVAS_STYLE_GUIDE_ACTIVE,
   GIMP_CANVAS_STYLE_SAMPLE_POINT_NORMAL,
   GIMP_CANVAS_STYLE_SAMPLE_POINT_ACTIVE,
   GIMP_CANVAS_STYLE_LAYER_MASK_ACTIVE,
diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c
index f4d592e..1738640 100644
--- a/app/display/gimpdisplayshell-callbacks.c
+++ b/app/display/gimpdisplayshell-callbacks.c
@@ -2297,7 +2297,9 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
   cairo_restore (cr);
 
   /* draw the guides */
-  gimp_display_shell_draw_guides (shell, eevent->region);
+  cairo_save (cr);
+  gimp_display_shell_draw_guides (shell, cr);
+  cairo_restore (cr);
 
   /* draw the sample points */
   gimp_display_shell_draw_sample_points (shell, eevent->region);
diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c
index 26e7de0..7bef310 100644
--- a/app/display/gimpdisplayshell-draw.c
+++ b/app/display/gimpdisplayshell-draw.c
@@ -132,89 +132,80 @@ gimp_display_shell_draw_get_scaled_image_size_for_scale (GimpDisplayShell *shell
 
 void
 gimp_display_shell_draw_guide (GimpDisplayShell   *shell,
+                               cairo_t            *cr,
                                GimpGuide          *guide,
-                               const GdkRectangle *area,
                                gboolean            active)
 {
-  gint  position;
-  gint  x1, y1, x2, y2;
-  gint  x, y;
+  gint    position;
+  gdouble dx1, dy1, dx2, dy2;
+  gint    x1, y1, x2, y2;
+  gint    x, y;
 
   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+  g_return_if_fail (cr != NULL);
   g_return_if_fail (GIMP_IS_GUIDE (guide));
 
   position = gimp_guide_get_position (guide);
-
   if (position < 0)
     return;
 
-  x1 = 0;
-  y1 = 0;
+  cairo_clip_extents (cr, &dx1, &dy1, &dx2, &dy2);
+
+  x1 = floor (dx1);
+  y1 = floor (dy1);
+  x2 = ceil (dx2);
+  y2 = ceil (dy2);
 
-  gdk_drawable_get_size (gtk_widget_get_window (shell->canvas), &x2, &y2);
+  gimp_display_shell_set_guide_style (shell, cr, active);
 
   switch (gimp_guide_get_orientation (guide))
     {
     case GIMP_ORIENTATION_HORIZONTAL:
       gimp_display_shell_transform_xy (shell, 0, position, &x, &y, FALSE);
-      if (area && (y < area->y || y >= area->y + area->height))
-        return;
-      if (y < y1 || y >= y2)
-        return;
-      y1 = y2 = y;
+      if (y >= y1 && y < y2)
+        {
+          cairo_move_to (cr, x1, y + 0.5);
+          cairo_line_to (cr, x2, y + 0.5);
+        }
       break;
 
     case GIMP_ORIENTATION_VERTICAL:
       gimp_display_shell_transform_xy (shell, position, 0, &x, &y, FALSE);
-      if (area && (x < area->x || x >= area->x + area->width))
-        return;
-      if (x < x1 || x >= x2)
-        return;
-      x1 = x2 = x;
+      if (x >= x1 && x < x2)
+        {
+          cairo_move_to (cr, x + 0.5, y1);
+          cairo_line_to (cr, x + 0.5, y2);
+        }
       break;
 
     case GIMP_ORIENTATION_UNKNOWN:
       return;
     }
 
-  gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas),
-                         (active ?
-                          GIMP_CANVAS_STYLE_GUIDE_ACTIVE :
-                          GIMP_CANVAS_STYLE_GUIDE_NORMAL), x1, y1, x2, y2);
+  cairo_stroke (cr);
 }
 
 void
 gimp_display_shell_draw_guides (GimpDisplayShell *shell,
-                                const GdkRegion  *region)
+                                cairo_t          *cr)
 {
   GimpImage *image;
 
   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
-  g_return_if_fail (region != NULL);
+  g_return_if_fail (cr != NULL);
 
   image = gimp_display_get_image (shell->display);
 
   if (image && gimp_display_shell_get_show_guides (shell))
     {
-      GdkRectangle  area;
-      GList        *list;
-
-      gimp_canvas_set_clip_region (GIMP_CANVAS (shell->canvas),
-                                   GIMP_CANVAS_STYLE_GUIDE_NORMAL,
-                                   region);
-      gdk_region_get_clipbox (region, &area);
+      GList *list;
 
       for (list = gimp_image_get_guides (image);
            list;
            list = g_list_next (list))
         {
-          gimp_display_shell_draw_guide (shell, list->data,
-                                         &area, FALSE);
+          gimp_display_shell_draw_guide (shell, cr, list->data, FALSE);
         }
-
-      gimp_canvas_set_clip_region (GIMP_CANVAS (shell->canvas),
-                                   GIMP_CANVAS_STYLE_GUIDE_NORMAL,
-                                   NULL);
     }
 }
 
diff --git a/app/display/gimpdisplayshell-draw.h b/app/display/gimpdisplayshell-draw.h
index 1f48106..7473e02 100644
--- a/app/display/gimpdisplayshell-draw.h
+++ b/app/display/gimpdisplayshell-draw.h
@@ -28,11 +28,11 @@ void   gimp_display_shell_draw_get_scaled_image_size_for_scale
                                                       gint               *w,
                                                       gint               *h);
 void   gimp_display_shell_draw_guide                 (GimpDisplayShell   *shell,
+                                                      cairo_t            *cr,
                                                       GimpGuide          *guide,
-                                                      const GdkRectangle *area,
                                                       gboolean            active);
 void   gimp_display_shell_draw_guides                (GimpDisplayShell   *shell,
-                                                      const GdkRegion    *region);
+                                                      cairo_t            *cr);
 void   gimp_display_shell_draw_grid                  (GimpDisplayShell   *shell,
                                                       cairo_t            *cr);
 void   gimp_display_shell_draw_pen                   (GimpDisplayShell   *shell,
diff --git a/app/display/gimpdisplayshell-style.c b/app/display/gimpdisplayshell-style.c
index b730302..52d1f82 100644
--- a/app/display/gimpdisplayshell-style.c
+++ b/app/display/gimpdisplayshell-style.c
@@ -34,6 +34,41 @@
 #include "gimpdisplayshell-style.h"
 
 
+static const GimpRGB guide_normal_fg = { 0.0, 0.0, 0.0, 1.0 };
+static const GimpRGB guide_normal_bg = { 0.0, 0.5, 1.0, 1.0 };
+static const GimpRGB guide_active_fg = { 0.0, 0.0, 0.0, 1.0 };
+static const GimpRGB guide_active_bg = { 1.0, 0.0, 0.0, 1.0 };
+
+
+/*  local function prototypes  */
+
+static void   gimp_display_shell_set_stipple_style (cairo_t       *cr,
+                                                    const GimpRGB *fg,
+                                                    const GimpRGB *bg);
+
+
+/*  public functions  */
+
+void
+gimp_display_shell_set_guide_style (GimpDisplayShell *shell,
+                                    cairo_t          *cr,
+                                    gboolean          active)
+{
+  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+  g_return_if_fail (cr != NULL);
+
+  cairo_set_line_width (cr, 1.0);
+
+  if (active)
+    gimp_display_shell_set_stipple_style (cr,
+                                          &guide_active_fg,
+                                          &guide_active_bg);
+  else
+    gimp_display_shell_set_stipple_style (cr,
+                                          &guide_normal_fg,
+                                          &guide_normal_bg);
+}
+
 void
 gimp_display_shell_set_grid_style (GimpDisplayShell *shell,
                                    cairo_t          *cr,
@@ -49,49 +84,20 @@ gimp_display_shell_set_grid_style (GimpDisplayShell *shell,
     {
     case GIMP_GRID_ON_OFF_DASH:
     case GIMP_GRID_DOUBLE_DASH:
-      {
-        guchar *data = g_malloc0 (8 * 8 * 4);
-        guchar  fg_r, fg_g, fg_b, fg_a;
-        guchar  bg_r, bg_g, bg_b, bg_a;
-        gint    x, y;
-        guchar *d;
-        cairo_surface_t *surface;
-        static cairo_user_data_key_t data_key;
-
-        gimp_rgba_get_uchar (&grid->fgcolor, &fg_r, &fg_g, &fg_b, &fg_a);
-
-        if (grid->style == GIMP_GRID_DOUBLE_DASH)
-          gimp_rgba_get_uchar (&grid->bgcolor, &bg_r, &bg_g, &bg_b, &bg_a);
-        else
-          bg_r = bg_g = bg_b = bg_a = 0;
-
-        d = data;
-
-        for (y = 0; y < 8; y++)
-          {
-            for (x = 0; x < 8; x++)
-              {
-                if ((y < 4 && x < 4) || (y >= 4 && x >= 4))
-                  GIMP_CAIRO_ARGB32_SET_PIXEL (d, fg_r, fg_g, fg_b, fg_a);
-                else
-                  GIMP_CAIRO_ARGB32_SET_PIXEL (d, bg_r, bg_g, bg_b, bg_a);
-
-                d += 4;
-              }
-          }
-
-        surface = cairo_image_surface_create_for_data (data,
-                                                       CAIRO_FORMAT_ARGB32,
-                                                       8, 8, 8 * 4);
-        cairo_surface_set_user_data (surface, &data_key,
-                                     data, (cairo_destroy_func_t) g_free);
-
-        cairo_set_source_surface (cr, surface, 0, 0);
-        cairo_surface_destroy (surface);
-
-        cairo_pattern_set_extend (cairo_get_source (cr),
-                                  CAIRO_EXTEND_REPEAT);
-      }
+      if (grid->style == GIMP_GRID_DOUBLE_DASH)
+        {
+          gimp_display_shell_set_stipple_style (cr,
+                                                &grid->fgcolor,
+                                                &grid->bgcolor);
+        }
+      else
+        {
+          GimpRGB bg = { 0.0, 0.0, 0.0, 0.0 };
+
+          gimp_display_shell_set_stipple_style (cr,
+                                                &grid->fgcolor,
+                                                &bg);
+        }
       break;
 
     case GIMP_GRID_DOTS:
@@ -104,3 +110,50 @@ gimp_display_shell_set_grid_style (GimpDisplayShell *shell,
       break;
     }
 }
+
+
+/*  private functions  */
+
+static cairo_user_data_key_t surface_data_key = { 0, };
+
+static void
+gimp_display_shell_set_stipple_style (cairo_t       *cr,
+                                      const GimpRGB *fg,
+                                      const GimpRGB *bg)
+{
+  cairo_surface_t *surface;
+  guchar          *data = g_malloc0 (8 * 8 * 4);
+  guchar           fg_r, fg_g, fg_b, fg_a;
+  guchar           bg_r, bg_g, bg_b, bg_a;
+  gint             x, y;
+  guchar          *d;
+
+  gimp_rgba_get_uchar (fg, &fg_r, &fg_g, &fg_b, &fg_a);
+  gimp_rgba_get_uchar (bg, &bg_r, &bg_g, &bg_b, &bg_a);
+
+  d = data;
+
+  for (y = 0; y < 8; y++)
+    {
+      for (x = 0; x < 8; x++)
+        {
+          if ((y < 4 && x < 4) || (y >= 4 && x >= 4))
+            GIMP_CAIRO_ARGB32_SET_PIXEL (d, fg_r, fg_g, fg_b, fg_a);
+          else
+            GIMP_CAIRO_ARGB32_SET_PIXEL (d, bg_r, bg_g, bg_b, bg_a);
+
+          d += 4;
+        }
+    }
+
+  surface = cairo_image_surface_create_for_data (data,
+                                                 CAIRO_FORMAT_ARGB32,
+                                                 8, 8, 8 * 4);
+  cairo_surface_set_user_data (surface, &surface_data_key,
+                               data, (cairo_destroy_func_t) g_free);
+
+  cairo_set_source_surface (cr, surface, 0, 0);
+  cairo_surface_destroy (surface);
+
+  cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+}
diff --git a/app/display/gimpdisplayshell-style.h b/app/display/gimpdisplayshell-style.h
index 5618af7..41bb759 100644
--- a/app/display/gimpdisplayshell-style.h
+++ b/app/display/gimpdisplayshell-style.h
@@ -22,9 +22,12 @@
 #define __GIMP_DISPLAY_SHELL_STYLE_H__
 
 
-void   gimp_display_shell_set_grid_style (GimpDisplayShell *shell,
-                                          cairo_t          *cr,
-                                          GimpGrid         *grid);
+void   gimp_display_shell_set_guide_style (GimpDisplayShell *shell,
+                                           cairo_t          *cr,
+                                           gboolean          active);
+void   gimp_display_shell_set_grid_style  (GimpDisplayShell *shell,
+                                           cairo_t          *cr,
+                                           GimpGrid         *grid);
 
 
 #endif /* __GIMP_DISPLAY_SHELL_STYLE_H__ */
diff --git a/app/tools/gimpmovetool.c b/app/tools/gimpmovetool.c
index 893c727..5655254 100644
--- a/app/tools/gimpmovetool.c
+++ b/app/tools/gimpmovetool.c
@@ -190,12 +190,20 @@ gimp_move_tool_control (GimpTool       *tool,
 
     case GIMP_TOOL_ACTION_RESUME:
       if (move->guide && gimp_display_shell_get_show_guides (shell))
-        gimp_display_shell_draw_guide (shell, move->guide, NULL, TRUE);
+        {
+          cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (shell->canvas));
+          gimp_display_shell_draw_guide (shell, cr, move->guide, TRUE);
+          cairo_destroy (cr);
+        }
       break;
 
     case GIMP_TOOL_ACTION_HALT:
       if (move->guide && gimp_display_shell_get_show_guides (shell))
-        gimp_display_shell_draw_guide (shell, move->guide, NULL, FALSE);
+        {
+          cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (shell->canvas));
+          gimp_display_shell_draw_guide (shell, cr, move->guide, FALSE);
+          cairo_destroy (cr);
+        }
       break;
     }
 
@@ -446,7 +454,11 @@ gimp_move_tool_button_release (GimpTool              *tool,
       gimp_image_flush (image);
 
       if (move->guide)
-        gimp_display_shell_draw_guide (shell, move->guide, NULL, TRUE);
+        {
+          cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (shell->canvas));
+          gimp_display_shell_draw_guide (shell, cr, move->guide, TRUE);
+          cairo_destroy (cr);
+        }
 
       move->moving_guide      = FALSE;
       move->guide_position    = -1;
@@ -667,12 +679,20 @@ gimp_move_tool_oper_update (GimpTool         *tool,
     }
 
   if (move->guide && move->guide != guide)
-    gimp_display_shell_draw_guide (shell, move->guide, NULL, FALSE);
+    {
+      cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (shell->canvas));
+      gimp_display_shell_draw_guide (shell, cr, move->guide, FALSE);
+      cairo_destroy (cr);
+    }
 
   move->guide = guide;
 
   if (move->guide)
-    gimp_display_shell_draw_guide (shell, move->guide, NULL, TRUE);
+    {
+      cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (shell->canvas));
+      gimp_display_shell_draw_guide (shell, cr, move->guide, TRUE);
+      cairo_destroy (cr);
+    }
 }
 
 static void
@@ -818,8 +838,12 @@ gimp_move_tool_start_guide (GimpMoveTool        *move,
   gimp_tool_control_set_scroll_lock (tool->control, TRUE);
 
   if (move->guide)
-    gimp_display_shell_draw_guide (gimp_display_get_shell (display),
-                                   move->guide, NULL, FALSE);
+    {
+      GimpDisplayShell *shell = gimp_display_get_shell (display);
+      cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (shell->canvas));
+      gimp_display_shell_draw_guide (shell, cr, move->guide, FALSE);
+      cairo_destroy (cr);
+    }
 
   move->guide             = NULL;
   move->moving_guide      = TRUE;



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