Anti-Grain Geometry - AGG (libagg)
2.5
|
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 // 00033 // color types gray8, gray16 00034 // 00035 //---------------------------------------------------------------------------- 00036 00037 #ifndef AGG_COLOR_GRAY_INCLUDED 00038 #define AGG_COLOR_GRAY_INCLUDED 00039 00040 #include "agg_basics.h" 00041 #include "agg_color_rgba.h" 00042 00043 namespace agg 00044 { 00045 00046 //===================================================================gray8 00047 struct gray8 00048 { 00049 typedef int8u value_type; 00050 typedef int32u calc_type; 00051 typedef int32 long_type; 00052 enum base_scale_e 00053 { 00054 base_shift = 8, 00055 base_scale = 1 << base_shift, 00056 base_mask = base_scale - 1 00057 }; 00058 typedef gray8 self_type; 00059 00060 value_type v; 00061 value_type a; 00062 00063 //-------------------------------------------------------------------- 00064 gray8() {} 00065 00066 //-------------------------------------------------------------------- 00067 gray8(unsigned v_, unsigned a_=base_mask) : 00068 v(int8u(v_)), a(int8u(a_)) {} 00069 00070 //-------------------------------------------------------------------- 00071 gray8(const self_type& c, unsigned a_) : 00072 v(c.v), a(value_type(a_)) {} 00073 00074 //-------------------------------------------------------------------- 00075 gray8(const rgba& c) : 00076 v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))), 00077 a((value_type)uround(c.a * double(base_mask))) {} 00078 00079 //-------------------------------------------------------------------- 00080 gray8(const rgba& c, double a_) : 00081 v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))), 00082 a((value_type)uround(a_ * double(base_mask))) {} 00083 00084 //-------------------------------------------------------------------- 00085 gray8(const rgba8& c) : 00086 v((c.r*77 + c.g*150 + c.b*29) >> 8), 00087 a(c.a) {} 00088 00089 //-------------------------------------------------------------------- 00090 gray8(const rgba8& c, unsigned a_) : 00091 v((c.r*77 + c.g*150 + c.b*29) >> 8), 00092 a(a_) {} 00093 00094 //-------------------------------------------------------------------- 00095 void clear() 00096 { 00097 v = a = 0; 00098 } 00099 00100 //-------------------------------------------------------------------- 00101 const self_type& transparent() 00102 { 00103 a = 0; 00104 return *this; 00105 } 00106 00107 //-------------------------------------------------------------------- 00108 void opacity(double a_) 00109 { 00110 if(a_ < 0.0) a_ = 0.0; 00111 if(a_ > 1.0) a_ = 1.0; 00112 a = (value_type)uround(a_ * double(base_mask)); 00113 } 00114 00115 //-------------------------------------------------------------------- 00116 double opacity() const 00117 { 00118 return double(a) / double(base_mask); 00119 } 00120 00121 00122 //-------------------------------------------------------------------- 00123 const self_type& premultiply() 00124 { 00125 if(a == base_mask) return *this; 00126 if(a == 0) 00127 { 00128 v = 0; 00129 return *this; 00130 } 00131 v = value_type((calc_type(v) * a) >> base_shift); 00132 return *this; 00133 } 00134 00135 //-------------------------------------------------------------------- 00136 const self_type& premultiply(unsigned a_) 00137 { 00138 if(a == base_mask && a_ >= base_mask) return *this; 00139 if(a == 0 || a_ == 0) 00140 { 00141 v = a = 0; 00142 return *this; 00143 } 00144 calc_type v_ = (calc_type(v) * a_) / a; 00145 v = value_type((v_ > a_) ? a_ : v_); 00146 a = value_type(a_); 00147 return *this; 00148 } 00149 00150 //-------------------------------------------------------------------- 00151 const self_type& demultiply() 00152 { 00153 if(a == base_mask) return *this; 00154 if(a == 0) 00155 { 00156 v = 0; 00157 return *this; 00158 } 00159 calc_type v_ = (calc_type(v) * base_mask) / a; 00160 v = value_type((v_ > base_mask) ? (value_type)base_mask : v_); 00161 return *this; 00162 } 00163 00164 //-------------------------------------------------------------------- 00165 self_type gradient(self_type c, double k) const 00166 { 00167 self_type ret; 00168 calc_type ik = uround(k * base_scale); 00169 ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift)); 00170 ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift)); 00171 return ret; 00172 } 00173 00174 //-------------------------------------------------------------------- 00175 AGG_INLINE void add(const self_type& c, unsigned cover) 00176 { 00177 calc_type cv, ca; 00178 if(cover == cover_mask) 00179 { 00180 if(c.a == base_mask) 00181 { 00182 *this = c; 00183 } 00184 else 00185 { 00186 cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv; 00187 ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; 00188 } 00189 } 00190 else 00191 { 00192 cv = v + ((c.v * cover + cover_mask/2) >> cover_shift); 00193 ca = a + ((c.a * cover + cover_mask/2) >> cover_shift); 00194 v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv; 00195 a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; 00196 } 00197 } 00198 00199 //-------------------------------------------------------------------- 00200 static self_type no_color() { return self_type(0,0); } 00201 }; 00202 00203 00204 //-------------------------------------------------------------gray8_pre 00205 inline gray8 gray8_pre(unsigned v, unsigned a = gray8::base_mask) 00206 { 00207 return gray8(v,a).premultiply(); 00208 } 00209 inline gray8 gray8_pre(const gray8& c, unsigned a) 00210 { 00211 return gray8(c,a).premultiply(); 00212 } 00213 inline gray8 gray8_pre(const rgba& c) 00214 { 00215 return gray8(c).premultiply(); 00216 } 00217 inline gray8 gray8_pre(const rgba& c, double a) 00218 { 00219 return gray8(c,a).premultiply(); 00220 } 00221 inline gray8 gray8_pre(const rgba8& c) 00222 { 00223 return gray8(c).premultiply(); 00224 } 00225 inline gray8 gray8_pre(const rgba8& c, unsigned a) 00226 { 00227 return gray8(c,a).premultiply(); 00228 } 00229 00230 00231 00232 00233 //==================================================================gray16 00234 struct gray16 00235 { 00236 typedef int16u value_type; 00237 typedef int32u calc_type; 00238 typedef int64 long_type; 00239 enum base_scale_e 00240 { 00241 base_shift = 16, 00242 base_scale = 1 << base_shift, 00243 base_mask = base_scale - 1 00244 }; 00245 typedef gray16 self_type; 00246 00247 value_type v; 00248 value_type a; 00249 00250 //-------------------------------------------------------------------- 00251 gray16() {} 00252 00253 //-------------------------------------------------------------------- 00254 gray16(unsigned v_, unsigned a_=base_mask) : 00255 v(int16u(v_)), a(int16u(a_)) {} 00256 00257 //-------------------------------------------------------------------- 00258 gray16(const self_type& c, unsigned a_) : 00259 v(c.v), a(value_type(a_)) {} 00260 00261 //-------------------------------------------------------------------- 00262 gray16(const rgba& c) : 00263 v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))), 00264 a((value_type)uround(c.a * double(base_mask))) {} 00265 00266 //-------------------------------------------------------------------- 00267 gray16(const rgba& c, double a_) : 00268 v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))), 00269 a((value_type)uround(a_ * double(base_mask))) {} 00270 00271 //-------------------------------------------------------------------- 00272 gray16(const rgba8& c) : 00273 v(c.r*77 + c.g*150 + c.b*29), 00274 a((value_type(c.a) << 8) | c.a) {} 00275 00276 //-------------------------------------------------------------------- 00277 gray16(const rgba8& c, unsigned a_) : 00278 v(c.r*77 + c.g*150 + c.b*29), 00279 a((value_type(a_) << 8) | c.a) {} 00280 00281 //-------------------------------------------------------------------- 00282 void clear() 00283 { 00284 v = a = 0; 00285 } 00286 00287 //-------------------------------------------------------------------- 00288 const self_type& transparent() 00289 { 00290 a = 0; 00291 return *this; 00292 } 00293 00294 //-------------------------------------------------------------------- 00295 void opacity(double a_) 00296 { 00297 if(a_ < 0.0) a_ = 0.0; 00298 if(a_ > 1.0) a_ = 1.0; 00299 a = (value_type)uround(a_ * double(base_mask)); 00300 } 00301 00302 //-------------------------------------------------------------------- 00303 double opacity() const 00304 { 00305 return double(a) / double(base_mask); 00306 } 00307 00308 00309 //-------------------------------------------------------------------- 00310 const self_type& premultiply() 00311 { 00312 if(a == base_mask) return *this; 00313 if(a == 0) 00314 { 00315 v = 0; 00316 return *this; 00317 } 00318 v = value_type((calc_type(v) * a) >> base_shift); 00319 return *this; 00320 } 00321 00322 //-------------------------------------------------------------------- 00323 const self_type& premultiply(unsigned a_) 00324 { 00325 if(a == base_mask && a_ >= base_mask) return *this; 00326 if(a == 0 || a_ == 0) 00327 { 00328 v = a = 0; 00329 return *this; 00330 } 00331 calc_type v_ = (calc_type(v) * a_) / a; 00332 v = value_type((v_ > a_) ? a_ : v_); 00333 a = value_type(a_); 00334 return *this; 00335 } 00336 00337 //-------------------------------------------------------------------- 00338 const self_type& demultiply() 00339 { 00340 if(a == base_mask) return *this; 00341 if(a == 0) 00342 { 00343 v = 0; 00344 return *this; 00345 } 00346 calc_type v_ = (calc_type(v) * base_mask) / a; 00347 v = value_type((v_ > base_mask) ? base_mask : v_); 00348 return *this; 00349 } 00350 00351 //-------------------------------------------------------------------- 00352 self_type gradient(self_type c, double k) const 00353 { 00354 self_type ret; 00355 calc_type ik = uround(k * base_scale); 00356 ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift)); 00357 ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift)); 00358 return ret; 00359 } 00360 00361 //-------------------------------------------------------------------- 00362 AGG_INLINE void add(const self_type& c, unsigned cover) 00363 { 00364 calc_type cv, ca; 00365 if(cover == cover_mask) 00366 { 00367 if(c.a == base_mask) 00368 { 00369 *this = c; 00370 } 00371 else 00372 { 00373 cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv; 00374 ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; 00375 } 00376 } 00377 else 00378 { 00379 cv = v + ((c.v * cover + cover_mask/2) >> cover_shift); 00380 ca = a + ((c.a * cover + cover_mask/2) >> cover_shift); 00381 v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv; 00382 a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; 00383 } 00384 } 00385 00386 //-------------------------------------------------------------------- 00387 static self_type no_color() { return self_type(0,0); } 00388 }; 00389 00390 00391 //------------------------------------------------------------gray16_pre 00392 inline gray16 gray16_pre(unsigned v, unsigned a = gray16::base_mask) 00393 { 00394 return gray16(v,a).premultiply(); 00395 } 00396 inline gray16 gray16_pre(const gray16& c, unsigned a) 00397 { 00398 return gray16(c,a).premultiply(); 00399 } 00400 inline gray16 gray16_pre(const rgba& c) 00401 { 00402 return gray16(c).premultiply(); 00403 } 00404 inline gray16 gray16_pre(const rgba& c, double a) 00405 { 00406 return gray16(c,a).premultiply(); 00407 } 00408 inline gray16 gray16_pre(const rgba8& c) 00409 { 00410 return gray16(c).premultiply(); 00411 } 00412 inline gray16 gray16_pre(const rgba8& c, unsigned a) 00413 { 00414 return gray16(c,a).premultiply(); 00415 } 00416 00417 00418 } 00419 00420 00421 00422 00423 #endif