From 6d6dfb96a9034df2e128303312a689be2ba2f058 Mon Sep 17 00:00:00 2001 From: Gaspar Capello Date: Fri, 16 Dec 2022 18:01:01 -0300 Subject: [PATCH] Add user data to tiles (fix #3626) Co-authored-by: David Capello --- src/app/cmd/add_tile.cpp | 19 ++++++++++++------- src/app/cmd/add_tile.h | 15 +++++++++++---- src/app/commands/cmd_sprite_size.cpp | 1 + src/app/util/cel_ops.cpp | 9 ++++++--- src/app/util/expand_cel_canvas.cpp | 2 +- src/doc/sprite.cpp | 4 +++- src/doc/tileset.cpp | 21 +++++++++++++++++++-- src/doc/tileset.h | 17 +++++++++++++++-- 8 files changed, 68 insertions(+), 20 deletions(-) diff --git a/src/app/cmd/add_tile.cpp b/src/app/cmd/add_tile.cpp index 8f6980616..9b456a602 100644 --- a/src/app/cmd/add_tile.cpp +++ b/src/app/cmd/add_tile.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019-2020 Igara Studio S.A. +// Copyright (C) 2019-2022 Igara Studio S.A. // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -20,12 +20,14 @@ namespace app { namespace cmd { AddTile::AddTile(doc::Tileset* tileset, - const doc::ImageRef& image) + const doc::ImageRef& image, + const doc::UserData& userData) : WithTileset(tileset) , WithImage(image.get()) , m_size(0) , m_tileIndex(doc::notile) , m_imageRef(image) + , m_userData(userData) { } @@ -36,6 +38,7 @@ AddTile::AddTile(doc::Tileset* tileset, , m_size(0) , m_tileIndex(ti) , m_imageRef(nullptr) + , m_userData(tileset->getTileData(ti)) { } @@ -51,7 +54,7 @@ void AddTile::onExecute() } else { ASSERT(m_imageRef); - addTile(tileset, m_imageRef); + addTile(tileset, m_imageRef, m_userData); m_imageRef.reset(); } } @@ -78,7 +81,7 @@ void AddTile::onRedo() m_imageRef.reset(read_image(m_stream)); ASSERT(m_imageRef); - addTile(tileset, m_imageRef); + addTile(tileset, m_imageRef, m_userData); m_imageRef.reset(); m_stream.str(std::string()); @@ -95,12 +98,14 @@ void AddTile::onFireNotifications() ->notifyTilesetChanged(tileset); } -void AddTile::addTile(doc::Tileset* tileset, const doc::ImageRef& image) +void AddTile::addTile(doc::Tileset* tileset, + const doc::ImageRef& image, + const doc::UserData& userData) { if (m_tileIndex == doc::notile) - m_tileIndex = tileset->add(image); + m_tileIndex = tileset->add(image, userData); else - tileset->insert(m_tileIndex, image); + tileset->insert(m_tileIndex, image, userData); tileset->sprite()->incrementVersion(); tileset->incrementVersion(); diff --git a/src/app/cmd/add_tile.h b/src/app/cmd/add_tile.h index 330aefad9..ab61cea18 100644 --- a/src/app/cmd/add_tile.h +++ b/src/app/cmd/add_tile.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019-2020 Igara Studio S.A. +// Copyright (C) 2019-2022 Igara Studio S.A. // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -13,6 +13,7 @@ #include "app/cmd/with_tileset.h" #include "doc/image_ref.h" #include "doc/tile.h" +#include "doc/user_data.h" #include @@ -27,8 +28,11 @@ namespace cmd { , public WithTileset , public WithImage { public: - AddTile(doc::Tileset* tileset, const doc::ImageRef& image); - AddTile(doc::Tileset* tileset, const doc::tile_index ti); + AddTile(doc::Tileset* tileset, + const doc::ImageRef& image, + const doc::UserData& userData = UserData()); + AddTile(doc::Tileset* tileset, + const doc::tile_index ti); doc::tile_index tileIndex() const { return m_tileIndex; } @@ -38,17 +42,20 @@ namespace cmd { void onRedo() override; void onFireNotifications() override; size_t onMemSize() const override { + // TODO add m_userData size return sizeof(*this) + m_size; } private: void addTile(doc::Tileset* tileset, - const doc::ImageRef& image); + const doc::ImageRef& image, + const doc::UserData& userData); size_t m_size; std::stringstream m_stream; doc::tile_index m_tileIndex; doc::ImageRef m_imageRef; + doc::UserData m_userData; }; } // namespace cmd diff --git a/src/app/commands/cmd_sprite_size.cpp b/src/app/commands/cmd_sprite_size.cpp index 977f3499f..131aaa002 100644 --- a/src/app/commands/cmd_sprite_size.cpp +++ b/src/app/commands/cmd_sprite_size.cpp @@ -138,6 +138,7 @@ protected: sprite()->rgbMap(0))); // TODO first frame? newTileset->set(idx, newTileImg); + newTileset->setTileData(idx, tileset->getTileData(idx)); } jobProgress((float)progress / img_count); diff --git a/src/app/util/cel_ops.cpp b/src/app/util/cel_ops.cpp index f63de62cc..e98530676 100644 --- a/src/app/util/cel_ops.cpp +++ b/src/app/util/cel_ops.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019-2021 Igara Studio S.A. +// Copyright (C) 2019-2022 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -889,14 +889,17 @@ void copy_tiles_in_tileset( OPS_TRACE("copy_tiles_in_tileset beforeIndex=%d npicks=%d\n", beforeIndex, picks.picks()); std::vector newTiles; + std::vector newDatas; for (int i=0; i= 0 && i < tileset->size()) { newTiles.emplace_back(Image::createCopy(tileset->get(i).get())); + newDatas.emplace_back(tileset->getTileData(i)); } else { newTiles.emplace_back(tileset->makeEmptyTile()); + newDatas.emplace_back(UserData()); } } @@ -921,8 +924,8 @@ void copy_tiles_in_tileset( // "beforeIndex" with empty tiles while (tileset->size() < i) cmds->executeAndAdd(new cmd::AddTile(tileset, tileset->makeEmptyTile())); - - tileset->insert(i, newTiles[j++]); + tileset->insert(i, newTiles[j], newDatas[j]); + j++; cmds->executeAndAdd(new cmd::AddTile(tileset, i)); } } diff --git a/src/app/util/expand_cel_canvas.cpp b/src/app/util/expand_cel_canvas.cpp index 9ff9ef089..84e37a8c5 100644 --- a/src/app/util/expand_cel_canvas.cpp +++ b/src/app/util/expand_cel_canvas.cpp @@ -752,7 +752,7 @@ void ExpandCelCanvas::copySourceTilestToDestTileset() for (tile_index i=0; isize(); ++i) { doc::copy_image(m_dstTileset->get(i).get(), srcTileset->get(i).get()); - + m_dstTileset->setTileData(i, srcTileset->getTileData(i)); // To rehash the tileset m_dstTileset->notifyTileContentChange(i); } diff --git a/src/doc/sprite.cpp b/src/doc/sprite.cpp index a747e5ba9..9665e15bd 100644 --- a/src/doc/sprite.cpp +++ b/src/doc/sprite.cpp @@ -534,8 +534,10 @@ void Sprite::replaceImage(ObjectId curImageId, const ImageRef& newImage) for (Tileset* tileset : *tilesets()) { for (tile_index i=0; isize(); ++i) { ImageRef image = tileset->get(i); - if (image && image->id() == curImageId) + if (image && image->id() == curImageId) { + // Change only the tile image (not its user data) tileset->set(i, newImage); + } } } } diff --git a/src/doc/tileset.cpp b/src/doc/tileset.cpp index 6b7ba9d22..747f87383 100644 --- a/src/doc/tileset.cpp +++ b/src/doc/tileset.cpp @@ -27,6 +27,7 @@ Tileset::Tileset(Sprite* sprite, , m_sprite(sprite) , m_grid(grid) , m_tiles(ntiles) + , m_datas(ntiles) { // The origin of tileset grids must be 0,0 (the origin is then // specified by each cel position) @@ -64,6 +65,7 @@ Tileset* Tileset::MakeCopyWithSameImages(const Tileset* tileset) ImageRef image = tileset->get(ti); ASSERT(image); copy->set(ti, image); + copy->setTileData(ti, tileset->getTileData(ti)); } return copy.release(); } @@ -77,6 +79,7 @@ Tileset* Tileset::MakeCopyCopyingImages(const Tileset* tileset) ASSERT(image); // TODO can we avoid making a copy of this image copy->set(ti, ImageRef(Image::createCopy(image.get()))); + copy->setTileData(ti, tileset->getTileData(ti)); } return copy.release(); } @@ -95,6 +98,7 @@ void Tileset::resize(const tile_index ntiles) { int oldSize = m_tiles.size(); m_tiles.resize(ntiles); + m_datas.resize(ntiles); for (tile_index ti=oldSize; tiwidth() == m_grid.tileSize().w); @@ -152,6 +165,7 @@ tile_index Tileset::add(const ImageRef& image) preprocess_transparent_pixels(image.get()); m_tiles.push_back(image); + m_datas.push_back(userData); const tile_index newIndex = tile_index(m_tiles.size()-1); if (!m_hash.empty()) @@ -160,7 +174,8 @@ tile_index Tileset::add(const ImageRef& image) } void Tileset::insert(const tile_index ti, - const ImageRef& image) + const ImageRef& image, + const UserData& userData) { ASSERT(image); ASSERT(image->width() == m_grid.tileSize().w); @@ -175,6 +190,7 @@ void Tileset::insert(const tile_index ti, ASSERT(ti >= 0 && ti <= m_tiles.size()+1); preprocess_transparent_pixels(image.get()); m_tiles.insert(m_tiles.begin()+ti, image); + m_datas.insert(m_datas.begin()+ti, userData); if (!m_hash.empty()) { // Fix all indexes in the hash that are greater than "ti" @@ -194,6 +210,7 @@ void Tileset::erase(const tile_index ti) //removeFromHash(ti, true); m_tiles.erase(m_tiles.begin()+ti); + m_datas.erase(m_datas.begin()+ti); rehash(); } diff --git a/src/doc/tileset.h b/src/doc/tileset.h index f25f5c318..5e4f260df 100644 --- a/src/doc/tileset.h +++ b/src/doc/tileset.h @@ -26,6 +26,7 @@ namespace doc { class Tileset : public WithUserData { public: typedef std::vector Tiles; + typedef std::vector Datas; typedef Tiles::iterator iterator; typedef Tiles::const_iterator const_iterator; @@ -68,9 +69,20 @@ namespace doc { void set(const tile_index ti, const ImageRef& image); - tile_index add(const ImageRef& image); + UserData getTileData(const tile_index ti) const { + if (ti >= 0 && ti < size()) + return m_datas[ti]; + else + return UserData(); + } + void setTileData(const tile_index ti, + const UserData& userData); + + tile_index add(const ImageRef& image, + const UserData& userData = UserData()); void insert(const tile_index ti, - const ImageRef& image); + const ImageRef& image, + const UserData& userData = UserData()); void erase(const tile_index ti); // Linked with an external file @@ -126,6 +138,7 @@ namespace doc { Sprite* m_sprite; Grid m_grid; Tiles m_tiles; + Datas m_datas; TilesetHashTable m_hash; std::string m_name; int m_baseIndex = 1;