#include #include namespace psemek::gfx { static util::hash_map const named_colors { {"black", {0, 0, 0, 255}}, {"white", {255, 255, 255, 255}}, {"grey", {127, 127, 127, 255}}, {"red", {255, 0, 0, 255}}, {"green", {0, 255, 0, 255}}, {"blue", {0, 0, 255, 255}}, {"cyan", {0, 255, 255, 255}}, {"magenta", {255, 0, 255, 255}}, {"yellow", {255, 255, 0, 255}}, {"dark_grey", {63, 63, 63, 255}}, {"light_grey", {191, 191, 191, 255}}, {"dark_red", {127, 0, 0, 255}}, {"dark_green", {0, 127, 0, 255}}, {"dark_blue", {0, 0, 127, 255}}, {"dark_cyan", {0, 127, 127, 255}}, {"dark_magenta", {127, 0, 127, 255}}, {"dark_yellow", {127, 127, 0, 255}}, {"light_red", {255, 127, 127, 255}}, {"light_green", {127, 255, 127, 255}}, {"light_blue", {127, 127, 255, 255}}, {"light_cyan", {127, 255, 255, 255}}, {"light_magenta", {255, 127, 255, 255}}, {"light_yellow", {255, 255, 127, 255}}, }; static bool all_hex(std::string_view const & text) { return std::all_of(text.begin(), text.end(), [](char c){ return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); }); } static std::uint8_t from_hex(char c) { if ('0' <= c && c <= '9') return c - '0'; if ('a' <= c && c <= 'f') return 10 + (c - 'a'); if ('A' <= c && c <= 'F') return 10 + (c - 'A'); return 0; } static std::uint8_t from_hex(char c1, char c0) { return (from_hex(c1) * 16) | from_hex(c0); } std::optional parse_color(std::string_view const & text) { if (auto it = named_colors.find(text); it != named_colors.end()) return it->second; if (all_hex(text)) { if (text.size() == 3) { return color_rgba{ 17 * from_hex(text[0]), 17 * from_hex(text[1]), 17 * from_hex(text[2]), 255 }; } else if (text.size() == 4) { return color_rgba{ 17 * from_hex(text[0]), 17 * from_hex(text[1]), 17 * from_hex(text[2]), 17 * from_hex(text[3]), }; } else if (text.size() == 6) { return color_rgba{ from_hex(text[0], text[1]), from_hex(text[2], text[3]), from_hex(text[4], text[5]), 255 }; } else if (text.size() == 8) { return color_rgba{ from_hex(text[0], text[1]), from_hex(text[2], text[3]), from_hex(text[4], text[5]), from_hex(text[6], text[7]), }; } } return std::nullopt; } }