1// Aseprite Document Library
2// Copyright (C) 2020-2022 Igara Studio S.A.
3// Copyright (C) 2001-2018 David Capello
4//
5// This file is released under the terms of the MIT license.
6// Read LICENSE.txt for more information.
7
8#ifndef DOC_PALETTE_H_INCLUDED
9#define DOC_PALETTE_H_INCLUDED
10#pragma once
11
12#include "base/debug.h"
13#include "doc/color.h"
14#include "doc/frame.h"
15#include "doc/object.h"
16#include "doc/palette_gradient_type.h"
17
18#include <vector>
19#include <string>
20
21namespace doc {
22
23 class Remap;
24
25 class Palette : public Object {
26 public:
27 static void initBestfit();
28
29 Palette();
30 Palette(frame_t frame, int ncolors);
31 Palette(const Palette& palette);
32 Palette(const Palette& palette, const Remap& remap);
33 ~Palette();
34
35 Palette& operator=(const Palette& that);
36
37 static Palette* createGrayscale();
38
39 int size() const { return (int)m_colors.size(); }
40 void resize(int ncolors);
41
42 const std::string& filename() const { return m_filename; }
43 const std::string& comment() const { return m_comment; }
44
45 void setFilename(const std::string& filename) {
46 m_filename = filename;
47 }
48
49 void setComment(const std::string& comment) {
50 m_comment = comment;
51 }
52
53 int getModifications() const { return m_modifications; }
54
55 // Return true if the palette has alpha != 255 in some entry
56 bool hasAlpha() const;
57
58 // Return true if the palette has an alpha value between > 0 and < 255.
59 bool hasSemiAlpha() const;
60
61 frame_t frame() const { return m_frame; }
62 void setFrame(frame_t frame);
63
64 color_t entry(int i) const {
65 // TODO At this moment we cannot enable this assert because
66 // there are situations that are not handled quite well yet.
67 // E.g. A palette with lesser colors is loaded
68 //
69 //ASSERT(i < size());
70 ASSERT(i >= 0);
71 if (i >= 0 && i < size())
72 return m_colors[i];
73 else
74 return 0;
75 }
76 color_t getEntry(int i) const {
77 return entry(i);
78 }
79 void setEntry(int i, color_t color);
80 void addEntry(color_t color);
81
82 void copyColorsTo(Palette* dst) const;
83
84 int countDiff(const Palette* other, int* from, int* to) const;
85
86 bool operator==(const Palette& other) const {
87 return (countDiff(&other, nullptr, nullptr) == 0);
88 }
89
90 bool operator!=(const Palette& other) const {
91 return !operator==(other);
92 }
93
94 // Returns true if the palette is completely black.
95 bool isBlack() const;
96 void makeBlack();
97
98 void makeGradient(int from, int to);
99 void makeHueGradient(int from, int to);
100
101 int findExactMatch(int r, int g, int b, int a, int mask_index) const;
102 bool findExactMatch(color_t color) const;
103 int findBestfit(int r, int g, int b, int a, int mask_index) const;
104 int findMaskColor() const;
105
106 void applyRemap(const Remap& remap);
107
108 // TODO add undo/redo support of entry names
109 void setEntryName(const int i, const std::string& name);
110 const std::string& getEntryName(const int i) const;
111
112 private:
113 frame_t m_frame;
114 std::vector<color_t> m_colors;
115 std::vector<std::string> m_names;
116 int m_modifications;
117 std::string m_filename; // If the palette is associated with a file.
118 std::string m_comment; // Some extra comment from the .gpl file (author, website, etc.).
119 };
120
121} // namespace doc
122
123#endif
124