diff --git a/src/app/cmd/clear_mask.cpp b/src/app/cmd/clear_mask.cpp index ff78dbee8..4ac7ffbbd 100644 --- a/src/app/cmd/clear_mask.cpp +++ b/src/app/cmd/clear_mask.cpp @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2020 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -16,6 +17,7 @@ #include "doc/cel.h" #include "doc/image_impl.h" #include "doc/layer.h" +#include "doc/layer_tilemap.h" #include "doc/mask.h" #include "doc/primitives.h" @@ -33,6 +35,9 @@ ClearMask::ClearMask(Cel* cel) // entire image in the cel. if (!doc->isMaskVisible()) { m_seq.add(new cmd::ClearCel(cel)); + + // In this case m_copy will be nullptr, so the clear()/restore() + // member functions will have no effect. return; } @@ -41,60 +46,78 @@ ClearMask::ClearMask(Cel* cel) if (!image) return; - Mask* mask = doc->mask(); - m_offset = mask->bounds().origin() - cel->position(); + const Mask* mask = doc->mask(); + gfx::Rect imageBounds; + gfx::Rect maskBounds; + if (image->pixelFormat() == IMAGE_TILEMAP) { + auto grid = cel->grid(); + imageBounds = gfx::Rect(grid.canvasToTile(cel->position()), + cel->image()->size()); + maskBounds = grid.canvasToTile(mask->bounds()); + m_bgcolor = doc::tile_i_notile; // TODO configurable empty tile + } + else { + imageBounds = cel->bounds(); + maskBounds = mask->bounds(); + m_bgcolor = doc->bgColor(cel->layer()); + } - gfx::Rect bounds = - image->bounds().createIntersection( - gfx::Rect( - m_offset.x, m_offset.y, - mask->bounds().w, mask->bounds().h)); - if (bounds.isEmpty()) + gfx::Rect cropBounds = (imageBounds & maskBounds); + if (cropBounds.isEmpty()) return; - m_dstImage.reset(new WithImage(image)); - m_bgcolor = doc->bgColor(cel->layer()); - m_boundsX = bounds.x; - m_boundsY = bounds.y; + cropBounds.offset(-imageBounds.origin()); + m_cropPos = cropBounds.origin(); - m_copy.reset(crop_image(image, - bounds.x, bounds.y, bounds.w, bounds.h, m_bgcolor)); + m_copy.reset(crop_image(image, cropBounds, m_bgcolor)); } void ClearMask::onExecute() { m_seq.execute(context()); - if (m_dstImage) - clear(); + clear(); } void ClearMask::onUndo() { - if (m_dstImage) - restore(); + restore(); m_seq.undo(); } void ClearMask::onRedo() { m_seq.redo(); - if (m_dstImage) - clear(); + clear(); } void ClearMask::clear() { + if (!m_copy) + return; + Cel* cel = this->cel(); - Image* image = m_dstImage->image(); Doc* doc = static_cast(cel->document()); Mask* mask = doc->mask(); - doc::algorithm::fill_selection(image, m_offset, mask, m_bgcolor); + Grid grid = cel->grid(); + doc::algorithm::fill_selection( + cel->image(), + cel->bounds(), + mask, + m_bgcolor, + (cel->image()->isTilemap() ? &grid: nullptr)); } void ClearMask::restore() { - copy_image(m_dstImage->image(), m_copy.get(), m_boundsX, m_boundsY); + if (!m_copy) + return; + + Cel* cel = this->cel(); + copy_image(cel->image(), + m_copy.get(), + m_cropPos.x, + m_cropPos.y); } } // namespace cmd diff --git a/src/app/cmd/clear_mask.h b/src/app/cmd/clear_mask.h index b87f02926..b283d359c 100644 --- a/src/app/cmd/clear_mask.h +++ b/src/app/cmd/clear_mask.h @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2020 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -13,6 +14,7 @@ #include "app/cmd/with_image.h" #include "app/cmd_sequence.h" #include "doc/image_ref.h" +#include "gfx/rect.h" #include @@ -39,10 +41,8 @@ namespace cmd { void restore(); CmdSequence m_seq; - std::unique_ptr m_dstImage; ImageRef m_copy; - gfx::Point m_offset; - int m_boundsX, m_boundsY; + gfx::Point m_cropPos; color_t m_bgcolor; }; diff --git a/src/app/commands/cmd_fill_and_stroke.cpp b/src/app/commands/cmd_fill_and_stroke.cpp index ed01e9860..02616af0c 100644 --- a/src/app/commands/cmd_fill_and_stroke.cpp +++ b/src/app/commands/cmd_fill_and_stroke.cpp @@ -74,7 +74,11 @@ void FillCommand::onExecute(Context* ctx) return; Preferences& pref = Preferences::instance(); - app::Color color = pref.colorBar.fgColor(); + doc::color_t color; + if (site.tilemapMode() == TilemapMode::Tiles) + color = pref.colorBar.fgTile(); + else + color = color_utils::color_for_layer(pref.colorBar.fgColor(), layer); { Tx tx(writer.context(), "Fill Selection with Foreground Color"); @@ -88,25 +92,28 @@ void FillCommand::onExecute(Context* ctx) mask->bounds()); expand.validateDestCanvas(rgn); - const gfx::Point offset = (mask->bounds().origin() - - expand.getCel()->position()); - const doc::color_t docColor = - color_utils::color_for_layer( - color, layer); + gfx::Rect imageBounds(expand.getCel()->position(), + expand.getDestCanvas()->size()); + doc::Grid grid = site.grid(); + + if (site.tilemapMode() == TilemapMode::Tiles) + imageBounds = grid.tileToCanvas(imageBounds); if (m_type == Stroke) { doc::algorithm::stroke_selection( expand.getDestCanvas(), - offset, + imageBounds, mask, - docColor); + color, + (site.tilemapMode() == TilemapMode::Tiles ? &grid: nullptr)); } else { doc::algorithm::fill_selection( expand.getDestCanvas(), - offset, + imageBounds, mask, - docColor); + color, + (site.tilemapMode() == TilemapMode::Tiles ? &grid: nullptr)); } expand.commit(); diff --git a/src/app/tools/ink_processing.h b/src/app/tools/ink_processing.h index a3218d670..a1cf9f875 100644 --- a/src/app/tools/ink_processing.h +++ b/src/app/tools/ink_processing.h @@ -1062,25 +1062,18 @@ void GradientInkProcessing::processPixel(int x, int y) template class XorInkProcessing : public DoubleInkProcessing, ImageTraits> { public: - XorInkProcessing(ToolLoop* loop) { - m_color = loop->getPrimaryColor(); - } - void processPixel(int x, int y) { - // Do nothing - } - -private: - color_t m_color; + XorInkProcessing(ToolLoop* loop) { } + void processPixel(int x, int y) { } }; template<> void XorInkProcessing::processPixel(int x, int y) { - *m_dstAddress = rgba_blender_neg_bw(*m_srcAddress, m_color, 255); + *m_dstAddress = rgba_blender_neg_bw(*m_srcAddress, 0, 255); } template<> void XorInkProcessing::processPixel(int x, int y) { - *m_dstAddress = graya_blender_neg_bw(*m_srcAddress, m_color, 255); + *m_dstAddress = graya_blender_neg_bw(*m_srcAddress, 0, 255); } template<> @@ -1088,19 +1081,17 @@ class XorInkProcessing : public DoubleInkProcessinggetRgbMap()), - m_color(m_palette->getEntry(loop->getPrimaryColor())) { + m_rgbmap(loop->getRgbMap()) { } void processPixel(int x, int y) { - color_t c = rgba_blender_neg_bw(m_palette->getEntry(*m_srcAddress), m_color, 255); + color_t c = rgba_blender_neg_bw(m_palette->getEntry(*m_srcAddress), 0, 255); *m_dstAddress = m_rgbmap->mapColor(c); } private: const Palette* m_palette; const RgbMap* m_rgbmap; - color_t m_color; }; ////////////////////////////////////////////////////////////////////// diff --git a/src/app/ui/editor/pixels_movement.cpp b/src/app/ui/editor/pixels_movement.cpp index a103ac751..a8ea8bc02 100644 --- a/src/app/ui/editor/pixels_movement.cpp +++ b/src/app/ui/editor/pixels_movement.cpp @@ -280,6 +280,7 @@ void PixelsMovement::cutMask() if (writer.cel()) { clear_mask_from_cel(m_tx, writer.cel(), + m_site.tilemapMode(), m_site.tilesetMode()); // Do not trim here so we don't lost the information about all @@ -1100,6 +1101,7 @@ void PixelsMovement::reproduceAllTransformationsWithInnerCmds() case InnerCmd::Clear: clear_mask_from_cel(m_tx, m_site.cel(), + m_site.tilemapMode(), m_site.tilesetMode()); break; case InnerCmd::Flip: diff --git a/src/app/util/cel_ops.cpp b/src/app/util/cel_ops.cpp index 632980715..451e684c3 100644 --- a/src/app/util/cel_ops.cpp +++ b/src/app/util/cel_ops.cpp @@ -612,13 +612,14 @@ void modify_tilemap_cel_region( void clear_mask_from_cel(CmdSequence* cmds, doc::Cel* cel, + const TilemapMode tilemapMode, const TilesetMode tilesetMode) { ASSERT(cmds); ASSERT(cel); ASSERT(cel->layer()); - if (cel->layer()->isTilemap()) { + if (cel->layer()->isTilemap() && tilemapMode == TilemapMode::Pixels) { Doc* doc = static_cast(cel->document()); // Simple case (there is no visible selection, so we remove the @@ -640,9 +641,10 @@ void clear_mask_from_cel(CmdSequence* cmds, doc::ImageRef modified(doc::Image::createCopy(origTile.get())); doc::algorithm::fill_selection( modified.get(), - mask->bounds().origin() - tileBoundsInCanvas.origin(), + tileBoundsInCanvas, mask, - bgcolor); + bgcolor, + nullptr); return modified; }); } diff --git a/src/app/util/cel_ops.h b/src/app/util/cel_ops.h index c667040de..16497c36d 100644 --- a/src/app/util/cel_ops.h +++ b/src/app/util/cel_ops.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019 Igara Studio S.A. +// Copyright (C) 2019-2020 Igara Studio S.A. // Copyright (C) 2001-2016 David Capello // // This program is distributed under the terms of @@ -9,6 +9,7 @@ #define APP_UTIL_CEL_OPS_H_INCLUDED #pragma once +#include "app/tilemap_mode.h" #include "app/tileset_mode.h" #include "doc/color.h" #include "doc/frame.h" @@ -69,6 +70,7 @@ namespace app { void clear_mask_from_cel( CmdSequence* cmds, doc::Cel* cel, + const TilemapMode tilemapMode, const TilesetMode tilesetMode); // unusedTiles is a set of possibles tiles to check if they are diff --git a/src/app/util/clipboard.cpp b/src/app/util/clipboard.cpp index f9892b565..b75ca1b7f 100644 --- a/src/app/util/clipboard.cpp +++ b/src/app/util/clipboard.cpp @@ -253,7 +253,10 @@ void clear_mask_from_cels(Tx& tx, ObjectId celId = cel->id(); clear_mask_from_cel( - tx, cel, ColorBar::instance()->tilesetMode()); + tx, cel, + // TODO use Site information instead of color bar + ColorBar::instance()->tilemapMode(), + ColorBar::instance()->tilesetMode()); // Get cel again just in case the cmd::ClearMask() called cmd::ClearCel() cel = doc::get(celId); diff --git a/src/doc/algorithm/fill_selection.cpp b/src/doc/algorithm/fill_selection.cpp index ade09781a..b9e1b94b9 100644 --- a/src/doc/algorithm/fill_selection.cpp +++ b/src/doc/algorithm/fill_selection.cpp @@ -1,4 +1,5 @@ // Aseprite Document Library +// Copyright (c) 2020 Igara Studio S.A. // Copyright (c) 2018 David Capello // // This file is released under the terms of the MIT license. @@ -10,6 +11,7 @@ #include "doc/algorithm/fill_selection.h" +#include "doc/grid.h" #include "doc/image_impl.h" #include "doc/mask.h" #include "doc/primitives.h" @@ -18,27 +20,40 @@ namespace doc { namespace algorithm { void fill_selection(Image* image, - const gfx::Point& offset, + const gfx::Rect& imageBounds, const Mask* mask, - const color_t color) + const color_t color, + const Grid* grid) { ASSERT(mask); ASSERT(mask->bitmap()); if (!mask || !mask->bitmap()) return; - const LockImageBits maskBits(mask->bitmap()); - LockImageBits::const_iterator it = maskBits.begin(); + const auto rc = (imageBounds & mask->bounds()); + if (rc.isEmpty()) + return; // <- There is no intersection between image bounds and mask bounds - const gfx::Rect maskBounds = mask->bounds(); - for (int v=0; v maskBits(mask->bitmap(), + gfx::Rect(rc).offset(-mask->origin())); + auto it = maskBits.begin(); + + for (int v=0; vcanvasToTile(pt); + } + else { + pt -= imageBounds.origin(); + } + + // TODO use iterator + put_pixel(image, pt.x, pt.y, color); } } } diff --git a/src/doc/algorithm/fill_selection.h b/src/doc/algorithm/fill_selection.h index 237c230df..174d30238 100644 --- a/src/doc/algorithm/fill_selection.h +++ b/src/doc/algorithm/fill_selection.h @@ -1,4 +1,5 @@ // Aseprite Document Library +// Copyright (c) 2020 Igara Studio S.A. // Copyright (c) 2018 David Capello // // This file is released under the terms of the MIT license. @@ -9,17 +10,23 @@ #pragma once #include "doc/color.h" -#include "gfx/point.h" +#include "gfx/rect.h" namespace doc { + class Grid; class Image; class Mask; + namespace algorithm { - void fill_selection(Image* image, - const gfx::Point& offset, - const Mask* mask, - const color_t color); + void fill_selection( + Image* image, + const gfx::Rect& imageBounds, + const Mask* mask, + // This can be a color_t or a tile_t if the image is a tilemap + const color_t color, + // Optional grid for tilemaps + const Grid* grid = nullptr); } // namespace algorithm } // namespace doc diff --git a/src/doc/algorithm/fill_selection_tests.cpp b/src/doc/algorithm/fill_selection_tests.cpp new file mode 100644 index 000000000..03b7a2e03 --- /dev/null +++ b/src/doc/algorithm/fill_selection_tests.cpp @@ -0,0 +1,101 @@ +// Aseprite Document Library +// Copyright (c) 2020 Igara Studio S.A. +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#include "gtest/gtest.h" + +#include "doc/algorithm/fill_selection.h" +#include "doc/grid.h" +#include "doc/image.h" +#include "doc/mask.h" + +using namespace doc; +using namespace gfx; + +::testing::AssertionResult cmp_img(const std::vector& pixels, + const Image* image) +{ + int c = 0; + for (int y=0; yheight(); ++y) { + for (int x=0; xwidth(); ++x) { + if (pixels[c] != image->getPixel(x, y)) { + return ::testing::AssertionFailure() + << "ExpectedPixel=" << (int)pixels[c] + << " ActualPixel=" << (int)image->getPixel(x, y) + << " x=" << x + << " y=" << y; + } + ++c; + } + } + return ::testing::AssertionSuccess(); +} + +TEST(FillSelection, Image) +{ + ImageRef image(Image::create(IMAGE_INDEXED, 4, 4)); + image->clear(1); + + // No-op (no intersection between image & mask) + Mask mask; + mask.replace(Rect(0, 0, 1, 5)); + algorithm::fill_selection(image.get(), Rect(1, 1, 4, 4), &mask, 2, nullptr); + EXPECT_TRUE(cmp_img({ 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1 }, image.get())); + + mask.replace(Rect(1, 0, 2, 3)); + algorithm::fill_selection(image.get(), Rect(1, 1, 4, 4), &mask, 2, nullptr); + EXPECT_TRUE(cmp_img({ 2, 2, 1, 1, + 2, 2, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1 }, image.get())); + + mask.replace(Rect(2, 2, 2, 3)); + algorithm::fill_selection(image.get(), Rect(1, 3, 4, 4), &mask, 3, nullptr); + EXPECT_TRUE(cmp_img({ 2, 3, 3, 1, + 2, 3, 3, 1, + 1, 1, 1, 1, + 1, 1, 1, 1 }, image.get())); +} + +TEST(FillSelection, Tilemap) +{ + ImageRef image(Image::create(IMAGE_TILEMAP, 4, 4)); + image->clear(1); + + Grid grid(Size(8, 8)); + grid.origin(Point(4, 4)); + + // No-op (no intersection between image & mask) + Mask mask; + mask.replace(Rect(0, 0, 4, 4)); + algorithm::fill_selection(image.get(), Rect(4, 4, 32, 32), &mask, 2, &grid); + EXPECT_TRUE(cmp_img({ 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1 }, image.get())); + + mask.replace(Rect(0, 0, 5, 5)); + algorithm::fill_selection(image.get(), Rect(4, 4, 32, 32), &mask, 2, &grid); + EXPECT_TRUE(cmp_img({ 2, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1 }, image.get())); + + mask.replace(Rect(12, 12, 9, 8)); + algorithm::fill_selection(image.get(), Rect(4, 4, 32, 32), &mask, 3, &grid); + EXPECT_TRUE(cmp_img({ 2, 1, 1, 1, + 1, 3, 3, 1, + 1, 1, 1, 1, + 1, 1, 1, 1 }, image.get())); +} + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/doc/algorithm/stroke_selection.cpp b/src/doc/algorithm/stroke_selection.cpp index 8d134f223..30a2365f3 100644 --- a/src/doc/algorithm/stroke_selection.cpp +++ b/src/doc/algorithm/stroke_selection.cpp @@ -18,9 +18,10 @@ namespace doc { namespace algorithm { void stroke_selection(Image* image, - const gfx::Point& offset, + const gfx::Rect& imageBounds, const Mask* origMask, - const color_t color) + const color_t color, + const Grid* grid) { ASSERT(origMask); ASSERT(origMask->bitmap()); @@ -44,7 +45,7 @@ void stroke_selection(Image* image, ASSERT(mask.bounds() == origMask->bounds()); if (mask.bitmap()) - fill_selection(image, offset, &mask, color); + fill_selection(image, imageBounds, &mask, color, grid); } } // namespace algorithm diff --git a/src/doc/algorithm/stroke_selection.h b/src/doc/algorithm/stroke_selection.h index 3eca85f6d..adb595d6f 100644 --- a/src/doc/algorithm/stroke_selection.h +++ b/src/doc/algorithm/stroke_selection.h @@ -1,4 +1,5 @@ // Aseprite Document Library +// Copyright (c) 2020 Igara Studio S.A. // Copyright (c) 2018 David Capello // // This file is released under the terms of the MIT license. @@ -9,17 +10,23 @@ #pragma once #include "doc/color.h" -#include "gfx/point.h" +#include "gfx/rect.h" namespace doc { + class Grid; class Image; class Mask; + namespace algorithm { - void stroke_selection(Image* image, - const gfx::Point& offset, - const Mask* mask, - const color_t color); + void stroke_selection( + Image* image, + const gfx::Rect& imageBounds, + const Mask* mask, + // This can be a color_t or a tile_t if the image is a tilemap + const color_t color, + // Optional grid for tilemaps + const Grid* grid = nullptr); } // namespace algorithm } // namespace doc diff --git a/src/doc/cel.cpp b/src/doc/cel.cpp index 41fdce6d5..d29b5a5f8 100644 --- a/src/doc/cel.cpp +++ b/src/doc/cel.cpp @@ -11,11 +11,13 @@ #include "doc/cel.h" -#include "gfx/rect.h" +#include "doc/grid.h" #include "doc/image.h" #include "doc/layer.h" +#include "doc/layer_tilemap.h" #include "doc/sprite.h" #include "doc/tile.h" +#include "gfx/rect.h" namespace doc { @@ -146,6 +148,20 @@ void Cel::setParentLayer(LayerImage* layer) fixupImage(); } +Grid Cel::grid() const +{ + if (m_layer) { + if (m_layer->isTilemap()) { + doc::Grid grid = static_cast(m_layer)->tileset()->grid(); + grid.origin(grid.origin() + position()); + return grid; + } + else + return m_layer->grid(); + } + return Grid(); +} + void Cel::fixupImage() { // Change the mask color to the sprite mask color diff --git a/src/doc/cel.h b/src/doc/cel.h index 6cb8b3f17..12b7391e7 100644 --- a/src/doc/cel.h +++ b/src/doc/cel.h @@ -1,5 +1,5 @@ // Aseprite Document Library -// Copyright (c) 2019 Igara Studio S.A. +// Copyright (c) 2019-2020 Igara Studio S.A. // Copyright (c) 2001-2016 David Capello // // This file is released under the terms of the MIT license. @@ -20,6 +20,7 @@ namespace doc { class Document; + class Grid; class LayerImage; class Sprite; @@ -67,6 +68,7 @@ namespace doc { } void setParentLayer(LayerImage* layer); + Grid grid() const; private: void fixupImage(); diff --git a/src/doc/image.h b/src/doc/image.h index 742e59cee..62dbf38a1 100644 --- a/src/doc/image.h +++ b/src/doc/image.h @@ -46,6 +46,7 @@ namespace doc { const ImageSpec& spec() const { return m_spec; } ColorMode colorMode() const { return m_spec.colorMode(); } PixelFormat pixelFormat() const { return (PixelFormat)colorMode(); } + bool isTilemap() const { return m_spec.colorMode() == ColorMode::TILEMAP; } int width() const { return m_spec.width(); } int height() const { return m_spec.height(); } gfx::Size size() const { return m_spec.size(); } diff --git a/src/doc/layer.cpp b/src/doc/layer.cpp index cc86481ac..382a6cf46 100644 --- a/src/doc/layer.cpp +++ b/src/doc/layer.cpp @@ -12,6 +12,7 @@ #include "doc/layer.h" #include "doc/cel.h" +#include "doc/grid.h" #include "doc/image.h" #include "doc/primitives.h" #include "doc/sprite.h" @@ -190,6 +191,15 @@ bool Layer::hasAncestor(const Layer* ancestor) const return false; } +Grid Layer::grid() const +{ + gfx::Rect rc = (m_sprite ? m_sprite->gridBounds(): + doc::Sprite::DefaultGridBounds()); + doc::Grid grid = Grid(rc.size()); + grid.origin(gfx::Point(rc.x % rc.w, rc.y % rc.h)); + return grid; +} + Cel* Layer::cel(frame_t frame) const { return nullptr; diff --git a/src/doc/layer.h b/src/doc/layer.h index 1efa01cce..c44672e6f 100644 --- a/src/doc/layer.h +++ b/src/doc/layer.h @@ -21,11 +21,12 @@ namespace doc { class Cel; + class Grid; class Image; - class Sprite; class Layer; class LayerGroup; class LayerImage; + class Sprite; ////////////////////////////////////////////////////////////////////// // Layer class @@ -120,6 +121,7 @@ namespace doc { m_flags = LayerFlags(int(m_flags) & ~int(flags)); } + virtual Grid grid() const; virtual Cel* cel(frame_t frame) const; virtual void getCels(CelList& cels) const = 0; virtual void displaceFrames(frame_t fromThis, frame_t delta) = 0; diff --git a/src/doc/layer_tilemap.cpp b/src/doc/layer_tilemap.cpp index 768bacf52..6de503108 100644 --- a/src/doc/layer_tilemap.cpp +++ b/src/doc/layer_tilemap.cpp @@ -1,5 +1,5 @@ // Aseprite Document Library -// Copyright (c) 2019 Igara Studio S.A. +// Copyright (c) 2019-2020 Igara Studio S.A. // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -28,6 +28,14 @@ LayerTilemap::~LayerTilemap() { } +Grid LayerTilemap::grid() const +{ + if (m_tileset) + return m_tileset->grid(); + else + return Layer::grid(); +} + void LayerTilemap::setTilesetIndex(tileset_index tsi) { m_tilesetIndex = tsi; diff --git a/src/doc/layer_tilemap.h b/src/doc/layer_tilemap.h index bfe3109dd..adc04da65 100644 --- a/src/doc/layer_tilemap.h +++ b/src/doc/layer_tilemap.h @@ -1,5 +1,5 @@ // Aseprite Document Library -// Copyright (c) 2019 Igara Studio S.A. +// Copyright (c) 2019-2020 Igara Studio S.A. // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -19,6 +19,8 @@ namespace doc { explicit LayerTilemap(Sprite* sprite, const tileset_index tsi); ~LayerTilemap(); + Grid grid() const override; + // Returns the tileset of this layer. New automatically-created // tiles should be stored into this tileset, and all tiles in the // layer should share the same Grid spec. diff --git a/src/doc/mask.h b/src/doc/mask.h index ffc6e9689..be6f0b8ee 100644 --- a/src/doc/mask.h +++ b/src/doc/mask.h @@ -1,4 +1,5 @@ // Aseprite Document Library +// Copyright (c) 2020 Igara Studio S.A. // Copyright (c) 2001-2018 David Capello // // This file is released under the terms of the MIT license. @@ -50,6 +51,7 @@ namespace doc { get_pixel(m_bitmap.get(), u-m_bounds.x, v-m_bounds.y)); } + gfx::Point origin() const { return m_bounds.origin(); } const gfx::Rect& bounds() const { return m_bounds; } void setOrigin(int x, int y) {