forked from ParadoxGameConverters/commonItems
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Color.h
113 lines (85 loc) · 3.81 KB
/
Color.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#ifndef COLOR_H
#define COLOR_H
// Represents a Paradox - defined color.
//
// Can be directly created in either the RGB or HSV color spaces.
// If alpha is persent we're assuming it's RGBA or HSVA.
//
// Can be imported in :
// * Unspecified with ints(becomes RGB) - "= { 64 128 128 }"
// * Unspecified with three floats(becomes RGB) - "= { 0.5 0.9 0.1 }"
// * Unspecified with four floats(becomes RGBA) - "= { 0.5 0.9 0.1 0.1 }"
// * RGB - "= rgb { 64 128 128 }"
// * Hex - "= hex { 408080 }"
// * HSV - "= hsv { 0.5 0.5 0.5 }"
// * HSVA - "= hsv { 0.5 0.5 0.5 0.1 }"
// * HSV360 - "= hsv360 { 180 50 50 }"
// * Name(requires caching definitions for the named colors in advance) - "= dark_moderate_cyan"
//
// Can be output in :
// * unspecified(rgb) - "= { 64 128 128 }"
// * RGB - "= rgb { 64 128 128 }"
// * RGBA - we don't export RGBA. yet.
// * hex - "= hex { 408080 }"
// * HSV - "= hsv { 0.5 0.5 0.5 }"
// * HSVA - "= hsv { 0.5 0.5 0.5 0.1 }"
// * HSV360 - "= hsv360 { 180 50 50 }"
//
// The individual components can be accessed in both RGB and HSV color spaces, equality and inequality can be checked, the color cache can be reviewed and
// modified, and colors can have a random fluctuation be applied automatically.
#include "Parser.h"
#include <array>
#include <iostream>
namespace commonItems
{
class Color
{
public:
class Factory;
Color() = default;
explicit Color(std::array<int, 3> rgbComponents): rgbComponents(rgbComponents) { deriveHsvFromRgb(); }
explicit Color(std::array<int, 3> rgbComponents, float alpha): rgbComponents(rgbComponents), alpha(alpha) { deriveHsvFromRgb(); }
explicit Color(std::array<float, 3> hsvComponents): hsvComponents(hsvComponents) { deriveRgbFromHsv(); }
explicit Color(std::array<float, 3> hsvComponents, float alpha): hsvComponents(hsvComponents), alpha(alpha) { deriveRgbFromHsv(); }
bool operator==(const Color& rhs) const;
bool operator!=(const Color& rhs) const;
[[nodiscard]] const auto& getRgbComponents() const { return rgbComponents; }
[[nodiscard]] const auto& getHsvComponents() const { return hsvComponents; }
[[nodiscard]] const auto& r() const { return rgbComponents[0]; }
[[nodiscard]] const auto& g() const { return rgbComponents[1]; }
[[nodiscard]] const auto& b() const { return rgbComponents[2]; }
[[nodiscard]] const auto& h() const { return hsvComponents[0]; }
[[nodiscard]] const auto& s() const { return hsvComponents[1]; }
[[nodiscard]] const auto& v() const { return hsvComponents[2]; }
[[nodiscard]] const auto& a() const { return alpha; }
[[nodiscard]] std::string outputRgb() const;
[[nodiscard]] std::string outputHex() const;
[[nodiscard]] std::string outputHsv() const;
[[nodiscard]] std::string outputHsv360() const;
// All three color components will go up or down by the some amount (according to stdDev), and then each is tweaked a
// bit more (with a much smaller standard deviation).
void RandomlyFluctuate(int stdDev);
friend std::ostream& operator<<(std::ostream& out, const Color& color);
private:
void deriveHsvFromRgb();
void deriveRgbFromHsv();
std::array<int, 3> rgbComponents{0, 0, 0};
std::array<float, 3> hsvComponents{0.0F, 0.0F, 0.0F};
std::optional<float> alpha;
};
std::ostream& operator<<(std::ostream& out, const Color& color);
class Color::Factory: parser
{
public:
[[nodiscard]] Color getColor(std::istream& theStream) const;
[[nodiscard]] Color getColor(const std::string& colorName) const;
[[nodiscard]] const auto& getRegisteredColors() const { return namedColors; }
void addNamedColor(const std::string& name, const Color& color);
void addNamedColor(const std::string& name, std::istream& theStream);
void addNamedColorMap(const std::map<std::string, Color>& colorMap);
void clear() { namedColors.clear(); }
private:
std::unordered_map<std::string, Color> namedColors;
};
} // namespace commonItems
#endif // COLOR_H