Restore transparent color correctly after undoing Indexed -> RGB

When we are in Indexed mode we can have a specific index as the
transparent color, if we convert the sprite to RGB, that transparent
color is lost, so we have to save it (in a cmd::SetTransparentColor)
to restore it correctly when we undo the ChangePixelFormatCommand.
This commit is contained in:
David Capello 2024-09-04 15:38:19 -03:00
parent d62d279a34
commit 09bb5cc3d3
2 changed files with 21 additions and 16 deletions

View File

@ -15,6 +15,7 @@
#include "app/cmd/replace_image.h" #include "app/cmd/replace_image.h"
#include "app/cmd/set_cel_opacity.h" #include "app/cmd/set_cel_opacity.h"
#include "app/cmd/set_palette.h" #include "app/cmd/set_palette.h"
#include "app/cmd/set_transparent_color.h"
#include "app/doc.h" #include "app/doc.h"
#include "app/doc_event.h" #include "app/doc_event.h"
#include "doc/cel.h" #include "doc/cel.h"
@ -139,12 +140,18 @@ SetPixelFormat::SetPixelFormat(Sprite* sprite,
} }
// Set all cels opacity to 100% if we are converting to indexed. // Set all cels opacity to 100% if we are converting to indexed.
// TODO remove this
if (newFormat == IMAGE_INDEXED) { if (newFormat == IMAGE_INDEXED) {
// TODO remove this (?)
for (Cel* cel : sprite->uniqueCels()) { for (Cel* cel : sprite->uniqueCels()) {
if (cel->opacity() < 255) if (cel->opacity() < 255)
m_seq.add(new cmd::SetCelOpacity(cel, 255)); m_pre.add(new cmd::SetCelOpacity(cel, 255));
} }
int newMaskIndex = sprite->palette(0)->findMaskColor();
if (newMaskIndex < 0)
newMaskIndex = 0;
if (newMaskIndex != sprite->transparentColor())
m_post.add(new cmd::SetTransparentColor(sprite, newMaskIndex));
} }
// When we are converting to grayscale color mode, we've to destroy // When we are converting to grayscale color mode, we've to destroy
@ -155,30 +162,33 @@ SetPixelFormat::SetPixelFormat(Sprite* sprite,
PalettesList palettes = sprite->getPalettes(); PalettesList palettes = sprite->getPalettes();
for (Palette* pal : palettes) for (Palette* pal : palettes)
if (pal->frame() != 0) if (pal->frame() != 0)
m_seq.add(new cmd::RemovePalette(sprite, pal)); m_pre.add(new cmd::RemovePalette(sprite, pal));
std::unique_ptr<Palette> graypal(Palette::createGrayscale()); std::unique_ptr<Palette> graypal(Palette::createGrayscale());
if (*graypal != *sprite->palette(0)) if (*graypal != *sprite->palette(0))
m_seq.add(new cmd::SetPalette(sprite, 0, graypal.get())); m_pre.add(new cmd::SetPalette(sprite, 0, graypal.get()));
} }
} }
void SetPixelFormat::onExecute() void SetPixelFormat::onExecute()
{ {
m_seq.execute(context()); m_pre.execute(context());
setFormat(m_newFormat); setFormat(m_newFormat);
m_post.execute(context());
} }
void SetPixelFormat::onUndo() void SetPixelFormat::onUndo()
{ {
m_seq.undo(); m_post.undo();
setFormat(m_oldFormat); setFormat(m_oldFormat);
m_pre.undo();
} }
void SetPixelFormat::onRedo() void SetPixelFormat::onRedo()
{ {
m_seq.redo(); m_pre.redo();
setFormat(m_newFormat); setFormat(m_newFormat);
m_post.redo();
} }
void SetPixelFormat::setFormat(PixelFormat format) void SetPixelFormat::setFormat(PixelFormat format)
@ -186,12 +196,6 @@ void SetPixelFormat::setFormat(PixelFormat format)
Sprite* sprite = this->sprite(); Sprite* sprite = this->sprite();
sprite->setPixelFormat(format); sprite->setPixelFormat(format);
if (format == IMAGE_INDEXED) {
int maskIndex = sprite->palette(0)->findMaskColor();
sprite->setTransparentColor(maskIndex == -1 ? 0 : maskIndex);
}
else
sprite->setTransparentColor(0);
sprite->incrementVersion(); sprite->incrementVersion();
// Regenerate extras // Regenerate extras
@ -245,7 +249,7 @@ void SetPixelFormat::convertImage(doc::Sprite* sprite,
toGray, toGray,
delegate)); delegate));
m_seq.add(new cmd::ReplaceImage(sprite, oldImage, newImage)); m_pre.add(new cmd::ReplaceImage(sprite, oldImage, newImage));
} }
} // namespace cmd } // namespace cmd

View File

@ -46,7 +46,7 @@ namespace cmd {
void onUndo() override; void onUndo() override;
void onRedo() override; void onRedo() override;
size_t onMemSize() const override { size_t onMemSize() const override {
return sizeof(*this) + m_seq.memSize(); return sizeof(*this) + m_pre.memSize() + m_post.memSize();
} }
private: private:
@ -63,7 +63,8 @@ namespace cmd {
doc::PixelFormat m_oldFormat; doc::PixelFormat m_oldFormat;
doc::PixelFormat m_newFormat; doc::PixelFormat m_newFormat;
CmdSequence m_seq; CmdSequence m_pre;
CmdSequence m_post;
}; };
} // namespace cmd } // namespace cmd