LibDraw: Parse some more color string formats found on the web

This patch adds the 17 color names from CSS2.1, as well as support for
the "#rgb" shorthand where each component is a hex digit that gets
multiplied by 17.
This commit is contained in:
Andreas Kling 2019-10-06 21:35:56 +02:00
parent 66caa7af2b
commit 122d12e617
Notes: sideshowbarker 2024-07-19 11:46:23 +09:00
3 changed files with 53 additions and 13 deletions

View file

@ -3,22 +3,22 @@
<title>Selector test</title>
<style>
#foo #bar #baz {
background-color: #00ff00;
background-color: lime;
}
.abc .def div {
background-color: #ffffff;
background-color: white;
border-style: solid;
border-width: 1;
border-color: #00ff00;
border-color: lime;
}
div > .boo > .bee {
background-color: #000000;
color: #ff00ff;
background-color: black;
color: magenta;
}
#gen_sib ~ div,
#adj_sib + div {
background-color: #0000ff;
color: #ffffff;
background-color: blue;
color: white;
}
</style>
</head>

View file

@ -3,11 +3,11 @@
<title>Welcome!</title>
<style type="text/css">
body {
background-color: #ffffff;
color: #000000;
background-color: #fff;
color: #000;
}
h1 {
color: #800000;
color: #800;
}
</style>
</head>

View file

@ -87,10 +87,38 @@ Optional<Color> Color::from_string(const StringView& string)
if (string.is_empty())
return {};
if (string[0] != '#')
return {};
struct ColorAndWebName {
RGBA32 color;
const char* name;
};
if (string.length() != 7 && string.length() != 9)
const ColorAndWebName web_colors[] = {
{ 0x800000, "maroon", },
{ 0xff0000, "red", },
{ 0xffa500, "orange" },
{ 0xffff00, "yellow" },
{ 0x808000, "olive" },
{ 0x800080, "purple" },
{ 0xff00ff, "fuchsia" },
{ 0xffffff, "white" },
{ 0x00ff00, "lime" },
{ 0x008000, "green" },
{ 0x000080, "navy" },
{ 0x0000ff, "blue" },
{ 0x00ffff, "aqua" },
{ 0x008080, "teal" },
{ 0x000000, "black" },
{ 0xc0c0c0, "silver" },
{ 0x808080, "gray" },
{ 0x000000, nullptr }
};
for (size_t i = 0; web_colors[i].name; ++i) {
if (string == web_colors[i].name)
return Color::from_rgb(web_colors[i].color);
}
if (string[0] != '#')
return {};
auto hex_nibble_to_u8 = [](char nibble) -> Optional<u8> {
@ -101,6 +129,18 @@ Optional<Color> Color::from_string(const StringView& string)
return 10 + (tolower(nibble) - 'a');
};
if (string.length() == 4) {
Optional<u8> r = hex_nibble_to_u8(string[1]);
Optional<u8> g = hex_nibble_to_u8(string[2]);
Optional<u8> b = hex_nibble_to_u8(string[3]);
if (!r.has_value() || !g.has_value() || !b.has_value())
return {};
return Color(r.value() * 17, g.value() * 17, b.value() * 17);
}
if (string.length() != 7 && string.length() != 9)
return {};
auto to_hex = [&](char c1, char c2) -> Optional<u8> {
auto nib1 = hex_nibble_to_u8(c1);
auto nib2 = hex_nibble_to_u8(c2);