[gimp/goat-invasion] app: return double not int from GimpPickable::get_opacity_at()



commit 5d8555a5721d142abe14465ccf4c8f1cbc34c201
Author: Michael Natterer <mitch gimp org>
Date:   Sat Apr 21 16:05:49 2012 +0200

    app: return double not int from GimpPickable::get_opacity_at()
    
    and fix GimpLayer's impl to honor the mask also for layers without
    alpha.

 app/core/gimpchannel.c              |   37 +++++++++++++---------------------
 app/core/gimpgrouplayer.c           |    8 +++---
 app/core/gimpimage-pick-layer.c     |    4 +-
 app/core/gimplayer.c                |   30 +++++++++++++---------------
 app/core/gimppickable.c             |    6 ++--
 app/core/gimppickable.h             |    4 +-
 app/core/gimpprojection.c           |    6 ++--
 app/gegl/gimp-gegl.c                |    6 +++++
 app/pdb/selection-cmds.c            |    9 +++++++-
 app/tools/gimprectangleselecttool.c |    3 +-
 tools/pdbgen/pdb/selection.pdb      |   10 +++++++-
 11 files changed, 65 insertions(+), 58 deletions(-)
---
diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c
index 03dd8ca..7ad30e8 100644
--- a/app/core/gimpchannel.c
+++ b/app/core/gimpchannel.c
@@ -167,7 +167,7 @@ static void      gimp_channel_swap_pixels    (GimpDrawable        *drawable,
                                               gint                 x,
                                               gint                 y);
 
-static gint      gimp_channel_get_opacity_at (GimpPickable        *pickable,
+static gdouble   gimp_channel_get_opacity_at (GimpPickable        *pickable,
                                               gint                 x,
                                               gint                 y);
 
@@ -941,38 +941,29 @@ gimp_channel_swap_pixels (GimpDrawable *drawable,
   GIMP_CHANNEL (drawable)->bounds_known = FALSE;
 }
 
-static gint
+static gdouble
 gimp_channel_get_opacity_at (GimpPickable *pickable,
                              gint          x,
                              gint          y)
 {
   GimpChannel *channel = GIMP_CHANNEL (pickable);
-  guchar       value;
+  gdouble      value   = GIMP_OPACITY_TRANSPARENT;
 
-  /*  Some checks to cut back on unnecessary work  */
-  if (channel->bounds_known)
+  if (x >= 0 && x < gimp_item_get_width  (GIMP_ITEM (channel)) &&
+      y >= 0 && y < gimp_item_get_height (GIMP_ITEM (channel)))
     {
-      if (channel->empty   ||
-          x <  channel->x1 ||
-          x >= channel->x2 ||
-          y <  channel->y1 ||
-          y >= channel->y2)
+      if (! channel->bounds_known ||
+          (! channel->empty &&
+           x >= channel->x1 &&
+           x <  channel->x2 &&
+           y >= channel->y1 &&
+           y <  channel->y2))
         {
-          return 0;
+          gegl_buffer_sample (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
+                              x, y, NULL, &value, babl_format ("Y double"),
+                              GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
         }
     }
-  else
-    {
-      if (x < 0 || x >= gimp_item_get_width  (GIMP_ITEM (channel)) ||
-          y < 0 || y >= gimp_item_get_height (GIMP_ITEM (channel)))
-        {
-          return 0;
-        }
-    }
-
-  gegl_buffer_sample (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
-                      x, y, NULL, &value, babl_format ("Y u8"),
-                      GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
 
   return value;
 }
diff --git a/app/core/gimpgrouplayer.c b/app/core/gimpgrouplayer.c
index 9049c84..8a3ec37 100644
--- a/app/core/gimpgrouplayer.c
+++ b/app/core/gimpgrouplayer.c
@@ -141,8 +141,7 @@ static void            gimp_group_layer_convert_type (GimpDrawable      *drawabl
 static const Babl    * gimp_group_layer_get_format   (GimpProjectable *projectable);
 static GeglNode      * gimp_group_layer_get_graph    (GimpProjectable *projectable);
 static GList         * gimp_group_layer_get_layers   (GimpProjectable *projectable);
-static gint            gimp_group_layer_get_opacity_at
-                                                     (GimpPickable    *pickable,
+static gdouble       gimp_group_layer_get_opacity_at (GimpPickable    *pickable,
                                                       gint             x,
                                                       gint             y);
 
@@ -940,13 +939,14 @@ gimp_group_layer_get_layers (GimpProjectable *projectable)
   return gimp_item_stack_get_item_iter (GIMP_ITEM_STACK (private->children));
 }
 
-static gint
+static gdouble
 gimp_group_layer_get_opacity_at (GimpPickable *pickable,
                                  gint          x,
                                  gint          y)
 {
   /* Only consider child layers as having content */
-  return 0;
+
+  return GIMP_OPACITY_TRANSPARENT;
 }
 
 
diff --git a/app/core/gimpimage-pick-layer.c b/app/core/gimpimage-pick-layer.c
index 70e5c91..8446f16 100644
--- a/app/core/gimpimage-pick-layer.c
+++ b/app/core/gimpimage-pick-layer.c
@@ -49,7 +49,7 @@ gimp_image_pick_layer (const GimpImage *image,
       gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y);
 
       if (gimp_pickable_get_opacity_at (GIMP_PICKABLE (layer),
-                                        x - off_x, y - off_y) > 63)
+                                        x - off_x, y - off_y) > 0.25)
         {
           g_list_free (all_layers);
 
@@ -134,7 +134,7 @@ gimp_image_pick_text_layer (const GimpImage *image,
           return GIMP_TEXT_LAYER (layer);
         }
       else if (gimp_pickable_get_opacity_at (GIMP_PICKABLE (layer),
-                                             x - off_x, y - off_y) > 63)
+                                             x - off_x, y - off_y) > 0.25)
         {
           /*  a normal layer covers any possible text layers below,
            *  bail out
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index 453cd4f..29c350b 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -159,7 +159,7 @@ static void    gimp_layer_invalidate_boundary   (GimpDrawable       *drawable);
 static void    gimp_layer_get_active_components (const GimpDrawable *drawable,
                                                  gboolean           *active);
 
-static gint    gimp_layer_get_opacity_at        (GimpPickable       *pickable,
+static gdouble gimp_layer_get_opacity_at        (GimpPickable       *pickable,
                                                  gint                x,
                                                  gint                y);
 
@@ -960,39 +960,37 @@ gimp_layer_get_active_components (const GimpDrawable *drawable,
     active[gimp_drawable_bytes (drawable) - 1] = FALSE;
 }
 
-static gint
+static gdouble
 gimp_layer_get_opacity_at (GimpPickable *pickable,
                            gint          x,
                            gint          y)
 {
   GimpLayer *layer = GIMP_LAYER (pickable);
-  guchar     value = 0;
+  gdouble    value = GIMP_OPACITY_TRANSPARENT;
 
   if (x >= 0 && x < gimp_item_get_width  (GIMP_ITEM (layer)) &&
       y >= 0 && y < gimp_item_get_height (GIMP_ITEM (layer)) &&
       gimp_item_get_visible (GIMP_ITEM (layer)))
     {
-      /*  If the point is inside, and the layer has no
-       *  alpha channel, success!
-       */
       if (! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
-        return OPAQUE_OPACITY;
-
-      /*  Otherwise, determine if the alpha value at
-       *  the given point is non-zero
-       */
-      gegl_buffer_sample (gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
-                          x, y, NULL, &value, babl_format ("A u8"),
-                          GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
+        {
+          value = GIMP_OPACITY_OPAQUE;
+        }
+      else
+        {
+          gegl_buffer_sample (gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
+                              x, y, NULL, &value, babl_format ("A double"),
+                              GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
+        }
 
       if (layer->mask)
         {
-          gint mask_value;
+          gdouble mask_value;
 
           mask_value = gimp_pickable_get_opacity_at (GIMP_PICKABLE (layer->mask),
                                                      x, y);
 
-          value = value * mask_value / 255;
+          value *= mask_value;
         }
     }
 
diff --git a/app/core/gimppickable.c b/app/core/gimppickable.c
index 319a80c..e3638f6 100644
--- a/app/core/gimppickable.c
+++ b/app/core/gimppickable.c
@@ -193,21 +193,21 @@ gimp_pickable_get_color_at (GimpPickable *pickable,
   return TRUE;
 }
 
-gint
+gdouble
 gimp_pickable_get_opacity_at (GimpPickable *pickable,
                               gint          x,
                               gint          y)
 {
   GimpPickableInterface *pickable_iface;
 
-  g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), 0);
+  g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), GIMP_OPACITY_TRANSPARENT);
 
   pickable_iface = GIMP_PICKABLE_GET_INTERFACE (pickable);
 
   if (pickable_iface->get_opacity_at)
     return pickable_iface->get_opacity_at (pickable, x, y);
 
-  return 0;
+  return GIMP_OPACITY_TRANSPARENT;
 }
 
 gboolean
diff --git a/app/core/gimppickable.h b/app/core/gimppickable.h
index c894a81..db174d4 100644
--- a/app/core/gimppickable.h
+++ b/app/core/gimppickable.h
@@ -46,7 +46,7 @@ struct _GimpPickableInterface
                                              gint          y,
                                              const Babl   *format,
                                              gpointer      pixel);
-  gint            (* get_opacity_at)        (GimpPickable *pickable,
+  gdouble         (* get_opacity_at)        (GimpPickable *pickable,
                                              gint          x,
                                              gint          y);
 };
@@ -69,7 +69,7 @@ gboolean        gimp_pickable_get_color_at          (GimpPickable *pickable,
                                                      gint          x,
                                                      gint          y,
                                                      GimpRGB      *color);
-gint            gimp_pickable_get_opacity_at        (GimpPickable *pickable,
+gdouble         gimp_pickable_get_opacity_at        (GimpPickable *pickable,
                                                      gint          x,
                                                      gint          y);
 
diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c
index 028c485..ba8f8da 100644
--- a/app/core/gimpprojection.c
+++ b/app/core/gimpprojection.c
@@ -69,7 +69,7 @@ static gboolean    gimp_projection_get_pixel_at          (GimpPickable    *picka
                                                           gint             y,
                                                           const Babl      *format,
                                                           gpointer         pixel);
-static gint        gimp_projection_get_opacity_at        (GimpPickable    *pickable,
+static gdouble     gimp_projection_get_opacity_at        (GimpPickable    *pickable,
                                                           gint             x,
                                                           gint             y);
 
@@ -356,12 +356,12 @@ gimp_projection_get_pixel_at (GimpPickable *pickable,
   return TRUE;
 }
 
-static gint
+static gdouble
 gimp_projection_get_opacity_at (GimpPickable *pickable,
                                 gint          x,
                                 gint          y)
 {
-  return OPAQUE_OPACITY;
+  return GIMP_OPACITY_OPAQUE;
 }
 
 GimpProjection *
diff --git a/app/gegl/gimp-gegl.c b/app/gegl/gimp-gegl.c
index 577bef3..758508e 100644
--- a/app/gegl/gimp-gegl.c
+++ b/app/gegl/gimp-gegl.c
@@ -134,6 +134,12 @@ gimp_gegl_init (Gimp *gimp)
                    babl_component ("A"),
                    NULL);
 
+  babl_format_new ("name", "A double",
+                   babl_model ("R'G'B'A"),
+                   babl_type ("double"),
+                   babl_component ("A"),
+                   NULL);
+
   g_type_class_ref (GIMP_TYPE_OPERATION_BORDER);
   g_type_class_ref (GIMP_TYPE_OPERATION_CAGE_COEF_CALC);
   g_type_class_ref (GIMP_TYPE_OPERATION_CAGE_TRANSFORM);
diff --git a/app/pdb/selection-cmds.c b/app/pdb/selection-cmds.c
index cfbcf13..6854a11 100644
--- a/app/pdb/selection-cmds.c
+++ b/app/pdb/selection-cmds.c
@@ -21,6 +21,8 @@
 
 #include <gegl.h>
 
+#include "libgimpmath/gimpmath.h"
+
 #include "pdb-types.h"
 
 #include "core/gimpchannel.h"
@@ -100,7 +102,12 @@ selection_value_invoker (GimpProcedure      *procedure,
 
   if (success)
     {
-      value = gimp_pickable_get_opacity_at (GIMP_PICKABLE (gimp_image_get_mask (image)), x, y);
+      gdouble val;
+
+      val= gimp_pickable_get_opacity_at (GIMP_PICKABLE (gimp_image_get_mask (image)),
+                                         x, y);
+
+      value = ROUND (CLAMP (val, 0.0, 1.0) * 255.0);
     }
 
   return_vals = gimp_procedure_get_return_values (procedure, success,
diff --git a/app/tools/gimprectangleselecttool.c b/app/tools/gimprectangleselecttool.c
index 6261bfa..2f80f36 100644
--- a/app/tools/gimprectangleselecttool.c
+++ b/app/tools/gimprectangleselecttool.c
@@ -25,7 +25,6 @@
 
 #include "tools-types.h"
 
-#include "core/gimpboundary.h"
 #include "core/gimpchannel.h"
 #include "core/gimpchannel-select.h"
 #include "core/gimplayer-floating-sel.h"
@@ -758,7 +757,7 @@ gimp_rectangle_select_tool_execute (GimpRectangleTool *rectangle,
 
       /*  if the click was inside the marching ants  */
       if (gimp_pickable_get_opacity_at (GIMP_PICKABLE (selection),
-                                        pressx, pressy) > GIMP_BOUNDARY_HALF_WAY)
+                                        pressx, pressy) > 0.5)
         {
           gint x1, y1, x2, y2;
 
diff --git a/tools/pdbgen/pdb/selection.pdb b/tools/pdbgen/pdb/selection.pdb
index aed5701..1acf588 100644
--- a/tools/pdbgen/pdb/selection.pdb
+++ b/tools/pdbgen/pdb/selection.pdb
@@ -86,7 +86,12 @@ HELP
     %invoke = (
 	code => <<'CODE'
 {
-  value = gimp_pickable_get_opacity_at (GIMP_PICKABLE (gimp_image_get_mask (image)), x, y);
+  gdouble val;
+
+  val= gimp_pickable_get_opacity_at (GIMP_PICKABLE (gimp_image_get_mask (image)),
+                                     x, y);
+
+  value = ROUND (CLAMP (val, 0.0, 1.0) * 255.0);
 }
 CODE
     );
@@ -512,7 +517,8 @@ CODE
     );
 }
 
- headers = qw("core/gimppickable.h"
+ headers = qw("libgimpmath/gimpmath.h"
+              "core/gimppickable.h"
               "gimppdb-utils.h"
               "gimp-intl.h");
 



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