3 * - By John Hodge (thePowersGang)
6 * - Generic colour handling and blending
15 static const uint8_t uint8_max = 0xFF;
16 static const unsigned int comp_max = 0x7FFF;
24 static unsigned int u8_to_ui(uint8_t u8v) {
25 return (unsigned int)u8v * comp_max / uint8_max;
27 static uint8_t ui_to_u8(unsigned int uiv) {
28 return uiv * uint8_max / comp_max;
30 // Perform an alpha-based blend on two components
31 static unsigned int alpha_blend(unsigned int alpha_comp, unsigned int left, unsigned int right) {
32 return (left * (comp_max - alpha_comp) + right * alpha_comp) / comp_max;
35 // - infinity == saturation, 1 == nothing
36 // fv = MAX / (MAX - uiv)
37 static float ui_to_float(unsigned int uiv) {
38 return (float)comp_max / (comp_max - uiv);
40 // uiv = MAX - MAX / fv
41 static unsigned int float_to_ui(float fv) {
42 return comp_max - comp_max / fv;
44 // perform a non-oversaturating blend of two colours (using an inverse relationship)
45 static unsigned int add_blend(unsigned int a, unsigned int b) {
46 return float_to_ui( ui_to_float(a) + ui_to_float(b) );
49 CColour(unsigned int r, unsigned int g, unsigned int b, unsigned int a):
50 m_alpha(a), m_red(r), m_green(g), m_blue(b)
55 static CColour from_argb(uint32_t val) {
57 u8_to_ui((val>>16) & 0xFF),
58 u8_to_ui((val>> 8) & 0xFF),
59 u8_to_ui((val>> 0) & 0xFF),
60 u8_to_ui((val>>24) & 0xFF)
64 uint32_t to_argb() const {
66 rv |= (uint32_t)ui_to_u8(m_red) << 16;
67 rv |= (uint32_t)ui_to_u8(m_green) << 8;
68 rv |= (uint32_t)ui_to_u8(m_blue) << 0;
69 rv |= (uint32_t)ui_to_u8(m_alpha) << 24;
73 // performs a blend of the two colours, maintaining the target alpha, using the source alpha as the blend control
74 CColour& blend(const CColour& other) {
75 m_red = alpha_blend(other.m_alpha, m_red , other.m_red );
76 m_green = alpha_blend(other.m_alpha, m_green, other.m_green);
77 m_blue = alpha_blend(other.m_alpha, m_blue , other.m_blue );
81 CColour& operator+(const CColour& other) {
82 m_alpha = add_blend(m_alpha, other.m_alpha);
83 m_red = add_blend(m_red , other.m_red );
84 m_green = add_blend(m_green, other.m_green);
85 m_blue = add_blend(m_blue , other.m_blue );