update dev300-m58
[ooovba.git] / agg / inc / agg_scanline_storage_bin.h
blobab499feb1259d5f5a6e03709e4d6fa5a0c4dfe4d
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
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 #ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED
17 #define AGG_SCANLINE_STORAGE_BIN_INCLUDED
19 #include <string.h>
20 #include <stdlib.h>
21 #include <math.h>
22 #include "agg_array.h"
23 #include "agg_render_scanlines.h"
26 namespace agg
29 //-----------------------------------------------scanline_storage_bin
30 class scanline_storage_bin
32 public:
33 //---------------------------------------------------------------
34 struct span_data
36 int16 x;
37 int16 len;
40 //---------------------------------------------------------------
41 struct scanline_data
43 int y;
44 unsigned num_spans;
45 unsigned start_span;
49 //---------------------------------------------------------------
50 class embedded_scanline
52 public:
54 //-----------------------------------------------------------
55 class const_iterator
57 public:
58 const_iterator(const embedded_scanline& sl) :
59 m_storage(sl.m_storage),
60 m_span_idx(sl.m_scanline.start_span)
62 m_span = m_storage->span_by_index(m_span_idx);
65 const span_data& operator*() const { return m_span; }
66 const span_data* operator->() const { return &m_span; }
68 void operator ++ ()
70 ++m_span_idx;
71 m_span = m_storage->span_by_index(m_span_idx);
74 private:
75 const scanline_storage_bin* m_storage;
76 unsigned m_span_idx;
77 span_data m_span;
80 friend class const_iterator;
83 //-----------------------------------------------------------
84 embedded_scanline(const scanline_storage_bin& storage) :
85 m_storage(&storage)
87 setup(0);
90 //-----------------------------------------------------------
91 void reset(int, int) {}
92 unsigned num_spans() const { return m_scanline.num_spans; }
93 int y() const { return m_scanline.y; }
94 const_iterator begin() const { return const_iterator(*this); }
96 //-----------------------------------------------------------
97 void setup(unsigned scanline_idx)
99 m_scanline_idx = scanline_idx;
100 m_scanline = m_storage->scanline_by_index(m_scanline_idx);
103 private:
104 const scanline_storage_bin* m_storage;
105 scanline_data m_scanline;
106 unsigned m_scanline_idx;
110 //---------------------------------------------------------------
111 scanline_storage_bin() :
112 m_spans(256-2), // Block increment size
113 m_scanlines(),
114 m_min_x( 0x7FFFFFFF),
115 m_min_y( 0x7FFFFFFF),
116 m_max_x(-0x7FFFFFFF),
117 m_max_y(-0x7FFFFFFF),
118 m_cur_scanline(0)
120 m_fake_scanline.y = 0;
121 m_fake_scanline.num_spans = 0;
122 m_fake_scanline.start_span = 0;
123 m_fake_span.x = 0;
124 m_fake_span.len = 0;
127 // Renderer Interface
128 //---------------------------------------------------------------
129 void prepare(unsigned)
131 m_scanlines.remove_all();
132 m_spans.remove_all();
133 m_min_x = 0x7FFFFFFF;
134 m_min_y = 0x7FFFFFFF;
135 m_max_x = -0x7FFFFFFF;
136 m_max_y = -0x7FFFFFFF;
137 m_cur_scanline = 0;
140 //---------------------------------------------------------------
141 template<class Scanline> void render(const Scanline& sl)
143 scanline_data sl_this;
145 int y = sl.y();
146 if(y < m_min_y) m_min_y = y;
147 if(y > m_max_y) m_max_y = y;
149 sl_this.y = y;
150 sl_this.num_spans = sl.num_spans();
151 sl_this.start_span = m_spans.size();
152 typename Scanline::const_iterator span_iterator = sl.begin();
154 unsigned num_spans = sl_this.num_spans;
157 span_data sp;
158 sp.x = span_iterator->x;
159 sp.len = (int16)abs((int)(span_iterator->len));
160 m_spans.add(sp);
161 int x1 = sp.x;
162 int x2 = sp.x + sp.len - 1;
163 if(x1 < m_min_x) m_min_x = x1;
164 if(x2 > m_max_x) m_max_x = x2;
165 ++span_iterator;
167 while(--num_spans);
168 m_scanlines.add(sl_this);
172 //---------------------------------------------------------------
173 // Iterate scanlines interface
174 int min_x() const { return m_min_x; }
175 int min_y() const { return m_min_y; }
176 int max_x() const { return m_max_x; }
177 int max_y() const { return m_max_y; }
179 //---------------------------------------------------------------
180 bool rewind_scanlines()
182 m_cur_scanline = 0;
183 return m_scanlines.size() > 0;
187 //---------------------------------------------------------------
188 template<class Scanline> bool sweep_scanline(Scanline& sl)
190 sl.reset_spans();
191 for(;;)
193 if(m_cur_scanline >= m_scanlines.size()) return false;
194 const scanline_data& sl_this = m_scanlines[m_cur_scanline];
196 unsigned num_spans = sl_this.num_spans;
197 unsigned span_idx = sl_this.start_span;
200 const span_data& sp = m_spans[span_idx++];
201 sl.add_span(sp.x, sp.len, cover_full);
203 while(--num_spans);
205 ++m_cur_scanline;
206 if(sl.num_spans())
208 sl.finalize(sl_this.y);
209 break;
212 return true;
216 //---------------------------------------------------------------
217 // Specialization for embedded_scanline
218 bool sweep_scanline(embedded_scanline& sl)
222 if(m_cur_scanline >= m_scanlines.size()) return false;
223 sl.setup(m_cur_scanline);
224 ++m_cur_scanline;
226 while(sl.num_spans() == 0);
227 return true;
231 //---------------------------------------------------------------
232 unsigned byte_size() const
234 unsigned i;
235 unsigned size = sizeof(int16) * 4; // min_x, min_y, max_x, max_y
237 for(i = 0; i < m_scanlines.size(); ++i)
239 size += sizeof(int16) * 2 + // Y, num_spans
240 unsigned(m_scanlines[i].num_spans) * sizeof(int16) * 2; // X, span_len
242 return size;
246 //---------------------------------------------------------------
247 static void write_int16(int8u* dst, int16 val)
249 dst[0] = ((const int8u*)&val)[0];
250 dst[1] = ((const int8u*)&val)[1];
254 //---------------------------------------------------------------
255 void serialize(int8u* data) const
257 unsigned i;
259 write_int16(data, int16u(min_x())); // min_x
260 data += sizeof(int16u);
261 write_int16(data, int16u(min_y())); // min_y
262 data += sizeof(int16u);
263 write_int16(data, int16u(max_x())); // max_x
264 data += sizeof(int16u);
265 write_int16(data, int16u(max_y())); // max_y
266 data += sizeof(int16u);
268 for(i = 0; i < m_scanlines.size(); ++i)
270 const scanline_data& sl_this = m_scanlines[i];
272 write_int16(data, int16(sl_this.y)); // Y
273 data += sizeof(int16);
275 write_int16(data, int16(sl_this.num_spans)); // num_spans
276 data += sizeof(int16);
278 unsigned num_spans = sl_this.num_spans;
279 unsigned span_idx = sl_this.start_span;
282 const span_data& sp = m_spans[span_idx++];
284 write_int16(data, int16(sp.x)); // X
285 data += sizeof(int16);
287 write_int16(data, int16(sp.len)); // len
288 data += sizeof(int16);
290 while(--num_spans);
295 //---------------------------------------------------------------
296 const scanline_data& scanline_by_index(unsigned i) const
298 return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline;
301 //---------------------------------------------------------------
302 const span_data& span_by_index(unsigned i) const
304 return (i < m_spans.size()) ? m_spans[i] : m_fake_span;
308 private:
309 pod_deque<span_data, 10> m_spans;
310 pod_deque<scanline_data, 8> m_scanlines;
311 span_data m_fake_span;
312 scanline_data m_fake_scanline;
313 int m_min_x;
314 int m_min_y;
315 int m_max_x;
316 int m_max_y;
317 unsigned m_cur_scanline;
332 //---------------------------------------serialized_scanlines_adaptor_bin
333 class serialized_scanlines_adaptor_bin
335 public:
336 typedef bool cover_type;
338 //--------------------------------------------------------------------
339 class embedded_scanline
341 public:
343 //----------------------------------------------------------------
344 class const_iterator
346 public:
347 struct span
349 int16 x;
350 int16 len;
353 const_iterator(const embedded_scanline& sl) :
354 m_ptr(sl.m_ptr),
355 m_dx(sl.m_dx)
357 m_span.x = read_int16() + m_dx;
358 m_span.len = read_int16();
361 const span& operator*() const { return m_span; }
362 const span* operator->() const { return &m_span; }
364 void operator ++ ()
366 m_span.x = read_int16() + m_dx;
367 m_span.len = read_int16();
370 private:
371 int read_int16()
373 int16 val;
374 ((int8u*)&val)[0] = *m_ptr++;
375 ((int8u*)&val)[1] = *m_ptr++;
376 return val;
379 const int8u* m_ptr;
380 span m_span;
381 int m_dx;
384 friend class const_iterator;
387 //----------------------------------------------------------------
388 embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {}
390 //----------------------------------------------------------------
391 void reset(int, int) {}
392 unsigned num_spans() const { return m_num_spans; }
393 int y() const { return m_y; }
394 const_iterator begin() const { return const_iterator(*this); }
397 private:
398 //----------------------------------------------------------------
399 int read_int16()
401 int16 val;
402 ((int8u*)&val)[0] = *m_ptr++;
403 ((int8u*)&val)[1] = *m_ptr++;
404 return val;
407 public:
408 //----------------------------------------------------------------
409 void init(const int8u* ptr, int dx, int dy)
411 m_ptr = ptr;
412 m_y = read_int16() + dy;
413 m_num_spans = unsigned(read_int16());
414 m_dx = dx;
417 private:
418 const int8u* m_ptr;
419 int m_y;
420 unsigned m_num_spans;
421 int m_dx;
426 public:
427 //--------------------------------------------------------------------
428 serialized_scanlines_adaptor_bin() :
429 m_data(0),
430 m_end(0),
431 m_ptr(0),
432 m_dx(0),
433 m_dy(0),
434 m_min_x(0x7FFFFFFF),
435 m_min_y(0x7FFFFFFF),
436 m_max_x(-0x7FFFFFFF),
437 m_max_y(-0x7FFFFFFF)
440 //--------------------------------------------------------------------
441 serialized_scanlines_adaptor_bin(const int8u* data, unsigned size,
442 double dx, double dy) :
443 m_data(data),
444 m_end(data + size),
445 m_ptr(data),
446 m_dx(int(floor(dx + 0.5))),
447 m_dy(int(floor(dy + 0.5))),
448 m_min_x(0x7FFFFFFF),
449 m_min_y(0x7FFFFFFF),
450 m_max_x(-0x7FFFFFFF),
451 m_max_y(-0x7FFFFFFF)
454 //--------------------------------------------------------------------
455 void init(const int8u* data, unsigned size, double dx, double dy)
457 m_data = data;
458 m_end = data + size;
459 m_ptr = data;
460 m_dx = int(floor(dx + 0.5));
461 m_dy = int(floor(dy + 0.5));
462 m_min_x = 0x7FFFFFFF;
463 m_min_y = 0x7FFFFFFF;
464 m_max_x = -0x7FFFFFFF;
465 m_max_y = -0x7FFFFFFF;
468 private:
469 //--------------------------------------------------------------------
470 int read_int16()
472 int16 val;
473 ((int8u*)&val)[0] = *m_ptr++;
474 ((int8u*)&val)[1] = *m_ptr++;
475 return val;
478 public:
479 // Iterate scanlines interface
480 //--------------------------------------------------------------------
481 bool rewind_scanlines()
483 m_ptr = m_data;
484 if(m_ptr < m_end)
486 m_min_x = read_int16() + m_dx;
487 m_min_y = read_int16() + m_dy;
488 m_max_x = read_int16() + m_dx;
489 m_max_y = read_int16() + m_dy;
490 return true;
492 return false;
495 //--------------------------------------------------------------------
496 int min_x() const { return m_min_x; }
497 int min_y() const { return m_min_y; }
498 int max_x() const { return m_max_x; }
499 int max_y() const { return m_max_y; }
501 //--------------------------------------------------------------------
502 template<class Scanline> bool sweep_scanline(Scanline& sl)
504 sl.reset_spans();
505 for(;;)
507 if(m_ptr >= m_end) return false;
509 int y = read_int16() + m_dy;
510 unsigned num_spans = read_int16();
514 int x = read_int16() + m_dx;
515 int len = read_int16();
517 if(len < 0) len = -len;
518 sl.add_span(x, unsigned(len), cover_full);
520 while(--num_spans);
522 if(sl.num_spans())
524 sl.finalize(y);
525 break;
528 return true;
532 //--------------------------------------------------------------------
533 // Specialization for embedded_scanline
534 bool sweep_scanline(embedded_scanline& sl)
538 if(m_ptr >= m_end) return false;
540 sl.init(m_ptr, m_dx, m_dy);
542 // Jump to the next scanline
543 //--------------------------
544 read_int16(); // Y
545 int num_spans = read_int16(); // num_spans
546 m_ptr += num_spans * sizeof(int16) * 2;
548 while(sl.num_spans() == 0);
549 return true;
552 private:
553 const int8u* m_data;
554 const int8u* m_end;
555 const int8u* m_ptr;
556 int m_dx;
557 int m_dy;
558 int m_min_x;
559 int m_min_y;
560 int m_max_x;
561 int m_max_y;
568 #endif