[gimp] Issue #1942 - Smudge Tool with Sample Merged Option



commit 34cad3a06e5c5f77b964534fe436082e48301684
Author: Michael Natterer <mitch gimp org>
Date:   Sun Jan 20 17:48:04 2019 +0100

    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.

 app/paint/gimpsmudge.c        | 113 ++++++++++++++++++++++++++++++------------
 app/paint/gimpsmudgeoptions.c |  14 ++++++
 app/paint/gimpsmudgeoptions.h |   1 +
 app/tools/gimpsmudgetool.c    |   4 ++
 4 files changed, 100 insertions(+), 32 deletions(-)
---
diff --git a/app/paint/gimpsmudge.c b/app/paint/gimpsmudge.c
index e5be54e8ca..5d11a78b6d 100644
--- a/app/paint/gimpsmudge.c
+++ b/app/paint/gimpsmudge.c
@@ -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;
-
-          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),
+          gint       pick_x;
+          gint       pick_y;
+
+          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,
diff --git a/app/paint/gimpsmudgeoptions.c b/app/paint/gimpsmudgeoptions.c
index ac0a75088a..cdf6f0b2a1 100644
--- a/app/paint/gimpsmudgeoptions.c
+++ b/app/paint/gimpsmudgeoptions.c
@@ -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);
diff --git a/app/paint/gimpsmudgeoptions.h b/app/paint/gimpsmudgeoptions.h
index 096a416688..910ff52e46 100644
--- a/app/paint/gimpsmudgeoptions.h
+++ b/app/paint/gimpsmudgeoptions.h
@@ -39,6 +39,7 @@ struct _GimpSmudgeOptions
   gdouble           rate;
   gdouble           flow;
   gboolean          no_erasing;
+  gboolean          sample_merged;
 };
 
 struct _GimpSmudgeOptionsClass
diff --git a/app/tools/gimpsmudgetool.c b/app/tools/gimpsmudgetool.c
index ca9e64c538..d6c5f65f13 100644
--- a/app/tools/gimpsmudgetool.c
+++ b/app/tools/gimpsmudgetool.c
@@ -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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]