|  |  | @@ -22,51 +22,66 @@ START_NAMESPACE_DGL | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // ----------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color::Color() noexcept | 
		
	
		
			
			|  |  |  | : red(1.0f), green(1.0f), blue(1.0f), alpha(1.0f) {} | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color::Color(const int r, const int g, const int b, const int a) noexcept | 
		
	
		
			
			|  |  |  | : red(static_cast<float>(r)/255.0f), green(static_cast<float>(g)/255.0f), blue(static_cast<float>(b)/255.0f), alpha(static_cast<float>(a)/255.0f) {} | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color::Color(const float r, const float g, const float b, const float a) noexcept | 
		
	
		
			
			|  |  |  | : red(r), green(g), blue(b), alpha(a) {} | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color::Color(const Color& color) noexcept | 
		
	
		
			
			|  |  |  | : red(color.red), green(color.green), blue(color.blue), alpha(color.alpha) {} | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color::Color(const Color& color1, const Color& color2, const float u) noexcept | 
		
	
		
			
			|  |  |  | : red(color1.red), green(color1.green), blue(color1.blue), alpha(color1.alpha) | 
		
	
		
			
			|  |  |  | static void fixRange(float& value) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | interpolate(color2, u); | 
		
	
		
			
			|  |  |  | /**/ if (value < 0.0f) | 
		
	
		
			
			|  |  |  | value = 0.0f; | 
		
	
		
			
			|  |  |  | else if (value > 1.0f) | 
		
	
		
			
			|  |  |  | value = 1.0f; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | void Color::interpolate(const Color& other, const float u) noexcept | 
		
	
		
			
			|  |  |  | static float getFixedRange(const float& value) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const float u2 = (u < 0.0f) ? 0.0f : ((u > 1.0f) ? 1.0f : u); | 
		
	
		
			
			|  |  |  | const float oneMinusU = 1.0f - u; | 
		
	
		
			
			|  |  |  | if (value <= 0.0f) | 
		
	
		
			
			|  |  |  | return 0.0f; | 
		
	
		
			
			|  |  |  | if (value >= 1.0f) | 
		
	
		
			
			|  |  |  | return 1.0f; | 
		
	
		
			
			|  |  |  | return value; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | red   = red   * oneMinusU + other.red   * u2; | 
		
	
		
			
			|  |  |  | green = green * oneMinusU + other.green * u2; | 
		
	
		
			
			|  |  |  | blue  = blue  * oneMinusU + other.blue  * u2; | 
		
	
		
			
			|  |  |  | alpha = alpha * oneMinusU + other.alpha * u2; | 
		
	
		
			
			|  |  |  | static uchar getFixedRange2(const float& value) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const float value2(getFixedRange(value)*255.0f); | 
		
	
		
			
			|  |  |  | if (value2 <= 0.0f) | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | if (value2 >= 255.0f) | 
		
	
		
			
			|  |  |  | return 255; | 
		
	
		
			
			|  |  |  | return static_cast<uchar>(value2); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color Color::HSL(const float hue, const float saturation, const float lightness, const int alpha) | 
		
	
		
			
			|  |  |  | // ----------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color::Color() noexcept | 
		
	
		
			
			|  |  |  | : red(1.0f), | 
		
	
		
			
			|  |  |  | green(1.0f), | 
		
	
		
			
			|  |  |  | blue(1.0f), | 
		
	
		
			
			|  |  |  | alpha(1.0f) {} | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color::Color(int r, int g, int b, int a) noexcept | 
		
	
		
			
			|  |  |  | : red(static_cast<float>(r)/255.0f), | 
		
	
		
			
			|  |  |  | green(static_cast<float>(g)/255.0f), | 
		
	
		
			
			|  |  |  | blue(static_cast<float>(b)/255.0f), | 
		
	
		
			
			|  |  |  | alpha(static_cast<float>(a)/255.0f) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | return nvgHSLA(hue, saturation, lightness, alpha); | 
		
	
		
			
			|  |  |  | fixBounds(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color::Color(const NVGcolor& c) noexcept | 
		
	
		
			
			|  |  |  | : red(c.r), green(c.g), blue(c.b), alpha(c.a) {} | 
		
	
		
			
			|  |  |  | Color::Color(float r, float g, float b, float a) noexcept | 
		
	
		
			
			|  |  |  | : red(r), | 
		
	
		
			
			|  |  |  | green(g), | 
		
	
		
			
			|  |  |  | blue(b), | 
		
	
		
			
			|  |  |  | alpha(a) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | fixBounds(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color::operator NVGcolor() const noexcept | 
		
	
		
			
			|  |  |  | Color::Color(const Color& color) noexcept | 
		
	
		
			
			|  |  |  | : red(color.red), | 
		
	
		
			
			|  |  |  | green(color.green), | 
		
	
		
			
			|  |  |  | blue(color.blue), | 
		
	
		
			
			|  |  |  | alpha(color.alpha) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | NVGcolor nc; | 
		
	
		
			
			|  |  |  | nc.r = red; | 
		
	
		
			
			|  |  |  | nc.g = green; | 
		
	
		
			
			|  |  |  | nc.b = blue; | 
		
	
		
			
			|  |  |  | nc.a = alpha; | 
		
	
		
			
			|  |  |  | return nc; | 
		
	
		
			
			|  |  |  | fixBounds(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color& Color::operator=(const Color& color) noexcept | 
		
	
	
		
			
				|  |  | @@ -75,17 +90,111 @@ Color& Color::operator=(const Color& color) noexcept | 
		
	
		
			
			|  |  |  | green = color.green; | 
		
	
		
			
			|  |  |  | blue  = color.blue; | 
		
	
		
			
			|  |  |  | alpha = color.alpha; | 
		
	
		
			
			|  |  |  | fixBounds(); | 
		
	
		
			
			|  |  |  | return *this; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color::Color(const Color& color1, const Color& color2, float u) noexcept | 
		
	
		
			
			|  |  |  | : red(color1.red), | 
		
	
		
			
			|  |  |  | green(color1.green), | 
		
	
		
			
			|  |  |  | blue(color1.blue), | 
		
	
		
			
			|  |  |  | alpha(color1.alpha) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | interpolate(color2, u); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color Color::fromHSL(float hue, float saturation, float lightness, float alpha) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | return nvgHSLA(hue, saturation, lightness, static_cast<uchar>(getFixedRange(alpha)*255.0f)); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | void Color::interpolate(const Color& other, float u) noexcept | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | fixRange(u); | 
		
	
		
			
			|  |  |  | const float oneMinusU(1.0f - u); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | red   = red   * oneMinusU + other.red   * u; | 
		
	
		
			
			|  |  |  | green = green * oneMinusU + other.green * u; | 
		
	
		
			
			|  |  |  | blue  = blue  * oneMinusU + other.blue  * u; | 
		
	
		
			
			|  |  |  | alpha = alpha * oneMinusU + other.alpha * u; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | fixBounds(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // ----------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | bool Color::isEqual(const Color& color, bool withAlpha) noexcept | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const uchar r1 = getFixedRange2(rgba[0]); | 
		
	
		
			
			|  |  |  | const uchar g1 = getFixedRange2(rgba[1]); | 
		
	
		
			
			|  |  |  | const uchar b1 = getFixedRange2(rgba[2]); | 
		
	
		
			
			|  |  |  | const uchar a1 = getFixedRange2(rgba[3]); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | const uchar r2 = getFixedRange2(color.rgba[0]); | 
		
	
		
			
			|  |  |  | const uchar g2 = getFixedRange2(color.rgba[1]); | 
		
	
		
			
			|  |  |  | const uchar b2 = getFixedRange2(color.rgba[2]); | 
		
	
		
			
			|  |  |  | const uchar a2 = getFixedRange2(color.rgba[3]); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (withAlpha) | 
		
	
		
			
			|  |  |  | return (r1 == r2 && g1 == g2 && b1 == b2 && a1 == a2); | 
		
	
		
			
			|  |  |  | else | 
		
	
		
			
			|  |  |  | return (r1 == r2 && g1 == g2 && b1 == b2); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | bool Color::isNotEqual(const Color& color, bool withAlpha) noexcept | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const uchar r1 = getFixedRange2(rgba[0]); | 
		
	
		
			
			|  |  |  | const uchar g1 = getFixedRange2(rgba[1]); | 
		
	
		
			
			|  |  |  | const uchar b1 = getFixedRange2(rgba[2]); | 
		
	
		
			
			|  |  |  | const uchar a1 = getFixedRange2(rgba[3]); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | const uchar r2 = getFixedRange2(color.rgba[0]); | 
		
	
		
			
			|  |  |  | const uchar g2 = getFixedRange2(color.rgba[1]); | 
		
	
		
			
			|  |  |  | const uchar b2 = getFixedRange2(color.rgba[2]); | 
		
	
		
			
			|  |  |  | const uchar a2 = getFixedRange2(color.rgba[3]); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (withAlpha) | 
		
	
		
			
			|  |  |  | return (r1 != r2 || g1 != g2 || b1 != b2 || a1 != a2); | 
		
	
		
			
			|  |  |  | else | 
		
	
		
			
			|  |  |  | return (r1 != r2 || g1 != g2 || b1 != b2); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | bool Color::operator==(const Color& color) noexcept | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | return (red == color.red && green == color.green && blue == color.blue && alpha == color.alpha); | 
		
	
		
			
			|  |  |  | return isEqual(color, true); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | bool Color::operator!=(const Color& color) noexcept | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | return (red != color.red || green != color.green || blue != color.blue || alpha != color.alpha); | 
		
	
		
			
			|  |  |  | return isNotEqual(color, true); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // ----------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | void Color::fixBounds() noexcept | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | fixRange(red); | 
		
	
		
			
			|  |  |  | fixRange(green); | 
		
	
		
			
			|  |  |  | fixRange(blue); | 
		
	
		
			
			|  |  |  | fixRange(alpha); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // ----------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color::Color(const NVGcolor& c) noexcept | 
		
	
		
			
			|  |  |  | : red(c.r), green(c.g), blue(c.b), alpha(c.a) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | fixBounds(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | Color::operator NVGcolor() const noexcept | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | NVGcolor nc; | 
		
	
		
			
			|  |  |  | nc.r = red; | 
		
	
		
			
			|  |  |  | nc.g = green; | 
		
	
		
			
			|  |  |  | nc.b = blue; | 
		
	
		
			
			|  |  |  | nc.a = alpha; | 
		
	
		
			
			|  |  |  | return nc; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // ----------------------------------------------------------------------- | 
		
	
	
		
			
				|  |  | 
 |