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_ALPHA_MASK_U8_INCLUDED 00026 #define AGG_ALPHA_MASK_U8_INCLUDED 00027 00028 #include <string.h> 00029 #include "agg_basics.h" 00030 #include "agg_rendering_buffer.h" 00031 00032 namespace agg 00033 { 00034 //===================================================one_component_mask_u8 00035 struct one_component_mask_u8 00036 { 00037 static unsigned calculate(const int8u* p) { return *p; } 00038 }; 00039 00040 00041 //=====================================================rgb_to_gray_mask_u8 00042 template<unsigned R, unsigned G, unsigned B> 00043 struct rgb_to_gray_mask_u8 00044 { 00045 static unsigned calculate(const int8u* p) 00046 { 00047 return (p[R]*77 + p[G]*150 + p[B]*29) >> 8; 00048 } 00049 }; 00050 00051 //==========================================================alpha_mask_u8 00052 template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8> 00053 class alpha_mask_u8 00054 { 00055 public: 00056 typedef int8u cover_type; 00057 typedef alpha_mask_u8<Step, Offset, MaskF> self_type; 00058 enum cover_scale_e 00059 { 00060 cover_shift = 8, 00061 cover_none = 0, 00062 cover_full = 255 00063 }; 00064 00065 alpha_mask_u8() : m_rbuf(0) {} 00066 explicit alpha_mask_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {} 00067 00068 void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; } 00069 00070 MaskF& mask_function() { return m_mask_function; } 00071 const MaskF& mask_function() const { return m_mask_function; } 00072 00073 00074 //-------------------------------------------------------------------- 00075 cover_type pixel(int x, int y) const 00076 { 00077 if(x >= 0 && y >= 0 && 00078 x < (int)m_rbuf->width() && 00079 y < (int)m_rbuf->height()) 00080 { 00081 return (cover_type)m_mask_function.calculate( 00082 m_rbuf->row_ptr(y) + x * Step + Offset); 00083 } 00084 return 0; 00085 } 00086 00087 //-------------------------------------------------------------------- 00088 cover_type combine_pixel(int x, int y, cover_type val) const 00089 { 00090 if(x >= 0 && y >= 0 && 00091 x < (int)m_rbuf->width() && 00092 y < (int)m_rbuf->height()) 00093 { 00094 return (cover_type)((cover_full + val * 00095 m_mask_function.calculate( 00096 m_rbuf->row_ptr(y) + x * Step + Offset)) >> 00097 cover_shift); 00098 } 00099 return 0; 00100 } 00101 00102 00103 //-------------------------------------------------------------------- 00104 void fill_hspan(int x, int y, cover_type* dst, int num_pix) const 00105 { 00106 int xmax = m_rbuf->width() - 1; 00107 int ymax = m_rbuf->height() - 1; 00108 00109 int count = num_pix; 00110 cover_type* covers = dst; 00111 00112 if(y < 0 || y > ymax) 00113 { 00114 memset(dst, 0, num_pix * sizeof(cover_type)); 00115 return; 00116 } 00117 00118 if(x < 0) 00119 { 00120 count += x; 00121 if(count <= 0) 00122 { 00123 memset(dst, 0, num_pix * sizeof(cover_type)); 00124 return; 00125 } 00126 memset(covers, 0, -x * sizeof(cover_type)); 00127 covers -= x; 00128 x = 0; 00129 } 00130 00131 if(x + count > xmax) 00132 { 00133 int rest = x + count - xmax - 1; 00134 count -= rest; 00135 if(count <= 0) 00136 { 00137 memset(dst, 0, num_pix * sizeof(cover_type)); 00138 return; 00139 } 00140 memset(covers + count, 0, rest * sizeof(cover_type)); 00141 } 00142 00143 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 00144 do 00145 { 00146 *covers++ = (cover_type)m_mask_function.calculate(mask); 00147 mask += Step; 00148 } 00149 while(--count); 00150 } 00151 00152 00153 //-------------------------------------------------------------------- 00154 void combine_hspan(int x, int y, cover_type* dst, int num_pix) const 00155 { 00156 int xmax = m_rbuf->width() - 1; 00157 int ymax = m_rbuf->height() - 1; 00158 00159 int count = num_pix; 00160 cover_type* covers = dst; 00161 00162 if(y < 0 || y > ymax) 00163 { 00164 memset(dst, 0, num_pix * sizeof(cover_type)); 00165 return; 00166 } 00167 00168 if(x < 0) 00169 { 00170 count += x; 00171 if(count <= 0) 00172 { 00173 memset(dst, 0, num_pix * sizeof(cover_type)); 00174 return; 00175 } 00176 memset(covers, 0, -x * sizeof(cover_type)); 00177 covers -= x; 00178 x = 0; 00179 } 00180 00181 if(x + count > xmax) 00182 { 00183 int rest = x + count - xmax - 1; 00184 count -= rest; 00185 if(count <= 0) 00186 { 00187 memset(dst, 0, num_pix * sizeof(cover_type)); 00188 return; 00189 } 00190 memset(covers + count, 0, rest * sizeof(cover_type)); 00191 } 00192 00193 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 00194 do 00195 { 00196 *covers = (cover_type)((cover_full + (*covers) * 00197 m_mask_function.calculate(mask)) >> 00198 cover_shift); 00199 ++covers; 00200 mask += Step; 00201 } 00202 while(--count); 00203 } 00204 00205 //-------------------------------------------------------------------- 00206 void fill_vspan(int x, int y, cover_type* dst, int num_pix) const 00207 { 00208 int xmax = m_rbuf->width() - 1; 00209 int ymax = m_rbuf->height() - 1; 00210 00211 int count = num_pix; 00212 cover_type* covers = dst; 00213 00214 if(x < 0 || x > xmax) 00215 { 00216 memset(dst, 0, num_pix * sizeof(cover_type)); 00217 return; 00218 } 00219 00220 if(y < 0) 00221 { 00222 count += y; 00223 if(count <= 0) 00224 { 00225 memset(dst, 0, num_pix * sizeof(cover_type)); 00226 return; 00227 } 00228 memset(covers, 0, -y * sizeof(cover_type)); 00229 covers -= y; 00230 y = 0; 00231 } 00232 00233 if(y + count > ymax) 00234 { 00235 int rest = y + count - ymax - 1; 00236 count -= rest; 00237 if(count <= 0) 00238 { 00239 memset(dst, 0, num_pix * sizeof(cover_type)); 00240 return; 00241 } 00242 memset(covers + count, 0, rest * sizeof(cover_type)); 00243 } 00244 00245 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 00246 do 00247 { 00248 *covers++ = (cover_type)m_mask_function.calculate(mask); 00249 mask += m_rbuf->stride(); 00250 } 00251 while(--count); 00252 } 00253 00254 //-------------------------------------------------------------------- 00255 void combine_vspan(int x, int y, cover_type* dst, int num_pix) const 00256 { 00257 int xmax = m_rbuf->width() - 1; 00258 int ymax = m_rbuf->height() - 1; 00259 00260 int count = num_pix; 00261 cover_type* covers = dst; 00262 00263 if(x < 0 || x > xmax) 00264 { 00265 memset(dst, 0, num_pix * sizeof(cover_type)); 00266 return; 00267 } 00268 00269 if(y < 0) 00270 { 00271 count += y; 00272 if(count <= 0) 00273 { 00274 memset(dst, 0, num_pix * sizeof(cover_type)); 00275 return; 00276 } 00277 memset(covers, 0, -y * sizeof(cover_type)); 00278 covers -= y; 00279 y = 0; 00280 } 00281 00282 if(y + count > ymax) 00283 { 00284 int rest = y + count - ymax - 1; 00285 count -= rest; 00286 if(count <= 0) 00287 { 00288 memset(dst, 0, num_pix * sizeof(cover_type)); 00289 return; 00290 } 00291 memset(covers + count, 0, rest * sizeof(cover_type)); 00292 } 00293 00294 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 00295 do 00296 { 00297 *covers = (cover_type)((cover_full + (*covers) * 00298 m_mask_function.calculate(mask)) >> 00299 cover_shift); 00300 ++covers; 00301 mask += m_rbuf->stride(); 00302 } 00303 while(--count); 00304 } 00305 00306 00307 private: 00308 alpha_mask_u8(const self_type&); 00309 const self_type& operator = (const self_type&); 00310 00311 rendering_buffer* m_rbuf; 00312 MaskF m_mask_function; 00313 }; 00314 00315 00316 typedef alpha_mask_u8<1, 0> alpha_mask_gray8; //----alpha_mask_gray8 00317 00318 typedef alpha_mask_u8<3, 0> alpha_mask_rgb24r; //----alpha_mask_rgb24r 00319 typedef alpha_mask_u8<3, 1> alpha_mask_rgb24g; //----alpha_mask_rgb24g 00320 typedef alpha_mask_u8<3, 2> alpha_mask_rgb24b; //----alpha_mask_rgb24b 00321 00322 typedef alpha_mask_u8<3, 2> alpha_mask_bgr24r; //----alpha_mask_bgr24r 00323 typedef alpha_mask_u8<3, 1> alpha_mask_bgr24g; //----alpha_mask_bgr24g 00324 typedef alpha_mask_u8<3, 0> alpha_mask_bgr24b; //----alpha_mask_bgr24b 00325 00326 typedef alpha_mask_u8<4, 0> alpha_mask_rgba32r; //----alpha_mask_rgba32r 00327 typedef alpha_mask_u8<4, 1> alpha_mask_rgba32g; //----alpha_mask_rgba32g 00328 typedef alpha_mask_u8<4, 2> alpha_mask_rgba32b; //----alpha_mask_rgba32b 00329 typedef alpha_mask_u8<4, 3> alpha_mask_rgba32a; //----alpha_mask_rgba32a 00330 00331 typedef alpha_mask_u8<4, 1> alpha_mask_argb32r; //----alpha_mask_argb32r 00332 typedef alpha_mask_u8<4, 2> alpha_mask_argb32g; //----alpha_mask_argb32g 00333 typedef alpha_mask_u8<4, 3> alpha_mask_argb32b; //----alpha_mask_argb32b 00334 typedef alpha_mask_u8<4, 0> alpha_mask_argb32a; //----alpha_mask_argb32a 00335 00336 typedef alpha_mask_u8<4, 2> alpha_mask_bgra32r; //----alpha_mask_bgra32r 00337 typedef alpha_mask_u8<4, 1> alpha_mask_bgra32g; //----alpha_mask_bgra32g 00338 typedef alpha_mask_u8<4, 0> alpha_mask_bgra32b; //----alpha_mask_bgra32b 00339 typedef alpha_mask_u8<4, 3> alpha_mask_bgra32a; //----alpha_mask_bgra32a 00340 00341 typedef alpha_mask_u8<4, 3> alpha_mask_abgr32r; //----alpha_mask_abgr32r 00342 typedef alpha_mask_u8<4, 2> alpha_mask_abgr32g; //----alpha_mask_abgr32g 00343 typedef alpha_mask_u8<4, 1> alpha_mask_abgr32b; //----alpha_mask_abgr32b 00344 typedef alpha_mask_u8<4, 0> alpha_mask_abgr32a; //----alpha_mask_abgr32a 00345 00346 typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgb24gray; //----alpha_mask_rgb24gray 00347 typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgr24gray; //----alpha_mask_bgr24gray 00348 typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgba32gray; //----alpha_mask_rgba32gray 00349 typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_argb32gray; //----alpha_mask_argb32gray 00350 typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgra32gray; //----alpha_mask_bgra32gray 00351 typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_abgr32gray; //----alpha_mask_abgr32gray 00352 00353 00354 00355 //==========================================================amask_no_clip_u8 00356 template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8> 00357 class amask_no_clip_u8 00358 { 00359 public: 00360 typedef int8u cover_type; 00361 typedef amask_no_clip_u8<Step, Offset, MaskF> self_type; 00362 enum cover_scale_e 00363 { 00364 cover_shift = 8, 00365 cover_none = 0, 00366 cover_full = 255 00367 }; 00368 00369 amask_no_clip_u8() : m_rbuf(0) {} 00370 explicit amask_no_clip_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {} 00371 00372 void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; } 00373 00374 MaskF& mask_function() { return m_mask_function; } 00375 const MaskF& mask_function() const { return m_mask_function; } 00376 00377 00378 //-------------------------------------------------------------------- 00379 cover_type pixel(int x, int y) const 00380 { 00381 return (cover_type)m_mask_function.calculate( 00382 m_rbuf->row_ptr(y) + x * Step + Offset); 00383 } 00384 00385 00386 //-------------------------------------------------------------------- 00387 cover_type combine_pixel(int x, int y, cover_type val) const 00388 { 00389 return (cover_type)((cover_full + val * 00390 m_mask_function.calculate( 00391 m_rbuf->row_ptr(y) + x * Step + Offset)) >> 00392 cover_shift); 00393 } 00394 00395 00396 //-------------------------------------------------------------------- 00397 void fill_hspan(int x, int y, cover_type* dst, int num_pix) const 00398 { 00399 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 00400 do 00401 { 00402 *dst++ = (cover_type)m_mask_function.calculate(mask); 00403 mask += Step; 00404 } 00405 while(--num_pix); 00406 } 00407 00408 00409 00410 //-------------------------------------------------------------------- 00411 void combine_hspan(int x, int y, cover_type* dst, int num_pix) const 00412 { 00413 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 00414 do 00415 { 00416 *dst = (cover_type)((cover_full + (*dst) * 00417 m_mask_function.calculate(mask)) >> 00418 cover_shift); 00419 ++dst; 00420 mask += Step; 00421 } 00422 while(--num_pix); 00423 } 00424 00425 00426 //-------------------------------------------------------------------- 00427 void fill_vspan(int x, int y, cover_type* dst, int num_pix) const 00428 { 00429 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 00430 do 00431 { 00432 *dst++ = (cover_type)m_mask_function.calculate(mask); 00433 mask += m_rbuf->stride(); 00434 } 00435 while(--num_pix); 00436 } 00437 00438 00439 //-------------------------------------------------------------------- 00440 void combine_vspan(int x, int y, cover_type* dst, int num_pix) const 00441 { 00442 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 00443 do 00444 { 00445 *dst = (cover_type)((cover_full + (*dst) * 00446 m_mask_function.calculate(mask)) >> 00447 cover_shift); 00448 ++dst; 00449 mask += m_rbuf->stride(); 00450 } 00451 while(--num_pix); 00452 } 00453 00454 private: 00455 amask_no_clip_u8(const self_type&); 00456 const self_type& operator = (const self_type&); 00457 00458 rendering_buffer* m_rbuf; 00459 MaskF m_mask_function; 00460 }; 00461 00462 00463 typedef amask_no_clip_u8<1, 0> amask_no_clip_gray8; //----amask_no_clip_gray8 00464 00465 typedef amask_no_clip_u8<3, 0> amask_no_clip_rgb24r; //----amask_no_clip_rgb24r 00466 typedef amask_no_clip_u8<3, 1> amask_no_clip_rgb24g; //----amask_no_clip_rgb24g 00467 typedef amask_no_clip_u8<3, 2> amask_no_clip_rgb24b; //----amask_no_clip_rgb24b 00468 00469 typedef amask_no_clip_u8<3, 2> amask_no_clip_bgr24r; //----amask_no_clip_bgr24r 00470 typedef amask_no_clip_u8<3, 1> amask_no_clip_bgr24g; //----amask_no_clip_bgr24g 00471 typedef amask_no_clip_u8<3, 0> amask_no_clip_bgr24b; //----amask_no_clip_bgr24b 00472 00473 typedef amask_no_clip_u8<4, 0> amask_no_clip_rgba32r; //----amask_no_clip_rgba32r 00474 typedef amask_no_clip_u8<4, 1> amask_no_clip_rgba32g; //----amask_no_clip_rgba32g 00475 typedef amask_no_clip_u8<4, 2> amask_no_clip_rgba32b; //----amask_no_clip_rgba32b 00476 typedef amask_no_clip_u8<4, 3> amask_no_clip_rgba32a; //----amask_no_clip_rgba32a 00477 00478 typedef amask_no_clip_u8<4, 1> amask_no_clip_argb32r; //----amask_no_clip_argb32r 00479 typedef amask_no_clip_u8<4, 2> amask_no_clip_argb32g; //----amask_no_clip_argb32g 00480 typedef amask_no_clip_u8<4, 3> amask_no_clip_argb32b; //----amask_no_clip_argb32b 00481 typedef amask_no_clip_u8<4, 0> amask_no_clip_argb32a; //----amask_no_clip_argb32a 00482 00483 typedef amask_no_clip_u8<4, 2> amask_no_clip_bgra32r; //----amask_no_clip_bgra32r 00484 typedef amask_no_clip_u8<4, 1> amask_no_clip_bgra32g; //----amask_no_clip_bgra32g 00485 typedef amask_no_clip_u8<4, 0> amask_no_clip_bgra32b; //----amask_no_clip_bgra32b 00486 typedef amask_no_clip_u8<4, 3> amask_no_clip_bgra32a; //----amask_no_clip_bgra32a 00487 00488 typedef amask_no_clip_u8<4, 3> amask_no_clip_abgr32r; //----amask_no_clip_abgr32r 00489 typedef amask_no_clip_u8<4, 2> amask_no_clip_abgr32g; //----amask_no_clip_abgr32g 00490 typedef amask_no_clip_u8<4, 1> amask_no_clip_abgr32b; //----amask_no_clip_abgr32b 00491 typedef amask_no_clip_u8<4, 0> amask_no_clip_abgr32a; //----amask_no_clip_abgr32a 00492 00493 typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgb24gray; //----amask_no_clip_rgb24gray 00494 typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgr24gray; //----amask_no_clip_bgr24gray 00495 typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgba32gray; //----amask_no_clip_rgba32gray 00496 typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_argb32gray; //----amask_no_clip_argb32gray 00497 typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgra32gray; //----amask_no_clip_bgra32gray 00498 typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_abgr32gray; //----amask_no_clip_abgr32gray 00499 00500 00501 } 00502 00503 00504 00505 #endif