Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | Related Pages | Examples

agg_pixfmt_rgba32.h

00001 //----------------------------------------------------------------------------
00002 // Anti-Grain Geometry - Version 2.2
00003 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
00004 //
00005 // Permission to copy, use, modify, sell and distribute this software 
00006 // is granted provided this copyright notice appears in all copies. 
00007 // This software is provided "as is" without express or implied
00008 // warranty, and with no claim as to its suitability for any purpose.
00009 //
00010 //----------------------------------------------------------------------------
00011 // Contact: mcseem@antigrain.com
00012 //          mcseemagg@yahoo.com
00013 //          http://www.antigrain.com
00014 //----------------------------------------------------------------------------
00015 
00016 #ifndef AGG_PIXFMT_RGBA32_INCLUDED
00017 #define AGG_PIXFMT_RGBA32_INCLUDED
00018 
00019 #include <string.h>
00020 #include "agg_basics.h"
00021 #include "agg_color_rgba8.h"
00022 #include "agg_rendering_buffer.h"
00023 
00024 namespace agg
00025 {
00026 
00027     //====================================================pixel_formats_rgba32
00028     template<class Order> class pixel_formats_rgba32
00029     {
00030     public:
00031         typedef rgba8 color_type;
00032         typedef Order order_type;
00033         typedef rendering_buffer::row_data row_data;
00034 
00035         //--------------------------------------------------------------------
00036         pixel_formats_rgba32(rendering_buffer& rb)
00037             : m_rbuf(&rb)
00038         {
00039         }
00040 
00041         //--------------------------------------------------------------------
00042         unsigned width()  const { return m_rbuf->width();  }
00043         unsigned height() const { return m_rbuf->height(); }
00044 
00045         //--------------------------------------------------------------------
00046         color_type pixel(int x, int y) const
00047         {
00048             int8u* p = m_rbuf->row(y) + (x << 2);
00049             return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
00050         }
00051 
00052         //--------------------------------------------------------------------
00053         row_data span(int x, int y) const
00054         {
00055             return row_data(x, width() - 1, m_rbuf->row(y) + (x << 2));
00056         }
00057 
00058         //--------------------------------------------------------------------
00059         void copy_pixel(int x, int y, const color_type& c)
00060         {
00061             int8u* p = m_rbuf->row(y) + (x << 2);
00062             p[Order::R] = (int8u)c.r;
00063             p[Order::G] = (int8u)c.g;
00064             p[Order::B] = (int8u)c.b;
00065             p[Order::A] = (int8u)c.a;
00066         }
00067 
00068         //--------------------------------------------------------------------
00069         void blend_pixel(int x, int y, const color_type& c, int8u cover)
00070         {
00071             int8u* p = m_rbuf->row(y) + (x << 2);
00072             int alpha = int(cover) * int(c.a);
00073             if(alpha == 255*255)
00074             {
00075                 p[Order::R] = (int8u)c.r;
00076                 p[Order::G] = (int8u)c.g;
00077                 p[Order::B] = (int8u)c.b;
00078                 p[Order::A] = (int8u)c.a;
00079             }
00080             else
00081             {
00082                 int r = p[Order::R];
00083                 int g = p[Order::G];
00084                 int b = p[Order::B];
00085                 int a = p[Order::A];
00086                 p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
00087                 p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
00088                 p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
00089                 p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00090             }
00091         }
00092 
00093         //--------------------------------------------------------------------
00094         void copy_hline(int x, int y, unsigned len, const color_type& c)
00095         {
00096             int32u v;
00097             int8u* p8 = (int8u*)&v;
00098             p8[Order::R] = (int8u)c.r;
00099             p8[Order::G] = (int8u)c.g;
00100             p8[Order::B] = (int8u)c.b;
00101             p8[Order::A] = (int8u)c.a;
00102             int32u* p32 = (int32u*)(m_rbuf->row(y)) + x;
00103             do
00104             {
00105                 *p32++ = v;
00106             }
00107             while(--len);
00108         }
00109 
00110         //--------------------------------------------------------------------
00111         void copy_vline(int x, int y, unsigned len, const color_type& c)
00112         {
00113             int32u v;
00114             int8u* p8 = (int8u*)&v;
00115             p8[Order::R] = (int8u)c.r;
00116             p8[Order::G] = (int8u)c.g;
00117             p8[Order::B] = (int8u)c.b;
00118             p8[Order::A] = (int8u)c.a;
00119             int8u* p = m_rbuf->row(y) + (x << 2);
00120             do
00121             {
00122                 *(int32u*)p = v; 
00123                 p += m_rbuf->stride();
00124             }
00125             while(--len);
00126         }
00127 
00128         //--------------------------------------------------------------------
00129         void blend_hline(int x, int y, unsigned len, 
00130                          const color_type& c, int8u cover)
00131         {
00132             int alpha = int(cover) * int(c.a);
00133             if(alpha == 255*255)
00134             {
00135                 int32u v;
00136                 int8u* p8 = (int8u*)&v;
00137                 p8[Order::R] = (int8u)c.r;
00138                 p8[Order::G] = (int8u)c.g;
00139                 p8[Order::B] = (int8u)c.b;
00140                 p8[Order::A] = (int8u)c.a;
00141                 int32u* p32 = (int32u*)(m_rbuf->row(y)) + x;
00142                 do
00143                 {
00144                     *p32++ = v;
00145                 }
00146                 while(--len);
00147             }
00148             else
00149             {
00150                 int8u* p = m_rbuf->row(y) + (x << 2);
00151                 do
00152                 {
00153                     int r = p[Order::R];
00154                     int g = p[Order::G];
00155                     int b = p[Order::B];
00156                     int a = p[Order::A];
00157                     p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
00158                     p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
00159                     p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
00160                     p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00161                     p += 4;
00162                 }
00163                 while(--len);
00164             }
00165         }
00166 
00167         //--------------------------------------------------------------------
00168         void blend_vline(int x, int y, unsigned len, 
00169                          const color_type& c, int8u cover)
00170         {
00171             int8u* p = m_rbuf->row(y) + (x << 2);
00172             int alpha = int(cover) * c.a;
00173             if(alpha == 255*255)
00174             {
00175                 int32u v;
00176                 int8u* p8 = (int8u*)&v;
00177                 p8[Order::R] = (int8u)c.r;
00178                 p8[Order::G] = (int8u)c.g;
00179                 p8[Order::B] = (int8u)c.b;
00180                 p8[Order::A] = (int8u)c.a;
00181                 do
00182                 {
00183                     *(int32u*)p = v; 
00184                     p += m_rbuf->stride();
00185                 }
00186                 while(--len);
00187             }
00188             else
00189             {
00190                 do
00191                 {
00192                     int r = p[Order::R];
00193                     int g = p[Order::G];
00194                     int b = p[Order::B];
00195                     int a = p[Order::A];
00196                     p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
00197                     p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
00198                     p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
00199                     p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00200                     p += m_rbuf->stride();
00201                 }
00202                 while(--len);
00203             }
00204         }
00205 
00206 
00207         //--------------------------------------------------------------------
00208         void copy_from(const rendering_buffer& from, 
00209                        int xdst, int ydst,
00210                        int xsrc, int ysrc,
00211                        unsigned len)
00212         {
00213             memmove(m_rbuf->row(ydst) + xdst * 4, 
00214                     (const void*)(from.row(ysrc) + xsrc * 4), len * 4);
00215         }
00216 
00217 
00218 
00219         //--------------------------------------------------------------------
00220         template<class SrcPixelFormatRenderer>
00221         void blend_from(const SrcPixelFormatRenderer& from, 
00222                         const int8u* psrc,
00223                         int xdst, int ydst,
00224                         int xsrc, int ysrc,
00225                         unsigned len)
00226         {
00227             typedef typename SrcPixelFormatRenderer::order_type src_order;
00228 
00229             int8u* pdst = m_rbuf->row(ydst) + (xdst << 2);
00230             int incp = 4;
00231             if(xdst > xsrc)
00232             {
00233                 psrc += (len-1) << 2;
00234                 pdst += (len-1) << 2;
00235                 incp = -4;
00236             }
00237             do 
00238             {
00239                 int alpha = psrc[src_order::A];
00240 
00241                 if(alpha)
00242                 {
00243                     if(alpha == 255)
00244                     {
00245                         pdst[Order::R] = psrc[src_order::R];
00246                         pdst[Order::G] = psrc[src_order::G];
00247                         pdst[Order::B] = psrc[src_order::B];
00248                         pdst[Order::A] = psrc[src_order::A];
00249                     }
00250                     else
00251                     {
00252                         int r = pdst[Order::R];
00253                         int g = pdst[Order::G];
00254                         int b = pdst[Order::B];
00255                         int a = pdst[Order::A];
00256                         pdst[Order::R] = (int8u)((((psrc[src_order::R] - r) * alpha) + (r << 8)) >> 8);
00257                         pdst[Order::G] = (int8u)((((psrc[src_order::G] - g) * alpha) + (g << 8)) >> 8);
00258                         pdst[Order::B] = (int8u)((((psrc[src_order::B] - b) * alpha) + (b << 8)) >> 8);
00259                         pdst[Order::A] = (int8u)((alpha + a) - ((alpha * a) >> 8));
00260                     }
00261                 }
00262                 psrc += incp;
00263                 pdst += incp;
00264             }
00265             while(--len);
00266         }
00267 
00268 
00269 
00270 
00271         //--------------------------------------------------------------------
00272         void blend_solid_hspan(int x, int y, unsigned len, 
00273                                const color_type& c, const int8u* covers)
00274         {
00275             int8u* p = m_rbuf->row(y) + (x << 2);
00276             do 
00277             {
00278                 int alpha = int(*covers++) * c.a;
00279 
00280                 if(alpha)
00281                 {
00282                     if(alpha == 255*255)
00283                     {
00284                         p[Order::R] = (int8u)c.r;
00285                         p[Order::G] = (int8u)c.g;
00286                         p[Order::B] = (int8u)c.b;
00287                         p[Order::A] = (int8u)c.a;
00288                     }
00289                     else
00290                     {
00291                         int r = p[Order::R];
00292                         int g = p[Order::G];
00293                         int b = p[Order::B];
00294                         int a = p[Order::A];
00295                         p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
00296                         p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
00297                         p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
00298                         p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00299                     }
00300                 }
00301                 p += 4;
00302             }
00303             while(--len);
00304         }
00305 
00306 
00307 
00308         //--------------------------------------------------------------------
00309         void blend_solid_vspan(int x, int y, unsigned len, 
00310                                const color_type& c, const int8u* covers)
00311         {
00312             int8u* p = m_rbuf->row(y) + (x << 2);
00313             do 
00314             {
00315                 int alpha = int(*covers++) * c.a;
00316 
00317                 if(alpha)
00318                 {
00319                     if(alpha == 255*255)
00320                     {
00321                         p[Order::R] = (int8u)c.r;
00322                         p[Order::G] = (int8u)c.g;
00323                         p[Order::B] = (int8u)c.b;
00324                         p[Order::A] = (int8u)c.a;
00325                     }
00326                     else
00327                     {
00328                         int r = p[Order::R];
00329                         int g = p[Order::G];
00330                         int b = p[Order::B];
00331                         int a = p[Order::A];
00332                         p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
00333                         p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
00334                         p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
00335                         p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00336                     }
00337                 }
00338                 p += m_rbuf->stride();
00339             }
00340             while(--len);
00341         }
00342 
00343 
00344         //--------------------------------------------------------------------
00345         void blend_color_hspan(int x, int y, unsigned len, 
00346                                const color_type* colors, 
00347                                const int8u* covers,
00348                                int8u cover)
00349         {
00350             int8u* p = m_rbuf->row(y) + (x << 2);
00351             do 
00352             {
00353                 int alpha = colors->a * (covers ? int(*covers++) : int(cover));
00354 
00355                 if(alpha)
00356                 {
00357                     if(alpha == 255*255)
00358                     {
00359                         p[Order::R] = (int8u)colors->r;
00360                         p[Order::G] = (int8u)colors->g;
00361                         p[Order::B] = (int8u)colors->b;
00362                         p[Order::A] = (int8u)colors->a;
00363                     }
00364                     else
00365                     {
00366                         int r = p[Order::R];
00367                         int g = p[Order::G];
00368                         int b = p[Order::B];
00369                         int a = p[Order::A];
00370                         p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16);
00371                         p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16);
00372                         p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16);
00373                         p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00374                     }
00375                 }
00376                 p += 4;
00377                 ++colors;
00378             }
00379             while(--len);
00380         }
00381 
00382 
00383         //--------------------------------------------------------------------
00384         void blend_color_vspan(int x, int y, unsigned len, 
00385                                const color_type* colors, 
00386                                const int8u* covers,
00387                                int8u cover)
00388         {
00389             int8u* p = m_rbuf->row(y) + (x << 2);
00390             do 
00391             {
00392                 int alpha = colors->a * (covers ? int(*covers++) : int(cover));
00393 
00394                 if(alpha)
00395                 {
00396                     if(alpha == 255*255)
00397                     {
00398                         p[Order::R] = (int8u)colors->r;
00399                         p[Order::G] = (int8u)colors->g;
00400                         p[Order::B] = (int8u)colors->b;
00401                         p[Order::A] = (int8u)colors->a;
00402                     }
00403                     else
00404                     {
00405                         int r = p[Order::R];
00406                         int g = p[Order::G];
00407                         int b = p[Order::B];
00408                         int a = p[Order::A];
00409                         p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16);
00410                         p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16);
00411                         p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16);
00412                         p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
00413                     }
00414                 }
00415                 p += m_rbuf->stride();
00416                 ++colors;
00417             }
00418             while(--len);
00419         }
00420 
00421     private:
00422         rendering_buffer* m_rbuf;
00423     };
00424 
00425     typedef pixel_formats_rgba32<order_rgba32> pixfmt_rgba32; //----pixfmt_rgba32
00426     typedef pixel_formats_rgba32<order_argb32> pixfmt_argb32; //----pixfmt_argb32
00427     typedef pixel_formats_rgba32<order_abgr32> pixfmt_abgr32; //----pixfmt_abgr32
00428     typedef pixel_formats_rgba32<order_bgra32> pixfmt_bgra32; //----pixfmt_bgra32
00429 }
00430 
00431 #endif
00432 

Generated on Wed Feb 9 11:31:35 2005 for OpenGUI by  doxygen 1.4.0