Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_color_rgba.h
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 // Anti-Grain Geometry (AGG) - Version 2.5
00003 // A high quality rendering engine for C++
00004 // Copyright (C) 2002-2006 Maxim Shemanarev
00005 // Contact: mcseem@antigrain.com
00006 //          mcseemagg@yahoo.com
00007 //          http://antigrain.com
00008 // 
00009 // AGG is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU General Public License
00011 // as published by the Free Software Foundation; either version 2
00012 // of the License, or (at your option) any later version.
00013 // 
00014 // AGG is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU General Public License
00020 // along with AGG; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00022 // MA 02110-1301, USA.
00023 //----------------------------------------------------------------------------
00024 //
00025 // Adaptation for high precision colors has been sponsored by 
00026 // Liberty Technology Systems, Inc., visit http://lib-sys.com
00027 //
00028 // Liberty Technology Systems, Inc. is the provider of
00029 // PostScript and PDF technology for software developers.
00030 // 
00031 //----------------------------------------------------------------------------
00032 // Contact: mcseem@antigrain.com
00033 //          mcseemagg@yahoo.com
00034 //          http://www.antigrain.com
00035 //----------------------------------------------------------------------------
00036 
00037 #ifndef AGG_COLOR_RGBA_INCLUDED
00038 #define AGG_COLOR_RGBA_INCLUDED
00039 
00040 #include <math.h>
00041 #include "agg_basics.h"
00042 
00043 namespace agg
00044 {
00045     // Supported byte orders for RGB and RGBA pixel formats
00046     //=======================================================================
00047     struct order_rgb  { enum rgb_e  { R=0, G=1, B=2, rgb_tag }; };       //----order_rgb
00048     struct order_bgr  { enum bgr_e  { B=0, G=1, R=2, rgb_tag }; };       //----order_bgr
00049     struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, rgba_tag }; }; //----order_rgba
00050     struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, rgba_tag }; }; //----order_argb
00051     struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, rgba_tag }; }; //----order_abgr
00052     struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, rgba_tag }; }; //----order_bgra
00053 
00054     //====================================================================rgba
00055     struct rgba
00056     {
00057         typedef double value_type;
00058 
00059         double r;
00060         double g;
00061         double b;
00062         double a;
00063 
00064         //--------------------------------------------------------------------
00065         rgba() {}
00066 
00067         //--------------------------------------------------------------------
00068         rgba(double r_, double g_, double b_, double a_=1.0) :
00069             r(r_), g(g_), b(b_), a(a_) {}
00070 
00071         //--------------------------------------------------------------------
00072         rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {}
00073 
00074         //--------------------------------------------------------------------
00075         void clear()
00076         {
00077             r = g = b = a = 0;
00078         }
00079 
00080         //--------------------------------------------------------------------
00081         const rgba& transparent()
00082         {
00083             a = 0.0;
00084             return *this;
00085         }
00086 
00087         //--------------------------------------------------------------------
00088         const rgba& opacity(double a_)
00089         {
00090             if(a_ < 0.0) a_ = 0.0;
00091             if(a_ > 1.0) a_ = 1.0;
00092             a = a_;
00093             return *this;
00094         }
00095 
00096         //--------------------------------------------------------------------
00097         double opacity() const
00098         {
00099             return a;
00100         }
00101 
00102         //--------------------------------------------------------------------
00103         const rgba& premultiply()
00104         {
00105             r *= a;
00106             g *= a;
00107             b *= a;
00108             return *this;
00109         }
00110 
00111         //--------------------------------------------------------------------
00112         const rgba& premultiply(double a_)
00113         {
00114             if(a <= 0.0 || a_ <= 0.0)
00115             {
00116                 r = g = b = a = 0.0;
00117                 return *this;
00118             }
00119             a_ /= a;
00120             r *= a_;
00121             g *= a_;
00122             b *= a_;
00123             a  = a_;
00124             return *this;
00125         }
00126 
00127         //--------------------------------------------------------------------
00128         const rgba& demultiply()
00129         {
00130             if(a == 0)
00131             {
00132                 r = g = b = 0;
00133                 return *this;
00134             }
00135             double a_ = 1.0 / a;
00136             r *= a_;
00137             g *= a_;
00138             b *= a_;
00139             return *this;
00140         }
00141 
00142 
00143         //--------------------------------------------------------------------
00144         rgba gradient(rgba c, double k) const
00145         {
00146             rgba ret;
00147             ret.r = r + (c.r - r) * k;
00148             ret.g = g + (c.g - g) * k;
00149             ret.b = b + (c.b - b) * k;
00150             ret.a = a + (c.a - a) * k;
00151             return ret;
00152         }
00153 
00154         //--------------------------------------------------------------------
00155         static rgba no_color() { return rgba(0,0,0,0); }
00156 
00157         //--------------------------------------------------------------------
00158         static rgba from_wavelength(double wl, double gamma = 1.0);
00159         
00160         //--------------------------------------------------------------------
00161         explicit rgba(double wavelen, double gamma=1.0)
00162         {
00163             *this = from_wavelength(wavelen, gamma);
00164         }
00165 
00166     };
00167 
00168     //----------------------------------------------------------------rgba_pre
00169     inline rgba rgba_pre(double r, double g, double b, double a=1.0)
00170     {
00171         return rgba(r, g, b, a).premultiply();
00172     }
00173     inline rgba rgba_pre(const rgba& c)
00174     {
00175         return rgba(c).premultiply();
00176     }
00177     inline rgba rgba_pre(const rgba& c, double a)
00178     {
00179         return rgba(c, a).premultiply();
00180     }
00181 
00182     //------------------------------------------------------------------------
00183     inline rgba rgba::from_wavelength(double wl, double gamma)
00184     {
00185         rgba t(0.0, 0.0, 0.0);
00186 
00187         if(wl >= 380.0 && wl <= 440.0)
00188         {
00189             t.r = -1.0 * (wl - 440.0) / (440.0 - 380.0);
00190             t.b = 1.0;
00191         }
00192         else 
00193         if(wl >= 440.0 && wl <= 490.0)
00194         {
00195             t.g = (wl - 440.0) / (490.0 - 440.0);
00196             t.b = 1.0;
00197         }
00198         else
00199         if(wl >= 490.0 && wl <= 510.0)
00200         {
00201             t.g = 1.0;
00202             t.b = -1.0 * (wl - 510.0) / (510.0 - 490.0);
00203         }
00204         else
00205         if(wl >= 510.0 && wl <= 580.0)
00206         {
00207             t.r = (wl - 510.0) / (580.0 - 510.0);
00208             t.g = 1.0;
00209         }
00210         else
00211         if(wl >= 580.0 && wl <= 645.0)
00212         {
00213             t.r = 1.0;
00214             t.g = -1.0 * (wl - 645.0) / (645.0 - 580.0);
00215         }
00216         else
00217         if(wl >= 645.0 && wl <= 780.0)
00218         {
00219             t.r = 1.0;
00220         }
00221 
00222         double s = 1.0;
00223         if(wl > 700.0)       s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0);
00224         else if(wl <  420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0);
00225 
00226         t.r = pow(t.r * s, gamma);
00227         t.g = pow(t.g * s, gamma);
00228         t.b = pow(t.b * s, gamma);
00229         return t;
00230     }
00231 
00232 
00233 
00234     
00235     //===================================================================rgba8
00236     struct rgba8
00237     {
00238         typedef int8u  value_type;
00239         typedef int32u calc_type;
00240         typedef int32  long_type;
00241         enum base_scale_e
00242         {
00243             base_shift = 8,
00244             base_scale = 1 << base_shift,
00245             base_mask  = base_scale - 1
00246         };
00247         typedef rgba8 self_type;
00248 
00249 
00250         value_type r;
00251         value_type g;
00252         value_type b;
00253         value_type a;
00254 
00255         //--------------------------------------------------------------------
00256         rgba8() {}
00257 
00258         //--------------------------------------------------------------------
00259         rgba8(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) :
00260             r(value_type(r_)), 
00261             g(value_type(g_)), 
00262             b(value_type(b_)), 
00263             a(value_type(a_)) {}
00264 
00265         //--------------------------------------------------------------------
00266         rgba8(const rgba& c, double a_) :
00267             r((value_type)uround(c.r * double(base_mask))), 
00268             g((value_type)uround(c.g * double(base_mask))), 
00269             b((value_type)uround(c.b * double(base_mask))), 
00270             a((value_type)uround(a_  * double(base_mask))) {}
00271 
00272         //--------------------------------------------------------------------
00273         rgba8(const self_type& c, unsigned a_) :
00274             r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
00275 
00276         //--------------------------------------------------------------------
00277         rgba8(const rgba& c) :
00278             r((value_type)uround(c.r * double(base_mask))), 
00279             g((value_type)uround(c.g * double(base_mask))), 
00280             b((value_type)uround(c.b * double(base_mask))), 
00281             a((value_type)uround(c.a * double(base_mask))) {}
00282 
00283         //--------------------------------------------------------------------
00284         void clear()
00285         {
00286             r = g = b = a = 0;
00287         }
00288         
00289         //--------------------------------------------------------------------
00290         const self_type& transparent()
00291         {
00292             a = 0;
00293             return *this;
00294         }
00295 
00296         //--------------------------------------------------------------------
00297         const self_type& opacity(double a_)
00298         {
00299             if(a_ < 0.0) a_ = 0.0;
00300             if(a_ > 1.0) a_ = 1.0;
00301             a = (value_type)uround(a_ * double(base_mask));
00302             return *this;
00303         }
00304 
00305         //--------------------------------------------------------------------
00306         double opacity() const
00307         {
00308             return double(a) / double(base_mask);
00309         }
00310 
00311         //--------------------------------------------------------------------
00312         AGG_INLINE const self_type& premultiply()
00313         {
00314             if(a == base_mask) return *this;
00315             if(a == 0)
00316             {
00317                 r = g = b = 0;
00318                 return *this;
00319             }
00320             r = value_type((calc_type(r) * a) >> base_shift);
00321             g = value_type((calc_type(g) * a) >> base_shift);
00322             b = value_type((calc_type(b) * a) >> base_shift);
00323             return *this;
00324         }
00325 
00326         //--------------------------------------------------------------------
00327         AGG_INLINE const self_type& premultiply(unsigned a_)
00328         {
00329             if(a == base_mask && a_ >= base_mask) return *this;
00330             if(a == 0 || a_ == 0)
00331             {
00332                 r = g = b = a = 0;
00333                 return *this;
00334             }
00335             calc_type r_ = (calc_type(r) * a_) / a;
00336             calc_type g_ = (calc_type(g) * a_) / a;
00337             calc_type b_ = (calc_type(b) * a_) / a;
00338             r = value_type((r_ > a_) ? a_ : r_);
00339             g = value_type((g_ > a_) ? a_ : g_);
00340             b = value_type((b_ > a_) ? a_ : b_);
00341             a = value_type(a_);
00342             return *this;
00343         }
00344 
00345         //--------------------------------------------------------------------
00346         AGG_INLINE const self_type& demultiply()
00347         {
00348             if(a == base_mask) return *this;
00349             if(a == 0)
00350             {
00351                 r = g = b = 0;
00352                 return *this;
00353             }
00354             calc_type r_ = (calc_type(r) * base_mask) / a;
00355             calc_type g_ = (calc_type(g) * base_mask) / a;
00356             calc_type b_ = (calc_type(b) * base_mask) / a;
00357             r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_);
00358             g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_);
00359             b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_);
00360             return *this;
00361         }
00362 
00363         //--------------------------------------------------------------------
00364         AGG_INLINE self_type gradient(const self_type& c, double k) const
00365         {
00366             self_type ret;
00367             calc_type ik = uround(k * base_scale);
00368             ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift));
00369             ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift));
00370             ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift));
00371             ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
00372             return ret;
00373         }
00374 
00375         //--------------------------------------------------------------------
00376         AGG_INLINE void add(const self_type& c, unsigned cover)
00377         {
00378             calc_type cr, cg, cb, ca;
00379             if(cover == cover_mask)
00380             {
00381                 if(c.a == base_mask) 
00382                 {
00383                     *this = c;
00384                 }
00385                 else
00386                 {
00387                     cr = r + c.r; r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
00388                     cg = g + c.g; g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
00389                     cb = b + c.b; b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
00390                     ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
00391                 }
00392             }
00393             else
00394             {
00395                 cr = r + ((c.r * cover + cover_mask/2) >> cover_shift);
00396                 cg = g + ((c.g * cover + cover_mask/2) >> cover_shift);
00397                 cb = b + ((c.b * cover + cover_mask/2) >> cover_shift);
00398                 ca = a + ((c.a * cover + cover_mask/2) >> cover_shift);
00399                 r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
00400                 g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
00401                 b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
00402                 a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
00403             }
00404         }
00405 
00406         //--------------------------------------------------------------------
00407         template<class GammaLUT>
00408         AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma)
00409         {
00410             r = gamma.dir(r);
00411             g = gamma.dir(g);
00412             b = gamma.dir(b);
00413         }
00414 
00415         //--------------------------------------------------------------------
00416         template<class GammaLUT>
00417         AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma)
00418         {
00419             r = gamma.inv(r);
00420             g = gamma.inv(g);
00421             b = gamma.inv(b);
00422         }
00423 
00424         //--------------------------------------------------------------------
00425         static self_type no_color() { return self_type(0,0,0,0); }
00426 
00427         //--------------------------------------------------------------------
00428         static self_type from_wavelength(double wl, double gamma = 1.0)
00429         {
00430             return self_type(rgba::from_wavelength(wl, gamma));
00431         }
00432     };
00433 
00434 
00435     //-------------------------------------------------------------rgba8_pre
00436     inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b, 
00437                            unsigned a = rgba8::base_mask)
00438     {
00439         return rgba8(r,g,b,a).premultiply();
00440     }
00441     inline rgba8 rgba8_pre(const rgba8& c)
00442     {
00443         return rgba8(c).premultiply();
00444     }
00445     inline rgba8 rgba8_pre(const rgba8& c, unsigned a)
00446     {
00447         return rgba8(c,a).premultiply();
00448     }
00449     inline rgba8 rgba8_pre(const rgba& c)
00450     {
00451         return rgba8(c).premultiply();
00452     }
00453     inline rgba8 rgba8_pre(const rgba& c, double a)
00454     {
00455         return rgba8(c,a).premultiply();
00456     }
00457 
00458 
00459     //-------------------------------------------------------------rgb8_packed
00460     inline rgba8 rgb8_packed(unsigned v)
00461     {
00462         return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF);
00463     }
00464 
00465     //-------------------------------------------------------------bgr8_packed
00466     inline rgba8 bgr8_packed(unsigned v)
00467     {
00468         return rgba8(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF);
00469     }
00470 
00471     //------------------------------------------------------------argb8_packed
00472     inline rgba8 argb8_packed(unsigned v)
00473     {
00474         return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF, v >> 24);
00475     }
00476 
00477     //---------------------------------------------------------rgba8_gamma_dir
00478     template<class GammaLUT>
00479     rgba8 rgba8_gamma_dir(rgba8 c, const GammaLUT& gamma)
00480     {
00481         return rgba8(gamma.dir(c.r), gamma.dir(c.g), gamma.dir(c.b), c.a);
00482     }
00483 
00484     //---------------------------------------------------------rgba8_gamma_inv
00485     template<class GammaLUT>
00486     rgba8 rgba8_gamma_inv(rgba8 c, const GammaLUT& gamma)
00487     {
00488         return rgba8(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a);
00489     }
00490 
00491 
00492 
00493 
00494 
00495     //==================================================================rgba16
00496     struct rgba16
00497     {
00498         typedef int16u value_type;
00499         typedef int32u calc_type;
00500         typedef int64  long_type;
00501         enum base_scale_e
00502         {
00503             base_shift = 16,
00504             base_scale = 1 << base_shift,
00505             base_mask  = base_scale - 1
00506         };
00507         typedef rgba16 self_type;
00508 
00509         value_type r;
00510         value_type g;
00511         value_type b;
00512         value_type a;
00513 
00514         //--------------------------------------------------------------------
00515         rgba16() {}
00516 
00517         //--------------------------------------------------------------------
00518         rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) :
00519             r(value_type(r_)), 
00520             g(value_type(g_)), 
00521             b(value_type(b_)), 
00522             a(value_type(a_)) {}
00523 
00524         //--------------------------------------------------------------------
00525         rgba16(const self_type& c, unsigned a_) :
00526             r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
00527 
00528         //--------------------------------------------------------------------
00529         rgba16(const rgba& c) :
00530             r((value_type)uround(c.r * double(base_mask))), 
00531             g((value_type)uround(c.g * double(base_mask))), 
00532             b((value_type)uround(c.b * double(base_mask))), 
00533             a((value_type)uround(c.a * double(base_mask))) {}
00534 
00535         //--------------------------------------------------------------------
00536         rgba16(const rgba& c, double a_) :
00537             r((value_type)uround(c.r * double(base_mask))), 
00538             g((value_type)uround(c.g * double(base_mask))), 
00539             b((value_type)uround(c.b * double(base_mask))), 
00540             a((value_type)uround(a_  * double(base_mask))) {}
00541 
00542         //--------------------------------------------------------------------
00543         rgba16(const rgba8& c) :
00544             r(value_type((value_type(c.r) << 8) | c.r)), 
00545             g(value_type((value_type(c.g) << 8) | c.g)), 
00546             b(value_type((value_type(c.b) << 8) | c.b)), 
00547             a(value_type((value_type(c.a) << 8) | c.a)) {}
00548 
00549         //--------------------------------------------------------------------
00550         rgba16(const rgba8& c, unsigned a_) :
00551             r(value_type((value_type(c.r) << 8) | c.r)), 
00552             g(value_type((value_type(c.g) << 8) | c.g)), 
00553             b(value_type((value_type(c.b) << 8) | c.b)), 
00554             a(value_type((             a_ << 8) | c.a)) {}
00555 
00556         //--------------------------------------------------------------------
00557         void clear()
00558         {
00559             r = g = b = a = 0;
00560         }
00561         
00562         //--------------------------------------------------------------------
00563         const self_type& transparent()
00564         {
00565             a = 0;
00566             return *this;
00567         }
00568 
00569         //--------------------------------------------------------------------
00570         AGG_INLINE const self_type& opacity(double a_)
00571         {
00572             if(a_ < 0.0) a_ = 0.0;
00573             if(a_ > 1.0) a_ = 1.0;
00574             a = (value_type)uround(a_ * double(base_mask));
00575             return *this;
00576         }
00577 
00578         //--------------------------------------------------------------------
00579         double opacity() const
00580         {
00581             return double(a) / double(base_mask);
00582         }
00583 
00584         //--------------------------------------------------------------------
00585         AGG_INLINE const self_type& premultiply()
00586         {
00587             if(a == base_mask) return *this;
00588             if(a == 0)
00589             {
00590                 r = g = b = 0;
00591                 return *this;
00592             }
00593             r = value_type((calc_type(r) * a) >> base_shift);
00594             g = value_type((calc_type(g) * a) >> base_shift);
00595             b = value_type((calc_type(b) * a) >> base_shift);
00596             return *this;
00597         }
00598 
00599         //--------------------------------------------------------------------
00600         AGG_INLINE const self_type& premultiply(unsigned a_)
00601         {
00602             if(a == base_mask && a_ >= base_mask) return *this;
00603             if(a == 0 || a_ == 0)
00604             {
00605                 r = g = b = a = 0;
00606                 return *this;
00607             }
00608             calc_type r_ = (calc_type(r) * a_) / a;
00609             calc_type g_ = (calc_type(g) * a_) / a;
00610             calc_type b_ = (calc_type(b) * a_) / a;
00611             r = value_type((r_ > a_) ? a_ : r_);
00612             g = value_type((g_ > a_) ? a_ : g_);
00613             b = value_type((b_ > a_) ? a_ : b_);
00614             a = value_type(a_);
00615             return *this;
00616         }
00617 
00618         //--------------------------------------------------------------------
00619         AGG_INLINE const self_type& demultiply()
00620         {
00621             if(a == base_mask) return *this;
00622             if(a == 0)
00623             {
00624                 r = g = b = 0;
00625                 return *this;
00626             }
00627             calc_type r_ = (calc_type(r) * base_mask) / a;
00628             calc_type g_ = (calc_type(g) * base_mask) / a;
00629             calc_type b_ = (calc_type(b) * base_mask) / a;
00630             r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_);
00631             g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_);
00632             b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_);
00633             return *this;
00634         }
00635 
00636         //--------------------------------------------------------------------
00637         AGG_INLINE self_type gradient(const self_type& c, double k) const
00638         {
00639             self_type ret;
00640             calc_type ik = uround(k * base_scale);
00641             ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift));
00642             ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift));
00643             ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift));
00644             ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
00645             return ret;
00646         }
00647 
00648         //--------------------------------------------------------------------
00649         AGG_INLINE void add(const self_type& c, unsigned cover)
00650         {
00651             calc_type cr, cg, cb, ca;
00652             if(cover == cover_mask)
00653             {
00654                 if(c.a == base_mask) 
00655                 {
00656                     *this = c;
00657                 }
00658                 else
00659                 {
00660                     cr = r + c.r; r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
00661                     cg = g + c.g; g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
00662                     cb = b + c.b; b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
00663                     ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
00664                 }
00665             }
00666             else
00667             {
00668                 cr = r + ((c.r * cover + cover_mask) >> cover_shift);
00669                 cg = g + ((c.g * cover + cover_mask) >> cover_shift);
00670                 cb = b + ((c.b * cover + cover_mask) >> cover_shift);
00671                 ca = a + ((c.a * cover + cover_mask) >> cover_shift);
00672                 r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
00673                 g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
00674                 b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
00675                 a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
00676             }
00677         }
00678 
00679         //--------------------------------------------------------------------
00680         template<class GammaLUT>
00681         AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma)
00682         {
00683             r = gamma.dir(r);
00684             g = gamma.dir(g);
00685             b = gamma.dir(b);
00686         }
00687 
00688         //--------------------------------------------------------------------
00689         template<class GammaLUT>
00690         AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma)
00691         {
00692             r = gamma.inv(r);
00693             g = gamma.inv(g);
00694             b = gamma.inv(b);
00695         }
00696 
00697         //--------------------------------------------------------------------
00698         static self_type no_color() { return self_type(0,0,0,0); }
00699 
00700         //--------------------------------------------------------------------
00701         static self_type from_wavelength(double wl, double gamma = 1.0)
00702         {
00703             return self_type(rgba::from_wavelength(wl, gamma));
00704         }
00705     };
00706 
00707 
00708 
00709     //--------------------------------------------------------------rgba16_pre
00710     inline rgba16 rgba16_pre(unsigned r, unsigned g, unsigned b, 
00711                              unsigned a = rgba16::base_mask)
00712     {
00713         return rgba16(r,g,b,a).premultiply();
00714     }
00715     inline rgba16 rgba16_pre(const rgba16& c, unsigned a)
00716     {
00717         return rgba16(c,a).premultiply();
00718     }
00719     inline rgba16 rgba16_pre(const rgba& c)
00720     {
00721         return rgba16(c).premultiply();
00722     }
00723     inline rgba16 rgba16_pre(const rgba& c, double a)
00724     {
00725         return rgba16(c,a).premultiply();
00726     }
00727     inline rgba16 rgba16_pre(const rgba8& c)
00728     {
00729         return rgba16(c).premultiply();
00730     }
00731     inline rgba16 rgba16_pre(const rgba8& c, unsigned a)
00732     {
00733         return rgba16(c,a).premultiply();
00734     }
00735 
00736 
00737     //------------------------------------------------------rgba16_gamma_dir
00738     template<class GammaLUT>
00739     rgba16 rgba16_gamma_dir(rgba16 c, const GammaLUT& gamma)
00740     {
00741         return rgba16(gamma.dir(c.r), gamma.dir(c.g), gamma.dir(c.b), c.a);
00742     }
00743 
00744     //------------------------------------------------------rgba16_gamma_inv
00745     template<class GammaLUT>
00746     rgba16 rgba16_gamma_inv(rgba16 c, const GammaLUT& gamma)
00747     {
00748         return rgba16(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a);
00749     }
00750 
00751 
00752 }
00753 
00754 
00755 
00756 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines