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

agg_renderer_base.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 // class renderer_base
00017 //
00018 //----------------------------------------------------------------------------
00019 
00020 #ifndef AGG_RENDERER_BASE_INCLUDED
00021 #define AGG_RENDERER_BASE_INCLUDED
00022 
00023 #include "agg_basics.h"
00024 #include "agg_rendering_buffer.h"
00025 
00026 namespace agg
00027 {
00028 
00029     //-----------------------------------------------------------renderer_base
00030     template<class PixelFormat> class renderer_base
00031     {
00032     public:
00033         typedef PixelFormat pixfmt_type;
00034         typedef typename pixfmt_type::color_type color_type;
00035 
00036         //--------------------------------------------------------------------
00037         renderer_base(pixfmt_type& ren) :
00038             m_ren(&ren),
00039             m_clip_box(0, 0, ren.width() - 1, ren.height() - 1)
00040         {
00041         }
00042 
00043         //--------------------------------------------------------------------
00044         const pixfmt_type& ren() const { return *m_ren;  }
00045         pixfmt_type& ren() { return *m_ren;  }
00046           
00047         //--------------------------------------------------------------------
00048         unsigned width()  const { return m_ren->width();  }
00049         unsigned height() const { return m_ren->height(); }
00050 
00051         //--------------------------------------------------------------------
00052         bool clip_box(int x1, int y1, int x2, int y2)
00053         {
00054             rect cb(x1, y1, x2, y2);
00055             cb.normalize();
00056             if(cb.clip(rect(0, 0, width() - 1, height() - 1)))
00057             {
00058                 m_clip_box = cb;
00059                 return true;
00060             }
00061             m_clip_box.x1 = 1;
00062             m_clip_box.y1 = 1;
00063             m_clip_box.x2 = 0;
00064             m_clip_box.y2 = 0;
00065             return false;
00066         }
00067 
00068         //--------------------------------------------------------------------
00069         void reset_clipping(bool visibility)
00070         {
00071             if(visibility)
00072             {
00073                 m_clip_box.x1 = 0;
00074                 m_clip_box.y1 = 0;
00075                 m_clip_box.x2 = width() - 1;
00076                 m_clip_box.y2 = height() - 1;
00077             }
00078             else
00079             {
00080                 m_clip_box.x1 = 1;
00081                 m_clip_box.y1 = 1;
00082                 m_clip_box.x2 = 0;
00083                 m_clip_box.y2 = 0;
00084             }
00085         }
00086 
00087         //--------------------------------------------------------------------
00088         void clip_box_naked(int x1, int y1, int x2, int y2)
00089         {
00090             m_clip_box.x1 = x1;
00091             m_clip_box.y1 = y1;
00092             m_clip_box.x2 = x2;
00093             m_clip_box.y2 = y2;
00094         }
00095 
00096         //--------------------------------------------------------------------
00097         bool inbox(int x, int y) const
00098         {
00099             return x >= m_clip_box.x1 && y >= m_clip_box.y1 &&
00100                    x <= m_clip_box.x2 && y <= m_clip_box.y2;
00101         }
00102         
00103         //--------------------------------------------------------------------
00104         void first_clip_box() {}
00105         bool next_clip_box() { return false; }
00106 
00107         //--------------------------------------------------------------------
00108         const rect& clip_box() const { return m_clip_box;    }
00109         int         xmin()     const { return m_clip_box.x1; }
00110         int         ymin()     const { return m_clip_box.y1; }
00111         int         xmax()     const { return m_clip_box.x2; }
00112         int         ymax()     const { return m_clip_box.y2; }
00113 
00114         //--------------------------------------------------------------------
00115         const rect& bounding_clip_box() const { return m_clip_box;    }
00116         int         bounding_xmin()     const { return m_clip_box.x1; }
00117         int         bounding_ymin()     const { return m_clip_box.y1; }
00118         int         bounding_xmax()     const { return m_clip_box.x2; }
00119         int         bounding_ymax()     const { return m_clip_box.y2; }
00120 
00121         //--------------------------------------------------------------------
00122         void clear(const color_type& c)
00123         {
00124             unsigned y;
00125             if(width())
00126             {
00127                 for(y = 0; y < height(); y++)
00128                 {
00129                     m_ren->copy_hline(0, y, width(), c);
00130                 }
00131             }
00132         }
00133           
00134         //--------------------------------------------------------------------
00135         void copy_pixel(int x, int y, const color_type& c)
00136         {
00137             if(inbox(x, y))
00138             {
00139                 m_ren->copy_pixel(x, y, c);
00140             }
00141         }
00142 
00143         //--------------------------------------------------------------------
00144         void blend_pixel(int x, int y, const color_type& c, cover_type cover)
00145         {
00146             if(inbox(x, y))
00147             {
00148                 m_ren->blend_pixel(x, y, c, cover);
00149             }
00150         }
00151 
00152         //--------------------------------------------------------------------
00153         color_type pixel(int x, int y) const
00154         {
00155             return inbox(x, y) ? 
00156                    m_ren->pixel(x, y) :
00157                    color_type::no_color();
00158         }
00159 
00160         //--------------------------------------------------------------------
00161         void copy_hline(int x1, int y, int x2, const color_type& c)
00162         {
00163             if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
00164             if(y  > ymax()) return;
00165             if(y  < ymin()) return;
00166             if(x1 > xmax()) return;
00167             if(x2 < xmin()) return;
00168 
00169             if(x1 < xmin()) x1 = xmin();
00170             if(x2 > xmax()) x2 = xmax();
00171 
00172             m_ren->copy_hline(x1, y, x2 - x1 + 1, c);
00173         }
00174 
00175         //--------------------------------------------------------------------
00176         void copy_vline(int x, int y1, int y2, const color_type& c)
00177         {
00178             if(y1 > y2) { int t = y2; y2 = y1; y1 = t; }
00179             if(x  > xmax()) return;
00180             if(x  < xmin()) return;
00181             if(y1 > ymax()) return;
00182             if(y2 < ymin()) return;
00183 
00184             if(y1 < ymin()) y1 = ymin();
00185             if(y2 > ymax()) y2 = ymax();
00186 
00187             m_ren->copy_vline(x, y1, y2 - y1 + 1, c);
00188         }
00189 
00190         //--------------------------------------------------------------------
00191         void blend_hline(int x1, int y, int x2, 
00192                          const color_type& c, cover_type cover)
00193         {
00194             if(x1 > x2) { int t = x2; x2 = x1; x1 = t; }
00195             if(y  > ymax()) return;
00196             if(y  < ymin()) return;
00197             if(x1 > xmax()) return;
00198             if(x2 < xmin()) return;
00199 
00200             if(x1 < xmin()) x1 = xmin();
00201             if(x2 > xmax()) x2 = xmax();
00202 
00203             m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover);
00204         }
00205 
00206         //--------------------------------------------------------------------
00207         void blend_vline(int x, int y1, int y2, 
00208                          const color_type& c, cover_type cover)
00209         {
00210             if(y1 > y2) { int t = y2; y2 = y1; y1 = t; }
00211             if(x  > xmax()) return;
00212             if(x  < xmin()) return;
00213             if(y1 > ymax()) return;
00214             if(y2 < ymin()) return;
00215 
00216             if(y1 < ymin()) y1 = ymin();
00217             if(y2 > ymax()) y2 = ymax();
00218 
00219             m_ren->blend_vline(x, y1, y2 - y1 + 1, c, cover);
00220         }
00221 
00222 
00223         //--------------------------------------------------------------------
00224         void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
00225         {
00226             rect rc(x1, y1, x2, y2);
00227             rc.normalize();
00228             if(rc.clip(clip_box()))
00229             {
00230                 int y;
00231                 for(y = rc.y1; y <= rc.y2; y++)
00232                 {
00233                     m_ren->copy_hline(rc.x1, y, unsigned(rc.x2 - rc.x1 + 1), c);
00234                 }
00235             }
00236         }
00237 
00238         //--------------------------------------------------------------------
00239         void blend_bar(int x1, int y1, int x2, int y2, 
00240                        const color_type& c, cover_type cover)
00241         {
00242             rect rc(x1, y1, x2, y2);
00243             rc.normalize();
00244             if(rc.clip(clip_box()))
00245             {
00246                 int y;
00247                 for(y = rc.y1; y <= rc.y2; y++)
00248                 {
00249                     m_ren->blend_hline(rc.x1,
00250                                        y,
00251                                        unsigned(rc.x2 - rc.x1 + 1), 
00252                                        c, 
00253                                        cover);
00254                 }
00255             }
00256         }
00257 
00258 
00259         //--------------------------------------------------------------------
00260         void blend_solid_hspan(int x, int y, int len, 
00261                                const color_type& c, 
00262                                const cover_type* covers)
00263         {
00264             if(y > ymax()) return;
00265             if(y < ymin()) return;
00266 
00267             if(x < xmin())
00268             {
00269                 len -= xmin() - x;
00270                 if(len <= 0) return;
00271                 covers += xmin() - x;
00272                 x = xmin();
00273             }
00274             if(x + len > xmax())
00275             {
00276                 len = xmax() - x + 1;
00277                 if(len <= 0) return;
00278             }
00279             m_ren->blend_solid_hspan(x, y, len, c, covers);
00280         }
00281 
00282         //--------------------------------------------------------------------
00283         void blend_solid_vspan(int x, int y, int len, 
00284                                const color_type& c, 
00285                                const cover_type* covers)
00286         {
00287             if(x > xmax()) return;
00288             if(x < xmin()) return;
00289 
00290             if(y < ymin())
00291             {
00292                 len -= ymin() - y;
00293                 if(len <= 0) return;
00294                 covers += ymin() - y;
00295                 y = ymin();
00296             }
00297             if(y + len > ymax())
00298             {
00299                 len = ymax() - y + 1;
00300                 if(len <= 0) return;
00301             }
00302             m_ren->blend_solid_vspan(x, y, len, c, covers);
00303         }
00304 
00305         //--------------------------------------------------------------------
00306         void blend_color_hspan(int x, int y, int len, 
00307                                const color_type* colors, 
00308                                const cover_type* covers,
00309                                cover_type cover = cover_full)
00310         {
00311             if(y > ymax()) return;
00312             if(y < ymin()) return;
00313 
00314             if(x < xmin())
00315             {
00316                 int d = xmin() - x;
00317                 len -= d;
00318                 if(len <= 0) return;
00319                 if(covers) covers += d;
00320                 colors += d;
00321                 x = xmin();
00322             }
00323             if(x + len > xmax())
00324             {
00325                 len = xmax() - x + 1;
00326                 if(len <= 0) return;
00327             }
00328             m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
00329         }
00330 
00331         //--------------------------------------------------------------------
00332         void blend_color_vspan(int x, int y, int len, 
00333                                const color_type* colors, 
00334                                const cover_type* covers,
00335                                cover_type cover = cover_full)
00336         {
00337             if(x > xmax()) return;
00338             if(x < xmin()) return;
00339 
00340             if(y < ymin())
00341             {
00342                 int d = ymin() - y;
00343                 len -= d;
00344                 if(len <= 0) return;
00345                 if(covers) covers += d;
00346                 colors += d;
00347                 y = ymin();
00348             }
00349             if(y + len > ymax())
00350             {
00351                 len = ymax() - y + 1;
00352                 if(len <= 0) return;
00353             }
00354             m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
00355         }
00356 
00357         //--------------------------------------------------------------------
00358         void blend_color_hspan_no_clip(int x, int y, int len, 
00359                                        const color_type* colors, 
00360                                        const cover_type* covers,
00361                                        cover_type cover = cover_full)
00362         {
00363             m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
00364         }
00365 
00366         //--------------------------------------------------------------------
00367         void blend_color_vspan_no_clip(int x, int y, int len, 
00368                                        const color_type* colors, 
00369                                        const cover_type* covers,
00370                                        cover_type cover = cover_full)
00371         {
00372             m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
00373         }
00374 
00375 
00376         //--------------------------------------------------------------------
00377         rect clip_rect_area(rect& dst, rect& src, int wsrc, int hsrc) const
00378         {
00379             rect rc(0,0,0,0);
00380             rect cb = clip_box();
00381             ++cb.x2;
00382             ++cb.y2;
00383 
00384             if(src.x1 < 0)
00385             {
00386                 dst.x1 -= src.x1;
00387                 src.x1 = 0;
00388             }
00389             if(src.y1 < 0)
00390             {
00391                 dst.y1 -= src.y1;
00392                 src.y1 = 0;
00393             }
00394 
00395             if(src.x2 > wsrc) src.x2 = wsrc;
00396             if(src.y2 > hsrc) src.y2 = hsrc;
00397 
00398             if(dst.x1 < cb.x1)
00399             {
00400                 src.x1 += cb.x1 - dst.x1;
00401                 dst.x1 = cb.x1;
00402             }
00403             if(dst.y1 < cb.y1)
00404             {
00405                 src.y1 += cb.y1 - dst.y1;
00406                 dst.y1 = cb.y1;
00407             }
00408 
00409             if(dst.x2 > cb.x2) dst.x2 = cb.x2;
00410             if(dst.y2 > cb.y2) dst.y2 = cb.y2;
00411 
00412             rc.x2 = dst.x2 - dst.x1;
00413             rc.y2 = dst.y2 - dst.y1;
00414 
00415             if(rc.x2 > src.x2 - src.x1) rc.x2 = src.x2 - src.x1;
00416             if(rc.y2 > src.y2 - src.y1) rc.y2 = src.y2 - src.y1;
00417             return rc;
00418         }
00419 
00420 
00421         //--------------------------------------------------------------------
00422         void copy_from(const rendering_buffer& src, 
00423                        const rect* rect_src_ptr = 0, 
00424                        int dx = 0, 
00425                        int dy = 0)
00426         {
00427             rect rsrc(0, 0, src.width(), src.height());
00428             if(rect_src_ptr)
00429             {
00430                 rsrc.x1 = rect_src_ptr->x1; 
00431                 rsrc.y1 = rect_src_ptr->y1;
00432                 rsrc.x2 = rect_src_ptr->x2 + 1;
00433                 rsrc.y2 = rect_src_ptr->y2 + 1;
00434             }
00435 
00436             // Version with xdst, ydst (absolute positioning)
00437             //rect rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
00438 
00439             // Version with dx, dy (relative positioning)
00440             rect rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
00441 
00442             rect rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
00443 
00444             if(rc.x2 > 0)
00445             {
00446                 int incy = 1;
00447                 if(rdst.y1 > rsrc.y1)
00448                 {
00449                     rsrc.y1 += rc.y2 - 1;
00450                     rdst.y1 += rc.y2 - 1;
00451                     incy = -1;
00452                 }
00453                 while(rc.y2 > 0)
00454                 {
00455                     m_ren->copy_from(src, 
00456                                      rdst.x1, rdst.y1,
00457                                      rsrc.x1, rsrc.y1,
00458                                      rc.x2);
00459                     rdst.y1 += incy;
00460                     rsrc.y1 += incy;
00461                     --rc.y2;
00462                 }
00463             }
00464         }
00465 
00466 
00467 
00468         //--------------------------------------------------------------------
00469         template<class SrcPixelFormatRenderer>
00470         void blend_from(const SrcPixelFormatRenderer& src, 
00471                        const rect* rect_src_ptr = 0, 
00472                        int dx = 0, 
00473                        int dy = 0)
00474         {
00475             rect rsrc(0, 0, src.width(), src.height());
00476             if(rect_src_ptr)
00477             {
00478                 rsrc.x1 = rect_src_ptr->x1; 
00479                 rsrc.y1 = rect_src_ptr->y1;
00480                 rsrc.x2 = rect_src_ptr->x2 + 1;
00481                 rsrc.y2 = rect_src_ptr->y2 + 1;
00482             }
00483 
00484             // Version with xdst, ydst (absolute positioning)
00485             //rect rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
00486 
00487             // Version with dx, dy (relative positioning)
00488             rect rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
00489 
00490             rect rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
00491 
00492             if(rc.x2 > 0)
00493             {
00494                 int incy = 1;
00495                 if(rdst.y1 > rsrc.y1)
00496                 {
00497                     rsrc.y1 += rc.y2 - 1;
00498                     rdst.y1 += rc.y2 - 1;
00499                     incy = -1;
00500                 }
00501                 while(rc.y2 > 0)
00502                 {
00503                     typename SrcPixelFormatRenderer::row_data span = src.span(rsrc.x1, rsrc.y1);
00504                     if(span.ptr)
00505                     {
00506                         int x1src = rsrc.x1;
00507                         int x1dst = rdst.x1;
00508                         int len   = rc.x2;
00509                         if(span.x1 > x1src)
00510                         {
00511                             x1dst += span.x1 - x1src;
00512                             len   -= span.x1 - x1src;
00513                             x1src = span.x1;
00514                         }
00515                         if(len > 0)
00516                         {
00517                             if(x1src + len-1 > span.x2)
00518                             {
00519                                 len -= x1src + len - span.x2 - 1;
00520                             }
00521                             if(len > 0)
00522                             {
00523                                 m_ren->blend_from(src, span.ptr,
00524                                                   x1dst, rdst.y1,
00525                                                   x1src, rsrc.y1,
00526                                                   len);
00527                             }
00528                         }
00529                     }
00530                     rdst.y1 += incy;
00531                     rsrc.y1 += incy;
00532                     --rc.y2;
00533                 }
00534             }
00535         }
00536 
00537 
00538 
00539     private:
00540         pixfmt_type* m_ren;
00541         rect         m_clip_box;
00542     };
00543 
00544 
00545 }
00546 
00547 #endif

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