Issue #1942 - Smudge Tool with Sample Merged Option

Add a Sample Merged option to smudge, a lot like for heal, just needed
tweaking in more places.
This commit is contained in:
Michael Natterer 2019-01-20 17:48:04 +01:00
parent 4db566f0e1
commit 34cad3a06e
4 changed files with 99 additions and 31 deletions

View File

@ -205,15 +205,21 @@ gimp_smudge_start (GimpPaintCore *paint_core,
GimpPaintOptions *paint_options,
GimpSymmetry *sym)
{
GimpSmudge *smudge = GIMP_SMUDGE (paint_core);
GeglBuffer *paint_buffer;
GimpCoords *coords;
gint paint_buffer_x;
gint paint_buffer_y;
gint accum_size;
gint n_strokes;
gint i;
gint x, y;
GimpSmudge *smudge = GIMP_SMUDGE (paint_core);
GimpSmudgeOptions *options = GIMP_SMUDGE_OPTIONS (paint_options);
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
GimpPickable *dest_pickable;
GeglBuffer *pickable_buffer;
GeglBuffer *paint_buffer;
GimpCoords *coords;
gint dest_pickable_off_x;
gint dest_pickable_off_y;
gint paint_buffer_x;
gint paint_buffer_y;
gint accum_size;
gint n_strokes;
gint i;
gint x, y;
coords = gimp_symmetry_get_origin (sym);
gimp_brush_core_eval_transform_dynamics (GIMP_BRUSH_CORE (paint_core),
@ -221,6 +227,24 @@ gimp_smudge_start (GimpPaintCore *paint_core,
paint_options,
coords);
if (options->sample_merged)
{
dest_pickable = GIMP_PICKABLE (image);
gimp_item_get_offset (GIMP_ITEM (drawable),
&dest_pickable_off_x,
&dest_pickable_off_y);
}
else
{
dest_pickable = GIMP_PICKABLE (drawable);
dest_pickable_off_x = 0;
dest_pickable_off_y = 0;
}
pickable_buffer = gimp_pickable_get_buffer (dest_pickable);
n_strokes = gimp_symmetry_get_size (sym);
for (i = 0; i < n_strokes; i++)
{
@ -263,14 +287,18 @@ gimp_smudge_start (GimpPaintCore *paint_core,
{
gfloat pixel[4];
GeglColor *color;
gint pick_x;
gint pick_y;
gimp_pickable_get_pixel_at (GIMP_PICKABLE (drawable),
CLAMP ((gint) coords->x,
0,
gimp_item_get_width (GIMP_ITEM (drawable)) - 1),
CLAMP ((gint) coords->y,
0,
gimp_item_get_height (GIMP_ITEM (drawable)) - 1),
pick_x = CLAMP ((gint) coords->x + dest_pickable_off_x,
0,
gegl_buffer_get_width (pickable_buffer) - 1);
pick_y = CLAMP ((gint) coords->y + dest_pickable_off_y,
0,
gegl_buffer_get_height (pickable_buffer) - 1);
gimp_pickable_get_pixel_at (dest_pickable,
pick_x, pick_y,
babl_format ("RGBA float"),
pixel);
@ -281,17 +309,17 @@ gimp_smudge_start (GimpPaintCore *paint_core,
}
/* copy the region under the original painthit. */
gimp_gegl_buffer_copy (
gimp_drawable_get_buffer (drawable),
GEGL_RECTANGLE (paint_buffer_x,
paint_buffer_y,
gegl_buffer_get_width (paint_buffer),
gegl_buffer_get_height (paint_buffer)),
GEGL_ABYSS_NONE,
accum_buffer,
GEGL_RECTANGLE (paint_buffer_x - x,
paint_buffer_y - y,
0, 0));
gimp_gegl_buffer_copy
(pickable_buffer,
GEGL_RECTANGLE (paint_buffer_x + dest_pickable_off_x,
paint_buffer_y + dest_pickable_off_y,
gegl_buffer_get_width (paint_buffer),
gegl_buffer_get_height (paint_buffer)),
GEGL_ABYSS_NONE,
accum_buffer,
GEGL_RECTANGLE (paint_buffer_x - x,
paint_buffer_y - y,
0, 0));
}
smudge->accum_buffers = g_list_reverse (smudge->accum_buffers);
@ -311,7 +339,10 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
GimpContext *context = GIMP_CONTEXT (paint_options);
GimpDynamics *dynamics = GIMP_BRUSH_CORE (paint_core)->dynamics;
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
GimpPickable *dest_pickable;
GeglBuffer *paint_buffer;
gint dest_pickable_off_x;
gint dest_pickable_off_y;
gint paint_buffer_x;
gint paint_buffer_y;
gint paint_buffer_width;
@ -336,6 +367,22 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
gint n_strokes;
gint i;
if (options->sample_merged)
{
dest_pickable = GIMP_PICKABLE (image);
gimp_item_get_offset (GIMP_ITEM (drawable),
&dest_pickable_off_x,
&dest_pickable_off_y);
}
else
{
dest_pickable = GIMP_PICKABLE (drawable);
dest_pickable_off_x = 0;
dest_pickable_off_y = 0;
}
fade_point = gimp_paint_options_get_fade (paint_options, image,
paint_core->pixel_dist);
@ -394,7 +441,7 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
/* Convert to linear RGBA */
if (brush_color_ptr)
gimp_pickable_srgb_to_pixel (GIMP_PICKABLE (drawable),
gimp_pickable_srgb_to_pixel (dest_pickable,
&brush_color,
babl_format ("RGBA double"),
&brush_color);
@ -462,9 +509,11 @@ gimp_smudge_motion (GimpPaintCore *paint_core,
paint_buffer_y - y,
paint_buffer_width,
paint_buffer_height),
gimp_drawable_get_buffer (drawable),
GEGL_RECTANGLE (paint_buffer_x,
paint_buffer_y,
gimp_pickable_get_buffer (dest_pickable),
GEGL_RECTANGLE (paint_buffer_x +
dest_pickable_off_x,
paint_buffer_y +
dest_pickable_off_y,
paint_buffer_width,
paint_buffer_height),
brush_color_ptr,

View File

@ -40,6 +40,7 @@ enum
PROP_RATE,
PROP_FLOW,
PROP_NO_ERASING,
PROP_SAMPLE_MERGED
};
@ -85,6 +86,13 @@ gimp_smudge_options_class_init (GimpSmudgeOptionsClass *klass)
_("Never decrease alpha of existing pixels"),
SMUDGE_DEFAULT_NO_ERASING,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SAMPLE_MERGED,
"sample-merged",
_("Sample merged"),
NULL,
FALSE,
GIMP_PARAM_STATIC_STRINGS);
}
static void
@ -111,6 +119,9 @@ gimp_smudge_options_set_property (GObject *object,
case PROP_NO_ERASING:
options->no_erasing = g_value_get_boolean (value);
break;
case PROP_SAMPLE_MERGED:
options->sample_merged = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@ -137,6 +148,9 @@ gimp_smudge_options_get_property (GObject *object,
case PROP_NO_ERASING:
g_value_set_boolean (value, options->no_erasing);
break;
case PROP_SAMPLE_MERGED:
g_value_set_boolean (value, options->sample_merged);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);

View File

@ -39,6 +39,7 @@ struct _GimpSmudgeOptions
gdouble rate;
gdouble flow;
gboolean no_erasing;
gboolean sample_merged;
};
struct _GimpSmudgeOptionsClass

View File

@ -96,6 +96,10 @@ gimp_smudge_options_gui (GimpToolOptions *tool_options)
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
button = gimp_prop_check_button_new (config, "sample-merged", NULL);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
/* the rate scale */
scale = gimp_prop_spin_scale_new (config, "rate", NULL,
1.0, 10.0, 1);