[gimp] app: fix symmetry transform in Clone/Heal tools when brush is cropped
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: fix symmetry transform in Clone/Heal tools when brush is cropped
- Date: Wed, 29 May 2019 09:28:14 +0000 (UTC)
commit a701032b4ea9e3588aea38de5d447db5091e3ccf
Author: Ell <ell_se yahoo com>
Date: Wed May 29 04:58:17 2019 -0400
app: fix symmetry transform in Clone/Heal tools when brush is cropped
In GimpSourceCore, when applying a symmetry transform to the source
content, combine the transform op with translation to the paint-
buffer coordinates, so that subclasses (namely, GimpClone and
GimpHeal) can use the op to apply the transformation directly from
the source buffer to the paint buffer in a single step. This is
both more efficient, and avoids incorrect symmetry transforms when
the paint buffer is cropped to the bounds of the drawable.
app/paint/gimpclone.c | 35 ++++++++++++++++++------------
app/paint/gimpheal.c | 30 ++++++++++++--------------
app/paint/gimpsourcecore.c | 54 +++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 84 insertions(+), 35 deletions(-)
---
diff --git a/app/paint/gimpclone.c b/app/paint/gimpclone.c
index 464a3a4ba4..9c807f43ff 100644
--- a/app/paint/gimpclone.c
+++ b/app/paint/gimpclone.c
@@ -169,21 +169,28 @@ gimp_clone_motion (GimpSourceCore *source_core,
if (gimp_source_core_use_source (source_core, source_options))
{
- gimp_gegl_buffer_copy (src_buffer,
- GEGL_RECTANGLE (src_rect->x,
- src_rect->y,
- paint_area_width,
- paint_area_height),
- GEGL_ABYSS_NONE,
- paint_buffer,
- GEGL_RECTANGLE (paint_area_offset_x,
- paint_area_offset_y,
- 0, 0));
-
- if (op)
+ if (! op)
{
- gimp_gegl_apply_operation (paint_buffer, NULL, NULL, op,
- paint_buffer, NULL, FALSE);
+ gimp_gegl_buffer_copy (src_buffer,
+ GEGL_RECTANGLE (src_rect->x,
+ src_rect->y,
+ paint_area_width,
+ paint_area_height),
+ GEGL_ABYSS_NONE,
+ paint_buffer,
+ GEGL_RECTANGLE (paint_area_offset_x,
+ paint_area_offset_y,
+ 0, 0));
+ }
+ else
+ {
+ gimp_gegl_apply_operation (src_buffer, NULL, NULL, op,
+ paint_buffer,
+ GEGL_RECTANGLE (paint_area_offset_x,
+ paint_area_offset_y,
+ paint_area_width,
+ paint_area_height),
+ FALSE);
}
}
else if (options->clone_type == GIMP_CLONE_PATTERN)
diff --git a/app/paint/gimpheal.c b/app/paint/gimpheal.c
index 2901df3315..8f7451a3b2 100644
--- a/app/paint/gimpheal.c
+++ b/app/paint/gimpheal.c
@@ -560,16 +560,23 @@ gimp_heal_motion (GimpSourceCore *source_core,
}
/* heal should work in perceptual space, use R'G'B' instead of RGB */
- src_copy = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
+ src_copy = gegl_buffer_new (GEGL_RECTANGLE (paint_area_offset_x,
+ paint_area_offset_y,
src_rect->width,
src_rect->height),
babl_format ("R'G'B'A float"));
- gimp_gegl_buffer_copy (src_buffer, src_rect, GEGL_ABYSS_NONE,
- src_copy,
- GEGL_RECTANGLE (0, 0,
- src_rect->width,
- src_rect->height));
+ if (! op)
+ {
+ gimp_gegl_buffer_copy (src_buffer, src_rect, GEGL_ABYSS_NONE,
+ src_copy, gegl_buffer_get_extent (src_copy));
+ }
+ else
+ {
+ gimp_gegl_apply_operation (src_buffer, NULL, NULL, op,
+ src_copy, gegl_buffer_get_extent (src_copy),
+ FALSE);
+ }
if (src_options->sample_merged)
{
@@ -610,16 +617,7 @@ gimp_heal_motion (GimpSourceCore *source_core,
mask_off_y = (y < 0) ? -y : 0;
}
- if (op)
- {
- gimp_gegl_apply_operation (src_copy, NULL, NULL, op,
- src_copy, NULL, FALSE);
- }
-
- gimp_heal (src_copy,
- GEGL_RECTANGLE (0, 0,
- gegl_buffer_get_width (src_copy),
- gegl_buffer_get_height (src_copy)),
+ gimp_heal (src_copy, gegl_buffer_get_extent (src_copy),
paint_buffer,
GEGL_RECTANGLE (paint_area_offset_x,
paint_area_offset_y,
diff --git a/app/paint/gimpsourcecore.c b/app/paint/gimpsourcecore.c
index bfa81d20ed..02db2186f6 100644
--- a/app/paint/gimpsourcecore.c
+++ b/app/paint/gimpsourcecore.c
@@ -480,9 +480,52 @@ gimp_source_core_motion (GimpSourceCore *source_core,
/* Set the paint buffer to transparent */
gegl_buffer_clear (paint_buffer, NULL);
- op = gimp_symmetry_get_operation (sym, i,
- gegl_buffer_get_width (paint_buffer),
- gegl_buffer_get_height (paint_buffer));
+ op = gimp_symmetry_get_operation (sym, i);
+
+ if (op)
+ {
+ GeglNode *node;
+ GeglNode *input;
+ GeglNode *translate_before;
+ GeglNode *translate_after;
+ GeglNode *output;
+
+ node = gegl_node_new ();
+
+ input = gegl_node_get_input_proxy (node, "input");
+
+ translate_before = gegl_node_new_child (
+ node,
+ "operation", "gegl:translate",
+ "x", -(source_core->src_x + 0.5),
+ "y", -(source_core->src_y + 0.5),
+ NULL);
+
+ gegl_node_add_child (node, op);
+
+ translate_after = gegl_node_new_child (
+ node,
+ "operation", "gegl:translate",
+ "x", (source_core->src_x + 0.5) +
+ (paint_area_offset_x - src_rect.x),
+ "y", (source_core->src_y + 0.5) +
+ (paint_area_offset_y - src_rect.y),
+ NULL);
+
+ output = gegl_node_get_output_proxy (node, "output");
+
+ gegl_node_link_many (input,
+ translate_before,
+ op,
+ translate_after,
+ output,
+ NULL);
+
+ g_object_unref (op);
+
+ op = node;
+ }
+
GIMP_SOURCE_CORE_GET_CLASS (source_core)->motion (source_core,
drawable,
paint_options,
@@ -502,8 +545,9 @@ gimp_source_core_motion (GimpSourceCore *source_core,
paint_area_width,
paint_area_height);
- if (src_buffer)
- g_object_unref (src_buffer);
+ g_clear_object (&op);
+
+ g_clear_object (&src_buffer);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]