1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry (AGG) - Version 2.5
3 // A high quality rendering engine for C++
4 // Copyright (C) 2002-2006 Maxim Shemanarev
5 // Contact: mcseem@antigrain.com
6 //          mcseemagg@yahoo.com
7 //          http://antigrain.com
8 //
9 // AGG is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // AGG is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with AGG; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 // MA 02110-1301, USA.
23 //----------------------------------------------------------------------------
24 //
25 // Adaptation for 32-bit screen coordinates has been sponsored by
26 // Liberty Technology Systems, Inc., visit http://lib-sys.com
27 //
28 // Liberty Technology Systems, Inc. is the provider of
29 // PostScript and PDF technology for software developers.
30 //
31 //----------------------------------------------------------------------------
32 
33 #ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED
34 #define AGG_SCANLINE_STORAGE_AA_INCLUDED
35 
36 #include <string.h>
37 #include <stdlib.h>
38 #include <math.h>
39 #include "agg_array.h"
40 
41 
42 namespace agg
43 {
44 
45     //----------------------------------------------scanline_cell_storage
46     template<class T> class scanline_cell_storage
47     {
48         struct extra_span
49         {
50             unsigned len;
51             T*       ptr;
52         };
53 
54     public:
55         typedef T value_type;
56 
57         //---------------------------------------------------------------
~scanline_cell_storage()58         ~scanline_cell_storage()
59         {
60             remove_all();
61         }
62 
63         //---------------------------------------------------------------
scanline_cell_storage()64         scanline_cell_storage() :
65             m_cells(128-2),
66             m_extra_storage()
67         {}
68 
69 
70         // Copying
71         //---------------------------------------------------------------
scanline_cell_storage(const scanline_cell_storage<T> & v)72         scanline_cell_storage(const scanline_cell_storage<T>& v) :
73             m_cells(v.m_cells),
74             m_extra_storage()
75         {
76             copy_extra_storage(v);
77         }
78 
79         //---------------------------------------------------------------
80         const scanline_cell_storage<T>&
81         operator = (const scanline_cell_storage<T>& v)
82         {
83             remove_all();
84             m_cells = v.m_cells;
85             copy_extra_storage(v);
86             return *this;
87         }
88 
89         //---------------------------------------------------------------
remove_all()90         void remove_all()
91         {
92             int i;
93             for(i = m_extra_storage.size()-1; i >= 0; --i)
94             {
95                 pod_allocator<T>::deallocate(m_extra_storage[i].ptr,
96                                              m_extra_storage[i].len);
97             }
98             m_extra_storage.remove_all();
99             m_cells.remove_all();
100         }
101 
102         //---------------------------------------------------------------
add_cells(const T * cells,unsigned num_cells)103         int add_cells(const T* cells, unsigned num_cells)
104         {
105             int idx = m_cells.allocate_continuous_block(num_cells);
106             if(idx >= 0)
107             {
108                 T* ptr = &m_cells[idx];
109                 memcpy(ptr, cells, sizeof(T) * num_cells);
110                 return idx;
111             }
112             extra_span s;
113             s.len = num_cells;
114             s.ptr = pod_allocator<T>::allocate(num_cells);
115             memcpy(s.ptr, cells, sizeof(T) * num_cells);
116             m_extra_storage.add(s);
117             return -int(m_extra_storage.size());
118         }
119 
120         //---------------------------------------------------------------
121         const T* operator [] (int idx) const
122         {
123             if(idx >= 0)
124             {
125                 if((unsigned)idx >= m_cells.size()) return 0;
126                 return &m_cells[(unsigned)idx];
127             }
128             unsigned i = unsigned(-idx - 1);
129             if(i >= m_extra_storage.size()) return 0;
130             return m_extra_storage[i].ptr;
131         }
132 
133         //---------------------------------------------------------------
134         T* operator [] (int idx)
135         {
136             if(idx >= 0)
137             {
138                 if((unsigned)idx >= m_cells.size()) return 0;
139                 return &m_cells[(unsigned)idx];
140             }
141             unsigned i = unsigned(-idx - 1);
142             if(i >= m_extra_storage.size()) return 0;
143             return m_extra_storage[i].ptr;
144         }
145 
146     private:
copy_extra_storage(const scanline_cell_storage<T> & v)147         void copy_extra_storage(const scanline_cell_storage<T>& v)
148         {
149             unsigned i;
150             for(i = 0; i < v.m_extra_storage.size(); ++i)
151             {
152                 const extra_span& src = v.m_extra_storage[i];
153                 extra_span dst;
154                 dst.len = src.len;
155                 dst.ptr = pod_allocator<T>::allocate(dst.len);
156                 memcpy(dst.ptr, src.ptr, dst.len * sizeof(T));
157                 m_extra_storage.add(dst);
158             }
159         }
160 
161         pod_bvector<T, 12>         m_cells;
162         pod_bvector<extra_span, 6> m_extra_storage;
163     };
164 
165 
166 
167 
168 
169 
170     //-----------------------------------------------scanline_storage_aa
171     template<class T> class scanline_storage_aa
172     {
173     public:
174         typedef T cover_type;
175 
176         //---------------------------------------------------------------
177         struct span_data
178         {
179             int32 x;
180             int32 len;       // If negative, it's a solid span, covers is valid
181             int   covers_id; // The index of the cells in the scanline_cell_storage
182         };
183 
184         //---------------------------------------------------------------
185         struct scanline_data
186         {
187             int      y;
188             unsigned num_spans;
189             unsigned start_span;
190         };
191 
192 
193         //---------------------------------------------------------------
194         class embedded_scanline
195         {
196         public:
197 
198             //-----------------------------------------------------------
199             class const_iterator
200             {
201             public:
202                 struct span
203                 {
204                     int32    x;
205                     int32    len; // If negative, it's a solid span, covers is valid
206                     const T* covers;
207                 };
208 
const_iterator()209                 const_iterator() : m_storage(0) {}
const_iterator(const embedded_scanline & sl)210                 const_iterator(const embedded_scanline& sl) :
211                     m_storage(sl.m_storage),
212                     m_span_idx(sl.m_scanline.start_span)
213                 {
214                     init_span();
215                 }
216 
217                 const span& operator*()  const { return m_span;  }
218                 const span* operator->() const { return &m_span; }
219 
220                 void operator ++ ()
221                 {
222                     ++m_span_idx;
223                     init_span();
224                 }
225 
226             private:
init_span()227                 void init_span()
228                 {
229                     const span_data& s = m_storage->span_by_index(m_span_idx);
230                     m_span.x      = s.x;
231                     m_span.len    = s.len;
232                     m_span.covers = m_storage->covers_by_index(s.covers_id);
233                 }
234 
235                 const scanline_storage_aa* m_storage;
236                 unsigned                   m_span_idx;
237                 span                       m_span;
238             };
239 
240             friend class const_iterator;
241 
242 
243             //-----------------------------------------------------------
embedded_scanline(const scanline_storage_aa & storage)244             embedded_scanline(const scanline_storage_aa& storage) :
245                 m_storage(&storage)
246             {
247                 init(0);
248             }
249 
250             //-----------------------------------------------------------
reset(int,int)251             void     reset(int, int)     {}
num_spans()252             unsigned num_spans()   const { return m_scanline.num_spans;  }
y()253             int      y()           const { return m_scanline.y;          }
begin()254             const_iterator begin() const { return const_iterator(*this); }
255 
256             //-----------------------------------------------------------
init(unsigned scanline_idx)257             void init(unsigned scanline_idx)
258             {
259                 m_scanline_idx = scanline_idx;
260                 m_scanline = m_storage->scanline_by_index(m_scanline_idx);
261             }
262 
263         private:
264             const scanline_storage_aa* m_storage;
265             scanline_data              m_scanline;
266             unsigned                   m_scanline_idx;
267         };
268 
269 
270         //---------------------------------------------------------------
scanline_storage_aa()271         scanline_storage_aa() :
272             m_covers(),
273             m_spans(256-2),         // Block increment size
274             m_scanlines(),
275             m_min_x( 0x7FFFFFFF),
276             m_min_y( 0x7FFFFFFF),
277             m_max_x(-0x7FFFFFFF),
278             m_max_y(-0x7FFFFFFF),
279             m_cur_scanline(0)
280         {
281             m_fake_scanline.y = 0;
282             m_fake_scanline.num_spans = 0;
283             m_fake_scanline.start_span = 0;
284             m_fake_span.x = 0;
285             m_fake_span.len = 0;
286             m_fake_span.covers_id = 0;
287         }
288 
289         // Renderer Interface
290         //---------------------------------------------------------------
prepare()291         void prepare()
292         {
293             m_covers.remove_all();
294             m_scanlines.remove_all();
295             m_spans.remove_all();
296             m_min_x =  0x7FFFFFFF;
297             m_min_y =  0x7FFFFFFF;
298             m_max_x = -0x7FFFFFFF;
299             m_max_y = -0x7FFFFFFF;
300             m_cur_scanline = 0;
301         }
302 
303         //---------------------------------------------------------------
render(const Scanline & sl)304         template<class Scanline> void render(const Scanline& sl)
305         {
306             scanline_data sl_this;
307 
308             int y = sl.y();
309             if(y < m_min_y) m_min_y = y;
310             if(y > m_max_y) m_max_y = y;
311 
312             sl_this.y = y;
313             sl_this.num_spans = sl.num_spans();
314             sl_this.start_span = m_spans.size();
315             typename Scanline::const_iterator span_iterator = sl.begin();
316 
317             unsigned num_spans = sl_this.num_spans;
318             for(;;)
319             {
320                 span_data sp;
321 
322                 sp.x         = span_iterator->x;
323                 sp.len       = span_iterator->len;
324                 int len      = abs(int(sp.len));
325                 sp.covers_id =
326                     m_covers.add_cells(span_iterator->covers,
327                                        unsigned(len));
328                 m_spans.add(sp);
329                 int x1 = sp.x;
330                 int x2 = sp.x + len - 1;
331                 if(x1 < m_min_x) m_min_x = x1;
332                 if(x2 > m_max_x) m_max_x = x2;
333                 if(--num_spans == 0) break;
334                 ++span_iterator;
335             }
336             m_scanlines.add(sl_this);
337         }
338 
339 
340         //---------------------------------------------------------------
341         // Iterate scanlines interface
min_x()342         int min_x() const { return m_min_x; }
min_y()343         int min_y() const { return m_min_y; }
max_x()344         int max_x() const { return m_max_x; }
max_y()345         int max_y() const { return m_max_y; }
346 
347         //---------------------------------------------------------------
rewind_scanlines()348         bool rewind_scanlines()
349         {
350             m_cur_scanline = 0;
351             return m_scanlines.size() > 0;
352         }
353 
354 
355         //---------------------------------------------------------------
sweep_scanline(Scanline & sl)356         template<class Scanline> bool sweep_scanline(Scanline& sl)
357         {
358             sl.reset_spans();
359             for(;;)
360             {
361                 if(m_cur_scanline >= m_scanlines.size()) return false;
362                 const scanline_data& sl_this = m_scanlines[m_cur_scanline];
363 
364                 unsigned num_spans = sl_this.num_spans;
365                 unsigned span_idx  = sl_this.start_span;
366                 do
367                 {
368                     const span_data& sp = m_spans[span_idx++];
369                     const T* covers = covers_by_index(sp.covers_id);
370                     if(sp.len < 0)
371                     {
372                         sl.add_span(sp.x, unsigned(-sp.len), *covers);
373                     }
374                     else
375                     {
376                         sl.add_cells(sp.x, sp.len, covers);
377                     }
378                 }
379                 while(--num_spans);
380                 ++m_cur_scanline;
381                 if(sl.num_spans())
382                 {
383                     sl.finalize(sl_this.y);
384                     break;
385                 }
386             }
387             return true;
388         }
389 
390 
391         //---------------------------------------------------------------
392         // Specialization for embedded_scanline
sweep_scanline(embedded_scanline & sl)393         bool sweep_scanline(embedded_scanline& sl)
394         {
395             do
396             {
397                 if(m_cur_scanline >= m_scanlines.size()) return false;
398                 sl.init(m_cur_scanline);
399                 ++m_cur_scanline;
400             }
401             while(sl.num_spans() == 0);
402             return true;
403         }
404 
405         //---------------------------------------------------------------
byte_size()406         unsigned byte_size() const
407         {
408             unsigned i;
409             unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
410 
411             for(i = 0; i < m_scanlines.size(); ++i)
412             {
413                 size += sizeof(int32) * 3; // scanline size in bytes, Y, num_spans
414 
415                 const scanline_data& sl_this = m_scanlines[i];
416 
417                 unsigned num_spans = sl_this.num_spans;
418                 unsigned span_idx  = sl_this.start_span;
419                 do
420                 {
421                     const span_data& sp = m_spans[span_idx++];
422 
423                     size += sizeof(int32) * 2;                // X, span_len
424                     if(sp.len < 0)
425                     {
426                         size += sizeof(T);                    // cover
427                     }
428                     else
429                     {
430                         size += sizeof(T) * unsigned(sp.len); // covers
431                     }
432                 }
433                 while(--num_spans);
434             }
435             return size;
436         }
437 
438 
439         //---------------------------------------------------------------
write_int32(int8u * dst,int32 val)440         static void write_int32(int8u* dst, int32 val)
441         {
442             dst[0] = ((const int8u*)&val)[0];
443             dst[1] = ((const int8u*)&val)[1];
444             dst[2] = ((const int8u*)&val)[2];
445             dst[3] = ((const int8u*)&val)[3];
446         }
447 
448 
449         //---------------------------------------------------------------
serialize(int8u * data)450         void serialize(int8u* data) const
451         {
452             unsigned i;
453 
454             write_int32(data, min_x()); // min_x
455             data += sizeof(int32);
456             write_int32(data, min_y()); // min_y
457             data += sizeof(int32);
458             write_int32(data, max_x()); // max_x
459             data += sizeof(int32);
460             write_int32(data, max_y()); // max_y
461             data += sizeof(int32);
462 
463             for(i = 0; i < m_scanlines.size(); ++i)
464             {
465                 const scanline_data& sl_this = m_scanlines[i];
466 
467                 int8u* size_ptr = data;
468                 data += sizeof(int32);  // Reserve space for scanline size in bytes
469 
470                 write_int32(data, sl_this.y);            // Y
471                 data += sizeof(int32);
472 
473                 write_int32(data, sl_this.num_spans);    // num_spans
474                 data += sizeof(int32);
475 
476                 unsigned num_spans = sl_this.num_spans;
477                 unsigned span_idx  = sl_this.start_span;
478                 do
479                 {
480                     const span_data& sp = m_spans[span_idx++];
481                     const T* covers = covers_by_index(sp.covers_id);
482 
483                     write_int32(data, sp.x);            // X
484                     data += sizeof(int32);
485 
486                     write_int32(data, sp.len);          // span_len
487                     data += sizeof(int32);
488 
489                     if(sp.len < 0)
490                     {
491                         memcpy(data, covers, sizeof(T));
492                         data += sizeof(T);
493                     }
494                     else
495                     {
496                         memcpy(data, covers, unsigned(sp.len) * sizeof(T));
497                         data += sizeof(T) * unsigned(sp.len);
498                     }
499                 }
500                 while(--num_spans);
501                 write_int32(size_ptr, int32(unsigned(data - size_ptr)));
502             }
503         }
504 
505 
506         //---------------------------------------------------------------
scanline_by_index(unsigned i)507         const scanline_data& scanline_by_index(unsigned i) const
508         {
509             return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline;
510         }
511 
512         //---------------------------------------------------------------
span_by_index(unsigned i)513         const span_data& span_by_index(unsigned i) const
514         {
515             return (i < m_spans.size()) ? m_spans[i] : m_fake_span;
516         }
517 
518         //---------------------------------------------------------------
covers_by_index(int i)519         const T* covers_by_index(int i) const
520         {
521             return m_covers[i];
522         }
523 
524     private:
525         scanline_cell_storage<T>      m_covers;
526         pod_bvector<span_data, 10>    m_spans;
527         pod_bvector<scanline_data, 8> m_scanlines;
528         span_data     m_fake_span;
529         scanline_data m_fake_scanline;
530         int           m_min_x;
531         int           m_min_y;
532         int           m_max_x;
533         int           m_max_y;
534         unsigned      m_cur_scanline;
535     };
536 
537 
538     typedef scanline_storage_aa<int8u>  scanline_storage_aa8;  //--------scanline_storage_aa8
539     typedef scanline_storage_aa<int16u> scanline_storage_aa16; //--------scanline_storage_aa16
540     typedef scanline_storage_aa<int32u> scanline_storage_aa32; //--------scanline_storage_aa32
541 
542 
543 
544 
545     //------------------------------------------serialized_scanlines_adaptor_aa
546     template<class T> class serialized_scanlines_adaptor_aa
547     {
548     public:
549         typedef T cover_type;
550 
551         //---------------------------------------------------------------------
552         class embedded_scanline
553         {
554         public:
555             typedef T cover_type;
556 
557             //-----------------------------------------------------------------
558             class const_iterator
559             {
560             public:
561                 struct span
562                 {
563                     int32    x;
564                     int32    len; // If negative, it's a solid span, "covers" is valid
565                     const T* covers;
566                 };
567 
const_iterator()568                 const_iterator() : m_ptr(0) {}
const_iterator(const embedded_scanline & sl)569                 const_iterator(const embedded_scanline& sl) :
570                     m_ptr(sl.m_ptr),
571                     m_dx(sl.m_dx)
572                 {
573                     init_span();
574                 }
575 
576                 const span& operator*()  const { return m_span;  }
577                 const span* operator->() const { return &m_span; }
578 
579                 void operator ++ ()
580                 {
581                     if(m_span.len < 0)
582                     {
583                         m_ptr += sizeof(T);
584                     }
585                     else
586                     {
587                         m_ptr += m_span.len * sizeof(T);
588                     }
589                     init_span();
590                 }
591 
592             private:
read_int32()593                 int read_int32()
594                 {
595                     int32 val;
596                     ((int8u*)&val)[0] = *m_ptr++;
597                     ((int8u*)&val)[1] = *m_ptr++;
598                     ((int8u*)&val)[2] = *m_ptr++;
599                     ((int8u*)&val)[3] = *m_ptr++;
600                     return val;
601                 }
602 
init_span()603                 void init_span()
604                 {
605                     m_span.x      = read_int32() + m_dx;
606                     m_span.len    = read_int32();
607                     m_span.covers = m_ptr;
608                 }
609 
610                 const int8u* m_ptr;
611                 span         m_span;
612                 int          m_dx;
613             };
614 
615             friend class const_iterator;
616 
617 
618             //-----------------------------------------------------------------
embedded_scanline()619             embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {}
620 
621             //-----------------------------------------------------------------
reset(int,int)622             void     reset(int, int)     {}
num_spans()623             unsigned num_spans()   const { return m_num_spans;  }
y()624             int      y()           const { return m_y;          }
begin()625             const_iterator begin() const { return const_iterator(*this); }
626 
627 
628         private:
629             //-----------------------------------------------------------------
read_int32()630             int read_int32()
631             {
632                 int32 val;
633                 ((int8u*)&val)[0] = *m_ptr++;
634                 ((int8u*)&val)[1] = *m_ptr++;
635                 ((int8u*)&val)[2] = *m_ptr++;
636                 ((int8u*)&val)[3] = *m_ptr++;
637                 return val;
638             }
639 
640         public:
641             //-----------------------------------------------------------------
init(const int8u * ptr,int dx,int dy)642             void init(const int8u* ptr, int dx, int dy)
643             {
644                 m_ptr       = ptr;
645                 m_y         = read_int32() + dy;
646                 m_num_spans = unsigned(read_int32());
647                 m_dx        = dx;
648             }
649 
650         private:
651             const int8u* m_ptr;
652             int          m_y;
653             unsigned     m_num_spans;
654             int          m_dx;
655         };
656 
657 
658 
659     public:
660         //--------------------------------------------------------------------
serialized_scanlines_adaptor_aa()661         serialized_scanlines_adaptor_aa() :
662             m_data(0),
663             m_end(0),
664             m_ptr(0),
665             m_dx(0),
666             m_dy(0),
667             m_min_x(0x7FFFFFFF),
668             m_min_y(0x7FFFFFFF),
669             m_max_x(-0x7FFFFFFF),
670             m_max_y(-0x7FFFFFFF)
671         {}
672 
673         //--------------------------------------------------------------------
serialized_scanlines_adaptor_aa(const int8u * data,unsigned size,double dx,double dy)674         serialized_scanlines_adaptor_aa(const int8u* data, unsigned size,
675                                         double dx, double dy) :
676             m_data(data),
677             m_end(data + size),
678             m_ptr(data),
679             m_dx(iround(dx)),
680             m_dy(iround(dy)),
681             m_min_x(0x7FFFFFFF),
682             m_min_y(0x7FFFFFFF),
683             m_max_x(-0x7FFFFFFF),
684             m_max_y(-0x7FFFFFFF)
685         {}
686 
687         //--------------------------------------------------------------------
init(const int8u * data,unsigned size,double dx,double dy)688         void init(const int8u* data, unsigned size, double dx, double dy)
689         {
690             m_data  = data;
691             m_end   = data + size;
692             m_ptr   = data;
693             m_dx    = iround(dx);
694             m_dy    = iround(dy);
695             m_min_x = 0x7FFFFFFF;
696             m_min_y = 0x7FFFFFFF;
697             m_max_x = -0x7FFFFFFF;
698             m_max_y = -0x7FFFFFFF;
699         }
700 
701     private:
702         //--------------------------------------------------------------------
read_int32()703         int read_int32()
704         {
705             int32 val;
706             ((int8u*)&val)[0] = *m_ptr++;
707             ((int8u*)&val)[1] = *m_ptr++;
708             ((int8u*)&val)[2] = *m_ptr++;
709             ((int8u*)&val)[3] = *m_ptr++;
710             return val;
711         }
712 
713         //--------------------------------------------------------------------
read_int32u()714         unsigned read_int32u()
715         {
716             int32u val;
717             ((int8u*)&val)[0] = *m_ptr++;
718             ((int8u*)&val)[1] = *m_ptr++;
719             ((int8u*)&val)[2] = *m_ptr++;
720             ((int8u*)&val)[3] = *m_ptr++;
721             return val;
722         }
723 
724     public:
725         // Iterate scanlines interface
726         //--------------------------------------------------------------------
rewind_scanlines()727         bool rewind_scanlines()
728         {
729             m_ptr = m_data;
730             if(m_ptr < m_end)
731             {
732                 m_min_x = read_int32() + m_dx;
733                 m_min_y = read_int32() + m_dy;
734                 m_max_x = read_int32() + m_dx;
735                 m_max_y = read_int32() + m_dy;
736             }
737             return m_ptr < m_end;
738         }
739 
740         //--------------------------------------------------------------------
min_x()741         int min_x() const { return m_min_x; }
min_y()742         int min_y() const { return m_min_y; }
max_x()743         int max_x() const { return m_max_x; }
max_y()744         int max_y() const { return m_max_y; }
745 
746         //--------------------------------------------------------------------
sweep_scanline(Scanline & sl)747         template<class Scanline> bool sweep_scanline(Scanline& sl)
748         {
749             sl.reset_spans();
750             for(;;)
751             {
752                 if(m_ptr >= m_end) return false;
753 
754                 read_int32();      // Skip scanline size in bytes
755                 int y = read_int32() + m_dy;
756                 unsigned num_spans = read_int32();
757 
758                 do
759                 {
760                     int x = read_int32() + m_dx;
761                     int len = read_int32();
762 
763                     if(len < 0)
764                     {
765                         sl.add_span(x, unsigned(-len), *m_ptr);
766                         m_ptr += sizeof(T);
767                     }
768                     else
769                     {
770                         sl.add_cells(x, len, m_ptr);
771                         m_ptr += len * sizeof(T);
772                     }
773                 }
774                 while(--num_spans);
775 
776                 if(sl.num_spans())
777                 {
778                     sl.finalize(y);
779                     break;
780                 }
781             }
782             return true;
783         }
784 
785 
786         //--------------------------------------------------------------------
787         // Specialization for embedded_scanline
sweep_scanline(embedded_scanline & sl)788         bool sweep_scanline(embedded_scanline& sl)
789         {
790             do
791             {
792                 if(m_ptr >= m_end) return false;
793 
794                 unsigned byte_size = read_int32u();
795                 sl.init(m_ptr, m_dx, m_dy);
796                 m_ptr += byte_size - sizeof(int32);
797             }
798             while(sl.num_spans() == 0);
799             return true;
800         }
801 
802     private:
803         const int8u* m_data;
804         const int8u* m_end;
805         const int8u* m_ptr;
806         int          m_dx;
807         int          m_dy;
808         int          m_min_x;
809         int          m_min_y;
810         int          m_max_x;
811         int          m_max_y;
812     };
813 
814 
815 
816     typedef serialized_scanlines_adaptor_aa<int8u>  serialized_scanlines_adaptor_aa8;  //----serialized_scanlines_adaptor_aa8
817     typedef serialized_scanlines_adaptor_aa<int16u> serialized_scanlines_adaptor_aa16; //----serialized_scanlines_adaptor_aa16
818     typedef serialized_scanlines_adaptor_aa<int32u> serialized_scanlines_adaptor_aa32; //----serialized_scanlines_adaptor_aa32
819 
820 }
821 
822 
823 #endif
824 
825