Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_pixfmt_rgb.h
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines