| 29 | } |
| 30 | |
| 31 | Colour Colour::FromHex(const UString &hexcode) |
| 32 | { |
| 33 | UString hexcode_lower = to_lower(hexcode); |
| 34 | if (hexcode_lower.empty()) |
| 35 | { |
| 36 | return {0, 0, 0}; |
| 37 | } |
| 38 | // invalid initial character |
| 39 | else if (*hexcode_lower.begin() != '#') |
| 40 | { |
| 41 | return {0, 0, 0}; |
| 42 | } |
| 43 | // invalid characters |
| 44 | else if (!std::all_of(++hexcode_lower.begin(), hexcode_lower.end(), isxdigit)) |
| 45 | { |
| 46 | return {0, 0, 0}; |
| 47 | } |
| 48 | std::array<int, 6> digits; |
| 49 | std::transform(++hexcode_lower.begin(), hexcode_lower.end(), digits.begin(), |
| 50 | [](int cp) { return '0' <= cp && cp <= '9' ? cp - '0' : cp - 'a' + 10; }); |
| 51 | if (hexcode_lower.length() == 4) |
| 52 | { |
| 53 | return {static_cast<uint8_t>(digits[0] * 0x11U), static_cast<uint8_t>(digits[1] * 0x11U), |
| 54 | static_cast<uint8_t>(digits[2] * 0x11U)}; |
| 55 | } |
| 56 | else if (hexcode_lower.length() == 7) |
| 57 | { |
| 58 | return {static_cast<uint8_t>(digits[0] * 0x10U + digits[1]), |
| 59 | static_cast<uint8_t>(digits[2] * 0x10U + digits[3]), |
| 60 | static_cast<uint8_t>(digits[4] * 0x10U + digits[5])}; |
| 61 | } |
| 62 | else |
| 63 | { |
| 64 | return {0, 0, 0}; |
| 65 | } |
| 66 | } |
| 67 | } // namespace OpenApoc |