[gimp] app: make Perspective Clone tool also work with multiple drawables.



commit 231ab4413bb0a20f4b74f27d4e2cd3628ce89ec7
Author: Jehan <jehan girinstud io>
Date:   Thu Aug 19 23:24:40 2021 +0200

    app: make Perspective Clone tool also work with multiple drawables.

 app/paint/gimpperspectiveclone.c     | 56 +++++++++++++++++++++++++++---------
 app/paint/gimpperspectiveclone.h     |  1 +
 app/paint/gimpsourcecore.c           |  1 +
 app/tools/gimpperspectiveclonetool.c |  9 ++----
 4 files changed, 48 insertions(+), 19 deletions(-)
---
diff --git a/app/paint/gimpperspectiveclone.c b/app/paint/gimpperspectiveclone.c
index 29bf79d91a..32491b3840 100644
--- a/app/paint/gimpperspectiveclone.c
+++ b/app/paint/gimpperspectiveclone.c
@@ -33,9 +33,11 @@
 
 #include "core/gimp.h"
 #include "core/gimp-utils.h"
+#include "core/gimpcontainer.h"
 #include "core/gimpdrawable.h"
 #include "core/gimperror.h"
 #include "core/gimpimage.h"
+#include "core/gimpimage-new.h"
 #include "core/gimppattern.h"
 #include "core/gimppickable.h"
 #include "core/gimpsymmetry.h"
@@ -160,9 +162,9 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
         }
       else
         {
+          GimpImage  *del_image   = NULL;
           GeglBuffer *orig_buffer = NULL;
           GeglNode   *tile        = NULL;
-          GeglNode   *src_node;
 
           if (options->align_mode == GIMP_SOURCE_ALIGN_NO)
             {
@@ -182,7 +184,7 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
             {
             case GIMP_CLONE_IMAGE:
               {
-                GimpPickable *src_pickable;
+                GimpPickable *src_pickable = NULL;
                 GimpImage    *src_image;
                 GimpImage    *dest_image;
 
@@ -192,8 +194,7 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
                  *  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_drawables->data);
-                src_image    = gimp_pickable_get_image (src_pickable);
+                src_image = gimp_pickable_get_image (source_core->src_drawables->data);
 
                 if (sample_merged)
                   src_pickable = GIMP_PICKABLE (src_image);
@@ -202,18 +203,36 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
 
                 if ((sample_merged &&
                      (src_image != dest_image)) ||
-                    (! sample_merged &&
-                     (source_core->src_drawable != drawables->data)))
+                    (! sample_merged                                 &&
+                     g_list_length (source_core->src_drawables) == 1 &&
+                     g_list_length (drawables) == 1                  &&
+                     (source_core->src_drawables != drawables->data)))
                   {
+                    if (! sample_merged)
+                      src_pickable = GIMP_PICKABLE (source_core->src_drawables->data);
+
                     orig_buffer = gimp_pickable_get_buffer (src_pickable);
                   }
                 else
                   {
-                    if (sample_merged)
+                    if (sample_merged && paint_core->use_saved_proj)
                       orig_buffer = gimp_paint_core_get_orig_proj (paint_core);
                     else
                       orig_buffer = gimp_paint_core_get_orig_image (paint_core, drawables->data);
                   }
+
+                if (! orig_buffer)
+                  {
+                    /* A composited image of the drawables */
+                    del_image = gimp_image_new_from_drawables (src_image->gimp, drawables,
+                                                               FALSE);
+                    gimp_container_remove (src_image->gimp->images, GIMP_OBJECT (del_image));
+
+                    src_pickable = GIMP_PICKABLE (del_image);
+                    gimp_pickable_flush (src_pickable);
+
+                    orig_buffer = gimp_pickable_get_buffer (src_pickable);
+                  }
               }
               break;
 
@@ -233,10 +252,10 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
               break;
             }
 
-          src_node = gegl_node_new_child (clone->node,
-                                          "operation", "gegl:buffer-source",
-                                          "buffer",    orig_buffer,
-                                          NULL);
+          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,
@@ -251,7 +270,7 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
 
           if (tile)
             {
-              gegl_node_link_many (src_node,
+              gegl_node_link_many (clone->src_node,
                                    tile,
                                    clone->crop,
                                    clone->transform_node,
@@ -262,11 +281,13 @@ gimp_perspective_clone_paint (GimpPaintCore    *paint_core,
             }
           else
             {
-              gegl_node_link_many (src_node,
+              gegl_node_link_many (clone->src_node,
                                    clone->transform_node,
                                    clone->dest_node,
                                    NULL);
             }
+
+          g_clear_object (&del_image);
         }
       break;
 
@@ -386,6 +407,9 @@ gimp_perspective_clone_get_source (GimpSourceCore   *source_core,
   GimpMatrix3           matrix;
   GimpMatrix3           gegl_matrix;
 
+  if (self_drawable)
+    src_pickable = GIMP_PICKABLE (drawable);
+
   src_buffer       = gimp_pickable_get_buffer (src_pickable);
   src_format_alpha = gimp_pickable_get_format_with_alpha (src_pickable);
 
@@ -423,6 +447,12 @@ gimp_perspective_clone_get_source (GimpSourceCore   *source_core,
           /* if the source area is completely out of the image */
           return NULL;
         }
+      else
+        {
+          gegl_node_set (clone->src_node,
+                         "buffer", src_buffer,
+                         NULL);
+        }
       break;
 
     case GIMP_CLONE_PATTERN:
diff --git a/app/paint/gimpperspectiveclone.h b/app/paint/gimpperspectiveclone.h
index 1d24957907..98da289a34 100644
--- a/app/paint/gimpperspectiveclone.h
+++ b/app/paint/gimpperspectiveclone.h
@@ -48,6 +48,7 @@ struct _GimpPerspectiveClone
   GeglNode      *node;
   GeglNode      *crop;
   GeglNode      *transform_node;
+  GeglNode      *src_node;
   GeglNode      *dest_node;
 };
 
diff --git a/app/paint/gimpsourcecore.c b/app/paint/gimpsourcecore.c
index 151a3beb31..67f043a60d 100644
--- a/app/paint/gimpsourcecore.c
+++ b/app/paint/gimpsourcecore.c
@@ -190,6 +190,7 @@ gimp_source_core_set_property (GObject      *object,
     case PROP_SRC_DRAWABLES:
       gimp_source_core_set_src_drawable (source_core,
                                          g_value_get_pointer (value));
+      gimp_source_core_make_pickable (source_core);
       break;
     case PROP_SRC_X:
       source_core->src_x = g_value_get_int (value);
diff --git a/app/tools/gimpperspectiveclonetool.c b/app/tools/gimpperspectiveclonetool.c
index f1567eadaa..14ecbd086e 100644
--- a/app/tools/gimpperspectiveclonetool.c
+++ b/app/tools/gimpperspectiveclonetool.c
@@ -188,6 +188,7 @@ gimp_perspective_clone_tool_init (GimpPerspectiveCloneTool *clone_tool)
                                          "context/context-pattern-select-set");
 
   gimp_matrix3_identity (&clone_tool->transform);
+  gimp_paint_tool_enable_multi_paint (GIMP_PAINT_TOOL (clone_tool));
 }
 
 static void
@@ -218,13 +219,9 @@ gimp_perspective_clone_tool_initialize (GimpTool     *tool,
     }
 
   drawables = gimp_image_get_selected_drawables (image);
-  if (g_list_length (drawables) != 1)
+  if (g_list_length (drawables) == 0)
     {
-      if (g_list_length (drawables) > 1)
-        gimp_tool_message_literal (tool, display,
-                                   _("Cannot paint on multiple layers. Select only one layer."));
-      else
-        gimp_tool_message_literal (tool, display, _("No selected drawables."));
+      gimp_tool_message_literal (tool, display, _("No selected drawables."));
 
       g_list_free (drawables);
 


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