From 85340f4b305d92d94ec2898cde074f0492fe4514 Mon Sep 17 00:00:00 2001 From: Ell Date: Sun, 26 May 2019 14:14:26 -0400 Subject: [PATCH] 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);