1
2//----------------------------------------------------------------------------
3// Anti-Grain Geometry - Version 2.3
4// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5//
6// Permission to copy, use, modify, sell and distribute this software
7// is granted provided this copyright notice appears in all copies.
8// This software is provided "as is" without express or implied
9// warranty, and with no claim as to its suitability for any purpose.
10//
11//----------------------------------------------------------------------------
12// Contact: mcseem@antigrain.com
13//          mcseemagg@yahoo.com
14//          http://www.antigrain.com
15//----------------------------------------------------------------------------
16#ifndef AGG_RENDERER_SCANLINE_INCLUDED
17#define AGG_RENDERER_SCANLINE_INCLUDED
18#include "agg_basics.h"
19#include "agg_renderer_base.h"
20#include "agg_render_scanlines.h"
21namespace agg
22{
23template<class BaseRenderer, class SpanGenerator> class renderer_scanline_aa : public CFX_Object
24{
25public:
26    typedef BaseRenderer  base_ren_type;
27    typedef SpanGenerator span_gen_type;
28    renderer_scanline_aa() : m_ren(0), m_span_gen(0) {}
29    renderer_scanline_aa(base_ren_type& ren, span_gen_type& span_gen) :
30        m_ren(&ren),
31        m_span_gen(&span_gen)
32    {}
33    void attach(base_ren_type& ren, span_gen_type& span_gen)
34    {
35        m_ren = &ren;
36        m_span_gen = &span_gen;
37    }
38    void prepare(unsigned max_span_len)
39    {
40        m_span_gen->prepare(max_span_len);
41    }
42    template<class Scanline> void render(const Scanline& sl)
43    {
44        int y = sl.y();
45        m_ren->first_clip_box();
46        do {
47            int xmin = m_ren->xmin();
48            int xmax = m_ren->xmax();
49            if(y >= m_ren->ymin() && y <= m_ren->ymax()) {
50                unsigned num_spans = sl.num_spans();
51                typename Scanline::const_iterator span = sl.begin();
52                for(;;) {
53                    int x = span->x;
54                    int len = span->len;
55                    bool solid = false;
56                    const typename Scanline::cover_type* covers = span->covers;
57                    if(len < 0) {
58                        solid = true;
59                        len = -len;
60                    }
61                    if(x < xmin) {
62                        len -= xmin - x;
63                        if(!solid) {
64                            covers += xmin - x;
65                        }
66                        x = xmin;
67                    }
68                    if(len > 0) {
69                        if(x + len > xmax) {
70                            len = xmax - x + 1;
71                        }
72                        if(len > 0) {
73                            m_ren->blend_color_hspan_no_clip(
74                                x, y, len,
75                                m_span_gen->generate(x, y, len),
76                                solid ? 0 : covers,
77                                *covers);
78                        }
79                    }
80                    if(--num_spans == 0) {
81                        break;
82                    }
83                    ++span;
84                }
85            }
86        } while(m_ren->next_clip_box());
87    }
88private:
89    base_ren_type* m_ren;
90    SpanGenerator* m_span_gen;
91};
92}
93#endif
94