[gimp] app: change boundary drawing by tools to work like the selection



commit 06da10bc082eb2f76bcce27a2180b66ef20c09af
Author: Michael Natterer <mitch gimp org>
Date:   Sun Sep 26 22:41:04 2010 +0200

    app: change boundary drawing by tools to work like the selection
    
    - GimpCanvasBoundary takes unsorted BoundSeg arrays now and uses
      gimp_display_shell_transform_boundary() and gimp_cairo_add_boundary().
    - Nobody calls boundary_sort() any longer for the purpose of displaying
      a boundary.
    - gimp_display_shell_transform_boundary() got offset parameters
      so it can transform things that are not in the image's coordinate
      system.

 app/base/boundary.c                      |   29 ++------
 app/display/gimpcanvasboundary.c         |  107 +++++++++++-------------------
 app/display/gimpdisplayshell-selection.c |    3 +-
 app/display/gimpdisplayshell-transform.c |   33 ++++-----
 app/display/gimpdisplayshell-transform.h |    4 +-
 app/paint/gimpbrushcore.c                |   21 ++-----
 app/tools/gimpeditselectiontool.c        |   11 +--
 app/tools/gimpregionselecttool.c         |   10 +---
 app/tools/gimptransformtool.c            |   64 +++++++-----------
 9 files changed, 101 insertions(+), 181 deletions(-)
---
diff --git a/app/base/boundary.c b/app/base/boundary.c
index d6d7ff9..a894086 100644
--- a/app/base/boundary.c
+++ b/app/base/boundary.c
@@ -373,30 +373,15 @@ boundary_transform (const BoundSeg *segs,
 
   for (i = 0; i < *num_segs; i++)
     {
-      /* dont transform sorting sentinels */
-      if (!(segs[i].x1 == -1 &&
-            segs[i].y1 == -1 &&
-            segs[i].x2 == -1 &&
-            segs[i].y2 == -1))
-        {
-          gdouble x1, y1, x2, y2;
+      gdouble x1, y1, x2, y2;
 
-          gimp_matrix3_transform_point (matrix, segs[i].x1, segs[i].y1, &x1, &y1);
-          gimp_matrix3_transform_point (matrix, segs[i].x2, segs[i].y2, &x2, &y2);
+      gimp_matrix3_transform_point (matrix, segs[i].x1, segs[i].y1, &x1, &y1);
+      gimp_matrix3_transform_point (matrix, segs[i].x2, segs[i].y2, &x2, &y2);
 
-          boundary_add_seg (boundary,
-                            (gint) ceil(x1), (gint) ceil(y1),
-                            (gint) ceil(x2), (gint) ceil(y2),
-                            segs[i].open);
-        }
-      else
-        {
-          /* Keep the sorting sentinel */
-          boundary_add_seg (boundary,
-                            -1, -1,
-                            -1, -1,
-                            segs[i].open);
-        }
+      boundary_add_seg (boundary,
+                        RINT (x1), RINT (y1),
+                        RINT (x2), RINT (y2),
+                        segs[i].open);
     }
 
   *num_segs = boundary->num_segs;
diff --git a/app/display/gimpcanvasboundary.c b/app/display/gimpcanvasboundary.c
index 6c9c989..1da4219 100644
--- a/app/display/gimpcanvasboundary.c
+++ b/app/display/gimpcanvasboundary.c
@@ -32,6 +32,8 @@
 
 #include "core/gimpparamspecs.h"
 
+#include "widgets/gimpcairo.h"
+
 #include "gimpcanvasboundary.h"
 #include "gimpdisplayshell.h"
 #include "gimpdisplayshell-transform.h"
@@ -121,6 +123,8 @@ gimp_canvas_boundary_class_init (GimpCanvasBoundaryClass *klass)
 static void
 gimp_canvas_boundary_init (GimpCanvasBoundary *boundary)
 {
+  gimp_canvas_item_set_line_cap (GIMP_CANVAS_ITEM (boundary),
+                                 CAIRO_LINE_CAP_SQUARE);
 }
 
 static void
@@ -191,36 +195,35 @@ gimp_canvas_boundary_get_property (GObject    *object,
 static void
 gimp_canvas_boundary_transform (GimpCanvasItem   *item,
                                 GimpDisplayShell *shell,
-                                BoundSeg         *segs)
+                                GdkSegment       *segs)
 {
   GimpCanvasBoundaryPrivate *private = GET_PRIVATE (item);
   gint                       i;
 
+  gimp_display_shell_transform_segments (shell,
+                                         private->segs, segs, private->n_segs,
+                                         private->offset_x, private->offset_y);
+
   for (i = 0; i < private->n_segs; i++)
     {
-      if (private->segs[i].x1 == -1 &&
-          private->segs[i].y1 == -1 &&
-          private->segs[i].x2 == -1 &&
-          private->segs[i].y2 == -1)
+      /*  If this segment is a closing segment && the segments lie inside
+       *  the region, OR if this is an opening segment and the segments
+       *  lie outside the region...
+       *  we need to transform it by one display pixel
+       */
+      if (! private->segs[i].open)
         {
-          segs[i] = private->segs[i];
-        }
-      else
-        {
-          gimp_display_shell_transform_xy (shell,
-                                           private->segs[i].x1 +
-                                           private->offset_x,
-                                           private->segs[i].y1 +
-                                           private->offset_y,
-                                           &segs[i].x1,
-                                           &segs[i].y1);
-          gimp_display_shell_transform_xy (shell,
-                                           private->segs[i].x2 +
-                                           private->offset_x,
-                                           private->segs[i].y2 +
-                                           private->offset_y,
-                                           &segs[i].x2,
-                                           &segs[i].y2);
+          /*  If it is vertical  */
+          if (segs[i].x1 == segs[i].x2)
+            {
+              segs[i].x1 -= 1;
+              segs[i].x2 -= 1;
+            }
+          else
+            {
+              segs[i].y1 -= 1;
+              segs[i].y2 -= 1;
+            }
         }
     }
 }
@@ -231,38 +234,14 @@ gimp_canvas_boundary_draw (GimpCanvasItem   *item,
                            cairo_t          *cr)
 {
   GimpCanvasBoundaryPrivate *private = GET_PRIVATE (item);
-  BoundSeg                  *segs;
-  gint                       i;
+  GdkSegment                *segs;
 
-  segs = g_new0 (BoundSeg, private->n_segs);
+  segs = g_new0 (GdkSegment, private->n_segs);
 
   gimp_canvas_boundary_transform (item, shell, segs);
 
-  cairo_move_to (cr, segs[0].x1 + 0.5, segs[0].y1 + 0.5);
-
-  for (i = 1; i < private->n_segs; i++)
-    {
-      if (segs[i].x1 == -1 &&
-          segs[i].y1 == -1 &&
-          segs[i].x2 == -1 &&
-          segs[i].y2 == -1)
-        {
-          cairo_close_path (cr);
-          _gimp_canvas_item_stroke (item, shell, cr);
+  gimp_cairo_add_segments (cr, segs, private->n_segs);
 
-          i++;
-          if (i == private->n_segs)
-            break;
-
-          cairo_move_to (cr, segs[i].x1 + 0.5, segs[i].y1 + 0.5);
-        }
-      else
-        {
-          cairo_line_to (cr, segs[i].x1 + 0.5, segs[i].y1 + 0.5);
-        }
-    }
-
-  cairo_close_path (cr);
   _gimp_canvas_item_stroke (item, shell, cr);
 
   g_free (segs);
@@ -274,11 +253,11 @@ gimp_canvas_boundary_get_extents (GimpCanvasItem   *item,
 {
   GimpCanvasBoundaryPrivate *private = GET_PRIVATE (item);
   GdkRectangle               rectangle;
-  BoundSeg                  *segs;
+  GdkSegment                *segs;
   gint                       x1, y1, x2, y2;
   gint                       i;
 
-  segs = g_new0 (BoundSeg, private->n_segs);
+  segs = g_new0 (GdkSegment, private->n_segs);
 
   gimp_canvas_boundary_transform (item, shell, segs);
 
@@ -289,21 +268,15 @@ gimp_canvas_boundary_get_extents (GimpCanvasItem   *item,
 
   for (i = 1; i < private->n_segs; i++)
     {
-      if (segs[i].x1 != -1 ||
-          segs[i].y1 != -1 ||
-          segs[i].x2 != -1 ||
-          segs[i].y2 != -1)
-        {
-          gint x3 = segs[i].x1 - 1;
-          gint y3 = segs[i].y1 - 1;
-          gint x4 = x3 + 3;
-          gint y4 = y3 + 3;
-
-          x1 = MIN (x1, x3);
-          y1 = MIN (y1, y3);
-          x2 = MAX (x2, x4);
-          y2 = MAX (y2, y4);
-        }
+      gint x3 = segs[i].x1 - 1;
+      gint y3 = segs[i].y1 - 1;
+      gint x4 = x3 + 3;
+      gint y4 = y3 + 3;
+
+      x1 = MIN (x1, x3);
+      y1 = MIN (y1, y3);
+      x2 = MAX (x2, x4);
+      y2 = MAX (y2, y4);
     }
 
   g_free (segs);
diff --git a/app/display/gimpdisplayshell-selection.c b/app/display/gimpdisplayshell-selection.c
index cbbfe49..936fbcf 100644
--- a/app/display/gimpdisplayshell-selection.c
+++ b/app/display/gimpdisplayshell-selection.c
@@ -409,7 +409,8 @@ selection_transform_segs (Selection      *selection,
   gint       i;
 
   gimp_display_shell_transform_segments (selection->shell,
-                                         src_segs, dest_segs, n_segs);
+                                         src_segs, dest_segs, n_segs,
+                                         0.0, 0.0);
 
   for (i = 0; i < n_segs; i++)
     {
diff --git a/app/display/gimpdisplayshell-transform.c b/app/display/gimpdisplayshell-transform.c
index f0e6f45..3c86bf4 100644
--- a/app/display/gimpdisplayshell-transform.c
+++ b/app/display/gimpdisplayshell-transform.c
@@ -307,7 +307,9 @@ void
 gimp_display_shell_transform_segments (const GimpDisplayShell *shell,
                                        const BoundSeg         *src_segs,
                                        GdkSegment             *dest_segs,
-                                       gint                    n_segs)
+                                       gint                    n_segs,
+                                       gdouble                 offset_x,
+                                       gdouble                 offset_y)
 {
   gint i;
 
@@ -315,23 +317,18 @@ gimp_display_shell_transform_segments (const GimpDisplayShell *shell,
 
   for (i = 0; i < n_segs ; i++)
     {
-      gint64 x1, x2;
-      gint64 y1, y2;
-
-      x1 = src_segs[i].x1;
-      x2 = src_segs[i].x2;
-      y1 = src_segs[i].y1;
-      y2 = src_segs[i].y2;
-
-      x1 = (x1 * shell->x_src_dec) / shell->x_dest_inc;
-      x2 = (x2 * shell->x_src_dec) / shell->x_dest_inc;
-      y1 = (y1 * shell->y_src_dec) / shell->y_dest_inc;
-      y2 = (y2 * shell->y_src_dec) / shell->y_dest_inc;
-
-      dest_segs[i].x1 = CLAMP (x1 - shell->offset_x, G_MININT, G_MAXINT);
-      dest_segs[i].x2 = CLAMP (x2 - shell->offset_x, G_MININT, G_MAXINT);
-      dest_segs[i].y1 = CLAMP (y1 - shell->offset_y, G_MININT, G_MAXINT);
-      dest_segs[i].y2 = CLAMP (y2 - shell->offset_y, G_MININT, G_MAXINT);
+      gdouble x1, x2;
+      gdouble y1, y2;
+
+      x1 = src_segs[i].x1 + offset_x;
+      x2 = src_segs[i].x2 + offset_x;
+      y1 = src_segs[i].y1 + offset_y;
+      y2 = src_segs[i].y2 + offset_y;
+
+      dest_segs[i].x1 = SCALEX (shell, x1) - shell->offset_x;
+      dest_segs[i].x2 = SCALEX (shell, x2) - shell->offset_x;
+      dest_segs[i].y1 = SCALEY (shell, y1) - shell->offset_y;
+      dest_segs[i].y2 = SCALEY (shell, y2) - shell->offset_y;
     }
 }
 
diff --git a/app/display/gimpdisplayshell-transform.h b/app/display/gimpdisplayshell-transform.h
index 296b0a2..9e44355 100644
--- a/app/display/gimpdisplayshell-transform.h
+++ b/app/display/gimpdisplayshell-transform.h
@@ -60,7 +60,9 @@ void  gimp_display_shell_transform_coords       (const GimpDisplayShell *shell,
 void  gimp_display_shell_transform_segments     (const GimpDisplayShell *shell,
                                                  const BoundSeg         *src_segs,
                                                  GdkSegment             *dest_segs,
-                                                 gint                    n_segs);
+                                                 gint                    n_segs,
+                                                 gdouble                 offset_x,
+                                                 gdouble                 offset_y);
 
 void  gimp_display_shell_untransform_viewport   (const GimpDisplayShell *shell,
                                                  gint                   *x,
diff --git a/app/paint/gimpbrushcore.c b/app/paint/gimpbrushcore.c
index 8eabb8c..fac579b 100644
--- a/app/paint/gimpbrushcore.c
+++ b/app/paint/gimpbrushcore.c
@@ -997,9 +997,7 @@ gimp_brush_core_create_bound_segs (GimpBrushCore    *core,
 
   if (mask)
     {
-      PixelRegion  PR = { 0, };
-      BoundSeg    *boundary;
-      gint         num_groups;
+      PixelRegion PR = { 0, };
 
       pixel_region_init_temp_buf (&PR, mask,
                                   0, 0, mask->width, mask->height);
@@ -1010,19 +1008,10 @@ gimp_brush_core_create_bound_segs (GimpBrushCore    *core,
       if (mask->width > 32 && mask->height > 32)
         smooth_region (&PR);
 
-
-      boundary = boundary_find (&PR, BOUNDARY_WITHIN_BOUNDS,
-                                0, 0, PR.w, PR.h,
-                                0,
-                                &core->n_brush_bound_segs);
-
-      core->brush_bound_segs = boundary_sort (boundary,
-                                              core->n_brush_bound_segs,
-                                              &num_groups);
-
-      core->n_brush_bound_segs += num_groups;
-
-      g_free (boundary);
+      core->brush_bound_segs = boundary_find (&PR, BOUNDARY_WITHIN_BOUNDS,
+                                              0, 0, PR.w, PR.h,
+                                              0,
+                                              &core->n_brush_bound_segs);
 
       core->brush_bound_width  = mask->width;
       core->brush_bound_height = mask->height;
diff --git a/app/tools/gimpeditselectiontool.c b/app/tools/gimpeditselectiontool.c
index ba463d5..b1cfbfc 100644
--- a/app/tools/gimpeditselectiontool.c
+++ b/app/tools/gimpeditselectiontool.c
@@ -194,7 +194,6 @@ gimp_edit_selection_tool_start (GimpTool          *parent_tool,
   gint                   off_x, off_y;
   const BoundSeg        *segs_in;
   const BoundSeg        *segs_out;
-  gint                   num_groups;
   const gchar           *undo_desc;
 
   edit_select = g_object_new (GIMP_TYPE_EDIT_SELECTION_TOOL,
@@ -281,13 +280,11 @@ gimp_edit_selection_tool_start (GimpTool          *parent_tool,
                          &edit_select->num_segs_in, &edit_select->num_segs_out,
                          0, 0, 0, 0);
 
-  edit_select->segs_in = boundary_sort (segs_in, edit_select->num_segs_in,
-                                        &num_groups);
-  edit_select->num_segs_in += num_groups;
+  edit_select->segs_in = g_memdup (segs_in,
+                                   edit_select->num_segs_in * sizeof (BoundSeg));
 
-  edit_select->segs_out = boundary_sort (segs_out, edit_select->num_segs_out,
-                                         &num_groups);
-  edit_select->num_segs_out += num_groups;
+  edit_select->segs_out = g_memdup (segs_out,
+                                    edit_select->num_segs_out * sizeof (BoundSeg));
 
   if (edit_select->edit_mode == GIMP_TRANSLATE_MODE_VECTORS)
     {
diff --git a/app/tools/gimpregionselecttool.c b/app/tools/gimpregionselecttool.c
index 41d2a51..9e28af0 100644
--- a/app/tools/gimpregionselecttool.c
+++ b/app/tools/gimpregionselecttool.c
@@ -342,9 +342,7 @@ gimp_region_select_tool_calculate (GimpRegionSelectTool *region_sel,
 {
   GimpDisplayShell *shell = gimp_display_get_shell (display);
   BoundSeg         *segs;
-  BoundSeg         *sorted;
   PixelRegion       maskPR;
-  gint              n_groups;
 
   gimp_display_shell_set_override_cursor (shell, GDK_WATCH);
 
@@ -380,13 +378,7 @@ gimp_region_select_tool_calculate (GimpRegionSelectTool *region_sel,
                         BOUNDARY_HALF_WAY,
                         n_segs);
 
-  sorted = boundary_sort (segs, *n_segs, &n_groups);
-
-  *n_segs += n_groups;
-
-  g_free (segs);
-
   gimp_display_shell_unset_override_cursor (shell);
 
-  return sorted;
+  return segs;
 }
diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c
index b7059ba..d72c8b8 100644
--- a/app/tools/gimptransformtool.c
+++ b/app/tools/gimptransformtool.c
@@ -949,7 +949,6 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
       BoundSeg       *segs_out;
       gint            num_segs_in;
       gint            num_segs_out;
-      gint            num_groups;
       gint            i;
 
       gimp_channel_boundary (gimp_image_get_mask (image),
@@ -957,11 +956,8 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
                              &num_segs_in, &num_segs_out,
                              0, 0, 0, 0);
 
-      segs_in = boundary_sort (orig_in, num_segs_in, &num_groups);
-      num_segs_in += num_groups;
-
-      segs_out = boundary_sort (orig_out, num_segs_out, &num_groups);
-      num_segs_out += num_groups;
+      segs_in  = g_memdup (orig_in,  num_segs_in  * sizeof (BoundSeg));
+      segs_out = g_memdup (orig_out, num_segs_out * sizeof (BoundSeg));
 
       if (segs_in)
         {
@@ -969,23 +965,17 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
             {
               gdouble tx, ty;
 
-              if (segs_in[i].x1 != -1 &&
-                  segs_in[i].y1 != -1 &&
-                  segs_in[i].x2 != -1 &&
-                  segs_in[i].y2 != -1)
-                {
-                  gimp_matrix3_transform_point (&matrix,
-                                                segs_in[i].x1, segs_in[i].y1,
-                                                &tx, &ty);
-                  segs_in[i].x1 = RINT (tx);
-                  segs_in[i].y1 = RINT (ty);
-
-                  gimp_matrix3_transform_point (&matrix,
-                                                segs_in[i].x2, segs_in[i].y2,
-                                                &tx, &ty);
-                  segs_in[i].x2 = RINT (tx);
-                  segs_in[i].y2 = RINT (ty);
-                }
+              gimp_matrix3_transform_point (&matrix,
+                                            segs_in[i].x1, segs_in[i].y1,
+                                            &tx, &ty);
+              segs_in[i].x1 = RINT (tx);
+              segs_in[i].y1 = RINT (ty);
+
+              gimp_matrix3_transform_point (&matrix,
+                                            segs_in[i].x2, segs_in[i].y2,
+                                            &tx, &ty);
+              segs_in[i].x2 = RINT (tx);
+              segs_in[i].y2 = RINT (ty);
             }
 
           gimp_draw_tool_add_boundary (draw_tool,
@@ -1000,23 +990,17 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
             {
               gdouble tx, ty;
 
-              if (segs_out[i].x1 != -1 &&
-                  segs_out[i].y1 != -1 &&
-                  segs_out[i].x2 != -1 &&
-                  segs_out[i].y2 != -1)
-                {
-                  gimp_matrix3_transform_point (&matrix,
-                                                segs_out[i].x1, segs_out[i].y1,
-                                                &tx, &ty);
-                  segs_out[i].x1 = RINT (tx);
-                  segs_out[i].y1 = RINT (ty);
-
-                  gimp_matrix3_transform_point (&matrix,
-                                                segs_out[i].x2, segs_out[i].y2,
-                                                &tx, &ty);
-                  segs_out[i].x2 = RINT (tx);
-                  segs_out[i].y2 = RINT (ty);
-                }
+              gimp_matrix3_transform_point (&matrix,
+                                            segs_out[i].x1, segs_out[i].y1,
+                                            &tx, &ty);
+              segs_out[i].x1 = RINT (tx);
+              segs_out[i].y1 = RINT (ty);
+
+              gimp_matrix3_transform_point (&matrix,
+                                            segs_out[i].x2, segs_out[i].y2,
+                                            &tx, &ty);
+              segs_out[i].x2 = RINT (tx);
+              segs_out[i].y2 = RINT (ty);
             }
 
           gimp_draw_tool_add_boundary (draw_tool,



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