1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #pragma once
24 
25 #include "../Math/Vector4.h"
26 
27 // Defined by Windows headers
28 #undef TRANSPARENT
29 
30 namespace Urho3D
31 {
32 
33 class String;
34 
35 /// RGBA color.
36 class URHO3D_API Color
37 {
38 public:
39     /// Construct with default values (opaque white.)
Color()40     Color() :
41         r_(1.0f),
42         g_(1.0f),
43         b_(1.0f),
44         a_(1.0f)
45     {
46     }
47 
48     /// Copy-construct from another color.
Color(const Color & color)49     Color(const Color& color) :
50         r_(color.r_),
51         g_(color.g_),
52         b_(color.b_),
53         a_(color.a_)
54     {
55     }
56 
57     /// Construct from another color and modify the alpha.
Color(const Color & color,float a)58     Color(const Color& color, float a) :
59         r_(color.r_),
60         g_(color.g_),
61         b_(color.b_),
62         a_(a)
63     {
64     }
65 
66     /// Construct from RGB values and set alpha fully opaque.
Color(float r,float g,float b)67     Color(float r, float g, float b) :
68         r_(r),
69         g_(g),
70         b_(b),
71         a_(1.0f)
72     {
73     }
74 
75     /// Construct from RGBA values.
Color(float r,float g,float b,float a)76     Color(float r, float g, float b, float a) :
77         r_(r),
78         g_(g),
79         b_(b),
80         a_(a)
81     {
82     }
83 
84     /// Construct from a float array.
Color(const float * data)85     explicit Color(const float* data) :
86         r_(data[0]),
87         g_(data[1]),
88         b_(data[2]),
89         a_(data[3])
90     {
91     }
92 
93     /// Assign from another color.
94     Color& operator =(const Color& rhs)
95     {
96         r_ = rhs.r_;
97         g_ = rhs.g_;
98         b_ = rhs.b_;
99         a_ = rhs.a_;
100         return *this;
101     }
102 
103     /// Test for equality with another color without epsilon.
104     bool operator ==(const Color& rhs) const { return r_ == rhs.r_ && g_ == rhs.g_ && b_ == rhs.b_ && a_ == rhs.a_; }
105 
106     /// Test for inequality with another color without epsilon.
107     bool operator !=(const Color& rhs) const { return r_ != rhs.r_ || g_ != rhs.g_ || b_ != rhs.b_ || a_ != rhs.a_; }
108 
109     /// Multiply with a scalar.
110     Color operator *(float rhs) const { return Color(r_ * rhs, g_ * rhs, b_ * rhs, a_ * rhs); }
111 
112     /// Add a color.
113     Color operator +(const Color& rhs) const { return Color(r_ + rhs.r_, g_ + rhs.g_, b_ + rhs.b_, a_ + rhs.a_); }
114 
115     /// Return negation.
116     Color operator -() const { return Color(-r_, -g_, -b_, -a_); }
117 
118     /// Subtract a color.
119     Color operator -(const Color& rhs) const { return Color(r_ - rhs.r_, g_ - rhs.g_, b_ - rhs.b_, a_ - rhs.a_); }
120 
121     /// Add-assign a color.
122     Color& operator +=(const Color& rhs)
123     {
124         r_ += rhs.r_;
125         g_ += rhs.g_;
126         b_ += rhs.b_;
127         a_ += rhs.a_;
128         return *this;
129     }
130 
131     /// Return float data.
Data()132     const float* Data() const { return &r_; }
133 
134     /// Return color packed to a 32-bit integer, with R component in the lowest 8 bits. Components are clamped to [0, 1] range.
135     unsigned ToUInt() const;
136     /// Return HSL color-space representation as a Vector3; the RGB values are clipped before conversion but not changed in the process.
137     Vector3 ToHSL() const;
138     /// Return HSV color-space representation as a Vector3; the RGB values are clipped before conversion but not changed in the process.
139     Vector3 ToHSV() const;
140     /// Set RGBA values from specified HSL values and alpha.
141     void FromHSL(float h, float s, float l, float a = 1.0f);
142     /// Set RGBA values from specified HSV values and alpha.
143     void FromHSV(float h, float s, float v, float a = 1.0f);
144 
145     /// Return RGB as a three-dimensional vector.
ToVector3()146     Vector3 ToVector3() const { return Vector3(r_, g_, b_); }
147 
148     /// Return RGBA as a four-dimensional vector.
ToVector4()149     Vector4 ToVector4() const { return Vector4(r_, g_, b_, a_); }
150 
151     /// Return sum of RGB components.
SumRGB()152     float SumRGB() const { return r_ + g_ + b_; }
153 
154     /// Return average value of the RGB channels.
Average()155     float Average() const { return (r_ + g_ + b_) / 3.0f; }
156 
157     /// Return the 'grayscale' representation of RGB values, as used by JPEG and PAL/NTSC among others.
Luma()158     float Luma() const { return r_ * 0.299f + g_ * 0.587f + b_ * 0.114f; }
159 
160     /// Return the colorfulness relative to the brightness of a similarly illuminated white.
161     float Chroma() const;
162     /// Return hue mapped to range [0, 1.0).
163     float Hue() const;
164     /// Return saturation as defined for HSL.
165     float SaturationHSL() const;
166     /// Return saturation as defined for HSV.
167     float SaturationHSV() const;
168 
169     /// Return value as defined for HSV: largest value of the RGB components. Equivalent to calling MinRGB().
Value()170     float Value() const { return MaxRGB(); }
171 
172     /// Return lightness as defined for HSL: average of the largest and smallest values of the RGB components.
173     float Lightness() const;
174 
175     /// Stores the values of least and greatest RGB component at specified pointer addresses, optionally clipping those values to [0, 1] range.
176     void Bounds(float* min, float* max, bool clipped = false) const;
177     /// Return the largest value of the RGB components.
178     float MaxRGB() const;
179     /// Return the smallest value of the RGB components.
180     float MinRGB() const;
181     /// Return range, defined as the difference between the greatest and least RGB component.
182     float Range() const;
183 
184     /// Clip to [0, 1.0] range.
185     void Clip(bool clipAlpha = false);
186     /// Inverts the RGB channels and optionally the alpha channel as well.
187     void Invert(bool invertAlpha = false);
188     /// Return linear interpolation of this color with another color.
189     Color Lerp(const Color& rhs, float t) const;
190 
191     /// Return color with absolute components.
Abs()192     Color Abs() const { return Color(Urho3D::Abs(r_), Urho3D::Abs(g_), Urho3D::Abs(b_), Urho3D::Abs(a_)); }
193 
194     /// Test for equality with another color with epsilon.
Equals(const Color & rhs)195     bool Equals(const Color& rhs) const
196     {
197         return Urho3D::Equals(r_, rhs.r_) && Urho3D::Equals(g_, rhs.g_) && Urho3D::Equals(b_, rhs.b_) && Urho3D::Equals(a_, rhs.a_);
198     }
199 
200     /// Return as string.
201     String ToString() const;
202 
203     /// Red value.
204     float r_;
205     /// Green value.
206     float g_;
207     /// Blue value.
208     float b_;
209     /// Alpha value.
210     float a_;
211 
212     /// Opaque white color.
213     static const Color WHITE;
214     /// Opaque gray color.
215     static const Color GRAY;
216     /// Opaque black color.
217     static const Color BLACK;
218     /// Opaque red color.
219     static const Color RED;
220     /// Opaque green color.
221     static const Color GREEN;
222     /// Opaque blue color.
223     static const Color BLUE;
224     /// Opaque cyan color.
225     static const Color CYAN;
226     /// Opaque magenta color.
227     static const Color MAGENTA;
228     /// Opaque yellow color.
229     static const Color YELLOW;
230     /// Transparent color (black with no alpha).
231     static const Color TRANSPARENT;
232 
233 protected:
234     /// Return hue value given greatest and least RGB component, value-wise.
235     float Hue(float min, float max) const;
236     /// Return saturation (HSV) given greatest and least RGB component, value-wise.
237     float SaturationHSV(float min, float max) const;
238     /// Return saturation (HSL) given greatest and least RGB component, value-wise.
239     float SaturationHSL(float min, float max) const;
240     /// Calculate and set RGB values. Convenience function used by FromHSV and FromHSL to avoid code duplication.
241     void FromHCM(float h, float c, float m);
242 };
243 
244 /// Multiply Color with a scalar.
245 inline Color operator *(float lhs, const Color& rhs) { return rhs * lhs; }
246 
247 }
248