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