Usermode/libc - Fix strchr and strrchr behavior
[tpg/acess2.git] / Usermode / Applications / axwin4_src / Server / include / CColour.hpp
1 /*
2  * Acess2 GUI v4
3  * - By John Hodge (thePowersGang)
4  *
5  * CColour.hpp
6  * - Generic colour handling and blending
7  */
8 #ifndef _CCOLOUR_HPP_
9 #define _CCOLOUR_HPP_
10
11 namespace AxWin {
12
13 class CColour
14 {
15         static const uint8_t    uint8_max = 0xFF;
16         static const unsigned int comp_max = 0x7FFF;
17         
18         unsigned int    m_alpha;
19         unsigned int    m_red;
20         unsigned int    m_green;
21         unsigned int    m_blue;
22
23 private:
24         static unsigned int u8_to_ui(uint8_t u8v) {
25                 return (unsigned int)u8v * comp_max / uint8_max;
26         }
27         static uint8_t ui_to_u8(unsigned int uiv) {
28                 return uiv * uint8_max / comp_max;
29         }
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;
33         }
34         // Float values:
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);
39         }
40         // uiv = MAX - MAX / fv
41         static unsigned int float_to_ui(float fv) {
42                 return comp_max - comp_max / fv;
43         }
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) );
47         }
48
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)
51         {
52         }
53 public:
54
55         static CColour from_argb(uint32_t val) {
56                 return CColour(
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)
61                         );
62         }
63         
64         uint32_t to_argb() const {
65                 uint32_t        rv = 0;
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;
70                 return rv;
71         }
72         
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 );
78                 return *this;
79         }
80         // Add all components
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 );
86                 return *this;
87         }
88 };
89
90 }       // namespace AxWin
91
92 #endif
93

UCC git Repository :: git.ucc.asn.au