1 /* === S Y N F I G ========================================================= */
2 /*!	\file color.h
3 **	\brief Color Class
4 **
5 **	$Id$
6 **
7 **	\legal
8 **	Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **	Copyright (c) 2007, 2008 Chris Moore
10 **	Copyright (c) 2012-2013 Carlos López
11 **  Copyright (c) 2015 Diego Barrios Romero
12 **
13 **	This package is free software; you can redistribute it and/or
14 **	modify it under the terms of the GNU General Public License as
15 **	published by the Free Software Foundation; either version 2 of
16 **	the License, or (at your option) any later version.
17 **
18 **	This package is distributed in the hope that it will be useful,
19 **	but WITHOUT ANY WARRANTY; without even the implied warranty of
20 **	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 **	General Public License for more details.
22 **	\endlegal
23 */
24 /* ========================================================================= */
25 
26 #ifndef __SYNFIG_COLOR_COLOR_H
27 #define __SYNFIG_COLOR_COLOR_H
28 
29 #include <synfig/color/common.h>
30 
31 namespace synfig {
32 
33 class CairoColor;
34 
35 /*!	\class Color
36 **	\ RGBA 128 bits Color class implementation
37 **	Future optimizations: lookup table for sqrt()?
38 */
39 class Color
40 {
41 public:
42 	typedef ColorReal value_type;
43 
44 private:
45 	value_type r_, g_, b_, a_;
46 
47 public:
48 
49 	static const value_type ceil;
50 	static const value_type floor;
51 
52 	const String get_string(void) const;
53 
54 	inline Color &	operator+= (const Color &rhs);
55     inline Color &	operator-= (const Color &rhs);
56 	inline Color &	operator*= (const float &rhs);
57 	inline Color &	operator/= (const float &rhs);
58 
59 	inline Color operator+ (const Color &rhs) const;
60 	inline Color operator- (const Color &rhs) const;
61 	inline Color operator* (const float &rhs) const;
62 	inline Color operator/ (const float &rhs) const;
63 	inline bool operator<  (const Color &rhs)const;
64 	inline bool operator== (const Color &rhs) const;
65 	inline bool operator!= (const Color &rhs) const;
66 	inline Color operator- () const;
67 	//! Effectively 1.0-color
68 	inline Color operator~() const;
69 
70 	inline bool is_valid() const;
71 
72 	inline Color premult_alpha() const;
73 	inline Color demult_alpha() const;
74 
75 public:
76 	// ETL/trunk/ETL/_gaussian.h does:
77 	//   SR1=SR2=SR3=typename T::value_type();
78 	// and expects that to give it initialized colors
79 	// Otherwise the 'gaussian' blur type is random.
80 	inline Color();
81 	explicit inline Color(const value_type &f);
82 	explicit inline Color(int f);
83 
84 	/*!	\param R Red
85 	**	\param G Green
86 	**	\param B Blue
87 	**	\param A Opacity(alpha) */
88 	inline Color(const value_type& R, const value_type& G,
89           const value_type& B, const value_type& A=1);
90 
91 	/*!	\param c Source for color components
92 	**	\param A Opacity(alpha) */
93 	inline Color(const Color& c, const value_type& A);
94 
95 	//!	Copy constructor
96 	inline Color(const Color& c);
97 
98 	//! Convert from CairoColor to Color
99 	inline Color(const CairoColor& c);
100 
101 #ifdef USE_HALF_TYPE
102 	friend class ColorAccumulator;
103 	//!	Convert constructor
104 	inline Color(const ColorAccumulator& c);
105 #endif
106 
107 	//!	Copy constructor
108 	//Color(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); }
109 
110 	/*const Color &operator=(const value_type &i)
111 	{
112 		r_ = g_ = b_ = a_ = i;
113 		return *this;
114 	}*/
115 	//Color& operator=(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); return *this; }
116 
117 	//! Returns the RED component
get_r()118 	const value_type& get_r()const { return r_; }
119 
120 	//! Returns the GREEN component
get_g()121 	const value_type& get_g()const { return g_; }
122 
123 	//! Returns the BLUE component
get_b()124 	const value_type& get_b()const { return b_; }
125 
126 	//! Returns the amount of opacity (alpha)
get_a()127 	const value_type& get_a()const { return a_; }
128 
129 	//! Synonym for get_a(). \see get_a()
get_alpha()130 	const value_type& get_alpha()const { return get_a(); }
131 
132 	//! Converts a 2 character hex string \a s (00-ff) into a ColorReal (0.0-1.0)
133 	static ColorReal hex2real(String s);
134 
135 	//! Converts a ColorReal \a c (0.0-1.0) into a 2 character hex string (00-ff)
136 	static const String real2hex(ColorReal c);
137 
138 	//! Returns the color as a 6 character hex sting
139 	inline const String get_hex()const;
140 
141 	//! Sets the color's R, G, and B from a 3 or 6 character hex string
142 	void set_hex(String& hex);
143 
144 	//! Sets the RED component to \a x
set_r(const value_type & x)145 	Color& set_r(const value_type& x) { r_ = x; return *this; }
146 
147 	//! Sets the GREEN component to \a x
set_g(const value_type & x)148 	Color& set_g(const value_type& x) { g_ = x; return *this; }
149 
150 	//! Sets the BLUE component to \a x
set_b(const value_type & x)151 	Color& set_b(const value_type& x) { b_ = x; return *this; }
152 
153 	//! Sets the opacity (alpha) to \a x
set_a(const value_type & x)154 	Color& set_a(const value_type& x) { a_ = x; return *this; }
155 
156 	//! Synonym for set_a(). \see set_a()
set_alpha(const value_type & x)157 	Color& set_alpha(const value_type& x) { return set_a(x); }
158 
159 	//! Returns color's luminance
160 	inline float get_y() const;
161 
162 	//! Returns U component of chromanance
163 	inline float get_u() const;
164 
165 	//! Returns V component of chromanance
166 	inline float get_v() const;
167 
168 	//! Returns the color's saturation
169 	/*!	This is is the magnitude of the U and V components.
170 	**	\see set_s() */
171 	inline float get_s() const;
172 
173 	//! Sets the luminance (\a y) and chromanance (\a u and \a v)
174 	inline Color& set_yuv(const float &y, const float &u, const float &v);
175 
176 	//! Sets color luminance
177 	inline Color& set_y(const float &y);
178 
179 	//! Set U component of chromanance
180 	inline Color& set_u(const float &u);
181 
182 	//! Set V component of chromanance
183 	inline Color& set_v(const float &v);
184 
185 	//! Set the U and V components of chromanance
186 	inline Color& set_uv(const float& u, const float& v);
187 
188 	//! Sets the color's saturation
189 	/*!	\see get_s() */
190 	inline Color& set_s(const float &x);
191 
192 	//! YUV Color constructor
193 	inline static Color YUV(const float& y, const float& u,
194                      const float& v, const value_type& a=1);
195 
196 	//! Returns the hue of the chromanance
197 	/*!	This is the angle of the U and V components.
198 	**	\see set_hue() */
199 	inline Angle get_hue() const;
200 
201 	//! Synonym for get_hue(). \see get_hue()
202 	inline Angle get_uv_angle() const;
203 
204 	//! Sets the color's hue
205 	/*!	\see get_hue() */
206 	inline Color& set_hue(const Angle& theta);
207 
208 	//! Synonym for set_hue(). \see set_hue()
209 	inline Color& set_uv_angle(const Angle& theta);
210 
211 	//! Rotates the chromanance vector by amount specified by \a theta
212 	inline Color& rotate_uv(const Angle& theta);
213 
214 	//! Sets the luminance (\a y) and chromanance (\a s and \a theta).
215 	/*!	\param y Luminance
216 	**	\param s Saturation
217 	**	\param theta Hue */
218 	inline Color& set_yuv(const float& y, const float& s, const Angle& theta);
219 
220 	//! YUV color constructor where the chroma is in the saturation/hue form.
221 	/*!	\param y Luminance
222 	**	\param s Saturation
223 	**	\param theta Hue
224 	**	\param a Opacity (alpha) */
225 	inline static Color YUV(const float& y,
226                      const float& s,
227                      const Angle& theta,
228                      const value_type& a=1);
229 
230 
231 	//! Clamps a color so that its values are in range. Ignores attempting to visualize negative colors.
232     Color clamped() const;
233 
234 	//! Clamps a color so that its values are in range.
235     Color clamped_negative() const;
236 
237 	/* Preset Colors */
238 
239 	//! Preset Color Constructors
240 	//@{
241 #ifdef HAS_VIMAGE
alpha()242 	static inline Color alpha() { return Color(0,0,0,0.0000001f); }
243 #else
alpha()244 	static inline Color alpha() { return Color(0,0,0,0); }
245 #endif
black()246 	static inline Color black() { return Color(0,0,0); }
white()247 	static inline Color white() { return Color(1,1,1); }
gray()248 	static inline Color gray() { return Color(0.5f,0.5f,0.5f); }
magenta()249 	static inline Color magenta() { return Color(1,0,1); }
red()250 	static inline Color red() { return Color(1,0,0); }
green()251 	static inline Color green() { return Color(0,1,0); }
blue()252 	static inline Color blue() { return Color(0,0,1); }
cyan()253 	static inline Color cyan() { return Color(0,1,1); }
yellow()254 	static inline Color yellow() { return Color(1,1,0); }
255 	//@}
256 
257 	enum Interpolation
258 	{
259 		INTERPOLATION_NEAREST = 0,
260 		INTERPOLATION_LINEAR = 1,
261 		INTERPOLATION_COSINE = 2,
262 		INTERPOLATION_CUBIC = 3
263 	};
264 
265 	enum {
266 		INTERPOLATION_COUNT = 4
267 	};
268 
269 	//! \writeme
270 	enum BlendMethod
271 	{
272 		BLEND_COMPOSITE=0,			//!< Color A is composited onto B (Taking A's alpha into account)
273 		BLEND_STRAIGHT=1,			//!< Straight linear interpolation from A->B (Alpha ignored)
274 		BLEND_ONTO=13,				//!< Similar to BLEND_COMPOSITE, except that B's alpha is maintained
275 		BLEND_STRAIGHT_ONTO=21,		//!< \deprecated \writeme
276 		BLEND_BEHIND=12,			//!< Similar to BLEND_COMPOSITE, except that B is composited onto A.
277 		BLEND_SCREEN=16,			//!< \writeme
278 		BLEND_OVERLAY=20,			//!< \writeme
279 		BLEND_HARD_LIGHT=17,		//!< \writeme
280 		BLEND_MULTIPLY=6,			//!< Simple A*B.
281 		BLEND_DIVIDE=7,				//!< Simple B/A
282 		BLEND_ADD=4,				//!< Simple A+B.
283 		BLEND_SUBTRACT=5,			//!< Simple A-B.
284 		BLEND_DIFFERENCE=18,		//!< Simple |A-B|.
285 		BLEND_BRIGHTEN=2,			//!< If composite is brighter than B, use composite. B otherwise.
286 		BLEND_DARKEN=3,				//!< If composite is darker than B, use composite. B otherwise.
287 		BLEND_COLOR=8,				//!< Preserves the U and V channels of color A
288 		BLEND_HUE=9,				//!< Preserves the angle of the UV vector of color A
289 		BLEND_SATURATION=10,		//!< Preserves the magnitude of the UV Vector of color A
290 		BLEND_LUMINANCE=11,			//!< Preserves the Y channel of color A
291 
292 		BLEND_ALPHA_BRIGHTEN=14,	//!< \deprecated If A is less opaque than B, use A
293 		BLEND_ALPHA_DARKEN=15,		//!< \deprecated If A is more opaque than B, use B
294 		BLEND_ALPHA_OVER=19,		//!< \deprecated multiply alphas and then straight blends using the amount
295 
296 		BLEND_END=22,				//!< \internal
297 		BLEND_BY_LAYER=999			//! Used to let the layer decides what Blend Method use by
298 									//! default when the layer is created
299 	};
300 
301 	typedef unsigned int BlendMethodFlags;
302 
303 	enum {
304 		BLEND_METHODS_ONTO = 0
305 			| (1 << BLEND_BRIGHTEN)
306 			| (1 << BLEND_DARKEN)
307 			| (1 << BLEND_MULTIPLY)
308 			| (1 << BLEND_DIVIDE)
309 			| (1 << BLEND_COLOR)
310 			| (1 << BLEND_HUE)
311 			| (1 << BLEND_SATURATION)
312 			| (1 << BLEND_LUMINANCE)
313 			| (1 << BLEND_ONTO)
314 			| (1 << BLEND_STRAIGHT_ONTO)
315 			| (1 << BLEND_SCREEN)
316 			| (1 << BLEND_OVERLAY)
317 			| (1 << BLEND_HARD_LIGHT),
318 
319 		BLEND_METHODS_STRAIGHT = 0
320 			| (1 << BLEND_STRAIGHT)
321 			| (1 << BLEND_STRAIGHT_ONTO)
322 			| (1 << BLEND_ALPHA_BRIGHTEN),
323 
324 		BLEND_METHODS_OVERWRITE_ON_ALPHA_ONE = 0
325 			| (1 << BLEND_COMPOSITE),
326 
327 		BLEND_METHODS_ASSOCIATIVE = 0
328 			| (1 << BLEND_COMPOSITE)
329 			| (1 << BLEND_ADD)
330 			| (1 << BLEND_BEHIND)
331 			| (1 << BLEND_ALPHA_DARKEN),
332 
333 		BLEND_METHODS_COMMUTATIVE = 0
334 			| (1 << BLEND_ADD),
335 
336 		BLEND_METHODS_ALL = (1 << BLEND_END) - 1
337 	};
338 
339 	/* Other */
340 	static Color blend(Color a, Color b,float amount,BlendMethod type=BLEND_COMPOSITE);
341 
is_onto(BlendMethod x)342 	static bool is_onto(BlendMethod x)
343 		{ return BLEND_METHODS_ONTO & (1 << x); }
344 
345 	//! a blending method is considered 'straight' if transparent pixels in the upper layer can affect the result of the blend
is_straight(BlendMethod x)346 	static bool is_straight(BlendMethod x)
347 		{ return BLEND_METHODS_STRAIGHT & (1 << x); }
348 
349 /*protected:
350 
351 	value_type& operator[](const int i)
352 	{
353 		assert(i>=0);
354 		assert(i<(signed)(sizeof(Color)/sizeof(value_type)));
355 		return (&r_)[i];
356 	}
357 
358 	const value_type& operator[](const int i)const
359 	{
360 		assert(i>=0);
361 		assert(i<(signed)(sizeof(Color)/sizeof(value_type)));
362 		return (&r_)[i];
363 	}
364 */
365 }; // END of class Color
366 
367 } // synfig namespace
368 
369 #include "color.hpp"
370 
371 #endif // __SYNFIG_COLOR_COLOR_H
372 
373