[aseprite] 221/250: Fix symmetry mode when cel origin != sprite origin (0, 0)
Tobias Hansen
thansen at moszumanska.debian.org
Sun Dec 20 15:27:33 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 08a04fcb64faf1f3a7ae267260ac8e9561b9bda3
Author: David Capello <davidcapello at gmail.com>
Date: Mon Nov 2 16:44:17 2015 -0300
Fix symmetry mode when cel origin != sprite origin (0,0)
Change ToolLoop::getOffset() to getCelOrigin()
---
src/app/tools/controller.h | 4 +++-
src/app/tools/ink_processing.h | 4 ++--
src/app/tools/inks.h | 8 ++++----
src/app/tools/intertwine.cpp | 15 ++++++++++++---
src/app/tools/intertwine.h | 3 +++
src/app/tools/point_shape.h | 2 ++
src/app/tools/point_shapes.h | 25 +++++++++++++------------
src/app/tools/symmetry.h | 2 ++
src/app/tools/tool_loop.h | 4 ++--
src/app/tools/tool_loop_manager.cpp | 24 ++++++++++++++----------
src/app/tools/tool_loop_manager.h | 1 +
src/app/ui/editor/brush_preview.cpp | 3 +--
src/app/ui/editor/tool_loop_impl.cpp | 23 +++++++++--------------
src/app/ui/editor/tool_loop_impl.h | 2 +-
14 files changed, 69 insertions(+), 51 deletions(-)
diff --git a/src/app/tools/controller.h b/src/app/tools/controller.h
index e0305e2..4206edf 100644
--- a/src/app/tools/controller.h
+++ b/src/app/tools/controller.h
@@ -39,7 +39,8 @@ namespace app {
// Called when the user starts drawing and each time a new button is
// pressed. The controller could be sure that this method is called
- // at least one time.
+ // at least one time. The point is a position relative to sprite
+ // bounds.
virtual void pressButton(Stroke& stroke, const gfx::Point& point) = 0;
// Called each time a mouse button is released.
@@ -48,6 +49,7 @@ namespace app {
// Called when the mouse is moved.
virtual void movement(ToolLoop* loop, Stroke& stroke, const gfx::Point& point) = 0;
+ // The input and output strokes are relative to sprite coordinates.
virtual void getStrokeToInterwine(const Stroke& input, Stroke& output) = 0;
virtual void getStatusBarText(const Stroke& stroke, std::string& text) = 0;
};
diff --git a/src/app/tools/ink_processing.h b/src/app/tools/ink_processing.h
index 7ec1df9..3add6b0 100644
--- a/src/app/tools/ink_processing.h
+++ b/src/app/tools/ink_processing.h
@@ -906,8 +906,8 @@ public:
m_opacity = loop->getOpacity();
m_width = m_brush->bounds().w;
m_height = m_brush->bounds().h;
- m_u = (loop->getOffset().x + m_brush->patternOrigin().x) % m_width;
- m_v = (loop->getOffset().y + m_brush->patternOrigin().y) % m_height;
+ m_u = (m_brush->patternOrigin().x - loop->getCelOrigin().x) % m_width;
+ m_v = (m_brush->patternOrigin().y - loop->getCelOrigin().y) % m_height;
}
void processPixel(int x, int y) {
diff --git a/src/app/tools/inks.h b/src/app/tools/inks.h
index 95aa4f4..da49656 100644
--- a/src/app/tools/inks.h
+++ b/src/app/tools/inks.h
@@ -321,19 +321,19 @@ public:
void inkHline(int x1, int y, int x2, ToolLoop* loop) override {
if (m_modify_selection) {
- Point offset = loop->getOffset();
+ Point origin = loop->getCelOrigin();
switch (loop->getSelectionMode()) {
case SelectionMode::DEFAULT:
case SelectionMode::ADD:
- m_mask.add(gfx::Rect(x1-offset.x, y-offset.y, x2-x1+1, 1));
+ m_mask.add(gfx::Rect(x1+origin.x, y+origin.y, x2-x1+1, 1));
break;
case SelectionMode::SUBTRACT:
- m_mask.subtract(gfx::Rect(x1-offset.x, y-offset.y, x2-x1+1, 1));
+ m_mask.subtract(gfx::Rect(x1+origin.x, y+origin.y, x2-x1+1, 1));
break;
}
- m_maxBounds |= gfx::Rect(x1-offset.x, y-offset.y, x2-x1+1, 1);
+ m_maxBounds |= gfx::Rect(x1+origin.x, y+origin.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 3cb2c97..02e992e 100644
--- a/src/app/tools/intertwine.cpp
+++ b/src/app/tools/intertwine.cpp
@@ -27,14 +27,23 @@ 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(gfx::Point(x, y));
+ main_stroke.addPoint(Point(x, y) + origin);
Strokes strokes;
symmetry->generateStrokes(main_stroke, strokes);
- for (const auto& stroke : strokes)
+ for (const auto& stroke : strokes) {
+ // We call transformPoint() moving back each point to the cel
+ // origin.
loop->getPointShape()->transformPoint(
- loop, stroke[0].x, stroke[0].y);
+ loop,
+ stroke[0].x - origin.x,
+ stroke[0].y - origin.y);
+ }
}
else {
loop->getPointShape()->transformPoint(loop, x, y);
diff --git a/src/app/tools/intertwine.h b/src/app/tools/intertwine.h
index f73d8a2..cf1b174 100644
--- a/src/app/tools/intertwine.h
+++ b/src/app/tools/intertwine.h
@@ -29,10 +29,13 @@ namespace app {
virtual ~Intertwine() { }
virtual bool snapByAngle() { return false; }
virtual void prepareIntertwine() { }
+
+ // The given stroke must be relative to the cel origin.
virtual void joinStroke(ToolLoop* loop, const Stroke& stroke) = 0;
virtual void fillStroke(ToolLoop* loop, const Stroke& stroke) = 0;
protected:
+ // The given point must be relative to the cel origin.
static void doPointshapePoint(int x, int y, ToolLoop* loop);
static void doPointshapeHline(int x1, int y, int x2, ToolLoop* loop);
static void doPointshapeLine(int x1, int y1, int x2, int y2, ToolLoop* loop);
diff --git a/src/app/tools/point_shape.h b/src/app/tools/point_shape.h
index 137c0dc..6f2034c 100644
--- a/src/app/tools/point_shape.h
+++ b/src/app/tools/point_shape.h
@@ -22,6 +22,8 @@ namespace app {
virtual bool isFloodFill() { return false; }
virtual bool isSpray() { return false; }
virtual void preparePointShape(ToolLoop* loop) { }
+
+ // The x, y position must be relative to the cel/src/dst image origin.
virtual void transformPoint(ToolLoop* loop, int x, int y) = 0;
virtual void getModifiedArea(ToolLoop* loop, int x, int y, gfx::Rect& area) = 0;
diff --git a/src/app/tools/point_shapes.h b/src/app/tools/point_shapes.h
index a3fb490..d524768 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->getOffset());
+ m_brush->setPatternOrigin(gfx::Point(x, y)+loop->getCelOrigin());
}
}
}
else {
if (m_brush->type() == kImageBrushType &&
m_brush->pattern() == BrushPattern::PAINT_BRUSH) {
- m_brush->setPatternOrigin(gfx::Point(x, y)-loop->getOffset());
+ m_brush->setPatternOrigin(gfx::Point(x, y)+loop->getCelOrigin());
}
}
@@ -84,24 +84,25 @@ public:
void transformPoint(ToolLoop* loop, int x, int y) override {
doc::algorithm::floodfill(
const_cast<Image*>(loop->getSrcImage()), x, y,
- paintBounds(loop, x, y),
+ floodfillBounds(loop, x, y),
loop->getTolerance(),
loop->getContiguous(),
loop, (AlgoHLine)doInkHline);
}
void getModifiedArea(ToolLoop* loop, int x, int y, Rect& area) override {
- area = paintBounds(loop, x, y);
+ area = floodfillBounds(loop, x, y);
}
private:
- gfx::Rect paintBounds(ToolLoop* loop, int x, int y) {
- gfx::Point offset = loop->getOffset();
- gfx::Rect bounds(
- offset.x, offset.y,
- loop->sprite()->width(), loop->sprite()->height());
+ 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->getSrcImage()->bounds());
+ bounds = bounds.createIntersection(
+ loop->getSrcImage()->bounds());
// Limit the flood-fill to the current tile if the grid is visible.
if (loop->getStopAtGrid()) {
@@ -109,8 +110,8 @@ private:
if (!grid.isEmpty()) {
div_t d, dx, dy;
- dx = div(grid.x+loop->getOffset().x, grid.w);
- dy = div(grid.y+loop->getOffset().y, grid.h);
+ dx = div(grid.x-origin.x, grid.w);
+ dy = div(grid.y-origin.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/symmetry.h b/src/app/tools/symmetry.h
index d1368dd..d70c637 100644
--- a/src/app/tools/symmetry.h
+++ b/src/app/tools/symmetry.h
@@ -20,6 +20,8 @@ namespace app {
class Symmetry {
public:
virtual ~Symmetry() { }
+
+ // The "stroke" must be relative to the sprite origin.
virtual void generateStrokes(const Stroke& stroke, Strokes& strokes) = 0;
};
diff --git a/src/app/tools/tool_loop.h b/src/app/tools/tool_loop.h
index 9e8306f..1a5d8f8 100644
--- a/src/app/tools/tool_loop.h
+++ b/src/app/tools/tool_loop.h
@@ -187,8 +187,8 @@ namespace app {
virtual int getSprayWidth() = 0;
virtual int getSpraySpeed() = 0;
- // Offset for each point
- virtual gfx::Point getOffset() = 0;
+ // X,Y origin of the cel where we are drawing
+ virtual gfx::Point getCelOrigin() = 0;
// Velocity vector of the mouse
virtual void setSpeed(const gfx::Point& speed) = 0;
diff --git a/src/app/tools/tool_loop_manager.cpp b/src/app/tools/tool_loop_manager.cpp
index ce858b4..8e7565f 100644
--- a/src/app/tools/tool_loop_manager.cpp
+++ b/src/app/tools/tool_loop_manager.cpp
@@ -164,15 +164,14 @@ void ToolLoopManager::movement(const Pointer& pointer)
void ToolLoopManager::doLoopStep(bool last_step)
{
- // Original set of points to interwine (original user stroke).
+ // Original set of points to interwine (original user stroke,
+ // relative to sprite origin).
Stroke main_stroke;
if (!last_step)
m_toolLoop->getController()->getStrokeToInterwine(m_stroke, main_stroke);
else
main_stroke = m_stroke;
- main_stroke.offset(m_toolLoop->getOffset());
-
// Calculate the area to be updated in all document observers.
Symmetry* symmetry = m_toolLoop->getSymmetry();
Strokes strokes;
@@ -209,6 +208,9 @@ 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);
@@ -235,6 +237,7 @@ void ToolLoopManager::snapToGrid(Point& point)
point = snap_to_grid(m_toolLoop->getGridBounds(), point);
}
+// Strokes are relative to sprite origin.
void ToolLoopManager::calculateDirtyArea(const Strokes& strokes)
{
// Save the current dirty area if it's needed
@@ -245,6 +248,8 @@ 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())
@@ -255,20 +260,19 @@ void ToolLoopManager::calculateDirtyArea(const Strokes& strokes)
m_toolLoop->getPointShape()->getModifiedArea(
m_toolLoop,
- strokeBounds.x,
- strokeBounds.y, r1);
+ strokeBounds.x - celOrigin.x,
+ strokeBounds.y - celOrigin.y, r1);
m_toolLoop->getPointShape()->getModifiedArea(
m_toolLoop,
- strokeBounds.x+strokeBounds.w-1,
- strokeBounds.y+strokeBounds.h-1, r2);
+ strokeBounds.x+strokeBounds.w-1 - celOrigin.x,
+ strokeBounds.y+strokeBounds.h-1 - celOrigin.y, r2);
m_dirtyArea.createUnion(m_dirtyArea, Region(r1.createUnion(r2)));
}
- // Apply offset mode
- Point offset(m_toolLoop->getOffset());
- m_dirtyArea.offset(-offset);
+ // 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
diff --git a/src/app/tools/tool_loop_manager.h b/src/app/tools/tool_loop_manager.h
index 500f777..063d191 100644
--- a/src/app/tools/tool_loop_manager.h
+++ b/src/app/tools/tool_loop_manager.h
@@ -38,6 +38,7 @@ namespace app {
// is called.
// 5. When the user release the mouse:
// - ToolLoopManager::releaseButton
+ //
class ToolLoopManager {
public:
diff --git a/src/app/ui/editor/brush_preview.cpp b/src/app/ui/editor/brush_preview.cpp
index cdeae7b..d236399 100644
--- a/src/app/ui/editor/brush_preview.cpp
+++ b/src/app/ui/editor/brush_preview.cpp
@@ -184,8 +184,7 @@ void BrushPreview::show(const gfx::Point& screenPos)
base::UniquePtr<tools::ToolLoop> loop(
create_tool_loop_preview(
m_editor, extraImage,
- -gfx::Point(brushBounds.x,
- brushBounds.y)));
+ brushBounds.getOrigin()));
if (loop) {
loop->getInk()->prepareInk(loop);
loop->getIntertwine()->prepareIntertwine();
diff --git a/src/app/ui/editor/tool_loop_impl.cpp b/src/app/ui/editor/tool_loop_impl.cpp
index 218965c..b4b3a42 100644
--- a/src/app/ui/editor/tool_loop_impl.cpp
+++ b/src/app/ui/editor/tool_loop_impl.cpp
@@ -70,7 +70,7 @@ protected:
int m_opacity;
int m_tolerance;
bool m_contiguous;
- gfx::Point m_offset;
+ gfx::Point m_celOrigin;
gfx::Point m_speed;
tools::ToolLoop::Button m_button;
base::UniquePtr<tools::Ink> m_ink;
@@ -207,7 +207,7 @@ public:
return false;
}
gfx::Rect getGridBounds() override { return m_docPref.grid.bounds(); }
- gfx::Point getOffset() override { return m_offset; }
+ gfx::Point getCelOrigin() override { return m_celOrigin; }
void setSpeed(const gfx::Point& speed) override { m_speed = speed; }
gfx::Point getSpeed() override { return m_speed; }
tools::Ink* getInk() override { return m_ink; }
@@ -317,16 +317,11 @@ public:
m_transaction.execute(new cmd::SetMask(m_document, &emptyMask));
}
- int x1 = m_expandCelCanvas.getCel()->x();
- int y1 = m_expandCelCanvas.getCel()->y();
-
+ m_celOrigin = m_expandCelCanvas.getCel()->position();
m_mask = m_document->mask();
- m_maskOrigin = (!m_mask->isEmpty() ? gfx::Point(m_mask->bounds().x-x1,
- m_mask->bounds().y-y1):
+ 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));
-
- m_offset.x = -x1;
- m_offset.y = -y1;
}
// IToolLoop interface
@@ -485,12 +480,12 @@ public:
const app::Color& fgColor,
const app::Color& bgColor,
Image* image,
- const gfx::Point& offset)
+ const gfx::Point& celOrigin)
: ToolLoopBase(editor, tool, ink, document,
tools::ToolLoop::Left, fgColor, bgColor)
, m_image(image)
{
- m_offset = offset;
+ m_celOrigin = celOrigin;
// Avoid preview for spray and flood fill like tools
if (m_pointShape->isSpray()) {
@@ -529,7 +524,7 @@ public:
tools::ToolLoop* create_tool_loop_preview(
Editor* editor, Image* image,
- const gfx::Point& offset)
+ const gfx::Point& celOrigin)
{
tools::Tool* current_tool = editor->getCurrentEditorTool();
tools::Ink* current_ink = editor->getCurrentEditorInk();
@@ -557,7 +552,7 @@ tools::ToolLoop* create_tool_loop_preview(
current_tool,
current_ink,
editor->document(),
- fg, bg, image, offset);
+ fg, bg, image, celOrigin);
}
catch (const std::exception&) {
return nullptr;
diff --git a/src/app/ui/editor/tool_loop_impl.h b/src/app/ui/editor/tool_loop_impl.h
index 0a83a3b..e89ec41 100644
--- a/src/app/ui/editor/tool_loop_impl.h
+++ b/src/app/ui/editor/tool_loop_impl.h
@@ -29,7 +29,7 @@ namespace app {
tools::ToolLoop* create_tool_loop_preview(
Editor* editor, doc::Image* image,
- const gfx::Point& offset);
+ const gfx::Point& celOrigin);
} // namespace app
--
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