diff --git a/data/pref.xml b/data/pref.xml index 9a4212402..ae8c27c9b 100644 --- a/data/pref.xml +++ b/data/pref.xml @@ -46,6 +46,10 @@ + + + + @@ -358,6 +362,7 @@
diff --git a/src/app/script/values.cpp b/src/app/script/values.cpp index a76836886..012275ef4 100644 --- a/src/app/script/values.cpp +++ b/src/app/script/values.cpp @@ -155,6 +155,7 @@ FOR_ENUM(app::gen::HueSaturationMode) FOR_ENUM(app::gen::OnionskinType) FOR_ENUM(app::gen::PaintingCursorType) FOR_ENUM(app::gen::PivotPosition) +FOR_ENUM(app::gen::PixelConnectivity) FOR_ENUM(app::gen::RightClickMode) FOR_ENUM(app::gen::SelectionMode) FOR_ENUM(app::gen::StopAtGrid) diff --git a/src/app/tools/point_shapes.h b/src/app/tools/point_shapes.h index a3a5ecd7c..e45e048f6 100644 --- a/src/app/tools/point_shapes.h +++ b/src/app/tools/point_shapes.h @@ -103,6 +103,7 @@ public: get_pixel(srcImage, pt.x, pt.y), loop->getTolerance(), loop->getContiguous(), + loop->isPixelConnectivityEightConnected(), loop, (AlgoHLine)doInkHline); } diff --git a/src/app/tools/tool_loop.h b/src/app/tools/tool_loop.h index eb6726ac8..9c6a2ea37 100644 --- a/src/app/tools/tool_loop.h +++ b/src/app/tools/tool_loop.h @@ -182,6 +182,7 @@ namespace app { virtual bool getSnapToGrid() = 0; virtual bool getStopAtGrid() = 0; // For floodfill-like tools virtual gfx::Rect getGridBounds() = 0; + virtual bool isPixelConnectivityEightConnected() = 0; // Returns true if the figure must be filled when we release the // mouse (e.g. a filled rectangle, etc.) diff --git a/src/app/ui/context_bar.cpp b/src/app/ui/context_bar.cpp index f76ab8bcc..d365d541f 100644 --- a/src/app/ui/context_bar.cpp +++ b/src/app/ui/context_bar.cpp @@ -383,6 +383,16 @@ protected: menu.addChild(&activeLayer); menu.addChild(&allLayers); + menu.addChild(new MenuSeparator); + menu.addChild(new Label("Pixel Connectivity:")); + + HBox box; + ButtonSet buttonset(2); + buttonset.addItem("4-Connected"); + buttonset.addItem("8-connected"); + box.addChild(&buttonset); + menu.addChild(&box); + stopAtGrid.setSelected( toolPref.floodfill.stopAtGrid() == app::gen::StopAtGrid::IF_VISIBLE); activeLayer.setSelected( @@ -390,6 +400,15 @@ protected: allLayers.setSelected( toolPref.floodfill.referTo() == app::gen::FillReferTo::ALL_LAYERS); + int index = 0; + + switch (toolPref.floodfill.pixelConnectivity()) { + case app::gen::PixelConnectivity::FOUR_CONNECTED: index = 0; break; + case app::gen::PixelConnectivity::EIGHT_CONNECTED: index = 1; break; + } + + buttonset.setSelectedItem(index); + stopAtGrid.Click.connect( [&]{ toolPref.floodfill.stopAtGrid( @@ -405,6 +424,18 @@ protected: toolPref.floodfill.referTo(app::gen::FillReferTo::ALL_LAYERS); }); + buttonset.ItemChange.connect( + [&buttonset, &toolPref](ButtonSet::Item* item){ + switch (buttonset.selectedItem()) { + case 0: + toolPref.floodfill.pixelConnectivity(app::gen::PixelConnectivity::FOUR_CONNECTED); + break; + case 1: + toolPref.floodfill.pixelConnectivity(app::gen::PixelConnectivity::EIGHT_CONNECTED); + break; + } + }); + menu.showPopup(gfx::Point(bounds.x, bounds.y+bounds.h)); deselectItems(); } diff --git a/src/app/ui/editor/tool_loop_impl.cpp b/src/app/ui/editor/tool_loop_impl.cpp index cb8169b2f..0f4f39a0f 100644 --- a/src/app/ui/editor/tool_loop_impl.cpp +++ b/src/app/ui/editor/tool_loop_impl.cpp @@ -246,6 +246,12 @@ public: } return false; } + + bool isPixelConnectivityEightConnected() override { + return (m_toolPref.floodfill.pixelConnectivity() + == app::gen::PixelConnectivity::EIGHT_CONNECTED); + } + gfx::Rect getGridBounds() override { return m_docPref.grid.bounds(); } gfx::Point getCelOrigin() override { return m_celOrigin; } void setSpeed(const gfx::Point& speed) override { m_speed = speed; } diff --git a/src/doc/algorithm/floodfill.cpp b/src/doc/algorithm/floodfill.cpp index 87c07b63c..c3116e0f2 100644 --- a/src/doc/algorithm/floodfill.cpp +++ b/src/doc/algorithm/floodfill.cpp @@ -346,6 +346,7 @@ void floodfill(const Image* image, const doc::color_t src_color, const int tolerance, const bool contiguous, + const bool isEightConnected, void* data, AlgoHLine proc) { @@ -398,8 +399,39 @@ void floodfill(const Image* image, // Check below the segment? if (p->flags & FLOOD_TODO_BELOW) { p->flags &= ~FLOOD_TODO_BELOW; + + if (isEightConnected) { + if (p->lpos+1 < bounds.x2() && + check_flood_line(image, mask, p->y+1, p->lpos+1, p->rpos, bounds, + src_color, tolerance, data, proc)) { + done = false; + p = FLOOD_LINE(c); + } + + if (p->lpos-1 >= 0 && + check_flood_line(image, mask, p->y+1, p->lpos-1, p->rpos, bounds, + src_color, tolerance, data, proc)) { + done = false; + p = FLOOD_LINE(c); + } + + if (p->rpos+1 < bounds.x2() && + check_flood_line(image, mask, p->y+1, p->lpos, p->rpos+1, bounds, + src_color, tolerance, data, proc)) { + done = false; + p = FLOOD_LINE(c); + } + + if (p->rpos-1 >= 0 && + check_flood_line(image, mask, p->y+1, p->lpos, p->rpos-1, bounds, + src_color, tolerance, data, proc)) { + done = false; + p = FLOOD_LINE(c); + } + } + if (check_flood_line(image, mask, p->y+1, p->lpos, p->rpos, bounds, - src_color, tolerance, data, proc)) { + src_color, tolerance, data, proc)) { done = false; p = FLOOD_LINE(c); } @@ -408,6 +440,31 @@ void floodfill(const Image* image, // Check above the segment? if (p->flags & FLOOD_TODO_ABOVE) { p->flags &= ~FLOOD_TODO_ABOVE; + + if (isEightConnected) { + if (p->lpos+1 < bounds.x2() && + check_flood_line(image, mask, p->y-1, p->lpos+1, p->rpos, bounds, + src_color, tolerance, data, proc)) { + done = false; + } + if (p->lpos-1 >= 0 && + check_flood_line(image, mask, p->y-1, p->lpos-1, p->rpos, bounds, + src_color, tolerance, data, proc)) { + done = false; + } + + if (p->rpos+1 < bounds.x2() && + check_flood_line(image, mask, p->y-1, p->lpos, p->rpos+1, bounds, + src_color, tolerance, data, proc)) { + done = false; + } + if (p->rpos-1 >= 0 && + check_flood_line(image, mask, p->y-1, p->lpos, p->rpos-1, bounds, + src_color, tolerance, data, proc)) { + done = false; + } + } + if (check_flood_line(image, mask, p->y-1, p->lpos, p->rpos, bounds, src_color, tolerance, data, proc)) { done = false; diff --git a/src/doc/algorithm/floodfill.h b/src/doc/algorithm/floodfill.h index 5bed5f767..e4fd37a08 100644 --- a/src/doc/algorithm/floodfill.h +++ b/src/doc/algorithm/floodfill.h @@ -26,6 +26,7 @@ namespace doc { const doc::color_t srcColor, const int tolerance, const bool contiguous, + const bool isEightConnected, void* data, AlgoHLine proc);