1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
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.
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 // Class scanline_p - a general purpose scanline container with packed spans.
18 //----------------------------------------------------------------------------
20 // Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by
21 // Liberty Technology Systems, Inc., visit http://lib-sys.com
23 // Liberty Technology Systems, Inc. is the provider of
24 // PostScript and PDF technology for software developers.
26 //----------------------------------------------------------------------------
27 #ifndef AGG_SCANLINE_P_INCLUDED
28 #define AGG_SCANLINE_P_INCLUDED
30 #include "agg_array.h"
35 //=============================================================scanline_p8
37 // This is a general purpose scaline container which supports the interface
38 // used in the rasterizer::render(). See description of scanline_u8
41 //------------------------------------------------------------------------
45 typedef scanline_p8 self_type
;
46 typedef int8u cover_type
;
47 typedef int16 coord_type
;
49 //--------------------------------------------------------------------
53 coord_type len
; // If negative, it's a solid span, covers is valid
54 const cover_type
* covers
;
57 typedef span
* iterator
;
58 typedef const span
* const_iterator
;
69 //--------------------------------------------------------------------
70 void reset(int min_x
, int max_x
)
72 unsigned max_len
= max_x
- min_x
+ 3;
73 if(max_len
> m_spans
.size())
75 m_spans
.resize(max_len
);
76 m_covers
.resize(max_len
);
78 m_last_x
= 0x7FFFFFF0;
79 m_cover_ptr
= &m_covers
[0];
80 m_cur_span
= &m_spans
[0];
84 //--------------------------------------------------------------------
85 void add_cell(int x
, unsigned cover
)
87 *m_cover_ptr
= (cover_type
)cover
;
88 if(x
== m_last_x
+1 && m_cur_span
->len
> 0)
95 m_cur_span
->covers
= m_cover_ptr
;
96 m_cur_span
->x
= (int16
)x
;
103 //--------------------------------------------------------------------
104 void add_cells(int x
, unsigned len
, const cover_type
* covers
)
106 memcpy(m_cover_ptr
, covers
, len
* sizeof(cover_type
));
107 if(x
== m_last_x
+1 && m_cur_span
->len
> 0)
109 m_cur_span
->len
+= (int16
)len
;
114 m_cur_span
->covers
= m_cover_ptr
;
115 m_cur_span
->x
= (int16
)x
;
116 m_cur_span
->len
= (int16
)len
;
119 m_last_x
= x
+ len
- 1;
122 //--------------------------------------------------------------------
123 void add_span(int x
, unsigned len
, unsigned cover
)
125 if(x
== m_last_x
+1 &&
126 m_cur_span
->len
< 0 &&
127 cover
== *m_cur_span
->covers
)
129 m_cur_span
->len
-= (int16
)len
;
133 *m_cover_ptr
= (cover_type
)cover
;
135 m_cur_span
->covers
= m_cover_ptr
++;
136 m_cur_span
->x
= (int16
)x
;
137 m_cur_span
->len
= (int16
)(-int(len
));
139 m_last_x
= x
+ len
- 1;
142 //--------------------------------------------------------------------
148 //--------------------------------------------------------------------
151 m_last_x
= 0x7FFFFFF0;
152 m_cover_ptr
= &m_covers
[0];
153 m_cur_span
= &m_spans
[0];
157 //--------------------------------------------------------------------
158 int y() const { return m_y
; }
159 unsigned num_spans() const { return unsigned(m_cur_span
- &m_spans
[0]); }
160 const_iterator
begin() const { return &m_spans
[1]; }
163 scanline_p8(const self_type
&);
164 const self_type
& operator = (const self_type
&);
168 pod_array
<cover_type
> m_covers
;
169 cover_type
* m_cover_ptr
;
170 pod_array
<span
> m_spans
;
181 //==========================================================scanline32_p8
185 typedef scanline32_p8 self_type
;
186 typedef int8u cover_type
;
187 typedef int32 coord_type
;
192 span(coord_type x_
, coord_type len_
, const cover_type
* covers_
) :
193 x(x_
), len(len_
), covers(covers_
) {}
196 coord_type len
; // If negative, it's a solid span, covers is valid
197 const cover_type
* covers
;
199 typedef pod_bvector
<span
, 4> span_array_type
;
202 //--------------------------------------------------------------------
206 const_iterator(const span_array_type
& spans
) :
211 const span
& operator*() const { return m_spans
[m_span_idx
]; }
212 const span
* operator->() const { return &m_spans
[m_span_idx
]; }
214 void operator ++ () { ++m_span_idx
; }
217 const span_array_type
& m_spans
;
221 //--------------------------------------------------------------------
224 m_last_x(0x7FFFFFF0),
230 //--------------------------------------------------------------------
231 void reset(int min_x
, int max_x
)
233 unsigned max_len
= max_x
- min_x
+ 3;
234 if(max_len
> m_covers
.size())
236 m_covers
.resize(max_len
);
238 m_last_x
= 0x7FFFFFF0;
239 m_cover_ptr
= &m_covers
[0];
240 m_spans
.remove_all();
243 //--------------------------------------------------------------------
244 void add_cell(int x
, unsigned cover
)
246 *m_cover_ptr
= cover_type(cover
);
247 if(x
== m_last_x
+1 && m_spans
.size() && m_spans
.last().len
> 0)
249 m_spans
.last().len
++;
253 m_spans
.add(span(coord_type(x
), 1, m_cover_ptr
));
259 //--------------------------------------------------------------------
260 void add_cells(int x
, unsigned len
, const cover_type
* covers
)
262 memcpy(m_cover_ptr
, covers
, len
* sizeof(cover_type
));
263 if(x
== m_last_x
+1 && m_spans
.size() && m_spans
.last().len
> 0)
265 m_spans
.last().len
+= coord_type(len
);
269 m_spans
.add(span(coord_type(x
), coord_type(len
), m_cover_ptr
));
272 m_last_x
= x
+ len
- 1;
275 //--------------------------------------------------------------------
276 void add_span(int x
, unsigned len
, unsigned cover
)
278 if(x
== m_last_x
+1 &&
280 m_spans
.last().len
< 0 &&
281 cover
== *m_spans
.last().covers
)
283 m_spans
.last().len
-= coord_type(len
);
287 *m_cover_ptr
= cover_type(cover
);
288 m_spans
.add(span(coord_type(x
), -coord_type(len
), m_cover_ptr
++));
290 m_last_x
= x
+ len
- 1;
293 //--------------------------------------------------------------------
299 //--------------------------------------------------------------------
302 m_last_x
= 0x7FFFFFF0;
303 m_cover_ptr
= &m_covers
[0];
304 m_spans
.remove_all();
307 //--------------------------------------------------------------------
308 int y() const { return m_y
; }
309 unsigned num_spans() const { return m_spans
.size(); }
310 const_iterator
begin() const { return const_iterator(m_spans
); }
313 scanline32_p8(const self_type
&);
314 const self_type
& operator = (const self_type
&);
319 pod_array
<cover_type
> m_covers
;
320 cover_type
* m_cover_ptr
;
321 span_array_type m_spans
;