summaryrefslogtreecommitdiffstats
path: root/src/color-rgba.h
blob: a48d1e4e6d0f434e0cba230ba7c9446c058d0542 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// SPDX-License-Identifier: GPL-2.0-or-later
/*
    Authors:
      bulia byak <buliabyak@gmail.com>

    Copyright (C) 2004 Authors

    Released under GNU GPL v2+, read the file 'COPYING' for more information.
*/
#ifndef SEEN_COLOR_RGBA_H
#define SEEN_COLOR_RGBA_H

#include <cassert>
#include <cmath>

/**
 * A class to contain a floating point RGBA color as one unit.
 */
class ColorRGBA {
public:

    /**
     * A constructor to create the color from four floating point values.
     * Load the values into the array of floats in this object.
     *
     * @param  c0  Red
     * @param  c1  Green
     * @param  c2  Blue
     * @param  c3  Alpha
     */
    ColorRGBA(float c0, float c1, float c2, float c3)
    {
        _c[0] = c0; _c[1] = c1;
        _c[2] = c2; _c[3] = c3;
    }

    /**
     * Create a quick ColorRGBA with all zeros.
     */
    ColorRGBA() : _c{0.0,0.0,0.0,0.0}
    {
    }

    /**
     * A constructor to create the color from an unsigned int, as found everywhere when dealing with colors.
     *
     * Separate the values and load them into the array of floats in this object.
     * @param  intcolor   rgba32 "unsigned int representation (0xRRGGBBAA)
     */
    ColorRGBA(unsigned int intcolor)
    {
         _c[0] = ((intcolor & 0xff000000) >> 24) / 255.0;
         _c[1] = ((intcolor & 0x00ff0000) >> 16) / 255.0;
         _c[2] = ((intcolor & 0x0000ff00) >>  8) / 255.0;
         _c[3] = ((intcolor & 0x000000ff) >>  0) / 255.0;

    }

    /**
     * Create a ColorRGBA using an array of floats.
     *
     * Go through each entry in the array and put it into \c _c.
     *
     * @param  in_array  The values to be placed into the object
     */
    ColorRGBA(float in_array[4])
    {
        for (int i = 0; i < 4; i++)
            _c[i] = in_array[i];
    }

    /**
     * Overwrite the values in this object with another \c ColorRGBA.
     * Copy all the values from \c m into \c this.
     *
     * @param  m  Values to use for the array.
     * @return This ColorRGBA object.
     */
    ColorRGBA &operator=(ColorRGBA const &m) {
        for (unsigned i = 0 ; i < 4 ; ++i) {
            _c[i] = m._c[i];
        }
        return *this;
    }

    /**
     * Grab a particular value from the ColorRGBA object.
     * First checks to make sure that the value is within the array,
     * and then return the value if it is.
     *
     * @param  i  Which value to grab.
     * @return The requested value.
     */
    float operator[](unsigned int const i) const {
        assert( unsigned(i) < 4 );
        return _c[i];
    }

    /**
     * Check to ensure that two \c ColorRGBA's are equal.
     * Check each value to see if they are equal.  If they all are,
     * return true.
     *
     * @param  other  The guy to check against.
     * @return Whether or not they are equal.
     */
    bool operator== (const ColorRGBA &other) const {
        for (int i = 0; i < 4; i++) {
            if (_c[i] != other[i])
                return false;
        }
        return true;
    }

    bool operator!=(ColorRGBA const &o) const {
        return !(*this == o);
    }

    /**
     * Average two \c ColorRGBAs to create another one.
     * This function goes through all the points in the two objects and
     * merges them together based on the weighting.  The current objects
     * value are multiplied by 1.0 - weight and the second object by weight.
     * This means that they should always be balanced by the parameter.
     *
     * @param  second  The second RGBA, with this being the first
     * @param  weight  How much of each should be used.  Zero is all
     * this while one is all the second.  Default is
     * half and half.
     */
    ColorRGBA average (const ColorRGBA &second, const float weight = 0.5) const {
        float returnval[4];

        for (int i = 0; i < 4; i++) {
            returnval[i] = _c[i] * (1.0 - weight) + second[i] * weight; 
        }

        return ColorRGBA(returnval[0], returnval[1], returnval[2], returnval[3]);
    }

    /**
     * Give the rgba32 "unsigned int" representation of the color.
     * round each components*255 and combine them (RRGGBBAA).
     * WARNING : this reduces color precision (from float to 0->255 int per component)
     * but it should be expected since we request this kind of output
     */
    unsigned int getIntValue() const {

        return
            (int(round(_c[0]*255)) << 24) | 
            (int(round(_c[1]*255)) << 16) | 
            (int(round(_c[2]*255)) <<  8) | 
            (int(round(_c[3]*255)));
    }

private:
    /** Array of values that are stored. */
    float _c[4];
};


#endif // SEEN_COLOR_RGBA_H

/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :