1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3     Authors:
4       bulia byak <buliabyak@gmail.com>
5 
6     Copyright (C) 2004 Authors
7 
8     Released under GNU GPL v2+, read the file 'COPYING' for more information.
9 */
10 #ifndef SEEN_COLOR_RGBA_H
11 #define SEEN_COLOR_RGBA_H
12 
13 #include <cassert>
14 #include <cmath>
15 
16 /**
17  * A class to contain a floating point RGBA color as one unit.
18  */
19 class ColorRGBA {
20 public:
21 
22     /**
23      * A constructor to create the color from four floating point values.
24      * Load the values into the array of floats in this object.
25      *
26      * @param  c0  Red
27      * @param  c1  Green
28      * @param  c2  Blue
29      * @param  c3  Alpha
30      */
ColorRGBA(float c0,float c1,float c2,float c3)31     ColorRGBA(float c0, float c1, float c2, float c3)
32     {
33         _c[0] = c0; _c[1] = c1;
34         _c[2] = c2; _c[3] = c3;
35     }
36 
37     /**
38      * Create a quick ColorRGBA with all zeros.
39      */
ColorRGBA()40     ColorRGBA()
41     {
42         for (float & i : _c)
43             i = 0.0;
44     }
45 
46     /**
47      * A constructor to create the color from an unsigned int, as found everywhere when dealing with colors.
48      *
49      * Separate the values and load them into the array of floats in this object.
50      * @param  intcolor   rgba32 "unsigned int representation (0xRRGGBBAA)
51      */
ColorRGBA(unsigned int intcolor)52     ColorRGBA(unsigned int intcolor)
53     {
54          _c[0] = ((intcolor & 0xff000000) >> 24) / 255.0;
55          _c[1] = ((intcolor & 0x00ff0000) >> 16) / 255.0;
56          _c[2] = ((intcolor & 0x0000ff00) >>  8) / 255.0;
57          _c[3] = ((intcolor & 0x000000ff) >>  0) / 255.0;
58 
59     }
60 
61     /**
62      * Create a ColorRGBA using an array of floats.
63      *
64      * Go through each entry in the array and put it into \c _c.
65      *
66      * @param  in_array  The values to be placed into the object
67      */
ColorRGBA(float in_array[4])68     ColorRGBA(float in_array[4])
69     {
70         for (int i = 0; i < 4; i++)
71             _c[i] = in_array[i];
72     }
73 
74     /**
75      * Overwrite the values in this object with another \c ColorRGBA.
76      * Copy all the values from \c m into \c this.
77      *
78      * @param  m  Values to use for the array.
79      * @return This ColorRGBA object.
80      */
81     ColorRGBA &operator=(ColorRGBA const &m) {
82         for (unsigned i = 0 ; i < 4 ; ++i) {
83             _c[i] = m._c[i];
84         }
85         return *this;
86     }
87 
88     /**
89      * Grab a particular value from the ColorRGBA object.
90      * First checks to make sure that the value is within the array,
91      * and then return the value if it is.
92      *
93      * @param  i  Which value to grab.
94      * @return The requested value.
95      */
96     float operator[](unsigned int const i) const {
97         assert( unsigned(i) < 4 );
98         return _c[i];
99     }
100 
101     /**
102      * Check to ensure that two \c ColorRGBA's are equal.
103      * Check each value to see if they are equal.  If they all are,
104      * return true.
105      *
106      * @param  other  The guy to check against.
107      * @return Whether or not they are equal.
108      */
109     bool operator== (const ColorRGBA &other) const {
110         for (int i = 0; i < 4; i++) {
111             if (_c[i] != other[i])
112                 return false;
113         }
114         return true;
115     }
116 
117     bool operator!=(ColorRGBA const &o) const {
118         return !(*this == o);
119     }
120 
121     /**
122      * Average two \c ColorRGBAs to create another one.
123      * This function goes through all the points in the two objects and
124      * merges them together based on the weighting.  The current objects
125      * value are multiplied by 1.0 - weight and the second object by weight.
126      * This means that they should always be balanced by the parameter.
127      *
128      * @param  second  The second RGBA, with this being the first
129      * @param  weight  How much of each should be used.  Zero is all
130      * this while one is all the second.  Default is
131      * half and half.
132      */
133     ColorRGBA average (const ColorRGBA &second, const float weight = 0.5) const {
134         float returnval[4];
135 
136         for (int i = 0; i < 4; i++) {
137             returnval[i] = _c[i] * (1.0 - weight) + second[i] * weight;
138         }
139 
140         return ColorRGBA(returnval[0], returnval[1], returnval[2], returnval[3]);
141     }
142 
143     /**
144      * Give the rgba32 "unsigned int" representation of the color.
145      * round each components*255 and combine them (RRGGBBAA).
146      * WARNING : this reduces color precision (from float to 0->255 int per component)
147      * but it should be expected since we request this kind of output
148      */
getIntValue()149     unsigned int getIntValue() const {
150 
151         return
152             (int(round(_c[0]*255)) << 24) |
153             (int(round(_c[1]*255)) << 16) |
154             (int(round(_c[2]*255)) <<  8) |
155             (int(round(_c[3]*255)));
156     }
157 
158 private:
159     /** Array of values that are stored. */
160     float _c[4];
161 };
162 
163 
164 #endif // SEEN_COLOR_RGBA_H
165 
166 /*
167   Local Variables:
168   mode:c++
169   c-file-style:"stroustrup"
170   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
171   indent-tabs-mode:nil
172   fill-column:99
173   End:
174 */
175 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
176