[aseprite] 233/250: Use mask in flood fill as edges (fix #823)

Tobias Hansen thansen at moszumanska.debian.org
Sun Dec 20 15:27:34 UTC 2015


This is an automated email from the git hooks/post-receive script.

thansen pushed a commit to branch master
in repository aseprite.

commit 4a67a96edd8cfc63843fee7b7607fc97ed82979d
Author: David Capello <davidcapello at gmail.com>
Date:   Wed Nov 4 16:48:25 2015 -0300

    Use mask in flood fill as edges (fix #823)
---
 src/app/tools/point_shapes.h    |  4 ++-
 src/doc/algorithm/floodfill.cpp | 60 ++++++++++++++++++++++++++---------------
 src/doc/algorithm/floodfill.h   |  5 +++-
 3 files changed, 46 insertions(+), 23 deletions(-)

diff --git a/src/app/tools/point_shapes.h b/src/app/tools/point_shapes.h
index d524768..292f3a1 100644
--- a/src/app/tools/point_shapes.h
+++ b/src/app/tools/point_shapes.h
@@ -83,7 +83,9 @@ public:
 
   void transformPoint(ToolLoop* loop, int x, int y) override {
     doc::algorithm::floodfill(
-      const_cast<Image*>(loop->getSrcImage()), x, y,
+      loop->getSrcImage(),
+      (loop->useMask() ? loop->getMask(): nullptr),
+      x, y,
       floodfillBounds(loop, x, y),
       loop->getTolerance(),
       loop->getContiguous(),
diff --git a/src/doc/algorithm/floodfill.cpp b/src/doc/algorithm/floodfill.cpp
index e278eba..bba44f3 100644
--- a/src/doc/algorithm/floodfill.cpp
+++ b/src/doc/algorithm/floodfill.cpp
@@ -1,8 +1,10 @@
 // The floodfill routine.
 // By Shawn Hargreaves.
 //
-// Adapted to Aseprite by David Capello
-// Added non-contiguous mode by David Capello
+// Changes by David Capello:
+// - Adapted to Aseprite
+// - Added non-contiguous mode
+// - Added mask parameter
 //
 // This file is released under the terms of the MIT license.
 // Read LICENSE.txt for more information.
@@ -15,7 +17,9 @@
 
 #include "doc/algo.h"
 #include "doc/image.h"
+#include "doc/mask.h"
 #include "doc/primitives.h"
+#include "doc/primitives_fast.h"
 
 #include <climits>
 #include <cmath>
@@ -125,10 +129,20 @@ inline bool color_equal<IndexedTraits>(color_t c1, color_t c2, int tolerance)
  *  to the list of drawn segments. Returns the first x coordinate after
  *  the part of the line which it has dealt with.
  */
-static int flooder(const Image* image, int x, int y,
+static int flooder(const Image* image,
+                   const Mask* mask,
+                   int x, int y,
                    const gfx::Rect& bounds,
                    color_t src_color, int tolerance, void *data, AlgoHLine proc)
 {
+#define MASKED(u, v)                                                    \
+        (mask &&                                                        \
+         (!mask->bounds().contains(u, v) ||                             \
+          (mask->bitmap() &&                                            \
+           !get_pixel_fast<BitmapTraits>(mask->bitmap(),                \
+                                         (u)-mask->bounds().x,          \
+                                         (v)-mask->bounds().y))))
+
   FLOODED_LINE *p;
   int left = 0, right = 0;
   int c;
@@ -140,18 +154,18 @@ static int flooder(const Image* image, int x, int y,
         uint32_t* address = reinterpret_cast<uint32_t*>(image->getPixelAddress(0, y));
 
         // Check start pixel
-        if (!color_equal_32((int)*(address+x), src_color, tolerance))
+        if (!color_equal_32((int)*(address+x), src_color, tolerance) || MASKED(x, y))
           return x+1;
 
         // Work left from starting point
         for (left=x-1; left>=bounds.x; left--) {
-          if (!color_equal_32((int)*(address+left), src_color, tolerance))
+          if (!color_equal_32((int)*(address+left), src_color, tolerance) || MASKED(left, y))
             break;
         }
 
         // Work right from starting point
         for (right=x+1; right<bounds.x2(); right++) {
-          if (!color_equal_32((int)*(address+right), src_color, tolerance))
+          if (!color_equal_32((int)*(address+right), src_color, tolerance) || MASKED(right, y))
             break;
         }
       }
@@ -162,18 +176,18 @@ static int flooder(const Image* image, int x, int y,
         uint16_t* address = reinterpret_cast<uint16_t*>(image->getPixelAddress(0, y));
 
         // Check start pixel
-        if (!color_equal_16((int)*(address+x), src_color, tolerance))
+        if (!color_equal_16((int)*(address+x), src_color, tolerance) || MASKED(x, y))
           return x+1;
 
         // Work left from starting point
         for (left=x-1; left>=bounds.x; left--) {
-          if (!color_equal_16((int)*(address+left), src_color, tolerance))
+          if (!color_equal_16((int)*(address+left), src_color, tolerance) || MASKED(left, y))
             break;
         }
 
         // Work right from starting point
         for (right=x+1; right<bounds.x2(); right++) {
-          if (!color_equal_16((int)*(address+right), src_color, tolerance))
+          if (!color_equal_16((int)*(address+right), src_color, tolerance) || MASKED(right, y))
             break;
         }
       }
@@ -184,18 +198,18 @@ static int flooder(const Image* image, int x, int y,
         uint8_t* address = image->getPixelAddress(0, y);
 
         // Check start pixel
-        if (!color_equal_8((int)*(address+x), src_color, tolerance))
+        if (!color_equal_8((int)*(address+x), src_color, tolerance) || MASKED(x, y))
           return x+1;
 
         // Work left from starting point
         for (left=x-1; left>=bounds.x; left--) {
-          if (!color_equal_8((int)*(address+left), src_color, tolerance))
+          if (!color_equal_8((int)*(address+left), src_color, tolerance) || MASKED(left, y))
             break;
         }
 
         // Work right from starting point
         for (right=x+1; right<bounds.x2(); right++) {
-          if (!color_equal_8((int)*(address+right), src_color, tolerance))
+          if (!color_equal_8((int)*(address+right), src_color, tolerance) || MASKED(right, y))
             break;
         }
       }
@@ -203,18 +217,18 @@ static int flooder(const Image* image, int x, int y,
 
     default:
       // Check start pixel
-      if (get_pixel(image, x, y) != src_color)
+      if (get_pixel(image, x, y) != src_color || MASKED(x, y))
         return x+1;
 
       // Work left from starting point
       for (left=x-1; left>=bounds.x; left--) {
-        if (get_pixel(image, left, y) != src_color)
+        if (get_pixel(image, left, y) != src_color || MASKED(left, y))
           break;
       }
 
       // Work right from starting point
       for (right=x+1; right<bounds.x2(); right++) {
-        if (get_pixel(image, right, y) != src_color)
+        if (get_pixel(image, right, y) != src_color || MASKED(right, y))
           break;
       }
       break;
@@ -263,7 +277,9 @@ static int flooder(const Image* image, int x, int y,
  *  segments which have already been drawn in order to minimise the required
  *  number of tests.
  */
-static int check_flood_line(const Image* image, int y, int left, int right,
+static int check_flood_line(const Image* image,
+                            const Mask* mask,
+                            int y, int left, int right,
                             const gfx::Rect& bounds,
                             int src_color, int tolerance, void *data, AlgoHLine proc)
 {
@@ -285,7 +301,7 @@ static int check_flood_line(const Image* image, int y, int left, int right,
       c = p->next;
 
       if (!c) {
-        left = flooder(image, left, y, bounds, src_color, tolerance, data, proc);
+        left = flooder(image, mask, left, y, bounds, src_color, tolerance, data, proc);
         ret = true;
         break;
       }
@@ -322,7 +338,9 @@ static void replace_color(const Image* image, const gfx::Rect& bounds, int src_c
 /* floodfill:
  *  Fills an enclosed area (starting at point x, y) with the specified color.
  */
-void floodfill(const Image* image, int x, int y,
+void floodfill(const Image* image,
+               const Mask* mask,
+               int x, int y,
                const gfx::Rect& bounds,
                int tolerance, bool contiguous,
                void* data,
@@ -365,7 +383,7 @@ void floodfill(const Image* image, int x, int y,
   }
 
   // Start up the flood algorithm
-  flooder(image, x, y, bounds, src_color, tolerance, data, proc);
+  flooder(image, mask, x, y, bounds, src_color, tolerance, data, proc);
 
   // Continue as long as there are some segments still to test
   bool done;
@@ -380,7 +398,7 @@ void floodfill(const Image* image, int x, int y,
       // Check below the segment?
       if (p->flags & FLOOD_TODO_BELOW) {
         p->flags &= ~FLOOD_TODO_BELOW;
-        if (check_flood_line(image, p->y+1, p->lpos, p->rpos, bounds,
+        if (check_flood_line(image, mask, p->y+1, p->lpos, p->rpos, bounds,
             src_color, tolerance, data, proc)) {
           done = false;
           p = FLOOD_LINE(c);
@@ -390,7 +408,7 @@ void floodfill(const Image* image, int x, int y,
       // Check above the segment?
       if (p->flags & FLOOD_TODO_ABOVE) {
         p->flags &= ~FLOOD_TODO_ABOVE;
-        if (check_flood_line(image, p->y-1, p->lpos, p->rpos, bounds,
+        if (check_flood_line(image, mask, p->y-1, p->lpos, p->rpos, bounds,
                              src_color, tolerance, data, proc)) {
           done = false;
           // Special case shortcut for going backwards
diff --git a/src/doc/algorithm/floodfill.h b/src/doc/algorithm/floodfill.h
index 01d939a..eced512 100644
--- a/src/doc/algorithm/floodfill.h
+++ b/src/doc/algorithm/floodfill.h
@@ -14,10 +14,13 @@
 namespace doc {
 
   class Image;
+  class Mask;
 
   namespace algorithm {
 
-    void floodfill(const Image* image, int x, int y,
+    void floodfill(const Image* image,
+                   const Mask* mask,
+                   int x, int y,
                    const gfx::Rect& bounds,
                    int tolerance, bool contiguous,
                    void* data,

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git



More information about the Pkg-games-commits mailing list