xref: /haiku/headers/libs/agg/agg_renderer_scanline.h (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.2
3 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 //          mcseemagg@yahoo.com
13 //          http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 
16 #ifndef AGG_RENDERER_SCANLINE_INCLUDED
17 #define AGG_RENDERER_SCANLINE_INCLUDED
18 
19 #include "agg_basics.h"
20 #include "agg_renderer_base.h"
21 #include "agg_render_scanlines.h"
22 
23 namespace agg
24 {
25 
26     //====================================================renderer_scanline_aa
27     template<class BaseRenderer, class SpanGenerator> class renderer_scanline_aa
28     {
29     public:
30         typedef BaseRenderer base_ren_type;
31 
32         //--------------------------------------------------------------------
33         renderer_scanline_aa(base_ren_type& ren, SpanGenerator& span_gen) :
34             m_ren(&ren),
35             m_span_gen(&span_gen)
36         {
37         }
38 
39         //--------------------------------------------------------------------
40         void prepare(unsigned max_span_len)
41         {
42             m_span_gen->prepare(max_span_len);
43         }
44 
45         //--------------------------------------------------------------------
46         template<class Scanline> void render(const Scanline& sl)
47         {
48             int y = sl.y();
49             m_ren->first_clip_box();
50             do
51             {
52                 int xmin = m_ren->xmin();
53                 int xmax = m_ren->xmax();
54 
55                 if(y >= m_ren->ymin() && y <= m_ren->ymax())
56                 {
57                     unsigned num_spans = sl.num_spans();
58                     typename Scanline::const_iterator span = sl.begin();
59                     do
60                     {
61                         int x = span->x;
62                         int len = span->len;
63                         bool solid = false;
64                         const typename Scanline::cover_type* covers = span->covers;
65 
66                         if(len < 0)
67                         {
68                             solid = true;
69                             len = -len;
70                         }
71 
72                         if(x < xmin)
73                         {
74                             len -= xmin - x;
75                             if(!solid)
76                             {
77                                 covers += xmin - x;
78                             }
79                             x = xmin;
80                         }
81 
82                         if(len > 0)
83                         {
84                             if(x + len > xmax)
85                             {
86                                 len = xmax - x + 1;
87                             }
88                             if(len > 0)
89                             {
90                                 m_ren->blend_color_hspan_no_clip(
91                                     x, y, len,
92                                     m_span_gen->generate(x, y, len),
93                                     solid ? 0 : covers,
94                                     *covers);
95                             }
96                         }
97                         ++span;
98                     }
99                     while(--num_spans);
100                 }
101             }
102             while(m_ren->next_clip_box());
103         }
104 
105     private:
106         base_ren_type* m_ren;
107         SpanGenerator* m_span_gen;
108     };
109 
110 
111 
112     //==============================================renderer_scanline_aa_solid
113     template<class BaseRenderer> class renderer_scanline_aa_solid
114     {
115     public:
116         typedef BaseRenderer base_ren_type;
117         typedef typename base_ren_type::color_type color_type;
118 
119         //--------------------------------------------------------------------
120         renderer_scanline_aa_solid(base_ren_type& ren) :
121             m_ren(&ren)
122         {
123         }
124 
125         //--------------------------------------------------------------------
126         void color(const color_type& c) { m_color = c; }
127         const color_type& color() const { return m_color; }
128 
129         //--------------------------------------------------------------------
130         void prepare(unsigned) {}
131 
132         //--------------------------------------------------------------------
133         template<class Scanline> void render(const Scanline& sl)
134         {
135             int y = sl.y();
136             unsigned num_spans = sl.num_spans();
137             typename Scanline::const_iterator span = sl.begin();
138 
139             do
140             {
141                 int x = span->x;
142                 if(span->len > 0)
143                 {
144                     m_ren->blend_solid_hspan(x, y, (unsigned)span->len,
145                                              m_color,
146                                              span->covers);
147                 }
148                 else
149                 {
150                     m_ren->blend_hline(x, y, (unsigned)(x - span->len - 1),
151                                        m_color,
152                                        *(span->covers));
153                 }
154                 ++span;
155             }
156             while(--num_spans);
157         }
158 
159     private:
160         base_ren_type* m_ren;
161         color_type m_color;
162     };
163 
164 
165 
166 
167 
168 
169 
170     //===================================================renderer_scanline_bin
171     template<class BaseRenderer, class SpanGenerator> class renderer_scanline_bin
172     {
173     public:
174         typedef BaseRenderer base_ren_type;
175 
176         //--------------------------------------------------------------------
177         renderer_scanline_bin(base_ren_type& ren, SpanGenerator& span_gen) :
178             m_ren(&ren),
179             m_span_gen(&span_gen)
180         {
181         }
182 
183         //--------------------------------------------------------------------
184         void prepare(unsigned max_span_len)
185         {
186             m_span_gen->prepare(max_span_len);
187         }
188 
189         //--------------------------------------------------------------------
190         template<class Scanline> void render(const Scanline& sl)
191         {
192             int y = sl.y();
193             m_ren->first_clip_box();
194             do
195             {
196                 int xmin = m_ren->xmin();
197                 int xmax = m_ren->xmax();
198 
199                 if(y >= m_ren->ymin() && y <= m_ren->ymax())
200                 {
201                     unsigned num_spans = sl.num_spans();
202                     typename Scanline::const_iterator span = sl.begin();
203                     do
204                     {
205                         int x = span->x;
206                         int len = span->len;
207 
208                         if(len < 0) len = -len;
209                         if(x < xmin)
210                         {
211                             len -= xmin - x;
212                             x = xmin;
213                         }
214                         if(len > 0)
215                         {
216                             if(x + len > xmax)
217                             {
218                                 len = xmax - x + 1;
219                             }
220                             if(len > 0)
221                             {
222                                 m_ren->blend_color_hspan_no_clip(
223                                     x, y, len,
224                                     m_span_gen->generate(x, y, len),
225                                     0);
226                             }
227                         }
228                         ++span;
229                     }
230                     while(--num_spans);
231                 }
232             }
233             while(m_ren->next_clip_box());
234         }
235 
236     private:
237         base_ren_type* m_ren;
238         SpanGenerator* m_span_gen;
239     };
240 
241 
242 
243     //=============================================renderer_scanline_bin_solid
244     template<class BaseRenderer> class renderer_scanline_bin_solid
245     {
246     public:
247         typedef BaseRenderer base_ren_type;
248         typedef typename base_ren_type::color_type color_type;
249 
250         //--------------------------------------------------------------------
251         renderer_scanline_bin_solid(base_ren_type& ren) :
252             m_ren(&ren)
253         {
254         }
255 
256         //--------------------------------------------------------------------
257         void color(const color_type& c) { m_color = c; }
258         const color_type& color() const { return m_color; }
259 
260         //--------------------------------------------------------------------
261         void prepare(unsigned) {}
262 
263         //--------------------------------------------------------------------
264         template<class Scanline> void render(const Scanline& sl)
265         {
266             unsigned num_spans = sl.num_spans();
267             typename Scanline::const_iterator span = sl.begin();
268             do
269             {
270                 m_ren->blend_hline(span->x,
271                                    sl.y(),
272                                    span->x - 1 + ((span->len < 0) ?
273                                                      -span->len :
274                                                       span->len),
275                                    m_color,
276                                    cover_full);
277                 ++span;
278             }
279             while(--num_spans);
280         }
281 
282     private:
283         base_ren_type* m_ren;
284         color_type m_color;
285     };
286 
287 }
288 
289 #endif
290