diff --git a/src/app/cmd/clear_rect.cpp b/src/app/cmd/clear_rect.cpp index 5b3eecfaa..59641ae34 100644 --- a/src/app/cmd/clear_rect.cpp +++ b/src/app/cmd/clear_rect.cpp @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2025 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -20,7 +21,20 @@ namespace app { namespace cmd { using namespace doc; +ClearRect::ClearRect(Cel* cel, const gfx::Rect& bounds, color_t color) +{ + ASSERT(cel); + initialize(cel, bounds, color); +} + ClearRect::ClearRect(Cel* cel, const gfx::Rect& bounds) +{ + ASSERT(cel); + Doc* doc = static_cast(cel->document()); + initialize(cel, bounds, doc->bgColor(cel->layer())); +} + +void ClearRect::initialize(Cel* cel, const gfx::Rect& bounds, color_t color) { ASSERT(cel); @@ -37,9 +51,7 @@ ClearRect::ClearRect(Cel* cel, const gfx::Rect& bounds) return; m_dstImage.reset(new WithImage(image)); - - Doc* doc = static_cast(cel->document()); - m_bgcolor = doc->bgColor(cel->layer()); + m_bgcolor = color; m_copy.reset(crop_image(image, bounds2.x, bounds2.y, bounds2.w, bounds2.h, m_bgcolor)); } diff --git a/src/app/cmd/clear_rect.h b/src/app/cmd/clear_rect.h index 10f070aa9..d48ebedfd 100644 --- a/src/app/cmd/clear_rect.h +++ b/src/app/cmd/clear_rect.h @@ -1,4 +1,5 @@ // Aseprite +// Copyright (C) 2025 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -26,6 +27,7 @@ using namespace doc; class ClearRect : public Cmd { public: ClearRect(Cel* cel, const gfx::Rect& bounds); + ClearRect(Cel* cel, const gfx::Rect& bounds, color_t color); protected: void onExecute() override; @@ -37,6 +39,7 @@ protected: } private: + void initialize(Cel* cel, const gfx::Rect& bounds, color_t color); void clear(); void restore(); diff --git a/src/app/script/image_class.cpp b/src/app/script/image_class.cpp index eff32a3fa..d3c047827 100644 --- a/src/app/script/image_class.cpp +++ b/src/app/script/image_class.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2018-2024 Igara Studio S.A. +// Copyright (C) 2018-2025 Igara Studio S.A. // Copyright (C) 2015-2018 David Capello // // This program is distributed under the terms of @@ -9,6 +9,7 @@ #include "config.h" #endif +#include "app/cmd/clear_rect.h" #include "app/cmd/copy_rect.h" #include "app/cmd/copy_region.h" #include "app/cmd/flip_image.h" @@ -246,7 +247,15 @@ int Image_clear(lua_State* L) else color = convert_args_into_pixel_color(L, i, img->pixelFormat()); - doc::fill_rect(img, rc, color); // Clips the rectangle to the image bounds + if (auto cel = obj->cel(L)) { + Tx tx(cel->sprite()); + tx(new cmd::ClearRect(cel, rc.offset(cel->position()), color)); + tx.commit(); + } + // If the destination image is not related to a sprite, we just draw + // the source image without undo information. + else + doc::fill_rect(img, rc, color); // Clips the rectangle to the image bounds return 0; } diff --git a/tests/scripts/image.lua b/tests/scripts/image.lua index b695ed6b1..6be4ebc5d 100644 --- a/tests/scripts/image.lua +++ b/tests/scripts/image.lua @@ -64,6 +64,108 @@ do 1, 2 }) end +-- Clear command with an image which is linked to a sprite +-- Clear command on RGBA images +do + local spr = Sprite(4, 4, ColorMode.RGB) + local image = Image(2, 2, ColorMode.RGB) + local mask = app.pixelColor.rgba(0, 0, 0, 0) + local imageCols = { app.pixelColor.rgba(255, 0, 0), app.pixelColor.rgba(0, 255, 0), + mask , app.pixelColor.rgba(0, 0 , 255) } + array_to_pixels(imageCols, image) + expect_img(image, imageCols) + spr:newCel(app.layer, 1, image, Point(2, 2)) + image:clear() + expect_img(image, { mask, mask, + mask, mask }) + + array_to_pixels(imageCols, image) + spr.layers[1]:cel(1).image = image + spr.layers[1]:cel(1).position = Point(2, 2) + image:clear(Rectangle(0, 0, 2, 1)) + expect_img(image, { mask , mask, + imageCols[3], imageCols[4] }) + app.undo() + -- Re-catch the cel image (TODO: 'image' variable should retain the link of the cel image) + image = spr.layers[1]:cel(1).image + expect_img(image, imageCols) + + local yellow = app.pixelColor.rgba(128, 128, 0) + image:clear(Rectangle(0, 0, 2, 1), yellow) + expect_img(image, { yellow , yellow, + imageCols[3] , imageCols[4] }) + app.undo() + expect_img(image, imageCols) +end + +-- Clear command on Grayscale images +do + local spr = Sprite(4, 4, ColorMode.GRAY) + local image = Image(2, 2, ColorMode.GRAY) + local mask = app.pixelColor.graya(0, 0) + local imageCols = { app.pixelColor.graya(255), app.pixelColor.graya(127), + mask , app.pixelColor.graya(63) } + array_to_pixels(imageCols, image) + expect_img(image, imageCols) + spr:newCel(app.layer, 1, image, Point(2, 2)) + image:clear() + expect_img(image, { mask, mask, + mask, mask }) + + array_to_pixels(imageCols, image) + spr.layers[1]:cel(1).image = image + spr.layers[1]:cel(1).position = Point(2, 2) + image:clear(Rectangle(0, 0, 2, 1)) + expect_img(image, { mask , mask, + imageCols[3], imageCols[4] }) + app.undo() + -- Re-catch the cel image (TODO: 'image' variable should retain the link of the cel image) + image = spr.layers[1]:cel(1).image + expect_img(image, imageCols) + + local white200 = app.pixelColor.graya(200) + image:clear(Rectangle(0, 0, 2, 1),white200) + expect_img(image, { white200 , white200, + imageCols[3] , imageCols[4] }) + app.undo() + expect_img(image, imageCols) +end + +-- Clear command on Indexed images +do + local spr = Sprite(4, 4, ColorMode.INDEXED) + local image = Image(2, 2, ColorMode.INDEXED) + spr.palettes[1]:setColor(1, Color(255, 0 , 0)) + spr.palettes[1]:setColor(2, Color(0 , 255, 0)) + spr.palettes[1]:setColor(3, Color(0 , 0 , 255)) + + local imageCols = { 1, 2, + 0, 3 } + array_to_pixels(imageCols, image) + expect_img(image, imageCols) + spr:newCel(app.layer, 1, image, Point(2, 2)) + image:clear() + expect_img(image, { 0, 0, + 0, 0 }) + + array_to_pixels(imageCols, image) + spr.layers[1]:cel(1).image = image + spr.layers[1]:cel(1).position = Point(2, 2) + image:clear(Rectangle(0, 0, 2, 1)) + expect_img(image, { 0 , 0, + imageCols[3], imageCols[4] }) + app.undo() + -- Re-catch the cel image (TODO: 'image' variable should retain the link of the cel image) + image = spr.layers[1]:cel(1).image + expect_img(image, imageCols) + + image:clear(Rectangle(0, 0, 2, 1), 4) + expect_img(image, { 4 , 4, + imageCols[3] , imageCols[4] }) + app.undo() + expect_img(image, imageCols) +end + -- Clone do local c = Image(a)