24 #ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED 25 #define AGG_SCANLINE_STORAGE_AA_INCLUDED 30 #include "agg_array.h" 67 copy_extra_storage(v);
76 copy_extra_storage(v);
84 for(i = m_extra_storage.size()-1; i >= 0; --i)
87 m_extra_storage[i].len);
89 m_extra_storage.remove_all();
94 int add_cells(
const T* cells,
unsigned num_cells)
96 int idx = m_cells.allocate_continuous_block(num_cells);
99 T* ptr = &m_cells[idx];
100 std::memcpy(ptr, cells,
sizeof(T) * num_cells);
106 std::memcpy(s.ptr, cells,
sizeof(T) * num_cells);
107 m_extra_storage.add(s);
108 return -int(m_extra_storage.size());
112 const T* operator [] (
int idx)
const 116 if((
unsigned)idx >= m_cells.size())
return 0;
117 return &m_cells[(unsigned)idx];
119 unsigned i = unsigned(-idx - 1);
120 if(i >= m_extra_storage.size())
return 0;
121 return m_extra_storage[i].ptr;
125 T* operator [] (
int idx)
129 if((
unsigned)idx >= m_cells.size())
return 0;
130 return &m_cells[(unsigned)idx];
132 unsigned i = unsigned(-idx - 1);
133 if(i >= m_extra_storage.size())
return 0;
134 return m_extra_storage[i].ptr;
141 for(i = 0; i < v.m_extra_storage.size(); ++i)
143 const extra_span& src = v.m_extra_storage[i];
147 std::memcpy(dst.ptr, src.ptr, dst.len *
sizeof(T));
148 m_extra_storage.add(dst);
165 typedef T cover_type;
202 m_storage(sl.m_storage),
203 m_span_idx(sl.m_scanline.start_span)
208 const span& operator*()
const {
return m_span; }
209 const span* operator->()
const {
return &m_span; }
220 const span_data& s = m_storage->span_by_index(m_span_idx);
223 m_span.covers = m_storage->covers_by_index(s.covers_id);
242 void reset(
int,
int) {}
243 unsigned num_spans()
const {
return m_scanline.num_spans; }
244 int y()
const {
return m_scanline.y; }
248 void init(
unsigned scanline_idx)
250 m_scanline_idx = scanline_idx;
251 m_scanline = m_storage->scanline_by_index(m_scanline_idx);
257 unsigned m_scanline_idx;
266 m_min_x(std::numeric_limits<int>::max()),
267 m_min_y(std::numeric_limits<int>::max()),
268 m_max_x(std::numeric_limits<int>::min()),
269 m_max_y(std::numeric_limits<int>::min()),
272 m_fake_scanline.y = 0;
273 m_fake_scanline.num_spans = 0;
274 m_fake_scanline.start_span = 0;
277 m_fake_span.covers_id = 0;
284 m_covers.remove_all();
285 m_scanlines.remove_all();
286 m_spans.remove_all();
287 m_min_x = std::numeric_limits<int>::max();
288 m_min_y = std::numeric_limits<int>::max();
289 m_max_x = std::numeric_limits<int>::min();
290 m_max_y = std::numeric_limits<int>::min();
295 template<
class Scanline>
void render(
const Scanline& sl)
300 if(y < m_min_y) m_min_y = y;
301 if(y > m_max_y) m_max_y = y;
304 sl_this.num_spans = sl.num_spans();
305 sl_this.start_span = m_spans.size();
306 typename Scanline::const_iterator span_iterator = sl.begin();
308 unsigned num_spans = sl_this.num_spans;
313 sp.x = span_iterator->x;
314 sp.len = span_iterator->len;
315 int len = std::abs(
int(sp.len));
317 m_covers.add_cells(span_iterator->covers,
321 int x2 = sp.x + len - 1;
322 if(x1 < m_min_x) m_min_x = x1;
323 if(x2 > m_max_x) m_max_x = x2;
324 if(--num_spans == 0)
break;
327 m_scanlines.add(sl_this);
333 int min_x()
const {
return m_min_x; }
334 int min_y()
const {
return m_min_y; }
335 int max_x()
const {
return m_max_x; }
336 int max_y()
const {
return m_max_y; }
339 bool rewind_scanlines()
342 return m_scanlines.size() > 0;
347 template<
class Scanline>
bool sweep_scanline(Scanline& sl)
352 if(m_cur_scanline >= m_scanlines.size())
return false;
355 unsigned num_spans = sl_this.num_spans;
356 unsigned span_idx = sl_this.start_span;
359 const span_data& sp = m_spans[span_idx++];
360 const T* covers = covers_by_index(sp.covers_id);
363 sl.add_span(sp.x,
unsigned(-sp.len), *covers);
367 sl.add_cells(sp.x, sp.len, covers);
374 sl.finalize(sl_this.y);
388 if(m_cur_scanline >= m_scanlines.size())
return false;
389 sl.init(m_cur_scanline);
392 while(sl.num_spans() == 0);
397 unsigned byte_size()
const 400 unsigned size =
sizeof(int32) * 4;
402 for(i = 0; i < m_scanlines.size(); ++i)
404 size +=
sizeof(int32) * 3;
408 unsigned num_spans = sl_this.num_spans;
409 unsigned span_idx = sl_this.start_span;
412 const span_data& sp = m_spans[span_idx++];
414 size +=
sizeof(int32) * 2;
421 size +=
sizeof(T) *
unsigned(sp.len);
431 static void write_int32(int8u* dst, int32 val)
433 dst[0] = ((
const int8u*)&val)[0];
434 dst[1] = ((
const int8u*)&val)[1];
435 dst[2] = ((
const int8u*)&val)[2];
436 dst[3] = ((
const int8u*)&val)[3];
441 void serialize(int8u* data)
const 445 write_int32(data, min_x());
446 data +=
sizeof(int32);
447 write_int32(data, min_y());
448 data +=
sizeof(int32);
449 write_int32(data, max_x());
450 data +=
sizeof(int32);
451 write_int32(data, max_y());
452 data +=
sizeof(int32);
454 for(i = 0; i < m_scanlines.size(); ++i)
458 int8u* size_ptr = data;
459 data +=
sizeof(int32);
461 write_int32(data, sl_this.y);
462 data +=
sizeof(int32);
464 write_int32(data, sl_this.num_spans);
465 data +=
sizeof(int32);
467 unsigned num_spans = sl_this.num_spans;
468 unsigned span_idx = sl_this.start_span;
471 const span_data& sp = m_spans[span_idx++];
472 const T* covers = covers_by_index(sp.covers_id);
474 write_int32(data, sp.x);
475 data +=
sizeof(int32);
477 write_int32(data, sp.len);
478 data +=
sizeof(int32);
482 std::memcpy(data, covers,
sizeof(T));
487 std::memcpy(data, covers,
unsigned(sp.len) *
sizeof(T));
488 data +=
sizeof(T) *
unsigned(sp.len);
492 write_int32(size_ptr, int32(
unsigned(data - size_ptr)));
500 return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline;
504 const span_data& span_by_index(
unsigned i)
const 506 return (i < m_spans.size()) ? m_spans[i] : m_fake_span;
510 const T* covers_by_index(
int i)
const 525 unsigned m_cur_scanline;
540 typedef T cover_type;
546 typedef T cover_type;
567 const span& operator*()
const {
return m_span; }
568 const span* operator->()
const {
return &m_span; }
578 m_ptr += m_span.len *
sizeof(T);
587 ((int8u*)&val)[0] = *m_ptr++;
588 ((int8u*)&val)[1] = *m_ptr++;
589 ((int8u*)&val)[2] = *m_ptr++;
590 ((int8u*)&val)[3] = *m_ptr++;
596 m_span.x = read_int32() + m_dx;
597 m_span.len = read_int32();
598 m_span.covers = m_ptr;
613 void reset(
int,
int) {}
614 unsigned num_spans()
const {
return m_num_spans; }
615 int y()
const {
return m_y; }
624 ((int8u*)&val)[0] = *m_ptr++;
625 ((int8u*)&val)[1] = *m_ptr++;
626 ((int8u*)&val)[2] = *m_ptr++;
627 ((int8u*)&val)[3] = *m_ptr++;
633 void init(
const int8u* ptr,
int dx,
int dy)
636 m_y = read_int32() + dy;
637 m_num_spans = unsigned(read_int32());
644 unsigned m_num_spans;
658 m_min_x(std::numeric_limits<int>::max()),
659 m_min_y(std::numeric_limits<int>::max()),
660 m_max_x(std::numeric_limits<int>::min()),
661 m_max_y(std::numeric_limits<int>::min())
666 double dx,
double dy) :
672 m_min_x(std::numeric_limits<int>::max()),
673 m_min_y(std::numeric_limits<int>::max()),
674 m_max_x(std::numeric_limits<int>::min()),
675 m_max_y(std::numeric_limits<int>::min())
679 void init(
const int8u* data,
unsigned size,
double dx,
double dy)
686 m_min_x = std::numeric_limits<int>::max();
687 m_min_y = std::numeric_limits<int>::max();
688 m_max_x = std::numeric_limits<int>::min();
689 m_max_y = std::numeric_limits<int>::min();
697 ((int8u*)&val)[0] = *m_ptr++;
698 ((int8u*)&val)[1] = *m_ptr++;
699 ((int8u*)&val)[2] = *m_ptr++;
700 ((int8u*)&val)[3] = *m_ptr++;
705 unsigned read_int32u()
708 ((int8u*)&val)[0] = *m_ptr++;
709 ((int8u*)&val)[1] = *m_ptr++;
710 ((int8u*)&val)[2] = *m_ptr++;
711 ((int8u*)&val)[3] = *m_ptr++;
718 bool rewind_scanlines()
723 m_min_x = read_int32() + m_dx;
724 m_min_y = read_int32() + m_dy;
725 m_max_x = read_int32() + m_dx;
726 m_max_y = read_int32() + m_dy;
728 return m_ptr < m_end;
732 int min_x()
const {
return m_min_x; }
733 int min_y()
const {
return m_min_y; }
734 int max_x()
const {
return m_max_x; }
735 int max_y()
const {
return m_max_y; }
738 template<
class Scanline>
bool sweep_scanline(Scanline& sl)
743 if(m_ptr >= m_end)
return false;
746 int y = read_int32() + m_dy;
747 unsigned num_spans = read_int32();
751 int x = read_int32() + m_dx;
752 int len = read_int32();
756 sl.add_span(x,
unsigned(-len), *m_ptr);
761 sl.add_cells(x, len, m_ptr);
762 m_ptr += len *
sizeof(T);
783 if(m_ptr >= m_end)
return false;
785 unsigned byte_size = read_int32u();
786 sl.init(m_ptr, m_dx, m_dy);
787 m_ptr += byte_size -
sizeof(int32);
789 while(sl.num_spans() == 0);