From 14c3cfe393cdffc8647a920f01b8066d8c7426f7 Mon Sep 17 00:00:00 2001 From: David Capello Date: Thu, 15 Apr 2021 21:26:45 -0300 Subject: [PATCH] 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). --- src/app/commands/convert_layer.cpp | 6 ++++-- src/app/util/cel_ops.cpp | 32 ++++++++++++++++++++---------- src/app/util/cel_ops.h | 4 ++-- src/doc/grid.cpp | 8 +++----- src/doc/tileset.cpp | 19 ++++++++++++------ src/doc/tileset.h | 3 +-- 6 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/app/commands/convert_layer.cpp b/src/app/commands/convert_layer.cpp index 922a8ede0..a53f1de6c 100644 --- a/src/app/commands/convert_layer.cpp +++ b/src/app/commands/convert_layer.cpp @@ -165,7 +165,7 @@ void ConvertLayerCommand::onExecute(Context* ctx) if (srcLayer->isBackground()) { tx(new cmd::LayerFromBackground(srcLayer)); } - // Background -> Tilemap + // Tilemap -> Layer else if (srcLayer->isTilemap()) { auto newLayer = new LayerImage(sprite); newLayer->setName(srcLayer->name()); @@ -183,7 +183,9 @@ void ConvertLayerCommand::onExecute(Context* ctx) if (srcLayer->isImage() && (srcLayer->isBackground() || 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); tx(addTileset); diff --git a/src/app/util/cel_ops.cpp b/src/app/util/cel_ops.cpp index 684bee8a2..5680d45ef 100644 --- a/src/app/util/cel_ops.cpp +++ b/src/app/util/cel_ops.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019-2020 Igara Studio S.A. +// Copyright (C) 2019-2021 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -187,15 +187,26 @@ Cel* create_cel_copy(CmdSequence* cmds, // From Tilemap -> Image if (srcCel->layer()->isTilemap() && !dstLayer->isTilemap()) { auto layerTilemap = static_cast(srcCel->layer()); - const auto& grid = layerTilemap->tileset()->grid(); - dstSize = grid.tilemapSizeToCanvas(dstSize); + dstSize = layerTilemap->tileset()->grid().tilemapSizeToCanvas(dstSize); } // From Image or Tilemap -> Tilemap else if (dstLayer->isTilemap()) { - auto layerTilemap = static_cast(dstLayer); - auto grid = layerTilemap->tileset()->grid(); - if (srcCel->layer()->isTilemap()) // TODO check if this is correct - grid.origin(grid.origin() + srcCel->position()); + auto dstLayerTilemap = static_cast(dstLayer); + + // Tilemap -> Tilemap + 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()); dstSize = tilemapBounds.size(); } @@ -276,7 +287,8 @@ Cel* create_cel_copy(CmdSequence* cmds, draw_image_into_new_tilemap_cel( cmds, static_cast(dstLayer), dstCel.get(), srcImage, - gfx::Point(0, 0), + // Use the grid origin of the sprite + srcCel->sprite()->gridBounds().origin(), srcCel->bounds().origin(), srcCel->bounds(), tilemap); @@ -356,7 +368,7 @@ void draw_image_into_new_tilemap_cel( doc::LayerTilemap* dstLayer, doc::Cel* dstCel, const doc::Image* srcImage, - const gfx::Point& originOffset, + const gfx::Point& gridOrigin, const gfx::Point& srcImagePos, const gfx::Rect& canvasBounds, doc::ImageRef& newTilemap) @@ -365,7 +377,7 @@ void draw_image_into_new_tilemap_cel( doc::Tileset* tileset = dstLayer->tileset(); doc::Grid grid = tileset->grid(); - grid.origin(grid.origin() + originOffset); + grid.origin(gridOrigin); gfx::Size tileSize = grid.tileSize(); const gfx::Rect tilemapBounds = grid.canvasToTile(canvasBounds); diff --git a/src/app/util/cel_ops.h b/src/app/util/cel_ops.h index b398e086d..acb6b9221 100644 --- a/src/app/util/cel_ops.h +++ b/src/app/util/cel_ops.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019-2020 Igara Studio S.A. +// Copyright (C) 2019-2021 Igara Studio S.A. // Copyright (C) 2001-2016 David Capello // // This program is distributed under the terms of @@ -60,7 +60,7 @@ namespace app { doc::LayerTilemap* dstLayer, doc::Cel* dstCel, const doc::Image* srcImage, - const gfx::Point& originOffset, + const gfx::Point& gridOrigin, const gfx::Point& srcImagePos, const gfx::Rect& canvasBounds, doc::ImageRef& newTilemap); diff --git a/src/doc/grid.cpp b/src/doc/grid.cpp index 27b183a4f..4f6db0ed4 100644 --- a/src/doc/grid.cpp +++ b/src/doc/grid.cpp @@ -1,5 +1,5 @@ // 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. // 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::Point pt = tileToCanvas(gfx::Point(tilemapSize.w-1, - tilemapSize.h-1)); - return gfx::Size(pt.x + m_tileSize.w, - pt.y + m_tileSize.h); + return gfx::Size(tilemapSize.w * m_tileSize.w, + tilemapSize.h * m_tileSize.h); } gfx::Rect Grid::tileBoundsInCanvas(const gfx::Point& tile) const diff --git a/src/doc/tileset.cpp b/src/doc/tileset.cpp index 6439563a8..294a75e59 100644 --- a/src/doc/tileset.cpp +++ b/src/doc/tileset.cpp @@ -1,5 +1,5 @@ // 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. // Read LICENSE.txt for more information. @@ -28,6 +28,10 @@ Tileset::Tileset(Sprite* sprite, , m_grid(grid) , 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 // sprite, but in the future we should save a whole sprite in the // clipboard @@ -73,11 +77,6 @@ Tileset* Tileset::MakeCopyCopyingImages(const Tileset* tileset) return copy.release(); } -void Tileset::setOrigin(const gfx::Point& pt) -{ - m_grid.origin(pt); -} - int Tileset::getMemSize() const { 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) { + ASSERT(image); + ASSERT(image->width() == m_grid.tileSize().w); + ASSERT(image->height() == m_grid.tileSize().h); + m_tiles.push_back(image); const tile_index newIndex = tile_index(m_tiles.size()-1); @@ -154,6 +157,10 @@ void Tileset::insert(const tile_index ti, } #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); m_tiles.insert(m_tiles.begin()+ti, image); diff --git a/src/doc/tileset.h b/src/doc/tileset.h index f049de00b..6ced9ec0b 100644 --- a/src/doc/tileset.h +++ b/src/doc/tileset.h @@ -1,5 +1,5 @@ // 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. // Read LICENSE.txt for more information. @@ -40,7 +40,6 @@ namespace doc { Sprite* sprite() const { return m_sprite; } const Grid& grid() const { return m_grid; } - void setOrigin(const gfx::Point& pt); const std::string& name() const { return m_name; } void setName(const std::string& name) { m_name = name; }