16 #ifndef AGG_RENDERER_SCANLINE_INCLUDED 17 #define AGG_RENDERER_SCANLINE_INCLUDED 22 #include "agg_basics.h" 23 #include "agg_renderer_base.h" 29 template<
class Scanline,
class BaseRenderer,
class ColorT>
30 void render_scanline_aa_solid(
const Scanline& sl,
35 unsigned num_spans = sl.num_spans();
36 typename Scanline::const_iterator span = sl.begin();
43 ren.blend_solid_hspan(x, y, (
unsigned)span->len,
49 ren.blend_hline(x, y, (
unsigned)(x - span->len - 1),
53 if(--num_spans == 0)
break;
59 template<
class Rasterizer,
class Scanline,
60 class BaseRenderer,
class ColorT>
61 void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl,
62 BaseRenderer& ren,
const ColorT& color)
64 if(ras.rewind_scanlines())
71 typename BaseRenderer::color_type ren_color = color;
73 sl.reset(ras.min_x(), ras.max_x());
74 while(ras.sweep_scanline(sl))
83 unsigned num_spans = sl.num_spans();
84 typename Scanline::const_iterator span = sl.begin();
91 ren.blend_solid_hspan(x, y, (
unsigned)span->len,
97 ren.blend_hline(x, y, (
unsigned)(x - span->len - 1),
101 if(--num_spans == 0)
break;
112 typedef BaseRenderer base_ren_type;
113 typedef typename base_ren_type::color_type color_type;
118 void attach(base_ren_type& ren)
124 void color(
const color_type& c) { m_color = c; }
125 const color_type& color()
const {
return m_color; }
131 template<
class Scanline>
void render(
const Scanline& sl)
133 render_scanline_aa_solid(sl, *m_ren, m_color);
137 base_ren_type* m_ren;
154 template<
class Scanline,
class BaseRenderer,
155 class SpanAllocator,
class SpanGenerator>
156 void render_scanline_aa(
const Scanline& sl, BaseRenderer& ren,
157 SpanAllocator& alloc, SpanGenerator& span_gen)
161 unsigned num_spans = sl.num_spans();
162 typename Scanline::const_iterator span = sl.begin();
167 const typename Scanline::cover_type* covers = span->covers;
169 if(len < 0) len = -len;
170 typename BaseRenderer::color_type* colors = alloc.allocate(len);
171 span_gen.generate(colors, x, y, len);
172 ren.blend_color_hspan(x, y, len, colors,
173 (span->len < 0) ? 0 : covers, *covers);
175 if(--num_spans == 0)
break;
181 template<
class Rasterizer,
class Scanline,
class BaseRenderer,
182 class SpanAllocator,
class SpanGenerator>
183 void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
184 SpanAllocator& alloc, SpanGenerator& span_gen)
186 if(ras.rewind_scanlines())
188 sl.reset(ras.min_x(), ras.max_x());
190 while(ras.sweep_scanline(sl))
192 render_scanline_aa(sl, ren, alloc, span_gen);
198 template<
class BaseRenderer,
class SpanAllocator,
class SpanGenerator>
202 typedef BaseRenderer base_ren_type;
203 typedef SpanAllocator alloc_type;
204 typedef SpanGenerator span_gen_type;
210 span_gen_type& span_gen) :
213 m_span_gen(&span_gen)
215 void attach(base_ren_type& ren,
217 span_gen_type& span_gen)
221 m_span_gen = &span_gen;
225 void prepare() { m_span_gen->prepare(); }
228 template<
class Scanline>
void render(
const Scanline& sl)
230 render_scanline_aa(sl, *m_ren, *m_alloc, *m_span_gen);
234 base_ren_type* m_ren;
236 span_gen_type* m_span_gen;
245 template<
class Scanline,
class BaseRenderer,
class ColorT>
246 void render_scanline_bin_solid(
const Scanline& sl,
250 unsigned num_spans = sl.num_spans();
251 typename Scanline::const_iterator span = sl.begin();
254 ren.blend_hline(span->x,
256 span->x - 1 + ((span->len < 0) ?
261 if(--num_spans == 0)
break;
267 template<
class Rasterizer,
class Scanline,
268 class BaseRenderer,
class ColorT>
269 void render_scanlines_bin_solid(Rasterizer& ras, Scanline& sl,
270 BaseRenderer& ren,
const ColorT& color)
272 if(ras.rewind_scanlines())
279 typename BaseRenderer::color_type ren_color(color);
281 sl.reset(ras.min_x(), ras.max_x());
282 while(ras.sweep_scanline(sl))
290 unsigned num_spans = sl.num_spans();
291 typename Scanline::const_iterator span = sl.begin();
294 ren.blend_hline(span->x,
296 span->x - 1 + ((span->len < 0) ?
301 if(--num_spans == 0)
break;
312 typedef BaseRenderer base_ren_type;
313 typedef typename base_ren_type::color_type color_type;
318 void attach(base_ren_type& ren)
324 void color(
const color_type& c) { m_color = c; }
325 const color_type& color()
const {
return m_color; }
331 template<
class Scanline>
void render(
const Scanline& sl)
333 render_scanline_bin_solid(sl, *m_ren, m_color);
337 base_ren_type* m_ren;
349 template<
class Scanline,
class BaseRenderer,
350 class SpanAllocator,
class SpanGenerator>
351 void render_scanline_bin(
const Scanline& sl, BaseRenderer& ren,
352 SpanAllocator& alloc, SpanGenerator& span_gen)
356 unsigned num_spans = sl.num_spans();
357 typename Scanline::const_iterator span = sl.begin();
362 if(len < 0) len = -len;
363 typename BaseRenderer::color_type* colors = alloc.allocate(len);
364 span_gen.generate(colors, x, y, len);
365 ren.blend_color_hspan(x, y, len, colors, 0, cover_full);
366 if(--num_spans == 0)
break;
372 template<
class Rasterizer,
class Scanline,
class BaseRenderer,
373 class SpanAllocator,
class SpanGenerator>
374 void render_scanlines_bin(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
375 SpanAllocator& alloc, SpanGenerator& span_gen)
377 if(ras.rewind_scanlines())
379 sl.reset(ras.min_x(), ras.max_x());
381 while(ras.sweep_scanline(sl))
383 render_scanline_bin(sl, ren, alloc, span_gen);
389 template<
class BaseRenderer,
class SpanAllocator,
class SpanGenerator>
393 typedef BaseRenderer base_ren_type;
394 typedef SpanAllocator alloc_type;
395 typedef SpanGenerator span_gen_type;
401 span_gen_type& span_gen) :
404 m_span_gen(&span_gen)
406 void attach(base_ren_type& ren,
408 span_gen_type& span_gen)
412 m_span_gen = &span_gen;
416 void prepare() { m_span_gen->prepare(); }
419 template<
class Scanline>
void render(
const Scanline& sl)
421 render_scanline_bin(sl, *m_ren, *m_alloc, *m_span_gen);
425 base_ren_type* m_ren;
427 span_gen_type* m_span_gen;
440 template<
class Rasterizer,
class Scanline,
class Renderer>
441 void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren)
443 if(ras.rewind_scanlines())
445 sl.reset(ras.min_x(), ras.max_x());
447 while(ras.sweep_scanline(sl))
455 template<
class Rasterizer,
class Scanline,
class Renderer,
456 class VertexSource,
class ColorStorage,
class PathId>
457 void render_all_paths(Rasterizer& ras,
461 const ColorStorage& as,
462 const PathId& path_id,
465 for(
unsigned i = 0; i < num_paths; i++)
468 ras.add_path(vs, path_id[i]);
470 render_scanlines(ras, sl, r);
480 template<
class Rasterizer,
486 void render_scanlines_compound(Rasterizer& ras,
490 SpanAllocator& alloc,
493 if(ras.rewind_scanlines())
495 int min_x = ras.min_x();
496 int len = ras.max_x() - min_x + 2;
497 sl_aa.reset(min_x, ras.max_x());
498 sl_bin.reset(min_x, ras.max_x());
500 typedef typename BaseRenderer::color_type color_type;
501 color_type* color_span = alloc.allocate(len * 2);
502 color_type* mix_buffer = color_span + len;
508 while((num_styles = ras.sweep_styles()) > 0)
510 typename ScanlineAA::const_iterator span_aa;
515 if(ras.sweep_scanline(sl_aa, 0))
517 style = ras.style(0);
518 if(sh.is_solid(style))
522 render_scanline_aa_solid(sl_aa, ren, sh.color(style));
528 span_aa = sl_aa.begin();
529 num_spans = sl_aa.num_spans();
533 sh.generate_span(color_span,
539 ren.blend_color_hspan(span_aa->x,
544 if(--num_spans == 0)
break;
552 if(ras.sweep_scanline(sl_bin, -1))
556 typename ScanlineBin::const_iterator span_bin = sl_bin.begin();
557 num_spans = sl_bin.num_spans();
560 std::memset(mix_buffer + span_bin->x - min_x,
562 span_bin->len *
sizeof(color_type));
564 if(--num_spans == 0)
break;
569 for(i = 0; i < num_styles; i++)
571 style = ras.style(i);
572 solid = sh.is_solid(style);
574 if(ras.sweep_scanline(sl_aa, i))
578 typename ScanlineAA::cover_type* covers;
579 span_aa = sl_aa.begin();
580 num_spans = sl_aa.num_spans();
587 color_type c = sh.color(style);
589 colors = mix_buffer + span_aa->x - min_x;
590 covers = span_aa->covers;
593 if(*covers == cover_full)
599 colors->add(c, *covers);
605 if(--num_spans == 0)
break;
616 colors = mix_buffer + span_aa->x - min_x;
618 sh.generate_span(cspan,
623 covers = span_aa->covers;
626 if(*covers == cover_full)
632 colors->add(*cspan, *covers);
639 if(--num_spans == 0)
break;
648 span_bin = sl_bin.begin();
649 num_spans = sl_bin.num_spans();
652 ren.blend_color_hspan(span_bin->x,
655 mix_buffer + span_bin->x - min_x,
658 if(--num_spans == 0)
break;
668 template<
class Rasterizer,
673 void render_scanlines_compound_layered(Rasterizer& ras,
676 SpanAllocator& alloc,
679 if(ras.rewind_scanlines())
681 int min_x = ras.min_x();
682 int len = ras.max_x() - min_x + 2;
683 sl_aa.reset(min_x, ras.max_x());
685 typedef typename BaseRenderer::color_type color_type;
686 color_type* color_span = alloc.allocate(len * 2);
687 color_type* mix_buffer = color_span + len;
688 cover_type* cover_buffer = ras.allocate_cover_buffer(len);
694 while((num_styles = ras.sweep_styles()) > 0)
696 typename ScanlineAA::const_iterator span_aa;
701 if(ras.sweep_scanline(sl_aa, 0))
703 style = ras.style(0);
704 if(sh.is_solid(style))
708 render_scanline_aa_solid(sl_aa, ren, sh.color(style));
714 span_aa = sl_aa.begin();
715 num_spans = sl_aa.num_spans();
719 sh.generate_span(color_span,
725 ren.blend_color_hspan(span_aa->x,
730 if(--num_spans == 0)
break;
738 int sl_start = ras.scanline_start();
739 unsigned sl_len = ras.scanline_length();
743 std::memset(mix_buffer + sl_start - min_x,
745 sl_len *
sizeof(color_type));
747 std::memset(cover_buffer + sl_start - min_x,
749 sl_len *
sizeof(cover_type));
751 int sl_y = std::numeric_limits<int>::max();
753 for(i = 0; i < num_styles; i++)
755 style = ras.style(i);
756 solid = sh.is_solid(style);
758 if(ras.sweep_scanline(sl_aa, i))
763 cover_type* src_covers;
764 cover_type* dst_covers;
765 span_aa = sl_aa.begin();
766 num_spans = sl_aa.num_spans();
774 color_type c = sh.color(style);
776 colors = mix_buffer + span_aa->x - min_x;
777 src_covers = span_aa->covers;
778 dst_covers = cover_buffer + span_aa->x - min_x;
782 if(*dst_covers + cover > cover_full)
784 cover = cover_full - *dst_covers;
788 colors->add(c, cover);
789 *dst_covers += cover;
796 if(--num_spans == 0)
break;
807 colors = mix_buffer + span_aa->x - min_x;
809 sh.generate_span(cspan,
814 src_covers = span_aa->covers;
815 dst_covers = cover_buffer + span_aa->x - min_x;
819 if(*dst_covers + cover > cover_full)
821 cover = cover_full - *dst_covers;
825 colors->add(*cspan, cover);
826 *dst_covers += cover;
834 if(--num_spans == 0)
break;
840 ren.blend_color_hspan(sl_start,
843 mix_buffer + sl_start - min_x,