Anti-Grain Geometry Tutorial
agg_scanline_p.h
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 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 // Class scanline_p - a general purpose scanline container with packed spans.
17 //
18 //----------------------------------------------------------------------------
19 //
20 // Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by
21 // Liberty Technology Systems, Inc., visit http://lib-sys.com
22 //
23 // Liberty Technology Systems, Inc. is the provider of
24 // PostScript and PDF technology for software developers.
25 //
26 //----------------------------------------------------------------------------
27 #ifndef AGG_SCANLINE_P_INCLUDED
28 #define AGG_SCANLINE_P_INCLUDED
29 
30 #include <cstring>
31 #include "agg_array.h"
32 
33 namespace agg
34 {
35 
36  //=============================================================scanline_p8
37  //
38  // This is a general purpose scaline container which supports the interface
39  // used in the rasterizer::render(). See description of scanline_u8
40  // for details.
41  //
42  //------------------------------------------------------------------------
44  {
45  public:
46  typedef scanline_p8 self_type;
47  typedef int8u cover_type;
48  typedef int16 coord_type;
49 
50  //--------------------------------------------------------------------
51  struct span
52  {
53  coord_type x;
54  coord_type len; // If negative, it's a solid span, covers is valid
55  const cover_type* covers;
56  };
57 
58  typedef span* iterator;
59  typedef const span* const_iterator;
60 
61  scanline_p8() :
62  m_last_x(0x7FFFFFF0),
63  m_covers(),
64  m_cover_ptr(0),
65  m_spans(),
66  m_cur_span(0)
67  {
68  }
69 
70  //--------------------------------------------------------------------
71  void reset(int min_x, int max_x)
72  {
73  unsigned max_len = max_x - min_x + 3;
74  if(max_len > m_spans.size())
75  {
76  m_spans.resize(max_len);
77  m_covers.resize(max_len);
78  }
79  m_last_x = 0x7FFFFFF0;
80  m_cover_ptr = &m_covers[0];
81  m_cur_span = &m_spans[0];
82  m_cur_span->len = 0;
83  }
84 
85  //--------------------------------------------------------------------
86  void add_cell(int x, unsigned cover)
87  {
88  *m_cover_ptr = (cover_type)cover;
89  if(x == m_last_x+1 && m_cur_span->len > 0)
90  {
91  m_cur_span->len++;
92  }
93  else
94  {
95  m_cur_span++;
96  m_cur_span->covers = m_cover_ptr;
97  m_cur_span->x = (int16)x;
98  m_cur_span->len = 1;
99  }
100  m_last_x = x;
101  m_cover_ptr++;
102  }
103 
104  //--------------------------------------------------------------------
105  void add_cells(int x, unsigned len, const cover_type* covers)
106  {
107  std::memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
108  if(x == m_last_x+1 && m_cur_span->len > 0)
109  {
110  m_cur_span->len += (int16)len;
111  }
112  else
113  {
114  m_cur_span++;
115  m_cur_span->covers = m_cover_ptr;
116  m_cur_span->x = (int16)x;
117  m_cur_span->len = (int16)len;
118  }
119  m_cover_ptr += len;
120  m_last_x = x + len - 1;
121  }
122 
123  //--------------------------------------------------------------------
124  void add_span(int x, unsigned len, unsigned cover)
125  {
126  if(x == m_last_x+1 &&
127  m_cur_span->len < 0 &&
128  cover == *m_cur_span->covers)
129  {
130  m_cur_span->len -= (int16)len;
131  }
132  else
133  {
134  *m_cover_ptr = (cover_type)cover;
135  m_cur_span++;
136  m_cur_span->covers = m_cover_ptr++;
137  m_cur_span->x = (int16)x;
138  m_cur_span->len = (int16)(-int(len));
139  }
140  m_last_x = x + len - 1;
141  }
142 
143  //--------------------------------------------------------------------
144  void finalize(int y)
145  {
146  m_y = y;
147  }
148 
149  //--------------------------------------------------------------------
150  void reset_spans()
151  {
152  m_last_x = 0x7FFFFFF0;
153  m_cover_ptr = &m_covers[0];
154  m_cur_span = &m_spans[0];
155  m_cur_span->len = 0;
156  }
157 
158  //--------------------------------------------------------------------
159  int y() const { return m_y; }
160  unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
161  const_iterator begin() const { return &m_spans[1]; }
162 
163  private:
164  scanline_p8(const self_type&);
165  const self_type& operator = (const self_type&);
166 
167  int m_last_x;
168  int m_y;
169  pod_array<cover_type> m_covers;
170  cover_type* m_cover_ptr;
171  pod_array<span> m_spans;
172  span* m_cur_span;
173  };
174 
175 
176 
177 
178 
179 
180 
181 
182  //==========================================================scanline32_p8
184  {
185  public:
186  typedef scanline32_p8 self_type;
187  typedef int8u cover_type;
188  typedef int32 coord_type;
189 
190  struct span
191  {
192  span() {}
193  span(coord_type x_, coord_type len_, const cover_type* covers_) :
194  x(x_), len(len_), covers(covers_) {}
195 
196  coord_type x;
197  coord_type len; // If negative, it's a solid span, covers is valid
198  const cover_type* covers;
199  };
201 
202 
203  //--------------------------------------------------------------------
205  {
206  public:
207  const_iterator(const span_array_type& spans) :
208  m_spans(spans),
209  m_span_idx(0)
210  {}
211 
212  const span& operator*() const { return m_spans[m_span_idx]; }
213  const span* operator->() const { return &m_spans[m_span_idx]; }
214 
215  void operator ++ () { ++m_span_idx; }
216 
217  private:
218  const span_array_type& m_spans;
219  unsigned m_span_idx;
220  };
221 
222  //--------------------------------------------------------------------
223  scanline32_p8() :
224  m_max_len(0),
225  m_last_x(0x7FFFFFF0),
226  m_covers(),
227  m_cover_ptr(0)
228  {
229  }
230 
231  //--------------------------------------------------------------------
232  void reset(int min_x, int max_x)
233  {
234  unsigned max_len = max_x - min_x + 3;
235  if(max_len > m_covers.size())
236  {
237  m_covers.resize(max_len);
238  }
239  m_last_x = 0x7FFFFFF0;
240  m_cover_ptr = &m_covers[0];
241  m_spans.remove_all();
242  }
243 
244  //--------------------------------------------------------------------
245  void add_cell(int x, unsigned cover)
246  {
247  *m_cover_ptr = cover_type(cover);
248  if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
249  {
250  m_spans.last().len++;
251  }
252  else
253  {
254  m_spans.add(span(coord_type(x), 1, m_cover_ptr));
255  }
256  m_last_x = x;
257  m_cover_ptr++;
258  }
259 
260  //--------------------------------------------------------------------
261  void add_cells(int x, unsigned len, const cover_type* covers)
262  {
263  std::memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
264  if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
265  {
266  m_spans.last().len += coord_type(len);
267  }
268  else
269  {
270  m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr));
271  }
272  m_cover_ptr += len;
273  m_last_x = x + len - 1;
274  }
275 
276  //--------------------------------------------------------------------
277  void add_span(int x, unsigned len, unsigned cover)
278  {
279  if(x == m_last_x+1 &&
280  m_spans.size() &&
281  m_spans.last().len < 0 &&
282  cover == *m_spans.last().covers)
283  {
284  m_spans.last().len -= coord_type(len);
285  }
286  else
287  {
288  *m_cover_ptr = cover_type(cover);
289  m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++));
290  }
291  m_last_x = x + len - 1;
292  }
293 
294  //--------------------------------------------------------------------
295  void finalize(int y)
296  {
297  m_y = y;
298  }
299 
300  //--------------------------------------------------------------------
301  void reset_spans()
302  {
303  m_last_x = 0x7FFFFFF0;
304  m_cover_ptr = &m_covers[0];
305  m_spans.remove_all();
306  }
307 
308  //--------------------------------------------------------------------
309  int y() const { return m_y; }
310  unsigned num_spans() const { return m_spans.size(); }
311  const_iterator begin() const { return const_iterator(m_spans); }
312 
313  private:
314  scanline32_p8(const self_type&);
315  const self_type& operator = (const self_type&);
316 
317  unsigned m_max_len;
318  int m_last_x;
319  int m_y;
320  pod_array<cover_type> m_covers;
321  cover_type* m_cover_ptr;
322  span_array_type m_spans;
323  };
324 
325 
326 }
327 
328 
329 #endif
330 
Definition: agg_arc.cpp:24