[gimp] app: calculate drawable bounding box according to graph by default



commit cb5a63e260f61ef5203c1dc192e20ff889a33513
Author: Ell <ell_se yahoo com>
Date:   Wed Jan 15 23:11:56 2020 +0200

    app: calculate drawable bounding box according to graph by default
    
    Change the default implementation of
    GimpDrawable::get_bounding_box() to return the drawable source
    node's bounding box, instead of the drawable's item bounds.  This
    allows filters to affect the size of all drawables, including, in
    particular, layer masks.
    
    Change GimpLayer's implementation of get_bounding_box() to return
    the intersection of the layer's own bounding box, and the layer
    mask's bounding box (if it has one), and update the layer's
    bounding box when the mask is enabled/disabled, or when its
    bounding box changes.

 app/core/gimpdrawable.c  | 10 +-----
 app/core/gimplayer.c     | 23 +++++++++++---
 app/core/gimplayermask.c | 83 ++++++++++++++++++++++++++++--------------------
 3 files changed, 69 insertions(+), 47 deletions(-)
---
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index b29a8a94c7..6349a31b81 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -931,15 +931,7 @@ gimp_drawable_real_set_buffer (GimpDrawable        *drawable,
 static GeglRectangle
 gimp_drawable_real_get_bounding_box (GimpDrawable *drawable)
 {
-  GimpItem      *item = GIMP_ITEM (drawable);
-  GeglRectangle  bounding_box;
-
-  bounding_box.x      = 0;
-  bounding_box.y      = 0;
-  bounding_box.width  = gimp_item_get_width  (item);
-  bounding_box.height = gimp_item_get_height (item);
-
-  return bounding_box;
+  return gegl_node_get_bounding_box (gimp_drawable_get_source_node (drawable));
 }
 
 static void
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index 1a6c00ea80..ab32fd4ddf 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -1522,12 +1522,25 @@ gimp_layer_set_buffer (GimpDrawable        *drawable,
 static GeglRectangle
 gimp_layer_get_bounding_box (GimpDrawable *drawable)
 {
-  GimpLayer *layer = GIMP_LAYER (drawable);
+  GimpLayer     *layer        = GIMP_LAYER (drawable);
+  GimpLayerMask *mask         = gimp_layer_get_mask (layer);
+  GeglRectangle  bounding_box;
+
+  bounding_box = GIMP_DRAWABLE_CLASS (parent_class)->get_bounding_box (
+    drawable);
+
+  if (mask && gimp_layer_get_apply_mask (layer))
+    {
+      GeglRectangle mask_bounding_box;
 
-  if (gimp_layer_get_mask (layer))
-    return GIMP_DRAWABLE_CLASS (parent_class)->get_bounding_box (drawable);
+      mask_bounding_box = gimp_drawable_get_bounding_box (
+        GIMP_DRAWABLE (mask));
 
-  return gegl_node_get_bounding_box (gimp_drawable_get_source_node (drawable));
+      gegl_rectangle_intersect (&bounding_box,
+                                &bounding_box, &mask_bounding_box);
+    }
+
+  return bounding_box;
 }
 
 static GimpColorProfile *
@@ -2292,6 +2305,8 @@ gimp_layer_set_apply_mask (GimpLayer *layer,
             }
         }
 
+      gimp_drawable_update_bounding_box (GIMP_DRAWABLE (layer));
+
       gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, -1, -1);
 
       g_signal_emit (layer, layer_signals[APPLY_MASK_CHANGED], 0);
diff --git a/app/core/gimplayermask.c b/app/core/gimplayermask.c
index 8986b9ee35..dd3435a771 100644
--- a/app/core/gimplayermask.c
+++ b/app/core/gimplayermask.c
@@ -32,29 +32,30 @@
 #include "gimp-intl.h"
 
 
-static void            gimp_layer_mask_preview_freeze     (GimpViewable      *viewable);
-static void            gimp_layer_mask_preview_thaw       (GimpViewable      *viewable);
-
-static gboolean        gimp_layer_mask_is_attached        (GimpItem          *item);
-static gboolean        gimp_layer_mask_is_content_locked  (GimpItem          *item);
-static gboolean        gimp_layer_mask_is_position_locked (GimpItem          *item);
-static GimpItemTree  * gimp_layer_mask_get_tree           (GimpItem          *item);
-static GimpItem      * gimp_layer_mask_duplicate          (GimpItem          *item,
-                                                           GType              new_type);
-static gboolean        gimp_layer_mask_rename             (GimpItem          *item,
-                                                           const gchar       *new_name,
-                                                           const gchar       *undo_desc,
-                                                           GError           **error);
-
-static void            gimp_layer_mask_convert_type       (GimpDrawable      *drawable,
-                                                           GimpImage         *dest_image,
-                                                           const Babl        *new_format,
-                                                           GimpColorProfile  *src_profile,
-                                                           GimpColorProfile  *dest_profile,
-                                                           GeglDitherMethod   layer_dither_type,
-                                                           GeglDitherMethod   mask_dither_type,
-                                                           gboolean           push_undo,
-                                                           GimpProgress      *progress);
+static void            gimp_layer_mask_preview_freeze       (GimpViewable      *viewable);
+static void            gimp_layer_mask_preview_thaw         (GimpViewable      *viewable);
+
+static gboolean        gimp_layer_mask_is_attached          (GimpItem          *item);
+static gboolean        gimp_layer_mask_is_content_locked    (GimpItem          *item);
+static gboolean        gimp_layer_mask_is_position_locked   (GimpItem          *item);
+static GimpItemTree  * gimp_layer_mask_get_tree             (GimpItem          *item);
+static GimpItem      * gimp_layer_mask_duplicate            (GimpItem          *item,
+                                                             GType              new_type);
+static gboolean        gimp_layer_mask_rename               (GimpItem          *item,
+                                                             const gchar       *new_name,
+                                                             const gchar       *undo_desc,
+                                                             GError           **error);
+
+static void            gimp_layer_mask_bounding_box_changed (GimpDrawable      *drawable);
+static void            gimp_layer_mask_convert_type         (GimpDrawable      *drawable,
+                                                             GimpImage         *dest_image,
+                                                             const Babl        *new_format,
+                                                             GimpColorProfile  *src_profile,
+                                                             GimpColorProfile  *dest_profile,
+                                                             GeglDitherMethod   layer_dither_type,
+                                                             GeglDitherMethod   mask_dither_type,
+                                                             gboolean           push_undo,
+                                                             GimpProgress      *progress);
 
 
 G_DEFINE_TYPE (GimpLayerMask, gimp_layer_mask, GIMP_TYPE_CHANNEL)
@@ -71,19 +72,20 @@ gimp_layer_mask_class_init (GimpLayerMaskClass *klass)
 
   viewable_class->default_icon_name = "gimp-layer-mask";
 
-  viewable_class->preview_freeze = gimp_layer_mask_preview_freeze;
-  viewable_class->preview_thaw   = gimp_layer_mask_preview_thaw;
+  viewable_class->preview_freeze       = gimp_layer_mask_preview_freeze;
+  viewable_class->preview_thaw         = gimp_layer_mask_preview_thaw;
 
-  item_class->is_attached        = gimp_layer_mask_is_attached;
-  item_class->is_content_locked  = gimp_layer_mask_is_content_locked;
-  item_class->is_position_locked = gimp_layer_mask_is_position_locked;
-  item_class->get_tree           = gimp_layer_mask_get_tree;
-  item_class->duplicate          = gimp_layer_mask_duplicate;
-  item_class->rename             = gimp_layer_mask_rename;
-  item_class->translate_desc     = C_("undo-type", "Move Layer Mask");
-  item_class->to_selection_desc  = C_("undo-type", "Layer Mask to Selection");
+  item_class->is_attached              = gimp_layer_mask_is_attached;
+  item_class->is_content_locked        = gimp_layer_mask_is_content_locked;
+  item_class->is_position_locked       = gimp_layer_mask_is_position_locked;
+  item_class->get_tree                 = gimp_layer_mask_get_tree;
+  item_class->duplicate                = gimp_layer_mask_duplicate;
+  item_class->rename                   = gimp_layer_mask_rename;
+  item_class->translate_desc           = C_("undo-type", "Move Layer Mask");
+  item_class->to_selection_desc        = C_("undo-type", "Layer Mask to Selection");
 
-  drawable_class->convert_type   = gimp_layer_mask_convert_type;
+  drawable_class->bounding_box_changed = gimp_layer_mask_bounding_box_changed;
+  drawable_class->convert_type         = gimp_layer_mask_convert_type;
 }
 
 static void
@@ -197,6 +199,19 @@ gimp_layer_mask_rename (GimpItem     *item,
   return FALSE;
 }
 
+static void
+gimp_layer_mask_bounding_box_changed (GimpDrawable *drawable)
+{
+  GimpLayerMask *mask  = GIMP_LAYER_MASK (drawable);
+  GimpLayer     *layer = gimp_layer_mask_get_layer (mask);
+
+  if (GIMP_DRAWABLE_CLASS (parent_class)->bounding_box_changed)
+    GIMP_DRAWABLE_CLASS (parent_class)->bounding_box_changed (drawable);
+
+  if (layer)
+    gimp_drawable_update_bounding_box (GIMP_DRAWABLE (layer));
+}
+
 static void
 gimp_layer_mask_convert_type (GimpDrawable      *drawable,
                               GimpImage         *dest_image,


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