[gimp] Bug 533590 - Perspective clone of a pattern doesn't apply perspective



commit 66bd90c9f2f737f27365ce1e1282b654f040ba28
Author: Michael Natterer <mitch gimp org>
Date:   Thu Nov 1 21:39:14 2012 +0100

    Bug 533590 - Perspective clone of a pattern doesn't apply perspective
    
    Implement perspective cloning from a pattern. This needed quite some
    refactoring, so GimpSourceCore would be able call its get_source()
    vfunc also for a GimpClone subclass: essentially this commit adds a
    new GimpSourceCore::use_source() vfunc that replaces the
    source_options->use_source flag hack, and makes sure the graph used in
    GimpPerspectiveClone's get_source() impl reads from the pattern
    instead the drawable.
    
    This version does not properly tile the pattern yet, so you can only
    clone one copy of the pattern (gegl:tile is not quite doing the right
    thing, so it's disabled).

 app/paint/gimpclone.c                |  125 ++++++++++++-----------
 app/paint/gimpcloneoptions.c         |   15 ---
 app/paint/gimpperspectiveclone.c     |  189 +++++++++++++++++++++-------------
 app/paint/gimpperspectiveclone.h     |    1 -
 app/paint/gimpsourcecore.c           |  107 +++++++++++--------
 app/paint/gimpsourcecore.h           |   80 ++++++++-------
 app/paint/gimpsourceoptions.c        |    1 -
 app/paint/gimpsourceoptions.h        |    2 -
 app/tools/gimpperspectiveclonetool.c |   25 ++---
 app/tools/gimpsourcetool.c           |   29 +++--
 10 files changed, 317 insertions(+), 257 deletions(-)
---
diff --git a/app/paint/gimpclone.c b/app/paint/gimpclone.c
index 8b0bc5b..49f928c 100644
--- a/app/paint/gimpclone.c
+++ b/app/paint/gimpclone.c
@@ -40,29 +40,32 @@
 #include "gimp-intl.h"
 
 
-static gboolean   gimp_clone_start  (GimpPaintCore    *paint_core,
-                                     GimpDrawable     *drawable,
-                                     GimpPaintOptions *paint_options,
-                                     const GimpCoords *coords,
-                                     GError          **error);
-
-static void       gimp_clone_motion (GimpSourceCore   *source_core,
-                                     GimpDrawable     *drawable,
-                                     GimpPaintOptions *paint_options,
-                                     const GimpCoords *coords,
-                                     gdouble           opacity,
-                                     GimpPickable     *src_pickable,
-                                     GeglBuffer       *src_buffer,
-                                     GeglRectangle    *src_rect,
-                                     gint              src_offset_x,
-                                     gint              src_offset_y,
-                                     GeglBuffer       *paint_buffer,
-                                     gint              paint_buffer_x,
-                                     gint              paint_buffer_y,
-                                     gint              paint_area_offset_x,
-                                     gint              paint_area_offset_y,
-                                     gint              paint_area_width,
-                                     gint              paint_area_height);
+static gboolean   gimp_clone_start      (GimpPaintCore     *paint_core,
+                                         GimpDrawable      *drawable,
+                                         GimpPaintOptions  *paint_options,
+                                         const GimpCoords  *coords,
+                                         GError           **error);
+
+static void       gimp_clone_motion     (GimpSourceCore    *source_core,
+                                         GimpDrawable      *drawable,
+                                         GimpPaintOptions  *paint_options,
+                                         const GimpCoords  *coords,
+                                         gdouble            opacity,
+                                         GimpPickable      *src_pickable,
+                                         GeglBuffer        *src_buffer,
+                                         GeglRectangle     *src_rect,
+                                         gint               src_offset_x,
+                                         gint               src_offset_y,
+                                         GeglBuffer        *paint_buffer,
+                                         gint               paint_buffer_x,
+                                         gint               paint_buffer_y,
+                                         gint               paint_area_offset_x,
+                                         gint               paint_area_offset_y,
+                                         gint               paint_area_width,
+                                         gint               paint_area_height);
+
+static gboolean   gimp_clone_use_source (GimpSourceCore    *source_core,
+                                         GimpSourceOptions *options);
 
 
 G_DEFINE_TYPE (GimpClone, gimp_clone, GIMP_TYPE_SOURCE_CORE)
@@ -88,9 +91,10 @@ gimp_clone_class_init (GimpCloneClass *klass)
   GimpPaintCoreClass  *paint_core_class  = GIMP_PAINT_CORE_CLASS (klass);
   GimpSourceCoreClass *source_core_class = GIMP_SOURCE_CORE_CLASS (klass);
 
-  paint_core_class->start   = gimp_clone_start;
+  paint_core_class->start       = gimp_clone_start;
 
-  source_core_class->motion = gimp_clone_motion;
+  source_core_class->use_source = gimp_clone_use_source;
+  source_core_class->motion     = gimp_clone_motion;
 }
 
 static void
@@ -154,41 +158,37 @@ gimp_clone_motion (GimpSourceCore   *source_core,
   gdouble            fade_point;
   gdouble            force;
 
-  switch (options->clone_type)
+  if (gimp_source_core_use_source (source_core, source_options))
     {
-    case GIMP_IMAGE_CLONE:
-      {
-        gegl_buffer_copy (src_buffer,
-                          GEGL_RECTANGLE (src_rect->x,
-                                          src_rect->y,
-                                          paint_area_width,
-                                          paint_area_height),
-                          paint_buffer,
-                          GEGL_RECTANGLE (paint_area_offset_x,
-                                          paint_area_offset_y,
-                                          0, 0));
-      }
-      break;
-
-    case GIMP_PATTERN_CLONE:
-      {
-        /* XXX: move this to INIT */
-        GimpPattern *pattern    = gimp_context_get_pattern (context);
-        GeglBuffer  *src_buffer = gimp_pattern_create_buffer (pattern);
-
-        gegl_buffer_set_pattern (paint_buffer,
-                                 GEGL_RECTANGLE (paint_area_offset_x,
-                                                 paint_area_offset_y,
-                                                 paint_area_width,
-                                                 paint_area_height),
-                                 src_buffer,
-                                 - paint_buffer_x - src_offset_x,
-                                 - paint_buffer_y - src_offset_y);
-
-        /* XXX: move this to FINISH */
-        g_object_unref (src_buffer);
-      }
-      break;
+      gegl_buffer_copy (src_buffer,
+                        GEGL_RECTANGLE (src_rect->x,
+                                        src_rect->y,
+                                        paint_area_width,
+                                        paint_area_height),
+                        paint_buffer,
+                        GEGL_RECTANGLE (paint_area_offset_x,
+                                        paint_area_offset_y,
+                                        0, 0));
+    }
+  else if (options->clone_type == GIMP_PATTERN_CLONE)
+    {
+      GimpPattern *pattern    = gimp_context_get_pattern (context);
+      GeglBuffer  *src_buffer = gimp_pattern_create_buffer (pattern);
+
+      gegl_buffer_set_pattern (paint_buffer,
+                               GEGL_RECTANGLE (paint_area_offset_x,
+                                               paint_area_offset_y,
+                                               paint_area_width,
+                                               paint_area_height),
+                               src_buffer,
+                               - paint_buffer_x - src_offset_x,
+                               - paint_buffer_y - src_offset_y);
+
+      g_object_unref (src_buffer);
+    }
+  else
+    {
+      g_return_if_reached ();
     }
 
   fade_point = gimp_paint_options_get_fade (paint_options, image,
@@ -218,3 +218,10 @@ gimp_clone_motion (GimpSourceCore   *source_core,
                                 GIMP_SOURCE_ALIGN_FIXED ?
                                 GIMP_PAINT_INCREMENTAL : GIMP_PAINT_CONSTANT);
 }
+
+static gboolean
+gimp_clone_use_source (GimpSourceCore    *source_core,
+                       GimpSourceOptions *options)
+{
+  return GIMP_CLONE_OPTIONS (options)->clone_type == GIMP_IMAGE_CLONE;
+}
diff --git a/app/paint/gimpcloneoptions.c b/app/paint/gimpcloneoptions.c
index 683ce87..2a90ae0 100644
--- a/app/paint/gimpcloneoptions.c
+++ b/app/paint/gimpcloneoptions.c
@@ -43,8 +43,6 @@ static void   gimp_clone_options_get_property (GObject      *object,
                                                guint         property_id,
                                                GValue       *value,
                                                GParamSpec   *pspec);
-static void   gimp_clone_options_notify       (GObject      *object,
-                                               GParamSpec   *pspec);
 
 
 G_DEFINE_TYPE (GimpCloneOptions, gimp_clone_options, GIMP_TYPE_SOURCE_OPTIONS)
@@ -59,7 +57,6 @@ gimp_clone_options_class_init (GimpCloneOptionsClass *klass)
 
   object_class->set_property = gimp_clone_options_set_property;
   object_class->get_property = gimp_clone_options_get_property;
-  object_class->notify       = gimp_clone_options_notify;
 
   GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_CLONE_TYPE,
                                  "clone-type", NULL,
@@ -110,15 +107,3 @@ gimp_clone_options_get_property (GObject    *object,
       break;
     }
 }
-
-static void
-gimp_clone_options_notify (GObject    *object,
-                           GParamSpec *pspec)
-{
-  if (G_OBJECT_CLASS (parent_class)->notify)
-    G_OBJECT_CLASS (parent_class)->notify (object, pspec);
-
-  if (! strcmp ("clone-type", g_param_spec_get_name (pspec)))
-    GIMP_SOURCE_OPTIONS (object)->use_source =
-      (GIMP_CLONE_OPTIONS (object)->clone_type == GIMP_IMAGE_CLONE);
-}
diff --git a/app/paint/gimpperspectiveclone.c b/app/paint/gimpperspectiveclone.c
index ffc08a9..be5930a 100644
--- a/app/paint/gimpperspectiveclone.c
+++ b/app/paint/gimpperspectiveclone.c
@@ -35,6 +35,7 @@
 #include "core/gimpdrawable.h"
 #include "core/gimperror.h"
 #include "core/gimpimage.h"
+#include "core/gimppattern.h"
 #include "core/gimppickable.h"
 
 #include "gimpperspectiveclone.h"
@@ -43,27 +44,29 @@
 #include "gimp-intl.h"
 
 
-static void         gimp_perspective_clone_paint      (GimpPaintCore    *paint_core,
-                                                       GimpDrawable     *drawable,
-                                                       GimpPaintOptions *paint_options,
-                                                       const GimpCoords *coords,
-                                                       GimpPaintState    paint_state,
-                                                       guint32           time);
-
-static GeglBuffer * gimp_perspective_clone_get_source (GimpSourceCore   *source_core,
-                                                       GimpDrawable     *drawable,
-                                                       GimpPaintOptions *paint_options,
-                                                       GimpPickable     *src_pickable,
-                                                       gint              src_offset_x,
-                                                       gint              src_offset_y,
-                                                       GeglBuffer       *paint_buffer,
-                                                       gint              paint_buffer_x,
-                                                       gint              paint_buffer_y,
-                                                       gint             *paint_area_offset_x,
-                                                       gint             *paint_area_offset_y,
-                                                       gint             *paint_area_width,
-                                                       gint             *paint_area_height,
-                                                       GeglRectangle    *src_rect);
+static void         gimp_perspective_clone_paint      (GimpPaintCore     *paint_core,
+                                                       GimpDrawable      *drawable,
+                                                       GimpPaintOptions  *paint_options,
+                                                       const GimpCoords  *coords,
+                                                       GimpPaintState     paint_state,
+                                                       guint32            time);
+
+static gboolean     gimp_perspective_clone_use_source (GimpSourceCore    *source_core,
+                                                       GimpSourceOptions *options);
+static GeglBuffer * gimp_perspective_clone_get_source (GimpSourceCore    *source_core,
+                                                       GimpDrawable      *drawable,
+                                                       GimpPaintOptions  *paint_options,
+                                                       GimpPickable      *src_pickable,
+                                                       gint               src_offset_x,
+                                                       gint               src_offset_y,
+                                                       GeglBuffer        *paint_buffer,
+                                                       gint               paint_buffer_x,
+                                                       gint               paint_buffer_y,
+                                                       gint              *paint_area_offset_x,
+                                                       gint              *paint_area_offset_y,
+                                                       gint              *paint_area_width,
+                                                       gint              *paint_area_height,
+                                                       GeglRectangle     *src_rect);
 
 static void         gimp_perspective_clone_get_matrix (GimpPerspectiveClone *clone,
                                                        GimpMatrix3          *matrix);
@@ -95,6 +98,7 @@ gimp_perspective_clone_class_init (GimpPerspectiveCloneClass *klass)
 
   paint_core_class->paint       = gimp_perspective_clone_paint;
 
+  source_core_class->use_source = gimp_perspective_clone_use_source;
   source_core_class->get_source = gimp_perspective_clone_get_source;
 }
 
@@ -119,9 +123,11 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
                               GimpPaintState    paint_state,
                               guint32           time)
 {
-  GimpSourceCore       *source_core = GIMP_SOURCE_CORE (paint_core);
-  GimpPerspectiveClone *clone       = GIMP_PERSPECTIVE_CLONE (paint_core);
-  GimpSourceOptions    *options     = GIMP_SOURCE_OPTIONS (paint_options);
+  GimpSourceCore       *source_core   = GIMP_SOURCE_CORE (paint_core);
+  GimpPerspectiveClone *clone         = GIMP_PERSPECTIVE_CLONE (paint_core);
+  GimpContext          *context       = GIMP_CONTEXT (paint_options);
+  GimpCloneOptions     *clone_options = GIMP_CLONE_OPTIONS (paint_options);
+  GimpSourceOptions    *options       = GIMP_SOURCE_OPTIONS (paint_options);
 
   switch (paint_state)
     {
@@ -144,10 +150,9 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
         }
       else
         {
-          GimpPickable *src_pickable;
-          GimpImage    *src_image;
-          GimpImage    *dest_image;
-          GeglBuffer   *orig_buffer;
+          GeglBuffer *orig_buffer = NULL;
+          GeglNode   *tile        = NULL;
+          GeglNode   *src_node;
 
           if (options->align_mode == GIMP_SOURCE_ALIGN_NO)
             {
@@ -157,46 +162,68 @@ 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,
                         "dont-cache", TRUE,
                         NULL);
 
-          clone->src_node =
-            gegl_node_new_child (clone->node,
-                                 "operation", "gegl:buffer-source",
-                                 "buffer",    orig_buffer,
-                                  NULL);
+          switch (clone_options->clone_type)
+            {
+            case GIMP_IMAGE_CLONE:
+              {
+                GimpPickable *src_pickable;
+                GimpImage    *src_image;
+                GimpImage    *dest_image;
+
+                /*  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);
+                  }
+              }
+              break;
+
+            case GIMP_PATTERN_CLONE:
+              {
+                GimpPattern *pattern = gimp_context_get_pattern (context);
+
+                orig_buffer = gimp_pattern_create_buffer (pattern);
+
+                tile = gegl_node_new_child (clone->node,
+                                            "operation", "gegl:tile",
+                                            NULL);
+              }
+              break;
+            }
+
+          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,
@@ -210,10 +237,24 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
                                  "operation", "gegl:write-buffer",
                                  NULL);
 
-          gegl_node_link_many (clone->src_node,
-                               clone->transform_node,
-                               clone->dest_node,
-                               NULL);
+          if (tile)
+            {
+              gegl_node_link_many (src_node,
+#warning enable gegl:tile once it works
+                                   //tile,
+                                   clone->transform_node,
+                                   clone->dest_node,
+                                   NULL);
+
+              g_object_unref (orig_buffer);
+            }
+          else
+            {
+              gegl_node_link_many (src_node,
+                                   clone->transform_node,
+                                   clone->dest_node,
+                                   NULL);
+            }
 
           clone->processor = gegl_node_new_processor (clone->dest_node, NULL);
         }
@@ -280,11 +321,10 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
         {
           g_object_unref (clone->node);
           g_object_unref (clone->processor);
-          clone->node = NULL;
-          clone->src_node = NULL;
+          clone->node           = NULL;
           clone->transform_node = NULL;
-          clone->dest_node = NULL;
-          clone->processor = NULL;
+          clone->dest_node      = NULL;
+          clone->processor      = NULL;
         }
       break;
 
@@ -296,6 +336,13 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
   g_object_notify (G_OBJECT (clone), "src-y");
 }
 
+static gboolean
+gimp_perspective_clone_use_source (GimpSourceCore    *source_core,
+                                   GimpSourceOptions *options)
+{
+  return TRUE;
+}
+
 static GeglBuffer *
 gimp_perspective_clone_get_source (GimpSourceCore   *source_core,
                                    GimpDrawable     *drawable,
@@ -353,7 +400,7 @@ gimp_perspective_clone_get_source (GimpSourceCore   *source_core,
                                   NULL, NULL, NULL, NULL))
     {
       /* if the source area is completely out of the image */
-      return FALSE;
+      return NULL;
     }
 
   dest_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, x2d - x1d, y2d - y1d),
diff --git a/app/paint/gimpperspectiveclone.h b/app/paint/gimpperspectiveclone.h
index 629eea8..c7fd86f 100644
--- a/app/paint/gimpperspectiveclone.h
+++ b/app/paint/gimpperspectiveclone.h
@@ -46,7 +46,6 @@ struct _GimpPerspectiveClone
   GimpMatrix3    transform_inv;
 
   GeglNode      *node;
-  GeglNode      *src_node;
   GeglNode      *transform_node;
   GeglNode      *dest_node;
   GeglProcessor *processor;
diff --git a/app/paint/gimpsourcecore.c b/app/paint/gimpsourcecore.c
index 304aac5..aa61869 100644
--- a/app/paint/gimpsourcecore.c
+++ b/app/paint/gimpsourcecore.c
@@ -47,52 +47,54 @@ enum
 };
 
 
-static void     gimp_source_core_set_property    (GObject          *object,
-                                                  guint             property_id,
-                                                  const GValue     *value,
-                                                  GParamSpec       *pspec);
-static void     gimp_source_core_get_property    (GObject          *object,
-                                                  guint             property_id,
-                                                  GValue           *value,
-                                                  GParamSpec       *pspec);
-
-static gboolean gimp_source_core_start           (GimpPaintCore    *paint_core,
-                                                  GimpDrawable     *drawable,
-                                                  GimpPaintOptions *paint_options,
-                                                  const GimpCoords *coords,
-                                                  GError          **error);
-static void     gimp_source_core_paint           (GimpPaintCore    *paint_core,
-                                                  GimpDrawable     *drawable,
-                                                  GimpPaintOptions *paint_options,
-                                                  const GimpCoords *coords,
-                                                  GimpPaintState    paint_state,
-                                                  guint32           time);
+static void     gimp_source_core_set_property    (GObject           *object,
+                                                  guint              property_id,
+                                                  const GValue      *value,
+                                                  GParamSpec        *pspec);
+static void     gimp_source_core_get_property    (GObject           *object,
+                                                  guint              property_id,
+                                                  GValue            *value,
+                                                  GParamSpec        *pspec);
+
+static gboolean gimp_source_core_start           (GimpPaintCore     *paint_core,
+                                                  GimpDrawable      *drawable,
+                                                  GimpPaintOptions  *paint_options,
+                                                  const GimpCoords  *coords,
+                                                  GError           **error);
+static void     gimp_source_core_paint           (GimpPaintCore     *paint_core,
+                                                  GimpDrawable      *drawable,
+                                                  GimpPaintOptions  *paint_options,
+                                                  const GimpCoords  *coords,
+                                                  GimpPaintState     paint_state,
+                                                  guint32            time);
 
 #if 0
-static void     gimp_source_core_motion          (GimpSourceCore   *source_core,
-                                                  GimpDrawable     *drawable,
-                                                  GimpPaintOptions *paint_options,
-                                                  const GimpCoords *coords);
+static void     gimp_source_core_motion          (GimpSourceCore    *source_core,
+                                                  GimpDrawable      *drawable,
+                                                  GimpPaintOptions  *paint_options,
+                                                  const GimpCoords  *coords);
 #endif
 
+static gboolean gimp_source_core_real_use_source (GimpSourceCore    *source_core,
+                                                  GimpSourceOptions *options);
 static GeglBuffer *
-                gimp_source_core_real_get_source (GimpSourceCore   *source_core,
-                                                  GimpDrawable     *drawable,
-                                                  GimpPaintOptions *paint_options,
-                                                  GimpPickable     *src_pickable,
-                                                  gint              src_offset_x,
-                                                  gint              src_offset_y,
-                                                  GeglBuffer       *paint_buffer,
-                                                  gint              paint_buffer_x,
-                                                  gint              paint_buffer_y,
-                                                  gint             *paint_area_offset_x,
-                                                  gint             *paint_area_offset_y,
-                                                  gint             *paint_area_width,
-                                                  gint             *paint_area_height,
-                                                  GeglRectangle    *src_rect);
-
-static void    gimp_source_core_set_src_drawable (GimpSourceCore   *source_core,
-                                                  GimpDrawable     *drawable);
+                gimp_source_core_real_get_source (GimpSourceCore    *source_core,
+                                                  GimpDrawable      *drawable,
+                                                  GimpPaintOptions  *paint_options,
+                                                  GimpPickable      *src_pickable,
+                                                  gint               src_offset_x,
+                                                  gint               src_offset_y,
+                                                  GeglBuffer        *paint_buffer,
+                                                  gint               paint_buffer_x,
+                                                  gint               paint_buffer_y,
+                                                  gint              *paint_area_offset_x,
+                                                  gint              *paint_area_offset_y,
+                                                  gint              *paint_area_width,
+                                                  gint              *paint_area_height,
+                                                  GeglRectangle     *src_rect);
+
+static void    gimp_source_core_set_src_drawable (GimpSourceCore    *source_core,
+                                                  GimpDrawable      *drawable);
 
 
 G_DEFINE_TYPE (GimpSourceCore, gimp_source_core, GIMP_TYPE_BRUSH_CORE)
@@ -115,6 +117,7 @@ gimp_source_core_class_init (GimpSourceCoreClass *klass)
 
   brush_core_class->handles_changing_brush = TRUE;
 
+  klass->use_source                        = gimp_source_core_real_use_source;
   klass->get_source                        = gimp_source_core_real_get_source;
   klass->motion                            = NULL;
 
@@ -224,7 +227,8 @@ gimp_source_core_start (GimpPaintCore     *paint_core,
 
   paint_core->use_saved_proj = FALSE;
 
-  if (! source_core->set_source && options->use_source)
+  if (! source_core->set_source &&
+      gimp_source_core_use_source (source_core, options))
     {
       if (! source_core->src_drawable)
         {
@@ -378,7 +382,7 @@ gimp_source_core_motion (GimpSourceCore   *source_core,
   src_offset_x = source_core->offset_x;
   src_offset_y = source_core->offset_y;
 
-  if (options->use_source)
+  if (gimp_source_core_use_source (source_core, options))
     {
       src_pickable = GIMP_PICKABLE (source_core->src_drawable);
 
@@ -411,7 +415,7 @@ gimp_source_core_motion (GimpSourceCore   *source_core,
   paint_area_width    = gegl_buffer_get_width  (paint_buffer);
   paint_area_height   = gegl_buffer_get_height (paint_buffer);
 
-  if (options->use_source)
+  if (gimp_source_core_use_source (source_core, options))
     {
       src_buffer =
         GIMP_SOURCE_CORE_GET_CLASS (source_core)->get_source (source_core,
@@ -457,6 +461,21 @@ gimp_source_core_motion (GimpSourceCore   *source_core,
     g_object_unref (src_buffer);
 }
 
+gboolean
+gimp_source_core_use_source (GimpSourceCore    *source_core,
+                             GimpSourceOptions *options)
+{
+  return GIMP_SOURCE_CORE_GET_CLASS (source_core)->use_source (source_core,
+                                                               options);
+}
+
+static gboolean
+gimp_source_core_real_use_source (GimpSourceCore    *source_core,
+                                  GimpSourceOptions *options)
+{
+  return TRUE;
+}
+
 static GeglBuffer *
 gimp_source_core_real_get_source (GimpSourceCore   *source_core,
                                   GimpDrawable     *drawable,
diff --git a/app/paint/gimpsourcecore.h b/app/paint/gimpsourcecore.h
index 059dd98..4f71bb0 100644
--- a/app/paint/gimpsourcecore.h
+++ b/app/paint/gimpsourcecore.h
@@ -54,50 +54,56 @@ struct _GimpSourceCoreClass
 {
   GimpBrushCoreClass  parent_class;
 
-  GeglBuffer * (* get_source) (GimpSourceCore   *source_core,
-                               GimpDrawable     *drawable,
-                               GimpPaintOptions *paint_options,
-                               GimpPickable     *src_pickable,
-                               gint              src_offset_x,
-                               gint              src_offset_y,
-                               GeglBuffer       *paint_buffer,
-                               gint              paint_buffer_x,
-                               gint              paint_buffer_y,
+  gboolean     (* use_source) (GimpSourceCore    *source_core,
+                               GimpSourceOptions *options);
+
+  GeglBuffer * (* get_source) (GimpSourceCore    *source_core,
+                               GimpDrawable      *drawable,
+                               GimpPaintOptions  *paint_options,
+                               GimpPickable      *src_pickable,
+                               gint               src_offset_x,
+                               gint               src_offset_y,
+                               GeglBuffer        *paint_buffer,
+                               gint               paint_buffer_x,
+                               gint               paint_buffer_y,
                                /* offsets *into* the paint_buffer: */
-                               gint             *paint_area_offset_x,
-                               gint             *paint_area_offset_y,
-                               gint             *paint_area_width,
-                               gint             *paint_area_height,
-                               GeglRectangle    *src_rect);
-
-  void         (*  motion)    (GimpSourceCore   *source_core,
-                               GimpDrawable     *drawable,
-                               GimpPaintOptions *paint_options,
-                               const GimpCoords *coords,
-                               gdouble           opacity,
-                               GimpPickable     *src_pickable,
-                               GeglBuffer       *src_buffer,
-                               GeglRectangle    *src_rect,
-                               gint              src_offset_x,
-                               gint              src_offset_y,
-                               GeglBuffer       *paint_buffer,
-                               gint              paint_buffer_x,
-                               gint              paint_buffer_y,
+                               gint              *paint_area_offset_x,
+                               gint              *paint_area_offset_y,
+                               gint              *paint_area_width,
+                               gint              *paint_area_height,
+                               GeglRectangle     *src_rect);
+
+  void         (*  motion)    (GimpSourceCore    *source_core,
+                               GimpDrawable      *drawable,
+                               GimpPaintOptions  *paint_options,
+                               const GimpCoords  *coords,
+                               gdouble            opacity,
+                               GimpPickable      *src_pickable,
+                               GeglBuffer        *src_buffer,
+                               GeglRectangle     *src_rect,
+                               gint               src_offset_x,
+                               gint               src_offset_y,
+                               GeglBuffer        *paint_buffer,
+                               gint               paint_buffer_x,
+                               gint               paint_buffer_y,
                                /* offsets *into* the paint_buffer: */
-                               gint              paint_area_offset_x,
-                               gint              paint_area_offset_y,
-                               gint              paint_area_width,
-                               gint              paint_area_height);
+                               gint               paint_area_offset_x,
+                               gint               paint_area_offset_y,
+                               gint               paint_area_width,
+                               gint               paint_area_height);
 };
 
 
-GType   gimp_source_core_get_type (void) G_GNUC_CONST;
+GType    gimp_source_core_get_type   (void) G_GNUC_CONST;
+
+gboolean gimp_source_core_use_source (GimpSourceCore    *source_core,
+                                      GimpSourceOptions *options);
 
 /* TEMP HACK */
-void    gimp_source_core_motion   (GimpSourceCore   *source_core,
-                                   GimpDrawable     *drawable,
-                                   GimpPaintOptions *paint_options,
-                                   const GimpCoords *coords);
+void     gimp_source_core_motion     (GimpSourceCore    *source_core,
+                                      GimpDrawable      *drawable,
+                                      GimpPaintOptions  *paint_options,
+                                      const GimpCoords  *coords);
 
 
 #endif  /*  __GIMP_SOURCE_CORE_H__  */
diff --git a/app/paint/gimpsourceoptions.c b/app/paint/gimpsourceoptions.c
index 60a5d3d..16585e9 100644
--- a/app/paint/gimpsourceoptions.c
+++ b/app/paint/gimpsourceoptions.c
@@ -70,7 +70,6 @@ gimp_source_options_class_init (GimpSourceOptionsClass *klass)
 static void
 gimp_source_options_init (GimpSourceOptions *options)
 {
-  options->use_source = TRUE;
 }
 
 static void
diff --git a/app/paint/gimpsourceoptions.h b/app/paint/gimpsourceoptions.h
index 18d1dbb..de3d38a 100644
--- a/app/paint/gimpsourceoptions.h
+++ b/app/paint/gimpsourceoptions.h
@@ -38,8 +38,6 @@ struct _GimpSourceOptions
 
   GimpSourceAlignMode  align_mode;
   gboolean             sample_merged;
-
-  gboolean             use_source; /* not a property */
 };
 
 struct _GimpSourceOptionsClass
diff --git a/app/tools/gimpperspectiveclonetool.c b/app/tools/gimpperspectiveclonetool.c
index 2069e59..875e69e 100644
--- a/app/tools/gimpperspectiveclonetool.c
+++ b/app/tools/gimpperspectiveclonetool.c
@@ -567,18 +567,15 @@ gimp_perspective_clone_tool_cursor_update (GimpTool         *tool,
     }
   else
     {
-      if (GIMP_CLONE_OPTIONS (options)->clone_type == GIMP_IMAGE_CLONE)
-        {
-          GdkModifierType toggle_mask = gimp_get_toggle_behavior_mask ();
+      GdkModifierType toggle_mask = gimp_get_toggle_behavior_mask ();
 
-          if ((state & (toggle_mask | GDK_SHIFT_MASK)) == toggle_mask)
-            {
-              cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
-            }
-          else if (! GIMP_SOURCE_CORE (GIMP_PAINT_TOOL (tool)->core)->src_drawable)
-            {
-              modifier = GIMP_CURSOR_MODIFIER_BAD;
-            }
+      if ((state & (toggle_mask | GDK_SHIFT_MASK)) == toggle_mask)
+        {
+          cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
+        }
+      else if (! GIMP_SOURCE_CORE (GIMP_PAINT_TOOL (tool)->core)->src_drawable)
+        {
+          modifier = GIMP_CURSOR_MODIFIER_BAD;
         }
     }
 
@@ -662,8 +659,7 @@ gimp_perspective_clone_tool_oper_update (GimpTool         *tool,
       GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state,
                                                    proximity, display);
 
-      if (GIMP_CLONE_OPTIONS (options)->clone_type == GIMP_IMAGE_CLONE &&
-          proximity)
+      if (proximity)
         {
           GimpPaintCore        *core        = GIMP_PAINT_TOOL (tool)->core;
           GimpPerspectiveClone *clone       = GIMP_PERSPECTIVE_CLONE (core);
@@ -766,8 +762,7 @@ gimp_perspective_clone_tool_draw (GimpDrawTool *draw_tool)
                                  GIMP_HANDLE_ANCHOR_CENTER);
     }
 
-  if (GIMP_CLONE_OPTIONS (options)->clone_type == GIMP_IMAGE_CLONE &&
-      source_core->src_drawable && clone_tool->src_display)
+  if (source_core->src_drawable && clone_tool->src_display)
     {
       GimpDisplay *tmp_display;
 
diff --git a/app/tools/gimpsourcetool.c b/app/tools/gimpsourcetool.c
index 561730f..95612b8 100644
--- a/app/tools/gimpsourcetool.c
+++ b/app/tools/gimpsourcetool.c
@@ -232,7 +232,9 @@ gimp_source_tool_modifier_key (GimpTool        *tool,
   GimpPaintTool     *paint_tool  = GIMP_PAINT_TOOL (tool);
   GimpSourceOptions *options     = GIMP_SOURCE_TOOL_GET_OPTIONS (tool);
 
-  if (options->use_source && key == gimp_get_toggle_behavior_mask ())
+  if (gimp_source_core_use_source (GIMP_SOURCE_CORE (paint_tool->core),
+                                   options) &&
+      key == gimp_get_toggle_behavior_mask ())
     {
       gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
 
@@ -262,11 +264,13 @@ gimp_source_tool_cursor_update (GimpTool         *tool,
                                 GdkModifierType   state,
                                 GimpDisplay      *display)
 {
-  GimpSourceOptions  *options  = GIMP_SOURCE_TOOL_GET_OPTIONS (tool);
-  GimpCursorType      cursor   = GIMP_CURSOR_MOUSE;
-  GimpCursorModifier  modifier = GIMP_CURSOR_MODIFIER_NONE;
+  GimpPaintTool      *paint_tool = GIMP_PAINT_TOOL (tool);
+  GimpSourceOptions  *options    = GIMP_SOURCE_TOOL_GET_OPTIONS (tool);
+  GimpCursorType      cursor     = GIMP_CURSOR_MOUSE;
+  GimpCursorModifier  modifier   = GIMP_CURSOR_MODIFIER_NONE;
 
-  if (options->use_source)
+  if (gimp_source_core_use_source (GIMP_SOURCE_CORE (paint_tool->core),
+                                   options))
     {
       GdkModifierType toggle_mask = gimp_get_toggle_behavior_mask ();
 
@@ -293,14 +297,16 @@ gimp_source_tool_oper_update (GimpTool         *tool,
                               gboolean          proximity,
                               GimpDisplay      *display)
 {
+  GimpPaintTool     *paint_tool  = GIMP_PAINT_TOOL (tool);
   GimpSourceTool    *source_tool = GIMP_SOURCE_TOOL (tool);
   GimpSourceOptions *options     = GIMP_SOURCE_TOOL_GET_OPTIONS (tool);
+  GimpSourceCore    *source;
+
+  source = GIMP_SOURCE_CORE (GIMP_PAINT_TOOL (tool)->core);
 
   if (proximity)
     {
-      GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool);
-
-      if (options->use_source)
+      if (gimp_source_core_use_source (source, options))
         paint_tool->status_ctrl = source_tool->status_set_source_ctrl;
       else
         paint_tool->status_ctrl = NULL;
@@ -309,10 +315,8 @@ gimp_source_tool_oper_update (GimpTool         *tool,
   GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
                                                display);
 
-  if (options->use_source)
+  if (gimp_source_core_use_source (source, options))
     {
-      GimpSourceCore *source = GIMP_SOURCE_CORE (GIMP_PAINT_TOOL (tool)->core);
-
       if (source->src_drawable == NULL)
         {
           GdkModifierType toggle_mask = gimp_get_toggle_behavior_mask ();
@@ -371,7 +375,8 @@ gimp_source_tool_draw (GimpDrawTool *draw_tool)
 
   GIMP_DRAW_TOOL_CLASS (parent_class)->draw (draw_tool);
 
-  if (options->use_source && source->src_drawable && source_tool->src_display)
+  if (gimp_source_core_use_source (source, options) &&
+      source->src_drawable && source_tool->src_display)
     {
       GimpDisplayShell *src_shell;
       gint              off_x;



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