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 "./colour.hpp"
|
||||||
|
|
||||||
|
#include "./ascii.hpp"
|
||||||
#include "./debug.hpp"
|
#include "./debug.hpp"
|
||||||
|
#include "./log.hpp"
|
||||||
#include "./range.hpp"
|
#include "./range.hpp"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
using util::colour;
|
using util::colour;
|
||||||
using util::colour3f;
|
using util::colour3f;
|
||||||
using util::colour4f;
|
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>>
|
static const std::map<std::string, colour<4,uint8_t>>
|
||||||
HTML_COLOURS { {
|
HTML_COLOURS { {
|
||||||
{ "white", { 0xff, 0xff, 0xff, 0xff } },
|
{ "white", { 0xff, 0xff, 0xff, 0xff } },
|
||||||
|
19
colour.hpp
19
colour.hpp
@ -34,9 +34,22 @@ namespace util {
|
|||||||
colour<S,U>
|
colour<S,U>
|
||||||
cast (void) const;
|
cast (void) const;
|
||||||
|
|
||||||
static colour from_html (const std::string&);
|
/// parse colours specified as "#AABBCCDD".
|
||||||
static colour from_x11 (const std::string&);
|
///
|
||||||
static colour from_string (const std::string&);
|
/// * 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
|
// Convenience types
|
||||||
|
@ -16,6 +16,47 @@ main (int, char**)
|
|||||||
tap.expect_eq (u.cast<float> (), f, "cast u8 to float");
|
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
|
// Check lookups are working
|
||||||
tap.expect_eq (util::colour4f::from_html ("white"), util::colour4f {1}, "HTML lookup");
|
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");
|
tap.expect_eq ( util::colour4f::from_x11 ("white"), util::colour4f {1}, "X11 lookup");
|
||||||
|
Loading…
Reference in New Issue
Block a user