Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_scanline_storage_aa.h
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 // Anti-Grain Geometry (AGG) - Version 2.5
00003 // A high quality rendering engine for C++
00004 // Copyright (C) 2002-2006 Maxim Shemanarev
00005 // Contact: mcseem@antigrain.com
00006 //          mcseemagg@yahoo.com
00007 //          http://antigrain.com
00008 // 
00009 // AGG is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU General Public License
00011 // as published by the Free Software Foundation; either version 2
00012 // of the License, or (at your option) any later version.
00013 // 
00014 // AGG is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU General Public License
00020 // along with AGG; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00022 // MA 02110-1301, USA.
00023 //----------------------------------------------------------------------------
00024 //
00025 // Adaptation for 32-bit screen coordinates has been sponsored by 
00026 // Liberty Technology Systems, Inc., visit http://lib-sys.com
00027 //
00028 // Liberty Technology Systems, Inc. is the provider of
00029 // PostScript and PDF technology for software developers.
00030 // 
00031 //----------------------------------------------------------------------------
00032 
00033 #ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED
00034 #define AGG_SCANLINE_STORAGE_AA_INCLUDED
00035 
00036 #include <string.h>
00037 #include <stdlib.h>
00038 #include <math.h>
00039 #include "agg_array.h"
00040 
00041 
00042 namespace agg
00043 {
00044 
00045     //----------------------------------------------scanline_cell_storage
00046     template<class T> class scanline_cell_storage
00047     {
00048         struct extra_span
00049         {
00050             unsigned len;
00051             T*       ptr;
00052         };
00053 
00054     public:
00055         typedef T value_type;
00056 
00057         //---------------------------------------------------------------
00058         ~scanline_cell_storage()
00059         {
00060             remove_all();
00061         }
00062 
00063         //---------------------------------------------------------------
00064         scanline_cell_storage() :
00065             m_cells(128-2),
00066             m_extra_storage()
00067         {}
00068 
00069 
00070         // Copying
00071         //---------------------------------------------------------------
00072         scanline_cell_storage(const scanline_cell_storage<T>& v) :
00073             m_cells(v.m_cells),
00074             m_extra_storage()
00075         {
00076             copy_extra_storage(v);
00077         }
00078 
00079         //---------------------------------------------------------------
00080         const scanline_cell_storage<T>& 
00081         operator = (const scanline_cell_storage<T>& v)
00082         {
00083             remove_all();
00084             m_cells = v.m_cells;
00085             copy_extra_storage(v);
00086             return *this;
00087         }
00088 
00089         //---------------------------------------------------------------
00090         void remove_all()
00091         {
00092             int i;
00093             for(i = m_extra_storage.size()-1; i >= 0; --i)
00094             {
00095                 pod_allocator<T>::deallocate(m_extra_storage[i].ptr,
00096                                              m_extra_storage[i].len);
00097             }
00098             m_extra_storage.remove_all();
00099             m_cells.remove_all();
00100         }
00101 
00102         //---------------------------------------------------------------
00103         int add_cells(const T* cells, unsigned num_cells)
00104         {
00105             int idx = m_cells.allocate_continuous_block(num_cells);
00106             if(idx >= 0)
00107             {
00108                 T* ptr = &m_cells[idx];
00109                 memcpy(ptr, cells, sizeof(T) * num_cells);
00110                 return idx;
00111             }
00112             extra_span s;
00113             s.len = num_cells;
00114             s.ptr = pod_allocator<T>::allocate(num_cells);
00115             memcpy(s.ptr, cells, sizeof(T) * num_cells);
00116             m_extra_storage.add(s);
00117             return -int(m_extra_storage.size());
00118         }
00119 
00120         //---------------------------------------------------------------
00121         const T* operator [] (int idx) const
00122         {
00123             if(idx >= 0)
00124             {
00125                 if((unsigned)idx >= m_cells.size()) return 0;
00126                 return &m_cells[(unsigned)idx];
00127             }
00128             unsigned i = unsigned(-idx - 1);
00129             if(i >= m_extra_storage.size()) return 0;
00130             return m_extra_storage[i].ptr;
00131         }
00132 
00133         //---------------------------------------------------------------
00134         T* operator [] (int idx)
00135         {
00136             if(idx >= 0)
00137             {
00138                 if((unsigned)idx >= m_cells.size()) return 0;
00139                 return &m_cells[(unsigned)idx];
00140             }
00141             unsigned i = unsigned(-idx - 1);
00142             if(i >= m_extra_storage.size()) return 0;
00143             return m_extra_storage[i].ptr;
00144         }
00145 
00146     private:
00147         void copy_extra_storage(const scanline_cell_storage<T>& v)
00148         {
00149             unsigned i;
00150             for(i = 0; i < v.m_extra_storage.size(); ++i)
00151             {
00152                 const extra_span& src = v.m_extra_storage[i];
00153                 extra_span dst;
00154                 dst.len = src.len;
00155                 dst.ptr = pod_allocator<T>::allocate(dst.len);
00156                 memcpy(dst.ptr, src.ptr, dst.len * sizeof(T));
00157                 m_extra_storage.add(dst);
00158             }
00159         }
00160 
00161         pod_bvector<T, 12>         m_cells;
00162         pod_bvector<extra_span, 6> m_extra_storage;
00163     };
00164 
00165 
00166 
00167 
00168 
00169 
00170     //-----------------------------------------------scanline_storage_aa
00171     template<class T> class scanline_storage_aa
00172     {
00173     public:
00174         typedef T cover_type;
00175 
00176         //---------------------------------------------------------------
00177         struct span_data
00178         {
00179             int32 x;
00180             int32 len;       // If negative, it's a solid span, covers is valid
00181             int   covers_id; // The index of the cells in the scanline_cell_storage
00182         };
00183 
00184         //---------------------------------------------------------------
00185         struct scanline_data
00186         {
00187             int      y;
00188             unsigned num_spans;
00189             unsigned start_span;
00190         };
00191 
00192 
00193         //---------------------------------------------------------------
00194         class embedded_scanline
00195         {
00196         public:
00197 
00198             //-----------------------------------------------------------
00199             class const_iterator
00200             {
00201             public:
00202                 struct span
00203                 {
00204                     int32    x;
00205                     int32    len; // If negative, it's a solid span, covers is valid
00206                     const T* covers;
00207                 };
00208 
00209                 const_iterator() : m_storage(0) {}
00210                 const_iterator(const embedded_scanline& sl) :
00211                     m_storage(sl.m_storage),
00212                     m_span_idx(sl.m_scanline.start_span)
00213                 {
00214                     init_span();
00215                 }
00216 
00217                 const span& operator*()  const { return m_span;  }
00218                 const span* operator->() const { return &m_span; }
00219 
00220                 void operator ++ ()
00221                 {
00222                     ++m_span_idx;
00223                     init_span();
00224                 }
00225 
00226             private:
00227                 void init_span()
00228                 {
00229                     const span_data& s = m_storage->span_by_index(m_span_idx);
00230                     m_span.x      = s.x;
00231                     m_span.len    = s.len;
00232                     m_span.covers = m_storage->covers_by_index(s.covers_id);
00233                 }
00234 
00235                 const scanline_storage_aa* m_storage;
00236                 unsigned                   m_span_idx;
00237                 span                       m_span;
00238             };
00239 
00240             friend class const_iterator;
00241 
00242 
00243             //-----------------------------------------------------------
00244             embedded_scanline(const scanline_storage_aa& storage) :
00245                 m_storage(&storage)
00246             {
00247                 init(0);
00248             }
00249 
00250             //-----------------------------------------------------------
00251             void     reset(int, int)     {}
00252             unsigned num_spans()   const { return m_scanline.num_spans;  }
00253             int      y()           const { return m_scanline.y;          }
00254             const_iterator begin() const { return const_iterator(*this); }
00255 
00256             //-----------------------------------------------------------
00257             void init(unsigned scanline_idx)
00258             {
00259                 m_scanline_idx = scanline_idx;
00260                 m_scanline = m_storage->scanline_by_index(m_scanline_idx);
00261             }
00262 
00263         private:
00264             const scanline_storage_aa* m_storage;
00265             scanline_data              m_scanline;
00266             unsigned                   m_scanline_idx;
00267         };
00268 
00269 
00270         //---------------------------------------------------------------
00271         scanline_storage_aa() :
00272             m_covers(),
00273             m_spans(256-2),         // Block increment size
00274             m_scanlines(),
00275             m_min_x( 0x7FFFFFFF),
00276             m_min_y( 0x7FFFFFFF),
00277             m_max_x(-0x7FFFFFFF),
00278             m_max_y(-0x7FFFFFFF),
00279             m_cur_scanline(0)
00280         {
00281             m_fake_scanline.y = 0;
00282             m_fake_scanline.num_spans = 0;
00283             m_fake_scanline.start_span = 0;
00284             m_fake_span.x = 0;
00285             m_fake_span.len = 0;
00286             m_fake_span.covers_id = 0;
00287         }
00288 
00289         // Renderer Interface
00290         //---------------------------------------------------------------
00291         void prepare()
00292         {
00293             m_covers.remove_all();
00294             m_scanlines.remove_all();
00295             m_spans.remove_all();
00296             m_min_x =  0x7FFFFFFF;
00297             m_min_y =  0x7FFFFFFF;
00298             m_max_x = -0x7FFFFFFF;
00299             m_max_y = -0x7FFFFFFF;
00300             m_cur_scanline = 0;
00301         }
00302 
00303         //---------------------------------------------------------------
00304         template<class Scanline> void render(const Scanline& sl)
00305         {
00306             scanline_data sl_this;
00307 
00308             int y = sl.y();
00309             if(y < m_min_y) m_min_y = y;
00310             if(y > m_max_y) m_max_y = y;
00311 
00312             sl_this.y = y;
00313             sl_this.num_spans = sl.num_spans();
00314             sl_this.start_span = m_spans.size();
00315             typename Scanline::const_iterator span_iterator = sl.begin();
00316 
00317             unsigned num_spans = sl_this.num_spans;
00318             for(;;)
00319             {
00320                 span_data sp;
00321 
00322                 sp.x         = span_iterator->x;
00323                 sp.len       = span_iterator->len;
00324                 int len      = abs(int(sp.len));
00325                 sp.covers_id = 
00326                     m_covers.add_cells(span_iterator->covers, 
00327                                        unsigned(len));
00328                 m_spans.add(sp);
00329                 int x1 = sp.x;
00330                 int x2 = sp.x + len - 1;
00331                 if(x1 < m_min_x) m_min_x = x1;
00332                 if(x2 > m_max_x) m_max_x = x2;
00333                 if(--num_spans == 0) break;
00334                 ++span_iterator;
00335             }
00336             m_scanlines.add(sl_this);
00337         }
00338 
00339 
00340         //---------------------------------------------------------------
00341         // Iterate scanlines interface
00342         int min_x() const { return m_min_x; }
00343         int min_y() const { return m_min_y; }
00344         int max_x() const { return m_max_x; }
00345         int max_y() const { return m_max_y; }
00346 
00347         //---------------------------------------------------------------
00348         bool rewind_scanlines()
00349         {
00350             m_cur_scanline = 0;
00351             return m_scanlines.size() > 0;
00352         }
00353 
00354 
00355         //---------------------------------------------------------------
00356         template<class Scanline> bool sweep_scanline(Scanline& sl)
00357         {
00358             sl.reset_spans();
00359             for(;;)
00360             {
00361                 if(m_cur_scanline >= m_scanlines.size()) return false;
00362                 const scanline_data& sl_this = m_scanlines[m_cur_scanline];
00363 
00364                 unsigned num_spans = sl_this.num_spans;
00365                 unsigned span_idx  = sl_this.start_span;
00366                 do
00367                 {
00368                     const span_data& sp = m_spans[span_idx++];
00369                     const T* covers = covers_by_index(sp.covers_id);
00370                     if(sp.len < 0)
00371                     {
00372                         sl.add_span(sp.x, unsigned(-sp.len), *covers);
00373                     }
00374                     else
00375                     {
00376                         sl.add_cells(sp.x, sp.len, covers);
00377                     }
00378                 }
00379                 while(--num_spans);
00380                 ++m_cur_scanline;
00381                 if(sl.num_spans())
00382                 {
00383                     sl.finalize(sl_this.y);
00384                     break;
00385                 }
00386             }
00387             return true;
00388         }
00389 
00390 
00391         //---------------------------------------------------------------
00392         // Specialization for embedded_scanline
00393         bool sweep_scanline(embedded_scanline& sl)
00394         {
00395             do
00396             {
00397                 if(m_cur_scanline >= m_scanlines.size()) return false;
00398                 sl.init(m_cur_scanline);
00399                 ++m_cur_scanline;
00400             }
00401             while(sl.num_spans() == 0);
00402             return true;
00403         }
00404 
00405         //---------------------------------------------------------------
00406         unsigned byte_size() const
00407         {
00408             unsigned i;
00409             unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
00410 
00411             for(i = 0; i < m_scanlines.size(); ++i)
00412             {
00413                 size += sizeof(int32) * 3; // scanline size in bytes, Y, num_spans
00414 
00415                 const scanline_data& sl_this = m_scanlines[i];
00416 
00417                 unsigned num_spans = sl_this.num_spans;
00418                 unsigned span_idx  = sl_this.start_span;
00419                 do
00420                 {
00421                     const span_data& sp = m_spans[span_idx++];
00422 
00423                     size += sizeof(int32) * 2;                // X, span_len
00424                     if(sp.len < 0)
00425                     {
00426                         size += sizeof(T);                    // cover
00427                     }
00428                     else
00429                     {
00430                         size += sizeof(T) * unsigned(sp.len); // covers
00431                     }
00432                 }
00433                 while(--num_spans);
00434             }
00435             return size;
00436         }
00437 
00438 
00439         //---------------------------------------------------------------
00440         static void write_int32(int8u* dst, int32 val)
00441         {
00442             dst[0] = ((const int8u*)&val)[0];
00443             dst[1] = ((const int8u*)&val)[1];
00444             dst[2] = ((const int8u*)&val)[2];
00445             dst[3] = ((const int8u*)&val)[3];
00446         }
00447 
00448 
00449         //---------------------------------------------------------------
00450         void serialize(int8u* data) const
00451         {
00452             unsigned i;
00453 
00454             write_int32(data, min_x()); // min_x
00455             data += sizeof(int32);
00456             write_int32(data, min_y()); // min_y
00457             data += sizeof(int32);
00458             write_int32(data, max_x()); // max_x
00459             data += sizeof(int32);
00460             write_int32(data, max_y()); // max_y
00461             data += sizeof(int32);
00462 
00463             for(i = 0; i < m_scanlines.size(); ++i)
00464             {
00465                 const scanline_data& sl_this = m_scanlines[i];
00466                 
00467                 int8u* size_ptr = data;
00468                 data += sizeof(int32);  // Reserve space for scanline size in bytes
00469 
00470                 write_int32(data, sl_this.y);            // Y
00471                 data += sizeof(int32);
00472 
00473                 write_int32(data, sl_this.num_spans);    // num_spans
00474                 data += sizeof(int32);
00475 
00476                 unsigned num_spans = sl_this.num_spans;
00477                 unsigned span_idx  = sl_this.start_span;
00478                 do
00479                 {
00480                     const span_data& sp = m_spans[span_idx++];
00481                     const T* covers = covers_by_index(sp.covers_id);
00482 
00483                     write_int32(data, sp.x);            // X
00484                     data += sizeof(int32);
00485 
00486                     write_int32(data, sp.len);          // span_len
00487                     data += sizeof(int32);
00488 
00489                     if(sp.len < 0)
00490                     {
00491                         memcpy(data, covers, sizeof(T));
00492                         data += sizeof(T);
00493                     }
00494                     else
00495                     {
00496                         memcpy(data, covers, unsigned(sp.len) * sizeof(T));
00497                         data += sizeof(T) * unsigned(sp.len);
00498                     }
00499                 }
00500                 while(--num_spans);
00501                 write_int32(size_ptr, int32(unsigned(data - size_ptr)));
00502             }
00503         }
00504 
00505 
00506         //---------------------------------------------------------------
00507         const scanline_data& scanline_by_index(unsigned i) const
00508         {
00509             return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline;
00510         }
00511 
00512         //---------------------------------------------------------------
00513         const span_data& span_by_index(unsigned i) const
00514         {
00515             return (i < m_spans.size()) ? m_spans[i] : m_fake_span;
00516         }
00517 
00518         //---------------------------------------------------------------
00519         const T* covers_by_index(int i) const
00520         {
00521             return m_covers[i];
00522         }
00523 
00524     private:
00525         scanline_cell_storage<T>      m_covers;
00526         pod_bvector<span_data, 10>    m_spans;
00527         pod_bvector<scanline_data, 8> m_scanlines;
00528         span_data     m_fake_span;
00529         scanline_data m_fake_scanline;
00530         int           m_min_x;
00531         int           m_min_y;
00532         int           m_max_x;
00533         int           m_max_y;
00534         unsigned      m_cur_scanline;
00535     };
00536 
00537 
00538     typedef scanline_storage_aa<int8u>  scanline_storage_aa8;  //--------scanline_storage_aa8
00539     typedef scanline_storage_aa<int16u> scanline_storage_aa16; //--------scanline_storage_aa16
00540     typedef scanline_storage_aa<int32u> scanline_storage_aa32; //--------scanline_storage_aa32
00541 
00542 
00543 
00544 
00545     //------------------------------------------serialized_scanlines_adaptor_aa
00546     template<class T> class serialized_scanlines_adaptor_aa
00547     {
00548     public:
00549         typedef T cover_type;
00550 
00551         //---------------------------------------------------------------------
00552         class embedded_scanline
00553         {
00554         public:
00555             typedef T cover_type;
00556 
00557             //-----------------------------------------------------------------
00558             class const_iterator
00559             {
00560             public:
00561                 struct span
00562                 {
00563                     int32    x;
00564                     int32    len; // If negative, it's a solid span, "covers" is valid
00565                     const T* covers; 
00566                 };
00567 
00568                 const_iterator() : m_ptr(0) {}
00569                 const_iterator(const embedded_scanline& sl) :
00570                     m_ptr(sl.m_ptr),
00571                     m_dx(sl.m_dx)
00572                 {
00573                     init_span();
00574                 }
00575 
00576                 const span& operator*()  const { return m_span;  }
00577                 const span* operator->() const { return &m_span; }
00578 
00579                 void operator ++ ()
00580                 {
00581                     if(m_span.len < 0) 
00582                     {
00583                         m_ptr += sizeof(T);
00584                     }
00585                     else 
00586                     {
00587                         m_ptr += m_span.len * sizeof(T);
00588                     }
00589                     init_span();
00590                 }
00591 
00592             private:
00593                 int read_int32()
00594                 {
00595                     int32 val;
00596                     ((int8u*)&val)[0] = *m_ptr++;
00597                     ((int8u*)&val)[1] = *m_ptr++;
00598                     ((int8u*)&val)[2] = *m_ptr++;
00599                     ((int8u*)&val)[3] = *m_ptr++;
00600                     return val;
00601                 }
00602 
00603                 void init_span()
00604                 {
00605                     m_span.x      = read_int32() + m_dx;
00606                     m_span.len    = read_int32();
00607                     m_span.covers = m_ptr;
00608                 }
00609 
00610                 const int8u* m_ptr;
00611                 span         m_span;
00612                 int          m_dx;
00613             };
00614 
00615             friend class const_iterator;
00616 
00617 
00618             //-----------------------------------------------------------------
00619             embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {}
00620 
00621             //-----------------------------------------------------------------
00622             void     reset(int, int)     {}
00623             unsigned num_spans()   const { return m_num_spans;  }
00624             int      y()           const { return m_y;          }
00625             const_iterator begin() const { return const_iterator(*this); }
00626 
00627 
00628         private:
00629             //-----------------------------------------------------------------
00630             int read_int32()
00631             {
00632                 int32 val;
00633                 ((int8u*)&val)[0] = *m_ptr++;
00634                 ((int8u*)&val)[1] = *m_ptr++;
00635                 ((int8u*)&val)[2] = *m_ptr++;
00636                 ((int8u*)&val)[3] = *m_ptr++;
00637                 return val;
00638             }
00639 
00640         public:
00641             //-----------------------------------------------------------------
00642             void init(const int8u* ptr, int dx, int dy)
00643             {
00644                 m_ptr       = ptr;
00645                 m_y         = read_int32() + dy;
00646                 m_num_spans = unsigned(read_int32());
00647                 m_dx        = dx;
00648             }
00649 
00650         private:
00651             const int8u* m_ptr;
00652             int          m_y;
00653             unsigned     m_num_spans;
00654             int          m_dx;
00655         };
00656 
00657 
00658 
00659     public:
00660         //--------------------------------------------------------------------
00661         serialized_scanlines_adaptor_aa() :
00662             m_data(0),
00663             m_end(0),
00664             m_ptr(0),
00665             m_dx(0),
00666             m_dy(0),
00667             m_min_x(0x7FFFFFFF),
00668             m_min_y(0x7FFFFFFF),
00669             m_max_x(-0x7FFFFFFF),
00670             m_max_y(-0x7FFFFFFF)
00671         {}
00672 
00673         //--------------------------------------------------------------------
00674         serialized_scanlines_adaptor_aa(const int8u* data, unsigned size,
00675                                         double dx, double dy) :
00676             m_data(data),
00677             m_end(data + size),
00678             m_ptr(data),
00679             m_dx(iround(dx)),
00680             m_dy(iround(dy)),
00681             m_min_x(0x7FFFFFFF),
00682             m_min_y(0x7FFFFFFF),
00683             m_max_x(-0x7FFFFFFF),
00684             m_max_y(-0x7FFFFFFF)
00685         {}
00686 
00687         //--------------------------------------------------------------------
00688         void init(const int8u* data, unsigned size, double dx, double dy)
00689         {
00690             m_data  = data;
00691             m_end   = data + size;
00692             m_ptr   = data;
00693             m_dx    = iround(dx);
00694             m_dy    = iround(dy);
00695             m_min_x = 0x7FFFFFFF;
00696             m_min_y = 0x7FFFFFFF;
00697             m_max_x = -0x7FFFFFFF;
00698             m_max_y = -0x7FFFFFFF;
00699         }
00700 
00701     private:
00702         //--------------------------------------------------------------------
00703         int read_int32()
00704         {
00705             int32 val;
00706             ((int8u*)&val)[0] = *m_ptr++;
00707             ((int8u*)&val)[1] = *m_ptr++;
00708             ((int8u*)&val)[2] = *m_ptr++;
00709             ((int8u*)&val)[3] = *m_ptr++;
00710             return val;
00711         }
00712 
00713         //--------------------------------------------------------------------
00714         unsigned read_int32u()
00715         {
00716             int32u val;
00717             ((int8u*)&val)[0] = *m_ptr++;
00718             ((int8u*)&val)[1] = *m_ptr++;
00719             ((int8u*)&val)[2] = *m_ptr++;
00720             ((int8u*)&val)[3] = *m_ptr++;
00721             return val;
00722         }
00723         
00724     public:
00725         // Iterate scanlines interface
00726         //--------------------------------------------------------------------
00727         bool rewind_scanlines()
00728         {
00729             m_ptr = m_data;
00730             if(m_ptr < m_end)
00731             {
00732                 m_min_x = read_int32() + m_dx; 
00733                 m_min_y = read_int32() + m_dy;
00734                 m_max_x = read_int32() + m_dx;
00735                 m_max_y = read_int32() + m_dy;
00736             }
00737             return m_ptr < m_end;
00738         }
00739 
00740         //--------------------------------------------------------------------
00741         int min_x() const { return m_min_x; }
00742         int min_y() const { return m_min_y; }
00743         int max_x() const { return m_max_x; }
00744         int max_y() const { return m_max_y; }
00745 
00746         //--------------------------------------------------------------------
00747         template<class Scanline> bool sweep_scanline(Scanline& sl)
00748         {
00749             sl.reset_spans();
00750             for(;;)
00751             {
00752                 if(m_ptr >= m_end) return false;
00753 
00754                 read_int32();      // Skip scanline size in bytes
00755                 int y = read_int32() + m_dy;
00756                 unsigned num_spans = read_int32();
00757 
00758                 do
00759                 {
00760                     int x = read_int32() + m_dx;
00761                     int len = read_int32();
00762 
00763                     if(len < 0)
00764                     {
00765                         sl.add_span(x, unsigned(-len), *m_ptr);
00766                         m_ptr += sizeof(T);
00767                     }
00768                     else
00769                     {
00770                         sl.add_cells(x, len, m_ptr);
00771                         m_ptr += len * sizeof(T);
00772                     }
00773                 }
00774                 while(--num_spans);
00775 
00776                 if(sl.num_spans())
00777                 {
00778                     sl.finalize(y);
00779                     break;
00780                 }
00781             }
00782             return true;
00783         }
00784 
00785 
00786         //--------------------------------------------------------------------
00787         // Specialization for embedded_scanline
00788         bool sweep_scanline(embedded_scanline& sl)
00789         {
00790             do
00791             {
00792                 if(m_ptr >= m_end) return false;
00793 
00794                 unsigned byte_size = read_int32u();
00795                 sl.init(m_ptr, m_dx, m_dy);
00796                 m_ptr += byte_size - sizeof(int32);
00797             }
00798             while(sl.num_spans() == 0);
00799             return true;
00800         }
00801 
00802     private:
00803         const int8u* m_data;
00804         const int8u* m_end;
00805         const int8u* m_ptr;
00806         int          m_dx;
00807         int          m_dy;
00808         int          m_min_x;
00809         int          m_min_y;
00810         int          m_max_x;
00811         int          m_max_y;
00812     };
00813 
00814 
00815 
00816     typedef serialized_scanlines_adaptor_aa<int8u>  serialized_scanlines_adaptor_aa8;  //----serialized_scanlines_adaptor_aa8
00817     typedef serialized_scanlines_adaptor_aa<int16u> serialized_scanlines_adaptor_aa16; //----serialized_scanlines_adaptor_aa16
00818     typedef serialized_scanlines_adaptor_aa<int32u> serialized_scanlines_adaptor_aa32; //----serialized_scanlines_adaptor_aa32
00819 
00820 }
00821 
00822 
00823 #endif
00824 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines