Fix conversions between layer <-> tilemap when grid origin != 0,0

We've changed a restriction for tilesets: grid's in doc::Tileset must
have origin=(0,0); and the origin of a doc::Grid only makes sense for
the sprite grid (where the origin is set by the user) or for a tilemap
cel (where the origin is the cel origin).
This commit is contained in:
David Capello 2021-04-15 21:26:45 -03:00
parent 5bd83d0c1a
commit 14c3cfe393
6 changed files with 45 additions and 27 deletions

View File

@ -165,7 +165,7 @@ void ConvertLayerCommand::onExecute(Context* ctx)
if (srcLayer->isBackground()) { if (srcLayer->isBackground()) {
tx(new cmd::LayerFromBackground(srcLayer)); tx(new cmd::LayerFromBackground(srcLayer));
} }
// Background -> Tilemap // Tilemap -> Layer
else if (srcLayer->isTilemap()) { else if (srcLayer->isTilemap()) {
auto newLayer = new LayerImage(sprite); auto newLayer = new LayerImage(sprite);
newLayer->setName(srcLayer->name()); newLayer->setName(srcLayer->name());
@ -183,7 +183,9 @@ void ConvertLayerCommand::onExecute(Context* ctx)
if (srcLayer->isImage() && if (srcLayer->isImage() &&
(srcLayer->isBackground() || (srcLayer->isBackground() ||
srcLayer->isTransparent())) { srcLayer->isTransparent())) {
auto tileset = new Tileset(sprite, site.grid(), 1); Grid grid0 = site.grid();
grid0.origin(gfx::Point(0, 0));
auto tileset = new Tileset(sprite, grid0, 1);
auto addTileset = new cmd::AddTileset(sprite, tileset); auto addTileset = new cmd::AddTileset(sprite, tileset);
tx(addTileset); tx(addTileset);

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2019-2020 Igara Studio S.A. // Copyright (C) 2019-2021 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -187,15 +187,26 @@ Cel* create_cel_copy(CmdSequence* cmds,
// From Tilemap -> Image // From Tilemap -> Image
if (srcCel->layer()->isTilemap() && !dstLayer->isTilemap()) { if (srcCel->layer()->isTilemap() && !dstLayer->isTilemap()) {
auto layerTilemap = static_cast<doc::LayerTilemap*>(srcCel->layer()); auto layerTilemap = static_cast<doc::LayerTilemap*>(srcCel->layer());
const auto& grid = layerTilemap->tileset()->grid(); dstSize = layerTilemap->tileset()->grid().tilemapSizeToCanvas(dstSize);
dstSize = grid.tilemapSizeToCanvas(dstSize);
} }
// From Image or Tilemap -> Tilemap // From Image or Tilemap -> Tilemap
else if (dstLayer->isTilemap()) { else if (dstLayer->isTilemap()) {
auto layerTilemap = static_cast<doc::LayerTilemap*>(dstLayer); auto dstLayerTilemap = static_cast<doc::LayerTilemap*>(dstLayer);
auto grid = layerTilemap->tileset()->grid();
if (srcCel->layer()->isTilemap()) // TODO check if this is correct // Tilemap -> Tilemap
grid.origin(grid.origin() + srcCel->position()); Grid grid;
if (srcCel->layer()->isTilemap()) {
grid = dstLayerTilemap->tileset()->grid();
if (srcCel->layer()->isTilemap())
grid.origin(srcCel->position());
}
// Image -> Tilemap
else {
auto gridBounds = dstLayerTilemap->sprite()->gridBounds();
grid.origin(gridBounds.origin());
grid.tileSize(gridBounds.size());
}
const gfx::Rect tilemapBounds = grid.canvasToTile(srcCel->bounds()); const gfx::Rect tilemapBounds = grid.canvasToTile(srcCel->bounds());
dstSize = tilemapBounds.size(); dstSize = tilemapBounds.size();
} }
@ -276,7 +287,8 @@ Cel* create_cel_copy(CmdSequence* cmds,
draw_image_into_new_tilemap_cel( draw_image_into_new_tilemap_cel(
cmds, static_cast<doc::LayerTilemap*>(dstLayer), dstCel.get(), cmds, static_cast<doc::LayerTilemap*>(dstLayer), dstCel.get(),
srcImage, srcImage,
gfx::Point(0, 0), // Use the grid origin of the sprite
srcCel->sprite()->gridBounds().origin(),
srcCel->bounds().origin(), srcCel->bounds().origin(),
srcCel->bounds(), srcCel->bounds(),
tilemap); tilemap);
@ -356,7 +368,7 @@ void draw_image_into_new_tilemap_cel(
doc::LayerTilemap* dstLayer, doc::LayerTilemap* dstLayer,
doc::Cel* dstCel, doc::Cel* dstCel,
const doc::Image* srcImage, const doc::Image* srcImage,
const gfx::Point& originOffset, const gfx::Point& gridOrigin,
const gfx::Point& srcImagePos, const gfx::Point& srcImagePos,
const gfx::Rect& canvasBounds, const gfx::Rect& canvasBounds,
doc::ImageRef& newTilemap) doc::ImageRef& newTilemap)
@ -365,7 +377,7 @@ void draw_image_into_new_tilemap_cel(
doc::Tileset* tileset = dstLayer->tileset(); doc::Tileset* tileset = dstLayer->tileset();
doc::Grid grid = tileset->grid(); doc::Grid grid = tileset->grid();
grid.origin(grid.origin() + originOffset); grid.origin(gridOrigin);
gfx::Size tileSize = grid.tileSize(); gfx::Size tileSize = grid.tileSize();
const gfx::Rect tilemapBounds = grid.canvasToTile(canvasBounds); const gfx::Rect tilemapBounds = grid.canvasToTile(canvasBounds);

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2019-2020 Igara Studio S.A. // Copyright (C) 2019-2021 Igara Studio S.A.
// Copyright (C) 2001-2016 David Capello // Copyright (C) 2001-2016 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -60,7 +60,7 @@ namespace app {
doc::LayerTilemap* dstLayer, doc::LayerTilemap* dstLayer,
doc::Cel* dstCel, doc::Cel* dstCel,
const doc::Image* srcImage, const doc::Image* srcImage,
const gfx::Point& originOffset, const gfx::Point& gridOrigin,
const gfx::Point& srcImagePos, const gfx::Point& srcImagePos,
const gfx::Rect& canvasBounds, const gfx::Rect& canvasBounds,
doc::ImageRef& newTilemap); doc::ImageRef& newTilemap);

View File

@ -1,5 +1,5 @@
// Aseprite Document Library // Aseprite Document Library
// Copyright (c) 2019-2020 Igara Studio S.A. // Copyright (c) 2019-2021 Igara Studio S.A.
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information. // Read LICENSE.txt for more information.
@ -128,10 +128,8 @@ gfx::Region Grid::canvasToTile(const gfx::Region& canvasRgn)
gfx::Size Grid::tilemapSizeToCanvas(const gfx::Size& tilemapSize) const gfx::Size Grid::tilemapSizeToCanvas(const gfx::Size& tilemapSize) const
{ {
gfx::Point pt = tileToCanvas(gfx::Point(tilemapSize.w-1, return gfx::Size(tilemapSize.w * m_tileSize.w,
tilemapSize.h-1)); tilemapSize.h * m_tileSize.h);
return gfx::Size(pt.x + m_tileSize.w,
pt.y + m_tileSize.h);
} }
gfx::Rect Grid::tileBoundsInCanvas(const gfx::Point& tile) const gfx::Rect Grid::tileBoundsInCanvas(const gfx::Point& tile) const

View File

@ -1,5 +1,5 @@
// Aseprite Document Library // Aseprite Document Library
// Copyright (c) 2019-2020 Igara Studio S.A. // Copyright (c) 2019-2021 Igara Studio S.A.
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information. // Read LICENSE.txt for more information.
@ -28,6 +28,10 @@ Tileset::Tileset(Sprite* sprite,
, m_grid(grid) , m_grid(grid)
, m_tiles(ntiles) , m_tiles(ntiles)
{ {
// The origin of tileset grids must be 0,0 (the origin is then
// specified by each cel position)
ASSERT(grid.origin() == gfx::Point(0, 0));
// TODO at the moment retrieving a tileset from the clipboard use no // TODO at the moment retrieving a tileset from the clipboard use no
// sprite, but in the future we should save a whole sprite in the // sprite, but in the future we should save a whole sprite in the
// clipboard // clipboard
@ -73,11 +77,6 @@ Tileset* Tileset::MakeCopyCopyingImages(const Tileset* tileset)
return copy.release(); return copy.release();
} }
void Tileset::setOrigin(const gfx::Point& pt)
{
m_grid.origin(pt);
}
int Tileset::getMemSize() const int Tileset::getMemSize() const
{ {
int size = sizeof(Tileset) + m_name.size(); int size = sizeof(Tileset) + m_name.size();
@ -137,6 +136,10 @@ void Tileset::set(const tile_index ti,
tile_index Tileset::add(const ImageRef& image) tile_index Tileset::add(const ImageRef& image)
{ {
ASSERT(image);
ASSERT(image->width() == m_grid.tileSize().w);
ASSERT(image->height() == m_grid.tileSize().h);
m_tiles.push_back(image); m_tiles.push_back(image);
const tile_index newIndex = tile_index(m_tiles.size()-1); const tile_index newIndex = tile_index(m_tiles.size()-1);
@ -154,6 +157,10 @@ void Tileset::insert(const tile_index ti,
} }
#endif #endif
ASSERT(image);
ASSERT(image->width() == m_grid.tileSize().w);
ASSERT(image->height() == m_grid.tileSize().h);
ASSERT(ti >= 0 && ti <= m_tiles.size()+1); ASSERT(ti >= 0 && ti <= m_tiles.size()+1);
m_tiles.insert(m_tiles.begin()+ti, image); m_tiles.insert(m_tiles.begin()+ti, image);

View File

@ -1,5 +1,5 @@
// Aseprite Document Library // Aseprite Document Library
// Copyright (c) 2019-2020 Igara Studio S.A. // Copyright (c) 2019-2021 Igara Studio S.A.
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information. // Read LICENSE.txt for more information.
@ -40,7 +40,6 @@ namespace doc {
Sprite* sprite() const { return m_sprite; } Sprite* sprite() const { return m_sprite; }
const Grid& grid() const { return m_grid; } const Grid& grid() const { return m_grid; }
void setOrigin(const gfx::Point& pt);
const std::string& name() const { return m_name; } const std::string& name() const { return m_name; }
void setName(const std::string& name) { m_name = name; } void setName(const std::string& name) { m_name = name; }