X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftrunk%2Fsrc%2Fsynfig%2Fcolor.cpp;h=1dcc314ebe049fe06add9eb84d6d7b953e96fc55;hb=756c0d29ac1742f231e6615f9a577e574e35a4af;hp=2799fc1bbfbec74070901699f18c71aac1385d87;hpb=28f28705612902c15cd0702cc891fba35bf2d2df;p=synfig.git diff --git a/synfig-core/trunk/src/synfig/color.cpp b/synfig-core/trunk/src/synfig/color.cpp index 2799fc1..1dcc314 100644 --- a/synfig-core/trunk/src/synfig/color.cpp +++ b/synfig-core/trunk/src/synfig/color.cpp @@ -1,20 +1,22 @@ /* === S Y N F I G ========================================================= */ -/*! \file color.h +/*! \file color.cpp ** \brief Color Class ** -** $Id: color.cpp,v 1.2 2005/01/23 04:03:21 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 */ /* ========================================================================= */ @@ -31,6 +33,9 @@ #include #include "color.h" #include +#include +#include +#include #endif @@ -50,6 +55,77 @@ using namespace std; +ColorReal +Color::hex2real(String s) +{ + std::istringstream i(s); + int n; + i.fill('0'); + if (!(i >> hex >> n)) + throw String("bad conversion from hex string \"") + s + String("\""); + return n / 255.0f; +} + +const String +Color::real2hex(ColorReal c) +{ + std::ostringstream o; + o.width(2); + o.fill('0'); + if (c<0) c = 0; + if (c>1) c = 1; + o << hex << int(c*255.0f); + return o.str(); +} + +void +Color::set_hex(String& str) +{ + value_type r, g, b; + String hex; + + // use just the hex characters + for (String::const_iterator iter = str.begin(); iter != str.end(); iter++) + if (isxdigit(*iter)) + hex.push_back(*iter); + + try + { + if (hex.size() == 1) + { + r = hex2real(hex.substr(0,1)+hex.substr(0,1)); + r_ = g_ = b_ = r; + } + else if (hex.size() == 3) + { + r = hex2real(hex.substr(0,1)+hex.substr(0,1)); + g = hex2real(hex.substr(1,1)+hex.substr(1,1)); + b = hex2real(hex.substr(2,1)+hex.substr(2,1)); + r_ = r; g_ = g; b_ = b; + } + else if (hex.size() == 6) + { + r = hex2real(hex.substr(0,2)); + g = hex2real(hex.substr(2,2)); + b = hex2real(hex.substr(4,2)); + r_ = r; g_ = g; b_ = b; + } + } + catch (string s) + { + printf("caught <%s>\n", s.c_str()); + return; + } +} + +const String +Color::get_string(void)const +{ + std::ostringstream o; + o << std::fixed << std::setprecision(3) << "#" << get_hex() << " : " << std::setw(6) << a_; + return String(o.str().c_str()); +} + #if 0 Color& Color::rotate_uv(const Angle& theta)const @@ -65,7 +141,7 @@ Color::rotate_uv(const Angle& theta)const const float u(get_u()), v(get_v()); - + return set_uv(b*u-a*v,a*u+b*v); //return YUV(get_y(),b*u-a*v,a*u+b*v,get_a()); //*/ @@ -76,7 +152,7 @@ Color Color::clamped_negative()const { Color ret=*this; - + if(ret.a_==0) return alpha(); @@ -161,13 +237,13 @@ blendfunc_COMPOSITE(Color &src,Color &dest,float amount) // if a_arc==0.0 //if(fabsf(a_src)COLOR_EPSILON) // if(a_out>COLOR_EPSILON || a_out<-COLOR_EPSILON) @@ -229,7 +305,7 @@ static Color blendfunc_BRIGHTEN(Color &a,Color &b,float amount) { const float alpha(a.get_a()*amount); - + if(b.get_r()(a.get_r()-1.0f)*alpha+1.0f) b.set_r((a.get_r()-1.0f)*alpha+1.0f); @@ -256,7 +332,7 @@ blendfunc_DARKEN(Color &a,Color &b,float amount) if(b.get_b()>(a.get_b()-1.0f)*alpha+1.0f) b.set_b((a.get_b()-1.0f)*alpha+1.0f); - + return b; } @@ -315,9 +391,9 @@ blendfunc_DIVIDE(Color &a,Color &b,float amount) // We add COLOR_EPSILON in order to avoid a divide-by-zero condition. // This causes DIVIDE to bias toward positive values, but the effect is - // really neglegable. There is a reason why we use COLOR_EPSILON--we - // want the change to be imperceptable. - + // really negligible. There is a reason why we use COLOR_EPSILON--we + // want the change to be imperceptible. + b.set_r(((b.get_r()/(a.get_r()+COLOR_EPSILON))-b.get_r())*(amount)+b.get_r()); b.set_g(((b.get_g()/(a.get_g()+COLOR_EPSILON))-b.get_g())*(amount)+b.get_g()); b.set_b(((b.get_b()/(a.get_b()+COLOR_EPSILON))-b.get_b())*(amount)+b.get_b()); @@ -330,7 +406,7 @@ blendfunc_COLOR(Color &a,Color &b,float amount) { Color temp(b); temp.set_uv(a.get_u(),a.get_v()); - return (temp-b)*amount*a.get_a()+b; + return (temp-b)*amount*a.get_a()+b; } static Color @@ -360,7 +436,7 @@ blendfunc_LUMINANCE(Color &a,Color &b,float amount) static Color blendfunc_BEHIND(Color &a,Color &b,float amount) { - if(a.get_a()==0)a.set_a(COLOR_EPSILON); //!< \hack + if(a.get_a()==0)a.set_a(COLOR_EPSILON); //!< \todo this is a hack a.set_a(a.get_a()*amount); return blendfunc_COMPOSITE(b,a,1.0); } @@ -368,7 +444,9 @@ blendfunc_BEHIND(Color &a,Color &b,float amount) static Color blendfunc_ALPHA_BRIGHTEN(Color &a,Color &b,float amount) { - if(a.get_a()b.get_a()) + if(a.get_a()*amount > b.get_a()) return a.set_a(a.get_a()*amount); return b; } @@ -389,13 +467,13 @@ blendfunc_SCREEN(Color &a,Color &b,float amount) a.set_r(1.0-(1.0f-a.get_r())*(1.0f-b.get_r())); a.set_g(1.0-(1.0f-a.get_g())*(1.0f-b.get_g())); a.set_b(1.0-(1.0f-a.get_b())*(1.0f-b.get_b())); - + return blendfunc_ONTO(a,b,amount); } static Color blendfunc_OVERLAY(Color &a,Color &b,float amount) -{ +{ if(amount<0) a=~a, amount=-amount; Color rm; @@ -409,7 +487,7 @@ blendfunc_OVERLAY(Color &a,Color &b,float amount) rs.set_b(1.0-(1.0f-a.get_b())*(1.0f-b.get_b())); Color& ret(a); - + ret.set_r(a.get_r()*rs.get_r() + (1.0-a.get_r())*rm.get_r()); ret.set_g(a.get_g()*rs.get_g() + (1.0-a.get_g())*rm.get_g()); ret.set_b(a.get_b()*rs.get_b() + (1.0-a.get_b())*rm.get_b()); @@ -466,7 +544,7 @@ Color::blend(Color a, Color b,float amount, Color::BlendMethod type) #endif } #endif - + /* if(!a.is_valid()&&b.is_valid()) return b; @@ -483,39 +561,39 @@ Color::blend(Color a, Color b,float amount, Color::BlendMethod type) #endif } */ - + // No matter what blend method is being used, // if the amount is equal to zero, then only B // will shine through if(fabsf(amount)<=COLOR_EPSILON)return b; - + assert(type