source: branches/help/WINDOW/aw_rgb.hxx

Last change on this file was 17002, checked in by westram, 7 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
34typedef unsigned long AW_rgb; // =XColor.pixel (motif color format)
35
36class AW_rgb_normalized;
37
38class AW_rgb16 {
39    uint16_t R, G, B;
40
41    void rescale(uint16_t my_max);
42public:
43    static CONSTEXPR float MAX = 65535.0;
44
45    AW_rgb16() : R(0), G(0), B(0) {}
46    AW_rgb16(uint16_t red, uint16_t green, uint16_t blue) : R(red), G(green), B(blue) {}
47    explicit AW_rgb16(const char *colorname);
48    explicit inline AW_rgb16(const AW_rgb_normalized& o);
49    explicit inline AW_rgb16(AW_rgb m) {
50        B = m & 255; m >>= 8;
51        G = m & 255; m >>= 8;
52        R = m & 255;
53    }
54
55    bool operator == (const AW_rgb16& o) const { return R==o.R && G==o.G && B == o.B; }
56    bool operator != (const AW_rgb16& o) const { return !operator==(o); }
57
58    uint16_t r() const { return R; }
59    uint16_t g() const { return G; }
60    uint16_t b() const { return B; }
61
62    const char *ascii() const;
63};
64
65class AW_rgb_normalized {
66    float R, G, B;
67
68    static bool is_normal(const float& f) { return f >= 0.0 && f<=1.0; }
69    static const float& normal(const float& f) { aw_assert(is_normal(f)); return f; }
70
71protected:
72    AW_rgb_normalized(void*, float red, float green, float blue) : // accepts any values
73        R(red),
74        G(green),
75        B(blue)
76    {}
77public:
78    AW_rgb_normalized(float red, float green, float blue) :
79        R(normal(red)),
80        G(normal(green)),
81        B(normal(blue))
82    {}
83    explicit AW_rgb_normalized(const AW_rgb16& o) :
84        R(normal(o.r()/AW_rgb16::MAX)),
85        G(normal(o.g()/AW_rgb16::MAX)),
86        B(normal(o.b()/AW_rgb16::MAX))
87    {}
88#if defined(Cxx11)
89    explicit AW_rgb_normalized(const char *colorname) : AW_rgb_normalized(AW_rgb16(colorname)) {}
90#else // !defined(Cxx11)
91    explicit AW_rgb_normalized(const char *colorname) { *this = AW_rgb_normalized(AW_rgb16(colorname)); }
92#endif
93
94    float r() const { return R; }
95    float g() const { return G; }
96    float b() const { return B; }
97};
98
99inline AW_rgb16::AW_rgb16(const AW_rgb_normalized& o) : R(o.r()*MAX), G(o.g()*MAX), B(o.b()*MAX) {}
100
101// ---------------------------
102//      color calculation
103//
104// Note: avoids color overflows (eg. white cannot get any whiter, black cannot get any blacker)
105
106class AW_rgb_diff : private AW_rgb_normalized {
107public:
108    AW_rgb_diff(float red, float green, float blue) : AW_rgb_normalized(NULp, red, green, blue) {}
109
110    float r() const { return AW_rgb_normalized::r(); }
111    float g() const { return AW_rgb_normalized::g(); }
112    float b() const { return AW_rgb_normalized::b(); }
113
114    AW_rgb_diff abs() const {
115        return AW_rgb_diff(fabs(r()),
116                           fabs(g()),
117                           fabs(b()));
118    }
119};
120
121inline AW_rgb_diff operator-(const AW_rgb_normalized& c1, const AW_rgb_normalized& c2) {
122    return AW_rgb_diff(c1.r()-c2.r(),
123                       c1.g()-c2.g(),
124                       c1.b()-c2.b());
125}
126
127// AW_rgb_diff (add, scale, negate)
128inline AW_rgb_diff operator+(const AW_rgb_diff& d1, const AW_rgb_diff& d2) {
129    return AW_rgb_diff(d1.r()+d2.r(),
130                       d1.g()+d2.g(),
131                       d1.b()+d2.b());
132}
133inline 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); }
134inline AW_rgb_diff operator*(const float& f, const AW_rgb_diff& d) { return d*f; }
135inline AW_rgb_diff operator-(const AW_rgb_diff& d) { return d*-1.0; }
136
137inline AW_rgb_diff max(const AW_rgb_diff& d1, const AW_rgb_diff& d2) {
138    return AW_rgb_diff(std::max(d1.r(), d2.r()),
139                       std::max(d1.g(), d2.g()),
140                       std::max(d1.b(), d2.b()));
141}
142
143// modify color using diff:
144inline float avoid_overflow(float f) { return f<0.0 ? 0.0 : (f>1.0 ? 1.0 : f); }
145
146inline AW_rgb_normalized operator+(const AW_rgb_normalized& col, const AW_rgb_diff& off) {
147    return AW_rgb_normalized(avoid_overflow(col.r()+off.r()),
148                             avoid_overflow(col.g()+off.g()),
149                             avoid_overflow(col.b()+off.b()));
150}
151inline AW_rgb_normalized operator-(const AW_rgb_normalized& col, const AW_rgb_diff& off) { return col + -off; }
152
153// allow to calculate directly with AW_rgb16:
154inline AW_rgb_diff operator-(const AW_rgb16& c1, const AW_rgb16& c2) { return AW_rgb_normalized(c1)-AW_rgb_normalized(c2); }
155inline AW_rgb16 operator+(const AW_rgb16& col, const AW_rgb_diff& off) { return AW_rgb16(AW_rgb_normalized(col)+off); }
156inline AW_rgb16 operator-(const AW_rgb16& col, const AW_rgb_diff& off) { return AW_rgb16(AW_rgb_normalized(col)-off); }
157
158
159#else
160#error aw_rgb.hxx included twice
161#endif // AW_RGB_HXX
Note: See TracBrowser for help on using the repository browser.