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 // 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.
22 //----------------------------------------------------------------------------
25 #ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED
26 #define AGG_SCANLINE_STORAGE_BIN_INCLUDED
31 #include "agg_array.h"
37 //-----------------------------------------------scanline_storage_bin
38 class scanline_storage_bin
41 //---------------------------------------------------------------
48 //---------------------------------------------------------------
57 //---------------------------------------------------------------
58 class embedded_scanline
62 //-----------------------------------------------------------
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
; }
80 m_span
= m_storage
->span_by_index(m_span_idx
);
84 const scanline_storage_bin
* m_storage
;
89 friend class const_iterator
;
92 //-----------------------------------------------------------
93 embedded_scanline(const scanline_storage_bin
& storage
) :
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
);
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
123 m_min_x( 0x7FFFFFFF),
124 m_min_y( 0x7FFFFFFF),
125 m_max_x(-0x7FFFFFFF),
126 m_max_y(-0x7FFFFFFF),
129 m_fake_scanline
.y
= 0;
130 m_fake_scanline
.num_spans
= 0;
131 m_fake_scanline
.start_span
= 0;
136 // Renderer Interface
137 //---------------------------------------------------------------
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;
149 //---------------------------------------------------------------
150 template<class Scanline
> void render(const Scanline
& sl
)
152 scanline_data sl_this
;
155 if(y
< m_min_y
) m_min_y
= y
;
156 if(y
> m_max_y
) m_max_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
;
167 sp
.x
= span_iterator
->x
;
168 sp
.len
= (int32
)abs((int)(span_iterator
->len
));
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;
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()
192 return m_scanlines
.size() > 0;
196 //---------------------------------------------------------------
197 template<class Scanline
> bool sweep_scanline(Scanline
& sl
)
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
);
217 sl
.finalize(sl_this
.y
);
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
);
235 while(sl
.num_spans() == 0);
240 //---------------------------------------------------------------
241 unsigned byte_size() const
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
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
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
);
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
;
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
;
328 unsigned m_cur_scanline
;
343 //---------------------------------------serialized_scanlines_adaptor_bin
344 class serialized_scanlines_adaptor_bin
347 typedef bool cover_type
;
349 //--------------------------------------------------------------------
350 class embedded_scanline
354 //----------------------------------------------------------------
364 const_iterator() : m_ptr(0) {}
365 const_iterator(const embedded_scanline
& sl
) :
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
; }
378 m_span
.x
= read_int32() + m_dx
;
379 m_span
.len
= read_int32();
386 ((int8u
*)&val
)[0] = *m_ptr
++;
387 ((int8u
*)&val
)[1] = *m_ptr
++;
388 ((int8u
*)&val
)[2] = *m_ptr
++;
389 ((int8u
*)&val
)[3] = *m_ptr
++;
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); }
412 //----------------------------------------------------------------
416 ((int8u
*)&val
)[0] = *m_ptr
++;
417 ((int8u
*)&val
)[1] = *m_ptr
++;
418 ((int8u
*)&val
)[2] = *m_ptr
++;
419 ((int8u
*)&val
)[3] = *m_ptr
++;
424 //----------------------------------------------------------------
425 void init(const int8u
* ptr
, int dx
, int dy
)
428 m_y
= read_int32() + dy
;
429 m_num_spans
= unsigned(read_int32());
436 unsigned m_num_spans
;
443 //--------------------------------------------------------------------
444 serialized_scanlines_adaptor_bin() :
452 m_max_x(-0x7FFFFFFF),
456 //--------------------------------------------------------------------
457 serialized_scanlines_adaptor_bin(const int8u
* data
, unsigned size
,
458 double dx
, double dy
) :
466 m_max_x(-0x7FFFFFFF),
470 //--------------------------------------------------------------------
471 void init(const int8u
* data
, unsigned size
, double dx
, double dy
)
478 m_min_x
= 0x7FFFFFFF;
479 m_min_y
= 0x7FFFFFFF;
480 m_max_x
= -0x7FFFFFFF;
481 m_max_y
= -0x7FFFFFFF;
485 //--------------------------------------------------------------------
489 ((int8u
*)&val
)[0] = *m_ptr
++;
490 ((int8u
*)&val
)[1] = *m_ptr
++;
491 ((int8u
*)&val
)[2] = *m_ptr
++;
492 ((int8u
*)&val
)[3] = *m_ptr
++;
497 // Iterate scanlines interface
498 //--------------------------------------------------------------------
499 bool rewind_scanlines()
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
)
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
);
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 //--------------------------
562 int num_spans
= read_int32(); // num_spans
563 m_ptr
+= num_spans
* sizeof(int32
) * 2;
565 while(sl
.num_spans() == 0);