1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.4 3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 4 // 5 // Permission to copy, use, modify, sell and distribute this software 6 // is granted provided this copyright notice appears in all copies. 7 // This software is provided "as is" without express or implied 8 // warranty, and with no claim as to its suitability for any purpose. 9 // 10 //---------------------------------------------------------------------------- 11 // Contact: mcseem@antigrain.com 12 // mcseemagg@yahoo.com 13 // http://www.antigrain.com 14 //---------------------------------------------------------------------------- 15 // 16 // scanline_u8 class 17 // 18 //---------------------------------------------------------------------------- 19 #ifndef AGG_ALPHA_MASK_U8_INCLUDED 20 #define AGG_ALPHA_MASK_U8_INCLUDED 21 22 #include <string.h> 23 #include "agg_basics.h" 24 #include "agg_rendering_buffer.h" 25 26 namespace agg 27 { 28 //===================================================one_component_mask_u8 29 struct one_component_mask_u8 30 { 31 static unsigned calculate(const int8u* p) { return *p; } 32 }; 33 34 35 //=====================================================rgb_to_gray_mask_u8 36 template<unsigned R, unsigned G, unsigned B> 37 struct rgb_to_gray_mask_u8 38 { 39 static unsigned calculate(const int8u* p) 40 { 41 return (p[R]*77 + p[G]*150 + p[B]*29) >> 8; 42 } 43 }; 44 45 //==========================================================alpha_mask_u8 46 template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8> 47 class alpha_mask_u8 48 { 49 public: 50 typedef int8u cover_type; 51 typedef alpha_mask_u8<Step, Offset, MaskF> self_type; 52 enum cover_scale_e 53 { 54 cover_shift = 8, 55 cover_none = 0, 56 cover_full = 255 57 }; 58 59 alpha_mask_u8() : m_rbuf(0) {} 60 alpha_mask_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {} 61 62 void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; } 63 64 MaskF& mask_function() { return m_mask_function; } 65 const MaskF& mask_function() const { return m_mask_function; } 66 67 68 //-------------------------------------------------------------------- 69 cover_type pixel(int x, int y) const 70 { 71 if(x >= 0 && y >= 0 && 72 x < (int)m_rbuf->width() && 73 y < (int)m_rbuf->height()) 74 { 75 return (cover_type)m_mask_function.calculate( 76 m_rbuf->row_ptr(y) + x * Step + Offset); 77 } 78 return 0; 79 } 80 81 //-------------------------------------------------------------------- 82 cover_type combine_pixel(int x, int y, cover_type val) const 83 { 84 if(x >= 0 && y >= 0 && 85 x < (int)m_rbuf->width() && 86 y < (int)m_rbuf->height()) 87 { 88 return (cover_type)((cover_full + val * 89 m_mask_function.calculate( 90 m_rbuf->row_ptr(y) + x * Step + Offset)) >> 91 cover_shift); 92 } 93 return 0; 94 } 95 96 97 //-------------------------------------------------------------------- 98 void fill_hspan(int x, int y, cover_type* dst, int num_pix) const 99 { 100 int xmax = m_rbuf->width() - 1; 101 int ymax = m_rbuf->height() - 1; 102 103 int count = num_pix; 104 cover_type* covers = dst; 105 106 if(y < 0 || y > ymax) 107 { 108 memset(dst, 0, num_pix * sizeof(cover_type)); 109 return; 110 } 111 112 if(x < 0) 113 { 114 count += x; 115 if(count <= 0) 116 { 117 memset(dst, 0, num_pix * sizeof(cover_type)); 118 return; 119 } 120 memset(covers, 0, -x * sizeof(cover_type)); 121 covers -= x; 122 x = 0; 123 } 124 125 if(x + count > xmax) 126 { 127 int rest = x + count - xmax - 1; 128 count -= rest; 129 if(count <= 0) 130 { 131 memset(dst, 0, num_pix * sizeof(cover_type)); 132 return; 133 } 134 memset(covers + count, 0, rest * sizeof(cover_type)); 135 } 136 137 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 138 do 139 { 140 *covers++ = (cover_type)m_mask_function.calculate(mask); 141 mask += Step; 142 } 143 while(--count); 144 } 145 146 147 //-------------------------------------------------------------------- 148 void combine_hspan(int x, int y, cover_type* dst, int num_pix) const 149 { 150 int xmax = m_rbuf->width() - 1; 151 int ymax = m_rbuf->height() - 1; 152 153 int count = num_pix; 154 cover_type* covers = dst; 155 156 if(y < 0 || y > ymax) 157 { 158 memset(dst, 0, num_pix * sizeof(cover_type)); 159 return; 160 } 161 162 if(x < 0) 163 { 164 count += x; 165 if(count <= 0) 166 { 167 memset(dst, 0, num_pix * sizeof(cover_type)); 168 return; 169 } 170 memset(covers, 0, -x * sizeof(cover_type)); 171 covers -= x; 172 x = 0; 173 } 174 175 if(x + count > xmax) 176 { 177 int rest = x + count - xmax - 1; 178 count -= rest; 179 if(count <= 0) 180 { 181 memset(dst, 0, num_pix * sizeof(cover_type)); 182 return; 183 } 184 memset(covers + count, 0, rest * sizeof(cover_type)); 185 } 186 187 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 188 do 189 { 190 *covers = (cover_type)((cover_full + (*covers) * 191 m_mask_function.calculate(mask)) >> 192 cover_shift); 193 ++covers; 194 mask += Step; 195 } 196 while(--count); 197 } 198 199 //-------------------------------------------------------------------- 200 void fill_vspan(int x, int y, cover_type* dst, int num_pix) const 201 { 202 int xmax = m_rbuf->width() - 1; 203 int ymax = m_rbuf->height() - 1; 204 205 int count = num_pix; 206 cover_type* covers = dst; 207 208 if(x < 0 || x > xmax) 209 { 210 memset(dst, 0, num_pix * sizeof(cover_type)); 211 return; 212 } 213 214 if(y < 0) 215 { 216 count += y; 217 if(count <= 0) 218 { 219 memset(dst, 0, num_pix * sizeof(cover_type)); 220 return; 221 } 222 memset(covers, 0, -y * sizeof(cover_type)); 223 covers -= y; 224 y = 0; 225 } 226 227 if(y + count > ymax) 228 { 229 int rest = y + count - ymax - 1; 230 count -= rest; 231 if(count <= 0) 232 { 233 memset(dst, 0, num_pix * sizeof(cover_type)); 234 return; 235 } 236 memset(covers + count, 0, rest * sizeof(cover_type)); 237 } 238 239 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 240 do 241 { 242 *covers++ = (cover_type)m_mask_function.calculate(mask); 243 mask += m_rbuf->stride(); 244 } 245 while(--count); 246 } 247 248 //-------------------------------------------------------------------- 249 void combine_vspan(int x, int y, cover_type* dst, int num_pix) const 250 { 251 int xmax = m_rbuf->width() - 1; 252 int ymax = m_rbuf->height() - 1; 253 254 int count = num_pix; 255 cover_type* covers = dst; 256 257 if(x < 0 || x > xmax) 258 { 259 memset(dst, 0, num_pix * sizeof(cover_type)); 260 return; 261 } 262 263 if(y < 0) 264 { 265 count += y; 266 if(count <= 0) 267 { 268 memset(dst, 0, num_pix * sizeof(cover_type)); 269 return; 270 } 271 memset(covers, 0, -y * sizeof(cover_type)); 272 covers -= y; 273 y = 0; 274 } 275 276 if(y + count > ymax) 277 { 278 int rest = y + count - ymax - 1; 279 count -= rest; 280 if(count <= 0) 281 { 282 memset(dst, 0, num_pix * sizeof(cover_type)); 283 return; 284 } 285 memset(covers + count, 0, rest * sizeof(cover_type)); 286 } 287 288 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 289 do 290 { 291 *covers = (cover_type)((cover_full + (*covers) * 292 m_mask_function.calculate(mask)) >> 293 cover_shift); 294 ++covers; 295 mask += m_rbuf->stride(); 296 } 297 while(--count); 298 } 299 300 301 private: 302 alpha_mask_u8(const self_type&); 303 const self_type& operator = (const self_type&); 304 305 rendering_buffer* m_rbuf; 306 MaskF m_mask_function; 307 }; 308 309 310 typedef alpha_mask_u8<1, 0> alpha_mask_gray8; //----alpha_mask_gray8 311 312 typedef alpha_mask_u8<3, 0> alpha_mask_rgb24r; //----alpha_mask_rgb24r 313 typedef alpha_mask_u8<3, 1> alpha_mask_rgb24g; //----alpha_mask_rgb24g 314 typedef alpha_mask_u8<3, 2> alpha_mask_rgb24b; //----alpha_mask_rgb24b 315 316 typedef alpha_mask_u8<3, 2> alpha_mask_bgr24r; //----alpha_mask_bgr24r 317 typedef alpha_mask_u8<3, 1> alpha_mask_bgr24g; //----alpha_mask_bgr24g 318 typedef alpha_mask_u8<3, 0> alpha_mask_bgr24b; //----alpha_mask_bgr24b 319 320 typedef alpha_mask_u8<4, 0> alpha_mask_rgba32r; //----alpha_mask_rgba32r 321 typedef alpha_mask_u8<4, 1> alpha_mask_rgba32g; //----alpha_mask_rgba32g 322 typedef alpha_mask_u8<4, 2> alpha_mask_rgba32b; //----alpha_mask_rgba32b 323 typedef alpha_mask_u8<4, 3> alpha_mask_rgba32a; //----alpha_mask_rgba32a 324 325 typedef alpha_mask_u8<4, 1> alpha_mask_argb32r; //----alpha_mask_argb32r 326 typedef alpha_mask_u8<4, 2> alpha_mask_argb32g; //----alpha_mask_argb32g 327 typedef alpha_mask_u8<4, 3> alpha_mask_argb32b; //----alpha_mask_argb32b 328 typedef alpha_mask_u8<4, 0> alpha_mask_argb32a; //----alpha_mask_argb32a 329 330 typedef alpha_mask_u8<4, 2> alpha_mask_bgra32r; //----alpha_mask_bgra32r 331 typedef alpha_mask_u8<4, 1> alpha_mask_bgra32g; //----alpha_mask_bgra32g 332 typedef alpha_mask_u8<4, 0> alpha_mask_bgra32b; //----alpha_mask_bgra32b 333 typedef alpha_mask_u8<4, 3> alpha_mask_bgra32a; //----alpha_mask_bgra32a 334 335 typedef alpha_mask_u8<4, 3> alpha_mask_abgr32r; //----alpha_mask_abgr32r 336 typedef alpha_mask_u8<4, 2> alpha_mask_abgr32g; //----alpha_mask_abgr32g 337 typedef alpha_mask_u8<4, 1> alpha_mask_abgr32b; //----alpha_mask_abgr32b 338 typedef alpha_mask_u8<4, 0> alpha_mask_abgr32a; //----alpha_mask_abgr32a 339 340 typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgb24gray; //----alpha_mask_rgb24gray 341 typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgr24gray; //----alpha_mask_bgr24gray 342 typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgba32gray; //----alpha_mask_rgba32gray 343 typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_argb32gray; //----alpha_mask_argb32gray 344 typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgra32gray; //----alpha_mask_bgra32gray 345 typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_abgr32gray; //----alpha_mask_abgr32gray 346 347 348 349 //==========================================================amask_no_clip_u8 350 template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8> 351 class amask_no_clip_u8 352 { 353 public: 354 typedef int8u cover_type; 355 typedef amask_no_clip_u8<Step, Offset, MaskF> self_type; 356 enum cover_scale_e 357 { 358 cover_shift = 8, 359 cover_none = 0, 360 cover_full = 255 361 }; 362 363 amask_no_clip_u8() : m_rbuf(0) {} 364 amask_no_clip_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {} 365 366 void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; } 367 368 MaskF& mask_function() { return m_mask_function; } 369 const MaskF& mask_function() const { return m_mask_function; } 370 371 372 //-------------------------------------------------------------------- 373 cover_type pixel(int x, int y) const 374 { 375 return (cover_type)m_mask_function.calculate( 376 m_rbuf->row_ptr(y) + x * Step + Offset); 377 } 378 379 380 //-------------------------------------------------------------------- 381 cover_type combine_pixel(int x, int y, cover_type val) const 382 { 383 return (cover_type)((cover_full + val * 384 m_mask_function.calculate( 385 m_rbuf->row_ptr(y) + x * Step + Offset)) >> 386 cover_shift); 387 } 388 389 390 //-------------------------------------------------------------------- 391 void fill_hspan(int x, int y, cover_type* dst, int num_pix) const 392 { 393 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 394 do 395 { 396 *dst++ = (cover_type)m_mask_function.calculate(mask); 397 mask += Step; 398 } 399 while(--num_pix); 400 } 401 402 403 404 //-------------------------------------------------------------------- 405 void combine_hspan(int x, int y, cover_type* dst, int num_pix) const 406 { 407 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 408 do 409 { 410 *dst = (cover_type)((cover_full + (*dst) * 411 m_mask_function.calculate(mask)) >> 412 cover_shift); 413 ++dst; 414 mask += Step; 415 } 416 while(--num_pix); 417 } 418 419 420 //-------------------------------------------------------------------- 421 void fill_vspan(int x, int y, cover_type* dst, int num_pix) const 422 { 423 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 424 do 425 { 426 *dst++ = (cover_type)m_mask_function.calculate(mask); 427 mask += m_rbuf->stride(); 428 } 429 while(--num_pix); 430 } 431 432 433 //-------------------------------------------------------------------- 434 void combine_vspan(int x, int y, cover_type* dst, int num_pix) const 435 { 436 const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; 437 do 438 { 439 *dst = (cover_type)((cover_full + (*dst) * 440 m_mask_function.calculate(mask)) >> 441 cover_shift); 442 ++dst; 443 mask += m_rbuf->stride(); 444 } 445 while(--num_pix); 446 } 447 448 private: 449 amask_no_clip_u8(const self_type&); 450 const self_type& operator = (const self_type&); 451 452 rendering_buffer* m_rbuf; 453 MaskF m_mask_function; 454 }; 455 456 457 typedef amask_no_clip_u8<1, 0> amask_no_clip_gray8; //----amask_no_clip_gray8 458 459 typedef amask_no_clip_u8<3, 0> amask_no_clip_rgb24r; //----amask_no_clip_rgb24r 460 typedef amask_no_clip_u8<3, 1> amask_no_clip_rgb24g; //----amask_no_clip_rgb24g 461 typedef amask_no_clip_u8<3, 2> amask_no_clip_rgb24b; //----amask_no_clip_rgb24b 462 463 typedef amask_no_clip_u8<3, 2> amask_no_clip_bgr24r; //----amask_no_clip_bgr24r 464 typedef amask_no_clip_u8<3, 1> amask_no_clip_bgr24g; //----amask_no_clip_bgr24g 465 typedef amask_no_clip_u8<3, 0> amask_no_clip_bgr24b; //----amask_no_clip_bgr24b 466 467 typedef amask_no_clip_u8<4, 0> amask_no_clip_rgba32r; //----amask_no_clip_rgba32r 468 typedef amask_no_clip_u8<4, 1> amask_no_clip_rgba32g; //----amask_no_clip_rgba32g 469 typedef amask_no_clip_u8<4, 2> amask_no_clip_rgba32b; //----amask_no_clip_rgba32b 470 typedef amask_no_clip_u8<4, 3> amask_no_clip_rgba32a; //----amask_no_clip_rgba32a 471 472 typedef amask_no_clip_u8<4, 1> amask_no_clip_argb32r; //----amask_no_clip_argb32r 473 typedef amask_no_clip_u8<4, 2> amask_no_clip_argb32g; //----amask_no_clip_argb32g 474 typedef amask_no_clip_u8<4, 3> amask_no_clip_argb32b; //----amask_no_clip_argb32b 475 typedef amask_no_clip_u8<4, 0> amask_no_clip_argb32a; //----amask_no_clip_argb32a 476 477 typedef amask_no_clip_u8<4, 2> amask_no_clip_bgra32r; //----amask_no_clip_bgra32r 478 typedef amask_no_clip_u8<4, 1> amask_no_clip_bgra32g; //----amask_no_clip_bgra32g 479 typedef amask_no_clip_u8<4, 0> amask_no_clip_bgra32b; //----amask_no_clip_bgra32b 480 typedef amask_no_clip_u8<4, 3> amask_no_clip_bgra32a; //----amask_no_clip_bgra32a 481 482 typedef amask_no_clip_u8<4, 3> amask_no_clip_abgr32r; //----amask_no_clip_abgr32r 483 typedef amask_no_clip_u8<4, 2> amask_no_clip_abgr32g; //----amask_no_clip_abgr32g 484 typedef amask_no_clip_u8<4, 1> amask_no_clip_abgr32b; //----amask_no_clip_abgr32b 485 typedef amask_no_clip_u8<4, 0> amask_no_clip_abgr32a; //----amask_no_clip_abgr32a 486 487 typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgb24gray; //----amask_no_clip_rgb24gray 488 typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgr24gray; //----amask_no_clip_bgr24gray 489 typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgba32gray; //----amask_no_clip_rgba32gray 490 typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_argb32gray; //----amask_no_clip_argb32gray 491 typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgra32gray; //----amask_no_clip_bgra32gray 492 typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_abgr32gray; //----amask_no_clip_abgr32gray 493 494 495 } 496 497 498 499 #endif 500