btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / headers / libs / agg / agg_scanline_p.h
blob1d1cbe72f1ecbb272a6bc3834c391bd528872d26
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 //----------------------------------------------------------------------------
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.
25 //
26 //----------------------------------------------------------------------------
27 #ifndef AGG_SCANLINE_P_INCLUDED
28 #define AGG_SCANLINE_P_INCLUDED
30 #include "agg_array.h"
32 namespace agg
35 //=============================================================scanline_p8
36 //
37 // This is a general purpose scaline container which supports the interface
38 // used in the rasterizer::render(). See description of scanline_u8
39 // for details.
40 //
41 //------------------------------------------------------------------------
42 class scanline_p8
44 public:
45 typedef scanline_p8 self_type;
46 typedef int8u cover_type;
47 typedef int16 coord_type;
49 //--------------------------------------------------------------------
50 struct span
52 coord_type x;
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;
60 scanline_p8() :
61 m_last_x(0x7FFFFFF0),
62 m_covers(),
63 m_cover_ptr(0),
64 m_spans(),
65 m_cur_span(0)
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];
81 m_cur_span->len = 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)
90 m_cur_span->len++;
92 else
94 m_cur_span++;
95 m_cur_span->covers = m_cover_ptr;
96 m_cur_span->x = (int16)x;
97 m_cur_span->len = 1;
99 m_last_x = x;
100 m_cover_ptr++;
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;
111 else
113 m_cur_span++;
114 m_cur_span->covers = m_cover_ptr;
115 m_cur_span->x = (int16)x;
116 m_cur_span->len = (int16)len;
118 m_cover_ptr += 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;
131 else
133 *m_cover_ptr = (cover_type)cover;
134 m_cur_span++;
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 //--------------------------------------------------------------------
143 void finalize(int y)
145 m_y = y;
148 //--------------------------------------------------------------------
149 void reset_spans()
151 m_last_x = 0x7FFFFFF0;
152 m_cover_ptr = &m_covers[0];
153 m_cur_span = &m_spans[0];
154 m_cur_span->len = 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]; }
162 private:
163 scanline_p8(const self_type&);
164 const self_type& operator = (const self_type&);
166 int m_last_x;
167 int m_y;
168 pod_array<cover_type> m_covers;
169 cover_type* m_cover_ptr;
170 pod_array<span> m_spans;
171 span* m_cur_span;
181 //==========================================================scanline32_p8
182 class scanline32_p8
184 public:
185 typedef scanline32_p8 self_type;
186 typedef int8u cover_type;
187 typedef int32 coord_type;
189 struct span
191 span() {}
192 span(coord_type x_, coord_type len_, const cover_type* covers_) :
193 x(x_), len(len_), covers(covers_) {}
195 coord_type x;
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 //--------------------------------------------------------------------
203 class const_iterator
205 public:
206 const_iterator(const span_array_type& spans) :
207 m_spans(spans),
208 m_span_idx(0)
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; }
216 private:
217 const span_array_type& m_spans;
218 unsigned m_span_idx;
221 //--------------------------------------------------------------------
222 scanline32_p8() :
223 m_max_len(0),
224 m_last_x(0x7FFFFFF0),
225 m_covers(),
226 m_cover_ptr(0)
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++;
251 else
253 m_spans.add(span(coord_type(x), 1, m_cover_ptr));
255 m_last_x = x;
256 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);
267 else
269 m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr));
271 m_cover_ptr += len;
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 &&
279 m_spans.size() &&
280 m_spans.last().len < 0 &&
281 cover == *m_spans.last().covers)
283 m_spans.last().len -= coord_type(len);
285 else
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 //--------------------------------------------------------------------
294 void finalize(int y)
296 m_y = y;
299 //--------------------------------------------------------------------
300 void reset_spans()
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); }
312 private:
313 scanline32_p8(const self_type&);
314 const self_type& operator = (const self_type&);
316 unsigned m_max_len;
317 int m_last_x;
318 int m_y;
319 pod_array<cover_type> m_covers;
320 cover_type* m_cover_ptr;
321 span_array_type m_spans;
328 #endif