Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_renderer_scanline.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 #ifndef AGG_RENDERER_SCANLINE_INCLUDED
00026 #define AGG_RENDERER_SCANLINE_INCLUDED
00027 
00028 #include "agg_basics.h"
00029 #include "agg_renderer_base.h"
00030 
00031 namespace agg
00032 {
00033 
00034     //================================================render_scanline_aa_solid
00035     template<class Scanline, class BaseRenderer, class ColorT> 
00036     void render_scanline_aa_solid(const Scanline& sl, 
00037                                   BaseRenderer& ren, 
00038                                   const ColorT& color)
00039     {
00040         int y = sl.y();
00041         unsigned num_spans = sl.num_spans();
00042         typename Scanline::const_iterator span = sl.begin();
00043 
00044         for(;;)
00045         {
00046             int x = span->x;
00047             if(span->len > 0)
00048             {
00049                 ren.blend_solid_hspan(x, y, (unsigned)span->len, 
00050                                       color, 
00051                                       span->covers);
00052             }
00053             else
00054             {
00055                 ren.blend_hline(x, y, (unsigned)(x - span->len - 1), 
00056                                 color, 
00057                                 *(span->covers));
00058             }
00059             if(--num_spans == 0) break;
00060             ++span;
00061         }
00062     }
00063 
00064     //===============================================render_scanlines_aa_solid
00065     template<class Rasterizer, class Scanline, 
00066              class BaseRenderer, class ColorT>
00067     void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl, 
00068                                    BaseRenderer& ren, const ColorT& color)
00069     {
00070         if(ras.rewind_scanlines())
00071         {
00072             // Explicitly convert "color" to the BaseRenderer color type.
00073             // For example, it can be called with color type "rgba", while
00074             // "rgba8" is needed. Otherwise it will be implicitly 
00075             // converted in the loop many times.
00076             //----------------------
00077             typename BaseRenderer::color_type ren_color(color);
00078 
00079             sl.reset(ras.min_x(), ras.max_x());
00080             while(ras.sweep_scanline(sl))
00081             {
00082                 //render_scanline_aa_solid(sl, ren, ren_color);
00083 
00084                 // This code is equivalent to the above call (copy/paste). 
00085                 // It's just a "manual" optimization for old compilers,
00086                 // like Microsoft Visual C++ v6.0
00087                 //-------------------------------
00088                 int y = sl.y();
00089                 unsigned num_spans = sl.num_spans();
00090                 typename Scanline::const_iterator span = sl.begin();
00091 
00092                 for(;;)
00093                 {
00094                     int x = span->x;
00095                     if(span->len > 0)
00096                     {
00097                         ren.blend_solid_hspan(x, y, (unsigned)span->len, 
00098                                               ren_color, 
00099                                               span->covers);
00100                     }
00101                     else
00102                     {
00103                         ren.blend_hline(x, y, (unsigned)(x - span->len - 1), 
00104                                         ren_color, 
00105                                         *(span->covers));
00106                     }
00107                     if(--num_spans == 0) break;
00108                     ++span;
00109                 }
00110             }
00111         }
00112     }
00113 
00114     //==============================================renderer_scanline_aa_solid
00115     template<class BaseRenderer> class renderer_scanline_aa_solid
00116     {
00117     public:
00118         typedef BaseRenderer base_ren_type;
00119         typedef typename base_ren_type::color_type color_type;
00120 
00121         //--------------------------------------------------------------------
00122         renderer_scanline_aa_solid() : m_ren(0) {}
00123         explicit renderer_scanline_aa_solid(base_ren_type& ren) : m_ren(&ren) {}
00124         void attach(base_ren_type& ren)
00125         {
00126             m_ren = &ren;
00127         }
00128         
00129         //--------------------------------------------------------------------
00130         void color(const color_type& c) { m_color = c; }
00131         const color_type& color() const { return m_color; }
00132 
00133         //--------------------------------------------------------------------
00134         void prepare() {}
00135 
00136         //--------------------------------------------------------------------
00137         template<class Scanline> void render(const Scanline& sl)
00138         {
00139             render_scanline_aa_solid(sl, *m_ren, m_color);
00140         }
00141         
00142     private:
00143         base_ren_type* m_ren;
00144         color_type m_color;
00145     };
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159     //======================================================render_scanline_aa
00160     template<class Scanline, class BaseRenderer, 
00161              class SpanAllocator, class SpanGenerator> 
00162     void render_scanline_aa(const Scanline& sl, BaseRenderer& ren, 
00163                             SpanAllocator& alloc, SpanGenerator& span_gen)
00164     {
00165         int y = sl.y();
00166 
00167         unsigned num_spans = sl.num_spans();
00168         typename Scanline::const_iterator span = sl.begin();
00169         for(;;)
00170         {
00171             int x = span->x;
00172             int len = span->len;
00173             const typename Scanline::cover_type* covers = span->covers;
00174 
00175             if(len < 0) len = -len;
00176             typename BaseRenderer::color_type* colors = alloc.allocate(len);
00177             span_gen.generate(colors, x, y, len);
00178             ren.blend_color_hspan(x, y, len, colors, 
00179                                   (span->len < 0) ? 0 : covers, *covers);
00180 
00181             if(--num_spans == 0) break;
00182             ++span;
00183         }
00184     }
00185 
00186     //=====================================================render_scanlines_aa
00187     template<class Rasterizer, class Scanline, class BaseRenderer, 
00188              class SpanAllocator, class SpanGenerator>
00189     void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, 
00190                              SpanAllocator& alloc, SpanGenerator& span_gen)
00191     {
00192         if(ras.rewind_scanlines())
00193         {
00194             sl.reset(ras.min_x(), ras.max_x());
00195             span_gen.prepare();
00196             while(ras.sweep_scanline(sl))
00197             {
00198                 render_scanline_aa(sl, ren, alloc, span_gen);
00199             }
00200         }
00201     }
00202 
00203     //====================================================renderer_scanline_aa
00204     template<class BaseRenderer, class SpanAllocator, class SpanGenerator> 
00205     class renderer_scanline_aa
00206     {
00207     public:
00208         typedef BaseRenderer  base_ren_type;
00209         typedef SpanAllocator alloc_type;
00210         typedef SpanGenerator span_gen_type;
00211 
00212         //--------------------------------------------------------------------
00213         renderer_scanline_aa() : m_ren(0), m_alloc(0), m_span_gen(0) {}
00214         renderer_scanline_aa(base_ren_type& ren, 
00215                              alloc_type& alloc, 
00216                              span_gen_type& span_gen) :
00217             m_ren(&ren),
00218             m_alloc(&alloc),
00219             m_span_gen(&span_gen)
00220         {}
00221         void attach(base_ren_type& ren, 
00222                     alloc_type& alloc, 
00223                     span_gen_type& span_gen)
00224         {
00225             m_ren = &ren;
00226             m_alloc = &alloc;
00227             m_span_gen = &span_gen;
00228         }
00229         
00230         //--------------------------------------------------------------------
00231         void prepare() { m_span_gen->prepare(); }
00232 
00233         //--------------------------------------------------------------------
00234         template<class Scanline> void render(const Scanline& sl)
00235         {
00236             render_scanline_aa(sl, *m_ren, *m_alloc, *m_span_gen);
00237         }
00238 
00239     private:
00240         base_ren_type* m_ren;
00241         alloc_type*    m_alloc;
00242         span_gen_type* m_span_gen;
00243     };
00244 
00245 
00246 
00247 
00248 
00249 
00250     //===============================================render_scanline_bin_solid
00251     template<class Scanline, class BaseRenderer, class ColorT> 
00252     void render_scanline_bin_solid(const Scanline& sl, 
00253                                    BaseRenderer& ren, 
00254                                    const ColorT& color)
00255     {
00256         unsigned num_spans = sl.num_spans();
00257         typename Scanline::const_iterator span = sl.begin();
00258         for(;;)
00259         {
00260             ren.blend_hline(span->x, 
00261                             sl.y(), 
00262                             span->x - 1 + ((span->len < 0) ? 
00263                                               -span->len : 
00264                                                span->len), 
00265                                color, 
00266                                cover_full);
00267             if(--num_spans == 0) break;
00268             ++span;
00269         }
00270     }
00271 
00272     //==============================================render_scanlines_bin_solid
00273     template<class Rasterizer, class Scanline, 
00274              class BaseRenderer, class ColorT>
00275     void render_scanlines_bin_solid(Rasterizer& ras, Scanline& sl, 
00276                                     BaseRenderer& ren, const ColorT& color)
00277     {
00278         if(ras.rewind_scanlines())
00279         {
00280             // Explicitly convert "color" to the BaseRenderer color type.
00281             // For example, it can be called with color type "rgba", while
00282             // "rgba8" is needed. Otherwise it will be implicitly 
00283             // converted in the loop many times.
00284             //----------------------
00285             typename BaseRenderer::color_type ren_color(color);
00286 
00287             sl.reset(ras.min_x(), ras.max_x());
00288             while(ras.sweep_scanline(sl))
00289             {
00290                 //render_scanline_bin_solid(sl, ren, ren_color);
00291 
00292                 // This code is equivalent to the above call (copy/paste). 
00293                 // It's just a "manual" optimization for old compilers,
00294                 // like Microsoft Visual C++ v6.0
00295                 //-------------------------------
00296                 unsigned num_spans = sl.num_spans();
00297                 typename Scanline::const_iterator span = sl.begin();
00298                 for(;;)
00299                 {
00300                     ren.blend_hline(span->x, 
00301                                     sl.y(), 
00302                                     span->x - 1 + ((span->len < 0) ? 
00303                                                       -span->len : 
00304                                                        span->len), 
00305                                        ren_color, 
00306                                        cover_full);
00307                     if(--num_spans == 0) break;
00308                     ++span;
00309                 }
00310             }
00311         }
00312     }
00313 
00314     //=============================================renderer_scanline_bin_solid
00315     template<class BaseRenderer> class renderer_scanline_bin_solid
00316     {
00317     public:
00318         typedef BaseRenderer base_ren_type;
00319         typedef typename base_ren_type::color_type color_type;
00320 
00321         //--------------------------------------------------------------------
00322         renderer_scanline_bin_solid() : m_ren(0) {}
00323         explicit renderer_scanline_bin_solid(base_ren_type& ren) : m_ren(&ren) {}
00324         void attach(base_ren_type& ren)
00325         {
00326             m_ren = &ren;
00327         }
00328         
00329         //--------------------------------------------------------------------
00330         void color(const color_type& c) { m_color = c; }
00331         const color_type& color() const { return m_color; }
00332 
00333         //--------------------------------------------------------------------
00334         void prepare() {}
00335 
00336         //--------------------------------------------------------------------
00337         template<class Scanline> void render(const Scanline& sl)
00338         {
00339             render_scanline_bin_solid(sl, *m_ren, m_color);
00340         }
00341         
00342     private:
00343         base_ren_type* m_ren;
00344         color_type m_color;
00345     };
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354     //======================================================render_scanline_bin
00355     template<class Scanline, class BaseRenderer, 
00356              class SpanAllocator, class SpanGenerator> 
00357     void render_scanline_bin(const Scanline& sl, BaseRenderer& ren, 
00358                              SpanAllocator& alloc, SpanGenerator& span_gen)
00359     {
00360         int y = sl.y();
00361 
00362         unsigned num_spans = sl.num_spans();
00363         typename Scanline::const_iterator span = sl.begin();
00364         for(;;)
00365         {
00366             int x = span->x;
00367             int len = span->len;
00368             if(len < 0) len = -len;
00369             typename BaseRenderer::color_type* colors = alloc.allocate(len);
00370             span_gen.generate(colors, x, y, len);
00371             ren.blend_color_hspan(x, y, len, colors, 0, cover_full); 
00372             if(--num_spans == 0) break;
00373             ++span;
00374         }
00375     }
00376 
00377     //=====================================================render_scanlines_bin
00378     template<class Rasterizer, class Scanline, class BaseRenderer, 
00379              class SpanAllocator, class SpanGenerator>
00380     void render_scanlines_bin(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, 
00381                               SpanAllocator& alloc, SpanGenerator& span_gen)
00382     {
00383         if(ras.rewind_scanlines())
00384         {
00385             sl.reset(ras.min_x(), ras.max_x());
00386             span_gen.prepare();
00387             while(ras.sweep_scanline(sl))
00388             {
00389                 render_scanline_bin(sl, ren, alloc, span_gen);
00390             }
00391         }
00392     }
00393 
00394     //====================================================renderer_scanline_bin
00395     template<class BaseRenderer, class SpanAllocator, class SpanGenerator> 
00396     class renderer_scanline_bin
00397     {
00398     public:
00399         typedef BaseRenderer  base_ren_type;
00400         typedef SpanAllocator alloc_type;
00401         typedef SpanGenerator span_gen_type;
00402 
00403         //--------------------------------------------------------------------
00404         renderer_scanline_bin() : m_ren(0), m_alloc(0), m_span_gen(0) {}
00405         renderer_scanline_bin(base_ren_type& ren, 
00406                               alloc_type& alloc, 
00407                               span_gen_type& span_gen) :
00408             m_ren(&ren),
00409             m_alloc(&alloc),
00410             m_span_gen(&span_gen)
00411         {}
00412         void attach(base_ren_type& ren, 
00413                     alloc_type& alloc, 
00414                     span_gen_type& span_gen)
00415         {
00416             m_ren = &ren;
00417             m_alloc = &alloc;
00418             m_span_gen = &span_gen;
00419         }
00420         
00421         //--------------------------------------------------------------------
00422         void prepare() { m_span_gen->prepare(); }
00423 
00424         //--------------------------------------------------------------------
00425         template<class Scanline> void render(const Scanline& sl)
00426         {
00427             render_scanline_bin(sl, *m_ren, *m_alloc, *m_span_gen);
00428         }
00429 
00430     private:
00431         base_ren_type* m_ren;
00432         alloc_type*    m_alloc;
00433         span_gen_type* m_span_gen;
00434     };
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445     //========================================================render_scanlines
00446     template<class Rasterizer, class Scanline, class Renderer>
00447     void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren)
00448     {
00449         if(ras.rewind_scanlines())
00450         {
00451             sl.reset(ras.min_x(), ras.max_x());
00452             ren.prepare();
00453             while(ras.sweep_scanline(sl))
00454             {
00455                 ren.render(sl);
00456             }
00457         }
00458     }
00459 
00460     //========================================================render_all_paths
00461     template<class Rasterizer, class Scanline, class Renderer, 
00462              class VertexSource, class ColorStorage, class PathId>
00463     void render_all_paths(Rasterizer& ras, 
00464                           Scanline& sl,
00465                           Renderer& r, 
00466                           VertexSource& vs, 
00467                           const ColorStorage& as, 
00468                           const PathId& path_id,
00469                           unsigned num_paths)
00470     {
00471         for(unsigned i = 0; i < num_paths; i++)
00472         {
00473             ras.reset();
00474             ras.add_path(vs, path_id[i]);
00475             r.color(as[i]);
00476             render_scanlines(ras, sl, r);
00477         }
00478     }
00479 
00480 
00481 
00482 
00483 
00484 
00485     //=============================================render_scanlines_compound
00486     template<class Rasterizer, 
00487              class ScanlineAA, 
00488              class ScanlineBin, 
00489              class BaseRenderer, 
00490              class SpanAllocator,
00491              class StyleHandler>
00492     void render_scanlines_compound(Rasterizer& ras, 
00493                                    ScanlineAA& sl_aa,
00494                                    ScanlineBin& sl_bin,
00495                                    BaseRenderer& ren,
00496                                    SpanAllocator& alloc,
00497                                    StyleHandler& sh)
00498     {
00499         if(ras.rewind_scanlines())
00500         {
00501             int min_x = ras.min_x();
00502             int len = ras.max_x() - min_x + 2;
00503             sl_aa.reset(min_x, ras.max_x());
00504             sl_bin.reset(min_x, ras.max_x());
00505 
00506             typedef typename BaseRenderer::color_type color_type;
00507             color_type* color_span = alloc.allocate(len * 2);
00508             color_type* mix_buffer = color_span + len;
00509             unsigned num_spans;
00510 
00511             unsigned num_styles;
00512             unsigned style;
00513             bool     solid;
00514             while((num_styles = ras.sweep_styles()) > 0)
00515             {
00516                 typename ScanlineAA::const_iterator span_aa;
00517                 if(num_styles == 1)
00518                 {
00519                     // Optimization for a single style. Happens often
00520                     //-------------------------
00521                     if(ras.sweep_scanline(sl_aa, 0))
00522                     {
00523                         style = ras.style(0);
00524                         if(sh.is_solid(style))
00525                         {
00526                             // Just solid fill
00527                             //-----------------------
00528                             render_scanline_aa_solid(sl_aa, ren, sh.color(style));
00529                         }
00530                         else
00531                         {
00532                             // Arbitrary span generator
00533                             //-----------------------
00534                             span_aa   = sl_aa.begin();
00535                             num_spans = sl_aa.num_spans();
00536                             for(;;)
00537                             {
00538                                 len = span_aa->len;
00539                                 sh.generate_span(color_span, 
00540                                                  span_aa->x, 
00541                                                  sl_aa.y(), 
00542                                                  len, 
00543                                                  style);
00544 
00545                                 ren.blend_color_hspan(span_aa->x, 
00546                                                       sl_aa.y(), 
00547                                                       span_aa->len,
00548                                                       color_span,
00549                                                       span_aa->covers);
00550                                 if(--num_spans == 0) break;
00551                                 ++span_aa;
00552                             }
00553                         }
00554                     }
00555                 }
00556                 else
00557                 {
00558                     if(ras.sweep_scanline(sl_bin, -1))
00559                     {
00560                         // Clear the spans of the mix_buffer
00561                         //--------------------
00562                         typename ScanlineBin::const_iterator span_bin = sl_bin.begin();
00563                         num_spans = sl_bin.num_spans();
00564                         for(;;)
00565                         {
00566                             memset(mix_buffer + span_bin->x - min_x, 
00567                                    0, 
00568                                    span_bin->len * sizeof(color_type));
00569 
00570                             if(--num_spans == 0) break;
00571                             ++span_bin;
00572                         }
00573 
00574                         unsigned i;
00575                         for(i = 0; i < num_styles; i++)
00576                         {
00577                             style = ras.style(i);
00578                             solid = sh.is_solid(style);
00579 
00580                             if(ras.sweep_scanline(sl_aa, i))
00581                             {
00582                                 color_type* colors;
00583                                 color_type* cspan;
00584                                 typename ScanlineAA::cover_type* covers;
00585                                 span_aa   = sl_aa.begin();
00586                                 num_spans = sl_aa.num_spans();
00587                                 if(solid)
00588                                 {
00589                                     // Just solid fill
00590                                     //-----------------------
00591                                     for(;;)
00592                                     {
00593                                         color_type c = sh.color(style);
00594                                         len    = span_aa->len;
00595                                         colors = mix_buffer + span_aa->x - min_x;
00596                                         covers = span_aa->covers;
00597                                         do
00598                                         {
00599                                             if(*covers == cover_full) 
00600                                             {
00601                                                 *colors = c;
00602                                             }
00603                                             else
00604                                             {
00605                                                 colors->add(c, *covers);
00606                                             }
00607                                             ++colors;
00608                                             ++covers;
00609                                         }
00610                                         while(--len);
00611                                         if(--num_spans == 0) break;
00612                                         ++span_aa;
00613                                     }
00614                                 }
00615                                 else
00616                                 {
00617                                     // Arbitrary span generator
00618                                     //-----------------------
00619                                     for(;;)
00620                                     {
00621                                         len = span_aa->len;
00622                                         colors = mix_buffer + span_aa->x - min_x;
00623                                         cspan  = color_span;
00624                                         sh.generate_span(cspan, 
00625                                                          span_aa->x, 
00626                                                          sl_aa.y(), 
00627                                                          len, 
00628                                                          style);
00629                                         covers = span_aa->covers;
00630                                         do
00631                                         {
00632                                             if(*covers == cover_full) 
00633                                             {
00634                                                 *colors = *cspan;
00635                                             }
00636                                             else
00637                                             {
00638                                                 colors->add(*cspan, *covers);
00639                                             }
00640                                             ++cspan;
00641                                             ++colors;
00642                                             ++covers;
00643                                         }
00644                                         while(--len);
00645                                         if(--num_spans == 0) break;
00646                                         ++span_aa;
00647                                     }
00648                                 }
00649                             }
00650                         }
00651 
00652                         // Emit the blended result as a color hspan
00653                         //-------------------------
00654                         span_bin = sl_bin.begin();
00655                         num_spans = sl_bin.num_spans();
00656                         for(;;)
00657                         {
00658                             ren.blend_color_hspan(span_bin->x, 
00659                                                   sl_bin.y(), 
00660                                                   span_bin->len,
00661                                                   mix_buffer + span_bin->x - min_x,
00662                                                   0,
00663                                                   cover_full);
00664                             if(--num_spans == 0) break;
00665                             ++span_bin;
00666                         }
00667                     } // if(ras.sweep_scanline(sl_bin, -1))
00668                 } // if(num_styles == 1) ... else
00669             } // while((num_styles = ras.sweep_styles()) > 0)
00670         } // if(ras.rewind_scanlines())
00671     }
00672 
00673     //=======================================render_scanlines_compound_layered
00674     template<class Rasterizer, 
00675              class ScanlineAA, 
00676              class BaseRenderer, 
00677              class SpanAllocator,
00678              class StyleHandler>
00679     void render_scanlines_compound_layered(Rasterizer& ras, 
00680                                            ScanlineAA& sl_aa,
00681                                            BaseRenderer& ren,
00682                                            SpanAllocator& alloc,
00683                                            StyleHandler& sh)
00684     {
00685         if(ras.rewind_scanlines())
00686         {
00687             int min_x = ras.min_x();
00688             int len = ras.max_x() - min_x + 2;
00689             sl_aa.reset(min_x, ras.max_x());
00690 
00691             typedef typename BaseRenderer::color_type color_type;
00692             color_type* color_span   = alloc.allocate(len * 2);
00693             color_type* mix_buffer   = color_span + len;
00694             cover_type* cover_buffer = ras.allocate_cover_buffer(len);
00695             unsigned num_spans;
00696 
00697             unsigned num_styles;
00698             unsigned style;
00699             bool     solid;
00700             while((num_styles = ras.sweep_styles()) > 0)
00701             {
00702                 typename ScanlineAA::const_iterator span_aa;
00703                 if(num_styles == 1)
00704                 {
00705                     // Optimization for a single style. Happens often
00706                     //-------------------------
00707                     if(ras.sweep_scanline(sl_aa, 0))
00708                     {
00709                         style = ras.style(0);
00710                         if(sh.is_solid(style))
00711                         {
00712                             // Just solid fill
00713                             //-----------------------
00714                             render_scanline_aa_solid(sl_aa, ren, sh.color(style));
00715                         }
00716                         else
00717                         {
00718                             // Arbitrary span generator
00719                             //-----------------------
00720                             span_aa   = sl_aa.begin();
00721                             num_spans = sl_aa.num_spans();
00722                             for(;;)
00723                             {
00724                                 len = span_aa->len;
00725                                 sh.generate_span(color_span, 
00726                                                  span_aa->x, 
00727                                                  sl_aa.y(), 
00728                                                  len, 
00729                                                  style);
00730 
00731                                 ren.blend_color_hspan(span_aa->x, 
00732                                                       sl_aa.y(), 
00733                                                       span_aa->len,
00734                                                       color_span,
00735                                                       span_aa->covers);
00736                                 if(--num_spans == 0) break;
00737                                 ++span_aa;
00738                             }
00739                         }
00740                     }
00741                 }
00742                 else
00743                 {
00744                     int      sl_start = ras.scanline_start();
00745                     unsigned sl_len   = ras.scanline_length();
00746 
00747                     if(sl_len)
00748                     {
00749                         memset(mix_buffer + sl_start - min_x, 
00750                                0, 
00751                                sl_len * sizeof(color_type));
00752 
00753                         memset(cover_buffer + sl_start - min_x, 
00754                                0, 
00755                                sl_len * sizeof(cover_type));
00756 
00757                         int sl_y = 0x7FFFFFFF;
00758                         unsigned i;
00759                         for(i = 0; i < num_styles; i++)
00760                         {
00761                             style = ras.style(i);
00762                             solid = sh.is_solid(style);
00763 
00764                             if(ras.sweep_scanline(sl_aa, i))
00765                             {
00766                                 unsigned    cover;
00767                                 color_type* colors;
00768                                 color_type* cspan;
00769                                 cover_type* src_covers;
00770                                 cover_type* dst_covers;
00771                                 span_aa   = sl_aa.begin();
00772                                 num_spans = sl_aa.num_spans();
00773                                 sl_y      = sl_aa.y();
00774                                 if(solid)
00775                                 {
00776                                     // Just solid fill
00777                                     //-----------------------
00778                                     for(;;)
00779                                     {
00780                                         color_type c = sh.color(style);
00781                                         len    = span_aa->len;
00782                                         colors = mix_buffer + span_aa->x - min_x;
00783                                         src_covers = span_aa->covers;
00784                                         dst_covers = cover_buffer + span_aa->x - min_x;
00785                                         do
00786                                         {
00787                                             cover = *src_covers;
00788                                             if(*dst_covers + cover > cover_full)
00789                                             {
00790                                                 cover = cover_full - *dst_covers;
00791                                             }
00792                                             if(cover)
00793                                             {
00794                                                 colors->add(c, cover);
00795                                                 *dst_covers += cover;
00796                                             }
00797                                             ++colors;
00798                                             ++src_covers;
00799                                             ++dst_covers;
00800                                         }
00801                                         while(--len);
00802                                         if(--num_spans == 0) break;
00803                                         ++span_aa;
00804                                     }
00805                                 }
00806                                 else
00807                                 {
00808                                     // Arbitrary span generator
00809                                     //-----------------------
00810                                     for(;;)
00811                                     {
00812                                         len = span_aa->len;
00813                                         colors = mix_buffer + span_aa->x - min_x;
00814                                         cspan  = color_span;
00815                                         sh.generate_span(cspan, 
00816                                                          span_aa->x, 
00817                                                          sl_aa.y(), 
00818                                                          len, 
00819                                                          style);
00820                                         src_covers = span_aa->covers;
00821                                         dst_covers = cover_buffer + span_aa->x - min_x;
00822                                         do
00823                                         {
00824                                             cover = *src_covers;
00825                                             if(*dst_covers + cover > cover_full)
00826                                             {
00827                                                 cover = cover_full - *dst_covers;
00828                                             }
00829                                             if(cover)
00830                                             {
00831                                                 colors->add(*cspan, cover);
00832                                                 *dst_covers += cover;
00833                                             }
00834                                             ++cspan;
00835                                             ++colors;
00836                                             ++src_covers;
00837                                             ++dst_covers;
00838                                         }
00839                                         while(--len);
00840                                         if(--num_spans == 0) break;
00841                                         ++span_aa;
00842                                     }
00843                                 }
00844                             }
00845                         }
00846                         ren.blend_color_hspan(sl_start, 
00847                                               sl_y, 
00848                                               sl_len,
00849                                               mix_buffer + sl_start - min_x,
00850                                               0,
00851                                               cover_full);
00852                     } //if(sl_len)
00853                 } //if(num_styles == 1) ... else
00854             } //while((num_styles = ras.sweep_styles()) > 0)
00855         } //if(ras.rewind_scanlines())
00856     }
00857 
00858 
00859 }
00860 
00861 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines