X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftrunk%2Fsrc%2Fsynfig%2Fcolor.h;h=d54b0e942ed69966b7e92efbb5c4c423e7a1799d;hb=9459638ad6797b8139f1e9f0715c96076dbf0890;hp=868420ba7dd9ed576060a94c0f2c8f274d2034b5;hpb=28f28705612902c15cd0702cc891fba35bf2d2df;p=synfig.git diff --git a/synfig-core/trunk/src/synfig/color.h b/synfig-core/trunk/src/synfig/color.h index 868420b..d54b0e9 100644 --- a/synfig-core/trunk/src/synfig/color.h +++ b/synfig-core/trunk/src/synfig/color.h @@ -2,19 +2,21 @@ /*! \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 Robert B. Quattlebaum Jr. +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2007, 2008 Chris Moore ** -** This software and associated documentation -** are CONFIDENTIAL and PROPRIETARY property of -** the above-mentioned copyright holder. +** This package is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License as +** published by the Free Software Foundation; either version 2 of +** the License, or (at your option) any later version. ** -** You may not copy, print, publish, or in any -** other way distribute this software without -** a prior written agreement with -** the copyright holder. +** This package is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. ** \endlegal */ /* ========================================================================= */ @@ -26,23 +28,27 @@ /* === H E A D E R S ======================================================= */ -#ifndef SYNFIG_NO_ANGLE -# include "angle.h" -#endif //#include #include #include #include "gamma.h" -#include +#include #ifdef USE_HALF_TYPE #include #endif +#ifndef SYNFIG_NO_ANGLE +# include "angle.h" +#endif + /* === M A C R O S ========================================================= */ -#ifndef isnan +#define use_colorspace_gamma() App::use_colorspace_gamma +#define colorspace_gamma() (2.2f) +#define gamma_in(x) ((x>=0) ? pow((float)x,1.0f/colorspace_gamma()) : -pow((float)-x,1.0f/colorspace_gamma())) +#define gamma_out(x) ((x>=0) ? pow((float)x, colorspace_gamma()) : -pow((float)-x, colorspace_gamma())) #ifdef WIN32 #include @@ -52,10 +58,15 @@ extern "C" { int _isnan(double x); } #endif #endif -#ifdef __APPLE__ -#define isnan __isnanf +// For some reason isnan() isn't working on macosx any more. +// This is a quick fix. +#if defined(__APPLE__) && !defined(SYNFIG_ISNAN_FIX) +#ifdef isnan +#undef isnan #endif - +inline bool isnan(double x) { return x != x; } +inline bool isnan(float x) { return x != x; } +#define SYNFIG_ISNAN_FIX 1 #endif namespace synfig { @@ -105,6 +116,8 @@ private: public: + const String get_string(void)const; + Color & operator+=(const Color &rhs) { @@ -181,12 +194,12 @@ 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_) @@ -197,7 +210,11 @@ public: } public: - Color() /*:r_(0), g_(0), b_(0), a_(0)*/ { } + // ETL/trunk/ETL/_gaussian.h does: + // SR1=SR2=SR3=typename T::value_type(); + // and expects that to give it initialized colors + // Otherwise the 'gaussian' blur type is random. + Color() :a_(0), r_(0), g_(0), b_(0) { } Color(const value_type &f) :a_(f),r_(f), g_(f), b_(f) { } Color(int f) :a_(f),r_(f), g_(f), b_(f) { } @@ -211,22 +228,22 @@ public: 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 @@ -242,7 +259,7 @@ public: 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_; } @@ -254,10 +271,22 @@ public: //! 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 String(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; } @@ -269,7 +298,7 @@ public: //! 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); } @@ -283,7 +312,7 @@ public: (float)get_b()*EncodeYUV[0][2]; } - + //! Returns U component of chromanance float get_u() const @@ -327,16 +356,16 @@ public: //! 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& @@ -344,7 +373,7 @@ public: { 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; @@ -367,7 +396,7 @@ public: //! Synonym for get_hue(). \see get_hue() Angle get_uv_angle() const { return get_hue(); } - + //! Sets the color's hue /*! \see get_hue() */ Color& @@ -382,16 +411,16 @@ public: //! 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 @@ -418,7 +447,7 @@ public: //! 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; @@ -441,41 +470,40 @@ public: static inline Color cyan() { return Color(0,1,1); } static inline Color yellow() { return Color(1,1,0); } //@} - + //! \writeme enum BlendMethod { - BLEND_COMPOSITE=0, //!< Color A is composited onto B (Taking into about A's alpha) - BLEND_STRAIGHT=1, //!< Straight linear interpolation from A->B (Alpha ignored) - BLEND_BRIGHTEN=2, //!< If composite is brighter than B, use composite. B otherwise. - BLEND_DARKEN=3, //!< If composite is brighter than B, use composite. B otherwise. - BLEND_ADD=4, //!< Simple A+B. - BLEND_SUBTRACT=5, //!< Simple A-B. - BLEND_MULTIPLY=6, //!< Simple A*B. - BLEND_DIVIDE=7, //!< Simple B/A - BLEND_COLOR=8, //!< Preserves the U and V channels of color A - BLEND_HUE=9, //!< Preserves the angle of the UV vector of color A - BLEND_SATURATION=10,//!< Preserves the magnitude of the UV Vector of color A - BLEND_LUMINANCE=11, //!< Preserves the Y channel of color A - BLEND_BEHIND=12, //!< Similar to BLEND_COMPOSITE, except that B is composited onto A. - BLEND_ONTO=13, //!< Similar to BLEND_COMPOSITE, except that B's alpha is maintained - BLEND_SCREEN=16, //!< \writeme - BLEND_OVERLAY=20, //!< \writeme - BLEND_DIFFERENCE=18, //!< \writeme + BLEND_COMPOSITE=0, //!< Color A is composited onto B (Taking A's alpha into account) + BLEND_STRAIGHT=1, //!< Straight linear interpolation from A->B (Alpha ignored) + BLEND_ONTO=13, //!< Similar to BLEND_COMPOSITE, except that B's alpha is maintained + BLEND_STRAIGHT_ONTO=21, //!< \deprecated \writeme + BLEND_BEHIND=12, //!< Similar to BLEND_COMPOSITE, except that B is composited onto A. + BLEND_SCREEN=16, //!< \writeme + BLEND_OVERLAY=20, //!< \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 + BLEND_MULTIPLY=6, //!< Simple A*B. + BLEND_DIVIDE=7, //!< Simple B/A + BLEND_ADD=4, //!< Simple A+B. + BLEND_SUBTRACT=5, //!< Simple A-B. + BLEND_DIFFERENCE=18, //!< Simple |A-B|. + BLEND_BRIGHTEN=2, //!< If composite is brighter than B, use composite. B otherwise. + BLEND_DARKEN=3, //!< If composite is darker than B, use composite. B otherwise. + BLEND_COLOR=8, //!< Preserves the U and V channels of color A + BLEND_HUE=9, //!< Preserves the angle of the UV vector of color A + BLEND_SATURATION=10, //!< Preserves the magnitude of the UV Vector of color A + BLEND_LUMINANCE=11, //!< Preserves the Y channel of color A + + BLEND_ALPHA_BRIGHTEN=14, //!< \deprecated If A is less opaque than B, use A + BLEND_ALPHA_DARKEN=15, //!< \deprecated If A is more opaque than B, use B + BLEND_ALPHA_OVER=19, //!< \deprecated multiply alphas and then straight blends using the amount + + 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 @@ -496,6 +524,15 @@ public: || x==BLEND_HARD_LIGHT ; } + + //! a blending method is considered 'straight' if transparent pixels in the upper layer can affect the result of the blend + static bool is_straight(BlendMethod x) + { + return x==BLEND_STRAIGHT + || x==BLEND_STRAIGHT_ONTO + || x==BLEND_ALPHA_BRIGHTEN + ; + } /*protected: value_type& operator[](const int i) @@ -627,6 +664,9 @@ public: 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_; } @@ -638,7 +678,7 @@ public: //! 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(); } @@ -653,7 +693,7 @@ public: //! 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); } }; @@ -681,7 +721,7 @@ enum PixelFormat ** 3 Endian (BGR/RGB) ** 4 Alpha Location (Start/End) ** 5 ZDepth Location (Start/End) -** 6 Alpha/ZDepth Arangement (ZA,AZ) +** 6 Alpha/ZDepth Arrangement (ZA,AZ) ** 7 Alpha Range (Inverted,Normal) ** 8 Z Range (Inverted,Normal) */ @@ -692,16 +732,16 @@ enum PixelFormat PF_BGR=(1<<3), //!< If set, reverse the order of the RGB channels PF_A_START=(1<<4), //!< If set, alpha channel is before the color data. If clear, it is after. PF_Z_START=(1<<5), //!< If set, ZDepth channel is before the color data. If clear, it is after. - PF_ZA=(1<<6), //!< If set, the ZDepth channel will be infront of the alpha channel. If clear, they are reversed. + PF_ZA=(1<<6), //!< If set, the ZDepth channel will be in front of the alpha channel. If clear, they are reversed. PF_A_INV=(1<<7), //!< If set, the alpha channel is stored as 1.0-a PF_Z_INV=(1<<8), //!< If set, the ZDepth channel is stored as 1.0-z - PF_RAW_COLOR=(1<<9)+(1<<1) //!< If set, the data represents a raw Color datastructure, and all other bits are ignored. + PF_RAW_COLOR=(1<<9)+(1<<1) //!< If set, the data represents a raw Color data structure, and all other bits are ignored. }; inline PixelFormat operator|(PixelFormat lhs, PixelFormat rhs) { return static_cast((int)lhs|(int)rhs); } - + inline PixelFormat operator&(PixelFormat lhs, PixelFormat rhs) { return static_cast((int)lhs&(int)rhs); } #define FLAGS(x,y) (((x)&(y))==(y)) @@ -721,7 +761,7 @@ channels(PixelFormat x) ++chan; if(FLAGS(x,PF_RAW_COLOR)) chan=sizeof(Color); - + return chan; } @@ -739,7 +779,7 @@ Color2PixelFormat(const Color &color, const PixelFormat &pf, unsigned char *out, 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)) @@ -753,7 +793,7 @@ Color2PixelFormat(const Color &color, const PixelFormat &pf, unsigned char *out, *out++=static_cast(alpha); if(FLAGS(pf,PF_Z_START)) *out++/*=(unsigned char)(color.GetZ()*255.0f)*/; - + } if(FLAGS(pf,PF_GRAY)) @@ -773,7 +813,7 @@ Color2PixelFormat(const Color &color, const PixelFormat &pf, unsigned char *out, *out++=static_cast(gamma.b_F32_to_U8(color.get_b())); } } - + if(FLAGS(pf,PF_ZA)) { if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z)) @@ -834,7 +874,7 @@ PixelFormat2Color(Color &color, const PixelFormat &pf,const unsigned char *out) color.set_b((float)*out++/255); } } - + if(FLAGS(pf,PF_ZA)) { if(!FLAGS(pf,PF_Z_START) && FLAGS(pf,PF_Z))