diff options
Diffstat (limited to 'agg/inc/agg_renderer_scanline.h')
-rwxr-xr-x | agg/inc/agg_renderer_scanline.h | 450 |
1 files changed, 450 insertions, 0 deletions
diff --git a/agg/inc/agg_renderer_scanline.h b/agg/inc/agg_renderer_scanline.h new file mode 100755 index 000000000000..cc33942a3770 --- /dev/null +++ b/agg/inc/agg_renderer_scanline.h @@ -0,0 +1,450 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.3 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- + +#ifndef AGG_RENDERER_SCANLINE_INCLUDED +#define AGG_RENDERER_SCANLINE_INCLUDED + +#include "agg_basics.h" +#include "agg_renderer_base.h" +#include "agg_render_scanlines.h" + +namespace agg +{ + + //====================================================renderer_scanline_aa + template<class BaseRenderer, class SpanGenerator> class renderer_scanline_aa + { + public: + typedef BaseRenderer base_ren_type; + + //-------------------------------------------------------------------- + renderer_scanline_aa(base_ren_type& ren, SpanGenerator& span_gen) : + m_ren(&ren), + m_span_gen(&span_gen) + { + } + + //-------------------------------------------------------------------- + void prepare(unsigned max_span_len) + { + m_span_gen->prepare(max_span_len); + } + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + int y = sl.y(); + m_ren->first_clip_box(); + do + { + int xmin = m_ren->xmin(); + int xmax = m_ren->xmax(); + + if(y >= m_ren->ymin() && y <= m_ren->ymax()) + { + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + do + { + int x = span->x; + int len = span->len; + bool solid = false; + const typename Scanline::cover_type* covers = span->covers; + + if(len < 0) + { + solid = true; + len = -len; + } + + if(x < xmin) + { + len -= xmin - x; + if(!solid) + { + covers += xmin - x; + } + x = xmin; + } + + if(len > 0) + { + if(x + len > xmax) + { + len = xmax - x + 1; + } + if(len > 0) + { + m_ren->blend_color_hspan_no_clip( + x, y, len, + m_span_gen->generate(x, y, len), + solid ? 0 : covers, + *covers); + } + } + ++span; + } + while(--num_spans); + } + } + while(m_ren->next_clip_box()); + } + + private: + base_ren_type* m_ren; + SpanGenerator* m_span_gen; + }; + + + + + //==============================================renderer_scanline_aa_opaque + template<class BaseRenderer, class SpanGenerator> class renderer_scanline_aa_opaque + { + public: + typedef BaseRenderer base_ren_type; + + //-------------------------------------------------------------------- + renderer_scanline_aa_opaque(base_ren_type& ren, SpanGenerator& span_gen) : + m_ren(&ren), + m_span_gen(&span_gen) + { + } + + //-------------------------------------------------------------------- + void prepare(unsigned max_span_len) + { + m_span_gen->prepare(max_span_len); + } + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + int y = sl.y(); + m_ren->first_clip_box(); + do + { + int xmin = m_ren->xmin(); + int xmax = m_ren->xmax(); + + if(y >= m_ren->ymin() && y <= m_ren->ymax()) + { + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + do + { + int x = span->x; + int len = span->len; + bool solid = false; + const typename Scanline::cover_type* covers = span->covers; + + if(len < 0) + { + solid = true; + len = -len; + } + + if(x < xmin) + { + len -= xmin - x; + if(!solid) + { + covers += xmin - x; + } + x = xmin; + } + + if(len > 0) + { + if(x + len > xmax) + { + len = xmax - x + 1; + } + if(len > 0) + { + m_ren->blend_opaque_color_hspan_no_clip( + x, y, len, + m_span_gen->generate(x, y, len), + solid ? 0 : covers, + *covers); + } + } + ++span; + } + while(--num_spans); + } + } + while(m_ren->next_clip_box()); + } + + private: + base_ren_type* m_ren; + SpanGenerator* m_span_gen; + }; + + + + //==============================================renderer_scanline_aa_solid + template<class BaseRenderer> class renderer_scanline_aa_solid + { + public: + typedef BaseRenderer base_ren_type; + typedef typename base_ren_type::color_type color_type; + + //-------------------------------------------------------------------- + renderer_scanline_aa_solid(base_ren_type& ren) : + m_ren(&ren) + { + } + + //-------------------------------------------------------------------- + void color(const color_type& c) { m_color = c; } + const color_type& color() const { return m_color; } + + //-------------------------------------------------------------------- + void prepare(unsigned) {} + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + int y = sl.y(); + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + + do + { + int x = span->x; + if(span->len > 0) + { + m_ren->blend_solid_hspan(x, y, (unsigned)span->len, + m_color, + span->covers); + } + else + { + m_ren->blend_hline(x, y, (unsigned)(x - span->len - 1), + m_color, + *(span->covers)); + } + ++span; + } + while(--num_spans); + } + + private: + base_ren_type* m_ren; + color_type m_color; + }; + + + + + + + + //===================================================renderer_scanline_bin + template<class BaseRenderer, class SpanGenerator> class renderer_scanline_bin + { + public: + typedef BaseRenderer base_ren_type; + + //-------------------------------------------------------------------- + renderer_scanline_bin(base_ren_type& ren, SpanGenerator& span_gen) : + m_ren(&ren), + m_span_gen(&span_gen) + { + } + + //-------------------------------------------------------------------- + void prepare(unsigned max_span_len) + { + m_span_gen->prepare(max_span_len); + } + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + int y = sl.y(); + m_ren->first_clip_box(); + do + { + int xmin = m_ren->xmin(); + int xmax = m_ren->xmax(); + + if(y >= m_ren->ymin() && y <= m_ren->ymax()) + { + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + do + { + int x = span->x; + int len = span->len; + + if(len < 0) len = -len; + if(x < xmin) + { + len -= xmin - x; + x = xmin; + } + if(len > 0) + { + if(x + len > xmax) + { + len = xmax - x + 1; + } + if(len > 0) + { + m_ren->blend_color_hspan_no_clip( + x, y, len, + m_span_gen->generate(x, y, len), + 0); + } + } + ++span; + } + while(--num_spans); + } + } + while(m_ren->next_clip_box()); + } + + private: + base_ren_type* m_ren; + SpanGenerator* m_span_gen; + }; + + + + //===============================================renderer_scanline_bin_opaque + template<class BaseRenderer, class SpanGenerator> class renderer_scanline_bin_opaque + { + public: + typedef BaseRenderer base_ren_type; + + //-------------------------------------------------------------------- + renderer_scanline_bin_opaque(base_ren_type& ren, SpanGenerator& span_gen) : + m_ren(&ren), + m_span_gen(&span_gen) + { + } + + //-------------------------------------------------------------------- + void prepare(unsigned max_span_len) + { + m_span_gen->prepare(max_span_len); + } + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + int y = sl.y(); + m_ren->first_clip_box(); + do + { + int xmin = m_ren->xmin(); + int xmax = m_ren->xmax(); + + if(y >= m_ren->ymin() && y <= m_ren->ymax()) + { + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + do + { + int x = span->x; + int len = span->len; + + if(len < 0) len = -len; + if(x < xmin) + { + len -= xmin - x; + x = xmin; + } + if(len > 0) + { + if(x + len > xmax) + { + len = xmax - x + 1; + } + if(len > 0) + { + m_ren->blend_opaque_color_hspan_no_clip( + x, y, len, + m_span_gen->generate(x, y, len), + 0); + } + } + ++span; + } + while(--num_spans); + } + } + while(m_ren->next_clip_box()); + } + + private: + base_ren_type* m_ren; + SpanGenerator* m_span_gen; + }; + + + + + //=============================================renderer_scanline_bin_solid + template<class BaseRenderer> class renderer_scanline_bin_solid + { + public: + typedef BaseRenderer base_ren_type; + typedef typename base_ren_type::color_type color_type; + + //-------------------------------------------------------------------- + renderer_scanline_bin_solid(base_ren_type& ren) : + m_ren(&ren) + { + } + + //-------------------------------------------------------------------- + void color(const color_type& c) { m_color = c; } + const color_type& color() const { return m_color; } + + //-------------------------------------------------------------------- + void prepare(unsigned) {} + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + do + { + m_ren->blend_hline(span->x, + sl.y(), + span->x - 1 + ((span->len < 0) ? + -span->len : + span->len), + m_color, + cover_full); + ++span; + } + while(--num_spans); + } + + private: + base_ren_type* m_ren; + color_type m_color; + }; + +} + +#endif |