[aseprite] 100/128: Fix problems using paint bucket referring to all layers and cels origin != 0, 0
Tobias Hansen
thansen at moszumanska.debian.org
Mon May 9 21:24:28 UTC 2016
This is an automated email from the git hooks/post-receive script.
thansen pushed a commit to branch master
in repository aseprite.
commit 0f3dea233b4520b63ac7d58a4ec3a204cc5d2243
Author: David Capello <davidcapello at gmail.com>
Date: Wed May 4 00:02:56 2016 -0300
Fix problems using paint bucket referring to all layers and cels origin != 0,0
With this change we've simplified several portions of the ToolLoop code
where the "cel origin" is added and then subtracted needlessly.
---
src/app/tools/ink.h | 5 ++
src/app/tools/inks.h | 12 ++--
src/app/tools/intertwine.cpp | 8 +--
src/app/tools/point_shape.cpp | 11 +++-
src/app/tools/point_shapes.h | 17 ++----
src/app/tools/tool_loop_manager.cpp | 16 ++----
src/app/ui/editor/brush_preview.cpp | 4 +-
src/app/ui/editor/tool_loop_impl.cpp | 107 ++++++++++++++++++++---------------
8 files changed, 99 insertions(+), 81 deletions(-)
diff --git a/src/app/tools/ink.h b/src/app/tools/ink.h
index c2325d3..91b46d4 100644
--- a/src/app/tools/ink.h
+++ b/src/app/tools/ink.h
@@ -66,6 +66,11 @@ namespace app {
// Returns true if this ink is used to mark slices
virtual bool isSlice() const { return false; }
+ // Returns true if inkHline() needs source cel coordinates
+ // instead of sprite coordinates (i.e. relative to
+ // ToolLoop::getCelOrigin()).
+ virtual bool needsCelCoordinates() const { return true; }
+
// Returns true if this ink needs a special source area. For
// example, blur tool needs one extra pixel to all sides of the
// modified area, so it can use a 3x3 convolution matrix.
diff --git a/src/app/tools/inks.h b/src/app/tools/inks.h
index 4d1d61d..8c0a1e9 100644
--- a/src/app/tools/inks.h
+++ b/src/app/tools/inks.h
@@ -173,6 +173,8 @@ public:
Ink* clone() override { return new SliceInk(*this); }
bool isSlice() const override { return true; }
+ bool needsCelCoordinates() const override { return false; }
+
void prepareInk(ToolLoop* loop) override { }
void inkHline(int x1, int y, int x2, ToolLoop* loop) override {
// TODO show the selection-preview with a XOR color or something like that
@@ -319,21 +321,23 @@ public:
Ink* clone() override { return new SelectionInk(*this); }
bool isSelection() const override { return true; }
+ bool needsCelCoordinates() const override {
+ return (m_modify_selection ? false: true);
+ }
void inkHline(int x1, int y, int x2, ToolLoop* loop) override {
if (m_modify_selection) {
int modifiers = int(loop->getModifiers());
- Point origin = loop->getCelOrigin();
if ((modifiers & (int(ToolLoopModifiers::kReplaceSelection) |
int(ToolLoopModifiers::kAddSelection))) != 0) {
- m_mask.add(gfx::Rect(x1+origin.x, y+origin.y, x2-x1+1, 1));
+ m_mask.add(gfx::Rect(x1, y, x2-x1+1, 1));
}
else if ((modifiers & int(ToolLoopModifiers::kSubtractSelection)) != 0) {
- m_mask.subtract(gfx::Rect(x1+origin.x, y+origin.y, x2-x1+1, 1));
+ m_mask.subtract(gfx::Rect(x1, y, x2-x1+1, 1));
}
- m_maxBounds |= gfx::Rect(x1+origin.x, y+origin.y, x2-x1+1, 1);
+ m_maxBounds |= gfx::Rect(x1, y, x2-x1+1, 1);
}
// TODO show the selection-preview with a XOR color or something like that
else {
diff --git a/src/app/tools/intertwine.cpp b/src/app/tools/intertwine.cpp
index ce918b3..75bec16 100644
--- a/src/app/tools/intertwine.cpp
+++ b/src/app/tools/intertwine.cpp
@@ -27,12 +27,10 @@ void Intertwine::doPointshapePoint(int x, int y, ToolLoop* loop)
{
Symmetry* symmetry = loop->getSymmetry();
if (symmetry) {
- Point origin(loop->getCelOrigin());
-
// Convert the point to the sprite position so we can apply the
// symmetry transformation.
Stroke main_stroke;
- main_stroke.addPoint(Point(x, y) + origin);
+ main_stroke.addPoint(Point(x, y));
Strokes strokes;
symmetry->generateStrokes(main_stroke, strokes, loop);
@@ -40,9 +38,7 @@ void Intertwine::doPointshapePoint(int x, int y, ToolLoop* loop)
// We call transformPoint() moving back each point to the cel
// origin.
loop->getPointShape()->transformPoint(
- loop,
- stroke[0].x - origin.x,
- stroke[0].y - origin.y);
+ loop, stroke[0].x, stroke[0].y);
}
}
else {
diff --git a/src/app/tools/point_shape.cpp b/src/app/tools/point_shape.cpp
index a7326c0..ab49291 100644
--- a/src/app/tools/point_shape.cpp
+++ b/src/app/tools/point_shape.cpp
@@ -27,13 +27,22 @@ void PointShape::doInkHline(int x1, int y, int x2, ToolLoop* loop)
TiledMode tiledMode = loop->getTiledMode();
int x, w, size; // width or height
+ // In case the ink needs original cel coordinates, we have to
+ // translate the x1/y/x2 coordinate.
+ if (loop->getInk()->needsCelCoordinates()) {
+ gfx::Point origin = loop->getCelOrigin();
+ x1 -= origin.x;
+ x2 -= origin.x;
+ y -= origin.y;
+ }
+
// Tiled in Y axis
if (int(tiledMode) & int(TiledMode::Y_AXIS)) {
size = loop->getDstImage()->height(); // size = image height
y = wrap_value(y, size);
}
else if (y < 0 || y >= loop->getDstImage()->height())
- return;
+ return;
// Tiled in X axis
if (int(tiledMode) & int(TiledMode::X_AXIS)) {
diff --git a/src/app/tools/point_shapes.h b/src/app/tools/point_shapes.h
index 61bf874..6398cec 100644
--- a/src/app/tools/point_shapes.h
+++ b/src/app/tools/point_shapes.h
@@ -52,14 +52,14 @@ public:
if (m_brush->type() == kImageBrushType) {
if (m_brush->pattern() == BrushPattern::ALIGNED_TO_DST ||
m_brush->pattern() == BrushPattern::PAINT_BRUSH) {
- m_brush->setPatternOrigin(gfx::Point(x, y)+loop->getCelOrigin());
+ m_brush->setPatternOrigin(gfx::Point(x, y));
}
}
}
else {
if (m_brush->type() == kImageBrushType &&
m_brush->pattern() == BrushPattern::PAINT_BRUSH) {
- m_brush->setPatternOrigin(gfx::Point(x, y)+loop->getCelOrigin());
+ m_brush->setPatternOrigin(gfx::Point(x, y));
}
}
@@ -98,13 +98,8 @@ public:
private:
gfx::Rect floodfillBounds(ToolLoop* loop, int x, int y) const {
- gfx::Point origin = loop->getCelOrigin();
- gfx::Rect bounds(-origin.x, -origin.y,
- loop->sprite()->width(),
- loop->sprite()->height());
-
- bounds = bounds.createIntersection(
- loop->getFloodFillSrcImage()->bounds());
+ gfx::Rect bounds = loop->sprite()->bounds();
+ bounds &= loop->getFloodFillSrcImage()->bounds();
// Limit the flood-fill to the current tile if the grid is visible.
if (loop->getStopAtGrid()) {
@@ -112,8 +107,8 @@ private:
if (!grid.isEmpty()) {
div_t d, dx, dy;
- dx = div(grid.x-origin.x, grid.w);
- dy = div(grid.y-origin.y, grid.h);
+ dx = div(grid.x, grid.w);
+ dy = div(grid.y, grid.h);
if (dx.rem > 0) dx.rem -= grid.w;
if (dy.rem > 0) dy.rem -= grid.h;
diff --git a/src/app/tools/tool_loop_manager.cpp b/src/app/tools/tool_loop_manager.cpp
index 06f2da7..f05ed4d 100644
--- a/src/app/tools/tool_loop_manager.cpp
+++ b/src/app/tools/tool_loop_manager.cpp
@@ -188,9 +188,6 @@ void ToolLoopManager::doLoopStep(bool last_step)
m_toolLoop->validateDstImage(m_dirtyArea);
- // Move the stroke to be relative to the cel origin.
- main_stroke.offset(-m_toolLoop->getCelOrigin());
-
// Join or fill user points
if (!m_toolLoop->getFilled() || (!last_step && !m_toolLoop->getPreviewFilled()))
m_toolLoop->getIntertwine()->joinStroke(m_toolLoop, main_stroke);
@@ -229,8 +226,6 @@ void ToolLoopManager::calculateDirtyArea(const Strokes& strokes)
// Start with a fresh dirty area
m_dirtyArea.clear();
- const Point celOrigin = m_toolLoop->getCelOrigin();
-
for (auto& stroke : strokes) {
gfx::Rect strokeBounds = stroke.bounds();
if (strokeBounds.isEmpty())
@@ -241,20 +236,17 @@ void ToolLoopManager::calculateDirtyArea(const Strokes& strokes)
m_toolLoop->getPointShape()->getModifiedArea(
m_toolLoop,
- strokeBounds.x - celOrigin.x,
- strokeBounds.y - celOrigin.y, r1);
+ strokeBounds.x,
+ strokeBounds.y, r1);
m_toolLoop->getPointShape()->getModifiedArea(
m_toolLoop,
- strokeBounds.x+strokeBounds.w-1 - celOrigin.x,
- strokeBounds.y+strokeBounds.h-1 - celOrigin.y, r2);
+ strokeBounds.x+strokeBounds.w-1,
+ strokeBounds.y+strokeBounds.h-1, r2);
m_dirtyArea.createUnion(m_dirtyArea, Region(r1.createUnion(r2)));
}
- // Make the dirty area relative to the sprite.
- m_dirtyArea.offset(celOrigin);
-
// Merge new dirty area with the previous one (for tools like line
// or rectangle it's needed to redraw the previous position and
// the new one)
diff --git a/src/app/ui/editor/brush_preview.cpp b/src/app/ui/editor/brush_preview.cpp
index 92f9663..02b6955 100644
--- a/src/app/ui/editor/brush_preview.cpp
+++ b/src/app/ui/editor/brush_preview.cpp
@@ -209,7 +209,9 @@ void BrushPreview::show(const gfx::Point& screenPos)
loop->getIntertwine()->prepareIntertwine();
loop->getPointShape()->preparePointShape(loop);
loop->getPointShape()->transformPoint(
- loop, -origBrushBounds.x, -origBrushBounds.y);
+ loop,
+ brushBounds.x-origBrushBounds.x,
+ brushBounds.y-origBrushBounds.y);
}
}
diff --git a/src/app/ui/editor/tool_loop_impl.cpp b/src/app/ui/editor/tool_loop_impl.cpp
index 9ebd43f..0843149 100644
--- a/src/app/ui/editor/tool_loop_impl.cpp
+++ b/src/app/ui/editor/tool_loop_impl.cpp
@@ -269,7 +269,7 @@ class ToolLoopImpl : public ToolLoopBase {
gfx::Point m_maskOrigin;
bool m_canceled;
Transaction m_transaction;
- ExpandCelCanvas m_expandCelCanvas;
+ ExpandCelCanvas* m_expandCelCanvas;
Image* m_floodfillSrcImage;
public:
@@ -294,23 +294,58 @@ public:
getInk()->isSlice() ||
getInk()->isZoom()) ? DoesntModifyDocument:
ModifyDocument))
- , m_expandCelCanvas(
- editor->getSite(),
- layer,
- m_docPref.tiled.mode(),
- m_transaction,
- ExpandCelCanvas::Flags(
- ExpandCelCanvas::NeedsSource |
- // If the tool is freehand-like, we can use the modified
- // region directly as undo information to save the modified
- // pixels (it's faster than creating a Dirty object).
- // See ExpandCelCanvas::commit() for details about this flag.
- (getController()->isFreehand() ?
- ExpandCelCanvas::UseModifiedRegionAsUndoInfo:
- ExpandCelCanvas::None)))
+ , m_expandCelCanvas(nullptr)
+ , m_floodfillSrcImage(nullptr)
{
ASSERT(m_context->activeDocument() == m_editor->document());
+ if (m_pointShape->isFloodFill()) {
+ // Prepare a special image for floodfill when it's configured to
+ // stop using all visible layers.
+ if (m_toolPref.floodfill.referTo() == gen::FillReferTo::ALL_LAYERS) {
+ m_floodfillSrcImage = Image::create(m_sprite->pixelFormat(),
+ m_sprite->width(),
+ m_sprite->height());
+
+ m_floodfillSrcImage->clear(m_sprite->transparentColor());
+
+ render::Render().renderSprite(
+ m_floodfillSrcImage,
+ m_sprite,
+ m_frame,
+ gfx::Clip(m_sprite->bounds()),
+ render::Zoom(1, 1));
+ }
+ else {
+ Cel* cel = m_layer->cel(m_frame);
+ if (cel && (cel->x() != 0 || cel->y() != 0)) {
+ m_floodfillSrcImage = Image::create(m_sprite->pixelFormat(),
+ m_sprite->width(),
+ m_sprite->height());
+ m_floodfillSrcImage->clear(m_sprite->transparentColor());
+ copy_image(m_floodfillSrcImage, cel->image(), cel->x(), cel->y());
+ }
+ }
+ }
+
+ m_expandCelCanvas = new ExpandCelCanvas(
+ editor->getSite(),
+ layer,
+ m_docPref.tiled.mode(),
+ m_transaction,
+ ExpandCelCanvas::Flags(
+ ExpandCelCanvas::NeedsSource |
+ // If the tool is freehand-like, we can use the modified
+ // region directly as undo information to save the modified
+ // pixels (it's faster than creating a Dirty object).
+ // See ExpandCelCanvas::commit() for details about this flag.
+ (getController()->isFreehand() ?
+ ExpandCelCanvas::UseModifiedRegionAsUndoInfo:
+ ExpandCelCanvas::None)));
+
+ if (!m_floodfillSrcImage)
+ m_floodfillSrcImage = const_cast<Image*>(getSrcImage());
+
// Settings
switch (tool->getFill(m_button)) {
case tools::FillNone:
@@ -341,37 +376,17 @@ public:
m_transaction.execute(new cmd::SetMask(m_document, &emptyMask));
}
- m_celOrigin = m_expandCelCanvas.getCel()->position();
+ m_celOrigin = m_expandCelCanvas->getCel()->position();
m_mask = m_document->mask();
m_maskOrigin = (!m_mask->isEmpty() ? gfx::Point(m_mask->bounds().x-m_celOrigin.x,
m_mask->bounds().y-m_celOrigin.y):
gfx::Point(0, 0));
-
- // Prepare a special image for floodfill when it's configured to
- // stop using all visible layers.
- if (m_pointShape->isFloodFill() &&
- m_toolPref.floodfill.referTo() == gen::FillReferTo::ALL_LAYERS) {
- m_floodfillSrcImage = Image::create(m_sprite->pixelFormat(),
- m_sprite->width(),
- m_sprite->height());
-
- m_floodfillSrcImage->clear(m_sprite->transparentColor());
-
- render::Render().renderSprite(
- m_floodfillSrcImage,
- m_sprite,
- m_frame,
- gfx::Clip(m_sprite->bounds()),
- render::Zoom(1, 1));
- }
- else {
- m_floodfillSrcImage = const_cast<Image*>(getSrcImage());
- }
}
~ToolLoopImpl() {
if (m_floodfillSrcImage != getSrcImage())
delete m_floodfillSrcImage;
+ delete m_expandCelCanvas;
}
// IToolLoop interface
@@ -385,7 +400,7 @@ public:
try {
ContextReader reader(m_context, 500);
ContextWriter writer(reader, 500);
- m_expandCelCanvas.commit();
+ m_expandCelCanvas->commit();
}
catch (const LockedDocumentException& ex) {
Console::showException(ex);
@@ -410,7 +425,7 @@ public:
try {
ContextReader reader(m_context, 500);
ContextWriter writer(reader, 500);
- m_expandCelCanvas.rollback();
+ m_expandCelCanvas->rollback();
}
catch (const LockedDocumentException& ex) {
Console::showException(ex);
@@ -421,23 +436,23 @@ public:
update_screen_for_document(m_document);
}
- const Image* getSrcImage() override { return m_expandCelCanvas.getSourceCanvas(); }
+ const Image* getSrcImage() override { return m_expandCelCanvas->getSourceCanvas(); }
const Image* getFloodFillSrcImage() override { return m_floodfillSrcImage; }
- Image* getDstImage() override { return m_expandCelCanvas.getDestCanvas(); }
+ Image* getDstImage() override { return m_expandCelCanvas->getDestCanvas(); }
void validateSrcImage(const gfx::Region& rgn) override {
- m_expandCelCanvas.validateSourceCanvas(rgn);
+ m_expandCelCanvas->validateSourceCanvas(rgn);
}
void validateDstImage(const gfx::Region& rgn) override {
- m_expandCelCanvas.validateDestCanvas(rgn);
+ m_expandCelCanvas->validateDestCanvas(rgn);
}
void invalidateDstImage() override {
- m_expandCelCanvas.invalidateDestCanvas();
+ m_expandCelCanvas->invalidateDestCanvas();
}
void invalidateDstImage(const gfx::Region& rgn) override {
- m_expandCelCanvas.invalidateDestCanvas(rgn);
+ m_expandCelCanvas->invalidateDestCanvas(rgn);
}
void copyValidDstToSrcImage(const gfx::Region& rgn) override {
- m_expandCelCanvas.copyValidDestToSourceCanvas(rgn);
+ m_expandCelCanvas->copyValidDestToSourceCanvas(rgn);
}
bool useMask() override { return m_useMask; }
--
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