Switch (back) to our own Color type instead of using wxColour.

The reason is that wxColour's default constructor creates an invalid color (what is that even?). It is nicer to just have default be transparent.
This commit is contained in:
Twan van Laarhoven
2020-04-26 21:41:35 +02:00
parent 8698144ac4
commit af7e8c9d39
13 changed files with 101 additions and 46 deletions
+28 -18
View File
@@ -11,11 +11,14 @@
// ----------------------------------------------------------------------------- : Parsing etc.
template <> void Reader::handle(Color& col) {
col = parse_color(getValue());
if (!col.Ok()) {
col = Color(0,0,0,0);
warning(_("Not a valid color value"));
template <> void Reader::handle(Color& out) {
String const& str = getValue();
auto col = parse_color(str);
if (!col.has_value()) {
out = Color();
warning(_("Not a valid color value: ") + str);
} else {
out = *col;
}
}
@@ -24,7 +27,7 @@ template <> void Writer::handle(const Color& col) {
}
Color parse_color(const String& v) {
optional<Color> parse_color(const String& v) {
UInt r,g,b,a;
if (wxSscanf(v.c_str(),_("rgb(%u,%u,%u)"),&r,&g,&b)) {
return Color(r, g, b);
@@ -33,7 +36,13 @@ Color parse_color(const String& v) {
} else if (v == _("transparent")) {
return Color(0,0,0,0);
} else {
return Color(v);
// Try to find a named color
wxColour c = wxTheColourDatabase->Find(v);
if (c.Ok()) {
return Color(c);
} else {
return optional<Color>();
}
}
}
@@ -49,7 +58,7 @@ String format_color(Color col) {
// ----------------------------------------------------------------------------- : Color utility functions
Color lerp(const Color& a, const Color& b, double t) {
Color lerp(Color a, Color b, double t) {
return Color(static_cast<int>( a.Red() + (b.Red() - a.Red() ) * t ),
static_cast<int>( a.Green() + (b.Green() - a.Green()) * t ),
static_cast<int>( a.Blue() + (b.Blue() - a.Blue() ) * t ),
@@ -79,21 +88,22 @@ Color hsl2rgb(double h, double s, double l) {
}
Color darken(const Color& c) {
Color darken(Color c) {
return Color(
c.Red() * 8 / 10,
c.Green() * 8 / 10,
c.Blue() * 8 / 10
c.r * 8 / 10,
c.g * 8 / 10,
c.b * 8 / 10,
c.a
);
}
Color saturate(const Color& c, double amount) {
int r = c.Red(), g = c.Green(), b = c.Blue();
double l = (r + g + b) / 3;
Color saturate(Color c, double amount) {
double l = (c.r + c.g + c.b) / 3;
return Color(
col(static_cast<int>( (r - amount * l) / (1 - amount) )),
col(static_cast<int>( (g - amount * l) / (1 - amount) )),
col(static_cast<int>( (b - amount * l) / (1 - amount) ))
col(static_cast<int>( (c.r - amount * l) / (1 - amount) )),
col(static_cast<int>( (c.g - amount * l) / (1 - amount) )),
col(static_cast<int>( (c.b - amount * l) / (1 - amount) )),
c.a
);
}
+42 -5
View File
@@ -14,9 +14,45 @@
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <optional>
// ----------------------------------------------------------------------------- : Colors
// Colors.
// Ideally we would just use wxColour, but that class is stupid because it has an "invalid" state,
// and the default constructor makes invalid values.
struct Color {
union {
struct {
unsigned char r, g, b, a;
};
uint32_t packed;
};
inline Color() : r(0), g(0), b(0), a(0) {}
inline Color(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 255) : r(r), g(g), b(b), a(a) {}
inline Color(wxColour color) : r(color.Red()), g(color.Green()), b(color.Blue()), a(color.Alpha()) {}
inline operator wxColour() const { return wxColour(r, g, b, a); }
inline operator wxPen() const { return wxPen((wxColour)*this); }
inline operator wxBrush() const { return wxBrush((wxColour)*this); }
inline bool operator == (Color const& that) const {
return packed == that.packed;
}
inline bool operator != (Color const& that) const {
return packed != that.packed;
}
inline constexpr unsigned char Red() const { return r; }
inline constexpr unsigned char Green() const { return g; }
inline constexpr unsigned char Blue() const { return b; }
inline constexpr unsigned char Alpha() const { return a; }
};
// -----------------------------------------------------------------------------
// RGB Color, packed into 3 bytes
// These are used for arrays in wxImage
// -----------------------------------------------------------------------------
// stupid headers stealing useful names
@@ -37,6 +73,7 @@ struct RGB {
RGB() {}
RGB(Byte x) : r(x), g(x), b(x) {}
RGB(Byte r, Byte g, Byte b) : r(r), g(g), b(b) {}
RGB(Color x) : r(x.Red()), g(x.Green()), b(x.Blue()) {}
RGB(wxColour const& x) : r(x.Red()), g(x.Green()), b(x.Blue()) {}
inline int total() { return r+g+b; }
@@ -65,7 +102,7 @@ struct RGB {
// ----------------------------------------------------------------------------- : Parsing
/// Parse a color
Color parse_color(const String& value);
optional<Color> parse_color(const String& value);
/// Convert a Color to a string
String format_color(Color col);
@@ -77,19 +114,19 @@ inline int top(int x) { return min(255, x); } ///< top range check for color
inline int col(int x) { return top(bot(x)); } ///< top and bottom range check for color values
/// Linear interpolation between colors
Color lerp(const Color& a, const Color& b, double t);
Color lerp(Color a, Color b, double t);
/// convert HSL to RGB, h,s,l must be in range [0...1)
Color hsl2rgb(double h, double s, double l);
/// A darker version of a color
Color darken(const Color& c);
Color darken(Color c);
/// A black or white color, that contrasts with c
Color contrasting_color(const Color& c);
Color contrasting_color(Color c);
/// A saturated version of a color
Color saturate(const Color& c, double amount);
Color saturate(Color c, double amount);
/// Recolor:
/**