Usermode/AxWin4 - Added text rendering (very hacky using VGA font)
[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 unsigned int comp_max = 0x7FFF;
16         
17         unsigned int    m_alpha;
18         unsigned int    m_red;
19         unsigned int    m_green;
20         unsigned int    m_blue;
21
22 private:
23         static unsigned int u8_to_ui(uint8_t u8v) {
24                 return (unsigned int)u8v * comp_max / UINT8_MAX;
25         }
26         static uint8_t ui_to_u8(unsigned int uiv) {
27                 return uiv * UINT8_MAX / comp_max;
28         }
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;
32         }
33         // Float values:
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);
38         }
39         // uiv = MAX - MAX / fv
40         static unsigned int float_to_ui(float fv) {
41                 return comp_max - comp_max / fv;
42         }
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) );
46         }
47
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)
50         {
51         }
52 public:
53
54         static CColour from_argb(uint32_t val) {
55                 return CColour(
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)
60                         );
61         }
62         
63         uint32_t to_argb() const {
64                 uint32_t        rv = 0;
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;
69                 return rv;
70         }
71         
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 );
77                 return *this;
78         }
79         // Add all components
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 );
85                 return *this;
86         }
87 };
88
89 }       // namespace AxWin
90
91 #endif
92

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