[gimp] Issue #3512 - feather selection doesn't work at edges of images
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Issue #3512 - feather selection doesn't work at edges of images
- Date: Sun, 16 Jun 2019 14:54:37 +0000 (UTC)
commit aace6b179b29c5728529d5c1c725ed33892d7056
Author: Michael Natterer <mitch gimp org>
Date: Sun Jun 16 16:51:30 2019 +0200
Issue #3512 - feather selection doesn't work at edges of images
Add a "gboolean edge_lock" parameter to GimpChannel::feather() and a
"Selected areas continue outside the image" toggle to the "Feather
Selection" dialog, just like they exist for shrink selection and
border selection. At the end, convert the boolean to the right abyss
policy for gegl:gaussian-blur.
app/actions/select-commands.c | 25 +++++++++++++++++++++++--
app/config/gimpdialogconfig.c | 14 ++++++++++++++
app/config/gimpdialogconfig.h | 1 +
app/config/gimprc-blurbs.h | 4 ++++
app/core/gimpchannel.c | 8 ++++++--
app/core/gimpchannel.h | 2 ++
app/dialogs/preferences-dialog.c | 4 ++++
app/gegl/gimp-gegl-apply-operation.c | 35 +++++++++++++++++++++++------------
app/gegl/gimp-gegl-apply-operation.h | 13 +++++++++++--
app/pdb/selection-cmds.c | 3 ++-
pdb/groups/selection.pdb | 3 ++-
11 files changed, 92 insertions(+), 20 deletions(-)
---
diff --git a/app/actions/select-commands.c b/app/actions/select-commands.c
index 1258a71466..c6bbd3e71b 100644
--- a/app/actions/select-commands.c
+++ b/app/actions/select-commands.c
@@ -148,6 +148,7 @@ select_feather_cmd_callback (GtkAction *action,
if (! dialog)
{
GimpDialogConfig *config = GIMP_DIALOG_CONFIG (image->gimp->config);
+ GtkWidget *button;
gdouble xres;
gdouble yres;
@@ -165,6 +166,19 @@ select_feather_cmd_callback (GtkAction *action,
G_OBJECT (image), "disconnect",
select_feather_callback, image);
+ /* Edge lock button */
+ button = gtk_check_button_new_with_mnemonic (_("_Selected areas continue outside the image"));
+ g_object_set_data (G_OBJECT (dialog), "edge-lock-toggle", button);
+ gimp_help_set_help_data (button,
+ _("When feathering, act as if selected areas"
+ "continued outside the image."),
+ NULL);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+ config->selection_feather_edge_lock);
+ gtk_box_pack_start (GTK_BOX (GIMP_QUERY_BOX_VBOX (dialog)), button,
+ FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
dialogs_attach_dialog (G_OBJECT (image), FEATHER_DIALOG_KEY, dialog);
}
@@ -478,11 +492,16 @@ select_feather_callback (GtkWidget *widget,
{
GimpImage *image = GIMP_IMAGE (data);
GimpDialogConfig *config = GIMP_DIALOG_CONFIG (image->gimp->config);
+ GtkWidget *button;
gdouble radius_x;
gdouble radius_y;
+ button = g_object_get_data (G_OBJECT (widget), "edge-lock-toggle");
+
g_object_set (config,
"selection-feather-radius", size,
+ "selection-feather-edge-lock",
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)),
NULL);
radius_x = config->selection_feather_radius;
@@ -505,7 +524,9 @@ select_feather_callback (GtkWidget *widget,
radius_x *= factor;
}
- gimp_channel_feather (gimp_image_get_mask (image), radius_x, radius_y, TRUE);
+ gimp_channel_feather (gimp_image_get_mask (image), radius_x, radius_y,
+ config->selection_feather_edge_lock,
+ TRUE);
gimp_image_flush (image);
}
@@ -616,7 +637,7 @@ select_shrink_callback (GtkWidget *widget,
button = g_object_get_data (G_OBJECT (widget), "edge-lock-toggle");
g_object_set (config,
- "selection-shrink-radius", size,
+ "selection-shrink-radius", size,
"selection-shrink-edge-lock",
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)),
NULL);
diff --git a/app/config/gimpdialogconfig.c b/app/config/gimpdialogconfig.c
index 9a226cf9d5..f81d778d86 100644
--- a/app/config/gimpdialogconfig.c
+++ b/app/config/gimpdialogconfig.c
@@ -98,6 +98,7 @@ enum
PROP_VECTORS_IMPORT_SCALE,
PROP_SELECTION_FEATHER_RADIUS,
+ PROP_SELECTION_FEATHER_EDGE_LOCK,
PROP_SELECTION_GROW_RADIUS,
@@ -465,6 +466,13 @@ gimp_dialog_config_class_init (GimpDialogConfigClass *klass)
0.0, 32767.0, 5.0,
GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SELECTION_FEATHER_EDGE_LOCK,
+ "selection-feather-edge-lock",
+ "Selection feather edge lock",
+ SELECTION_FEATHER_EDGE_LOCK_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_SELECTION_GROW_RADIUS,
"selection-grow-radius",
"Selection grow radius",
@@ -736,6 +744,9 @@ gimp_dialog_config_set_property (GObject *object,
case PROP_SELECTION_FEATHER_RADIUS:
config->selection_feather_radius = g_value_get_double (value);
break;
+ case PROP_SELECTION_FEATHER_EDGE_LOCK:
+ config->selection_feather_edge_lock = g_value_get_boolean (value);
+ break;
case PROP_SELECTION_GROW_RADIUS:
config->selection_grow_radius = g_value_get_double (value);
@@ -921,6 +932,9 @@ gimp_dialog_config_get_property (GObject *object,
case PROP_SELECTION_FEATHER_RADIUS:
g_value_set_double (value, config->selection_feather_radius);
break;
+ case PROP_SELECTION_FEATHER_EDGE_LOCK:
+ g_value_set_boolean (value, config->selection_feather_edge_lock);
+ break;
case PROP_SELECTION_GROW_RADIUS:
g_value_set_double (value, config->selection_grow_radius);
diff --git a/app/config/gimpdialogconfig.h b/app/config/gimpdialogconfig.h
index c59f12b556..1053f6d339 100644
--- a/app/config/gimpdialogconfig.h
+++ b/app/config/gimpdialogconfig.h
@@ -96,6 +96,7 @@ struct _GimpDialogConfig
gboolean vectors_import_scale;
gdouble selection_feather_radius;
+ gboolean selection_feather_edge_lock;
gdouble selection_grow_radius;
diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h
index 5d6bf63b83..f63b27f5db 100644
--- a/app/config/gimprc-blurbs.h
+++ b/app/config/gimprc-blurbs.h
@@ -591,6 +591,10 @@ _("Sets the default 'Scale imported paths to fit size' state for the 'Import Pat
#define SELECTION_FEATHER_RADIUS_BLURB \
_("Sets the default feather radius for the 'Feather Selection' dialog.")
+#define SELECTION_FEATHER_EDGE_LOCK_BLURB \
+_("Sets the default 'Selected areas continue outside the image' setting " \
+ "for the 'Feather Selection' dialog.")
+
#define SELECTION_GROW_RADIUS_BLURB \
_("Sets the default grow radius for the 'Grow Selection' dialog.")
diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c
index efc330f4e6..3c9c2be7f2 100644
--- a/app/core/gimpchannel.c
+++ b/app/core/gimpchannel.c
@@ -186,6 +186,7 @@ static gboolean gimp_channel_real_is_empty (GimpChannel *channel);
static void gimp_channel_real_feather (GimpChannel *channel,
gdouble radius_x,
gdouble radius_y,
+ gboolean edge_lock,
gboolean push_undo);
static void gimp_channel_real_sharpen (GimpChannel *channel,
gboolean push_undo);
@@ -1177,6 +1178,7 @@ static void
gimp_channel_real_feather (GimpChannel *channel,
gdouble radius_x,
gdouble radius_y,
+ gboolean edge_lock,
gboolean push_undo)
{
gint x1, y1, x2, y2;
@@ -1208,7 +1210,8 @@ gimp_channel_real_feather (GimpChannel *channel,
gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1),
radius_x,
- radius_y);
+ radius_y,
+ edge_lock);
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0, -1, -1);
}
@@ -1890,6 +1893,7 @@ void
gimp_channel_feather (GimpChannel *channel,
gdouble radius_x,
gdouble radius_y,
+ gboolean edge_lock,
gboolean push_undo)
{
g_return_if_fail (GIMP_IS_CHANNEL (channel));
@@ -1898,7 +1902,7 @@ gimp_channel_feather (GimpChannel *channel,
push_undo = FALSE;
GIMP_CHANNEL_GET_CLASS (channel)->feather (channel, radius_x, radius_y,
- push_undo);
+ edge_lock, push_undo);
}
void
diff --git a/app/core/gimpchannel.h b/app/core/gimpchannel.h
index 468645050a..348f4f64f6 100644
--- a/app/core/gimpchannel.h
+++ b/app/core/gimpchannel.h
@@ -77,6 +77,7 @@ struct _GimpChannelClass
void (* feather) (GimpChannel *channel,
gdouble radius_x,
gdouble radius_y,
+ gboolean edge_lock,
gboolean push_undo);
void (* sharpen) (GimpChannel *channel,
gboolean push_undo);
@@ -180,6 +181,7 @@ gboolean gimp_channel_is_empty (GimpChannel *mask);
void gimp_channel_feather (GimpChannel *mask,
gdouble radius_x,
gdouble radius_y,
+ gboolean edge_lock,
gboolean push_undo);
void gimp_channel_sharpen (GimpChannel *mask,
gboolean push_undo);
diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c
index fb37b506bb..98514394d6 100644
--- a/app/dialogs/preferences-dialog.c
+++ b/app/dialogs/preferences-dialog.c
@@ -2388,6 +2388,10 @@ prefs_dialog_new (Gimp *gimp,
_("Feather radius:"),
GTK_GRID (grid), 0, size_group);
+ prefs_check_button_add (object, "selection-feather-edge-lock",
+ _("Selected areas continue outside the image"),
+ GTK_BOX (vbox2));
+
/* Grow Selection Dialog */
vbox2 = prefs_frame_new (_("Grow Selection Dialog"),
GTK_CONTAINER (vbox), FALSE);
diff --git a/app/gegl/gimp-gegl-apply-operation.c b/app/gegl/gimp-gegl-apply-operation.c
index e4f58e526b..931d147d86 100644
--- a/app/gegl/gimp-gegl-apply-operation.c
+++ b/app/gegl/gimp-gegl-apply-operation.c
@@ -361,12 +361,20 @@ gimp_gegl_apply_feather (GeglBuffer *src_buffer,
GeglBuffer *dest_buffer,
const GeglRectangle *dest_rect,
gdouble radius_x,
- gdouble radius_y)
+ gdouble radius_y,
+ gboolean edge_lock)
{
+ GaussianBlurAbyssPolicy abyss_policy;
+
g_return_if_fail (GEGL_IS_BUFFER (src_buffer));
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
g_return_if_fail (GEGL_IS_BUFFER (dest_buffer));
+ if (edge_lock)
+ abyss_policy = GAUSSIAN_BLUR_ABYSS_CLAMP;
+ else
+ abyss_policy = GAUSSIAN_BLUR_ABYSS_NONE;
+
/* 3.5 is completely magic and picked to visually match the old
* gaussian_blur_region() on a crappy laptop display
*/
@@ -374,7 +382,8 @@ gimp_gegl_apply_feather (GeglBuffer *src_buffer,
progress, undo_desc,
dest_buffer, dest_rect,
radius_x / 3.5,
- radius_y / 3.5);
+ radius_y / 3.5,
+ abyss_policy);
}
void
@@ -545,13 +554,14 @@ gimp_gegl_apply_flood (GeglBuffer *src_buffer,
}
void
-gimp_gegl_apply_gaussian_blur (GeglBuffer *src_buffer,
- GimpProgress *progress,
- const gchar *undo_desc,
- GeglBuffer *dest_buffer,
- const GeglRectangle *dest_rect,
- gdouble std_dev_x,
- gdouble std_dev_y)
+gimp_gegl_apply_gaussian_blur (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gdouble std_dev_x,
+ gdouble std_dev_y,
+ GaussianBlurAbyssPolicy abyss_policy)
{
GeglNode *node;
@@ -560,9 +570,10 @@ gimp_gegl_apply_gaussian_blur (GeglBuffer *src_buffer,
g_return_if_fail (GEGL_IS_BUFFER (dest_buffer));
node = gegl_node_new_child (NULL,
- "operation", "gegl:gaussian-blur",
- "std-dev-x", std_dev_x,
- "std-dev-y", std_dev_y,
+ "operation", "gegl:gaussian-blur",
+ "std-dev-x", std_dev_x,
+ "std-dev-y", std_dev_y,
+ "abyss-policy", abyss_policy,
NULL);
gimp_gegl_apply_operation (src_buffer, progress, undo_desc,
diff --git a/app/gegl/gimp-gegl-apply-operation.h b/app/gegl/gimp-gegl-apply-operation.h
index ad863db2be..7864026b99 100644
--- a/app/gegl/gimp-gegl-apply-operation.h
+++ b/app/gegl/gimp-gegl-apply-operation.h
@@ -70,7 +70,8 @@ void gimp_gegl_apply_feather (GeglBuffer *src_buffer,
GeglBuffer *dest_buffer,
const GeglRectangle *dest_rect,
gdouble radius_x,
- gdouble radius_y);
+ gdouble radius_y,
+ gboolean edge_lock);
void gimp_gegl_apply_border (GeglBuffer *src_buffer,
GimpProgress *progress,
@@ -105,13 +106,21 @@ void gimp_gegl_apply_flood (GeglBuffer *src_buffer,
GeglBuffer *dest_buffer,
const GeglRectangle *dest_rect);
+/* UGLY: private enum of gegl:gaussian-blur */
+typedef enum
+{
+ GAUSSIAN_BLUR_ABYSS_NONE,
+ GAUSSIAN_BLUR_ABYSS_CLAMP
+} GaussianBlurAbyssPolicy;
+
void gimp_gegl_apply_gaussian_blur (GeglBuffer *src_buffer,
GimpProgress *progress,
const gchar *undo_desc,
GeglBuffer *dest_buffer,
const GeglRectangle *dest_rect,
gdouble std_dev_x,
- gdouble std_dev_y);
+ gdouble std_dev_y,
+ GaussianBlurAbyssPolicy abyss_policy);
void gimp_gegl_apply_invert_gamma (GeglBuffer *src_buffer,
GimpProgress *progress,
diff --git a/app/pdb/selection-cmds.c b/app/pdb/selection-cmds.c
index a54e2b9f61..5e0641ebb0 100644
--- a/app/pdb/selection-cmds.c
+++ b/app/pdb/selection-cmds.c
@@ -337,8 +337,9 @@ selection_feather_invoker (GimpProcedure *procedure,
if (success)
{
+ /* FIXME: "edge-lock" hardcoded to TRUE */
gimp_channel_feather (gimp_image_get_mask (image),
- radius, radius, TRUE);
+ radius, radius, TRUE, TRUE);
}
return gimp_procedure_get_return_values (procedure, success,
diff --git a/pdb/groups/selection.pdb b/pdb/groups/selection.pdb
index 920c23261c..dbde6fc029 100644
--- a/pdb/groups/selection.pdb
+++ b/pdb/groups/selection.pdb
@@ -332,8 +332,9 @@ HELP
%invoke = (
code => <<'CODE'
{
+ /* FIXME: "edge-lock" hardcoded to TRUE */
gimp_channel_feather (gimp_image_get_mask (image),
- radius, radius, TRUE);
+ radius, radius, TRUE, TRUE);
}
CODE
);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]