[gimp/gimp-2-10] Issue #2837 - Floating selection is clipped to base layer



commit 72eeee39db87f69e01bdde7e82c8e20c55d651d5
Author: Ell <ell_se yahoo com>
Date:   Wed Oct 2 18:09:41 2019 +0300

    Issue #2837 - Floating selection is clipped to base layer
    
    When attaching a floating selection to a layer, don't clip the
    floating selection to the layer's boundary, and instead resize the
    layer to include the entire floating selection when it's anchored.
    As per the last commit, this can be prevented by locking the
    layer's position.
    
    (cherry picked from commit 64b979c2f37fc159a6eddfe01303752c8aefd21b)

 app/core/gimpdrawable-floating-selection.c | 100 ++++++++++++++++++++---------
 app/core/gimplayer-floating-selection.c    |  31 +++++----
 2 files changed, 89 insertions(+), 42 deletions(-)
---
diff --git a/app/core/gimpdrawable-floating-selection.c b/app/core/gimpdrawable-floating-selection.c
index ad5c387de9..8088754a6a 100644
--- a/app/core/gimpdrawable-floating-selection.c
+++ b/app/core/gimpdrawable-floating-selection.c
@@ -44,9 +44,11 @@
 static void    gimp_drawable_remove_fs_filter             (GimpDrawable      *drawable);
 static void    gimp_drawable_sync_fs_filter               (GimpDrawable      *drawable);
 
-static void    gimp_drawable_fs_notify                    (GimpLayer         *fs,
+static void    gimp_drawable_fs_notify                    (GObject           *object,
                                                            const GParamSpec  *pspec,
                                                            GimpDrawable      *drawable);
+static void    gimp_drawable_fs_lock_position_changed     (GimpDrawable      *signal_drawable,
+                                                           GimpDrawable      *drawable);
 static void    gimp_drawable_fs_format_changed            (GimpDrawable      *signal_drawable,
                                                            GimpDrawable      *drawable);
 static void    gimp_drawable_fs_affect_changed            (GimpImage         *image,
@@ -214,10 +216,9 @@ _gimp_drawable_add_floating_sel_filter (GimpDrawable *drawable)
 
   gimp_applicator_set_cache (private->fs_applicator, TRUE);
 
-  private->fs_crop_node =
-    gegl_node_new_child (node,
-                         "operation", "gegl:crop",
-                         NULL);
+  private->fs_crop_node = gegl_node_new_child (node,
+                                               "operation", "gegl:nop",
+                                               NULL);
 
   gegl_node_connect_to (fs_source,             "output",
                         private->fs_crop_node, "input");
@@ -229,6 +230,15 @@ _gimp_drawable_add_floating_sel_filter (GimpDrawable *drawable)
   g_signal_connect (fs, "notify",
                     G_CALLBACK (gimp_drawable_fs_notify),
                     drawable);
+  g_signal_connect (drawable, "notify::offset-x",
+                    G_CALLBACK (gimp_drawable_fs_notify),
+                    drawable);
+  g_signal_connect (drawable, "notify::offset-y",
+                    G_CALLBACK (gimp_drawable_fs_notify),
+                    drawable);
+  g_signal_connect (drawable, "lock-position-changed",
+                    G_CALLBACK (gimp_drawable_fs_lock_position_changed),
+                    drawable);
   g_signal_connect (drawable, "format-changed",
                     G_CALLBACK (gimp_drawable_fs_format_changed),
                     drawable);
@@ -260,6 +270,12 @@ gimp_drawable_remove_fs_filter (GimpDrawable *drawable)
       g_signal_handlers_disconnect_by_func (fs,
                                             gimp_drawable_fs_notify,
                                             drawable);
+      g_signal_handlers_disconnect_by_func (drawable,
+                                            gimp_drawable_fs_notify,
+                                            drawable);
+      g_signal_handlers_disconnect_by_func (drawable,
+                                            gimp_drawable_fs_lock_position_changed,
+                                            drawable);
       g_signal_handlers_disconnect_by_func (drawable,
                                             gimp_drawable_fs_format_changed,
                                             drawable);
@@ -310,12 +326,25 @@ gimp_drawable_sync_fs_filter (GimpDrawable *drawable)
   gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
   gimp_item_get_offset (GIMP_ITEM (fs), &fs_off_x, &fs_off_y);
 
-  gegl_node_set (private->fs_crop_node,
-                 "x",      (gdouble) (off_x - fs_off_x),
-                 "y",      (gdouble) (off_y - fs_off_y),
-                 "width",  (gdouble) gimp_item_get_width  (GIMP_ITEM (drawable)),
-                 "height", (gdouble) gimp_item_get_height (GIMP_ITEM (drawable)),
-                 NULL);
+  if (gimp_item_get_clip (GIMP_ITEM (drawable), GIMP_TRANSFORM_RESIZE_ADJUST) ==
+      GIMP_TRANSFORM_RESIZE_CLIP)
+    {
+      gegl_node_set (
+        private->fs_crop_node,
+        "operation", "gegl:crop",
+        "x",         (gdouble) (off_x - fs_off_x),
+        "y",         (gdouble) (off_y - fs_off_y),
+        "width",     (gdouble) gimp_item_get_width  (GIMP_ITEM (drawable)),
+        "height",    (gdouble) gimp_item_get_height (GIMP_ITEM (drawable)),
+        NULL);
+    }
+  else
+    {
+      gegl_node_set (
+        private->fs_crop_node,
+        "operation", "gegl:nop",
+        NULL);
+    }
 
   gimp_applicator_set_apply_offset (private->fs_applicator,
                                     fs_off_x - off_x,
@@ -345,10 +374,12 @@ gimp_drawable_sync_fs_filter (GimpDrawable *drawable)
                               gimp_drawable_get_active_mask (drawable));
   gimp_applicator_set_output_format (private->fs_applicator,
                                      gimp_drawable_get_format (drawable));
+
+  gimp_drawable_update_bounding_box (drawable);
 }
 
 static void
-gimp_drawable_fs_notify (GimpLayer        *fs,
+gimp_drawable_fs_notify (GObject          *object,
                          const GParamSpec *pspec,
                          GimpDrawable     *drawable)
 {
@@ -365,6 +396,17 @@ gimp_drawable_fs_notify (GimpLayer        *fs,
     }
 }
 
+static void
+gimp_drawable_fs_lock_position_changed (GimpDrawable *signal_drawable,
+                                        GimpDrawable *drawable)
+{
+  GimpLayer *fs = gimp_drawable_get_floating_sel (drawable);
+
+  gimp_drawable_sync_fs_filter (drawable);
+
+  gimp_drawable_update (GIMP_DRAWABLE (fs), 0, 0, -1, -1);
+}
+
 static void
 gimp_drawable_fs_format_changed (GimpDrawable *signal_drawable,
                                  GimpDrawable *drawable)
@@ -425,28 +467,28 @@ gimp_drawable_fs_update (GimpLayer    *fs,
                          gint          height,
                          GimpDrawable *drawable)
 {
-  gint fs_off_x, fs_off_y;
-  gint off_x, off_y;
-  gint dr_x, dr_y, dr_width, dr_height;
+  GeglRectangle bounding_box;
+  GeglRectangle rect;
+  gint          fs_off_x, fs_off_y;
+  gint          off_x, off_y;
 
   gimp_item_get_offset (GIMP_ITEM (fs), &fs_off_x, &fs_off_y);
   gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
 
-  if (gimp_rectangle_intersect (x + fs_off_x,
-                                y + fs_off_y,
-                                width,
-                                height,
-                                off_x,
-                                off_y,
-                                gimp_item_get_width  (GIMP_ITEM (drawable)),
-                                gimp_item_get_height (GIMP_ITEM (drawable)),
-                                &dr_x,
-                                &dr_y,
-                                &dr_width,
-                                &dr_height))
+  bounding_box = gimp_drawable_get_bounding_box (drawable);
+
+  bounding_box.x += off_x;
+  bounding_box.y += off_y;
+
+  rect.x      = x + fs_off_x;
+  rect.y      = y + fs_off_y;
+  rect.width  = width;
+  rect.height = height;
+
+  if (gegl_rectangle_intersect (&rect, &rect, &bounding_box))
     {
       gimp_drawable_update (drawable,
-                            dr_x - off_x, dr_y - off_y,
-                            dr_width, dr_height);
+                            rect.x - off_x, rect.y - off_y,
+                            rect.width, rect.height);
     }
 }
diff --git a/app/core/gimplayer-floating-selection.c b/app/core/gimplayer-floating-selection.c
index 59eb691d8e..aa6cc6bc2a 100644
--- a/app/core/gimplayer-floating-selection.c
+++ b/app/core/gimplayer-floating-selection.c
@@ -100,11 +100,13 @@ floating_sel_attach (GimpLayer    *layer,
 void
 floating_sel_anchor (GimpLayer *layer)
 {
-  GimpImage    *image;
-  GimpDrawable *drawable;
-  GimpFilter   *filter = NULL;
-  gint          off_x, off_y;
-  gint          dr_off_x, dr_off_y;
+  GimpImage     *image;
+  GimpDrawable  *drawable;
+  GimpFilter    *filter = NULL;
+  GeglRectangle  bounding_box;
+  GeglRectangle  dr_bounding_box;
+  gint           off_x, off_y;
+  gint           dr_off_x, dr_off_y;
 
   g_return_if_fail (GIMP_IS_LAYER (layer));
   g_return_if_fail (gimp_layer_is_floating_sel (layer));
@@ -122,14 +124,17 @@ floating_sel_anchor (GimpLayer *layer)
   gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y);
   gimp_item_get_offset (GIMP_ITEM (drawable), &dr_off_x, &dr_off_y);
 
+  bounding_box    = gimp_drawable_get_bounding_box (GIMP_DRAWABLE (layer));
+  dr_bounding_box = gimp_drawable_get_bounding_box (drawable);
+
+  bounding_box.x    += off_x;
+  bounding_box.y    += off_y;
+
+  dr_bounding_box.x += dr_off_x;
+  dr_bounding_box.y += dr_off_y;
+
   if (gimp_item_get_visible (GIMP_ITEM (layer)) &&
-      gimp_rectangle_intersect (off_x, off_y,
-                                gimp_item_get_width  (GIMP_ITEM (layer)),
-                                gimp_item_get_height (GIMP_ITEM (layer)),
-                                dr_off_x, dr_off_y,
-                                gimp_item_get_width  (GIMP_ITEM (drawable)),
-                                gimp_item_get_height (GIMP_ITEM (drawable)),
-                                NULL, NULL, NULL, NULL))
+      gegl_rectangle_intersect (NULL, &bounding_box, &dr_bounding_box))
     {
       filter = gimp_drawable_get_floating_sel_filter (drawable);
     }
@@ -137,7 +142,7 @@ floating_sel_anchor (GimpLayer *layer)
   if (filter)
     {
       gimp_drawable_merge_filter (drawable, filter, NULL, NULL,
-                                  TRUE, FALSE, FALSE);
+                                  FALSE, FALSE, FALSE);
     }
 
   gimp_image_remove_layer (image, layer, TRUE, NULL);


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