header_utils
Loading...
Searching...
No Matches
colors.h
1
4
5#pragma once
6
7#include <charconv>
8#include <string_view>
9#include <glm/common.hpp>
10#include <glm/fwd.hpp>
11//#include <glm/ext/vector_float4.hpp>
12#include "named.h"
13#include "constexpr_math.h"
14
15namespace ghassanpl
16{
19
21
24
25 enum class color_space
26 {
27 linear_rgba,
28 srgb,
29 hsva,
30
31 rgbe,
32 };
33
35 using color_rgba_t = glm::vec4;
37 using color_hsva_t = named<glm::vec4, "color_hsva">;
40
42 using color_rgba_u32_t = named<uint32_t, "color_rgba_u32">;
44 using color_abgr_u32_t = named<uint32_t, "color_abgr_u32">;
45
48 namespace colors
49 {
50#define DEF_COLOR(name, r, g, b) \
51 [[nodiscard]] constexpr color_t get_##name(float alpha) { return color_t{ float(r), float(g), float(b), alpha }; } \
52 constexpr inline color_t name = get_##name(1.0f);
53#define DEF_COLORS(name, r, g, b) \
54 DEF_COLOR(name, r, g, b) \
55 [[nodiscard]] constexpr color_t get_dark_##name(float alpha) { return color_t{ float(r) * 0.5f, float(g) * 0.5f, float(b) * 0.5f, alpha }; } \
56 constexpr inline color_t dark_##name = get_dark_##name(1.0f); \
57 [[nodiscard]] constexpr color_t get_light_##name(float alpha) { return color_t{ r + float(1.0f-r) * 0.5f, g + float(1.0f-g) * 0.5f, b + float(1.0f-b) * 0.5f, alpha }; } \
58 constexpr inline color_t light_##name = get_light_##name(1.0f);
59
60 DEF_COLORS(red, 1, 0, 0)
61 DEF_COLORS(green, 0, 1, 0)
62 DEF_COLORS(blue, 0, 0, 1)
63 DEF_COLORS(yellow, 1, 1, 0)
64 DEF_COLORS(magenta, 1, 0, 1)
65 DEF_COLORS(cyan, 0, 1, 1)
66 DEF_COLORS(gray, 0.5f, 0.5f, 0.5f)
67 DEF_COLORS(grey, 0.5f, 0.5f, 0.5f)
68
69 DEF_COLORS(orange, 1, 0.65f, 0)
70 DEF_COLORS(brown, 0.59f, 0.29f, 0)
71
72 DEF_COLOR(black, 0, 0, 0)
73 DEF_COLOR(white, 1, 1, 1)
74 constexpr inline color_t transparent = get_black(0.0f);
75
76 #undef DEF_COLOR
77 #undef DEF_COLORS
78 }
79
81 [[nodiscard]] constexpr color_t premultiplied(color_t const& color)
82 {
83 return { color.x * color.w, color.y * color.w, color.z * color.w, color.w };
84 }
85
87 [[nodiscard]] constexpr color_t with_alpha(color_t const& color, float a)
88 {
89 return color_t{ color.r, color.g, color.b, a };
90 }
91
93 [[nodiscard]] constexpr color_t saturated(color_t const& color)
94 {
95 return glm::clamp(color_t(color.x, color.y, color.z, color.w), color_t{ 0,0,0,0 }, color_t{ 1,1,1,1 });
96 }
97
99 [[nodiscard]] constexpr color_t lighten(color_t const& color, float coef)
100 {
101 const auto rgb_max = glm::max(color.x, glm::max(color.y, color.z));
102 const auto lighter = color * (1.0f / rgb_max);
103 const auto dif = rgb_max;
104 return saturated(color_t(lighter.x + dif * coef, lighter.y + dif * coef, lighter.z + dif * coef, 1.0f) * rgb_max);
105 }
106
110 [[nodiscard]] constexpr color_t contrast(color_t const& color, float contrast)
111 {
112 const auto t = (1.0f - contrast) * 0.5f;
113 return color_t(color.x*contrast + t, color.y*contrast + t, color.z*contrast + t, color.w);
114 }
115
120 [[nodiscard]] constexpr color_t contrast2(color_t const& color, float contrast)
121 {
122 constexpr double m = 1.0156862745098039215686274509804;
123 const auto t = (m * (contrast + 1.0f)) / (m - contrast);
124 return color_t(t * (color.x - 0.5f) + 0.5f, t * (color.y - 0.5f) + 0.5f, t * (color.z - 0.5f) + 0.5f, color.w);
125 }
126
128 [[nodiscard]] constexpr color_t gamma_correct(color_t const& color, const float gamma)
129 {
130 const auto gamma_correct = 1.0f / gamma;
131 return { cem::pow(color.x, gamma_correct), cem::pow(color.y, gamma_correct), cem::pow(color.z, gamma_correct), color.w };
132 }
133
135 [[nodiscard]] constexpr color_t inverted(color_t const& color)
136 {
137 return color_t(1.0f - color.x, 1.0f - color.y, 1.0f - color.z, color.w);
138 }
139
141 [[nodiscard]] constexpr color_t contrasting(color_t const& color)
142 {
143 const float gamma = 2.2f;
144 const float L = 0.2126f * cem::pow(color.r, gamma) + 0.7152f * cem::pow(color.g, gamma) + 0.0722f * cem::pow(color.b, gamma);
145 return (L > cem::pow(0.5f, gamma)) ? colors::black : colors::white;
146 }
147
149 [[nodiscard]] constexpr float luminance(color_t const& color)
150 {
151 return color.x * 0.3f + color.y * 0.59f + color.z * 0.11f;
152 }
153
155 [[nodiscard]] constexpr color_t desaturated(color_t const& color, float desaturation)
156 {
157 const auto l = luminance(color);
158 return glm::mix(color, color_t{l, l, l, color.w}, desaturation);
159 }
160
161 namespace detail
162 {
163 constexpr float b2f(uint32_t byte) { return (byte & 0xFF) / 255.0f; }
164 constexpr uint32_t f2b(float f) { return uint8_t(0.5f + f * 255.0f); }
165 constexpr uint32_t f2u4(float b1, float b2, float b3, float b4) { return (f2b(b1) << 24) | (f2b(b2) << 16) | (f2b(b3) << 8) | f2b(b4); }
166 constexpr uint32_t f2u4(float b1, float b2, float b3) { return (f2b(b1) << 16) | (f2b(b2) << 8) | f2b(b3); }
167
169 template <typename T> constexpr auto min(const T& x, const T& y, const T& z) { return glm::min(glm::min(x, y), z); }
170 template <typename T> constexpr auto max(const T& x, const T& y, const T& z) { return glm::max(glm::max(x, y), z); }
171 }
172
174 [[nodiscard]] constexpr color_t from_u32_rgb(uint32_t rgb) { return color_t(detail::b2f(rgb >> 16), detail::b2f(rgb >> 8), detail::b2f(rgb), 1.0f); }
176 [[nodiscard]] constexpr color_t from_u32_bgr(uint32_t rgb) { return color_t(detail::b2f(rgb), detail::b2f(rgb >> 8), detail::b2f(rgb >> 16), 1.0f); }
178 [[nodiscard]] constexpr color_t from_u32_rgba(uint32_t rgb) { return color_t(detail::b2f(rgb >> 24), detail::b2f(rgb >> 16), detail::b2f(rgb >> 8), detail::b2f(rgb)); }
180 [[nodiscard]] constexpr color_t from_u32_bgra(uint32_t rgb) { return color_t(detail::b2f(rgb >> 8), detail::b2f(rgb >> 16), detail::b2f(rgb >> 24), detail::b2f(rgb)); }
182 [[nodiscard]] constexpr color_t from_u32_argb(uint32_t rgb) { return color_t(detail::b2f(rgb >> 16), detail::b2f(rgb >> 8), detail::b2f(rgb), detail::b2f(rgb >> 24)); }
184 [[nodiscard]] constexpr color_t from_u32_abgr(uint32_t rgb) { return color_t(detail::b2f(rgb), detail::b2f(rgb >> 8), detail::b2f(rgb >> 16), detail::b2f(rgb >> 24)); }
185
187 [[nodiscard]] constexpr color_t from_u8_rgb(uint8_t r, uint8_t g, uint8_t b) { return color_t(detail::b2f(r), detail::b2f(g), detail::b2f(b), 1.0f); }
189 [[nodiscard]] constexpr color_t from_u8_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { return color_t(detail::b2f(r), detail::b2f(g), detail::b2f(b), detail::b2f(a)); }
190
192 [[nodiscard]] constexpr uint32_t to_u32_argb(color_t const& rgba) { return detail::f2u4(rgba.w, rgba.x, rgba.y, rgba.z); }
194 [[nodiscard]] constexpr uint32_t to_u32_abgr(color_t const& rgba) { return detail::f2u4(rgba.w, rgba.z, rgba.y, rgba.x); }
196 [[nodiscard]] constexpr uint32_t to_u32_rgba(color_t const& rgba) { return detail::f2u4(rgba.x, rgba.y, rgba.z, rgba.w); }
198 [[nodiscard]] constexpr uint32_t to_u32_bgra(color_t const& rgba) { return detail::f2u4(rgba.z, rgba.y, rgba.x, rgba.w); }
200 [[nodiscard]] constexpr uint32_t to_u32_rgb(color_t const& rgba) { return detail::f2u4(rgba.x, rgba.y, rgba.z); }
202 [[nodiscard]] constexpr uint32_t to_u32_bgr(color_t const& rgba) { return detail::f2u4(rgba.z, rgba.y, rgba.x); }
203
204 template <std::same_as<color_rgba_u32_t> TO>
205 [[nodiscard]] constexpr TO named_cast(color_rgba_t const& from)
206 {
207 return TO{ to_u32_rgba(from) };
208 }
209
210 template <std::same_as<color_abgr_u32_t> TO>
211 [[nodiscard]] constexpr TO named_cast(color_rgba_t const& from)
212 {
213 return TO{ to_u32_abgr(from) };
214 }
215
216 template <typename TO, typename FROM>
217 [[nodiscard]] constexpr TO color_cast(FROM const& from)
218 {
219 return named_cast<TO>(from);
220 }
221
223 [[nodiscard]] constexpr glm::tvec4<uint8_t> to_u8(color_t const& rgba) { return { detail::f2b(rgba.x), detail::f2b(rgba.y), detail::f2b(rgba.z), detail::f2b(rgba.w) }; }
224
226 [[nodiscard]] constexpr color_t to_rgb(color_hsva_t const& hsva)
227 {
228 const auto hue = hsva->r;
229 const auto saturation = hsva->g;
230 const auto value = hsva->b;
231 const auto alpha = hsva->a;
232 const auto i = (int)hue;
233 float fraction = hue - (float)i;
234 if (!(i & 1)) fraction = 1.0f - fraction;
235 const auto m = value * (1.0f - saturation);
236 const auto n = value * (1.0f - saturation * fraction);
237 switch (i)
238 {
239 case 6:
240 case 0: return color_t(value, n, m, alpha);
241 case 1: return color_t(n, value, m, alpha);
242 case 2: return color_t(m, value, n, alpha);
243 case 3: return color_t(m, n, value, alpha);
244 case 4: return color_t(n, m, value, alpha);
245 case 5: return color_t(value, m, n, alpha);
246 default: return color_t(value, value, value, alpha);
247 }
248 }
249
251 [[nodiscard]] constexpr color_hsva_t to_hsv(color_t const& rgba)
252 {
253 const auto min = detail::min(rgba.x, rgba.y, rgba.z);
254 const auto max = detail::max(rgba.x, rgba.y, rgba.z);
255 const auto delta = max - min;
256
257 float h = 0;
258
259 if (delta != 0)
260 {
261 if (rgba.x == max)
262 h = fmod((rgba.y - rgba.z) / delta, 6.0f);
263 else if (rgba.y == max)
264 h = 2 + (rgba.z - rgba.x) / delta;
265 else
266 h = 4 + (rgba.x - rgba.y) / delta;
267 }
268
269 return color_hsva_t{
270 h,
271 (max != 0) ? (delta / max) : 0,
272 max,
273 rgba.w
274 };
275 }
276
278 [[nodiscard]] constexpr color_rgba_t from_html(const char* str, size_t n)
279 {
280 if (n == 0)
281 throw n;
282 if (str[0] == '#')
283 {
284 str++;
285 n--;
286 }
287 uint8_t r{};
288 uint8_t g{};
289 uint8_t b{};
290 uint8_t a = 255;
291 switch (n)
292 {
293 case 4:
294 std::from_chars(str + 3, str + 4, a, 16); a = a << 4 | a;
295 [[fallthrough]];
296 case 3:
297 std::from_chars(str + 0, str + 1, r, 16); r = r << 4 | r;
298 std::from_chars(str + 1, str + 2, g, 16); g = g << 4 | g;
299 std::from_chars(str + 2, str + 3, b, 16); b = b << 4 | b;
300 break;
301 case 8:
302 std::from_chars(str + 6, str + 8, a, 16);
303 [[fallthrough]];
304 case 6:
305 std::from_chars(str + 0, str + 2, r, 16);
306 std::from_chars(str + 2, str + 4, g, 16);
307 std::from_chars(str + 4, str + 6, b, 16);
308 break;
309 default: throw "invalid number of characters";
310 }
311 return { r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f };
312 }
313
315 [[nodiscard]] consteval color_rgba_t operator ""_rgb(const char* str, size_t n)
316 {
317 return from_html(str, n);
318 }
319
321 [[nodiscard]] constexpr color_rgba_t from_html(std::string_view html)
322 {
323 return from_html(html.data(), html.size());
324 }
325
327
328#if 0
329
330 float GetDotProduct() const {
331 return R*R + G*G + B*B;
332 }
333 float GetFullDotProduct() const {
334 return R*R + G*G + B*B + A*A;
335 }
336
337 const Color* FindClosestColor(ArrayView<Color> palette) const {
338 return std::min_element(palette.begin(), palette.end(), [this](const Color& a, const Color& b) {
339 const auto diff_a = a - *this;
340 const auto diff_b = b - *this;
341 return diff_a.GetDotProduct() < diff_b.GetDotProduct();
342 });
343 }
344
345 const Color* FindClosestFullColor(ArrayView<Color> palette) const {
346 return std::min_element(palette.begin(), palette.end(), [this](const Color& a, const Color& b) {
347 const auto diff_a = a.FullDifference(*this);
348 const auto diff_b = b.FullDifference(*this);
349 return diff_a.GetFullDotProduct() < diff_b.GetFullDotProduct();
350 });
351 }
352
353
354 enum class GrayscaleType
355 {
356 Lightness,
357 Average,
358 Luminosity
359 };
360
361 template <GrayscaleType TYPE = GrayscaleType::Luminosity>
362 Color Grayscale() const {
363 switch (TYPE)
364 {
365 case GrayscaleType::Lightness: return Color((Max3(R, G, B) + Min3(R, G, B))*0.5, A);
366 case GrayscaleType::Average: return Color((R+G+B)/3.0, A);
367 default:
368 case GrayscaleType::Luminosity: return Color(R*0.21 + G*0.72 + B*0.07, A);
369 }
370 }
371
372 Color BlendedOver(const Color& other) const {
373 const auto oma = 1.0f - A;
374 return *this * A + other * oma;
375 }
376
377 template <typename FUNC>
378 Color BlendWithAlpha(const Color& other, FUNC func) const {
379 return Lerp(func(*this, other), other, A);
380 }
381 /*
382 static Color Multiply(const Color& c1, const Color& c2 ) { return Color(c1.x*c2.x, c1.y*c2.y, c1.z*c2.z); }
383 static Color Screen(const Color& c1, const Color& c2) { return Multiply(c1.Inverted(), c2.Inverted()).Inverted(); }
384 static Color Overlay(const Color& c1, const Color& c2) {
385 return Color(
386 c2.x < 0.5f ? c1.x*c2.x * 2 : (1 - 2 * (1 - c2.x)*(1 - c1.x)),
387 c2.y < 0.5f ? c1.y*c2.y * 2 : (1 - 2 * (1 - c2.y)*(1 - c1.y)),
388 c2.z < 0.5f ? c1.z*c2.z * 2 : (1 - 2 * (1 - c2.z)*(1 - c1.z)));
389 }
390 static Color HardLight(const Color& c2, const Color& c1) {
391 return Color(
392 c2.x < 0.5f ? c1.x*c2.x * 2 : (1 - 2 * (1 - c2.x)*(1 - c1.x)),
393 c2.y < 0.5f ? c1.y*c2.y * 2 : (1 - 2 * (1 - c2.y)*(1 - c1.y)),
394 c2.z < 0.5f ? c1.z*c2.z * 2 : (1 - 2 * (1 - c2.z)*(1 - c1.z)));
395 }
396 static Color Overlay(const Color& c1, const Color& c2) {
397 return Multiply((2 * c2).Inverted(), Multiply(c1, c1)) + 2 * Multiply(c1, c2); /// pegtop!
398 }
399 */
400 /*
401 #define ChannelBlend_Normal(A,B) ((uint8)(A))
402 #define ChannelBlend_Lighten(A,B) ((uint8)((B > A) ? B:A))
403 #define ChannelBlend_Darken(A,B) ((uint8)((B > A) ? A:B))
404 #define ChannelBlend_Multiply(A,B) ((uint8)((A * B) / 255))
405 #define ChannelBlend_Average(A,B) ((uint8)((A + B) / 2))
406 #define ChannelBlend_Add(A,B) ((uint8)(min(255, (A + B))))
407 #define ChannelBlend_Subtract(A,B) ((uint8)((A + B < 255) ? 0:(A + B - 255)))
408 #define ChannelBlend_Difference(A,B) ((uint8)(abs(A - B)))
409 #define ChannelBlend_Negation(A,B) ((uint8)(255 - abs(255 - A - B)))
410 #define ChannelBlend_Screen(A,B) ((uint8)(255 - (((255 - A) * (255 - B)) >> 8)))
411 #define ChannelBlend_Exclusion(A,B) ((uint8)(A + B - 2 * A * B / 255))
412 #define ChannelBlend_Overlay(A,B) ((uint8)((B < 128) ? (2 * A * B / 255):(255 - 2 * (255 - A) * (255 - B) / 255)))
413 #define ChannelBlend_SoftLight(A,B) ((uint8)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255))))
414 #define ChannelBlend_HardLight(A,B) (ChannelBlend_Overlay(B,A))
415 #define ChannelBlend_ColorDodge(A,B) ((uint8)((B == 255) ? B:min(255, ((A << 8 ) / (255 - B)))))
416 #define ChannelBlend_ColorBurn(A,B) ((uint8)((B == 0) ? B:max(0, (255 - ((255 - A) << 8 ) / B))))
417 #define ChannelBlend_LinearDodge(A,B)(ChannelBlend_Add(A,B))
418 #define ChannelBlend_LinearBurn(A,B) (ChannelBlend_Subtract(A,B))
419 #define ChannelBlend_LinearLight(A,B)((uint8)(B < 128)?ChannelBlend_LinearBurn(A,(2 * B)):ChannelBlend_LinearDodge(A,(2 * (B - 128))))
420 #define ChannelBlend_VividLight(A,B) ((uint8)(B < 128)?ChannelBlend_ColorBurn(A,(2 * B)):ChannelBlend_ColorDodge(A,(2 * (B - 128))))
421 #define ChannelBlend_PinLight(A,B) ((uint8)(B < 128)?ChannelBlend_Darken(A,(2 * B)):ChannelBlend_Lighten(A,(2 * (B - 128))))
422 #define ChannelBlend_HardMix(A,B) ((uint8)((ChannelBlend_VividLight(A,B) < 128) ? 0:255))
423 #define ChannelBlend_Reflect(A,B) ((uint8)((B == 255) ? B:min(255, (A * A / (255 - B)))))
424 #define ChannelBlend_Glow(A,B) (ChannelBlend_Reflect(B,A))
425 #define ChannelBlend_Phoenix(A,B) ((uint8)(min(A,B) - max(A,B) + 255))
426 #define ChannelBlend_Alpha(A,B,O) ((uint8)(O * A + (1 - O) * B))
427 #define ChannelBlend_AlphaF(A,B,F,O) (ChannelBlend_Alpha(F(A,B),A,O))
428 */
429 //Color BlendMultiply(const Color& other) const { return BlendWithAlpha(other, colors::Multiply); }
430
431 static Color FromHTML(StringView str)
432 {
433 str.Consume('#');
434 if (str.size() == 6)
435 {
436 uint32_t hex = StringToUnsignedLong(str, nullptr, 16);
437 return colors::FromRGBInt(hex);
438 }
439 else if (str.size() == 8)
440 {
441 uint32_t hex = StringToUnsignedLong(str, nullptr, 16);
442 return colors::FromRGBAInt(hex);
443 }
444 else if (str.size() == 3)
445 {
446 uint32_t hex = StringToUnsignedLong(str, nullptr, 16);
447 hex = ((hex << 12) & 0xF00000) | ((hex << 8) & 0xF000) | ((hex << 4) & 0xF0);
448 hex = hex | (hex >> 4);
449 return colors::FromRGBInt(hex);
450 }
451 else return Color();
452 }
453
455
456 uint8_t GetR8() const { return uint8_t(R*255.0f); }
457 uint8_t GetG8() const { return uint8_t(G*255.0f); }
458 uint8_t GetB8() const { return uint8_t(B*255.0f); }
459 uint8_t GetA8() const { return uint8_t(A*255.0f); }
460
461#endif
462
464}
constexpr auto to_u8(FROM byte) noexcept
Bit-casts the given bytelike to a uint8_t.
Definition bytes.h:80
constexpr float luminance(color_t const &color)
Get brightness of color.
Definition colors.h:149
constexpr uint32_t to_u32_bgra(color_t const &rgba)
Creates an 8bpp BGRA integer from a color.
Definition colors.h:198
color_space
Implementation note: These functions use the .xyzw members instead of the .rgba members because acces...
Definition colors.h:26
constexpr uint32_t to_u32_rgb(color_t const &rgba)
Creates a 32 bitbpp RGB integer from a color, with the most significant 8 bits set to 0.
Definition colors.h:200
constexpr color_t premultiplied(color_t const &color)
Returns the color multiplied by its own alpha.
Definition colors.h:81
named< uint32_t, "color_abgr_u32"> color_abgr_u32_t
Represent a packed ABGR color with 8 bits per pixel.
Definition colors.h:44
constexpr color_t from_u32_rgba(uint32_t rgb)
Gets a color from an RGBA 8bpp integer, with R being most significant.
Definition colors.h:178
constexpr color_t from_u32_bgr(uint32_t rgb)
Gets a color from an BGR 8bpp integer, with R being least significant.
Definition colors.h:176
constexpr color_t lighten(color_t const &color, float coef)
Returns a color lightened by a coefficient.
Definition colors.h:99
constexpr color_t saturated(color_t const &color)
Returns a color with all elements clamped between 0 and 1.
Definition colors.h:93
constexpr color_t to_rgb(color_hsva_t const &hsva)
Converts a HSVA color to RGBA space.
Definition colors.h:226
constexpr uint32_t to_u32_rgba(color_t const &rgba)
Creates an 8bpp RGBA integer from a color.
Definition colors.h:196
constexpr uint32_t to_u32_abgr(color_t const &rgba)
Creates an 8bpp ABGR integer from a color.
Definition colors.h:194
named< uint32_t, "color_rgba_u32"> color_rgba_u32_t
Represent a packed RGBA color with 8 bits per pixel.
Definition colors.h:42
constexpr color_t contrast(color_t const &color, float contrast)
Returns a color with its contrast changed.
Definition colors.h:110
constexpr color_t contrast2(color_t const &color, float contrast)
Returns a color with its contrast changed This uses a differen algorithm and contrast value than cont...
Definition colors.h:120
constexpr color_t from_u32_abgr(uint32_t rgb)
Gets a color from an ABGR 8bpp integer, with A being most significant, and R being least significant.
Definition colors.h:184
constexpr color_t from_u32_argb(uint32_t rgb)
Gets a color from an ARGB 8bpp integer, with A being most significant, and B being least significant.
Definition colors.h:182
constexpr color_rgba_t from_html(const char *str, size_t n)
Converts a HTML color string (like #FBA or fafafa) to an RGBA color.
Definition colors.h:278
constexpr color_t gamma_correct(color_t const &color, const float gamma)
Returns a gamma corrected color.
Definition colors.h:128
glm::vec4 color_rgba_t
Represents a color in RGBA color space, with 0.0-1.0 float elements.
Definition colors.h:35
color_rgba_t color_t
Default color_t type is RGBA.
Definition colors.h:39
constexpr color_t contrasting(color_t const &color)
Returns a color that's a good contrasting color for the original.
Definition colors.h:141
constexpr color_hsva_t to_hsv(color_t const &rgba)
Converts an RGBA color to HSVA space.
Definition colors.h:251
constexpr color_t inverted(color_t const &color)
Returns an inverted color, i.e. with (1.0-x) on all of its elements, excluding its alpha.
Definition colors.h:135
constexpr uint32_t to_u32_argb(color_t const &rgba)
Creates an 8bpp ARGB integer from a color.
Definition colors.h:192
constexpr color_t desaturated(color_t const &color, float desaturation)
Returns a color sapped of desaturation percent (0-1) of its saturation.
Definition colors.h:155
named< glm::vec4, "color_hsva"> color_hsva_t
Represents a color in HSVA color space, with H=0.0-6.0, S=0.0-1.0, V=0.0-1.0, A=0....
Definition colors.h:37
constexpr color_t from_u32_rgb(uint32_t rgb)
Gets a color from an RGB 8bpp integer, with R being most significant.
Definition colors.h:174
constexpr color_t from_u32_bgra(uint32_t rgb)
Gets a color from an BGRA 8bpp integer, with A being least significant, and B being most significant.
Definition colors.h:180
constexpr uint32_t to_u32_bgr(color_t const &rgba)
Creates a 32 bitbpp BGR integer from a color, with the most significant 8 bits set to 0.
Definition colors.h:202
The below code is based on Sun's libm library code, which is licensed under the following license:
Contains the basic colors as variables and functions.
Definition colors.h:49
Primary namespace for everything in this library.
Definition align+rec2.h:10
Used to create a strong typedef of T.
Definition named.h:133