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 #ifndef AGG_IMAGE_ACCESSORS_INCLUDED 00026 #define AGG_IMAGE_ACCESSORS_INCLUDED 00027 00028 #include "agg_basics.h" 00029 00030 namespace agg 00031 { 00032 00033 //-----------------------------------------------------image_accessor_clip 00034 template<class PixFmt> class image_accessor_clip 00035 { 00036 public: 00037 typedef PixFmt pixfmt_type; 00038 typedef typename pixfmt_type::color_type color_type; 00039 typedef typename pixfmt_type::order_type order_type; 00040 typedef typename pixfmt_type::value_type value_type; 00041 enum pix_width_e { pix_width = pixfmt_type::pix_width }; 00042 00043 image_accessor_clip() {} 00044 explicit image_accessor_clip(const pixfmt_type& pixf, 00045 const color_type& bk) : 00046 m_pixf(&pixf) 00047 { 00048 pixfmt_type::make_pix(m_bk_buf, bk); 00049 } 00050 00051 void attach(const pixfmt_type& pixf) 00052 { 00053 m_pixf = &pixf; 00054 } 00055 00056 void background_color(const color_type& bk) 00057 { 00058 pixfmt_type::make_pix(m_bk_buf, bk); 00059 } 00060 00061 private: 00062 AGG_INLINE const int8u* pixel() const 00063 { 00064 if(m_y >= 0 && m_y < (int)m_pixf->height() && 00065 m_x >= 0 && m_x < (int)m_pixf->width()) 00066 { 00067 return m_pixf->pix_ptr(m_x, m_y); 00068 } 00069 return m_bk_buf; 00070 } 00071 00072 public: 00073 AGG_INLINE const int8u* span(int x, int y, unsigned len) 00074 { 00075 m_x = m_x0 = x; 00076 m_y = y; 00077 if(y >= 0 && y < (int)m_pixf->height() && 00078 x >= 0 && x+(int)len <= (int)m_pixf->width()) 00079 { 00080 return m_pix_ptr = m_pixf->pix_ptr(x, y); 00081 } 00082 m_pix_ptr = 0; 00083 return pixel(); 00084 } 00085 00086 AGG_INLINE const int8u* next_x() 00087 { 00088 if(m_pix_ptr) return m_pix_ptr += pix_width; 00089 ++m_x; 00090 return pixel(); 00091 } 00092 00093 AGG_INLINE const int8u* next_y() 00094 { 00095 ++m_y; 00096 m_x = m_x0; 00097 if(m_pix_ptr && 00098 m_y >= 0 && m_y < (int)m_pixf->height()) 00099 { 00100 return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y); 00101 } 00102 m_pix_ptr = 0; 00103 return pixel(); 00104 } 00105 00106 private: 00107 const pixfmt_type* m_pixf; 00108 int8u m_bk_buf[4]; 00109 int m_x, m_x0, m_y; 00110 const int8u* m_pix_ptr; 00111 }; 00112 00113 00114 00115 00116 //--------------------------------------------------image_accessor_no_clip 00117 template<class PixFmt> class image_accessor_no_clip 00118 { 00119 public: 00120 typedef PixFmt pixfmt_type; 00121 typedef typename pixfmt_type::color_type color_type; 00122 typedef typename pixfmt_type::order_type order_type; 00123 typedef typename pixfmt_type::value_type value_type; 00124 enum pix_width_e { pix_width = pixfmt_type::pix_width }; 00125 00126 image_accessor_no_clip() {} 00127 explicit image_accessor_no_clip(const pixfmt_type& pixf) : 00128 m_pixf(&pixf) 00129 {} 00130 00131 void attach(const pixfmt_type& pixf) 00132 { 00133 m_pixf = &pixf; 00134 } 00135 00136 AGG_INLINE const int8u* span(int x, int y, unsigned) 00137 { 00138 m_x = x; 00139 m_y = y; 00140 return m_pix_ptr = m_pixf->pix_ptr(x, y); 00141 } 00142 00143 AGG_INLINE const int8u* next_x() 00144 { 00145 return m_pix_ptr += pix_width; 00146 } 00147 00148 AGG_INLINE const int8u* next_y() 00149 { 00150 ++m_y; 00151 return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y); 00152 } 00153 00154 private: 00155 const pixfmt_type* m_pixf; 00156 int m_x, m_y; 00157 const int8u* m_pix_ptr; 00158 }; 00159 00160 00161 00162 00163 //----------------------------------------------------image_accessor_clone 00164 template<class PixFmt> class image_accessor_clone 00165 { 00166 public: 00167 typedef PixFmt pixfmt_type; 00168 typedef typename pixfmt_type::color_type color_type; 00169 typedef typename pixfmt_type::order_type order_type; 00170 typedef typename pixfmt_type::value_type value_type; 00171 enum pix_width_e { pix_width = pixfmt_type::pix_width }; 00172 00173 image_accessor_clone() {} 00174 explicit image_accessor_clone(const pixfmt_type& pixf) : 00175 m_pixf(&pixf) 00176 {} 00177 00178 void attach(const pixfmt_type& pixf) 00179 { 00180 m_pixf = &pixf; 00181 } 00182 00183 private: 00184 AGG_INLINE const int8u* pixel() const 00185 { 00186 register int x = m_x; 00187 register int y = m_y; 00188 if(x < 0) x = 0; 00189 if(y < 0) y = 0; 00190 if(x >= (int)m_pixf->width()) x = m_pixf->width() - 1; 00191 if(y >= (int)m_pixf->height()) y = m_pixf->height() - 1; 00192 return m_pixf->pix_ptr(x, y); 00193 } 00194 00195 public: 00196 AGG_INLINE const int8u* span(int x, int y, unsigned len) 00197 { 00198 m_x = m_x0 = x; 00199 m_y = y; 00200 if(y >= 0 && y < (int)m_pixf->height() && 00201 x >= 0 && x+len <= (int)m_pixf->width()) 00202 { 00203 return m_pix_ptr = m_pixf->pix_ptr(x, y); 00204 } 00205 m_pix_ptr = 0; 00206 return pixel(); 00207 } 00208 00209 AGG_INLINE const int8u* next_x() 00210 { 00211 if(m_pix_ptr) return m_pix_ptr += pix_width; 00212 ++m_x; 00213 return pixel(); 00214 } 00215 00216 AGG_INLINE const int8u* next_y() 00217 { 00218 ++m_y; 00219 m_x = m_x0; 00220 if(m_pix_ptr && 00221 m_y >= 0 && m_y < (int)m_pixf->height()) 00222 { 00223 return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y); 00224 } 00225 m_pix_ptr = 0; 00226 return pixel(); 00227 } 00228 00229 private: 00230 const pixfmt_type* m_pixf; 00231 int m_x, m_x0, m_y; 00232 const int8u* m_pix_ptr; 00233 }; 00234 00235 00236 00237 00238 00239 //-----------------------------------------------------image_accessor_wrap 00240 template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap 00241 { 00242 public: 00243 typedef PixFmt pixfmt_type; 00244 typedef typename pixfmt_type::color_type color_type; 00245 typedef typename pixfmt_type::order_type order_type; 00246 typedef typename pixfmt_type::value_type value_type; 00247 enum pix_width_e { pix_width = pixfmt_type::pix_width }; 00248 00249 image_accessor_wrap() {} 00250 explicit image_accessor_wrap(const pixfmt_type& pixf) : 00251 m_pixf(&pixf), 00252 m_wrap_x(pixf.width()), 00253 m_wrap_y(pixf.height()) 00254 {} 00255 00256 void attach(const pixfmt_type& pixf) 00257 { 00258 m_pixf = &pixf; 00259 } 00260 00261 AGG_INLINE const int8u* span(int x, int y, unsigned) 00262 { 00263 m_x = x; 00264 m_row_ptr = m_pixf->row_ptr(m_wrap_y(y)); 00265 return m_row_ptr + m_wrap_x(x) * pix_width; 00266 } 00267 00268 AGG_INLINE const int8u* next_x() 00269 { 00270 int x = ++m_wrap_x; 00271 return m_row_ptr + x * pix_width; 00272 } 00273 00274 AGG_INLINE const int8u* next_y() 00275 { 00276 m_row_ptr = m_pixf->row_ptr(++m_wrap_y); 00277 return m_row_ptr + m_wrap_x(m_x) * pix_width; 00278 } 00279 00280 private: 00281 const pixfmt_type* m_pixf; 00282 const int8u* m_row_ptr; 00283 int m_x; 00284 WrapX m_wrap_x; 00285 WrapY m_wrap_y; 00286 }; 00287 00288 00289 00290 00291 //--------------------------------------------------------wrap_mode_repeat 00292 class wrap_mode_repeat 00293 { 00294 public: 00295 wrap_mode_repeat() {} 00296 wrap_mode_repeat(unsigned size) : 00297 m_size(size), 00298 m_add(size * (0x3FFFFFFF / size)), 00299 m_value(0) 00300 {} 00301 00302 AGG_INLINE unsigned operator() (int v) 00303 { 00304 return m_value = (unsigned(v) + m_add) % m_size; 00305 } 00306 00307 AGG_INLINE unsigned operator++ () 00308 { 00309 ++m_value; 00310 if(m_value >= m_size) m_value = 0; 00311 return m_value; 00312 } 00313 private: 00314 unsigned m_size; 00315 unsigned m_add; 00316 unsigned m_value; 00317 }; 00318 00319 00320 //---------------------------------------------------wrap_mode_repeat_pow2 00321 class wrap_mode_repeat_pow2 00322 { 00323 public: 00324 wrap_mode_repeat_pow2() {} 00325 wrap_mode_repeat_pow2(unsigned size) : m_value(0) 00326 { 00327 m_mask = 1; 00328 while(m_mask < size) m_mask = (m_mask << 1) | 1; 00329 m_mask >>= 1; 00330 } 00331 AGG_INLINE unsigned operator() (int v) 00332 { 00333 return m_value = unsigned(v) & m_mask; 00334 } 00335 AGG_INLINE unsigned operator++ () 00336 { 00337 ++m_value; 00338 if(m_value > m_mask) m_value = 0; 00339 return m_value; 00340 } 00341 private: 00342 unsigned m_mask; 00343 unsigned m_value; 00344 }; 00345 00346 00347 //----------------------------------------------wrap_mode_repeat_auto_pow2 00348 class wrap_mode_repeat_auto_pow2 00349 { 00350 public: 00351 wrap_mode_repeat_auto_pow2() {} 00352 wrap_mode_repeat_auto_pow2(unsigned size) : 00353 m_size(size), 00354 m_add(size * (0x3FFFFFFF / size)), 00355 m_mask((m_size & (m_size-1)) ? 0 : m_size-1), 00356 m_value(0) 00357 {} 00358 00359 AGG_INLINE unsigned operator() (int v) 00360 { 00361 if(m_mask) return m_value = unsigned(v) & m_mask; 00362 return m_value = (unsigned(v) + m_add) % m_size; 00363 } 00364 AGG_INLINE unsigned operator++ () 00365 { 00366 ++m_value; 00367 if(m_value >= m_size) m_value = 0; 00368 return m_value; 00369 } 00370 00371 private: 00372 unsigned m_size; 00373 unsigned m_add; 00374 unsigned m_mask; 00375 unsigned m_value; 00376 }; 00377 00378 00379 //-------------------------------------------------------wrap_mode_reflect 00380 class wrap_mode_reflect 00381 { 00382 public: 00383 wrap_mode_reflect() {} 00384 wrap_mode_reflect(unsigned size) : 00385 m_size(size), 00386 m_size2(size * 2), 00387 m_add(m_size2 * (0x3FFFFFFF / m_size2)), 00388 m_value(0) 00389 {} 00390 00391 AGG_INLINE unsigned operator() (int v) 00392 { 00393 m_value = (unsigned(v) + m_add) % m_size2; 00394 if(m_value >= m_size) return m_size2 - m_value - 1; 00395 return m_value; 00396 } 00397 00398 AGG_INLINE unsigned operator++ () 00399 { 00400 ++m_value; 00401 if(m_value >= m_size2) m_value = 0; 00402 if(m_value >= m_size) return m_size2 - m_value - 1; 00403 return m_value; 00404 } 00405 private: 00406 unsigned m_size; 00407 unsigned m_size2; 00408 unsigned m_add; 00409 unsigned m_value; 00410 }; 00411 00412 00413 00414 //--------------------------------------------------wrap_mode_reflect_pow2 00415 class wrap_mode_reflect_pow2 00416 { 00417 public: 00418 wrap_mode_reflect_pow2() {} 00419 wrap_mode_reflect_pow2(unsigned size) : m_value(0) 00420 { 00421 m_mask = 1; 00422 m_size = 1; 00423 while(m_mask < size) 00424 { 00425 m_mask = (m_mask << 1) | 1; 00426 m_size <<= 1; 00427 } 00428 } 00429 AGG_INLINE unsigned operator() (int v) 00430 { 00431 m_value = unsigned(v) & m_mask; 00432 if(m_value >= m_size) return m_mask - m_value; 00433 return m_value; 00434 } 00435 AGG_INLINE unsigned operator++ () 00436 { 00437 ++m_value; 00438 m_value &= m_mask; 00439 if(m_value >= m_size) return m_mask - m_value; 00440 return m_value; 00441 } 00442 private: 00443 unsigned m_size; 00444 unsigned m_mask; 00445 unsigned m_value; 00446 }; 00447 00448 00449 00450 //---------------------------------------------wrap_mode_reflect_auto_pow2 00451 class wrap_mode_reflect_auto_pow2 00452 { 00453 public: 00454 wrap_mode_reflect_auto_pow2() {} 00455 wrap_mode_reflect_auto_pow2(unsigned size) : 00456 m_size(size), 00457 m_size2(size * 2), 00458 m_add(m_size2 * (0x3FFFFFFF / m_size2)), 00459 m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1), 00460 m_value(0) 00461 {} 00462 00463 AGG_INLINE unsigned operator() (int v) 00464 { 00465 m_value = m_mask ? unsigned(v) & m_mask : 00466 (unsigned(v) + m_add) % m_size2; 00467 if(m_value >= m_size) return m_size2 - m_value - 1; 00468 return m_value; 00469 } 00470 AGG_INLINE unsigned operator++ () 00471 { 00472 ++m_value; 00473 if(m_value >= m_size2) m_value = 0; 00474 if(m_value >= m_size) return m_size2 - m_value - 1; 00475 return m_value; 00476 } 00477 00478 private: 00479 unsigned m_size; 00480 unsigned m_size2; 00481 unsigned m_add; 00482 unsigned m_mask; 00483 unsigned m_value; 00484 }; 00485 00486 00487 } 00488 00489 00490 #endif