source: tags/ms_r17q2/WINDOW/aw_rgb.hxx

Last change on this file was 15049, checked in by westram, 8 years ago
File size: 5.4 KB
Line 
1// ============================================================ //
2//                                                              //
3//   File      : aw_rgb.hxx                                     //
4//   Purpose   :                                                //
5//                                                              //
6//   Coded by Ralf Westram (coder@reallysoft.de) in June 2016   //
7//   http://www.arb-home.de/                                    //
8//                                                              //
9// ============================================================ //
10
11#ifndef AW_RGB_HXX
12#define AW_RGB_HXX
13
14#ifndef CXXFORWARD_H
15#include <cxxforward.h>
16#endif
17#ifndef ARB_ASSERT_H
18#include <arb_assert.h>
19#endif
20#ifndef _STDINT_H
21#include <stdint.h>
22#endif
23#ifndef _GLIBCXX_CMATH
24#include <cmath>
25#endif
26#ifndef _GLIBCXX_ALGORITHM
27#include <algorithm>
28#endif
29
30#ifndef aw_assert
31#define aw_assert(bed) arb_assert(bed)
32#endif
33
34#if defined(ARB_GTK)
35#define AW_WINDOW_FG AW_rgb()
36#endif
37
38class AW_rgb_normalized;
39
40class AW_rgb16 {
41    uint16_t R, G, B;
42
43    void rescale(uint16_t my_max);
44public:
45    static CONSTEXPR float MAX = 65535.0;
46
47    AW_rgb16() : R(0), G(0), B(0) {}
48    AW_rgb16(uint16_t red, uint16_t green, uint16_t blue) : R(red), G(green), B(blue) {}
49    explicit AW_rgb16(const char *colorname);
50    explicit inline AW_rgb16(const AW_rgb_normalized& o);
51
52    bool operator == (const AW_rgb16& o) const { return R==o.R && G==o.G && B == o.B; }
53    bool operator != (const AW_rgb16& o) const { return !operator==(o); }
54
55    uint16_t r() const { return R; }
56    uint16_t g() const { return G; }
57    uint16_t b() const { return B; }
58
59    const char *ascii() const;
60};
61
62class AW_rgb_normalized {
63    float R, G, B;
64
65    static bool is_normal(const float& f) { return f >= 0.0 && f<=1.0; }
66    static const float& normal(const float& f) { aw_assert(is_normal(f)); return f; }
67
68protected:
69    AW_rgb_normalized(void*, float red, float green, float blue) : // accepts any values
70        R(red),
71        G(green),
72        B(blue)
73    {}
74public:
75    AW_rgb_normalized(float red, float green, float blue) :
76        R(normal(red)),
77        G(normal(green)),
78        B(normal(blue))
79    {}
80    explicit AW_rgb_normalized(const AW_rgb16& o) :
81        R(normal(o.r()/AW_rgb16::MAX)),
82        G(normal(o.g()/AW_rgb16::MAX)),
83        B(normal(o.b()/AW_rgb16::MAX))
84    {}
85#if defined(Cxx11)
86    explicit AW_rgb_normalized(const char *colorname) : AW_rgb_normalized(AW_rgb16(colorname)) {}
87#else // !defined(Cxx11)
88    explicit AW_rgb_normalized(const char *colorname) { *this = AW_rgb_normalized(AW_rgb16(colorname)); }
89#endif
90
91    float r() const { return R; }
92    float g() const { return G; }
93    float b() const { return B; }
94};
95
96inline AW_rgb16::AW_rgb16(const AW_rgb_normalized& o) : R(o.r()*MAX), G(o.g()*MAX), B(o.b()*MAX) {}
97
98// ---------------------------
99//      color calculation
100//
101// Note: avoids color overflows (eg. white cannot get any whiter, black cannot get any blacker)
102
103class AW_rgb_diff : private AW_rgb_normalized {
104public:
105    AW_rgb_diff(float red, float green, float blue) : AW_rgb_normalized(NULL, red, green, blue) {}
106
107    float r() const { return AW_rgb_normalized::r(); }
108    float g() const { return AW_rgb_normalized::g(); }
109    float b() const { return AW_rgb_normalized::b(); }
110
111    AW_rgb_diff abs() const {
112        return AW_rgb_diff(fabs(r()),
113                           fabs(g()),
114                           fabs(b()));
115    }
116};
117
118inline AW_rgb_diff operator-(const AW_rgb_normalized& c1, const AW_rgb_normalized& c2) {
119    return AW_rgb_diff(c1.r()-c2.r(),
120                       c1.g()-c2.g(),
121                       c1.b()-c2.b());
122}
123
124// AW_rgb_diff (add, scale, negate)
125inline AW_rgb_diff operator+(const AW_rgb_diff& d1, const AW_rgb_diff& d2) {
126    return AW_rgb_diff(d1.r()+d2.r(),
127                       d1.g()+d2.g(),
128                       d1.b()+d2.b());
129}
130inline AW_rgb_diff operator*(const AW_rgb_diff& d, const float& f) { return AW_rgb_diff(d.r()*f, d.g()*f, d.b()*f); }
131inline AW_rgb_diff operator*(const float& f, const AW_rgb_diff& d) { return d*f; }
132inline AW_rgb_diff operator-(const AW_rgb_diff& d) { return d*-1.0; }
133
134inline AW_rgb_diff max(const AW_rgb_diff& d1, const AW_rgb_diff& d2) {
135    return AW_rgb_diff(std::max(d1.r(), d2.r()),
136                       std::max(d1.g(), d2.g()),
137                       std::max(d1.b(), d2.b()));
138}
139
140// modify color using diff:
141inline float avoid_overflow(float f) { return f<0.0 ? 0.0 : (f>1.0 ? 1.0 : f); }
142
143inline AW_rgb_normalized operator+(const AW_rgb_normalized& col, const AW_rgb_diff& off) {
144    return AW_rgb_normalized(avoid_overflow(col.r()+off.r()),
145                             avoid_overflow(col.g()+off.g()),
146                             avoid_overflow(col.b()+off.b()));
147}
148inline AW_rgb_normalized operator-(const AW_rgb_normalized& col, const AW_rgb_diff& off) { return col + -off; }
149
150// allow to calculate directly with AW_rgb16:
151inline AW_rgb_diff operator-(const AW_rgb16& c1, const AW_rgb16& c2) { return AW_rgb_normalized(c1)-AW_rgb_normalized(c2); }
152inline AW_rgb16 operator+(const AW_rgb16& col, const AW_rgb_diff& off) { return AW_rgb16(AW_rgb_normalized(col)+off); }
153inline AW_rgb16 operator-(const AW_rgb16& col, const AW_rgb_diff& off) { return AW_rgb16(AW_rgb_normalized(col)-off); }
154
155
156#if defined(ARB_MOTIF)
157typedef unsigned long AW_rgb; // =XColor.pixel
158#else // ARB_GTK
159typedef AW_rgb16 AW_rgb;
160#endif
161
162#else
163#error aw_rgb.hxx included twice
164#endif // AW_RGB_HXX
Note: See TracBrowser for help on using the repository browser.