Fix slice tool for tiles mode (fix #4306, #4705)

This commit is contained in:
دانتي باولا 2024-10-21 14:58:54 -03:00 committed by GitHub
parent a7799b76fc
commit 85eb64ca35
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 21 deletions

View File

@ -51,6 +51,26 @@ public:
m_proc->prepareUForPointShapeSlicedScanline(loop, leftSlice, x1); m_proc->prepareUForPointShapeSlicedScanline(loop, leftSlice, x1);
} }
// Common to both SelectionInk and SliceInk
gfx::Rect tileSelectionToCanvas(int x1, int y, int x2, ToolLoop* loop, bool offset) {
gfx::Rect rc(x1, y, x2-x1+1, 1);
// For tile point shape, the point shape is done in "tiles"
// coordinates, but we want the selection in canvas/pixels
// coordinates.
if (loop->getPointShape()->isTile()) {
const Grid& grid = loop->getGrid();
rc = grid.tileToCanvas(rc);
if (offset) {
// For feedback purposes, the coordinates must be relative to
// the getDstImage() and not in absolute sprite canvas
// coordinates.
rc.offset(-grid.origin());
}
}
return rc;
}
protected: protected:
void setProc(BaseInkProcessing* proc) { void setProc(BaseInkProcessing* proc) {
m_proc.reset(proc); m_proc.reset(proc);
@ -293,10 +313,17 @@ public:
} }
void inkHline(int x1, int y, int x2, ToolLoop* loop) override { void inkHline(int x1, int y, int x2, ToolLoop* loop) override {
// Map tile coords to canvas if needed
gfx::Rect rc(BaseInk::tileSelectionToCanvas(
x1, y, x2, loop, !m_createSlice));
if (m_createSlice) if (m_createSlice)
m_maxBounds |= gfx::Rect(x1, y, x2-x1+1, 1); m_maxBounds |= rc;
else else {
BaseInk::inkHline(x1, y, x2, loop); rc &= loop->getDstImage()->bounds();
for (int v=rc.y; v<rc.y2(); ++v)
BaseInk::inkHline(rc.x, v, rc.x2()-1, loop);
}
} }
void setFinalStep(ToolLoop* loop, bool state) override { void setFinalStep(ToolLoop* loop, bool state) override {
@ -305,6 +332,7 @@ public:
m_maxBounds = gfx::Rect(0, 0, 0, 0); m_maxBounds = gfx::Rect(0, 0, 0, 0);
} }
else { else {
m_maxBounds &= loop->getDstImage()->bounds();
loop->onSliceRect(m_maxBounds); loop->onSliceRect(m_maxBounds);
} }
} }
@ -448,21 +476,9 @@ public:
} }
void inkHline(int x1, int y, int x2, ToolLoop* loop) override { void inkHline(int x1, int y, int x2, ToolLoop* loop) override {
gfx::Rect rc(x1, y, x2-x1+1, 1); // Map tile coords to canvas if needed
gfx::Rect rc(BaseInk::tileSelectionToCanvas(
// For tile point shape, the point shape is done in "tiles" x1, y, x2, loop, !m_modify_selection));
// coordinates, but we want the selection in canvas/pixels
// coordinates.
if (loop->getPointShape()->isTile()) {
const Grid& grid = loop->getGrid();
rc = grid.tileToCanvas(rc);
if (!m_modify_selection) {
// For feedback purposes, the coordinates must be relative to
// the getDstImage() and not in absolute sprite canvas
// coordinates.
rc.offset(-grid.origin());
}
}
if (m_modify_selection) { if (m_modify_selection) {
int modifiers = int(loop->getModifiers()); int modifiers = int(loop->getModifiers());

View File

@ -226,7 +226,7 @@ public:
// tilemap layer to preview the selection, or 2) using a // tilemap layer to preview the selection, or 2) using a
// path to show the selection (so there is no preview layer // path to show the selection (so there is no preview layer
// at all and nor ExpandCelCanvas) // at all and nor ExpandCelCanvas)
if (m_ink->isSelection()) if (m_ink->isSelection() || m_ink->isSlice())
site.tilemapMode(TilemapMode::Pixels); site.tilemapMode(TilemapMode::Pixels);
} }
@ -529,7 +529,7 @@ public:
ExpandCelCanvas::NeedsSource | ExpandCelCanvas::NeedsSource |
(m_layer->isTilemap() && (m_layer->isTilemap() &&
(!m_tilesMode || (!m_tilesMode ||
m_ink->isSelection()) ? ExpandCelCanvas::PixelsBounds: isSelectionPreview) ? ExpandCelCanvas::PixelsBounds:
ExpandCelCanvas::None) | ExpandCelCanvas::None) |
(m_layer->isTilemap() && (m_layer->isTilemap() &&
site.tilemapMode() == TilemapMode::Pixels && site.tilemapMode() == TilemapMode::Pixels &&
@ -762,7 +762,8 @@ static void adjust_ink_for_tilemaps(const Site& site,
ToolLoopParams& params) ToolLoopParams& params)
{ {
if (!params.ink->isSelection() && if (!params.ink->isSelection() &&
!params.ink->isEraser()) { !params.ink->isEraser() &&
!params.ink->isSlice()) {
params.ink = App::instance()->toolBox()->getInkById(tools::WellKnownInks::PaintCopy); params.ink = App::instance()->toolBox()->getInkById(tools::WellKnownInks::PaintCopy);
} }
} }