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