mirror of https://github.com/aseprite/aseprite.git
Fix cel.image:clear() cannot be undone (fix #5015)
This commit is contained in:
parent
fdc9b2f000
commit
7f07becd74
|
@ -1,4 +1,5 @@
|
||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2025 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
|
||||||
|
@ -20,7 +21,20 @@ namespace app { namespace cmd {
|
||||||
|
|
||||||
using namespace doc;
|
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)
|
ClearRect::ClearRect(Cel* cel, const gfx::Rect& bounds)
|
||||||
|
{
|
||||||
|
ASSERT(cel);
|
||||||
|
Doc* doc = static_cast<Doc*>(cel->document());
|
||||||
|
initialize(cel, bounds, doc->bgColor(cel->layer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearRect::initialize(Cel* cel, const gfx::Rect& bounds, color_t color)
|
||||||
{
|
{
|
||||||
ASSERT(cel);
|
ASSERT(cel);
|
||||||
|
|
||||||
|
@ -37,9 +51,7 @@ ClearRect::ClearRect(Cel* cel, const gfx::Rect& bounds)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_dstImage.reset(new WithImage(image));
|
m_dstImage.reset(new WithImage(image));
|
||||||
|
m_bgcolor = color;
|
||||||
Doc* doc = static_cast<Doc*>(cel->document());
|
|
||||||
m_bgcolor = doc->bgColor(cel->layer());
|
|
||||||
|
|
||||||
m_copy.reset(crop_image(image, bounds2.x, bounds2.y, bounds2.w, bounds2.h, m_bgcolor));
|
m_copy.reset(crop_image(image, bounds2.x, bounds2.y, bounds2.w, bounds2.h, m_bgcolor));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2025 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
|
||||||
|
@ -26,6 +27,7 @@ using namespace doc;
|
||||||
class ClearRect : public Cmd {
|
class ClearRect : public Cmd {
|
||||||
public:
|
public:
|
||||||
ClearRect(Cel* cel, const gfx::Rect& bounds);
|
ClearRect(Cel* cel, const gfx::Rect& bounds);
|
||||||
|
ClearRect(Cel* cel, const gfx::Rect& bounds, color_t color);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onExecute() override;
|
void onExecute() override;
|
||||||
|
@ -37,6 +39,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void initialize(Cel* cel, const gfx::Rect& bounds, color_t color);
|
||||||
void clear();
|
void clear();
|
||||||
void restore();
|
void restore();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2024 Igara Studio S.A.
|
// Copyright (C) 2018-2025 Igara Studio S.A.
|
||||||
// Copyright (C) 2015-2018 David Capello
|
// Copyright (C) 2015-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "app/cmd/clear_rect.h"
|
||||||
#include "app/cmd/copy_rect.h"
|
#include "app/cmd/copy_rect.h"
|
||||||
#include "app/cmd/copy_region.h"
|
#include "app/cmd/copy_region.h"
|
||||||
#include "app/cmd/flip_image.h"
|
#include "app/cmd/flip_image.h"
|
||||||
|
@ -246,7 +247,15 @@ int Image_clear(lua_State* L)
|
||||||
else
|
else
|
||||||
color = convert_args_into_pixel_color(L, i, img->pixelFormat());
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,108 @@ do
|
||||||
1, 2 })
|
1, 2 })
|
||||||
end
|
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
|
-- Clone
|
||||||
do
|
do
|
||||||
local c = Image(a)
|
local c = Image(a)
|
||||||
|
|
Loading…
Reference in New Issue