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.
This commit is contained in:
Jehan 2018-03-14 19:54:10 +01:00
parent a7f3a2dd9f
commit 87330a7746
7 changed files with 129 additions and 39 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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));

View File

@ -532,6 +532,38 @@ gimp_desaturate_mode_get_type (void)
return type;
}
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)
{

View File

@ -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 ())