Add color from text parsing

This commit is contained in:
Nikita Lisitsa 2022-05-21 21:44:38 +03:00
parent 12733cf239
commit 7b99158b4d
2 changed files with 114 additions and 0 deletions

View file

@ -5,6 +5,8 @@
#include <psemek/geom/math.hpp>
#include <cstdint>
#include <string_view>
#include <optional>
namespace psemek::gfx
{
@ -205,4 +207,6 @@ namespace psemek::gfx
return generic_color{dark(c.c, darkness)};
}
std::optional<color_rgba> parse_color(std::string_view const & text);
}

110
libs/gfx/source/color.cpp Normal file
View file

@ -0,0 +1,110 @@
#include <psemek/gfx/color.hpp>
#include <unordered_map>
namespace psemek::gfx
{
static std::unordered_map<std::string_view, color_rgba> 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<color_rgba> 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;
}
}