[gimp/metadata-browser] app: don't create copies in gimp_paint_core_get_orig_image, proj()



commit 9934c687ac5297eb9fc057421e77b2994611709a
Author: Michael Natterer <mitch gimp org>
Date:   Sat Mar 31 15:40:21 2012 +0200

    app: don't create copies in gimp_paint_core_get_orig_image,proj()
    
    and instead simply return the paint_core owned buffers. Also, move
    graph creation and source buffer fiddling out of perspective clone's
    inner loop, and set an area to be processed manually, which makes it
    responsive again.

 app/paint/gimpclone.c            |    8 +-
 app/paint/gimpdodgeburn.c        |    3 +-
 app/paint/gimpheal.c             |    8 ++-
 app/paint/gimppaintcore.c        |   93 +---------------------------
 app/paint/gimppaintcore.h        |   16 +----
 app/paint/gimpperspectiveclone.c |  126 ++++++++++++++++++-------------------
 app/paint/gimpperspectiveclone.h |   23 ++++---
 app/paint/gimpsourcecore.c       |   35 ++++------
 app/paint/gimpsourcecore.h       |    4 +-
 9 files changed, 107 insertions(+), 209 deletions(-)
---
diff --git a/app/paint/gimpclone.c b/app/paint/gimpclone.c
index c684755..8b7ad9f 100644
--- a/app/paint/gimpclone.c
+++ b/app/paint/gimpclone.c
@@ -26,11 +26,8 @@
 
 #include "paint-types.h"
 
-#include "base/pixel-region.h"
 #include "base/temp-buf.h"
 
-#include "paint-funcs/paint-funcs.h"
-
 #include "gegl/gimp-gegl-utils.h"
 
 #include "core/gimp.h"
@@ -61,6 +58,7 @@ static void       gimp_clone_motion (GimpSourceCore   *source_core,
                                      gdouble           opacity,
                                      GimpPickable     *src_pickable,
                                      GeglBuffer       *src_buffer,
+                                     GeglRectangle    *src_rect,
                                      gint              src_offset_x,
                                      gint              src_offset_y,
                                      TempBuf          *paint_area,
@@ -140,6 +138,7 @@ gimp_clone_motion (GimpSourceCore   *source_core,
                    gdouble           opacity,
                    GimpPickable     *src_pickable,
                    GeglBuffer       *src_buffer,
+                   GeglRectangle    *src_rect,
                    gint              src_offset_x,
                    gint              src_offset_y,
                    TempBuf          *paint_area,
@@ -173,7 +172,8 @@ gimp_clone_motion (GimpSourceCore   *source_core,
     case GIMP_IMAGE_CLONE:
       {
         gegl_buffer_copy (src_buffer,
-                          GIMP_GEGL_RECT (0, 0,
+                          GIMP_GEGL_RECT (src_rect->x,
+                                          src_rect->y,
                                           paint_area_width,
                                           paint_area_height),
                           dest_buffer,
diff --git a/app/paint/gimpdodgeburn.c b/app/paint/gimpdodgeburn.c
index 71b6e4a..4d0a6aa 100644
--- a/app/paint/gimpdodgeburn.c
+++ b/app/paint/gimpdodgeburn.c
@@ -223,13 +223,14 @@ gimp_dodge_burn_motion (GimpPaintCore    *paint_core,
       {
         return;
       }
-
+#if 0
     /*  get the original untouched image  */
     orig = gimp_paint_core_get_orig_image (paint_core, drawable,
                                            x, y, width, height);
 
     pixel_region_init_temp_buf (&srcPR, orig,
                                 0, 0, width, height);
+#endif
   }
 
   /* tempPR will hold the dodgeburned region */
diff --git a/app/paint/gimpheal.c b/app/paint/gimpheal.c
index aded3ba..07a6e9b 100644
--- a/app/paint/gimpheal.c
+++ b/app/paint/gimpheal.c
@@ -105,6 +105,7 @@ static void         gimp_heal_motion             (GimpSourceCore   *source_core,
                                                   gdouble           opacity,
                                                   GimpPickable     *src_pickable,
                                                   GeglBuffer       *src_buffer,
+                                                  GeglRectangle    *src_rect,
                                                   gint              src_offset_x,
                                                   gint              src_offset_y,
                                                   TempBuf          *paint_area,
@@ -443,6 +444,7 @@ gimp_heal_motion (GimpSourceCore   *source_core,
                   gdouble           opacity,
                   GimpPickable     *src_pickable,
                   GeglBuffer       *src_buffer,
+                  GeglRectangle    *src_rect,
                   gint              src_offset_x,
                   gint              src_offset_y,
                   TempBuf          *paint_area,
@@ -484,8 +486,7 @@ gimp_heal_motion (GimpSourceCore   *source_core,
   {
     GeglBuffer *tmp;
 
-    src_temp_buf = temp_buf_new (gegl_buffer_get_width (src_buffer),
-                                 gegl_buffer_get_height (src_buffer),
+    src_temp_buf = temp_buf_new (src_rect->width, src_rect->height,
                                  gimp_drawable_bytes_with_alpha (drawable),
                                  0, 0, NULL);
 
@@ -499,7 +500,8 @@ gimp_heal_motion (GimpSourceCore   *source_core,
                                         src_temp_buf->bytes,
                                         NULL, NULL);
 
-    gegl_buffer_copy (src_buffer, NULL, tmp, NULL);
+    gegl_buffer_copy (src_buffer, src_rect,
+                      tmp, GIMP_GEGL_RECT (0, 0, 0, 0));
     g_object_unref (tmp);
   }
 
diff --git a/app/paint/gimppaintcore.c b/app/paint/gimppaintcore.c
index 0fb7361..55e0d04 100644
--- a/app/paint/gimppaintcore.c
+++ b/app/paint/gimppaintcore.c
@@ -548,18 +548,6 @@ gimp_paint_core_cleanup (GimpPaintCore *core)
       core->canvas_buffer = NULL;
     }
 
-  if (core->orig_buf)
-    {
-      g_object_unref (core->orig_buf);
-      core->orig_buf = NULL;
-    }
-
-  if (core->orig_proj_buf)
-    {
-      g_object_unref (core->orig_proj_buf);
-      core->orig_proj_buf = NULL;
-    }
-
   if (core->canvas_buf)
     {
       temp_buf_free (core->canvas_buf);
@@ -684,94 +672,21 @@ gimp_paint_core_get_paint_area (GimpPaintCore    *core,
 }
 
 GeglBuffer *
-gimp_paint_core_get_orig_image (GimpPaintCore *core,
-                                GimpDrawable  *drawable,
-                                gint           x,
-                                gint           y,
-                                gint           width,
-                                gint           height)
+gimp_paint_core_get_orig_image (GimpPaintCore *core)
 {
-  gint orig_x = x;
-  gint orig_y = y;
-
   g_return_val_if_fail (GIMP_IS_PAINT_CORE (core), NULL);
-  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
   g_return_val_if_fail (core->undo_buffer != NULL, NULL);
 
-  if (core->orig_buf &&
-      (gegl_buffer_get_width  (core->orig_buf) != width ||
-       gegl_buffer_get_height (core->orig_buf) != height))
-    {
-      g_object_unref (core->orig_buf);
-      core->orig_buf = NULL;
-    }
-
-  if (! core->orig_buf)
-    core->orig_buf = gegl_buffer_new (GIMP_GEGL_RECT (0, 0, width, height),
-                                      gimp_drawable_get_format (drawable));
-
-  gimp_rectangle_intersect (x, y,
-                            width, height,
-                            0, 0,
-                            gimp_item_get_width  (GIMP_ITEM (drawable)),
-                            gimp_item_get_height (GIMP_ITEM (drawable)),
-                            &x, &y,
-                            &width, &height);
-
-  gegl_buffer_copy (core->undo_buffer,
-                    GIMP_GEGL_RECT (x, y, width, height),
-                    core->orig_buf,
-                    GIMP_GEGL_RECT (x - orig_x, y - orig_y,
-                                    width, height));
-
-  return core->orig_buf;
+  return core->undo_buffer;
 }
 
 GeglBuffer *
-gimp_paint_core_get_orig_proj (GimpPaintCore *core,
-                               GimpPickable  *pickable,
-                               gint           x,
-                               gint           y,
-                               gint           width,
-                               gint           height)
+gimp_paint_core_get_orig_proj (GimpPaintCore *core)
 {
-  GeglBuffer *pickable_buffer;
-  gint        orig_x = x;
-  gint        orig_y = y;
-
   g_return_val_if_fail (GIMP_IS_PAINT_CORE (core), NULL);
-  g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), NULL);
   g_return_val_if_fail (core->saved_proj_buffer != NULL, NULL);
 
-  if (core->orig_proj_buf &&
-      (gegl_buffer_get_width  (core->orig_proj_buf) != width ||
-       gegl_buffer_get_height (core->orig_proj_buf) != height))
-    {
-      g_object_unref (core->orig_proj_buf);
-      core->orig_proj_buf = NULL;
-    }
-
-  if (! core->orig_proj_buf)
-    core->orig_proj_buf = gegl_buffer_new (GIMP_GEGL_RECT (0, 0, width, height),
-                                           gimp_pickable_get_format (pickable));
-
-  pickable_buffer = gimp_pickable_get_buffer (pickable);
-
-  gimp_rectangle_intersect (x, y,
-                            width, height,
-                            0, 0,
-                            gegl_buffer_get_width  (pickable_buffer),
-                            gegl_buffer_get_height (pickable_buffer),
-                            &x, &y,
-                            &width, &height);
-
-  gegl_buffer_copy (core->saved_proj_buffer,
-                    GIMP_GEGL_RECT (x, y, width, height),
-                    core->orig_proj_buf,
-                    GIMP_GEGL_RECT (x - orig_x, y - orig_y,
-                                    width, height));
-
-  return core->orig_proj_buf;
+  return core->saved_proj_buffer;
 }
 
 void
diff --git a/app/paint/gimppaintcore.h b/app/paint/gimppaintcore.h
index b99349c..a05f158 100644
--- a/app/paint/gimppaintcore.h
+++ b/app/paint/gimppaintcore.h
@@ -59,8 +59,6 @@ struct _GimpPaintCore
   GeglBuffer  *saved_proj_buffer; /*  proj tiles which have been modified */
   GeglBuffer  *canvas_buffer;     /*  the buffer to paint the mask to     */
 
-  GeglBuffer  *orig_buf;          /*  the unmodified drawable pixels      */
-  GeglBuffer  *orig_proj_buf;     /*  the unmodified projection pixels    */
   TempBuf     *canvas_buf;        /*  the buffer to paint pixels to       */
 
   GArray      *stroke_buffer;
@@ -157,18 +155,8 @@ TempBuf    * gimp_paint_core_get_paint_area         (GimpPaintCore    *core,
                                                      GimpDrawable     *drawable,
                                                      GimpPaintOptions *options,
                                                      const GimpCoords *coords);
-GeglBuffer * gimp_paint_core_get_orig_image         (GimpPaintCore    *core,
-                                                     GimpDrawable     *drawable,
-                                                     gint              x,
-                                                     gint              y,
-                                                     gint              width,
-                                                     gint              height);
-GeglBuffer * gimp_paint_core_get_orig_proj          (GimpPaintCore    *core,
-                                                     GimpPickable     *pickable,
-                                                     gint              x,
-                                                     gint              y,
-                                                     gint              width,
-                                                     gint              height);
+GeglBuffer * gimp_paint_core_get_orig_image         (GimpPaintCore    *core);
+GeglBuffer * gimp_paint_core_get_orig_proj          (GimpPaintCore    *core);
 
 void      gimp_paint_core_paste             (GimpPaintCore            *core,
                                              PixelRegion              *paint_maskPR,
diff --git a/app/paint/gimpperspectiveclone.c b/app/paint/gimpperspectiveclone.c
index 4267530..1b07a31 100644
--- a/app/paint/gimpperspectiveclone.c
+++ b/app/paint/gimpperspectiveclone.c
@@ -67,7 +67,8 @@ static GeglBuffer * gimp_perspective_clone_get_source (GimpSourceCore   *source_
                                                        gint             *paint_area_offset_x,
                                                        gint             *paint_area_offset_y,
                                                        gint             *paint_area_width,
-                                                       gint             *paint_area_height);
+                                                       gint             *paint_area_height,
+                                                       GeglRectangle    *src_rect);
 
 static void         gimp_perspective_clone_get_matrix (GimpPerspectiveClone *clone,
                                                        GimpMatrix3          *matrix);
@@ -176,6 +177,11 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
         }
       else
         {
+          GimpPickable *src_pickable;
+          GimpImage    *src_image;
+          GimpImage    *dest_image;
+          GeglBuffer   *orig_buffer;
+
           if (options->align_mode == GIMP_SOURCE_ALIGN_NO)
             {
               source_core->orig_src_x = source_core->src_x;
@@ -184,6 +190,35 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
               source_core->first_stroke = TRUE;
             }
 
+          /*  If the source image is different from the destination,
+           *  then we should copy straight from the source image
+           *  to the canvas.
+           *  Otherwise, we need a call to get_orig_image to make sure
+           *  we get a copy of the unblemished (offset) image
+           */
+          src_pickable = GIMP_PICKABLE (source_core->src_drawable);
+          src_image    = gimp_pickable_get_image (src_pickable);
+
+          if (options->sample_merged)
+            src_pickable = GIMP_PICKABLE (gimp_image_get_projection (src_image));
+
+          dest_image = gimp_item_get_image (GIMP_ITEM (drawable));
+
+          if ((options->sample_merged &&
+               (src_image != dest_image)) ||
+              (! options->sample_merged &&
+               (source_core->src_drawable != drawable)))
+            {
+              orig_buffer = gimp_pickable_get_buffer (src_pickable);
+            }
+          else
+            {
+              if (options->sample_merged)
+                orig_buffer = gimp_paint_core_get_orig_proj (paint_core);
+              else
+                orig_buffer = gimp_paint_core_get_orig_image (paint_core);
+            }
+
           clone->node = gegl_node_new ();
 
           g_object_set (clone->node,
@@ -193,12 +228,13 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
           clone->src_node =
             gegl_node_new_child (clone->node,
                                  "operation", "gegl:buffer-source",
+                                 "buffer",    orig_buffer,
                                   NULL);
 
           clone->transform_node =
             gegl_node_new_child (clone->node,
                                  "operation",  "gegl:transform",
-                                 "filter",     gimp_interpolation_to_gegl_filter (GIMP_INTERPOLATION_NONE),
+                                 "filter",     gimp_interpolation_to_gegl_filter (GIMP_INTERPOLATION_LINEAR),
                                  "hard-edges", TRUE,
                                  NULL);
 
@@ -211,6 +247,8 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
                                clone->transform_node,
                                clone->dest_node,
                                NULL);
+
+          clone->processor = gegl_node_new_processor (clone->dest_node, NULL);
         }
       break;
 
@@ -274,10 +312,12 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
       if (clone->node)
         {
           g_object_unref (clone->node);
+          g_object_unref (clone->processor);
           clone->node = NULL;
           clone->src_node = NULL;
           clone->transform_node = NULL;
           clone->dest_node = NULL;
+          clone->processor = NULL;
         }
       break;
 
@@ -300,29 +340,22 @@ gimp_perspective_clone_get_source (GimpSourceCore   *source_core,
                                    gint             *paint_area_offset_x,
                                    gint             *paint_area_offset_y,
                                    gint             *paint_area_width,
-                                   gint             *paint_area_height)
+                                   gint             *paint_area_height,
+                                   GeglRectangle    *src_rect)
 {
-  GimpPerspectiveClone *clone      = GIMP_PERSPECTIVE_CLONE (source_core);
-  GimpPaintCore        *paint_core = GIMP_PAINT_CORE (source_core);
-  GimpSourceOptions    *options    = GIMP_SOURCE_OPTIONS (paint_options);
-  GimpImage            *src_image;
-  GimpImage            *image;
+  GimpPerspectiveClone *clone = GIMP_PERSPECTIVE_CLONE (source_core);
+  GeglBuffer           *src_buffer;
+  GeglBuffer           *dest_buffer;
   const Babl           *src_format_alpha;
   gint                  x1d, y1d, x2d, y2d;
   gdouble               x1s, y1s, x2s, y2s, x3s, y3s, x4s, y4s;
   gint                  xmin, ymin, xmax, ymax;
-  GeglBuffer           *src_buffer;
-  GeglBuffer           *orig_buffer;
-  GeglBuffer           *dest_buffer;
   GimpMatrix3           matrix;
   gchar                *matrix_string;
   GimpMatrix3           gegl_matrix;
 
-  src_image = gimp_pickable_get_image (src_pickable);
-  image     = gimp_item_get_image (GIMP_ITEM (drawable));
-
-  src_format_alpha = gimp_pickable_get_format_with_alpha (src_pickable);
   src_buffer       = gimp_pickable_get_buffer (src_pickable);
+  src_format_alpha = gimp_pickable_get_format_with_alpha (src_pickable);
 
   /* Destination coordinates that will be painted */
   x1d = paint_area->x;
@@ -344,51 +377,15 @@ gimp_perspective_clone_get_source (GimpSourceCore   *source_core,
   xmax = ceil  (MAX4 (x1s, x2s, x3s, x4s));
   ymax = ceil  (MAX4 (y1s, y2s, y3s, y4s));
 
-  xmin = CLAMP (xmin - 1, 0, gegl_buffer_get_width  (src_buffer));
-  ymin = CLAMP (ymin - 1, 0, gegl_buffer_get_height (src_buffer));
-  xmax = CLAMP (xmax + 1, 0, gegl_buffer_get_width  (src_buffer));
-  ymax = CLAMP (ymax + 1, 0, gegl_buffer_get_height (src_buffer));
-
-  /* if the source area is completely out of the image */
-  if (!(xmax - xmin) || !(ymax - ymin))
-    return FALSE;
-
-  /*  If the source image is different from the destination,
-   *  then we should copy straight from the source image
-   *  to the canvas.
-   *  Otherwise, we need a call to get_orig_image to make sure
-   *  we get a copy of the unblemished (offset) image
-   */
-  if ((  options->sample_merged && (src_image                 != image)) ||
-      (! options->sample_merged && (source_core->src_drawable != drawable)))
+  if (! gimp_rectangle_intersect (xmin, ymin,
+                                  xmax - xmin, ymax - ymin,
+                                  0, 0,
+                                  gegl_buffer_get_width  (src_buffer),
+                                  gegl_buffer_get_height (src_buffer),
+                                  NULL, NULL, NULL, NULL))
     {
-      orig_buffer = gegl_buffer_new (GIMP_GEGL_RECT (0, 0,
-                                                     xmax - xmin, ymax - ymin),
-                                     src_format_alpha);
-
-      gegl_buffer_copy (src_buffer,
-                        GIMP_GEGL_RECT (xmin, ymin,
-                                        xmax - xmin, ymax - ymin),
-                        orig_buffer,
-                        GIMP_GEGL_RECT (0, 0, 0, 0));
-    }
-  else
-    {
-      /*  get the original image  */
-      if (options->sample_merged)
-        orig_buffer = gimp_paint_core_get_orig_proj (paint_core,
-                                                     src_pickable,
-                                                     xmin, ymin,
-                                                     xmax - xmin,
-                                                     ymax - ymin);
-      else
-        orig_buffer = gimp_paint_core_get_orig_image (paint_core,
-                                                      GIMP_DRAWABLE (src_pickable),
-                                                      xmin, ymin,
-                                                      xmax - xmin,
-                                                      ymax - ymin);
-
-      g_object_ref (orig_buffer);
+      /* if the source area is completely out of the image */
+      return FALSE;
     }
 
   dest_buffer = gegl_buffer_new (GIMP_GEGL_RECT (0, 0, x2d - x1d, y2d - y1d),
@@ -398,7 +395,6 @@ gimp_perspective_clone_get_source (GimpSourceCore   *source_core,
   gimp_perspective_clone_get_matrix (clone, &matrix);
 
   gimp_matrix3_identity (&gegl_matrix);
-  gimp_matrix3_translate (&gegl_matrix, xmin, ymin);
   gimp_matrix3_mult (&matrix, &gegl_matrix);
   gimp_matrix3_translate (&gegl_matrix, -x1d, -y1d);
 
@@ -408,16 +404,16 @@ gimp_perspective_clone_get_source (GimpSourceCore   *source_core,
                  NULL);
   g_free (matrix_string);
 
-  gegl_node_set (clone->src_node,
-                 "buffer", orig_buffer,
-                 NULL);
   gegl_node_set (clone->dest_node,
                  "buffer", dest_buffer,
                  NULL);
 
-  gegl_node_process (clone->dest_node);
+  gegl_processor_set_rectangle (clone->processor,
+                                GIMP_GEGL_RECT (0, 0,
+                                                x2d - x1d, y2d - y1d));
+  while (gegl_processor_work (clone->processor, NULL));
 
-  g_object_unref (orig_buffer);
+  *src_rect = *GIMP_GEGL_RECT (0, 0, x2d - x1d, y2d - y1d);
 
   return dest_buffer;
 }
diff --git a/app/paint/gimpperspectiveclone.h b/app/paint/gimpperspectiveclone.h
index a3d56f0..629eea8 100644
--- a/app/paint/gimpperspectiveclone.h
+++ b/app/paint/gimpperspectiveclone.h
@@ -34,21 +34,22 @@ typedef struct _GimpPerspectiveCloneClass GimpPerspectiveCloneClass;
 
 struct _GimpPerspectiveClone
 {
-  GimpClone    parent_instance;
+  GimpClone      parent_instance;
 
-  gdouble      src_x_fv;     /* source coords in front_view perspective */
-  gdouble      src_y_fv;
+  gdouble        src_x_fv;     /* source coords in front_view perspective */
+  gdouble        src_y_fv;
 
-  gdouble      dest_x_fv;    /* destination coords in front_view perspective */
-  gdouble      dest_y_fv;
+  gdouble        dest_x_fv;    /* destination coords in front_view perspective */
+  gdouble        dest_y_fv;
 
-  GimpMatrix3  transform;
-  GimpMatrix3  transform_inv;
+  GimpMatrix3    transform;
+  GimpMatrix3    transform_inv;
 
-  GeglNode    *node;
-  GeglNode    *src_node;
-  GeglNode    *transform_node;
-  GeglNode    *dest_node;
+  GeglNode      *node;
+  GeglNode      *src_node;
+  GeglNode      *transform_node;
+  GeglNode      *dest_node;
+  GeglProcessor *processor;
 };
 
 struct _GimpPerspectiveCloneClass
diff --git a/app/paint/gimpsourcecore.c b/app/paint/gimpsourcecore.c
index d3f75ac..6fa09b7 100644
--- a/app/paint/gimpsourcecore.c
+++ b/app/paint/gimpsourcecore.c
@@ -89,7 +89,8 @@ static GeglBuffer *
                                                   gint             *paint_area_offset_x,
                                                   gint             *paint_area_offset_y,
                                                   gint             *paint_area_width,
-                                                  gint             *paint_area_height);
+                                                  gint             *paint_area_height,
+                                                  GeglRectangle    *src_rect);
 
 static void    gimp_source_core_set_src_drawable (GimpSourceCore   *source_core,
                                                   GimpDrawable     *drawable);
@@ -352,6 +353,7 @@ gimp_source_core_motion (GimpSourceCore   *source_core,
   GimpImage          *image        = gimp_item_get_image (GIMP_ITEM (drawable));
   GimpPickable       *src_pickable = NULL;
   GeglBuffer         *src_buffer   = NULL;
+  GeglRectangle       src_rect;
   gint                src_offset_x;
   gint                src_offset_y;
   TempBuf            *paint_area;
@@ -422,7 +424,8 @@ gimp_source_core_motion (GimpSourceCore   *source_core,
                                                               &paint_area_offset_x,
                                                               &paint_area_offset_y,
                                                               &paint_area_width,
-                                                              &paint_area_height);
+                                                              &paint_area_height,
+                                                              &src_rect);
       if (! src_buffer)
         return;
     }
@@ -437,6 +440,7 @@ gimp_source_core_motion (GimpSourceCore   *source_core,
                                                     opacity,
                                                     src_pickable,
                                                     src_buffer,
+                                                    &src_rect,
                                                     src_offset_x,
                                                     src_offset_y,
                                                     paint_area,
@@ -460,7 +464,8 @@ gimp_source_core_real_get_source (GimpSourceCore   *source_core,
                                   gint             *paint_area_offset_x,
                                   gint             *paint_area_offset_y,
                                   gint             *paint_area_width,
-                                  gint             *paint_area_height)
+                                  gint             *paint_area_height,
+                                  GeglRectangle    *src_rect)
 {
   GimpSourceOptions *options    = GIMP_SOURCE_OPTIONS (paint_options);
   GimpImage         *image      = gimp_item_get_image (GIMP_ITEM (drawable));
@@ -492,29 +497,15 @@ gimp_source_core_real_get_source (GimpSourceCore   *source_core,
   if ((  options->sample_merged && (src_image                 != image)) ||
       (! options->sample_merged && (source_core->src_drawable != drawable)))
     {
-      dest_buffer = gegl_buffer_new (GIMP_GEGL_RECT (0, 0, width, height),
-                                     gimp_pickable_get_format (src_pickable));
-
-      gegl_buffer_copy (src_buffer,
-                        GIMP_GEGL_RECT (x, y, width, height),
-                        dest_buffer,
-                        GIMP_GEGL_RECT (0, 0, 0, 0));
+      dest_buffer = src_buffer;
     }
   else
     {
       /*  get the original image  */
       if (options->sample_merged)
-        dest_buffer =
-          gimp_paint_core_get_orig_proj (GIMP_PAINT_CORE (source_core),
-                                         src_pickable,
-                                         x, y, width, height);
+        dest_buffer = gimp_paint_core_get_orig_proj (GIMP_PAINT_CORE (source_core));
       else
-        dest_buffer =
-          gimp_paint_core_get_orig_image (GIMP_PAINT_CORE (source_core),
-                                          GIMP_DRAWABLE (src_pickable),
-                                          x, y, width, height);
-
-      g_object_ref (dest_buffer);
+        dest_buffer = gimp_paint_core_get_orig_image (GIMP_PAINT_CORE (source_core));
     }
 
   *paint_area_offset_x = x - (paint_area->x + src_offset_x);
@@ -522,7 +513,9 @@ gimp_source_core_real_get_source (GimpSourceCore   *source_core,
   *paint_area_width    = width;
   *paint_area_height   = height;
 
-  return dest_buffer;
+  *src_rect = *GIMP_GEGL_RECT (x, y, width, height);
+
+  return g_object_ref (dest_buffer);
 }
 
 static void
diff --git a/app/paint/gimpsourcecore.h b/app/paint/gimpsourcecore.h
index 6e50b91..e581b70 100644
--- a/app/paint/gimpsourcecore.h
+++ b/app/paint/gimpsourcecore.h
@@ -64,7 +64,8 @@ struct _GimpSourceCoreClass
                                gint             *paint_area_offset_x,
                                gint             *paint_area_offset_y,
                                gint             *paint_area_width,
-                               gint             *paint_area_height);
+                               gint             *paint_area_height,
+                               GeglRectangle    *src_rect);
 
   void         (*  motion)    (GimpSourceCore   *source_core,
                                GimpDrawable     *drawable,
@@ -73,6 +74,7 @@ struct _GimpSourceCoreClass
                                gdouble           opacity,
                                GimpPickable     *src_pickable,
                                GeglBuffer       *src_buffer,
+                               GeglRectangle    *src_rect,
                                gint              src_offset_x,
                                gint              src_offset_y,
                                TempBuf          *paint_area,



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