/*! \file color.h
** \brief Color Class Implementation
**
-** $Id: color.h,v 1.1.1.1 2005/01/04 01:23:14 darco Exp $
+** $Id$
**
** \legal
** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
#include <math.h>
#include <cassert>
#include "gamma.h"
-#include <string.h>
+#include <synfig/string.h>
#ifdef USE_HALF_TYPE
#include <OpenEXR/half.h>
private:
value_type a_, r_, g_, b_;
+ static String hex_;
public:
bool is_valid()const
{ return !isnan(r_) && !isnan(g_) && !isnan(b_) && !isnan(a_); }
-
+
Color premult_alpha() const
{
return Color (r_*a_, g_*a_, b_*a_, a_);
}
-
+
Color demult_alpha() const
{
if(a_)
g_(G),
b_(B) { }
- /*! \param C Source for color components
+ /*! \param c Source for color components
** \param A Opacity(alpha) */
Color(const Color& c, const value_type& A):
- a_(c.a_),
+ a_(A),
r_(c.r_),
g_(c.g_),
b_(c.b_) { }
-
+
//! Copy constructor
Color(const Color& c):
a_(c.a_),
r_(c.r_),
g_(c.g_),
b_(c.b_) { }
-
+
#ifdef USE_HALF_TYPE
friend class ColorAccumulator;
//! Convert constructor
return *this;
}*/
//Color& operator=(const Color &c) { memcpy((void*)this, (const void*)&c, sizeof(Color)); return *this; }
-
+
//! Returns the RED component
const value_type& get_r()const { return r_; }
//! Returns the amount of opacity (alpha)
const value_type& get_a()const { return a_; }
-
+
//! Synonym for get_a(). \see get_a()
const value_type& get_alpha()const { return get_a(); }
+ //! Converts a 2 character hex string \a s (00-ff) into a ColorReal (0.0-1.0)
+ static ColorReal hex2real(String s);
+
+ //! Converts a ColorReal \a c (0.0-1.0) into a 2 character hex string (00-ff)
+ static const String real2hex(ColorReal c);
+
+ //! Returns the color as a 6 character hex sting
+ const String& get_hex()const { return hex_ = real2hex(r_)+real2hex(g_)+real2hex(b_); }
+
+ //! Sets the color's R, G, and B from a 3 or 6 character hex string
+ void set_hex(String& hex);
+
//! Sets the RED component to \a x
Color& set_r(const value_type& x) { r_ = x; return *this; }
//! Sets the opacity (alpha) to \a x
Color& set_a(const value_type& x) { a_ = x; return *this; }
-
+
//! Synonym for set_a(). \see set_a()
Color& set_alpha(const value_type& x) { return set_a(x); }
(float)get_b()*EncodeYUV[0][2];
}
-
+
//! Returns U component of chromanance
float
get_u() const
//! Sets color luminance
Color& set_y(const float &y) { return set_yuv(y,get_u(),get_v()); }
-
+
//! Set U component of chromanance
Color& set_u(const float &u) { return set_yuv(get_y(),u,get_v()); }
-
+
//! Set V component of chromanance
Color& set_v(const float &v) { return set_yuv(get_y(),get_u(),v); }
-
+
//! Set the U and V components of chromanance
Color& set_uv(const float& u, const float& v) { return set_yuv(get_y(),u,v); }
-
+
//! Sets the color's saturation
/*! \see get_s() */
Color&
{
float u(get_u()), v(get_v());
const float s(sqrt(u*u+v*v));
- if(s)
+ if(s)
{
u=(u/s)*x;
v=(v/s)*x;
//! Synonym for get_hue(). \see get_hue()
Angle get_uv_angle() const { return get_hue(); }
-
+
//! Sets the color's hue
/*! \see get_hue() */
Color&
//! Synonym for set_hue(). \see set_hue()
Color& set_uv_angle(const Angle& theta) { return set_hue(theta); }
-
+
//! Rotates the chromanance vector by amount specified by \a theta
Color& rotate_uv(const Angle& theta)
{
const float a(Angle::sin(theta).get()), b(Angle::cos(theta).get());
const float u(get_u()), v(get_v());
-
+
return set_uv(b*u-a*v,a*u+b*v);
}
-
+
//! Sets the luminance (\a y) and chromanance (\a s and \a theta).
/*! \param y Luminance
** \param s Saturation
//! Clamps a color so that its values are in range. Ignores attempting to visualize negative colors.
Color clamped()const;
-
+
//! Clamps a color so that its values are in range.
Color clamped_negative()const;
static inline Color cyan() { return Color(0,1,1); }
static inline Color yellow() { return Color(1,1,0); }
//@}
-
+
//! \writeme
enum BlendMethod
{
BLEND_OVERLAY=20, //!< \writeme
BLEND_DIFFERENCE=18, //!< \writeme
BLEND_HARD_LIGHT=17, //!< \writeme
-
+
//! Deprecated
BLEND_ALPHA_BRIGHTEN=14, //!< If A is less opaque than B, use A
BLEND_ALPHA_DARKEN=15, //!< If A is more opaque than B, use B
BLEND_ALPHA_OVER=19,//!< multiply alphas and then straight blends that using the amount
BLEND_STRAIGHT_ONTO=21,//!< \writeme
-
+
BLEND_END=22 //!< \internal
};
/* Other */
static Color blend(Color a, Color b,float amount,BlendMethod type=BLEND_COMPOSITE);
-
+
static bool is_onto(BlendMethod x)
{
return x==BLEND_BRIGHTEN
g_(c.g_),
b_(c.b_) { }
+ //! Converter
+ ColorAccumulator(int c): a_(c),r_(c), g_(c), b_(c) { }
+
//! Returns the RED component
const value_type& get_r()const { return r_; }
//! Returns the amount of opacity (alpha)
const value_type& get_a()const { return a_; }
-
+
//! Synonym for get_a(). \see get_a()
const value_type& get_alpha()const { return get_a(); }
//! Sets the opacity (alpha) to \a x
ColorAccumulator& set_a(const value_type& x) { a_ = x; return *this; }
-
+
//! Synonym for set_a(). \see set_a()
ColorAccumulator& set_alpha(const value_type& x) { return set_a(x); }
};
inline PixelFormat operator|(PixelFormat lhs, PixelFormat rhs)
{ return static_cast<PixelFormat>((int)lhs|(int)rhs); }
-
+
inline PixelFormat operator&(PixelFormat lhs, PixelFormat rhs)
{ return static_cast<PixelFormat>((int)lhs&(int)rhs); }
#define FLAGS(x,y) (((x)&(y))==(y))
++chan;
if(FLAGS(x,PF_RAW_COLOR))
chan=sizeof(Color);
-
+
return chan;
}
int alpha=(int)((FLAGS(pf,PF_A_INV)?(-(float)color.get_a()+1):(float)color.get_a())*255);
if(alpha<0)alpha=0;
if(alpha>255)alpha=255;
-
+
if(FLAGS(pf,PF_ZA|PF_A_START|PF_Z_START))
{
if(FLAGS(pf,PF_Z_START))
*out++=static_cast<unsigned char>(alpha);
if(FLAGS(pf,PF_Z_START))
*out++/*=(unsigned char)(color.GetZ()*255.0f)*/;
-
+
}
if(FLAGS(pf,PF_GRAY))
*out++=static_cast<unsigned char>(gamma.b_F32_to_U8(color.get_b()));
}
}
-
+
if(FLAGS(pf,PF_ZA))
{
if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))
color.set_b((float)*out++/255);
}
}
-
+
if(FLAGS(pf,PF_ZA))
{
if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))