[gimp] app: eliminate double application of the selection mask ...



commit bd5544394b87075aae9c6905bc012d1ac7ceb188
Author: Ell <ell_se yahoo com>
Date:   Thu Jun 30 16:24:14 2016 +0000

    app: eliminate double application of the selection mask ...
    
    ... in gimp_drawable_bucket_fill()
    
    gimp_drawable_apply_buffer() already takes the selection mask into
    account.  Intersecting the selection mask with the fill region
    prior to that leads to wrong (too low) alpha values, in general,
    when partial selection is involved.
    
    This commit eliminates the intersection of the fill region and
    selection mask data before the apply_buffer() call, although it
    does calculate the intersection of their bounds, to avoid
    processing regions that won't be visible anyway.

 app/core/gimpdrawable-bucket-fill.c |   51 ++++++++++++++++++++++++-----------
 1 files changed, 35 insertions(+), 16 deletions(-)
---
diff --git a/app/core/gimpdrawable-bucket-fill.c b/app/core/gimpdrawable-bucket-fill.c
index b2b4a08..98ea706 100644
--- a/app/core/gimpdrawable-bucket-fill.c
+++ b/app/core/gimpdrawable-bucket-fill.c
@@ -21,6 +21,7 @@
 #include <gegl.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
+#include "libgimpbase/gimpbase.h"
 #include "libgimpcolor/gimpcolor.h"
 
 #include "core-types.h"
@@ -62,6 +63,7 @@ gimp_drawable_bucket_fill (GimpDrawable         *drawable,
   gint          mask_offset_x = 0;
   gint          mask_offset_y = 0;
   gboolean      selection;
+  gint          sel_x1, sel_y1, sel_x2, sel_y2;
 
   g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
   g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
@@ -69,9 +71,10 @@ gimp_drawable_bucket_fill (GimpDrawable         *drawable,
 
   image = gimp_item_get_image (GIMP_ITEM (drawable));
 
-  selection = gimp_item_mask_bounds (GIMP_ITEM (drawable), &x1, &y1, &x2, &y2);
+  selection = gimp_item_mask_bounds (GIMP_ITEM (drawable),
+                                     &sel_x1, &sel_y1, &sel_x2, &sel_y2);
 
-  if ((x1 == x2) || (y1 == y2))
+  if ((sel_x1 == sel_x2) || (sel_y1 == sel_y2))
     return;
 
   gimp_set_busy (image->gimp);
@@ -82,8 +85,7 @@ gimp_drawable_bucket_fill (GimpDrawable         *drawable,
     pickable = GIMP_PICKABLE (drawable);
 
   /*  Do a seed bucket fill...To do this, calculate a new
-   *  contiguous region. If there is a selection, calculate the
-   *  intersection of this region with the existing selection.
+   *  contiguous region.
    */
   mask_buffer = gimp_pickable_contiguous_region_by_seed (pickable,
                                                          TRUE,
@@ -94,25 +96,42 @@ gimp_drawable_bucket_fill (GimpDrawable         *drawable,
                                                          (gint) x,
                                                          (gint) y);
 
+  gimp_gegl_mask_bounds (mask_buffer, &x1, &y1, &x2, &y2);
+
+  /*  If there is a selection, inersect the region bounds
+   *  with the selection bounds, to avoid processing areas
+   *  that are going to be masked out anyway.  The actual
+   *  intersection of the fill region with the mask data
+   *  happens when combining the fill buffer, in
+   *  gimp_drawable_apply_buffer().
+   */
   if (selection)
     {
-      GimpDrawable *sel;
-      gint          off_x = 0;
-      gint          off_y = 0;
+      gint off_x = 0;
+      gint off_y = 0;
 
-      if (! sample_merged)
+      if (sample_merged)
         gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
 
-      sel = GIMP_DRAWABLE (gimp_image_get_mask (image));
-
-      gimp_gegl_mask_combine_buffer (mask_buffer,
-                                     gimp_drawable_get_buffer (sel),
-                                     GIMP_CHANNEL_OP_INTERSECT,
-                                     -off_x, -off_y);
+      if (gimp_rectangle_intersect (x1,              y1,
+                                    x2 - x1,         y2 - y1,
+
+                                    sel_x1 + off_x,  sel_y1 + off_y,
+                                    sel_x2 - sel_x1, sel_y2 - sel_y1,
+
+                                    &x1,             &y1,
+                                    &x2,             &y2))
+        {
+          x2 += x1;
+          y2 += y1;
+        }
+      else
+        {
+          /*  The fill region and the selection are disjoint; bail.  */
+          return;
+        }
     }
 
-  gimp_gegl_mask_bounds (mask_buffer, &x1, &y1, &x2, &y2);
-
   /*  make sure we handle the mask correctly if it was sample-merged  */
   if (sample_merged)
     {


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