Merge to XFA: Separate agg-authored code from fx-authored code.
[pdfium.git] / third_party / agg23 / agg_renderer_scanline.h
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"
21 namespace agg
22 {
23 template<class BaseRenderer, class SpanGenerator> class renderer_scanline_aa 
24 {
25 public:
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     }
88 private:
89     base_ren_type* m_ren;
90     SpanGenerator* m_span_gen;
91 };
92 }
93 #endif