mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 04:19:12 +00:00
Fix dirty area calculation
Dirty area region was not calculated correctly when the bottom part of the modified area fell on the intersection of the top left and top middle tile sprites on a tiled-mode-enabled canvas and the top part fell outside of the canvas.
This commit is contained in:
parent
3bce6f2272
commit
d79c193e40
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "app/shade.h"
|
||||
#include "app/util/tiled_mode.h"
|
||||
#include "app/tools/dynamics.h"
|
||||
#include "app/tools/stroke.h"
|
||||
#include "app/tools/tool_loop_modifiers.h"
|
||||
@ -256,6 +257,8 @@ namespace app {
|
||||
virtual void savePointshapeStrokePtArea(const int pti, const Stroke::Pt& pt) = 0;
|
||||
|
||||
virtual void restoreLastPts(const int pti, const tools::Stroke::Pt& pt) = 0;
|
||||
|
||||
virtual const app::TiledModeHelper& getTiledModeHelper() = 0;
|
||||
};
|
||||
|
||||
} // namespace tools
|
||||
|
@ -327,42 +327,8 @@ void ToolLoopManager::calculateDirtyArea(const Strokes& strokes)
|
||||
// Apply tiled mode
|
||||
TiledMode tiledMode = m_toolLoop->getTiledMode();
|
||||
if (tiledMode != TiledMode::NONE) {
|
||||
int w = m_toolLoop->sprite()->width();
|
||||
int h = m_toolLoop->sprite()->height();
|
||||
Region sprite_area(Rect(0, 0, w, h));
|
||||
Region outside;
|
||||
outside.createSubtraction(m_dirtyArea, sprite_area);
|
||||
|
||||
switch (tiledMode) {
|
||||
case TiledMode::X_AXIS:
|
||||
outside.createIntersection(outside, Region(Rect(-w*10000, 0, w*20000, h)));
|
||||
break;
|
||||
case TiledMode::Y_AXIS:
|
||||
outside.createIntersection(outside, Region(Rect(0, -h*10000, w, h*20000)));
|
||||
break;
|
||||
}
|
||||
|
||||
Rect outsideBounds = outside.bounds();
|
||||
if (outsideBounds.x < 0) outside.offset(w * (1+((-outsideBounds.x) / w)), 0);
|
||||
if (outsideBounds.y < 0) outside.offset(0, h * (1+((-outsideBounds.y) / h)));
|
||||
int x1 = outside.bounds().x;
|
||||
|
||||
while (true) {
|
||||
Region in_sprite;
|
||||
in_sprite.createIntersection(outside, sprite_area);
|
||||
outside.createSubtraction(outside, in_sprite);
|
||||
m_dirtyArea.createUnion(m_dirtyArea, in_sprite);
|
||||
|
||||
outsideBounds = outside.bounds();
|
||||
if (outsideBounds.isEmpty())
|
||||
break;
|
||||
else if (outsideBounds.x+outsideBounds.w > w)
|
||||
outside.offset(-w, 0);
|
||||
else if (outsideBounds.y+outsideBounds.h > h)
|
||||
outside.offset(x1-outsideBounds.x, -h);
|
||||
else
|
||||
break;
|
||||
}
|
||||
m_toolLoop->getTiledModeHelper().wrapPosition(m_dirtyArea);
|
||||
m_toolLoop->getTiledModeHelper().collapseRegionByTiledMode(m_dirtyArea);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,6 +148,8 @@ protected:
|
||||
// Last point index.
|
||||
int m_lastPti;
|
||||
|
||||
app::TiledModeHelper m_tiledModeHelper;
|
||||
|
||||
public:
|
||||
ToolLoopBase(Editor* editor,
|
||||
Site& site, const doc::Grid& grid,
|
||||
@ -193,6 +195,7 @@ public:
|
||||
, m_primaryColor(m_button == tools::ToolLoop::Left ? m_fgColor: m_bgColor)
|
||||
, m_secondaryColor(m_button == tools::ToolLoop::Left ? m_bgColor: m_fgColor)
|
||||
, m_staticToolModifiers(params.modifiers)
|
||||
, m_tiledModeHelper(m_docPref.tiled.mode(), m_sprite)
|
||||
{
|
||||
ASSERT(m_tool);
|
||||
ASSERT(m_ink);
|
||||
@ -436,6 +439,10 @@ public:
|
||||
|
||||
void restoreLastPts(const int pti, const tools::Stroke::Pt& pt) override { }
|
||||
|
||||
const app::TiledModeHelper& getTiledModeHelper() override {
|
||||
return m_tiledModeHelper;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_UI
|
||||
protected:
|
||||
void updateAllVisibleRegion() {
|
||||
@ -473,7 +480,6 @@ class ToolLoopImpl : public ToolLoopBase,
|
||||
std::unique_ptr<ExpandCelCanvas> m_expandCelCanvas;
|
||||
Image* m_floodfillSrcImage;
|
||||
bool m_saveLastPoint;
|
||||
app::TiledModeHelper m_tiledModeHelper;
|
||||
|
||||
public:
|
||||
ToolLoopImpl(Editor* editor,
|
||||
@ -494,7 +500,6 @@ public:
|
||||
ModifyDocument))
|
||||
, m_floodfillSrcImage(nullptr)
|
||||
, m_saveLastPoint(saveLastPoint)
|
||||
, m_tiledModeHelper(m_docPref.tiled.mode(), m_sprite)
|
||||
{
|
||||
if (m_pointShape->isFloodFill()) {
|
||||
if (m_tilesMode) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user