mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-11 09:40:42 +00:00
Added support for 4 and 8 connected pixel fill method in paint bucket
This commit is contained in:
parent
39d229b0e9
commit
a08cfa9e13
@ -46,6 +46,10 @@
|
||||
<value id="ACTIVE_LAYER" value="0" />
|
||||
<value id="ALL_LAYERS" value="1" />
|
||||
</enum>
|
||||
<enum id="PixelConnectivity">
|
||||
<value id="FOUR_CONNECTED" value="0" />
|
||||
<value id="EIGHT_CONNECTED" value="1" />
|
||||
</enum>
|
||||
<enum id="EyedropperChannel">
|
||||
<value id="COLOR_ALPHA" value="0" />
|
||||
<value id="COLOR" value="1" />
|
||||
@ -358,6 +362,7 @@
|
||||
<section id="floodfill">
|
||||
<option id="stop_at_grid" type="StopAtGrid" default="StopAtGrid::NEVER" />
|
||||
<option id="refer_to" type="FillReferTo" default="FillReferTo::ACTIVE_LAYER" />
|
||||
<option id="pixel_connectivity" type="PixelConnectivity" default="PixelConnectivity::FOUR_CONNECTED" />
|
||||
</section>
|
||||
</tool>
|
||||
|
||||
|
@ -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)
|
||||
|
@ -103,6 +103,7 @@ public:
|
||||
get_pixel(srcImage, pt.x, pt.y),
|
||||
loop->getTolerance(),
|
||||
loop->getContiguous(),
|
||||
loop->isPixelConnectivityEightConnected(),
|
||||
loop, (AlgoHLine)doInkHline);
|
||||
}
|
||||
|
||||
|
@ -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.)
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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;
|
||||
|
@ -26,6 +26,7 @@ namespace doc {
|
||||
const doc::color_t srcColor,
|
||||
const int tolerance,
|
||||
const bool contiguous,
|
||||
const bool isEightConnected,
|
||||
void* data,
|
||||
AlgoHLine proc);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user