1#include "color.h"
2
3#include "str.h"
4
5template<typename T>
6std::optional<T> color_parse(const char *pStr)
7{
8 if(!str_isallnum_hex(str: pStr))
9 return {};
10
11 const unsigned Num = str_toulong_base(str: pStr, base: 16);
12
13 T Color;
14 switch(str_length(str: pStr))
15 {
16 case 3:
17 Color.x = (((Num >> 8) & 0x0F) + ((Num >> 4) & 0xF0)) / 255.0f;
18 Color.y = (((Num >> 4) & 0x0F) + ((Num >> 0) & 0xF0)) / 255.0f;
19 Color.z = (((Num >> 0) & 0x0F) + ((Num << 4) & 0xF0)) / 255.0f;
20 Color.a = 1.0f;
21 return Color;
22
23 case 4:
24 Color.x = (((Num >> 12) & 0x0F) + ((Num >> 8) & 0xF0)) / 255.0f;
25 Color.y = (((Num >> 8) & 0x0F) + ((Num >> 4) & 0xF0)) / 255.0f;
26 Color.z = (((Num >> 4) & 0x0F) + ((Num >> 0) & 0xF0)) / 255.0f;
27 Color.a = (((Num >> 0) & 0x0F) + ((Num << 4) & 0xF0)) / 255.0f;
28 return Color;
29
30 case 6:
31 Color.x = ((Num >> 16) & 0xFF) / 255.0f;
32 Color.y = ((Num >> 8) & 0xFF) / 255.0f;
33 Color.z = ((Num >> 0) & 0xFF) / 255.0f;
34 Color.a = 1.0f;
35 return Color;
36
37 case 8:
38 Color.x = ((Num >> 24) & 0xFF) / 255.0f;
39 Color.y = ((Num >> 16) & 0xFF) / 255.0f;
40 Color.z = ((Num >> 8) & 0xFF) / 255.0f;
41 Color.a = ((Num >> 0) & 0xFF) / 255.0f;
42 return Color;
43
44 default:
45 return {};
46 }
47}
48
49template std::optional<ColorRGBA> color_parse<ColorRGBA>(const char *);
50