[gimp] app: port GimpDisplayShell layer boundary drawing to cairo



commit 4e0925a67c0af366357fd3196f851b99dec53456
Author: Michael Natterer <mitch gimp org>
Date:   Tue Aug 24 18:07:31 2010 +0200

    app: port GimpDisplayShell layer boundary drawing to cairo
    
    The boundary is temporarily kept around as both BoundSeg and
    GdkSegment arrays now, but this uglyness will go away once porting to
    cairo is complete.

 app/display/gimpcanvas.c                 |   33 ---------------
 app/display/gimpcanvas.h                 |    3 -
 app/display/gimpdisplayshell-draw.c      |   67 ++++++++++++++++++++++++++++++
 app/display/gimpdisplayshell-draw.h      |    5 ++
 app/display/gimpdisplayshell-selection.c |   54 ++++++++++++++----------
 app/display/gimpdisplayshell-style.c     |   41 ++++++++++++++++++
 app/display/gimpdisplayshell-style.h     |    3 +
 7 files changed, 148 insertions(+), 58 deletions(-)
---
diff --git a/app/display/gimpcanvas.c b/app/display/gimpcanvas.c
index 77227e6..0043ebf 100644
--- a/app/display/gimpcanvas.c
+++ b/app/display/gimpcanvas.c
@@ -398,9 +398,6 @@ gimp_canvas_gc_new (GimpCanvas      *canvas,
 
     case GIMP_CANVAS_STYLE_SELECTION_IN:
     case GIMP_CANVAS_STYLE_SELECTION_OUT:
-    case GIMP_CANVAS_STYLE_LAYER_BOUNDARY:
-    case GIMP_CANVAS_STYLE_LAYER_GROUP_BOUNDARY:
-    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;
       values.fill      = GDK_OPAQUE_STIPPLED;
@@ -456,36 +453,6 @@ gimp_canvas_gc_new (GimpCanvas      *canvas,
       bg.green = 0x7f7f;
       bg.blue  = 0x7f7f;
       break;
-
-    case GIMP_CANVAS_STYLE_LAYER_BOUNDARY:
-      fg.red   = 0x0;
-      fg.green = 0x0;
-      fg.blue  = 0x0;
-
-      bg.red   = 0xffff;
-      bg.green = 0xffff;
-      bg.blue  = 0x0;
-      break;
-
-    case GIMP_CANVAS_STYLE_LAYER_GROUP_BOUNDARY:
-      fg.red   = 0x0;
-      fg.green = 0x0;
-      fg.blue  = 0x0;
-
-      bg.red   = 0x0;
-      bg.green = 0xffff;
-      bg.blue  = 0xffff;
-      break;
-
-    case GIMP_CANVAS_STYLE_LAYER_MASK_ACTIVE:
-      fg.red   = 0x0;
-      fg.green = 0x0;
-      fg.blue  = 0x0;
-
-      bg.red   = 0x0;
-      bg.green = 0xffff;
-      bg.blue  = 0x0;
-      break;
     }
 
   gdk_gc_set_rgb_fg_color (gc, &fg);
diff --git a/app/display/gimpcanvas.h b/app/display/gimpcanvas.h
index 2be5ec3..52eb9db 100644
--- a/app/display/gimpcanvas.h
+++ b/app/display/gimpcanvas.h
@@ -32,9 +32,6 @@ typedef enum
   GIMP_CANVAS_STYLE_XOR_DOTTED,
   GIMP_CANVAS_STYLE_SELECTION_IN,
   GIMP_CANVAS_STYLE_SELECTION_OUT,
-  GIMP_CANVAS_STYLE_LAYER_BOUNDARY,
-  GIMP_CANVAS_STYLE_LAYER_GROUP_BOUNDARY,
-  GIMP_CANVAS_STYLE_LAYER_MASK_ACTIVE,
   GIMP_CANVAS_NUM_STYLES
 } GimpCanvasStyle;
 
diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c
index b6d209f..45b3d85 100644
--- a/app/display/gimpdisplayshell-draw.c
+++ b/app/display/gimpdisplayshell-draw.c
@@ -26,9 +26,11 @@
 
 #include "display-types.h"
 
+#include "base/boundary.h"
 #include "base/tile-manager.h"
 
 #include "core/gimpcontext.h"
+#include "core/gimpdrawable.h"
 #include "core/gimpgrid.h"
 #include "core/gimpguide.h"
 #include "core/gimpimage.h"
@@ -530,6 +532,71 @@ gimp_display_shell_draw_sample_points (GimpDisplayShell *shell,
 }
 
 void
+gimp_display_shell_draw_layer_boundary (GimpDisplayShell *shell,
+                                        cairo_t          *cr,
+                                        GimpDrawable     *drawable,
+                                        BoundSeg         *segs,
+                                        gint              n_segs)
+{
+  gint i;
+
+  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+  g_return_if_fail (cr != NULL);
+  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+  g_return_if_fail (segs != NULL && n_segs == 4);
+
+  gimp_display_shell_set_layer_style (shell, cr, drawable);
+
+  for (i = 0; i < n_segs; i++)
+    {
+      gint xclamp = shell->disp_width  + 1;
+      gint yclamp = shell->disp_height + 1;
+      gint x1, y1;
+      gint x2, y2;
+
+      gimp_display_shell_transform_xy (shell,
+                                       segs[i].x1, segs[i].y1,
+                                       &x1, &y1,
+                                       FALSE);
+      gimp_display_shell_transform_xy (shell,
+                                       segs[i].x2, segs[i].y2,
+                                       &x2, &y2,
+                                       FALSE);
+
+      x1 = CLAMP (x1, -1, xclamp);
+      y1 = CLAMP (y1, -1, yclamp);
+
+      x2 = CLAMP (x2, -1, xclamp);
+      y2 = CLAMP (y2, -1, yclamp);
+
+      if (x1 == x2)
+        {
+          if (! segs[i].open)
+            {
+              x1 -= 1;
+              x2 -= 1;
+            }
+
+          cairo_move_to (cr, x1 + 0.5, y1);
+          cairo_line_to (cr, x2 + 0.5, y2);
+        }
+      else
+        {
+          if (! segs[i].open)
+            {
+              y1 -= 1;
+              y2 -= 1;
+            }
+
+          cairo_move_to (cr, x1, y1 + 0.5);
+          cairo_line_to (cr, x2, y2 + 0.5);
+        }
+    }
+
+  cairo_stroke (cr);
+}
+
+void
 gimp_display_shell_draw_vector (GimpDisplayShell *shell,
                                 GimpVectors      *vectors)
 {
diff --git a/app/display/gimpdisplayshell-draw.h b/app/display/gimpdisplayshell-draw.h
index b4d8aad..6bb8bd6 100644
--- a/app/display/gimpdisplayshell-draw.h
+++ b/app/display/gimpdisplayshell-draw.h
@@ -48,6 +48,11 @@ void   gimp_display_shell_draw_sample_point          (GimpDisplayShell   *shell,
                                                       gboolean            active);
 void   gimp_display_shell_draw_sample_points         (GimpDisplayShell   *shell,
                                                       cairo_t            *cr);
+void   gimp_display_shell_draw_layer_boundary        (GimpDisplayShell   *shell,
+                                                      cairo_t            *cr,
+                                                      GimpDrawable       *drawable,
+                                                      BoundSeg           *segs,
+                                                      gint                n_segs);
 void   gimp_display_shell_draw_vector                (GimpDisplayShell   *shell,
                                                       GimpVectors        *vectors);
 void   gimp_display_shell_draw_vectors               (GimpDisplayShell   *shell);
diff --git a/app/display/gimpdisplayshell-selection.c b/app/display/gimpdisplayshell-selection.c
index 1cc0a2a..a031035 100644
--- a/app/display/gimpdisplayshell-selection.c
+++ b/app/display/gimpdisplayshell-selection.c
@@ -35,6 +35,7 @@
 #include "gimpdisplay.h"
 #include "gimpdisplayshell.h"
 #include "gimpdisplayshell-appearance.h"
+#include "gimpdisplayshell-draw.h"
 #include "gimpdisplayshell-expose.h"
 #include "gimpdisplayshell-selection.h"
 #include "gimpdisplayshell-transform.h"
@@ -56,6 +57,9 @@ struct _Selection
   GdkSegment       *segs_out;         /*  gdk segments of area boundary     */
   gint              n_segs_out;       /*  number of segments in segs2       */
 
+  BoundSeg         *bound_segs_layer;
+  gint              n_bound_segs_layer;
+
   GdkSegment       *segs_layer;       /*  gdk segments of layer boundary    */
   gint              n_segs_layer;     /*  number of segments in segs3       */
 
@@ -384,21 +388,20 @@ selection_layer_draw (Selection *selection)
 {
   if (selection->segs_layer)
     {
-      GimpCanvas     *canvas   = GIMP_CANVAS (selection->shell->canvas);
-      GimpImage      *image    = gimp_display_get_image (selection->shell->display);
-      GimpDrawable   *drawable = gimp_image_get_active_drawable (image);
-      GimpCanvasStyle style;
-
-      if (GIMP_IS_LAYER_MASK (drawable))
-        style = GIMP_CANVAS_STYLE_LAYER_MASK_ACTIVE;
-      else if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
-        style = GIMP_CANVAS_STYLE_LAYER_GROUP_BOUNDARY;
-      else
-        style = GIMP_CANVAS_STYLE_LAYER_BOUNDARY;
+      GimpImage    *image;
+      GimpDrawable *drawable;
+      cairo_t      *cr;
+
+      image    = gimp_display_get_image (selection->shell->display);
+      drawable = gimp_image_get_active_drawable (image);
+
+      cr = gdk_cairo_create (gtk_widget_get_window (selection->shell->canvas));
+
+      gimp_display_shell_draw_layer_boundary (selection->shell, cr, drawable,
+                                              selection->bound_segs_layer,
+                                              selection->n_bound_segs_layer);
 
-      gimp_canvas_draw_segments (canvas, style,
-                                 selection->segs_layer,
-                                 selection->n_segs_layer);
+      cairo_destroy (cr);
     }
 }
 
@@ -659,19 +662,19 @@ selection_generate_segs (Selection *selection)
 
   if (layer)
     {
-      BoundSeg *segs;
+      selection->bound_segs_layer =
+        gimp_layer_boundary (layer, &selection->n_bound_segs_layer);
 
-      segs = gimp_layer_boundary (layer, &selection->n_segs_layer);
-
-      if (selection->n_segs_layer)
+      if (selection->n_bound_segs_layer)
         {
-          selection->segs_layer = g_new (GdkSegment, selection->n_segs_layer);
+          selection->segs_layer   = g_new (GdkSegment,
+                                           selection->n_bound_segs_layer);
+          selection->n_segs_layer = selection->n_bound_segs_layer;
 
-          selection_transform_segs (selection, segs,
+          selection_transform_segs (selection,
+                                    selection->bound_segs_layer,
                                     selection->segs_layer,
                                     selection->n_segs_layer);
-
-          g_free (segs);
         }
     }
 }
@@ -695,6 +698,13 @@ selection_free_segs (Selection *selection)
       selection->n_segs_out = 0;
     }
 
+  if (selection->bound_segs_layer)
+    {
+      g_free (selection->bound_segs_layer);
+      selection->bound_segs_layer   = NULL;
+      selection->n_bound_segs_layer = 0;
+    }
+
   if (selection->segs_layer)
     {
       g_free (selection->segs_layer);
diff --git a/app/display/gimpdisplayshell-style.c b/app/display/gimpdisplayshell-style.c
index cfba3b6..adb1603 100644
--- a/app/display/gimpdisplayshell-style.c
+++ b/app/display/gimpdisplayshell-style.c
@@ -30,6 +30,7 @@
 
 #include "core/gimpcontext.h"
 #include "core/gimpgrid.h"
+#include "core/gimplayermask.h"
 
 #include "gimpdisplayshell.h"
 #include "gimpdisplayshell-style.h"
@@ -43,6 +44,15 @@ static const GimpRGB guide_active_bg     = { 1.0, 0.0, 0.0, 1.0 };
 static const GimpRGB sample_point_normal = { 0.0, 0.5, 1.0, 1.0 };
 static const GimpRGB sample_point_active = { 1.0, 0.0, 0.0, 1.0 };
 
+static const GimpRGB layer_fg            = { 0.0, 0.0, 0.0, 1.0 };
+static const GimpRGB layer_bg            = { 1.0, 1.0, 0.0, 1.0 };
+
+static const GimpRGB layer_group_fg      = { 0.0, 0.0, 0.0, 1.0 };
+static const GimpRGB layer_group_bg      = { 0.0, 1.0, 1.0, 1.0 };
+
+static const GimpRGB layer_mask_fg       = { 0.0, 0.0, 0.0, 1.0 };
+static const GimpRGB layer_mask_bg       = { 0.0, 1.0, 0.0, 1.0 };
+
 
 /*  local function prototypes  */
 
@@ -182,6 +192,37 @@ gimp_display_shell_set_pen_style (GimpDisplayShell *shell,
   cairo_set_source_rgb (cr, rgb.r, rgb.g, rgb.b);
 }
 
+void
+gimp_display_shell_set_layer_style (GimpDisplayShell *shell,
+                                    cairo_t          *cr,
+                                    GimpDrawable     *drawable)
+{
+  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+  g_return_if_fail (cr != NULL);
+  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+
+  cairo_set_line_width (cr, 1.0);
+
+  if (GIMP_IS_LAYER_MASK (drawable))
+    {
+      gimp_display_shell_set_stipple_style (cr,
+                                            &layer_mask_fg,
+                                            &layer_mask_bg);
+    }
+  else if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
+    {
+      gimp_display_shell_set_stipple_style (cr,
+                                            &layer_group_fg,
+                                            &layer_group_bg);
+    }
+  else
+    {
+      gimp_display_shell_set_stipple_style (cr,
+                                            &layer_fg,
+                                            &layer_bg);
+    }
+}
+
 
 /*  private functions  */
 
diff --git a/app/display/gimpdisplayshell-style.h b/app/display/gimpdisplayshell-style.h
index a71f683..2717da4 100644
--- a/app/display/gimpdisplayshell-style.h
+++ b/app/display/gimpdisplayshell-style.h
@@ -38,6 +38,9 @@ void   gimp_display_shell_set_pen_style          (GimpDisplayShell *shell,
                                                   GimpContext      *context,
                                                   GimpActiveColor   active,
                                                   gint              width);
+void   gimp_display_shell_set_layer_style        (GimpDisplayShell *shell,
+                                                  cairo_t          *cr,
+                                                  GimpDrawable     *drawable);
 
 
 #endif /* __GIMP_DISPLAY_SHELL_STYLE_H__ */



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