Commit e164aee7 authored by Jehan's avatar Jehan

app, libgimp, pdb: add "distance-metric" property to GimpPDBContext.

This property is currently only used for gimp_edit_blend() to control
how are computed distances. In the future, it could be used for more
functions making use of "gegl:distance-transform" operation, or even for
other algorithms, if relevant.
This new property obviously comes with 2 new PDB calls:
gimp_context_get_distance_metric() & gimp_context_set_distance_metric()
parent 11dcabc4
......@@ -40,24 +40,25 @@
/* public functions */
void
gimp_drawable_blend (GimpDrawable *drawable,
GimpContext *context,
GimpGradient *gradient,
GimpLayerMode paint_mode,
GimpGradientType gradient_type,
gdouble opacity,
gdouble offset,
GimpRepeatMode repeat,
gboolean reverse,
gboolean supersample,
gint max_depth,
gdouble threshold,
gboolean dither,
gdouble startx,
gdouble starty,
gdouble endx,
gdouble endy,
GimpProgress *progress)
gimp_drawable_blend (GimpDrawable *drawable,
GimpContext *context,
GimpGradient *gradient,
GeglDistanceMetric metric,
GimpLayerMode paint_mode,
GimpGradientType gradient_type,
gdouble opacity,
gdouble offset,
GimpRepeatMode repeat,
gboolean reverse,
gboolean supersample,
gint max_depth,
gdouble threshold,
gboolean dither,
gdouble startx,
gdouble starty,
gdouble endx,
gdouble endy,
GimpProgress *progress)
{
GimpImage *image;
GeglBuffer *buffer;
......@@ -85,12 +86,8 @@ 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,
GEGL_DISTANCE_METRIC_MANHATTAN,
gimp_drawable_blend_shapeburst_distmap (drawable, metric,
GEGL_RECTANGLE (x, y, width, height),
progress);
}
......
......@@ -19,24 +19,25 @@
#define __GIMP_DRAWABLE_BLEND_H__
void gimp_drawable_blend (GimpDrawable *drawable,
GimpContext *context,
GimpGradient *gradient,
GimpLayerMode paint_mode,
GimpGradientType gradient_type,
gdouble opacity,
gdouble offset,
GimpRepeatMode repeat,
gboolean reverse,
gboolean supersample,
gint max_depth,
gdouble threshold,
gboolean dither,
gdouble startx,
gdouble starty,
gdouble endx,
gdouble endy,
GimpProgress *progress);
void gimp_drawable_blend (GimpDrawable *drawable,
GimpContext *context,
GimpGradient *gradient,
GeglDistanceMetric metric,
GimpLayerMode paint_mode,
GimpGradientType gradient_type,
gdouble opacity,
gdouble offset,
GimpRepeatMode repeat,
gboolean reverse,
gboolean supersample,
gint max_depth,
gdouble threshold,
gboolean dither,
gdouble startx,
gdouble starty,
gdouble endx,
gdouble endy,
GimpProgress *progress);
GeglBuffer *
gimp_drawable_blend_shapeburst_distmap (GimpDrawable *drawable,
......
......@@ -2764,6 +2764,51 @@ context_set_ink_blob_angle_invoker (GimpProcedure *procedure,
error ? *error : NULL);
}
static GimpValueArray *
context_get_distance_metric_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
GimpValueArray *return_vals;
gint32 metric = 0;
g_object_get (context,
"distance-metric", &metric,
NULL);
return_vals = gimp_procedure_get_return_values (procedure, TRUE, NULL);
g_value_set_enum (gimp_value_array_index (return_vals, 1), metric);
return return_vals;
}
static GimpValueArray *
context_set_distance_metric_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
gboolean success = TRUE;
gint32 metric;
metric = g_value_get_enum (gimp_value_array_index (args, 0));
if (success)
{
g_object_set (context,
"distance-metric", metric,
NULL);
}
return gimp_procedure_get_return_values (procedure, success,
error ? *error : NULL);
}
void
register_context_procs (GimpPDB *pdb)
{
......@@ -5178,4 +5223,52 @@ register_context_procs (GimpPDB *pdb)
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-context-get-distance-metric
*/
procedure = gimp_procedure_new (context_get_distance_metric_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-context-get-distance-metric");
gimp_procedure_set_static_strings (procedure,
"gimp-context-get-distance-metric",
"Get the distance metric used in some computations.",
"This procedure returns the distance metric in the current context. See 'gimp-context-set-distance-metric' to know more about its usage.",
"Ed Swartz",
"Ed Swartz",
"2018",
NULL);
gimp_procedure_add_return_value (procedure,
g_param_spec_enum ("metric",
"metric",
"The distance metric",
GEGL_TYPE_DISTANCE_METRIC,
GEGL_DISTANCE_METRIC_EUCLIDEAN,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-context-set-distance-metric
*/
procedure = gimp_procedure_new (context_set_distance_metric_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-context-set-distance-metric");
gimp_procedure_set_static_strings (procedure,
"gimp-context-set-distance-metric",
"Set the distance metric used in some computations.",
"This procedure modifies the distance metric used in some computations, such as 'gimp-edit-blend'. In particular, it does not change the metric used in generic distance computation on canvas, as in the Measure tool.",
"Ed Swartz",
"Ed Swartz",
"2018",
NULL);
gimp_procedure_add_argument (procedure,
g_param_spec_enum ("metric",
"metric",
"The distance metric",
GEGL_TYPE_DISTANCE_METRIC,
GEGL_DISTANCE_METRIC_EUCLIDEAN,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
}
......@@ -819,6 +819,7 @@ edit_blend_invoker (GimpProcedure *procedure,
gimp_drawable_blend (drawable,
context,
gradient,
GIMP_PDB_CONTEXT (context)->distance_metric,
paint_mode,
gradient_type,
opacity / 100.0,
......
......@@ -55,7 +55,8 @@ enum
PROP_DIAGONAL_NEIGHBORS,
PROP_INTERPOLATION,
PROP_TRANSFORM_DIRECTION,
PROP_TRANSFORM_RESIZE
PROP_TRANSFORM_RESIZE,
PROP_DISTANCE_METRIC
};
......@@ -181,6 +182,22 @@ gimp_pdb_context_class_init (GimpPDBContextClass *klass)
GIMP_TYPE_TRANSFORM_RESIZE,
GIMP_TRANSFORM_RESIZE_ADJUST,
GIMP_PARAM_STATIC_STRINGS);
/* Legacy blend used "manhattan" metric to compute distance.
* API needs to stay compatible, hence the default value for this
* property.
* Nevertheless Euclidean distance since to render better; for GIMP 3
* API, we might therefore want to change the defaults to
* GEGL_DISTANCE_METRIC_EUCLIDEAN. FIXME.
*/
GIMP_CONFIG_PROP_ENUM (object_class, PROP_DISTANCE_METRIC,
"distance-metric",
_("Distance metric"),
NULL,
GEGL_TYPE_DISTANCE_METRIC,
GEGL_DISTANCE_METRIC_MANHATTAN,
GIMP_PARAM_STATIC_STRINGS);
}
static void
......@@ -324,6 +341,10 @@ gimp_pdb_context_set_property (GObject *object,
options->transform_resize = g_value_get_enum (value);
break;
case PROP_DISTANCE_METRIC:
options->distance_metric = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
......@@ -388,6 +409,10 @@ gimp_pdb_context_get_property (GObject *object,
g_value_set_enum (value, options->transform_resize);
break;
case PROP_DISTANCE_METRIC:
g_value_set_enum (value, options->distance_metric);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
......
......@@ -55,6 +55,8 @@ struct _GimpPDBContext
GimpContainer *paint_options_list;
GimpStrokeOptions *stroke_options;
GeglDistanceMetric distance_metric;
};
struct _GimpPDBContextClass
......
......@@ -28,7 +28,7 @@
#include "internal-procs.h"
/* 814 procedures registered total */
/* 816 procedures registered total */
void
internal_procs_init (GimpPDB *pdb)
......
......@@ -78,6 +78,7 @@ EXPORTS
gimp_context_get_brush_size
gimp_context_get_brush_spacing
gimp_context_get_diagonal_neighbors
gimp_context_get_distance_metric
gimp_context_get_dynamics
gimp_context_get_feather
gimp_context_get_feather_radius
......@@ -133,6 +134,7 @@ EXPORTS
gimp_context_set_default_colors
gimp_context_set_defaults
gimp_context_set_diagonal_neighbors
gimp_context_set_distance_metric
gimp_context_set_dynamics
gimp_context_set_feather
gimp_context_set_feather_radius
......
......@@ -3398,3 +3398,68 @@ gimp_context_set_ink_blob_angle (gdouble angle)
return success;
}
/**
* gimp_context_get_distance_metric:
*
* Get the distance metric used in some computations.
*
* This procedure returns the distance metric in the current context.
* See gimp_context_set_distance_metric() to know more about its usage.
*
* Returns: The distance metric.
*
* Since: 2.10
**/
GeglDistanceMetric
gimp_context_get_distance_metric (void)
{
GimpParam *return_vals;
gint nreturn_vals;
GeglDistanceMetric metric = 0;
return_vals = gimp_run_procedure ("gimp-context-get-distance-metric",
&nreturn_vals,
GIMP_PDB_END);
if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
metric = return_vals[1].data.d_int32;
gimp_destroy_params (return_vals, nreturn_vals);
return metric;
}
/**
* gimp_context_set_distance_metric:
* @metric: The distance metric.
*
* Set the distance metric used in some computations.
*
* This procedure modifies the distance metric used in some
* computations, such as gimp_edit_blend(). In particular, it does not
* change the metric used in generic distance computation on canvas, as
* in the Measure tool.
*
* Returns: TRUE on success.
*
* Since: 2.10
**/
gboolean
gimp_context_set_distance_metric (GeglDistanceMetric metric)
{
GimpParam *return_vals;
gint nreturn_vals;
gboolean success = TRUE;
return_vals = gimp_run_procedure ("gimp-context-set-distance-metric",
&nreturn_vals,
GIMP_PDB_INT32, metric,
GIMP_PDB_END);
success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;
gimp_destroy_params (return_vals, nreturn_vals);
return success;
}
......@@ -142,6 +142,8 @@ gdouble gimp_context_get_ink_blob_aspect_ratio (void);
gboolean gimp_context_set_ink_blob_aspect_ratio (gdouble aspect);
gdouble gimp_context_get_ink_blob_angle (void);
gboolean gimp_context_set_ink_blob_angle (gdouble angle);
GeglDistanceMetric gimp_context_get_distance_metric (void);
gboolean gimp_context_set_distance_metric (GeglDistanceMetric metric);
G_END_DECLS
......
......@@ -3032,6 +3032,59 @@ CODE
);
}
sub context_get_distance_metric {
$blurb = 'Get the distance metric used in some computations.';
$help = <<'HELP';
This procedure returns the distance metric in the current context.
See gimp_context_set_distance_metric() to know more about its usage.
HELP
&ejs_pdb_misc('2018', '2.10');
@outargs = (
{ name => 'metric', type => 'enum GeglDistanceMetric',
desc => 'The distance metric' }
);
%invoke = (
code => <<'CODE'
{
g_object_get (context,
"distance-metric", &metric,
NULL);
}
CODE
);
}
sub context_set_distance_metric {
$blurb = 'Set the distance metric used in some computations.';
$help = <<'HELP';
This procedure modifies the distance metric used in some computations,
such as gimp_edit_blend(). In particular, it does not change the metric used
in generic distance computation on canvas, as in the Measure tool.
HELP
&ejs_pdb_misc('2018', '2.10');
@inargs = (
{ name => 'metric', type => 'enum GeglDistanceMetric',
desc => 'The distance metric' }
);
%invoke = (
code => <<'CODE'
{
g_object_set (context,
"distance-metric", metric,
NULL);
}
CODE
);
}
@headers = qw("core/gimp.h"
"core/gimpcontainer.h"
"core/gimpdashpattern.h"
......@@ -3099,7 +3152,8 @@ CODE
context_get_ink_speed_sensitivity context_set_ink_speed_sensitivity
context_get_ink_blob_type context_set_ink_blob_type
context_get_ink_blob_aspect_ratio context_set_ink_blob_aspect_ratio
context_get_ink_blob_angle context_set_ink_blob_angle);
context_get_ink_blob_angle context_set_ink_blob_angle
context_get_distance_metric context_set_distance_metric);
%exports = (app => [@procs], lib => [@procs]);
......
......@@ -899,6 +899,7 @@ HELP
gimp_drawable_blend (drawable,
context,
gradient,
GIMP_PDB_CONTEXT (context)->distance_metric,
paint_mode,
gradient_type,
opacity / 100.0,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment