[gimp] app: add "distance-metric" property to the Blend tool options.



commit 87330a77462836a7c0776c814668a7c6b8234027
Author: Jehan <jehan girinstud io>
Date:   Wed Mar 14 19:54:10 2018 +0100

    app: add "distance-metric" property to the Blend tool options.
    
    It seems old blend tool (from GIMP 2.8) was using manhattan distance,
    whereas the new one uses euclidean. I guess there must be use cases for
    both. In any case, it is a good idea to simply propose the option since
    the property exists in the "gegl:distance-transform" operation.
    See also bug 781621.

 app/core/gimpdrawable-blend.c |   14 +++-----
 app/core/gimpdrawable-blend.h |    2 +-
 app/tools/gimpblendoptions.c  |   71 +++++++++++++++++++++++++++++++---------
 app/tools/gimpblendoptions.h  |   23 +++++++------
 app/tools/gimpblendtool.c     |   16 +++++++--
 libgimpbase/gimpbaseenums.c   |   32 ++++++++++++++++++
 libgimpbase/gimpbaseenums.h   |   10 ++++++
 7 files changed, 129 insertions(+), 39 deletions(-)
---
diff --git a/app/core/gimpdrawable-blend.c b/app/core/gimpdrawable-blend.c
index bed2c25..7273bdc 100644
--- a/app/core/gimpdrawable-blend.c
+++ b/app/core/gimpdrawable-blend.c
@@ -85,8 +85,11 @@ gimp_drawable_blend (GimpDrawable     *drawable,
   if (gradient_type >= GIMP_GRADIENT_SHAPEBURST_ANGULAR &&
       gradient_type <= GIMP_GRADIENT_SHAPEBURST_DIMPLED)
     {
+      /* Legacy blend used "manhattan" metric to compute distance.
+       * API needs to stay compatible.
+       */
       shapeburst =
-        gimp_drawable_blend_shapeburst_distmap (drawable, TRUE,
+        gimp_drawable_blend_shapeburst_distmap (drawable, GIMP_DISTANCE_METRIC_MANHATTAN,
                                                 GEGL_RECTANGLE (x, y, width, height),
                                                 progress);
     }
@@ -136,7 +139,7 @@ gimp_drawable_blend (GimpDrawable     *drawable,
 
 GeglBuffer *
 gimp_drawable_blend_shapeburst_distmap (GimpDrawable        *drawable,
-                                        gboolean             legacy_shapeburst,
+                                        GimpDistanceMetric   metric,
                                         const GeglRectangle *region,
                                         GimpProgress        *progress)
 {
@@ -203,12 +206,7 @@ gimp_drawable_blend_shapeburst_distmap (GimpDrawable        *drawable,
   shapeburst = gegl_node_new_child (NULL,
                                     "operation", "gegl:distance-transform",
                                     "normalize", TRUE,
-                                    /* Legacy blend used "manhattan"
-                                     * metric to compute distance, vs.
-                                     * "euclidean". API needs to stay
-                                     * compatible.
-                                     */
-                                    "metric",    legacy_shapeburst ? 1 : 0,
+                                    "metric",    metric,
                                     NULL);
 
   if (progress)
diff --git a/app/core/gimpdrawable-blend.h b/app/core/gimpdrawable-blend.h
index 4853f4e..1f6f30e 100644
--- a/app/core/gimpdrawable-blend.h
+++ b/app/core/gimpdrawable-blend.h
@@ -40,7 +40,7 @@ void   gimp_drawable_blend (GimpDrawable     *drawable,
 
 GeglBuffer *
 gimp_drawable_blend_shapeburst_distmap (GimpDrawable        *drawable,
-                                        gboolean             legacy_shapeburst,
+                                        GimpDistanceMetric   metric,
                                         const GeglRectangle *region,
                                         GimpProgress        *progress);
 
diff --git a/app/tools/gimpblendoptions.c b/app/tools/gimpblendoptions.c
index 6036339..98e9556 100644
--- a/app/tools/gimpblendoptions.c
+++ b/app/tools/gimpblendoptions.c
@@ -44,6 +44,7 @@ enum
   PROP_0,
   PROP_OFFSET,
   PROP_GRADIENT_TYPE,
+  PROP_DISTANCE_METRIC,
   PROP_GRADIENT_REPEAT,  /*  overrides a GimpPaintOptions property  */
   PROP_SUPERSAMPLE,
   PROP_SUPERSAMPLE_DEPTH,
@@ -54,18 +55,21 @@ enum
 };
 
 
-static void   gimp_blend_options_set_property    (GObject          *object,
-                                                  guint             property_id,
-                                                  const GValue     *value,
-                                                  GParamSpec       *pspec);
-static void   gimp_blend_options_get_property    (GObject          *object,
-                                                  guint             property_id,
-                                                  GValue           *value,
-                                                  GParamSpec       *pspec);
+static void   gimp_blend_options_set_property           (GObject          *object,
+                                                         guint             property_id,
+                                                         const GValue     *value,
+                                                         GParamSpec       *pspec);
+static void   gimp_blend_options_get_property           (GObject          *object,
+                                                         guint             property_id,
+                                                         GValue           *value,
+                                                         GParamSpec       *pspec);
 
-static void   blend_options_gradient_type_notify (GimpBlendOptions *options,
-                                                  GParamSpec       *pspec,
-                                                  GtkWidget        *repeat_combo);
+static void   blend_options_repeat_gradient_type_notify (GimpBlendOptions *options,
+                                                         GParamSpec       *pspec,
+                                                         GtkWidget        *repeat_combo);
+static void   blend_options_metric_gradient_type_notify (GimpBlendOptions *options,
+                                                         GParamSpec       *pspec,
+                                                         GtkWidget        *repeat_combo);
 
 
 G_DEFINE_TYPE (GimpBlendOptions, gimp_blend_options, GIMP_TYPE_PAINT_OPTIONS)
@@ -92,6 +96,13 @@ gimp_blend_options_class_init (GimpBlendOptionsClass *klass)
                          GIMP_TYPE_GRADIENT_TYPE,
                          GIMP_GRADIENT_LINEAR,
                          GIMP_PARAM_STATIC_STRINGS);
+  GIMP_CONFIG_PROP_ENUM (object_class, PROP_DISTANCE_METRIC,
+                         "distance-metric",
+                         _("Metric"),
+                         _("Metric to use for the distance calculation"),
+                         GIMP_TYPE_DISTANCE_METRIC,
+                         GIMP_DISTANCE_METRIC_EUCLIDEAN,
+                         GIMP_PARAM_STATIC_STRINGS);
   GIMP_CONFIG_PROP_ENUM (object_class, PROP_GRADIENT_REPEAT,
                          "gradient-repeat",
                          _("Repeat"),
@@ -162,6 +173,9 @@ gimp_blend_options_set_property (GObject      *object,
     case PROP_GRADIENT_TYPE:
       options->gradient_type = g_value_get_enum (value);
       break;
+    case PROP_DISTANCE_METRIC:
+      options->distance_metric = g_value_get_enum (value);
+      break;
     case PROP_GRADIENT_REPEAT:
       GIMP_PAINT_OPTIONS (options)->gradient_options->gradient_repeat =
         g_value_get_enum (value);
@@ -210,6 +224,9 @@ gimp_blend_options_get_property (GObject    *object,
     case PROP_GRADIENT_TYPE:
       g_value_set_enum (value, options->gradient_type);
       break;
+    case PROP_DISTANCE_METRIC:
+      g_value_set_enum (value, options->distance_metric);
+      break;
     case PROP_GRADIENT_REPEAT:
       g_value_set_enum (value,
                         GIMP_PAINT_OPTIONS (options)->gradient_options->gradient_repeat);
@@ -281,6 +298,18 @@ gimp_blend_options_gui (GimpToolOptions *tool_options)
   gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
   gtk_widget_show (combo);
 
+  /*  the distance metric menu  */
+  combo = gimp_prop_enum_combo_box_new (config, "distance-metric", 0, 0);
+  gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Metric"));
+  g_object_set (combo, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+  gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
+  gtk_widget_show (combo);
+
+  g_signal_connect (config, "notify::gradient-type",
+                    G_CALLBACK (blend_options_metric_gradient_type_notify),
+                    combo);
+  blend_options_metric_gradient_type_notify (options, NULL, combo);
+
   /*  the repeat option  */
   combo = gimp_prop_enum_combo_box_new (config, "gradient-repeat", 0, 0);
   gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (combo), _("Repeat"));
@@ -289,9 +318,9 @@ gimp_blend_options_gui (GimpToolOptions *tool_options)
   gtk_widget_show (combo);
 
   g_signal_connect (config, "notify::gradient-type",
-                    G_CALLBACK (blend_options_gradient_type_notify),
+                    G_CALLBACK (blend_options_repeat_gradient_type_notify),
                     combo);
-  blend_options_gradient_type_notify (options, NULL, combo);
+  blend_options_repeat_gradient_type_notify (options, NULL, combo);
 
   /*  the offset scale  */
   scale = gimp_prop_spin_scale_new (config, "offset", NULL,
@@ -371,10 +400,20 @@ gimp_blend_options_gui (GimpToolOptions *tool_options)
 }
 
 static void
-blend_options_gradient_type_notify (GimpBlendOptions *options,
-                                    GParamSpec       *pspec,
-                                    GtkWidget        *repeat_combo)
+blend_options_repeat_gradient_type_notify (GimpBlendOptions *options,
+                                           GParamSpec       *pspec,
+                                           GtkWidget        *repeat_combo)
 {
   gtk_widget_set_sensitive (repeat_combo,
                             options->gradient_type < GIMP_GRADIENT_SHAPEBURST_ANGULAR);
 }
+
+static void
+blend_options_metric_gradient_type_notify (GimpBlendOptions *options,
+                                           GParamSpec       *pspec,
+                                           GtkWidget        *repeat_combo)
+{
+  gtk_widget_set_sensitive (repeat_combo,
+                            options->gradient_type >= GIMP_GRADIENT_SHAPEBURST_ANGULAR &&
+                            options->gradient_type <= GIMP_GRADIENT_SHAPEBURST_DIMPLED);
+}
diff --git a/app/tools/gimpblendoptions.h b/app/tools/gimpblendoptions.h
index 0eaeda8..6a8a4fc 100644
--- a/app/tools/gimpblendoptions.h
+++ b/app/tools/gimpblendoptions.h
@@ -37,22 +37,23 @@ struct _GimpBlendOptions
 {
   GimpPaintOptions  paint_options;
 
-  gdouble           offset;
-  GimpGradientType  gradient_type;
+  gdouble            offset;
+  GimpGradientType   gradient_type;
+  GimpDistanceMetric distance_metric;
 
-  gboolean          supersample;
-  gint              supersample_depth;
-  gdouble           supersample_threshold;
+  gboolean           supersample;
+  gint               supersample_depth;
+  gdouble            supersample_threshold;
 
-  gboolean          dither;
+  gboolean           dither;
 
-  gboolean          instant;
-  gboolean          modify_active;
+  gboolean           instant;
+  gboolean           modify_active;
 
   /*  options gui  */
-  GtkWidget        *instant_toggle;
-  GtkWidget        *modify_active_frame;
-  GtkWidget        *modify_active_hint;
+  GtkWidget         *instant_toggle;
+  GtkWidget         *modify_active_frame;
+  GtkWidget         *modify_active_hint;
 };
 
 
diff --git a/app/tools/gimpblendtool.c b/app/tools/gimpblendtool.c
index b362342..ef6d62c 100644
--- a/app/tools/gimpblendtool.c
+++ b/app/tools/gimpblendtool.c
@@ -519,6 +519,15 @@ gimp_blend_tool_options_notify (GimpTool         *tool,
 
       gimp_drawable_filter_apply (blend_tool->filter, NULL);
     }
+  else if (blend_tool->render_node                    &&
+           gimp_blend_tool_is_shapeburst (blend_tool) &&
+           g_strcmp0 (pspec->name, "distance-metric") == 0)
+    {
+      g_clear_object (&blend_tool->dist_buffer);
+      gimp_blend_tool_precalc_shapeburst (blend_tool);
+      gimp_blend_tool_update_graph (blend_tool);
+      gimp_drawable_filter_apply (blend_tool->filter, NULL);
+    }
   else if (blend_tool->filter &&
            ! strcmp (pspec->name, "opacity"))
     {
@@ -742,8 +751,9 @@ gimp_blend_tool_line_response (GimpToolWidget *widget,
 static void
 gimp_blend_tool_precalc_shapeburst (GimpBlendTool *blend_tool)
 {
-  GimpTool *tool = GIMP_TOOL (blend_tool);
-  gint      x, y, width, height;
+  GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool);
+  GimpTool         *tool    = GIMP_TOOL (blend_tool);
+  gint              x, y, width, height;
 
   if (blend_tool->dist_buffer || ! tool->drawable)
     return;
@@ -753,7 +763,7 @@ gimp_blend_tool_precalc_shapeburst (GimpBlendTool *blend_tool)
     return;
 
   blend_tool->dist_buffer =
-    gimp_drawable_blend_shapeburst_distmap (tool->drawable, FALSE,
+    gimp_drawable_blend_shapeburst_distmap (tool->drawable, options->distance_metric,
                                             GEGL_RECTANGLE (x, y, width, height),
                                             GIMP_PROGRESS (blend_tool));
 
diff --git a/libgimpbase/gimpbaseenums.c b/libgimpbase/gimpbaseenums.c
index 648940d..f591623 100644
--- a/libgimpbase/gimpbaseenums.c
+++ b/libgimpbase/gimpbaseenums.c
@@ -533,6 +533,38 @@ gimp_desaturate_mode_get_type (void)
 }
 
 GType
+gimp_distance_metric_get_type (void)
+{
+  static const GEnumValue values[] =
+  {
+    { GIMP_DISTANCE_METRIC_EUCLIDEAN, "GIMP_DISTANCE_METRIC_EUCLIDEAN", "euclidean" },
+    { GIMP_DISTANCE_METRIC_MANHATTAN, "GIMP_DISTANCE_METRIC_MANHATTAN", "manhattan" },
+    { GIMP_DISTANCE_METRIC_CHESSBOARD, "GIMP_DISTANCE_METRIC_CHESSBOARD", "chessboard" },
+    { 0, NULL, NULL }
+  };
+
+  static const GimpEnumDesc descs[] =
+  {
+    { GIMP_DISTANCE_METRIC_EUCLIDEAN, NC_("distance-metric", "Euclidean"), NULL },
+    { GIMP_DISTANCE_METRIC_MANHATTAN, NC_("distance-metric", "Manhattan"), NULL },
+    { GIMP_DISTANCE_METRIC_CHESSBOARD, NC_("distance-metric", "Chessboard"), NULL },
+    { 0, NULL, NULL }
+  };
+
+  static GType type = 0;
+
+  if (G_UNLIKELY (! type))
+    {
+      type = g_enum_register_static ("GimpDistanceMetric", values);
+      gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp");
+      gimp_type_set_translation_context (type, "distance-metric");
+      gimp_enum_set_value_descriptions (type, descs);
+    }
+
+  return type;
+}
+
+GType
 gimp_dodge_burn_type_get_type (void)
 {
   static const GEnumValue values[] =
diff --git a/libgimpbase/gimpbaseenums.h b/libgimpbase/gimpbaseenums.h
index 7fb115d..afa6538 100644
--- a/libgimpbase/gimpbaseenums.h
+++ b/libgimpbase/gimpbaseenums.h
@@ -290,6 +290,16 @@ typedef enum
 #endif /* GIMP_DISABLE_DEPRECATED */
 } GimpDesaturateMode;
 
+#define GIMP_TYPE_DISTANCE_METRIC (gimp_distance_metric_get_type ())
+
+GType gimp_distance_metric_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+  GIMP_DISTANCE_METRIC_EUCLIDEAN,  /*< desc="Euclidean"  >*/
+  GIMP_DISTANCE_METRIC_MANHATTAN,  /*< desc="Manhattan"  >*/
+  GIMP_DISTANCE_METRIC_CHESSBOARD  /*< desc="Chessboard" >*/
+} GimpDistanceMetric;
 
 #define GIMP_TYPE_DODGE_BURN_TYPE (gimp_dodge_burn_type_get_type ())
 


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