[gimp/gimp-2-10] app: in GimpImage, ignore "show all" when image used as pickable



commit ceb8b398ca1fb33acd17ee6f2efcb8c27dc5b551
Author: Ell <ell_se yahoo com>
Date:   Wed Sep 4 14:42:55 2019 +0300

    app: in GimpImage, ignore "show all" when image used as pickable
    
    In GimpImage, make sure the image's pickable interface keeps
    behaving as before (i.e., restricted to the canvas size), even when
    the image is in "show all" mode.  In contrast, the image's
    projection, when used as a pickable, *is* affected by "show all".

 app/core/gimpimage-private.h |  1 +
 app/core/gimpimage.c         | 82 ++++++++++++++++++++++++++++++++++++++------
 2 files changed, 72 insertions(+), 11 deletions(-)
---
diff --git a/app/core/gimpimage-private.h b/app/core/gimpimage-private.h
index a8fdc2fb61..7bbaa04183 100644
--- a/app/core/gimpimage-private.h
+++ b/app/core/gimpimage-private.h
@@ -51,6 +51,7 @@ struct _GimpImagePrivate
 
   gint               show_all;              /*  render full image content    */
   GeglRectangle      bounding_box;          /*  image content bounding box   */
+  GeglBuffer        *pickable_buffer;
 
   guchar            *colormap;              /*  colormap (for indexed)       */
   gint               n_colors;              /*  # of colors (for indexed)    */
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index 2434b4a85a..4a6b65679e 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -37,6 +37,7 @@
 #include "operations/layer-modes/gimp-layer-modes.h"
 
 #include "gegl/gimp-babl.h"
+#include "gegl/gimp-gegl-loops.h"
 
 #include "gimp.h"
 #include "gimp-memsize.h"
@@ -222,6 +223,10 @@ static void         gimp_image_srgb_to_pixel     (GimpPickable      *pickable,
                                                   const Babl        *format,
                                                   gpointer           pixel);
 
+static void     gimp_image_projection_buffer_notify
+                                                 (GimpProjection    *projection,
+                                                  const GParamSpec  *pspec,
+                                                  GimpImage         *image);
 static void     gimp_image_mask_update           (GimpDrawable      *drawable,
                                                   gint               x,
                                                   gint               y,
@@ -734,6 +739,7 @@ gimp_image_init (GimpImage *image)
   private->bounding_box.y      = 0;
   private->bounding_box.width  = 0;
   private->bounding_box.height = 0;
+  private->pickable_buffer     = NULL;
 
   private->colormap            = NULL;
   private->n_colors            = 0;
@@ -774,6 +780,10 @@ gimp_image_init (GimpImage *image)
                                                      GIMP_TYPE_VECTORS);
   private->layer_stack         = NULL;
 
+  g_signal_connect (private->projection, "notify::buffer",
+                    G_CALLBACK (gimp_image_projection_buffer_notify),
+                    image);
+
   g_signal_connect (private->layers, "notify::active-item",
                     G_CALLBACK (gimp_image_active_layer_notify),
                     image);
@@ -1092,6 +1102,7 @@ gimp_image_finalize (GObject *object)
   if (private->color_profile)
     _gimp_image_free_color_profile (image);
 
+  g_clear_object (&private->pickable_buffer);
   g_clear_object (&private->metadata);
   g_clear_object (&private->file);
   g_clear_object (&private->imported_file);
@@ -1271,6 +1282,8 @@ gimp_image_size_changed (GimpViewable *viewable)
 
   gimp_image_metadata_update_pixel_size (image);
 
+  g_clear_object (&GIMP_IMAGE_GET_PRIVATE (image)->pickable_buffer);
+
   gimp_image_update_bounding_box (image);
 }
 
@@ -1464,9 +1477,30 @@ gimp_image_pickable_flush (GimpPickable *pickable)
 static GeglBuffer *
 gimp_image_get_buffer (GimpPickable *pickable)
 {
-  GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (pickable);
+  GimpImage        *image   = GIMP_IMAGE (pickable);
+  GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
+
+  if (! private->pickable_buffer)
+    {
+      GeglBuffer *buffer;
+
+      buffer = gimp_pickable_get_buffer (GIMP_PICKABLE (private->projection));
+
+      if (! private->show_all)
+        {
+          private->pickable_buffer = g_object_ref (buffer);
+        }
+      else
+        {
+          private->pickable_buffer = gegl_buffer_create_sub_buffer (
+            buffer,
+            GEGL_RECTANGLE (0, 0,
+                            gimp_image_get_width  (image),
+                            gimp_image_get_height (image)));
+        }
+    }
 
-  return gimp_pickable_get_buffer (GIMP_PICKABLE (private->projection));
+  return private->pickable_buffer;
 }
 
 static gboolean
@@ -1476,10 +1510,19 @@ gimp_image_get_pixel_at (GimpPickable *pickable,
                          const Babl   *format,
                          gpointer      pixel)
 {
-  GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (pickable);
+  GimpImage        *image   = GIMP_IMAGE (pickable);
+  GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
+
+  if (x >= 0                            &&
+      y >= 0                            &&
+      x < gimp_image_get_width  (image) &&
+      y < gimp_image_get_height (image))
+    {
+      return gimp_pickable_get_pixel_at (GIMP_PICKABLE (private->projection),
+                                         x, y, format, pixel);
+    }
 
-  return gimp_pickable_get_pixel_at (GIMP_PICKABLE (private->projection),
-                                     x, y, format, pixel);
+  return FALSE;
 }
 
 static gdouble
@@ -1487,10 +1530,19 @@ gimp_image_get_opacity_at (GimpPickable *pickable,
                            gint          x,
                            gint          y)
 {
-  GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (pickable);
+  GimpImage        *image   = GIMP_IMAGE (pickable);
+  GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
 
-  return gimp_pickable_get_opacity_at (GIMP_PICKABLE (private->projection),
-                                       x, y);
+  if (x >= 0                            &&
+      y >= 0                            &&
+      x < gimp_image_get_width  (image) &&
+      y < gimp_image_get_height (image))
+    {
+      return gimp_pickable_get_opacity_at (GIMP_PICKABLE (private->projection),
+                                           x, y);
+    }
+
+  return FALSE;
 }
 
 static void
@@ -1499,10 +1551,10 @@ gimp_image_get_pixel_average (GimpPickable        *pickable,
                               const Babl          *format,
                               gpointer             pixel)
 {
-  GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (pickable);
+  GeglBuffer *buffer = gimp_pickable_get_buffer (pickable);
 
-  return gimp_pickable_get_pixel_average (GIMP_PICKABLE (private->projection),
-                                          rect, format, pixel);
+  return gimp_gegl_average_color (buffer, rect, TRUE, GEGL_ABYSS_NONE, format,
+                                  pixel);
 }
 
 static void
@@ -1581,6 +1633,14 @@ gimp_image_get_graph (GimpProjectable *projectable)
   return private->graph;
 }
 
+static void
+gimp_image_projection_buffer_notify (GimpProjection   *projection,
+                                     const GParamSpec *pspec,
+                                     GimpImage        *image)
+{
+  g_clear_object (&GIMP_IMAGE_GET_PRIVATE (image)->pickable_buffer);
+}
+
 static void
 gimp_image_mask_update (GimpDrawable *drawable,
                         gint          x,


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