Line data Source code
1 : /**
2 : Copyright (c) 2008-2010 Ricardo Quesada
3 : Copyright (c) 2010-2012 cocos2d-x.org
4 : Copyright (c) 2011 Zynga Inc.
5 : Copyright (c) 2013-2015 Chukong Technologies Inc.
6 : Copyright (c) 2016-2022 Roman Katuntsev <sbkarr@stappler.org>
7 : Copyright (c) 2023-2024 Stappler LLC <admin@stappler.dev>
8 :
9 : Permission is hereby granted, free of charge, to any person obtaining a copy
10 : of this software and associated documentation files (the "Software"), to deal
11 : in the Software without restriction, including without limitation the rights
12 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 : copies of the Software, and to permit persons to whom the Software is
14 : furnished to do so, subject to the following conditions:
15 :
16 : The above copyright notice and this permission notice shall be included in
17 : all copies or substantial portions of the Software.
18 :
19 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 : THE SOFTWARE.
26 : **/
27 :
28 : #ifndef CORE_GEOM_SPCOLOR_H_
29 : #define CORE_GEOM_SPCOLOR_H_
30 :
31 : #include "SPCommon.h"
32 : #include "SPVec4.h"
33 :
34 : namespace STAPPLER_VERSIONIZED stappler::geom {
35 :
36 : #define LAYOUT_COLOR_SPEC_BASE(Name) \
37 : static Color Name ## _50; \
38 : static Color Name ## _100; \
39 : static Color Name ## _200; \
40 : static Color Name ## _300; \
41 : static Color Name ## _400; \
42 : static Color Name ## _500; \
43 : static Color Name ## _600; \
44 : static Color Name ## _700; \
45 : static Color Name ## _800; \
46 : static Color Name ## _900;
47 :
48 : #define LAYOUT_COLOR_SPEC_ACCENT(Name) \
49 : static Color Name ## _A100; \
50 : static Color Name ## _A200; \
51 : static Color Name ## _A400; \
52 : static Color Name ## _A700;
53 :
54 : #define LAYOUT_COLOR_SPEC(Name) \
55 : LAYOUT_COLOR_SPEC_BASE(Name) \
56 : LAYOUT_COLOR_SPEC_ACCENT(Name)
57 :
58 : struct Color3B;
59 : struct Color4B;
60 : struct Color4F;
61 :
62 : enum class ColorMask : uint8_t {
63 : None = 0,
64 : R = 0x01,
65 : G = 0x02,
66 : B = 0x04,
67 : A = 0x08,
68 : Color = 0x07,
69 : All = 0x0F
70 : };
71 :
72 : SP_DEFINE_ENUM_AS_MASK(ColorMask)
73 :
74 : bool readColor(const StringView &str, Color4B &color);
75 : bool readColor(const StringView &str, Color3B &color);
76 :
77 : /*
78 : * Based on cocos2d-x sources
79 : * stappler-cocos2d-x fork use this sources as a replacement of original
80 : */
81 :
82 : /**
83 : * RGB color composed of bytes 3 bytes.
84 : */
85 : struct Color3B {
86 : static Color3B getColorByName(StringView, const Color3B & = Color3B::BLACK);
87 :
88 : constexpr Color3B() : r(0), g(0) , b(0) {}
89 17867 : constexpr Color3B(uint8_t _r, uint8_t _g, uint8_t _b) : r(_r), g(_g), b(_b) { }
90 : constexpr Color3B(uint32_t value) : Color3B((value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF) { }
91 : explicit Color3B(const Color4B& color);
92 : explicit Color3B(const Color4F& color);
93 :
94 : bool operator==(const Color3B& right) const;
95 : bool operator==(const Color4B& right) const;
96 : bool operator==(const Color4F& right) const;
97 : bool operator!=(const Color3B& right) const;
98 : bool operator!=(const Color4B& right) const;
99 : bool operator!=(const Color4F& right) const;
100 :
101 : bool equals(const Color3B& other) {
102 : return (*this == other);
103 : }
104 :
105 : template <typename Interface>
106 : auto name() const -> typename Interface::StringType;
107 :
108 : uint8_t r;
109 : uint8_t g;
110 : uint8_t b;
111 :
112 : static const Color3B WHITE;
113 : static const Color3B BLACK;
114 :
115 : static Color3B progress(const Color3B &a, const Color3B &b, float p);
116 : };
117 :
118 : /**
119 : * RGBA color composed of 4 bytes.
120 : */
121 : struct Color4B {
122 : static const Color4B WHITE;
123 : static const Color4B BLACK;
124 :
125 : static Color4B progress(const Color4B &a, const Color4B &b, float p);
126 : static Color4B getColorByName(StringView, const Color4B & = Color4B::BLACK);
127 :
128 25 : constexpr Color4B() : r(0), g(0), b(0), a(0) {}
129 1122003 : constexpr Color4B(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a) : r(_r), g(_g), b(_b), a(_a) { }
130 18688 : constexpr Color4B(const Color3B& color, uint8_t _a) : r(color.r), g(color.g), b(color.b), a(_a) { }
131 : explicit Color4B(const Color3B& color);
132 : explicit Color4B(const Color4F& color);
133 :
134 : bool operator==(const Color4B& right) const;
135 : bool operator==(const Color3B& right) const;
136 : bool operator==(const Color4F& right) const;
137 : bool operator!=(const Color4B& right) const;
138 : bool operator!=(const Color3B& right) const;
139 : bool operator!=(const Color4F& right) const;
140 :
141 : uint8_t r;
142 : uint8_t g;
143 : uint8_t b;
144 : uint8_t a;
145 :
146 : static Color4B white(uint8_t);
147 : static Color4B black(uint8_t);
148 : };
149 :
150 : /**
151 : * RGBA color composed of 4 floats.
152 : */
153 : struct alignas(16) Color4F {
154 : static const Color4F WHITE;
155 : static const Color4F BLACK;
156 : static const Color4F ZERO;
157 : static const Color4F ONE;
158 :
159 : static Color4F progress(const Color4F &a, const Color4F &b, float p);
160 :
161 1295312 : constexpr Color4F() : r(0.0f), g(0.0f), b(0.0f), a(0.0f) { }
162 1727877 : constexpr Color4F(float _r, float _g, float _b, float _a) : r(_r), g(_g), b(_b), a(_a) { }
163 :
164 3865 : constexpr Color4F(const Color3B& color, uint8_t alpha)
165 3865 : : r(color.r / 255.0f), g(color.g / 255.0f), b(color.b / 255.0f), a(alpha / 255.0f) { }
166 :
167 50 : constexpr explicit Color4F(const Color3B& color)
168 50 : : r(color.r / 255.0f), g(color.g / 255.0f), b(color.b / 255.0f), a(1.0f) { }
169 :
170 1628265 : constexpr explicit Color4F(const Color4B& color)
171 1628265 : : r(color.r / 255.0f), g(color.g / 255.0f), b(color.b / 255.0f), a(color.a / 255.0f) { }
172 :
173 : bool operator==(const Color4F& right) const;
174 : bool operator==(const Color3B& right) const;
175 : bool operator==(const Color4B& right) const;
176 : bool operator!=(const Color4F& right) const;
177 : bool operator!=(const Color3B& right) const;
178 : bool operator!=(const Color4B& right) const;
179 :
180 : bool equals(const Color4F &other) {
181 : return (*this == other);
182 : }
183 :
184 18696975 : constexpr operator Vec4() const { return Vec4(r, g, b, a); }
185 :
186 : Color3B getColor() const;
187 : uint8_t getOpacity() const;
188 :
189 : void setMasked(const Color4F &, ColorMask);
190 : void setUnmasked(const Color4F &, ColorMask);
191 :
192 : float r;
193 : float g;
194 : float b;
195 : float a;
196 : };
197 :
198 : class Color {
199 : public:
200 : LAYOUT_COLOR_SPEC(Red); // 0
201 : LAYOUT_COLOR_SPEC(Pink); // 1
202 : LAYOUT_COLOR_SPEC(Purple); // 2
203 : LAYOUT_COLOR_SPEC(DeepPurple); // 3
204 : LAYOUT_COLOR_SPEC(Indigo); // 4
205 : LAYOUT_COLOR_SPEC(Blue); // 5
206 : LAYOUT_COLOR_SPEC(LightBlue); // 6
207 : LAYOUT_COLOR_SPEC(Cyan); // 7
208 : LAYOUT_COLOR_SPEC(Teal); // 8
209 : LAYOUT_COLOR_SPEC(Green); // 9
210 : LAYOUT_COLOR_SPEC(LightGreen); // 10
211 : LAYOUT_COLOR_SPEC(Lime); // 11
212 : LAYOUT_COLOR_SPEC(Yellow); // 12
213 : LAYOUT_COLOR_SPEC(Amber); // 13
214 : LAYOUT_COLOR_SPEC(Orange); // 14
215 : LAYOUT_COLOR_SPEC(DeepOrange); // 15
216 :
217 : LAYOUT_COLOR_SPEC_BASE(Brown); // 16
218 : LAYOUT_COLOR_SPEC_BASE(Grey); // 17
219 : LAYOUT_COLOR_SPEC_BASE(BlueGrey); // 18
220 :
221 : static Color White;
222 : static Color Black;
223 :
224 : enum class Level : int16_t {
225 : Unknown = -1,
226 : b50 = 0,
227 : b100,
228 : b200,
229 : b300,
230 : b400,
231 : b500,
232 : b600,
233 : b700,
234 : b800,
235 : b900,
236 : a100,
237 : a200,
238 : a400,
239 : a700
240 : };
241 :
242 : enum class Tone : int16_t {
243 : Unknown = -1,
244 : Red = 0,
245 : Pink,
246 : Purple,
247 : DeepPurple,
248 : Indigo,
249 : Blue,
250 : LightBlue,
251 : Cyan,
252 : Teal,
253 : Green,
254 : LightGreen,
255 : Lime,
256 : Yellow,
257 : Amber,
258 : Orange,
259 : DeepOrange,
260 : Brown,
261 : Grey,
262 : BlueGrey,
263 : BlackWhite,
264 : };
265 :
266 330 : inline Color3B asColor3B() const {
267 330 : return Color3B((_value >> 16) & 0xFF, (_value >> 8) & 0xFF, _value & 0xFF);
268 : }
269 :
270 6867 : inline Color4B asColor4B() const {
271 6867 : return Color4B((_value >> 16) & 0xFF, (_value >> 8) & 0xFF, _value & 0xFF, 255);
272 : }
273 :
274 81561 : inline Color4F asColor4F() const {
275 163122 : return Color4F(
276 81561 : float((_value >> 16) & 0xFF) / float(0xFF),
277 81561 : float((_value >> 8) & 0xFF) / float(0xFF),
278 81561 : float(_value & 0xFF) / float(0xFF),
279 81561 : 1.0f);
280 : }
281 :
282 255 : inline operator Color3B () const {
283 255 : return asColor3B();
284 : }
285 6842 : inline operator Color4B () const {
286 6842 : return asColor4B();
287 : }
288 81511 : inline operator Color4F () const {
289 81511 : return asColor4F();
290 : }
291 :
292 : inline bool operator == (const Color &other) const {
293 : return _value == other._value;
294 : }
295 :
296 : inline bool operator != (const Color &other) const {
297 : return _value != other._value;
298 : }
299 :
300 : inline uint8_t r() const { return (_value >> 16) & 0xFF; }
301 : inline uint8_t g() const { return (_value >> 8) & 0xFF; }
302 : inline uint8_t b() const { return _value & 0xFF; }
303 :
304 100 : inline uint32_t value() const { return _value; }
305 25 : inline uint32_t index() const { return _index; }
306 :
307 : Color text() const;
308 :
309 : inline Level level() const { return (_index == maxOf<uint16_t>())?Level::Unknown:((Level)(_index & 0x0F)); }
310 : inline Tone tone() const { return (_index == maxOf<uint16_t>())?Tone::Unknown:((Tone)((_index & 0xFFF0) / 16)); }
311 :
312 : Color previous() const;
313 : Color next() const;
314 :
315 : Color lighter(uint8_t index = 1) const;
316 : Color darker(uint8_t index = 1) const;
317 :
318 : Color medium() const;
319 : Color specific(uint8_t index) const;
320 : Color specific(Level l) const;
321 :
322 : Color(Tone, Level);
323 : Color(uint32_t value);
324 : Color(uint32_t value, int16_t index);
325 : Color(const Color3B &color);
326 : Color(const Color4B &color);
327 :
328 25 : Color() = default;
329 :
330 : Color(const Color &) = default;
331 : Color(Color &&) = default;
332 : Color & operator=(const Color &) = default;
333 : Color & operator=(Color &&) = default;
334 :
335 : template <typename Interface>
336 : auto name() const -> typename Interface::StringType;
337 :
338 : static Color getColorByName(const StringView &, const Color & = Color::Black);
339 : static Color progress(const Color &a, const Color &b, float p);
340 :
341 : private:
342 : static Color getById(uint16_t index);
343 : static uint16_t getColorIndex(uint32_t);
344 :
345 : uint32_t _value = 0;
346 : uint16_t _index = uint16_t(19 * 16 + 1);
347 : };
348 :
349 : std::ostream & operator<<(std::ostream & stream, const Color & obj);
350 : std::ostream & operator<<(std::ostream & stream, const Color3B & obj);
351 : std::ostream & operator<<(std::ostream & stream, const Color4B & obj);
352 : std::ostream & operator<<(std::ostream & stream, const Color4F & obj);
353 :
354 363 : inline Color4F Color4F::progress(const Color4F &a, const Color4F &b, float p) {
355 363 : Color4F dst;
356 363 : simd::store(&dst.r, simd::add(
357 363 : simd::mul(simd::load(&a.r), simd::load(1.0f - p)),
358 363 : simd::mul(simd::load(&b.r), simd::load(p))
359 : ));
360 363 : return dst;
361 : }
362 :
363 25 : inline Color4F operator*(const Color4F &l, const Color4F &r) {
364 25 : Color4F dst;
365 25 : simd::store(&dst.r, simd::mul(simd::load(&l.r), simd::load(&r.r)));
366 25 : return dst;
367 : }
368 :
369 : inline Color4F operator/(const Color4F &l, const Color4F &r) {
370 : Color4F dst;
371 : simd::store(&dst.r, simd::div(simd::load(&l.r), simd::load(&r.r)));
372 : return dst;
373 : }
374 :
375 97727 : inline Color4F operator*(const Color4F &l, float r) {
376 97727 : Color4F dst;
377 97727 : simd::store(&dst.r, simd::mul(simd::load(&l.r), simd::load(r)));
378 97727 : return dst;
379 : }
380 :
381 : inline Color4F operator*(float l, const Color4F &r) {
382 : Color4F dst;
383 : simd::store(&dst.r, simd::mul(simd::load(l), simd::load(&r.r)));
384 : return dst;
385 : }
386 :
387 43222 : inline Color4F operator+(const Color4F &l, const Color4F &r) {
388 43222 : Color4F dst;
389 43222 : simd::store(&dst.r, simd::add(simd::load(&l.r), simd::load(&r.r)));
390 43222 : return dst;
391 : }
392 :
393 : inline Color4F operator-(const Color4F &l, const Color4F &r) {
394 : Color4F dst;
395 : simd::store(&dst.r, simd::sub(simd::load(&l.r), simd::load(&r.r)));
396 : return dst;
397 : }
398 :
399 : inline Color4F operator*(const Color4F &l, const Color4B &r) {
400 : return l * Color4F(r);
401 : }
402 :
403 : inline Color4F operator*(const Color4B &l, const Color4F &r) {
404 : return Color4F(l) * r;
405 : }
406 :
407 : inline Color4F operator/(const Color4F &l, const Color4B &r) {
408 : return l / Color4F(r);
409 : }
410 :
411 : inline Color4F operator/(const Color4B &l, const Color4F &r) {
412 : return Color4F(l) / r;
413 : }
414 :
415 : #ifndef __LCC__
416 :
417 : constexpr const Color3B Color3B::WHITE(255, 255, 255);
418 : constexpr const Color3B Color3B::BLACK(0, 0, 0);
419 :
420 : constexpr const Color4B Color4B::WHITE(255, 255, 255, 255);
421 : constexpr const Color4B Color4B::BLACK(0, 0, 0, 255);
422 :
423 : constexpr const Color4F Color4F::WHITE(1, 1, 1, 1);
424 : constexpr const Color4F Color4F::BLACK(0, 0, 0, 1);
425 : constexpr const Color4F Color4F::ZERO(0, 0, 0, 0);
426 : constexpr const Color4F Color4F::ONE(1, 1, 1, 1);
427 :
428 : #endif
429 :
430 : }
431 :
432 : namespace STAPPLER_VERSIONIZED stappler {
433 :
434 : template <> inline
435 25 : geom::Color progress<geom::Color>(const geom::Color &a, const geom::Color &b, float p) {
436 25 : return geom::Color::progress(a, b, p);
437 : }
438 :
439 : template <> inline
440 25 : geom::Color3B progress<geom::Color3B>(const geom::Color3B &a, const geom::Color3B &b, float p) {
441 25 : return geom::Color3B::progress(a, b, p);
442 : }
443 :
444 : template <> inline
445 25 : geom::Color4B progress<geom::Color4B>(const geom::Color4B &a, const geom::Color4B &b, float p) {
446 25 : return geom::Color4B::progress(a, b, p);
447 : }
448 :
449 : template <> inline
450 363 : geom::Color4F progress<geom::Color4F>(const geom::Color4F &a, const geom::Color4F &b, float p) {
451 363 : return geom::Color4F::progress(a, b, p);
452 : }
453 :
454 : }
455 :
456 : #endif /* CORE_GEOM_SPCOLOR_H_ */
|