diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp index 7cf4fe9e3..b7c89768e 100644 --- a/src/app/ui/editor/editor.cpp +++ b/src/app/ui/editor/editor.cpp @@ -147,6 +147,7 @@ Editor::Editor(Doc* document, EditorFlags flags) , m_layer(m_sprite->root()->firstLayer()) , m_frame(frame_t(0)) , m_docPref(Preferences::instance().document(document)) + , m_tiledModeHelper(app::TiledModeHelper(m_docPref.tiled.mode(), m_sprite)) , m_brushPreview(this) , m_toolLoopModifiers(tools::ToolLoopModifiers::kNone) , m_padding(0, 0) @@ -2222,6 +2223,8 @@ void Editor::onTiledModeChange() screenPos = editorToScreen(spritePos); centerInSpritePoint(spritePos); + + m_tiledModeHelper.mode(m_docPref.tiled.mode()); } void Editor::onShowExtrasChange() @@ -2810,77 +2813,23 @@ gfx::Point Editor::calcExtraPadding(const Projection& proj) gfx::Size Editor::canvasSize() const { - gfx::Size sz(m_sprite->width(), - m_sprite->height()); - if (int(m_docPref.tiled.mode()) & int(filters::TiledMode::X_AXIS)) { - sz.w += sz.w*2; - } - if (int(m_docPref.tiled.mode()) & int(filters::TiledMode::Y_AXIS)) { - sz.h += sz.h*2; - } - return sz; + return m_tiledModeHelper.canvasSize(); } gfx::Point Editor::mainTilePosition() const { - gfx::Point pt(0, 0); - if (int(m_docPref.tiled.mode()) & int(filters::TiledMode::X_AXIS)) { - pt.x += m_sprite->width(); - } - if (int(m_docPref.tiled.mode()) & int(filters::TiledMode::Y_AXIS)) { - pt.y += m_sprite->height(); - } - return pt; + return m_tiledModeHelper.mainTilePosition(); } void Editor::expandRegionByTiledMode(gfx::Region& rgn, const bool withProj) const { - gfx::Region tile = rgn; - const bool xTiled = (int(m_docPref.tiled.mode()) & int(filters::TiledMode::X_AXIS)); - const bool yTiled = (int(m_docPref.tiled.mode()) & int(filters::TiledMode::Y_AXIS)); - int w = m_sprite->width(); - int h = m_sprite->height(); - if (withProj) { - w = m_proj.applyX(w); - h = m_proj.applyY(h); - } - if (xTiled) { - tile.offset(w, 0); rgn |= tile; - tile.offset(w, 0); rgn |= tile; - tile.offset(-2*w, 0); - } - if (yTiled) { - tile.offset(0, h); rgn |= tile; - tile.offset(0, h); rgn |= tile; - tile.offset(0, -2*h); - } - if (xTiled && yTiled) { - tile.offset(w, h); rgn |= tile; - tile.offset(w, 0); rgn |= tile; - tile.offset(-w, h); rgn |= tile; - tile.offset(w, 0); rgn |= tile; - } + m_tiledModeHelper.expandRegionByTiledMode(rgn, withProj ? &m_proj : nullptr); } void Editor::collapseRegionByTiledMode(gfx::Region& rgn) const { - auto canvasSize = this->canvasSize(); - rgn &= gfx::Region(gfx::Rect(canvasSize)); - - const int sprW = m_sprite->width(); - const int sprH = m_sprite->height(); - - gfx::Region newRgn; - for (int v=0; v m_expandCelCanvas; Image* m_floodfillSrcImage; bool m_saveLastPoint; + app::TiledModeHelper m_tiledModeHelper; public: ToolLoopImpl(Editor* editor, @@ -493,6 +494,7 @@ public: ModifyDocument)) , m_floodfillSrcImage(nullptr) , m_saveLastPoint(saveLastPoint) + , m_tiledModeHelper(m_docPref.tiled.mode(), m_sprite) { if (m_pointShape->isFloodFill()) { if (m_tilesMode) { @@ -766,7 +768,7 @@ public: getPointShape()->getModifiedArea(this, pos.x, pos.y, r); gfx::Region rgn(r); - m_editor->collapseRegionByTiledMode(rgn); + m_tiledModeHelper.collapseRegionByTiledMode(rgn); for (auto a : rgn) { ImageRef i(Image::create(getSrcImage()->pixelFormat(), a.w, a.h)); @@ -834,10 +836,10 @@ private: return; if (int(getTiledMode()) & int(TiledMode::X_AXIS)) { - result.x %= m_editor->canvasSize().w; + result.x %= m_tiledModeHelper.canvasSize().w; } if (int(getTiledMode()) & int(TiledMode::Y_AXIS)) { - result.y %= m_editor->canvasSize().h; + result.y %= m_tiledModeHelper.canvasSize().h; } gfx::Rect r; @@ -845,12 +847,12 @@ private: if (r.x < 0) result.x += m_sprite->width(); - else if (r.x2() > m_editor->canvasSize().w) + else if (r.x2() > m_tiledModeHelper.canvasSize().w) result.x -= m_sprite->width(); if (r.y < 0) result.y += m_sprite->height(); - else if (r.y2() > m_editor->canvasSize().h) + else if (r.y2() > m_tiledModeHelper.canvasSize().h) result.y -= m_sprite->height(); } }; diff --git a/src/app/util/tiled_mode.h b/src/app/util/tiled_mode.h new file mode 100644 index 000000000..c2562f5b0 --- /dev/null +++ b/src/app/util/tiled_mode.h @@ -0,0 +1,109 @@ +// Aseprite +// Copyright (C) 2001-2015 David Capello +// +// This program is distributed under the terms of +// the End-User License Agreement for Aseprite. +#ifndef APP_TILED_MODE_H_INCLUDED +#define APP_TILED_MODE_H_INCLUDED +#pragma once + +#include "filters/tiled_mode.h" + +#include "app/doc.h" +#include "gfx/region.h" +#include "render/projection.h" + +namespace app { + + class TiledModeHelper { + public: + TiledModeHelper(const filters::TiledMode mode, const doc::Sprite* canvas) : + m_mode(mode), + m_canvas(canvas) { + } + ~TiledModeHelper() {} + + void mode(const filters::TiledMode mode) { + m_mode = mode; + } + + gfx::Size canvasSize() const { + gfx::Size sz(m_canvas->width(), + m_canvas->height()); + if (int(m_mode) & int(filters::TiledMode::X_AXIS)) { + sz.w += sz.w * 2; + } + if (int(m_mode) & int(filters::TiledMode::Y_AXIS)) { + sz.h += sz.h * 2; + } + return sz; + } + + gfx::Point mainTilePosition() const { + gfx::Point pt(0, 0); + if (int(m_mode) & int(filters::TiledMode::X_AXIS)) { + pt.x += m_canvas->width(); + } + if (int(m_mode) & int(filters::TiledMode::Y_AXIS)) { + pt.y += m_canvas->height(); + } + return pt; + } + + void expandRegionByTiledMode(gfx::Region& rgn, + const render::Projection* proj = nullptr) const { + gfx::Region tile = rgn; + const bool xTiled = (int(m_mode) & int(filters::TiledMode::X_AXIS)); + const bool yTiled = (int(m_mode) & int(filters::TiledMode::Y_AXIS)); + int w = m_canvas->width(); + int h = m_canvas->height(); + if (proj) { + w = proj->applyX(w); + h = proj->applyY(h); + } + if (xTiled) { + tile.offset(w, 0); rgn |= tile; + tile.offset(w, 0); rgn |= tile; + tile.offset(-2 * w, 0); + } + if (yTiled) { + tile.offset(0, h); rgn |= tile; + tile.offset(0, h); rgn |= tile; + tile.offset(0, -2 * h); + } + if (xTiled && yTiled) { + tile.offset(w, h); rgn |= tile; + tile.offset(w, 0); rgn |= tile; + tile.offset(-w, h); rgn |= tile; + tile.offset(w, 0); rgn |= tile; + } + } + + void collapseRegionByTiledMode(gfx::Region& rgn) const { + auto canvasSize = this->canvasSize(); + rgn &= gfx::Region(gfx::Rect(canvasSize)); + + const int sprW = m_canvas->width(); + const int sprH = m_canvas->height(); + + gfx::Region newRgn; + for (int v = 0; v < canvasSize.h; v += sprH) { + for (int u = 0; u < canvasSize.w; u += sprW) { + gfx::Region tmp(gfx::Rect(u, v, sprW, sprH)); + tmp &= rgn; + tmp.offset(-u, -v); + newRgn |= tmp; + } + } + rgn = newRgn; + } + + private: + filters::TiledMode m_mode; + const doc::Sprite* m_canvas; + + }; + +} // namespace app + +#endif