btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / headers / libs / agg / agg_scanline_storage_bin.h
blobd760016970532d4e5b2269a285e5e210062a3c6b
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 // Adaptation for 32-bit screen coordinates has been sponsored by
17 // Liberty Technology Systems, Inc., visit http://lib-sys.com
19 // Liberty Technology Systems, Inc. is the provider of
20 // PostScript and PDF technology for software developers.
21 //
22 //----------------------------------------------------------------------------
25 #ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED
26 #define AGG_SCANLINE_STORAGE_BIN_INCLUDED
28 #include <string.h>
29 #include <stdlib.h>
30 #include <math.h>
31 #include "agg_array.h"
34 namespace agg
37 //-----------------------------------------------scanline_storage_bin
38 class scanline_storage_bin
40 public:
41 //---------------------------------------------------------------
42 struct span_data
44 int32 x;
45 int32 len;
48 //---------------------------------------------------------------
49 struct scanline_data
51 int y;
52 unsigned num_spans;
53 unsigned start_span;
57 //---------------------------------------------------------------
58 class embedded_scanline
60 public:
62 //-----------------------------------------------------------
63 class const_iterator
65 public:
66 const_iterator() : m_storage(0) {}
67 const_iterator(const embedded_scanline& sl) :
68 m_storage(sl.m_storage),
69 m_span_idx(sl.m_scanline.start_span)
71 m_span = m_storage->span_by_index(m_span_idx);
74 const span_data& operator*() const { return m_span; }
75 const span_data* operator->() const { return &m_span; }
77 void operator ++ ()
79 ++m_span_idx;
80 m_span = m_storage->span_by_index(m_span_idx);
83 private:
84 const scanline_storage_bin* m_storage;
85 unsigned m_span_idx;
86 span_data m_span;
89 friend class const_iterator;
92 //-----------------------------------------------------------
93 embedded_scanline(const scanline_storage_bin& storage) :
94 m_storage(&storage)
96 setup(0);
99 //-----------------------------------------------------------
100 void reset(int, int) {}
101 unsigned num_spans() const { return m_scanline.num_spans; }
102 int y() const { return m_scanline.y; }
103 const_iterator begin() const { return const_iterator(*this); }
105 //-----------------------------------------------------------
106 void setup(unsigned scanline_idx)
108 m_scanline_idx = scanline_idx;
109 m_scanline = m_storage->scanline_by_index(m_scanline_idx);
112 private:
113 const scanline_storage_bin* m_storage;
114 scanline_data m_scanline;
115 unsigned m_scanline_idx;
119 //---------------------------------------------------------------
120 scanline_storage_bin() :
121 m_spans(256-2), // Block increment size
122 m_scanlines(),
123 m_min_x( 0x7FFFFFFF),
124 m_min_y( 0x7FFFFFFF),
125 m_max_x(-0x7FFFFFFF),
126 m_max_y(-0x7FFFFFFF),
127 m_cur_scanline(0)
129 m_fake_scanline.y = 0;
130 m_fake_scanline.num_spans = 0;
131 m_fake_scanline.start_span = 0;
132 m_fake_span.x = 0;
133 m_fake_span.len = 0;
136 // Renderer Interface
137 //---------------------------------------------------------------
138 void prepare()
140 m_scanlines.remove_all();
141 m_spans.remove_all();
142 m_min_x = 0x7FFFFFFF;
143 m_min_y = 0x7FFFFFFF;
144 m_max_x = -0x7FFFFFFF;
145 m_max_y = -0x7FFFFFFF;
146 m_cur_scanline = 0;
149 //---------------------------------------------------------------
150 template<class Scanline> void render(const Scanline& sl)
152 scanline_data sl_this;
154 int y = sl.y();
155 if(y < m_min_y) m_min_y = y;
156 if(y > m_max_y) m_max_y = y;
158 sl_this.y = y;
159 sl_this.num_spans = sl.num_spans();
160 sl_this.start_span = m_spans.size();
161 typename Scanline::const_iterator span_iterator = sl.begin();
163 unsigned num_spans = sl_this.num_spans;
164 for(;;)
166 span_data sp;
167 sp.x = span_iterator->x;
168 sp.len = (int32)abs((int)(span_iterator->len));
169 m_spans.add(sp);
170 int x1 = sp.x;
171 int x2 = sp.x + sp.len - 1;
172 if(x1 < m_min_x) m_min_x = x1;
173 if(x2 > m_max_x) m_max_x = x2;
174 if(--num_spans == 0) break;
175 ++span_iterator;
177 m_scanlines.add(sl_this);
181 //---------------------------------------------------------------
182 // Iterate scanlines interface
183 int min_x() const { return m_min_x; }
184 int min_y() const { return m_min_y; }
185 int max_x() const { return m_max_x; }
186 int max_y() const { return m_max_y; }
188 //---------------------------------------------------------------
189 bool rewind_scanlines()
191 m_cur_scanline = 0;
192 return m_scanlines.size() > 0;
196 //---------------------------------------------------------------
197 template<class Scanline> bool sweep_scanline(Scanline& sl)
199 sl.reset_spans();
200 for(;;)
202 if(m_cur_scanline >= m_scanlines.size()) return false;
203 const scanline_data& sl_this = m_scanlines[m_cur_scanline];
205 unsigned num_spans = sl_this.num_spans;
206 unsigned span_idx = sl_this.start_span;
209 const span_data& sp = m_spans[span_idx++];
210 sl.add_span(sp.x, sp.len, cover_full);
212 while(--num_spans);
214 ++m_cur_scanline;
215 if(sl.num_spans())
217 sl.finalize(sl_this.y);
218 break;
221 return true;
225 //---------------------------------------------------------------
226 // Specialization for embedded_scanline
227 bool sweep_scanline(embedded_scanline& sl)
231 if(m_cur_scanline >= m_scanlines.size()) return false;
232 sl.setup(m_cur_scanline);
233 ++m_cur_scanline;
235 while(sl.num_spans() == 0);
236 return true;
240 //---------------------------------------------------------------
241 unsigned byte_size() const
243 unsigned i;
244 unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
246 for(i = 0; i < m_scanlines.size(); ++i)
248 size += sizeof(int32) * 2 + // Y, num_spans
249 unsigned(m_scanlines[i].num_spans) * sizeof(int32) * 2; // X, span_len
251 return size;
255 //---------------------------------------------------------------
256 static void write_int32(int8u* dst, int32 val)
258 dst[0] = ((const int8u*)&val)[0];
259 dst[1] = ((const int8u*)&val)[1];
260 dst[2] = ((const int8u*)&val)[2];
261 dst[3] = ((const int8u*)&val)[3];
265 //---------------------------------------------------------------
266 void serialize(int8u* data) const
268 unsigned i;
270 write_int32(data, min_x()); // min_x
271 data += sizeof(int32);
272 write_int32(data, min_y()); // min_y
273 data += sizeof(int32);
274 write_int32(data, max_x()); // max_x
275 data += sizeof(int32);
276 write_int32(data, max_y()); // max_y
277 data += sizeof(int32);
279 for(i = 0; i < m_scanlines.size(); ++i)
281 const scanline_data& sl_this = m_scanlines[i];
283 write_int32(data, sl_this.y); // Y
284 data += sizeof(int32);
286 write_int32(data, sl_this.num_spans); // num_spans
287 data += sizeof(int32);
289 unsigned num_spans = sl_this.num_spans;
290 unsigned span_idx = sl_this.start_span;
293 const span_data& sp = m_spans[span_idx++];
295 write_int32(data, sp.x); // X
296 data += sizeof(int32);
298 write_int32(data, sp.len); // len
299 data += sizeof(int32);
301 while(--num_spans);
306 //---------------------------------------------------------------
307 const scanline_data& scanline_by_index(unsigned i) const
309 return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline;
312 //---------------------------------------------------------------
313 const span_data& span_by_index(unsigned i) const
315 return (i < m_spans.size()) ? m_spans[i] : m_fake_span;
319 private:
320 pod_bvector<span_data, 10> m_spans;
321 pod_bvector<scanline_data, 8> m_scanlines;
322 span_data m_fake_span;
323 scanline_data m_fake_scanline;
324 int m_min_x;
325 int m_min_y;
326 int m_max_x;
327 int m_max_y;
328 unsigned m_cur_scanline;
343 //---------------------------------------serialized_scanlines_adaptor_bin
344 class serialized_scanlines_adaptor_bin
346 public:
347 typedef bool cover_type;
349 //--------------------------------------------------------------------
350 class embedded_scanline
352 public:
354 //----------------------------------------------------------------
355 class const_iterator
357 public:
358 struct span
360 int32 x;
361 int32 len;
364 const_iterator() : m_ptr(0) {}
365 const_iterator(const embedded_scanline& sl) :
366 m_ptr(sl.m_ptr),
367 m_dx(sl.m_dx)
369 m_span.x = read_int32() + m_dx;
370 m_span.len = read_int32();
373 const span& operator*() const { return m_span; }
374 const span* operator->() const { return &m_span; }
376 void operator ++ ()
378 m_span.x = read_int32() + m_dx;
379 m_span.len = read_int32();
382 private:
383 int read_int32()
385 int32 val;
386 ((int8u*)&val)[0] = *m_ptr++;
387 ((int8u*)&val)[1] = *m_ptr++;
388 ((int8u*)&val)[2] = *m_ptr++;
389 ((int8u*)&val)[3] = *m_ptr++;
390 return val;
393 const int8u* m_ptr;
394 span m_span;
395 int m_dx;
398 friend class const_iterator;
401 //----------------------------------------------------------------
402 embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {}
404 //----------------------------------------------------------------
405 void reset(int, int) {}
406 unsigned num_spans() const { return m_num_spans; }
407 int y() const { return m_y; }
408 const_iterator begin() const { return const_iterator(*this); }
411 private:
412 //----------------------------------------------------------------
413 int read_int32()
415 int32 val;
416 ((int8u*)&val)[0] = *m_ptr++;
417 ((int8u*)&val)[1] = *m_ptr++;
418 ((int8u*)&val)[2] = *m_ptr++;
419 ((int8u*)&val)[3] = *m_ptr++;
420 return val;
423 public:
424 //----------------------------------------------------------------
425 void init(const int8u* ptr, int dx, int dy)
427 m_ptr = ptr;
428 m_y = read_int32() + dy;
429 m_num_spans = unsigned(read_int32());
430 m_dx = dx;
433 private:
434 const int8u* m_ptr;
435 int m_y;
436 unsigned m_num_spans;
437 int m_dx;
442 public:
443 //--------------------------------------------------------------------
444 serialized_scanlines_adaptor_bin() :
445 m_data(0),
446 m_end(0),
447 m_ptr(0),
448 m_dx(0),
449 m_dy(0),
450 m_min_x(0x7FFFFFFF),
451 m_min_y(0x7FFFFFFF),
452 m_max_x(-0x7FFFFFFF),
453 m_max_y(-0x7FFFFFFF)
456 //--------------------------------------------------------------------
457 serialized_scanlines_adaptor_bin(const int8u* data, unsigned size,
458 double dx, double dy) :
459 m_data(data),
460 m_end(data + size),
461 m_ptr(data),
462 m_dx(iround(dx)),
463 m_dy(iround(dy)),
464 m_min_x(0x7FFFFFFF),
465 m_min_y(0x7FFFFFFF),
466 m_max_x(-0x7FFFFFFF),
467 m_max_y(-0x7FFFFFFF)
470 //--------------------------------------------------------------------
471 void init(const int8u* data, unsigned size, double dx, double dy)
473 m_data = data;
474 m_end = data + size;
475 m_ptr = data;
476 m_dx = iround(dx);
477 m_dy = iround(dy);
478 m_min_x = 0x7FFFFFFF;
479 m_min_y = 0x7FFFFFFF;
480 m_max_x = -0x7FFFFFFF;
481 m_max_y = -0x7FFFFFFF;
484 private:
485 //--------------------------------------------------------------------
486 int read_int32()
488 int32 val;
489 ((int8u*)&val)[0] = *m_ptr++;
490 ((int8u*)&val)[1] = *m_ptr++;
491 ((int8u*)&val)[2] = *m_ptr++;
492 ((int8u*)&val)[3] = *m_ptr++;
493 return val;
496 public:
497 // Iterate scanlines interface
498 //--------------------------------------------------------------------
499 bool rewind_scanlines()
501 m_ptr = m_data;
502 if(m_ptr < m_end)
504 m_min_x = read_int32() + m_dx;
505 m_min_y = read_int32() + m_dy;
506 m_max_x = read_int32() + m_dx;
507 m_max_y = read_int32() + m_dy;
509 return m_ptr < m_end;
512 //--------------------------------------------------------------------
513 int min_x() const { return m_min_x; }
514 int min_y() const { return m_min_y; }
515 int max_x() const { return m_max_x; }
516 int max_y() const { return m_max_y; }
518 //--------------------------------------------------------------------
519 template<class Scanline> bool sweep_scanline(Scanline& sl)
521 sl.reset_spans();
522 for(;;)
524 if(m_ptr >= m_end) return false;
526 int y = read_int32() + m_dy;
527 unsigned num_spans = read_int32();
531 int x = read_int32() + m_dx;
532 int len = read_int32();
534 if(len < 0) len = -len;
535 sl.add_span(x, unsigned(len), cover_full);
537 while(--num_spans);
539 if(sl.num_spans())
541 sl.finalize(y);
542 break;
545 return true;
549 //--------------------------------------------------------------------
550 // Specialization for embedded_scanline
551 bool sweep_scanline(embedded_scanline& sl)
555 if(m_ptr >= m_end) return false;
557 sl.init(m_ptr, m_dx, m_dy);
559 // Jump to the next scanline
560 //--------------------------
561 read_int32(); // Y
562 int num_spans = read_int32(); // num_spans
563 m_ptr += num_spans * sizeof(int32) * 2;
565 while(sl.num_spans() == 0);
566 return true;
569 private:
570 const int8u* m_data;
571 const int8u* m_end;
572 const int8u* m_ptr;
573 int m_dx;
574 int m_dy;
575 int m_min_x;
576 int m_min_y;
577 int m_max_x;
578 int m_max_y;
585 #endif