00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef AGG_COLOR_RGBA_INCLUDED
00021 #define AGG_COLOR_RGBA_INCLUDED
00022
00023 #include <math.h>
00024 #include "agg_basics.h"
00025
00026 namespace agg
00027 {
00028
00029 struct rgba
00030 {
00031 typedef double alpha_type;
00032 enum premul { pre };
00033
00034 double r;
00035 double g;
00036 double b;
00037 double a;
00038
00039
00040 rgba() {}
00041
00042
00043 rgba(double r_, double g_, double b_, double a_=1.0) :
00044 r(r_), g(g_), b(b_), a(a_) {}
00045
00046
00047 rgba(premul, double r_, double g_, double b_, double a_=1.0) :
00048 r(r_), g(g_), b(b_), a(a_)
00049 {
00050 premultiply();
00051 }
00052
00053
00054 rgba(premul, const rgba& c) : r(c.r), g(c.g), b(c.b), a(c.a)
00055 {
00056 premultiply();
00057 }
00058
00059
00060 rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {}
00061
00062
00063 rgba(premul, const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_)
00064 {
00065 premultiply();
00066 }
00067
00068
00069 void clear()
00070 {
00071 r = g = b = a = 0;
00072 }
00073
00074
00075 const rgba& transparent()
00076 {
00077 a = 0.0;
00078 return *this;
00079 }
00080
00081
00082 const rgba& transparent(premul)
00083 {
00084 clear();
00085 return *this;
00086 }
00087
00088
00089 const rgba& opacity(double a_)
00090 {
00091 if(a_ < 0.0) a_ = 0.0;
00092 if(a_ > 1.0) a_ = 1.0;
00093 a = a_;
00094 return *this;
00095 }
00096
00097
00098 const rgba& opacity(premul, double a_)
00099 {
00100 if(a_ < 0.0) a_ = 0.0;
00101 if(a_ > 1.0) a_ = 1.0;
00102 premultiply(a_);
00103 return *this;
00104 }
00105
00106
00107 double opacity() const
00108 {
00109 return a;
00110 }
00111
00112
00113 const rgba& premultiply()
00114 {
00115 r *= a;
00116 g *= a;
00117 b *= a;
00118 return *this;
00119 }
00120
00121
00122 const rgba& premultiply(double a_)
00123 {
00124 if(a == 0.0 || a_ == 0.0)
00125 {
00126 r = g = b = a = 0.0;
00127 return *this;
00128 }
00129 a_ /= a;
00130 r *= a_;
00131 g *= a_;
00132 b *= a_;
00133 a = a_;
00134 return *this;
00135 }
00136
00137
00138 const rgba& demultiply()
00139 {
00140 if(a == 0)
00141 {
00142 r = g = b = 0;
00143 return *this;
00144 }
00145 double a_ = 1.0 / a;
00146 r *= a_;
00147 g *= a_;
00148 b *= a_;
00149 return *this;
00150 }
00151
00152
00153
00154 rgba gradient(rgba c, double k) const
00155 {
00156 rgba ret;
00157 ret.r = r + (c.r - r) * k;
00158 ret.g = g + (c.g - g) * k;
00159 ret.b = b + (c.b - b) * k;
00160 ret.a = a + (c.a - a) * k;
00161 return ret;
00162 }
00163
00164
00165 static rgba no_color() { return rgba(0,0,0,0); }
00166
00167
00168 static rgba from_wavelength(double wl, double gamma = 1.0);
00169
00170
00171 rgba(double wavelen, double gamma=1.0)
00172 {
00173 *this = from_wavelength(wavelen, gamma);
00174 }
00175
00176 };
00177
00178
00179
00180 inline rgba rgba_pre(double r, double g, double b, double a=1.0)
00181 {
00182 return rgba(rgba::pre, r, g, b, a);
00183 }
00184
00185
00186 inline rgba rgba_pre(const rgba& c)
00187 {
00188 return rgba(rgba::pre, c);
00189 }
00190
00191
00192 inline rgba rgba_pre(const rgba& c, double a)
00193 {
00194 return rgba(rgba::pre, c, a);
00195 }
00196
00197
00198
00199 inline rgba rgba::from_wavelength(double wl, double gamma)
00200 {
00201 rgba t(0.0, 0.0, 0.0);
00202
00203 if(wl >= 380.0 && wl <= 440.0)
00204 {
00205 t.r = -1.0 * (wl - 440.0) / (440.0 - 380.0);
00206 t.b = 1.0;
00207 }
00208 else
00209 if(wl >= 440.0 && wl <= 490.0)
00210 {
00211 t.g = (wl - 440.0) / (490.0 - 440.0);
00212 t.b = 1.0;
00213 }
00214 else
00215 if(wl >= 490.0 && wl <= 510.0)
00216 {
00217 t.g = 1.0;
00218 t.b = -1.0 * (wl - 510.0) / (510.0 - 490.0);
00219 }
00220 else
00221 if(wl >= 510.0 && wl <= 580.0)
00222 {
00223 t.r = (wl - 510.0) / (580.0 - 510.0);
00224 t.g = 1.0;
00225 }
00226 else
00227 if(wl >= 580.0 && wl <= 645.0)
00228 {
00229 t.r = 1.0;
00230 t.g = -1.0 * (wl - 645.0) / (645.0 - 580.0);
00231 }
00232 else
00233 if(wl >= 645.0 && wl <= 780.0)
00234 {
00235 t.r = 1.0;
00236 }
00237
00238 double s = 1.0;
00239 if(wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0);
00240 else if(wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0);
00241
00242 t.r = pow(t.r * s, gamma);
00243 t.g = pow(t.g * s, gamma);
00244 t.b = pow(t.b * s, gamma);
00245 return t;
00246 }
00247
00248
00249
00250 }
00251
00252
00253 #endif