[gimp] app: add GimpCanvasTransformGuides and use them in the transform tool



commit c2e6f246875ff99c066264a4da9a6d1a17ff6be2
Author: Michael Natterer <mitch gimp org>
Date:   Sun Jul 24 18:42:13 2011 +0200

    app: add GimpCanvasTransformGuides and use them in the transform tool
    
    which removes a lot of code from the transform tool, and reduces the
    number of canvas items used for the transform grid from possibly
    gazillions to one.

 app/display/Makefile.am                 |    2 +
 app/display/gimpcanvastransformguides.c |  511 +++++++++++++++++++++++++++++++
 app/display/gimpcanvastransformguides.h |   67 ++++
 app/tools/gimpdrawtool.c                |   26 ++
 app/tools/gimpdrawtool.h                |    8 +
 app/tools/gimptransformtool.c           |  149 +---------
 app/tools/gimptransformtool.h           |    8 -
 7 files changed, 622 insertions(+), 149 deletions(-)
---
diff --git a/app/display/Makefile.am b/app/display/Makefile.am
index 3ac38c7..6bee6f8 100644
--- a/app/display/Makefile.am
+++ b/app/display/Makefile.am
@@ -63,6 +63,8 @@ libappdisplay_a_sources = \
 	gimpcanvassamplepoint.h			\
 	gimpcanvastextcursor.c			\
 	gimpcanvastextcursor.h			\
+	gimpcanvastransformguides.c		\
+	gimpcanvastransformguides.h		\
 	gimpcanvastransformpreview.c		\
 	gimpcanvastransformpreview.h		\
 	gimpcursorview.c			\
diff --git a/app/display/gimpcanvastransformguides.c b/app/display/gimpcanvastransformguides.c
new file mode 100644
index 0000000..d8e6f0e
--- /dev/null
+++ b/app/display/gimpcanvastransformguides.c
@@ -0,0 +1,511 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpcanvastransformguides.c
+ * Copyright (C) 2011 Michael Natterer <mitch gimp org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpmath/gimpmath.h"
+
+#include "display-types.h"
+
+#include "core/gimp-transform-utils.h"
+
+#include "gimpcanvastransformguides.h"
+#include "gimpdisplayshell.h"
+#include "gimpdisplayshell-transform.h"
+#include "core/gimp-utils.h"
+
+
+enum
+{
+  PROP_0,
+  PROP_TRANSFORM,
+  PROP_X1,
+  PROP_Y1,
+  PROP_X2,
+  PROP_Y2,
+  PROP_TYPE,
+  PROP_N_GUIDES
+};
+
+
+typedef struct _GimpCanvasTransformGuidesPrivate GimpCanvasTransformGuidesPrivate;
+
+struct _GimpCanvasTransformGuidesPrivate
+{
+  GimpMatrix3    transform;
+  gdouble        x1, y1;
+  gdouble        x2, y2;
+  GimpGuidesType type;
+  gint           n_guides;
+};
+
+#define GET_PRIVATE(transform) \
+        G_TYPE_INSTANCE_GET_PRIVATE (transform, \
+                                     GIMP_TYPE_CANVAS_TRANSFORM_GUIDES, \
+                                     GimpCanvasTransformGuidesPrivate)
+
+
+/*  local function prototypes  */
+
+static void             gimp_canvas_transform_guides_set_property (GObject          *object,
+                                                                   guint             property_id,
+                                                                   const GValue     *value,
+                                                                   GParamSpec       *pspec);
+static void             gimp_canvas_transform_guides_get_property (GObject          *object,
+                                                                   guint             property_id,
+                                                                   GValue           *value,
+                                                                   GParamSpec       *pspec);
+static void             gimp_canvas_transform_guides_draw         (GimpCanvasItem   *item,
+                                                                   GimpDisplayShell *shell,
+                                                                   cairo_t          *cr);
+static cairo_region_t * gimp_canvas_transform_guides_get_extents  (GimpCanvasItem   *item,
+                                                                   GimpDisplayShell *shell);
+
+
+G_DEFINE_TYPE (GimpCanvasTransformGuides, gimp_canvas_transform_guides,
+               GIMP_TYPE_CANVAS_ITEM)
+
+#define parent_class gimp_canvas_transform_guides_parent_class
+
+
+static void
+gimp_canvas_transform_guides_class_init (GimpCanvasTransformGuidesClass *klass)
+{
+  GObjectClass        *object_class = G_OBJECT_CLASS (klass);
+  GimpCanvasItemClass *item_class   = GIMP_CANVAS_ITEM_CLASS (klass);
+
+  object_class->set_property = gimp_canvas_transform_guides_set_property;
+  object_class->get_property = gimp_canvas_transform_guides_get_property;
+
+  item_class->draw           = gimp_canvas_transform_guides_draw;
+  item_class->get_extents    = gimp_canvas_transform_guides_get_extents;
+
+  g_object_class_install_property (object_class, PROP_TRANSFORM,
+                                   gimp_param_spec_matrix3 ("transform",
+                                                            NULL, NULL,
+                                                            NULL,
+                                                            GIMP_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_X1,
+                                   g_param_spec_double ("x1",
+                                                        NULL, NULL,
+                                                        -GIMP_MAX_IMAGE_SIZE,
+                                                        GIMP_MAX_IMAGE_SIZE,
+                                                        0.0,
+                                                        GIMP_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_Y1,
+                                   g_param_spec_double ("y1",
+                                                        NULL, NULL,
+                                                        -GIMP_MAX_IMAGE_SIZE,
+                                                        GIMP_MAX_IMAGE_SIZE,
+                                                        0.0,
+                                                        GIMP_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_X2,
+                                   g_param_spec_double ("x2",
+                                                        NULL, NULL,
+                                                        -GIMP_MAX_IMAGE_SIZE,
+                                                        GIMP_MAX_IMAGE_SIZE,
+                                                        0.0,
+                                                        GIMP_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_Y2,
+                                   g_param_spec_double ("y2",
+                                                        NULL, NULL,
+                                                        -GIMP_MAX_IMAGE_SIZE,
+                                                        GIMP_MAX_IMAGE_SIZE,
+                                                        0.0,
+                                                        GIMP_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_TYPE,
+                                   g_param_spec_enum ("type", NULL, NULL,
+                                                      GIMP_TYPE_GUIDES_TYPE,
+                                                      GIMP_GUIDES_NONE,
+                                                      GIMP_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_N_GUIDES,
+                                   g_param_spec_int ("n-guides", NULL, NULL,
+                                                     1, 128, 4,
+                                                     GIMP_PARAM_READWRITE));
+
+  g_type_class_add_private (klass, sizeof (GimpCanvasTransformGuidesPrivate));
+}
+
+static void
+gimp_canvas_transform_guides_init (GimpCanvasTransformGuides *transform)
+{
+}
+
+static void
+gimp_canvas_transform_guides_set_property (GObject      *object,
+                                           guint         property_id,
+                                           const GValue *value,
+                                           GParamSpec   *pspec)
+{
+  GimpCanvasTransformGuidesPrivate *private = GET_PRIVATE (object);
+
+  switch (property_id)
+    {
+    case PROP_TRANSFORM:
+      {
+        GimpMatrix3 *transform = g_value_get_boxed (value);
+
+        if (transform)
+          private->transform = *transform;
+        else
+          gimp_matrix3_identity (&private->transform);
+      }
+      break;
+
+    case PROP_X1:
+      private->x1 = g_value_get_double (value);
+      break;
+
+    case PROP_Y1:
+      private->y1 = g_value_get_double (value);
+      break;
+
+    case PROP_X2:
+      private->x2 = g_value_get_double (value);
+      break;
+
+    case PROP_Y2:
+      private->y2 = g_value_get_double (value);
+      break;
+
+    case PROP_TYPE:
+      private->type = g_value_get_enum (value);
+      break;
+
+    case PROP_N_GUIDES:
+      private->n_guides = g_value_get_int (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_canvas_transform_guides_get_property (GObject    *object,
+                                           guint       property_id,
+                                           GValue     *value,
+                                           GParamSpec *pspec)
+{
+  GimpCanvasTransformGuidesPrivate *private = GET_PRIVATE (object);
+
+  switch (property_id)
+    {
+    case PROP_TRANSFORM:
+      g_value_set_boxed (value, &private->transform);
+      break;
+
+    case PROP_X1:
+      g_value_set_double (value, private->x1);
+      break;
+
+    case PROP_Y1:
+      g_value_set_double (value, private->y1);
+      break;
+
+    case PROP_X2:
+      g_value_set_double (value, private->x2);
+      break;
+
+    case PROP_Y2:
+      g_value_set_double (value, private->y2);
+      break;
+
+    case PROP_TYPE:
+      g_value_set_enum (value, private->type);
+      break;
+
+    case PROP_N_GUIDES:
+      g_value_set_int (value, private->n_guides);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static gboolean
+gimp_canvas_transform_guides_transform (GimpCanvasItem   *item,
+                                        GimpDisplayShell *shell,
+                                        gdouble          *tx1,
+                                        gdouble          *ty1,
+                                        gdouble          *tx2,
+                                        gdouble          *ty2,
+                                        gdouble          *tx3,
+                                        gdouble          *ty3,
+                                        gdouble          *tx4,
+                                        gdouble          *ty4)
+{
+  GimpCanvasTransformGuidesPrivate *private = GET_PRIVATE (item);
+
+  gimp_matrix3_transform_point (&private->transform,
+                                private->x1, private->y1,
+                                tx1, ty1);
+  gimp_matrix3_transform_point (&private->transform,
+                                private->x2, private->y1,
+                                tx2, ty2);
+  gimp_matrix3_transform_point (&private->transform,
+                                private->x1, private->y2,
+                                tx3, ty3);
+  gimp_matrix3_transform_point (&private->transform,
+                                private->x2, private->y2,
+                                tx4, ty4);
+
+  return gimp_transform_polygon_is_convex (*tx1, *ty1,
+                                           *tx2, *ty2,
+                                           *tx3, *ty3,
+                                           *tx4, *ty4);
+}
+
+static void
+draw_line (cairo_t          *cr,
+           GimpDisplayShell *shell,
+           GimpMatrix3      *transform,
+           gdouble           x1,
+           gdouble           y1,
+           gdouble           x2,
+           gdouble           y2)
+{
+  gimp_matrix3_transform_point (transform, x1, y1, &x1, &y1);
+  gimp_matrix3_transform_point (transform, x2, y2, &x2, &y2);
+
+  gimp_display_shell_transform_xy_f (shell, x1, y1, &x1, &y1);
+  gimp_display_shell_transform_xy_f (shell, x2, y2, &x2, &y2);
+
+  x1 = floor (x1) + 0.5;
+  y1 = floor (y1) + 0.5;
+  x2 = floor (x2) + 0.5;
+  y2 = floor (y2) + 0.5;
+
+  cairo_move_to (cr, x1, y1);
+  cairo_line_to (cr, x2, y2);
+}
+
+static void
+gimp_canvas_transform_guides_draw (GimpCanvasItem   *item,
+                                   GimpDisplayShell *shell,
+                                   cairo_t          *cr)
+{
+  GimpCanvasTransformGuidesPrivate *private = GET_PRIVATE (item);
+  gdouble                           x1, y1;
+  gdouble                           x2, y2;
+  gdouble                           x3, y3;
+  gdouble                           x4, y4;
+  gboolean                          convex;
+
+  convex = gimp_canvas_transform_guides_transform (item, shell,
+                                                   &x1, &y1,
+                                                   &x2, &y2,
+                                                   &x3, &y3,
+                                                   &x4, &y4);
+
+  gimp_display_shell_transform_xy_f (shell, x1, y1, &x1, &y1);
+  gimp_display_shell_transform_xy_f (shell, x2, y2, &x2, &y2);
+  gimp_display_shell_transform_xy_f (shell, x3, y3, &x3, &y3);
+  gimp_display_shell_transform_xy_f (shell, x4, y4, &x4, &y4);
+
+  x1 = floor (x1) + 0.5;
+  y1 = floor (y1) + 0.5;
+  x2 = floor (x2) + 0.5;
+  y2 = floor (y2) + 0.5;
+  x3 = floor (x3) + 0.5;
+  y3 = floor (y3) + 0.5;
+  x4 = floor (x4) + 0.5;
+  y4 = floor (y4) + 0.5;
+
+  cairo_move_to (cr, x1, y1);
+  cairo_line_to (cr, x2, y2);
+  cairo_line_to (cr, x4, y4);
+  cairo_line_to (cr, x3, y3);
+  cairo_line_to (cr, x1, y1);
+
+  if (! convex)
+    {
+      _gimp_canvas_item_stroke (item, cr);
+      return;
+    }
+
+  switch (private->type)
+    {
+    case GIMP_GUIDES_NONE:
+      break;
+
+    case GIMP_GUIDES_CENTER_LINES:
+      /* TODO */
+      break;
+
+    case GIMP_GUIDES_THIRDS:
+      /* TODO */
+      break;
+
+    case GIMP_GUIDES_FIFTHS:
+      /* TODO */
+      break;
+
+    case GIMP_GUIDES_GOLDEN:
+      /* TODO */
+      break;
+
+    case GIMP_GUIDES_DIAGONALS:
+      /* TODO */
+      break;
+
+    case GIMP_GUIDES_N_LINES:
+    case GIMP_GUIDES_SPACING:
+      {
+        gint width, height;
+        gint ngx, ngy;
+        gint i;
+
+        width  = MAX (1, private->x2 - private->x1);
+        height = MAX (1, private->y2 - private->y1);
+
+        if (private->type == GIMP_GUIDES_N_LINES)
+          {
+            if (width <= height)
+              {
+                ngx = private->n_guides;
+                ngy = ngx * MAX (1, height / width);
+              }
+            else
+              {
+                ngy = private->n_guides;
+                ngx = ngy * MAX (1, width / height);
+              }
+          }
+        else /* GIMP_GUIDES_SPACING */
+          {
+            gint grid_size = MAX (2, private->n_guides);
+
+            ngx = width  / grid_size;
+            ngy = height / grid_size;
+          }
+
+        for (i = 1; i <= ngx; i++)
+          {
+            gdouble x = private->x1 + (((gdouble) i) / (ngx + 1) *
+                                       (private->x2 - private->x1));
+
+            draw_line (cr, shell, &private->transform,
+                       x, private->y1,
+                       x, private->y2);
+          }
+
+        for (i = 1; i <= ngy; i++)
+          {
+            gdouble y = private->y1 + (((gdouble) i) / (ngy + 1) *
+                                       (private->y2 - private->y1));
+
+            draw_line (cr, shell, &private->transform,
+                       private->x1, y,
+                       private->x2, y);
+          }
+      }
+    }
+
+  _gimp_canvas_item_stroke (item, cr);
+}
+
+static cairo_region_t *
+gimp_canvas_transform_guides_get_extents (GimpCanvasItem   *item,
+                                          GimpDisplayShell *shell)
+{
+  gdouble               x1, y1;
+  gdouble               x2, y2;
+  gdouble               x3, y3;
+  gdouble               x4, y4;
+  cairo_rectangle_int_t extents;
+
+  gimp_canvas_transform_guides_transform (item, shell,
+                                          &x1, &y1,
+                                          &x2, &y2,
+                                          &x3, &y3,
+                                          &x4, &y4);
+
+  gimp_display_shell_transform_xy_f (shell, x1, y1, &x1, &y1);
+  gimp_display_shell_transform_xy_f (shell, x2, y2, &x2, &y2);
+  gimp_display_shell_transform_xy_f (shell, x3, y3, &x3, &y3);
+  gimp_display_shell_transform_xy_f (shell, x4, y4, &x4, &y4);
+
+  extents.x      = (gint) floor (MIN4 (x1, x2, x3, x4) - 1.5);
+  extents.y      = (gint) floor (MIN4 (y1, y2, y3, y4) - 1.5);
+  extents.width  = (gint) ceil  (MAX4 (x1, x2, x3, x4) + 1.5);
+  extents.height = (gint) ceil  (MAX4 (y1, y2, y3, y4) + 1.5);
+
+  extents.width  -= extents.x;
+  extents.height -= extents.y;
+
+  return cairo_region_create_rectangle (&extents);
+}
+
+GimpCanvasItem *
+gimp_canvas_transform_guides_new (GimpDisplayShell  *shell,
+                                  const GimpMatrix3 *transform,
+                                  gdouble            x1,
+                                  gdouble            y1,
+                                  gdouble            x2,
+                                  gdouble            y2,
+                                  GimpGuidesType     type,
+                                  gint               n_guides)
+{
+  g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
+
+  return g_object_new (GIMP_TYPE_CANVAS_TRANSFORM_GUIDES,
+                       "shell",     shell,
+                       "transform", transform,
+                       "x1",        x1,
+                       "y1",        y1,
+                       "x2",        x2,
+                       "y2",        y2,
+                       "type",      type,
+                       "n-guides",  n_guides,
+                       NULL);
+}
+
+void
+gimp_canvas_transform_guides_set (GimpCanvasItem    *guides,
+                                  const GimpMatrix3 *transform,
+                                  GimpGuidesType     type,
+                                  gint               n_guides)
+{
+  g_return_if_fail (GIMP_IS_CANVAS_TRANSFORM_GUIDES (guides));
+
+  gimp_canvas_item_begin_change (guides);
+
+  g_object_set (guides,
+                "transform", transform,
+                "type",      type,
+                "n-guides",  n_guides,
+                NULL);
+
+  gimp_canvas_item_end_change (guides);
+}
diff --git a/app/display/gimpcanvastransformguides.h b/app/display/gimpcanvastransformguides.h
new file mode 100644
index 0000000..84fe386
--- /dev/null
+++ b/app/display/gimpcanvastransformguides.h
@@ -0,0 +1,67 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpcanvastransformguides.h
+ * Copyright (C) 2011 Michael Natterer <mitch gimp org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_CANVAS_TRANSFORM_GUIDES_H__
+#define __GIMP_CANVAS_TRANSFORM_GUIDES_H__
+
+
+#include "gimpcanvasitem.h"
+
+
+#define GIMP_TYPE_CANVAS_TRANSFORM_GUIDES            (gimp_canvas_transform_guides_get_type ())
+#define GIMP_CANVAS_TRANSFORM_GUIDES(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CANVAS_TRANSFORM_GUIDES, GimpCanvasTransformGuides))
+#define GIMP_CANVAS_TRANSFORM_GUIDES_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CANVAS_TRANSFORM_GUIDES, GimpCanvasTransformGuidesClass))
+#define GIMP_IS_CANVAS_TRANSFORM_GUIDES(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CANVAS_TRANSFORM_GUIDES))
+#define GIMP_IS_CANVAS_TRANSFORM_GUIDES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CANVAS_TRANSFORM_GUIDES))
+#define GIMP_CANVAS_TRANSFORM_GUIDES_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CANVAS_TRANSFORM_GUIDES, GimpCanvasTransformGuidesClass))
+
+
+typedef struct _GimpCanvasTransformGuides      GimpCanvasTransformGuides;
+typedef struct _GimpCanvasTransformGuidesClass GimpCanvasTransformGuidesClass;
+
+struct _GimpCanvasTransformGuides
+{
+  GimpCanvasItem  parent_instance;
+};
+
+struct _GimpCanvasTransformGuidesClass
+{
+  GimpCanvasItemClass  parent_class;
+};
+
+
+GType            gimp_canvas_transform_guides_get_type (void) G_GNUC_CONST;
+
+GimpCanvasItem * gimp_canvas_transform_guides_new      (GimpDisplayShell  *shell,
+                                                        const GimpMatrix3 *transform,
+                                                        gdouble            x1,
+                                                        gdouble            y1,
+                                                        gdouble            x2,
+                                                        gdouble            y2,
+                                                        GimpGuidesType     type,
+                                                        gint               n_guides);
+
+void             gimp_canvas_transform_guides_set      (GimpCanvasItem    *guides,
+                                                        const GimpMatrix3 *transform,
+                                                        GimpGuidesType     type,
+                                                        gint               n_guides);
+
+
+#endif /* __GIMP_CANVAS_TRANSFORM_GUIDES_H__ */
diff --git a/app/tools/gimpdrawtool.c b/app/tools/gimpdrawtool.c
index 9eb927b..e7b6568 100644
--- a/app/tools/gimpdrawtool.c
+++ b/app/tools/gimpdrawtool.c
@@ -49,6 +49,7 @@
 #include "display/gimpcanvasrectangleguides.h"
 #include "display/gimpcanvassamplepoint.h"
 #include "display/gimpcanvastextcursor.h"
+#include "display/gimpcanvastransformguides.h"
 #include "display/gimpcanvastransformpreview.h"
 #include "display/gimpdisplay.h"
 #include "display/gimpdisplayshell.h"
@@ -864,6 +865,31 @@ gimp_draw_tool_add_text_cursor (GimpDrawTool   *draw_tool,
 }
 
 GimpCanvasItem *
+gimp_draw_tool_add_transform_guides (GimpDrawTool      *draw_tool,
+                                     const GimpMatrix3 *transform,
+                                     GimpGuidesType     type,
+                                     gint               n_guides,
+                                     gdouble            x1,
+                                     gdouble            y1,
+                                     gdouble            x2,
+                                     gdouble            y2)
+{
+  GimpCanvasItem *item;
+
+  g_return_val_if_fail (GIMP_IS_DRAW_TOOL (draw_tool), NULL);
+  g_return_val_if_fail (transform != NULL, NULL);
+
+  item = gimp_canvas_transform_guides_new (gimp_display_get_shell (draw_tool->display),
+                                           transform, x1, y1, x2, y2,
+                                           type, n_guides);
+
+  gimp_draw_tool_add_item (draw_tool, item);
+  g_object_unref (item);
+
+  return item;
+}
+
+GimpCanvasItem *
 gimp_draw_tool_add_transform_preview (GimpDrawTool      *draw_tool,
                                       GimpDrawable      *drawable,
                                       const GimpMatrix3 *transform,
diff --git a/app/tools/gimpdrawtool.h b/app/tools/gimpdrawtool.h
index 3c13568..b968ffe 100644
--- a/app/tools/gimpdrawtool.h
+++ b/app/tools/gimpdrawtool.h
@@ -135,6 +135,14 @@ GimpCanvasItem * gimp_draw_tool_add_arc              (GimpDrawTool     *draw_too
                                                       gdouble           height,
                                                       gdouble           start_angle,
                                                       gdouble           slice_angle);
+GimpCanvasItem * gimp_draw_tool_add_transform_guides (GimpDrawTool     *draw_tool,
+                                                      const GimpMatrix3 *transform,
+                                                      GimpGuidesType    type,
+                                                      gint              n_guides,
+                                                      gdouble           x1,
+                                                      gdouble           y1,
+                                                      gdouble           x2,
+                                                      gdouble           y2);
 GimpCanvasItem * gimp_draw_tool_add_transform_preview(GimpDrawTool     *draw_tool,
                                                       GimpDrawable     *drawable,
                                                       const GimpMatrix3 *transform,
diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c
index 544454f..873b22d 100644
--- a/app/tools/gimptransformtool.c
+++ b/app/tools/gimptransformtool.c
@@ -140,7 +140,6 @@ static void      gimp_transform_tool_prepare                (GimpTransformTool
 static void      gimp_transform_tool_transform              (GimpTransformTool     *tr_tool,
                                                              GimpDisplay           *display);
 static void      gimp_transform_tool_transform_bounding_box (GimpTransformTool     *tr_tool);
-static void      gimp_transform_tool_grid_recalc            (GimpTransformTool     *tr_tool);
 
 static void      gimp_transform_tool_handles_recalc         (GimpTransformTool     *tr_tool,
                                                              GimpDisplay           *display,
@@ -222,12 +221,6 @@ gimp_transform_tool_finalize (GObject *object)
       tr_tool->dialog = NULL;
     }
 
-  if (tr_tool->grid_coords)
-    {
-      g_free (tr_tool->grid_coords);
-      tr_tool->grid_coords = NULL;
-    }
-
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -674,7 +667,6 @@ gimp_transform_tool_options_notify (GimpTool         *tool,
 
       if (tr_tool->function != TRANSFORM_CREATING)
         {
-          gimp_transform_tool_grid_recalc (tr_tool);
           gimp_transform_tool_transform_bounding_box (tr_tool);
         }
 
@@ -703,8 +695,6 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
 
   if (tr_tool->use_grid)
     {
-      GimpCanvasGroup *stroke_group;
-
       if (gimp_transform_options_show_preview (options))
         {
           gimp_draw_tool_add_transform_preview (draw_tool,
@@ -718,52 +708,14 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
                                                 options->preview_opacity);
         }
 
-      stroke_group = gimp_draw_tool_add_stroke_group (draw_tool);
-
-      gimp_draw_tool_push_group (draw_tool, stroke_group);
-
-      /*  draw the grid  */
-      if (tr_tool->grid_coords &&
-          gimp_transform_polygon_is_convex (tr_tool->tx1, tr_tool->ty1,
-                                            tr_tool->tx2, tr_tool->ty2,
-                                            tr_tool->tx3, tr_tool->ty3,
-                                            tr_tool->tx4, tr_tool->ty4))
-        {
-          gint k = tr_tool->ngx + tr_tool->ngy;
-          gint i, gci;
-
-          for (i = 0, gci = 0; i < k; i++, gci += 4)
-            {
-              gdouble x1, y1, x2, y2;
-
-              gimp_matrix3_transform_point (&tr_tool->transform,
-                                            tr_tool->grid_coords[gci],
-                                            tr_tool->grid_coords[gci + 1],
-                                            &x1, &y1);
-              gimp_matrix3_transform_point (&tr_tool->transform,
-                                            tr_tool->grid_coords[gci + 2],
-                                            tr_tool->grid_coords[gci + 3],
-                                            &x2, &y2);
-
-              gimp_draw_tool_add_line (draw_tool, x1, y1, x2, y2);
-            }
-        }
-
-      /*  draw the bounding box  */
-      gimp_draw_tool_add_line (draw_tool,
-                               tr_tool->tx1, tr_tool->ty1,
-                               tr_tool->tx2, tr_tool->ty2);
-      gimp_draw_tool_add_line (draw_tool,
-                               tr_tool->tx2, tr_tool->ty2,
-                               tr_tool->tx4, tr_tool->ty4);
-      gimp_draw_tool_add_line (draw_tool,
-                               tr_tool->tx3, tr_tool->ty3,
-                               tr_tool->tx4, tr_tool->ty4);
-      gimp_draw_tool_add_line (draw_tool,
-                               tr_tool->tx3, tr_tool->ty3,
-                               tr_tool->tx1, tr_tool->ty1);
-
-      gimp_draw_tool_pop_group (draw_tool);
+      gimp_draw_tool_add_transform_guides (draw_tool,
+                                           &tr_tool->transform,
+                                           options->grid_type,
+                                           options->grid_size,
+                                           tr_tool->x1,
+                                           tr_tool->y1,
+                                           tr_tool->x2,
+                                           tr_tool->y2);
     }
 
   gimp_transform_tool_handles_recalc (tr_tool, tool->display,
@@ -1327,91 +1279,6 @@ gimp_transform_tool_bounds (GimpTransformTool *tr_tool,
 
   tr_tool->aspect = ((gdouble) (tr_tool->x2 - tr_tool->x1) /
                      (gdouble) (tr_tool->y2 - tr_tool->y1));
-
-  /*  changing the bounds invalidates any grid we may have  */
-  if (tr_tool->use_grid)
-    gimp_transform_tool_grid_recalc (tr_tool);
-}
-
-static void
-gimp_transform_tool_grid_recalc (GimpTransformTool *tr_tool)
-{
-  GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
-
-  if (tr_tool->grid_coords != NULL)
-    {
-      g_free (tr_tool->grid_coords);
-      tr_tool->grid_coords = NULL;
-    }
-
-  if (options->preview_type != GIMP_TRANSFORM_PREVIEW_TYPE_GRID &&
-      options->preview_type != GIMP_TRANSFORM_PREVIEW_TYPE_IMAGE_GRID)
-    return;
-
-  switch (options->grid_type)
-    {
-    case GIMP_GUIDES_N_LINES:
-    case GIMP_GUIDES_SPACING:
-      {
-        gint     i, gci;
-        gdouble *coords;
-        gint     width, height;
-
-        width  = MAX (1, tr_tool->x2 - tr_tool->x1);
-        height = MAX (1, tr_tool->y2 - tr_tool->y1);
-
-        if (options->grid_type == GIMP_GUIDES_N_LINES)
-          {
-            if (width <= height)
-              {
-                tr_tool->ngx = options->grid_size;
-                tr_tool->ngy = tr_tool->ngx * MAX (1, height / width);
-              }
-            else
-              {
-                tr_tool->ngy = options->grid_size;
-                tr_tool->ngx = tr_tool->ngy * MAX (1, width / height);
-              }
-          }
-        else /* GIMP_GUIDES_SPACING */
-          {
-            gint grid_size = MAX (2, options->grid_size);
-
-            tr_tool->ngx = width  / grid_size;
-            tr_tool->ngy = height / grid_size;
-          }
-
-        tr_tool->grid_coords = coords =
-          g_new (gdouble, (tr_tool->ngx + tr_tool->ngy) * 4);
-
-        gci = 0;
-
-        for (i = 1; i <= tr_tool->ngx; i++)
-          {
-            coords[gci]     = tr_tool->x1 + (((gdouble) i) / (tr_tool->ngx + 1) *
-                                             (tr_tool->x2 - tr_tool->x1));
-            coords[gci + 1] = tr_tool->y1;
-            coords[gci + 2] = coords[gci];
-            coords[gci + 3] = tr_tool->y2;
-
-            gci += 4;
-          }
-
-        for (i = 1; i <= tr_tool->ngy; i++)
-          {
-            coords[gci]     = tr_tool->x1;
-            coords[gci + 1] = tr_tool->y1 + (((gdouble) i) / (tr_tool->ngy + 1) *
-                                             (tr_tool->y2 - tr_tool->y1));
-            coords[gci + 2] = tr_tool->x2;
-            coords[gci + 3] = coords[gci + 1];
-
-            gci += 4;
-          }
-      }
-
-    default:
-      break;
-    }
 }
 
 static void
diff --git a/app/tools/gimptransformtool.h b/app/tools/gimptransformtool.h
index b445bea..04e64e2 100644
--- a/app/tools/gimptransformtool.h
+++ b/app/tools/gimptransformtool.h
@@ -87,14 +87,6 @@ struct _GimpTransformTool
   gboolean        use_center;      /*  uses the center handle            */
   gboolean        use_mid_handles; /*  use handles at midpoints of edges */
 
-  gint            ngx, ngy;        /*  number of grid lines in original
-                                    *  x and y directions
-                                    */
-  gdouble        *grid_coords;     /*  x and y coordinates of the grid
-                                    *  endpoints (a total of (ngx+ngy)*2
-                                    *  coordinate pairs)
-                                    */
-
   GimpCanvasItem *handles[TRANSFORM_HANDLE_CENTER + 1];
 
   const gchar    *undo_desc;



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