colour: add html-style colour parsing
This commit is contained in:
parent
813600e774
commit
30fa4a378d
41
colour.cpp
41
colour.cpp
@ -16,19 +16,56 @@
|
||||
|
||||
#include "./colour.hpp"
|
||||
|
||||
#include "./ascii.hpp"
|
||||
#include "./debug.hpp"
|
||||
#include "./log.hpp"
|
||||
#include "./range.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <map>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
using util::colour;
|
||||
using util::colour3f;
|
||||
using util::colour4f;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <size_t S, typename T>
|
||||
colour<S,T>
|
||||
colour<S,T>::parse_html (const char *fmt)
|
||||
{
|
||||
// ensure the format is the correct length
|
||||
auto len = strlen (fmt);
|
||||
|
||||
switch (len) {
|
||||
case 1 + 2 * S:
|
||||
if (*fmt != '#')
|
||||
throw std::invalid_argument ("missing leading hash");
|
||||
++fmt;
|
||||
break;
|
||||
|
||||
case 2 * S:
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::invalid_argument ("format is the wrong length");
|
||||
}
|
||||
|
||||
// parse the octets
|
||||
util::colour<S,uint8_t> res;
|
||||
for (size_t i = 0; i < res.size (); ++i) {
|
||||
auto a = util::ascii::from_hex (fmt[i*2+0]);
|
||||
auto b = util::ascii::from_hex (fmt[i*2+1]);
|
||||
|
||||
res[i] = (a << 4u) | b;
|
||||
}
|
||||
|
||||
return res.template cast<T> ();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static const std::map<std::string, colour<4,uint8_t>>
|
||||
HTML_COLOURS { {
|
||||
{ "white", { 0xff, 0xff, 0xff, 0xff } },
|
||||
|
19
colour.hpp
19
colour.hpp
@ -34,9 +34,22 @@ namespace util {
|
||||
colour<S,U>
|
||||
cast (void) const;
|
||||
|
||||
static colour from_html (const std::string&);
|
||||
static colour from_x11 (const std::string&);
|
||||
static colour from_string (const std::string&);
|
||||
/// parse colours specified as "#AABBCCDD".
|
||||
///
|
||||
/// * the leading hash is optional.
|
||||
/// * all components must be 2 hex digits.
|
||||
static colour parse_html (const char*);
|
||||
static colour parse_html (const std::string&);
|
||||
|
||||
/// look up the name of a colour from those specified in
|
||||
/// html/x11/etc specifications.
|
||||
static colour from_html (const std::string &name);
|
||||
static colour from_x11 (const std::string &name);
|
||||
|
||||
/// look up all the specifications and returns the colour from one
|
||||
/// that matches. the search order is unspecified, so if you want a
|
||||
/// known colour then try them first yourself.
|
||||
static colour from_string (const std::string &name);
|
||||
};
|
||||
|
||||
// Convenience types
|
||||
|
@ -16,6 +16,47 @@ main (int, char**)
|
||||
tap.expect_eq (u.cast<float> (), f, "cast u8 to float");
|
||||
}
|
||||
|
||||
// Check parsing is working
|
||||
tap.expect_eq (
|
||||
util::colour4u::parse_html ("#11223344"),
|
||||
util::colour4u (0x11, 0x22, 0x33, 0x44),
|
||||
"4-component html parsing with hash"
|
||||
);
|
||||
|
||||
tap.expect_eq (
|
||||
util::colour4u::parse_html ("11223344"),
|
||||
util::colour4u (0x11, 0x22, 0x33, 0x44),
|
||||
"4-component html parsing without hash"
|
||||
);
|
||||
|
||||
tap.expect_eq (
|
||||
util::colour1f::parse_html ("ff"),
|
||||
util::colour1f (1.f),
|
||||
"1-component html parsing"
|
||||
);
|
||||
|
||||
tap.expect_eq (
|
||||
util::colour3u::parse_html ("3399ff"),
|
||||
util::colour3u (0x33, 0x99, 0xff),
|
||||
"3-component html parsing"
|
||||
);
|
||||
|
||||
tap.expect_throw<std::invalid_argument> (
|
||||
[] () { util::colour1f::parse_html ("00112233"); },
|
||||
"1-component parsing with 4-component format"
|
||||
);
|
||||
|
||||
tap.expect_throw<std::invalid_argument> (
|
||||
[] () { util::colour4f::parse_html ("00"); },
|
||||
"4-component parsing with 1-component format"
|
||||
);
|
||||
|
||||
tap.expect_throw<std::invalid_argument> (
|
||||
[] () { util::colour4f::parse_html ("0011223"); },
|
||||
"4-component parsing with one too few digits"
|
||||
);
|
||||
|
||||
|
||||
// Check lookups are working
|
||||
tap.expect_eq (util::colour4f::from_html ("white"), util::colour4f {1}, "HTML lookup");
|
||||
tap.expect_eq ( util::colour4f::from_x11 ("white"), util::colour4f {1}, "X11 lookup");
|
||||
|
Loading…
Reference in New Issue
Block a user