1 | // Aseprite |
---|---|
2 | // Copyright (C) 2019-2021 Igara Studio S.A. |
3 | // Copyright (C) 2001-2015 David Capello |
4 | // |
5 | // This program is distributed under the terms of |
6 | // the End-User License Agreement for Aseprite. |
7 | |
8 | #ifdef HAVE_CONFIG_H |
9 | #include "config.h" |
10 | #endif |
11 | |
12 | #include "app/cmd/set_palette.h" |
13 | |
14 | #include "app/doc.h" |
15 | #include "base/serialization.h" |
16 | #include "doc/palette.h" |
17 | #include "doc/sprite.h" |
18 | |
19 | namespace app { |
20 | namespace cmd { |
21 | |
22 | using namespace doc; |
23 | |
24 | SetPalette::SetPalette(Sprite* sprite, frame_t frame, const Palette* newPalette) |
25 | : WithSprite(sprite) |
26 | , m_frame(frame) |
27 | { |
28 | const Palette* curPalette = sprite->palette(frame); |
29 | |
30 | m_oldNColors = curPalette->size(); |
31 | m_newNColors = newPalette->size(); |
32 | |
33 | // Check differences between current sprite palette and the new one |
34 | m_from = m_to = -1; |
35 | int diffs = curPalette->countDiff(newPalette, &m_from, &m_to); |
36 | (void)diffs; |
37 | ASSERT(diffs > 0); |
38 | |
39 | if (m_from >= 0 && m_to >= m_from) { |
40 | int oldColors = std::min(m_to+1, m_oldNColors)-m_from; |
41 | if (oldColors > 0) |
42 | m_oldColors.resize(oldColors); |
43 | |
44 | int newColors = std::min(m_to+1, m_newNColors)-m_from; |
45 | if (newColors > 0) |
46 | m_newColors.resize(newColors); |
47 | |
48 | for (size_t i=0; i<size_t(m_to-m_from+1); ++i) { |
49 | if (i < m_oldColors.size()) |
50 | m_oldColors[i] = curPalette->getEntry(m_from+i); |
51 | |
52 | if (i < m_newColors.size()) |
53 | m_newColors[i] = newPalette->getEntry(m_from+i); |
54 | } |
55 | } |
56 | |
57 | if (sprite->pixelFormat() == IMAGE_INDEXED) { |
58 | m_oldTransparentIndex = sprite->transparentColor(); |
59 | if (m_oldTransparentIndex >= newPalette->size()) |
60 | m_newTransparentIndex = newPalette->size() - 1; |
61 | else |
62 | m_newTransparentIndex = m_oldTransparentIndex; |
63 | } |
64 | else { |
65 | ASSERT(sprite->transparentColor() == 0); |
66 | m_oldTransparentIndex = 0; |
67 | m_newTransparentIndex = 0; |
68 | } |
69 | } |
70 | |
71 | void SetPalette::onExecute() |
72 | { |
73 | Sprite* sprite = this->sprite(); |
74 | Palette* palette = sprite->palette(m_frame); |
75 | palette->resize(m_newNColors); |
76 | |
77 | for (size_t i=0; i<m_newColors.size(); ++i) |
78 | palette->setEntry(m_from+i, m_newColors[i]); |
79 | |
80 | if (m_newTransparentIndex != m_oldTransparentIndex) |
81 | sprite->setTransparentColor(m_newTransparentIndex); |
82 | |
83 | palette->incrementVersion(); |
84 | } |
85 | |
86 | void SetPalette::onUndo() |
87 | { |
88 | Sprite* sprite = this->sprite(); |
89 | Palette* palette = sprite->palette(m_frame); |
90 | palette->resize(m_oldNColors); |
91 | |
92 | for (size_t i=0; i<m_oldColors.size(); ++i) |
93 | palette->setEntry(m_from+i, m_oldColors[i]); |
94 | |
95 | if (m_newTransparentIndex != m_oldTransparentIndex) |
96 | sprite->setTransparentColor(m_oldTransparentIndex); |
97 | |
98 | palette->incrementVersion(); |
99 | } |
100 | |
101 | void SetPalette::onFireNotifications() |
102 | { |
103 | doc::Sprite* sprite = this->sprite(); |
104 | Doc* doc = static_cast<Doc*>(sprite->document()); |
105 | doc->notifyPaletteChanged(); |
106 | } |
107 | |
108 | } // namespace cmd |
109 | } // namespace app |
110 |