[gimp] Bug 771678 - Parametric Brush Aspect Ratio and Angle values...



commit 184f0929ceb144751508710006d4062b2afb9985
Author: Michael Natterer <mitch gimp org>
Date:   Tue Oct 11 00:57:25 2016 +0200

    Bug 771678 - Parametric Brush Aspect Ratio and Angle values...
    
    ...are not submitted to respective Tool Options sliders
    
    Treat brush angle and aspect ratio like all other paint options values
    that can be linked to brush defaults and take their default values
    from the brush. They were special casing their defaults to constants,
    and GimpBrushGenerated was adding the passed dynamic radius and aspect
    values to its own. This was totally incomprehensible.
    
    Now GimpBrushGenerated's transform_size() and transform_mask()
    implementations just translate between these APIs value ranges and the
    brush's own value range and only use the passed values (not the
    brush's native values), which makes the editor <-> tool options
    interaction and the painted brush shape predictable.
    
    Also connect the active brush's property notifications to the paint
    options properties, so the paint options follow a brush edit live if
    the respective "linked" toggles are checked.
    
    And some cleanup.

 app/core/gimpbrush.c             |    3 +-
 app/core/gimpbrushgenerated.c    |   65 +++++++++----------
 app/paint/gimppaintoptions.c     |  131 +++++++++++++++++++++++++++-----------
 app/paint/gimppaintoptions.h     |    9 ++-
 app/tools/gimppaintoptions-gui.c |   94 +++++++++++++++++++--------
 5 files changed, 201 insertions(+), 101 deletions(-)
---
diff --git a/app/core/gimpbrush.c b/app/core/gimpbrush.c
index 37dbe05..6c2e549 100644
--- a/app/core/gimpbrush.c
+++ b/app/core/gimpbrush.c
@@ -314,7 +314,8 @@ gimp_brush_get_new_preview (GimpViewable *viewable,
                GimpBrushGenerated *gen_brush = GIMP_BRUSH_GENERATED (brush);
 
                mask_buf = gimp_brush_transform_mask (brush, NULL, scale,
-                                                     0.0, 0.0,
+                                                     (gimp_brush_generated_get_aspect_ratio (gen_brush) - 
1.0) * 20.0 / 19.0,
+                                                     gimp_brush_generated_get_angle (gen_brush) / 360.0,
                                                      gimp_brush_generated_get_hardness (gen_brush));
             }
           else
diff --git a/app/core/gimpbrushgenerated.c b/app/core/gimpbrushgenerated.c
index fdb1d11..fa634a8 100644
--- a/app/core/gimpbrushgenerated.c
+++ b/app/core/gimpbrushgenerated.c
@@ -301,22 +301,22 @@ gimp_brush_generated_transform_size (GimpBrush *gbrush,
   GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (gbrush);
   gdouble             ratio;
 
-  if (aspect_ratio == 0.0)
-    {
-      ratio = brush->aspect_ratio;
-    }
-  else
-    {
-      ratio = MIN (fabs (aspect_ratio) + 1, 20);
-      /* Since generated brushes are symmetric the dont have input
-       * for aspect ratios  < 1.0. its same as rotate by 90 degrees and
-       * 1 / ratio. So we fix the input up for this case.   */
+  ratio = fabs (aspect_ratio) * 19.0 / 20.0 + 1.0;
+  ratio = MIN (ratio, 20);
 
-      if (aspect_ratio < 0.0)
-        {
-          angle = angle + 0.25;
-        }
-    }
+  /* Since generated brushes are symmetric they don't have aspect
+   * ratios < 1.0. it's the same as rotating by 90 degrees and 1 /
+   * ratio, so we fix the input for this case.
+   */
+  if (aspect_ratio < 0.0)
+    angle = angle + 0.25;
+
+  angle *= 360;
+
+  if (angle < 0.0)
+    angle = -1.0 * fmod (angle, 180.0);
+  else if (angle > 180.0)
+    angle = fmod (angle, 180.0);
 
   gimp_brush_generated_get_size (brush,
                                  brush->shape,
@@ -324,7 +324,7 @@ gimp_brush_generated_transform_size (GimpBrush *gbrush,
                                  brush->spikes,
                                  brush->hardness,
                                  ratio,
-                                 (brush->angle + 360 * angle),
+                                 angle,
                                  width, height,
                                  NULL, NULL, NULL, NULL);
 }
@@ -339,23 +339,22 @@ gimp_brush_generated_transform_mask (GimpBrush *gbrush,
   GimpBrushGenerated *brush  = GIMP_BRUSH_GENERATED (gbrush);
   gdouble             ratio;
 
-  if (aspect_ratio == 0.0)
-    {
-      ratio = brush->aspect_ratio;
-    }
-  else
-    {
-      ratio = MIN (fabs (aspect_ratio) + 1, 20);
-      /* Since generated brushes are symmetric the dont have input
-       * for aspect ratios  < 1.0. its same as rotate by 90 degrees and
-       * 1 / ratio. So we fix the input up for this case.   */
+  ratio = fabs (aspect_ratio) * 19.0 / 20.0 + 1.0;
+  ratio = MIN (ratio, 20);
 
-      if (aspect_ratio < 0.0)
-        {
-          angle = angle + 0.25;
-        }
-   }
+  /* Since generated brushes are symmetric they don't have aspect
+   * ratios < 1.0. it's the same as rotating by 90 degrees and 1 /
+   * ratio, so we fix the input for this case.
+   */
+  if (aspect_ratio < 0.0)
+    angle = angle + 0.25;
+
+  angle *= 360;
 
+  if (angle < 0.0)
+    angle = -1.0 * fmod (angle, 180.0);
+  else if (angle > 180.0)
+    angle = fmod (angle, 180.0);
 
   return gimp_brush_generated_calc (brush,
                                     brush->shape,
@@ -363,7 +362,7 @@ gimp_brush_generated_transform_mask (GimpBrush *gbrush,
                                     brush->spikes,
                                     hardness,
                                     ratio,
-                                    (brush->angle + 360 * angle),
+                                    angle,
                                     NULL, NULL);
 }
 
diff --git a/app/paint/gimppaintoptions.c b/app/paint/gimppaintoptions.c
index 33cc471..8756388 100644
--- a/app/paint/gimppaintoptions.c
+++ b/app/paint/gimppaintoptions.c
@@ -981,6 +981,63 @@ gimp_paint_options_set_default_brush_size (GimpPaintOptions *paint_options,
 }
 
 void
+gimp_paint_options_set_default_brush_angle (GimpPaintOptions *paint_options,
+                                            GimpBrush        *brush)
+{
+  g_return_if_fail (GIMP_IS_PAINT_OPTIONS (paint_options));
+  g_return_if_fail (brush == NULL || GIMP_IS_BRUSH (brush));
+
+  if (! brush)
+    brush = gimp_context_get_brush (GIMP_CONTEXT (paint_options));
+
+  if (GIMP_IS_BRUSH_GENERATED (brush))
+    {
+      GimpBrushGenerated *generated_brush = GIMP_BRUSH_GENERATED (brush);
+
+      g_object_set (paint_options,
+                    "brush-angle", (gdouble) gimp_brush_generated_get_angle (generated_brush),
+                    NULL);
+    }
+  else
+    {
+      g_object_set (paint_options,
+                    "brush-angle", DEFAULT_BRUSH_ANGLE,
+                    NULL);
+    }
+}
+
+void
+gimp_paint_options_set_default_brush_aspect_ratio (GimpPaintOptions *paint_options,
+                                                   GimpBrush        *brush)
+{
+  g_return_if_fail (GIMP_IS_PAINT_OPTIONS (paint_options));
+  g_return_if_fail (brush == NULL || GIMP_IS_BRUSH (brush));
+
+  if (! brush)
+    brush = gimp_context_get_brush (GIMP_CONTEXT (paint_options));
+
+  if (GIMP_IS_BRUSH_GENERATED (brush))
+    {
+      GimpBrushGenerated *generated_brush = GIMP_BRUSH_GENERATED (brush);
+      gdouble             ratio;
+
+      ratio = gimp_brush_generated_get_aspect_ratio (generated_brush);
+
+      ratio = (ratio - 1.0) * 20.0 / 19.0;
+
+      g_object_set (paint_options,
+                    "brush-aspect-ratio", ratio,
+                    NULL);
+    }
+  else
+    {
+      g_object_set (paint_options,
+                    "brush-aspect-ratio", DEFAULT_BRUSH_ASPECT_RATIO,
+                    NULL);
+    }
+}
+
+void
 gimp_paint_options_set_default_brush_spacing (GimpPaintOptions *paint_options,
                                               GimpBrush        *brush)
 {
@@ -1037,8 +1094,8 @@ gimp_paint_options_copy_brush_props (GimpPaintOptions *src,
   gdouble  brush_force;
 
   gboolean brush_link_size;
-  gboolean brush_link_aspect_ratio;
   gboolean brush_link_angle;
+  gboolean brush_link_aspect_ratio;
   gboolean brush_link_spacing;
   gboolean brush_link_hardness;
 
@@ -1046,33 +1103,33 @@ gimp_paint_options_copy_brush_props (GimpPaintOptions *src,
   g_return_if_fail (GIMP_IS_PAINT_OPTIONS (dest));
 
   g_object_get (src,
-                "brush-size", &brush_size,
-                "brush-zoom", &brush_zoom,
-                "brush-angle", &brush_angle,
-                "brush-aspect-ratio", &brush_aspect_ratio,
-                "brush-spacing", &brush_spacing,
-                "brush-hardness", &brush_hardness,
-                "brush-force", &brush_force,
-                "brush-link-size", &brush_link_size,
-                "brush-link-angle", &brush_link_angle,
+                "brush-size",              &brush_size,
+                "brush-zoom",              &brush_zoom,
+                "brush-angle",             &brush_angle,
+                "brush-aspect-ratio",      &brush_aspect_ratio,
+                "brush-spacing",           &brush_spacing,
+                "brush-hardness",          &brush_hardness,
+                "brush-force",             &brush_force,
+                "brush-link-size",         &brush_link_size,
+                "brush-link-angle",        &brush_link_angle,
                 "brush-link-aspect-ratio", &brush_link_aspect_ratio,
-                "brush-link-spacing", &brush_link_spacing,
-                "brush-link-hardness", &brush_link_hardness,
+                "brush-link-spacing",      &brush_link_spacing,
+                "brush-link-hardness",     &brush_link_hardness,
                 NULL);
 
   g_object_set (dest,
-                "brush-size", brush_size,
-                "brush-zoom", brush_zoom,
-                "brush-angle", brush_angle,
-                "brush-aspect-ratio", brush_aspect_ratio,
-                "brush-spacing", brush_spacing,
-                "brush-hardness", brush_hardness,
-                "brush-force", brush_force,
-                "brush-link-size", brush_link_size,
-                "brush-link-angle", brush_link_angle,
+                "brush-size",              brush_size,
+                "brush-zoom",              brush_zoom,
+                "brush-angle",             brush_angle,
+                "brush-aspect-ratio",      brush_aspect_ratio,
+                "brush-spacing",           brush_spacing,
+                "brush-hardness",          brush_hardness,
+                "brush-force",             brush_force,
+                "brush-link-size",         brush_link_size,
+                "brush-link-angle",        brush_link_angle,
                 "brush-link-aspect-ratio", brush_link_aspect_ratio,
-                "brush-link-spacing", brush_link_spacing,
-                "brush-link-hardness", brush_link_hardness,
+                "brush-link-spacing",      brush_link_spacing,
+                "brush-link-hardness",     brush_link_hardness,
                 NULL);
 }
 
@@ -1080,29 +1137,29 @@ void
 gimp_paint_options_copy_dynamics_props (GimpPaintOptions *src,
                                         GimpPaintOptions *dest)
 {
-  gboolean        dynamics_expanded;
-  gboolean        fade_reverse;
-  gdouble         fade_length;
-  GimpUnit        fade_unit;
-  GimpRepeatMode  fade_repeat;
+  gboolean       dynamics_expanded;
+  gboolean       fade_reverse;
+  gdouble        fade_length;
+  GimpUnit       fade_unit;
+  GimpRepeatMode fade_repeat;
 
   g_return_if_fail (GIMP_IS_PAINT_OPTIONS (src));
   g_return_if_fail (GIMP_IS_PAINT_OPTIONS (dest));
 
   g_object_get (src,
                 "dynamics-expanded", &dynamics_expanded,
-                "fade-reverse", &fade_reverse,
-                "fade-length", &fade_length,
-                "fade-unit", &fade_unit,
-                "fade-repeat", &fade_repeat,
+                "fade-reverse",      &fade_reverse,
+                "fade-length",       &fade_length,
+                "fade-unit",         &fade_unit,
+                "fade-repeat",       &fade_repeat,
                 NULL);
 
   g_object_set (dest,
                 "dynamics-expanded", dynamics_expanded,
-                "fade-reverse", fade_reverse,
-                "fade-length", fade_length,
-                "fade-unit", fade_unit,
-                "fade-repeat", fade_repeat,
+                "fade-reverse",      fade_reverse,
+                "fade-length",       fade_length,
+                "fade-unit",         fade_unit,
+                "fade-repeat",       fade_repeat,
                 NULL);
 }
 
@@ -1110,7 +1167,7 @@ void
 gimp_paint_options_copy_gradient_props (GimpPaintOptions *src,
                                         GimpPaintOptions *dest)
 {
-  gboolean  gradient_reverse;
+  gboolean gradient_reverse;
 
   g_return_if_fail (GIMP_IS_PAINT_OPTIONS (src));
   g_return_if_fail (GIMP_IS_PAINT_OPTIONS (dest));
diff --git a/app/paint/gimppaintoptions.h b/app/paint/gimppaintoptions.h
index c4ec593..bdf00f6 100644
--- a/app/paint/gimppaintoptions.h
+++ b/app/paint/gimppaintoptions.h
@@ -82,6 +82,8 @@ struct _GimpPaintOptions
 
   gboolean                  use_applicator;
 
+  GimpBrush                *brush; /* weak-refed storage for the GUI */
+
   gdouble                   brush_size;
   gboolean                  brush_zoom;
   gdouble                   brush_angle;
@@ -147,7 +149,12 @@ GimpBrushApplicationMode
 void    gimp_paint_options_set_default_brush_size
                                                (GimpPaintOptions *paint_options,
                                                 GimpBrush        *brush);
-
+void    gimp_paint_options_set_default_brush_angle
+                                               (GimpPaintOptions *paint_options,
+                                                GimpBrush        *brush);
+void    gimp_paint_options_set_default_brush_aspect_ratio
+                                               (GimpPaintOptions *paint_options,
+                                                GimpBrush        *brush);
 void    gimp_paint_options_set_default_brush_spacing
                                                (GimpPaintOptions *paint_options,
                                                 GimpBrush        *brush);
diff --git a/app/tools/gimppaintoptions-gui.c b/app/tools/gimppaintoptions-gui.c
index 88cc975..4716002 100644
--- a/app/tools/gimppaintoptions-gui.c
+++ b/app/tools/gimppaintoptions-gui.c
@@ -53,7 +53,11 @@
 
 static void gimp_paint_options_gui_brush_changed
                                                (GimpContext      *context,
-                                                GimpBrush        *brush);
+                                                GimpBrush        *brush,
+                                                GtkWidget        *gui);
+static void gimp_paint_options_gui_brush_notify(GimpBrush        *brush,
+                                                const GParamSpec *pspec,
+                                                GimpPaintOptions *options);
 
 static void gimp_paint_options_gui_reset_size  (GtkWidget        *button,
                                                 GimpPaintOptions *paint_options);
@@ -171,7 +175,7 @@ gimp_paint_options_gui (GimpToolOptions *tool_options)
 
       hbox = gimp_paint_options_gui_scale_with_buttons
         (config, "brush-aspect-ratio", "brush-link-aspect-ratio",
-         _("Reset aspect ratio to brush's native"),
+         _("Reset aspect ratio to brush's native aspect ratio"),
          0.1, 1.0, 2, -20.0, 20.0, 1.0, 1.0,
          G_CALLBACK (gimp_paint_options_gui_reset_aspect_ratio), link_group);
       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
@@ -179,7 +183,7 @@ gimp_paint_options_gui (GimpToolOptions *tool_options)
 
       hbox = gimp_paint_options_gui_scale_with_buttons
         (config, "brush-angle", "brush-link-angle",
-         _("Reset angle to zero"),
+         _("Reset angle to brush's native angle"),
          0.1, 1.0, 2, -180.0, 180.0, 1.0, 1.0,
          G_CALLBACK (gimp_paint_options_gui_reset_angle), link_group);
       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
@@ -195,7 +199,7 @@ gimp_paint_options_gui (GimpToolOptions *tool_options)
 
       hbox = gimp_paint_options_gui_scale_with_buttons
         (config, "brush-hardness", "brush-link-hardness",
-         _("Reset hardness to default"),
+         _("Reset hardness to brush's native hardness"),
          0.1, 1.0, 1, 0.0, 100.0, 100.0, 1.0,
          G_CALLBACK (gimp_paint_options_gui_reset_hardness), link_group);
       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
@@ -228,9 +232,9 @@ gimp_paint_options_gui (GimpToolOptions *tool_options)
       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
       gtk_widget_show (frame);
 
-      g_signal_connect (options, "brush-changed",
-                        G_CALLBACK (gimp_paint_options_gui_brush_changed),
-                        NULL);
+      g_signal_connect_object (options, "brush-changed",
+                               G_CALLBACK (gimp_paint_options_gui_brush_changed),
+                               G_OBJECT (vbox), 0);
     }
 
   /*  the "smooth stroke" options  */
@@ -420,34 +424,64 @@ smoothing_options_gui (GimpPaintOptions *paint_options,
 
 static void
 gimp_paint_options_gui_brush_changed (GimpContext *context,
-                                      GimpBrush   *brush)
+                                      GimpBrush   *brush,
+                                      GtkWidget   *gui)
 {
   GimpPaintOptions *options = GIMP_PAINT_OPTIONS (context);
 
-  if (brush)
+  if (options->brush)
     {
-      if (options->brush_link_size)
-        gimp_paint_options_set_default_brush_size (options, brush);
+      g_signal_handlers_disconnect_by_func (options->brush,
+                                            gimp_paint_options_gui_brush_notify,
+                                            options);
+      g_object_remove_weak_pointer (G_OBJECT (options->brush),
+                                    (gpointer) &options->brush);
+    }
+
+  options->brush = brush;
 
-      if (options->brush_link_aspect_ratio)
-        g_object_set (options,
-                      "brush-aspect-ratio", 0.0,
-                      NULL);
+  if (options->brush)
+    {
+      GClosure *closure;
 
-      if (options->brush_link_angle)
-        g_object_set (options,
-                      "brush-angle", 0.0,
-                      NULL);
+      g_object_add_weak_pointer (G_OBJECT (options->brush),
+                                 (gpointer) &options->brush);
 
-      if (options->brush_link_spacing)
-        gimp_paint_options_set_default_brush_spacing (options, brush);
+      closure = g_cclosure_new (G_CALLBACK (gimp_paint_options_gui_brush_notify),
+                                options, NULL);
+      g_object_watch_closure (G_OBJECT (gui), closure);
+      g_signal_connect_closure (options->brush, "notify", closure, FALSE);
 
-      if (options->brush_link_hardness)
-        gimp_paint_options_set_default_brush_hardness (options, brush);
+      gimp_paint_options_gui_brush_notify (options->brush, NULL, options);
     }
 }
 
 static void
+gimp_paint_options_gui_brush_notify (GimpBrush        *brush,
+                                     const GParamSpec *pspec,
+                                     GimpPaintOptions *options)
+{
+#define IS_PSPEC(p,n) (p == NULL || ! strcmp (n, p->name))
+
+  if (options->brush_link_size && IS_PSPEC (pspec, "radius"))
+    gimp_paint_options_set_default_brush_size (options, brush);
+
+  if (options->brush_link_aspect_ratio && IS_PSPEC (pspec, "aspect-ratio"))
+    gimp_paint_options_set_default_brush_aspect_ratio (options, brush);
+
+  if (options->brush_link_angle && IS_PSPEC (pspec, "angle"))
+    gimp_paint_options_set_default_brush_angle (options, brush);
+
+  if (options->brush_link_spacing && IS_PSPEC (pspec, "spacing"))
+    gimp_paint_options_set_default_brush_spacing (options, brush);
+
+  if (options->brush_link_hardness && IS_PSPEC (pspec, "hardness"))
+    gimp_paint_options_set_default_brush_hardness (options, brush);
+
+#undef IS_SPEC
+}
+
+static void
 gimp_paint_options_gui_reset_size (GtkWidget        *button,
                                    GimpPaintOptions *paint_options)
 {
@@ -461,18 +495,20 @@ static void
 gimp_paint_options_gui_reset_aspect_ratio (GtkWidget        *button,
                                            GimpPaintOptions *paint_options)
 {
-  g_object_set (paint_options,
-                "brush-aspect-ratio", 0.0,
-                NULL);
+  GimpBrush *brush = gimp_context_get_brush (GIMP_CONTEXT (paint_options));
+
+  if (brush)
+    gimp_paint_options_set_default_brush_aspect_ratio (paint_options, brush);
 }
 
 static void
 gimp_paint_options_gui_reset_angle (GtkWidget        *button,
                                     GimpPaintOptions *paint_options)
 {
-  g_object_set (paint_options,
-                "brush-angle", 0.0,
-                NULL);
+  GimpBrush *brush = gimp_context_get_brush (GIMP_CONTEXT (paint_options));
+
+  if (brush)
+    gimp_paint_options_set_default_brush_angle (paint_options, brush);
 }
 
 static void


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