[gimp/gimp-2-10] app: add gimp_symmetry_get_transform()



commit 85340f4b305d92d94ec2898cde074f0492fe4514
Author: Ell <ell_se yahoo com>
Date:   Sun May 26 14:14:26 2019 -0400

    app: add gimp_symmetry_get_transform()
    
    Add a GimpSymmetry::get_transform() virtual function, and a
    corresponding gimp_symmetry_get_transform() function, which return
    the brush transform corresponding to a given symmetry stroke in
    terms of the rotation angle and reflection flag (in contrast to
    gimp_symmetry_get_operation() which returns the same transforation
    in terms of a GeglNode).  This would allow us to simplify, fix, and
    improve the painting-code perofmrnace in the next commits.
    
    Implement GimpSymmetry::get_transform() in its various subclasses.
    
    (cherry picked from commit e0f2a6f1be4514609bde5304be99b91182e31183)

 app/core/gimpsymmetry-mandala.c | 19 ++++++++++++++++
 app/core/gimpsymmetry-mirror.c  | 49 +++++++++++++++++++++++++++++++++++++++++
 app/core/gimpsymmetry-tiling.c  | 15 -------------
 app/core/gimpsymmetry.c         | 46 ++++++++++++++++++++++++++++++++++++++
 app/core/gimpsymmetry.h         |  8 +++++++
 5 files changed, 122 insertions(+), 15 deletions(-)
---
diff --git a/app/core/gimpsymmetry-mandala.c b/app/core/gimpsymmetry-mandala.c
index f8578ab6f2..acb9700080 100644
--- a/app/core/gimpsymmetry-mandala.c
+++ b/app/core/gimpsymmetry-mandala.c
@@ -85,6 +85,10 @@ static GeglNode * gimp_mandala_get_operation      (GimpSymmetry *mandala,
                                                    gint          stroke,
                                                    gint          paint_width,
                                                    gint          paint_height);
+static void       gimp_mandala_get_transform      (GimpSymmetry *mandala,
+                                                   gint          stroke,
+                                                   gdouble      *angle,
+                                                   gboolean     *reflect);
 static void    gimp_mandala_image_size_changed_cb (GimpImage    *image,
                                                    gint          previous_origin_x,
                                                    gint          previous_origin_y,
@@ -113,6 +117,7 @@ gimp_mandala_class_init (GimpMandalaClass *klass)
   symmetry_class->label             = _("Mandala");
   symmetry_class->update_strokes    = gimp_mandala_update_strokes;
   symmetry_class->get_operation     = gimp_mandala_get_operation;
+  symmetry_class->get_transform     = gimp_mandala_get_transform;
   symmetry_class->active_changed    = gimp_mandala_active_changed;
 
   GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_CENTER_X,
@@ -552,6 +557,20 @@ gimp_mandala_get_operation (GimpSymmetry *sym,
   return op;
 }
 
+static void
+gimp_mandala_get_transform (GimpSymmetry *sym,
+                            gint          stroke,
+                            gdouble      *angle,
+                            gboolean     *reflect)
+{
+  GimpMandala *mandala = GIMP_MANDALA (sym);
+
+  if (mandala->disable_transformation)
+    return;
+
+  *angle = 360.0 * stroke / mandala->size;
+}
+
 static void
 gimp_mandala_image_size_changed_cb (GimpImage    *image,
                                     gint          previous_origin_x,
diff --git a/app/core/gimpsymmetry-mirror.c b/app/core/gimpsymmetry-mirror.c
index 66b960a338..7045835b2c 100644
--- a/app/core/gimpsymmetry-mirror.c
+++ b/app/core/gimpsymmetry-mirror.c
@@ -78,6 +78,10 @@ static GeglNode * gimp_mirror_get_operation           (GimpSymmetry        *mirr
                                                        gint                 stroke,
                                                        gint                 paint_width,
                                                        gint                 paint_height);
+static void       gimp_mirror_get_transform           (GimpSymmetry        *mirror,
+                                                       gint                 stroke,
+                                                       gdouble             *angle,
+                                                       gboolean            *reflect);
 static void       gimp_mirror_reset                   (GimpMirror          *mirror);
 static void       gimp_mirror_add_guide               (GimpMirror          *mirror,
                                                        GimpOrientationType  orientation);
@@ -123,6 +127,7 @@ gimp_mirror_class_init (GimpMirrorClass *klass)
   symmetry_class->label             = _("Mirror");
   symmetry_class->update_strokes    = gimp_mirror_update_strokes;
   symmetry_class->get_operation     = gimp_mirror_get_operation;
+  symmetry_class->get_transform     = gimp_mirror_get_transform;
   symmetry_class->active_changed    = gimp_mirror_active_changed;
 
   GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_HORIZONTAL_SYMMETRY,
@@ -439,6 +444,50 @@ gimp_mirror_get_operation (GimpSymmetry *sym,
   return op;
 }
 
+static void
+gimp_mirror_get_transform (GimpSymmetry *sym,
+                           gint          stroke,
+                           gdouble      *angle,
+                           gboolean     *reflect)
+{
+  GimpMirror *mirror = GIMP_MIRROR (sym);
+
+  if (mirror->disable_transformation)
+    return;
+
+  if (! mirror->horizontal_mirror && stroke >= 1)
+    stroke++;
+
+  if (! mirror->vertical_mirror && stroke >= 2)
+    stroke++;
+
+  switch (stroke)
+    {
+    /* original */
+    case 0:
+      break;
+
+    /* horizontal */
+    case 1:
+      *angle   = 180.0;
+      *reflect = TRUE;
+      break;
+
+    /* vertical */
+    case 2:
+      *reflect = TRUE;
+      break;
+
+    /* central */
+    case 3:
+      *angle   = 180.0;
+      break;
+
+    default:
+      g_return_if_reached ();
+    }
+}
+
 static void
 gimp_mirror_reset (GimpMirror *mirror)
 {
diff --git a/app/core/gimpsymmetry-tiling.c b/app/core/gimpsymmetry-tiling.c
index 25480346e5..555f58480c 100644
--- a/app/core/gimpsymmetry-tiling.c
+++ b/app/core/gimpsymmetry-tiling.c
@@ -70,10 +70,6 @@ static void       gimp_tiling_get_property       (GObject      *object,
 static void       gimp_tiling_update_strokes     (GimpSymmetry *tiling,
                                                   GimpDrawable *drawable,
                                                   GimpCoords   *origin);
-static GeglNode * gimp_tiling_get_operation      (GimpSymmetry *tiling,
-                                                  gint          stroke,
-                                                  gint          paint_width,
-                                                  gint          paint_height);
 static void    gimp_tiling_image_size_changed_cb (GimpImage    *image,
                                                   gint          previous_origin_x,
                                                   gint          previous_origin_y,
@@ -101,7 +97,6 @@ gimp_tiling_class_init (GimpTilingClass *klass)
 
   symmetry_class->label           = _("Tiling");
   symmetry_class->update_strokes  = gimp_tiling_update_strokes;
-  symmetry_class->get_operation   = gimp_tiling_get_operation;
 
   GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_INTERVAL_X,
                            "interval-x",
@@ -431,16 +426,6 @@ gimp_tiling_update_strokes (GimpSymmetry *sym,
   g_signal_emit_by_name (sym, "strokes-updated", sym->image);
 }
 
-static GeglNode *
-gimp_tiling_get_operation (GimpSymmetry *sym,
-                           gint          stroke,
-                           gint          paint_width,
-                           gint          paint_height)
-{
-  /* No buffer transformation happens for tiling. */
-  return NULL;
-}
-
 static void
 gimp_tiling_image_size_changed_cb (GimpImage    *image,
                                    gint          previous_origin_x,
diff --git a/app/core/gimpsymmetry.c b/app/core/gimpsymmetry.c
index 04a2510a49..fc0f892970 100644
--- a/app/core/gimpsymmetry.c
+++ b/app/core/gimpsymmetry.c
@@ -75,6 +75,10 @@ static GeglNode * gimp_symmetry_real_get_op         (GimpSymmetry *sym,
                                                      gint          stroke,
                                                      gint          paint_width,
                                                      gint          paint_height);
+static void       gimp_symmetry_real_get_transform  (GimpSymmetry *sym,
+                                                     gint          stroke,
+                                                     gdouble      *angle,
+                                                     gboolean     *reflect);
 static gboolean   gimp_symmetry_real_update_version (GimpSymmetry *sym);
 
 
@@ -134,6 +138,7 @@ gimp_symmetry_class_init (GimpSymmetryClass *klass)
   klass->label               = _("None");
   klass->update_strokes      = gimp_symmetry_real_update_strokes;
   klass->get_operation       = gimp_symmetry_real_get_op;
+  klass->get_transform       = gimp_symmetry_real_get_transform;
   klass->active_changed      = NULL;
   klass->update_version      = gimp_symmetry_real_update_version;
 
@@ -246,6 +251,16 @@ gimp_symmetry_real_get_op (GimpSymmetry *sym,
   return NULL;
 }
 
+static void
+gimp_symmetry_real_get_transform (GimpSymmetry *sym,
+                                  gint          stroke,
+                                  gdouble      *angle,
+                                  gboolean     *reflect)
+{
+  /* The basic symmetry does nothing, since no transformation of the
+   * brush painting happen. */
+}
+
 static gboolean
 gimp_symmetry_real_update_version (GimpSymmetry *symmetry)
 {
@@ -419,6 +434,37 @@ gimp_symmetry_get_operation (GimpSymmetry *sym,
                                                        paint_height);
 }
 
+/**
+ * gimp_symmetry_get_transform:
+ * @sym:     the #GimpSymmetry
+ * @stroke:  the stroke number
+ * @angle:   output pointer to the transformation rotation angle,
+ *           in degrees (ccw)
+ * @reflect: output pointer to the transformation reflection flag
+ *
+ * Returns the transformation to apply to the paint buffer for stroke
+ * number @stroke.  The transformation is comprised of rotation around the
+ * center, possibly followed by horizontal reflection around the center.
+ **/
+void
+gimp_symmetry_get_transform (GimpSymmetry *sym,
+                             gint          stroke,
+                             gdouble      *angle,
+                             gboolean     *reflect)
+{
+  g_return_if_fail (GIMP_IS_SYMMETRY (sym));
+  g_return_if_fail (angle != NULL);
+  g_return_if_fail (reflect != NULL);
+
+  *angle   = 0.0;
+  *reflect = FALSE;
+
+  GIMP_SYMMETRY_GET_CLASS (sym)->get_transform (sym,
+                                                stroke,
+                                                angle,
+                                                reflect);
+}
+
 /*
  * gimp_symmetry_parasite_name:
  * @type: the #GimpSymmetry's #GType
diff --git a/app/core/gimpsymmetry.h b/app/core/gimpsymmetry.h
index 20dbe02481..3d3152245f 100644
--- a/app/core/gimpsymmetry.h
+++ b/app/core/gimpsymmetry.h
@@ -67,6 +67,10 @@ struct _GimpSymmetryClass
                                              gint                stroke,
                                              gint                paint_width,
                                              gint                paint_height);
+  void       (* get_transform)              (GimpSymmetry       *symmetry,
+                                             gint                stroke,
+                                             gdouble            *angle,
+                                             gboolean           *reflect);
   void       (* active_changed)             (GimpSymmetry       *symmetry);
 
   gboolean   (* update_version)             (GimpSymmetry       *symmetry);
@@ -90,6 +94,10 @@ GeglNode     * gimp_symmetry_get_operation  (GimpSymmetry       *symmetry,
                                              gint                stroke,
                                              gint                paint_width,
                                              gint                paint_height);
+void           gimp_symmetry_get_transform  (GimpSymmetry       *symmetry,
+                                             gint                stroke,
+                                             gdouble            *angle,
+                                             gboolean           *reflect);
 
 gchar        * gimp_symmetry_parasite_name  (GType               type);
 GimpParasite * gimp_symmetry_to_parasite    (const GimpSymmetry *symmetry);


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