Anti-Grain Geometry - AGG (libagg)
2.5
|
00001 //---------------------------------------------------------------------------- 00002 // Anti-Grain Geometry (AGG) - Version 2.5 00003 // A high quality rendering engine for C++ 00004 // Copyright (C) 2002-2006 Maxim Shemanarev 00005 // Contact: mcseem@antigrain.com 00006 // mcseemagg@yahoo.com 00007 // http://antigrain.com 00008 // 00009 // AGG is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU General Public License 00011 // as published by the Free Software Foundation; either version 2 00012 // of the License, or (at your option) any later version. 00013 // 00014 // AGG is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with AGG; if not, write to the Free Software 00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00022 // MA 02110-1301, USA. 00023 //---------------------------------------------------------------------------- 00024 00025 #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