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 #ifndef AGG_PIXFMT_RGB_INCLUDED 00034 #define AGG_PIXFMT_RGB_INCLUDED 00035 00036 #include <string.h> 00037 #include "agg_basics.h" 00038 #include "agg_color_rgba.h" 00039 #include "agg_rendering_buffer.h" 00040 00041 namespace agg 00042 { 00043 00044 //=====================================================apply_gamma_dir_rgb 00045 template<class ColorT, class Order, class GammaLut> class apply_gamma_dir_rgb 00046 { 00047 public: 00048 typedef typename ColorT::value_type value_type; 00049 00050 apply_gamma_dir_rgb(const GammaLut& gamma) : m_gamma(gamma) {} 00051 00052 AGG_INLINE void operator () (value_type* p) 00053 { 00054 p[Order::R] = m_gamma.dir(p[Order::R]); 00055 p[Order::G] = m_gamma.dir(p[Order::G]); 00056 p[Order::B] = m_gamma.dir(p[Order::B]); 00057 } 00058 00059 private: 00060 const GammaLut& m_gamma; 00061 }; 00062 00063 00064 00065 //=====================================================apply_gamma_inv_rgb 00066 template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgb 00067 { 00068 public: 00069 typedef typename ColorT::value_type value_type; 00070 00071 apply_gamma_inv_rgb(const GammaLut& gamma) : m_gamma(gamma) {} 00072 00073 AGG_INLINE void operator () (value_type* p) 00074 { 00075 p[Order::R] = m_gamma.inv(p[Order::R]); 00076 p[Order::G] = m_gamma.inv(p[Order::G]); 00077 p[Order::B] = m_gamma.inv(p[Order::B]); 00078 } 00079 00080 private: 00081 const GammaLut& m_gamma; 00082 }; 00083 00084 00085 //=========================================================blender_rgb 00086 template<class ColorT, class Order> struct blender_rgb 00087 { 00088 typedef ColorT color_type; 00089 typedef Order order_type; 00090 typedef typename color_type::value_type value_type; 00091 typedef typename color_type::calc_type calc_type; 00092 enum base_scale_e { base_shift = color_type::base_shift }; 00093 00094 //-------------------------------------------------------------------- 00095 static AGG_INLINE void blend_pix(value_type* p, 00096 unsigned cr, unsigned cg, unsigned cb, 00097 unsigned alpha, 00098 unsigned cover=0) 00099 { 00100 p[Order::R] += (value_type)(((cr - p[Order::R]) * alpha) >> base_shift); 00101 p[Order::G] += (value_type)(((cg - p[Order::G]) * alpha) >> base_shift); 00102 p[Order::B] += (value_type)(((cb - p[Order::B]) * alpha) >> base_shift); 00103 } 00104 }; 00105 00106 00107 //======================================================blender_rgb_pre 00108 template<class ColorT, class Order> struct blender_rgb_pre 00109 { 00110 typedef ColorT color_type; 00111 typedef Order order_type; 00112 typedef typename color_type::value_type value_type; 00113 typedef typename color_type::calc_type calc_type; 00114 enum base_scale_e { base_shift = color_type::base_shift }; 00115 00116 //-------------------------------------------------------------------- 00117 static AGG_INLINE void blend_pix(value_type* p, 00118 unsigned cr, unsigned cg, unsigned cb, 00119 unsigned alpha, 00120 unsigned cover) 00121 { 00122 alpha = color_type::base_mask - alpha; 00123 cover = (cover + 1) << (base_shift - 8); 00124 p[Order::R] = (value_type)((p[Order::R] * alpha + cr * cover) >> base_shift); 00125 p[Order::G] = (value_type)((p[Order::G] * alpha + cg * cover) >> base_shift); 00126 p[Order::B] = (value_type)((p[Order::B] * alpha + cb * cover) >> base_shift); 00127 } 00128 00129 //-------------------------------------------------------------------- 00130 static AGG_INLINE void blend_pix(value_type* p, 00131 unsigned cr, unsigned cg, unsigned cb, 00132 unsigned alpha) 00133 { 00134 alpha = color_type::base_mask - alpha; 00135 p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr); 00136 p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg); 00137 p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb); 00138 } 00139 00140 }; 00141 00142 00143 00144 //===================================================blender_rgb_gamma 00145 template<class ColorT, class Order, class Gamma> class blender_rgb_gamma 00146 { 00147 public: 00148 typedef ColorT color_type; 00149 typedef Order order_type; 00150 typedef Gamma gamma_type; 00151 typedef typename color_type::value_type value_type; 00152 typedef typename color_type::calc_type calc_type; 00153 enum base_scale_e { base_shift = color_type::base_shift }; 00154 00155 //-------------------------------------------------------------------- 00156 blender_rgb_gamma() : m_gamma(0) {} 00157 void gamma(const gamma_type& g) { m_gamma = &g; } 00158 00159 //-------------------------------------------------------------------- 00160 AGG_INLINE void blend_pix(value_type* p, 00161 unsigned cr, unsigned cg, unsigned cb, 00162 unsigned alpha, 00163 unsigned cover=0) 00164 { 00165 calc_type r = m_gamma->dir(p[Order::R]); 00166 calc_type g = m_gamma->dir(p[Order::G]); 00167 calc_type b = m_gamma->dir(p[Order::B]); 00168 p[Order::R] = m_gamma->inv((((m_gamma->dir(cr) - r) * alpha) >> base_shift) + r); 00169 p[Order::G] = m_gamma->inv((((m_gamma->dir(cg) - g) * alpha) >> base_shift) + g); 00170 p[Order::B] = m_gamma->inv((((m_gamma->dir(cb) - b) * alpha) >> base_shift) + b); 00171 } 00172 00173 private: 00174 const gamma_type* m_gamma; 00175 }; 00176 00177 00178 00179 00180 //==================================================pixfmt_alpha_blend_rgb 00181 template<class Blender, class RenBuf> class pixfmt_alpha_blend_rgb 00182 { 00183 public: 00184 typedef RenBuf rbuf_type; 00185 typedef Blender blender_type; 00186 typedef typename rbuf_type::row_data row_data; 00187 typedef typename blender_type::color_type color_type; 00188 typedef typename blender_type::order_type order_type; 00189 typedef typename color_type::value_type value_type; 00190 typedef typename color_type::calc_type calc_type; 00191 enum base_scale_e 00192 { 00193 base_shift = color_type::base_shift, 00194 base_scale = color_type::base_scale, 00195 base_mask = color_type::base_mask, 00196 pix_width = sizeof(value_type) * 3 00197 }; 00198 00199 private: 00200 //-------------------------------------------------------------------- 00201 AGG_INLINE void copy_or_blend_pix(value_type* p, 00202 const color_type& c, 00203 unsigned cover) 00204 { 00205 if (c.a) 00206 { 00207 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; 00208 if(alpha == base_mask) 00209 { 00210 p[order_type::R] = c.r; 00211 p[order_type::G] = c.g; 00212 p[order_type::B] = c.b; 00213 } 00214 else 00215 { 00216 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); 00217 } 00218 } 00219 } 00220 00221 //-------------------------------------------------------------------- 00222 AGG_INLINE void copy_or_blend_pix(value_type* p, 00223 const color_type& c) 00224 { 00225 if (c.a) 00226 { 00227 if(c.a == base_mask) 00228 { 00229 p[order_type::R] = c.r; 00230 p[order_type::G] = c.g; 00231 p[order_type::B] = c.b; 00232 } 00233 else 00234 { 00235 m_blender.blend_pix(p, c.r, c.g, c.b, c.a); 00236 } 00237 } 00238 } 00239 00240 00241 public: 00242 //-------------------------------------------------------------------- 00243 explicit pixfmt_alpha_blend_rgb(rbuf_type& rb) : 00244 m_rbuf(&rb) 00245 {} 00246 void attach(rbuf_type& rb) { m_rbuf = &rb; } 00247 00248 //-------------------------------------------------------------------- 00249 template<class PixFmt> 00250 bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) 00251 { 00252 rect_i r(x1, y1, x2, y2); 00253 if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) 00254 { 00255 int stride = pixf.stride(); 00256 m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), 00257 (r.x2 - r.x1) + 1, 00258 (r.y2 - r.y1) + 1, 00259 stride); 00260 return true; 00261 } 00262 return false; 00263 } 00264 00265 //-------------------------------------------------------------------- 00266 Blender& blender() { return m_blender; } 00267 00268 //-------------------------------------------------------------------- 00269 AGG_INLINE unsigned width() const { return m_rbuf->width(); } 00270 AGG_INLINE unsigned height() const { return m_rbuf->height(); } 00271 AGG_INLINE int stride() const { return m_rbuf->stride(); } 00272 00273 //-------------------------------------------------------------------- 00274 AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } 00275 AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } 00276 AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); } 00277 00278 //-------------------------------------------------------------------- 00279 AGG_INLINE int8u* pix_ptr(int x, int y) 00280 { 00281 return m_rbuf->row_ptr(y) + x * pix_width; 00282 } 00283 00284 AGG_INLINE const int8u* pix_ptr(int x, int y) const 00285 { 00286 return m_rbuf->row_ptr(y) + x * pix_width; 00287 } 00288 00289 //-------------------------------------------------------------------- 00290 AGG_INLINE static void make_pix(int8u* p, const color_type& c) 00291 { 00292 ((value_type*)p)[order_type::R] = c.r; 00293 ((value_type*)p)[order_type::G] = c.g; 00294 ((value_type*)p)[order_type::B] = c.b; 00295 } 00296 00297 //-------------------------------------------------------------------- 00298 AGG_INLINE color_type pixel(int x, int y) const 00299 { 00300 value_type* p = (value_type*)m_rbuf->row_ptr(y) + x + x + x; 00301 return color_type(p[order_type::R], 00302 p[order_type::G], 00303 p[order_type::B]); 00304 } 00305 00306 //-------------------------------------------------------------------- 00307 AGG_INLINE void copy_pixel(int x, int y, const color_type& c) 00308 { 00309 value_type* p = (value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x; 00310 p[order_type::R] = c.r; 00311 p[order_type::G] = c.g; 00312 p[order_type::B] = c.b; 00313 } 00314 00315 //-------------------------------------------------------------------- 00316 AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) 00317 { 00318 copy_or_blend_pix((value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x, c, cover); 00319 } 00320 00321 00322 //-------------------------------------------------------------------- 00323 AGG_INLINE void copy_hline(int x, int y, 00324 unsigned len, 00325 const color_type& c) 00326 { 00327 value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + x + x + x; 00328 do 00329 { 00330 p[order_type::R] = c.r; 00331 p[order_type::G] = c.g; 00332 p[order_type::B] = c.b; 00333 p += 3; 00334 } 00335 while(--len); 00336 } 00337 00338 00339 //-------------------------------------------------------------------- 00340 AGG_INLINE void copy_vline(int x, int y, 00341 unsigned len, 00342 const color_type& c) 00343 { 00344 do 00345 { 00346 value_type* p = (value_type*) 00347 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 00348 p[order_type::R] = c.r; 00349 p[order_type::G] = c.g; 00350 p[order_type::B] = c.b; 00351 } 00352 while(--len); 00353 } 00354 00355 00356 //-------------------------------------------------------------------- 00357 void blend_hline(int x, int y, 00358 unsigned len, 00359 const color_type& c, 00360 int8u cover) 00361 { 00362 if (c.a) 00363 { 00364 value_type* p = (value_type*) 00365 m_rbuf->row_ptr(x, y, len) + x + x + x; 00366 00367 calc_type alpha = (calc_type(c.a) * (calc_type(cover) + 1)) >> 8; 00368 if(alpha == base_mask) 00369 { 00370 do 00371 { 00372 p[order_type::R] = c.r; 00373 p[order_type::G] = c.g; 00374 p[order_type::B] = c.b; 00375 p += 3; 00376 } 00377 while(--len); 00378 } 00379 else 00380 { 00381 do 00382 { 00383 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); 00384 p += 3; 00385 } 00386 while(--len); 00387 } 00388 } 00389 } 00390 00391 00392 //-------------------------------------------------------------------- 00393 void blend_vline(int x, int y, 00394 unsigned len, 00395 const color_type& c, 00396 int8u cover) 00397 { 00398 if (c.a) 00399 { 00400 value_type* p; 00401 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; 00402 if(alpha == base_mask) 00403 { 00404 do 00405 { 00406 p = (value_type*) 00407 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 00408 00409 p[order_type::R] = c.r; 00410 p[order_type::G] = c.g; 00411 p[order_type::B] = c.b; 00412 } 00413 while(--len); 00414 } 00415 else 00416 { 00417 do 00418 { 00419 p = (value_type*) 00420 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 00421 00422 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); 00423 } 00424 while(--len); 00425 } 00426 } 00427 } 00428 00429 00430 //-------------------------------------------------------------------- 00431 void blend_solid_hspan(int x, int y, 00432 unsigned len, 00433 const color_type& c, 00434 const int8u* covers) 00435 { 00436 if (c.a) 00437 { 00438 value_type* p = (value_type*) 00439 m_rbuf->row_ptr(x, y, len) + x + x + x; 00440 00441 do 00442 { 00443 calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8; 00444 if(alpha == base_mask) 00445 { 00446 p[order_type::R] = c.r; 00447 p[order_type::G] = c.g; 00448 p[order_type::B] = c.b; 00449 } 00450 else 00451 { 00452 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers); 00453 } 00454 p += 3; 00455 ++covers; 00456 } 00457 while(--len); 00458 } 00459 } 00460 00461 00462 //-------------------------------------------------------------------- 00463 void blend_solid_vspan(int x, int y, 00464 unsigned len, 00465 const color_type& c, 00466 const int8u* covers) 00467 { 00468 if (c.a) 00469 { 00470 do 00471 { 00472 value_type* p = (value_type*) 00473 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 00474 00475 calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8; 00476 if(alpha == base_mask) 00477 { 00478 p[order_type::R] = c.r; 00479 p[order_type::G] = c.g; 00480 p[order_type::B] = c.b; 00481 } 00482 else 00483 { 00484 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers); 00485 } 00486 ++covers; 00487 } 00488 while(--len); 00489 } 00490 } 00491 00492 00493 //-------------------------------------------------------------------- 00494 void copy_color_hspan(int x, int y, 00495 unsigned len, 00496 const color_type* colors) 00497 { 00498 value_type* p = (value_type*) 00499 m_rbuf->row_ptr(x, y, len) + x + x + x; 00500 00501 do 00502 { 00503 p[order_type::R] = colors->r; 00504 p[order_type::G] = colors->g; 00505 p[order_type::B] = colors->b; 00506 ++colors; 00507 p += 3; 00508 } 00509 while(--len); 00510 } 00511 00512 00513 //-------------------------------------------------------------------- 00514 void copy_color_vspan(int x, int y, 00515 unsigned len, 00516 const color_type* colors) 00517 { 00518 do 00519 { 00520 value_type* p = (value_type*) 00521 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 00522 p[order_type::R] = colors->r; 00523 p[order_type::G] = colors->g; 00524 p[order_type::B] = colors->b; 00525 ++colors; 00526 } 00527 while(--len); 00528 } 00529 00530 00531 //-------------------------------------------------------------------- 00532 void blend_color_hspan(int x, int y, 00533 unsigned len, 00534 const color_type* colors, 00535 const int8u* covers, 00536 int8u cover) 00537 { 00538 value_type* p = (value_type*) 00539 m_rbuf->row_ptr(x, y, len) + x + x + x; 00540 00541 if(covers) 00542 { 00543 do 00544 { 00545 copy_or_blend_pix(p, *colors++, *covers++); 00546 p += 3; 00547 } 00548 while(--len); 00549 } 00550 else 00551 { 00552 if(cover == 255) 00553 { 00554 do 00555 { 00556 copy_or_blend_pix(p, *colors++); 00557 p += 3; 00558 } 00559 while(--len); 00560 } 00561 else 00562 { 00563 do 00564 { 00565 copy_or_blend_pix(p, *colors++, cover); 00566 p += 3; 00567 } 00568 while(--len); 00569 } 00570 } 00571 } 00572 00573 00574 00575 //-------------------------------------------------------------------- 00576 void blend_color_vspan(int x, int y, 00577 unsigned len, 00578 const color_type* colors, 00579 const int8u* covers, 00580 int8u cover) 00581 { 00582 value_type* p; 00583 if(covers) 00584 { 00585 do 00586 { 00587 p = (value_type*) 00588 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 00589 00590 copy_or_blend_pix(p, *colors++, *covers++); 00591 } 00592 while(--len); 00593 } 00594 else 00595 { 00596 if(cover == 255) 00597 { 00598 do 00599 { 00600 p = (value_type*) 00601 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 00602 00603 copy_or_blend_pix(p, *colors++); 00604 } 00605 while(--len); 00606 } 00607 else 00608 { 00609 do 00610 { 00611 p = (value_type*) 00612 m_rbuf->row_ptr(x, y++, 1) + x + x + x; 00613 00614 copy_or_blend_pix(p, *colors++, cover); 00615 } 00616 while(--len); 00617 } 00618 } 00619 } 00620 00621 //-------------------------------------------------------------------- 00622 template<class Function> void for_each_pixel(Function f) 00623 { 00624 unsigned y; 00625 for(y = 0; y < height(); ++y) 00626 { 00627 row_data r = m_rbuf->row(y); 00628 if(r.ptr) 00629 { 00630 unsigned len = r.x2 - r.x1 + 1; 00631 value_type* p = (value_type*) 00632 m_rbuf->row_ptr(r.x1, y, len) + r.x1 * 3; 00633 do 00634 { 00635 f(p); 00636 p += 3; 00637 } 00638 while(--len); 00639 } 00640 } 00641 } 00642 00643 //-------------------------------------------------------------------- 00644 template<class GammaLut> void apply_gamma_dir(const GammaLut& g) 00645 { 00646 for_each_pixel(apply_gamma_dir_rgb<color_type, order_type, GammaLut>(g)); 00647 } 00648 00649 //-------------------------------------------------------------------- 00650 template<class GammaLut> void apply_gamma_inv(const GammaLut& g) 00651 { 00652 for_each_pixel(apply_gamma_inv_rgb<color_type, order_type, GammaLut>(g)); 00653 } 00654 00655 //-------------------------------------------------------------------- 00656 template<class RenBuf2> 00657 void copy_from(const RenBuf2& from, 00658 int xdst, int ydst, 00659 int xsrc, int ysrc, 00660 unsigned len) 00661 { 00662 const int8u* p = from.row_ptr(ysrc); 00663 if(p) 00664 { 00665 memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, 00666 p + xsrc * pix_width, 00667 len * pix_width); 00668 } 00669 } 00670 00671 00672 //-------------------------------------------------------------------- 00673 template<class SrcPixelFormatRenderer> 00674 void blend_from(const SrcPixelFormatRenderer& from, 00675 int xdst, int ydst, 00676 int xsrc, int ysrc, 00677 unsigned len, 00678 int8u cover) 00679 { 00680 typedef typename SrcPixelFormatRenderer::order_type src_order; 00681 00682 const value_type* psrc = (const value_type*)from.row_ptr(ysrc); 00683 if(psrc) 00684 { 00685 psrc += xsrc * 4; 00686 value_type* pdst = 00687 (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3; 00688 00689 if(cover == 255) 00690 { 00691 do 00692 { 00693 value_type alpha = psrc[src_order::A]; 00694 if(alpha) 00695 { 00696 if(alpha == base_mask) 00697 { 00698 pdst[order_type::R] = psrc[src_order::R]; 00699 pdst[order_type::G] = psrc[src_order::G]; 00700 pdst[order_type::B] = psrc[src_order::B]; 00701 } 00702 else 00703 { 00704 m_blender.blend_pix(pdst, 00705 psrc[src_order::R], 00706 psrc[src_order::G], 00707 psrc[src_order::B], 00708 alpha); 00709 } 00710 } 00711 psrc += 4; 00712 pdst += 3; 00713 } 00714 while(--len); 00715 } 00716 else 00717 { 00718 color_type color; 00719 do 00720 { 00721 color.r = psrc[src_order::R]; 00722 color.g = psrc[src_order::G]; 00723 color.b = psrc[src_order::B]; 00724 color.a = psrc[src_order::A]; 00725 copy_or_blend_pix(pdst, color, cover); 00726 psrc += 4; 00727 pdst += 3; 00728 } 00729 while(--len); 00730 } 00731 } 00732 } 00733 00734 //-------------------------------------------------------------------- 00735 template<class SrcPixelFormatRenderer> 00736 void blend_from_color(const SrcPixelFormatRenderer& from, 00737 const color_type& color, 00738 int xdst, int ydst, 00739 int xsrc, int ysrc, 00740 unsigned len, 00741 int8u cover) 00742 { 00743 typedef typename SrcPixelFormatRenderer::value_type src_value_type; 00744 const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); 00745 if(psrc) 00746 { 00747 value_type* pdst = 00748 (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3; 00749 do 00750 { 00751 copy_or_blend_pix(pdst, 00752 color, 00753 (*psrc * cover + base_mask) >> base_shift); 00754 ++psrc; 00755 pdst += 3; 00756 } 00757 while(--len); 00758 } 00759 } 00760 00761 //-------------------------------------------------------------------- 00762 template<class SrcPixelFormatRenderer> 00763 void blend_from_lut(const SrcPixelFormatRenderer& from, 00764 const color_type* color_lut, 00765 int xdst, int ydst, 00766 int xsrc, int ysrc, 00767 unsigned len, 00768 int8u cover) 00769 { 00770 typedef typename SrcPixelFormatRenderer::value_type src_value_type; 00771 const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); 00772 if(psrc) 00773 { 00774 value_type* pdst = 00775 (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3; 00776 00777 if(cover == 255) 00778 { 00779 do 00780 { 00781 const color_type& color = color_lut[*psrc]; 00782 m_blender.blend_pix(pdst, 00783 color.r, color.g, color.b, color.a); 00784 ++psrc; 00785 pdst += 3; 00786 } 00787 while(--len); 00788 } 00789 else 00790 { 00791 do 00792 { 00793 copy_or_blend_pix(pdst, color_lut[*psrc], cover); 00794 ++psrc; 00795 pdst += 3; 00796 } 00797 while(--len); 00798 } 00799 } 00800 } 00801 00802 private: 00803 rbuf_type* m_rbuf; 00804 Blender m_blender; 00805 }; 00806 00807 typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8, order_rgb>, rendering_buffer> pixfmt_rgb24; //----pixfmt_rgb24 00808 typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8, order_bgr>, rendering_buffer> pixfmt_bgr24; //----pixfmt_bgr24 00809 typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba16, order_rgb>, rendering_buffer> pixfmt_rgb48; //----pixfmt_rgb48 00810 typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba16, order_bgr>, rendering_buffer> pixfmt_bgr48; //----pixfmt_bgr48 00811 00812 typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba8, order_rgb>, rendering_buffer> pixfmt_rgb24_pre; //----pixfmt_rgb24_pre 00813 typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba8, order_bgr>, rendering_buffer> pixfmt_bgr24_pre; //----pixfmt_bgr24_pre 00814 typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba16, order_rgb>, rendering_buffer> pixfmt_rgb48_pre; //----pixfmt_rgb48_pre 00815 typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba16, order_bgr>, rendering_buffer> pixfmt_bgr48_pre; //----pixfmt_bgr48_pre 00816 00817 //-----------------------------------------------------pixfmt_rgb24_gamma 00818 template<class Gamma> class pixfmt_rgb24_gamma : 00819 public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer> 00820 { 00821 public: 00822 pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) : 00823 pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer>(rb) 00824 { 00825 this->blender().gamma(g); 00826 } 00827 }; 00828 00829 //-----------------------------------------------------pixfmt_bgr24_gamma 00830 template<class Gamma> class pixfmt_bgr24_gamma : 00831 public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer> 00832 { 00833 public: 00834 pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) : 00835 pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer>(rb) 00836 { 00837 this->blender().gamma(g); 00838 } 00839 }; 00840 00841 //-----------------------------------------------------pixfmt_rgb48_gamma 00842 template<class Gamma> class pixfmt_rgb48_gamma : 00843 public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer> 00844 { 00845 public: 00846 pixfmt_rgb48_gamma(rendering_buffer& rb, const Gamma& g) : 00847 pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer>(rb) 00848 { 00849 this->blender().gamma(g); 00850 } 00851 }; 00852 00853 //-----------------------------------------------------pixfmt_bgr48_gamma 00854 template<class Gamma> class pixfmt_bgr48_gamma : 00855 public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer> 00856 { 00857 public: 00858 pixfmt_bgr48_gamma(rendering_buffer& rb, const Gamma& g) : 00859 pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer>(rb) 00860 { 00861 this->blender().gamma(g); 00862 } 00863 }; 00864 00865 00866 } 00867 00868 #endif 00869