Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_scanline_storage_bin.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 
00034 #ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED
00035 #define AGG_SCANLINE_STORAGE_BIN_INCLUDED
00036 
00037 #include <string.h>
00038 #include <stdlib.h>
00039 #include <math.h>
00040 #include "agg_array.h"
00041 
00042 
00043 namespace agg
00044 {
00045 
00046     //-----------------------------------------------scanline_storage_bin
00047     class scanline_storage_bin
00048     {
00049     public:
00050         //---------------------------------------------------------------
00051         struct span_data
00052         {
00053             int32 x;
00054             int32 len;
00055         };
00056 
00057         //---------------------------------------------------------------
00058         struct scanline_data
00059         {
00060             int      y;
00061             unsigned num_spans;
00062             unsigned start_span;
00063         };
00064 
00065 
00066         //---------------------------------------------------------------
00067         class embedded_scanline
00068         {
00069         public:
00070 
00071             //-----------------------------------------------------------
00072             class const_iterator
00073             {
00074             public:
00075                 const_iterator() : m_storage(0) {}
00076                 const_iterator(const embedded_scanline& sl) :
00077                     m_storage(sl.m_storage),
00078                     m_span_idx(sl.m_scanline.start_span)
00079                 {
00080                     m_span = m_storage->span_by_index(m_span_idx);
00081                 }
00082 
00083                 const span_data& operator*()  const { return m_span;  }
00084                 const span_data* operator->() const { return &m_span; }
00085 
00086                 void operator ++ ()
00087                 {
00088                     ++m_span_idx;
00089                     m_span = m_storage->span_by_index(m_span_idx);
00090                 }
00091 
00092             private:
00093                 const scanline_storage_bin* m_storage;
00094                 unsigned                    m_span_idx;
00095                 span_data                   m_span;
00096             };
00097 
00098             friend class const_iterator;
00099 
00100 
00101             //-----------------------------------------------------------
00102             embedded_scanline(const scanline_storage_bin& storage) :
00103                 m_storage(&storage)
00104             {
00105                 setup(0);
00106             }
00107 
00108             //-----------------------------------------------------------
00109             void     reset(int, int)     {}
00110             unsigned num_spans()   const { return m_scanline.num_spans;  }
00111             int      y()           const { return m_scanline.y;          }
00112             const_iterator begin() const { return const_iterator(*this); }
00113 
00114             //-----------------------------------------------------------
00115             void setup(unsigned scanline_idx)
00116             {
00117                 m_scanline_idx = scanline_idx;
00118                 m_scanline = m_storage->scanline_by_index(m_scanline_idx);
00119             }
00120 
00121         private:
00122             const scanline_storage_bin* m_storage;
00123             scanline_data               m_scanline;
00124             unsigned                    m_scanline_idx;
00125         };
00126 
00127 
00128         //---------------------------------------------------------------
00129         scanline_storage_bin() :
00130             m_spans(256-2),         // Block increment size
00131             m_scanlines(),
00132             m_min_x( 0x7FFFFFFF),
00133             m_min_y( 0x7FFFFFFF),
00134             m_max_x(-0x7FFFFFFF),
00135             m_max_y(-0x7FFFFFFF),
00136             m_cur_scanline(0)
00137         {
00138             m_fake_scanline.y = 0;
00139             m_fake_scanline.num_spans = 0;
00140             m_fake_scanline.start_span = 0;
00141             m_fake_span.x = 0;
00142             m_fake_span.len = 0;
00143         }
00144 
00145         // Renderer Interface
00146         //---------------------------------------------------------------
00147         void prepare()
00148         {
00149             m_scanlines.remove_all();
00150             m_spans.remove_all();
00151             m_min_x =  0x7FFFFFFF;
00152             m_min_y =  0x7FFFFFFF;
00153             m_max_x = -0x7FFFFFFF;
00154             m_max_y = -0x7FFFFFFF;
00155             m_cur_scanline = 0;
00156         }
00157 
00158         //---------------------------------------------------------------
00159         template<class Scanline> void render(const Scanline& sl)
00160         {
00161             scanline_data sl_this;
00162 
00163             int y = sl.y();
00164             if(y < m_min_y) m_min_y = y;
00165             if(y > m_max_y) m_max_y = y;
00166 
00167             sl_this.y = y;
00168             sl_this.num_spans = sl.num_spans();
00169             sl_this.start_span = m_spans.size();
00170             typename Scanline::const_iterator span_iterator = sl.begin();
00171 
00172             unsigned num_spans = sl_this.num_spans;
00173             for(;;)
00174             {
00175                 span_data sp;
00176                 sp.x   = span_iterator->x;
00177                 sp.len = (int32)abs((int)(span_iterator->len));
00178                 m_spans.add(sp);
00179                 int x1 = sp.x;
00180                 int x2 = sp.x + sp.len - 1;
00181                 if(x1 < m_min_x) m_min_x = x1;
00182                 if(x2 > m_max_x) m_max_x = x2;
00183                 if(--num_spans == 0) break;
00184                 ++span_iterator;
00185             }
00186             m_scanlines.add(sl_this);
00187         }
00188 
00189 
00190         //---------------------------------------------------------------
00191         // Iterate scanlines interface
00192         int min_x() const { return m_min_x; }
00193         int min_y() const { return m_min_y; }
00194         int max_x() const { return m_max_x; }
00195         int max_y() const { return m_max_y; }
00196 
00197         //---------------------------------------------------------------
00198         bool rewind_scanlines()
00199         {
00200             m_cur_scanline = 0;
00201             return m_scanlines.size() > 0;
00202         }
00203 
00204 
00205         //---------------------------------------------------------------
00206         template<class Scanline> bool sweep_scanline(Scanline& sl)
00207         {
00208             sl.reset_spans();
00209             for(;;)
00210             {
00211                 if(m_cur_scanline >= m_scanlines.size()) return false;
00212                 const scanline_data& sl_this = m_scanlines[m_cur_scanline];
00213 
00214                 unsigned num_spans = sl_this.num_spans;
00215                 unsigned span_idx  = sl_this.start_span;
00216                 do
00217                 {
00218                     const span_data& sp = m_spans[span_idx++];
00219                     sl.add_span(sp.x, sp.len, cover_full);
00220                 }
00221                 while(--num_spans);
00222 
00223                 ++m_cur_scanline;
00224                 if(sl.num_spans())
00225                 {
00226                     sl.finalize(sl_this.y);
00227                     break;
00228                 }
00229             }
00230             return true;
00231         }
00232 
00233 
00234         //---------------------------------------------------------------
00235         // Specialization for embedded_scanline
00236         bool sweep_scanline(embedded_scanline& sl)
00237         {
00238             do
00239             {
00240                 if(m_cur_scanline >= m_scanlines.size()) return false;
00241                 sl.setup(m_cur_scanline);
00242                 ++m_cur_scanline;
00243             }
00244             while(sl.num_spans() == 0);
00245             return true;
00246         }
00247 
00248 
00249         //---------------------------------------------------------------
00250         unsigned byte_size() const
00251         {
00252             unsigned i;
00253             unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
00254 
00255             for(i = 0; i < m_scanlines.size(); ++i)
00256             {
00257                 size += sizeof(int32) * 2 + // Y, num_spans
00258                         unsigned(m_scanlines[i].num_spans) * sizeof(int32) * 2; // X, span_len
00259             }
00260             return size;
00261         }
00262 
00263 
00264         //---------------------------------------------------------------
00265         static void write_int32(int8u* dst, int32 val)
00266         {
00267             dst[0] = ((const int8u*)&val)[0];
00268             dst[1] = ((const int8u*)&val)[1];
00269             dst[2] = ((const int8u*)&val)[2];
00270             dst[3] = ((const int8u*)&val)[3];
00271         }
00272 
00273 
00274         //---------------------------------------------------------------
00275         void serialize(int8u* data) const
00276         {
00277             unsigned i;
00278 
00279             write_int32(data, min_x()); // min_x
00280             data += sizeof(int32);
00281             write_int32(data, min_y()); // min_y
00282             data += sizeof(int32);
00283             write_int32(data, max_x()); // max_x
00284             data += sizeof(int32);
00285             write_int32(data, max_y()); // max_y
00286             data += sizeof(int32);
00287 
00288             for(i = 0; i < m_scanlines.size(); ++i)
00289             {
00290                 const scanline_data& sl_this = m_scanlines[i];
00291 
00292                 write_int32(data, sl_this.y);            // Y
00293                 data += sizeof(int32);
00294 
00295                 write_int32(data, sl_this.num_spans);    // num_spans
00296                 data += sizeof(int32);
00297 
00298                 unsigned num_spans = sl_this.num_spans;
00299                 unsigned span_idx  = sl_this.start_span;
00300                 do
00301                 {
00302                     const span_data& sp = m_spans[span_idx++];
00303 
00304                     write_int32(data, sp.x);             // X
00305                     data += sizeof(int32);
00306 
00307                     write_int32(data, sp.len);           // len
00308                     data += sizeof(int32);
00309                 }
00310                 while(--num_spans);
00311             }
00312         }
00313 
00314 
00315         //---------------------------------------------------------------
00316         const scanline_data& scanline_by_index(unsigned i) const
00317         {
00318             return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline;
00319         }
00320 
00321         //---------------------------------------------------------------
00322         const span_data& span_by_index(unsigned i) const
00323         {
00324             return (i < m_spans.size()) ? m_spans[i] : m_fake_span;
00325         }
00326 
00327 
00328     private:
00329         pod_bvector<span_data, 10>    m_spans;
00330         pod_bvector<scanline_data, 8> m_scanlines;
00331         span_data     m_fake_span;
00332         scanline_data m_fake_scanline;
00333         int           m_min_x;
00334         int           m_min_y;
00335         int           m_max_x;
00336         int           m_max_y;
00337         unsigned      m_cur_scanline;
00338     };
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352     //---------------------------------------serialized_scanlines_adaptor_bin
00353     class serialized_scanlines_adaptor_bin
00354     {
00355     public:
00356         typedef bool cover_type;
00357 
00358         //--------------------------------------------------------------------
00359         class embedded_scanline
00360         {
00361         public:
00362 
00363             //----------------------------------------------------------------
00364             class const_iterator
00365             {
00366             public:
00367                 struct span
00368                 {
00369                     int32 x;
00370                     int32 len;
00371                 };
00372 
00373                 const_iterator() : m_ptr(0) {}
00374                 const_iterator(const embedded_scanline& sl) :
00375                     m_ptr(sl.m_ptr),
00376                     m_dx(sl.m_dx)
00377                 {
00378                     m_span.x   = read_int32() + m_dx;
00379                     m_span.len = read_int32();
00380                 }
00381 
00382                 const span& operator*()  const { return m_span;  }
00383                 const span* operator->() const { return &m_span; }
00384 
00385                 void operator ++ ()
00386                 {
00387                     m_span.x   = read_int32() + m_dx;
00388                     m_span.len = read_int32();
00389                 }
00390 
00391             private:
00392                 int read_int32()
00393                 {
00394                     int32 val;
00395                     ((int8u*)&val)[0] = *m_ptr++;
00396                     ((int8u*)&val)[1] = *m_ptr++;
00397                     ((int8u*)&val)[2] = *m_ptr++;
00398                     ((int8u*)&val)[3] = *m_ptr++;
00399                     return val;
00400                 }
00401 
00402                 const int8u* m_ptr;
00403                 span         m_span;
00404                 int          m_dx;
00405             };
00406 
00407             friend class const_iterator;
00408 
00409 
00410             //----------------------------------------------------------------
00411             embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {}
00412 
00413             //----------------------------------------------------------------
00414             void     reset(int, int)     {}
00415             unsigned num_spans()   const { return m_num_spans;  }
00416             int      y()           const { return m_y;          }
00417             const_iterator begin() const { return const_iterator(*this); }
00418 
00419 
00420         private:
00421             //----------------------------------------------------------------
00422             int read_int32()
00423             {
00424                 int32 val;
00425                 ((int8u*)&val)[0] = *m_ptr++;
00426                 ((int8u*)&val)[1] = *m_ptr++;
00427                 ((int8u*)&val)[2] = *m_ptr++;
00428                 ((int8u*)&val)[3] = *m_ptr++;
00429                 return val;
00430             }
00431 
00432         public:
00433             //----------------------------------------------------------------
00434             void init(const int8u* ptr, int dx, int dy)
00435             {
00436                 m_ptr       = ptr;
00437                 m_y         = read_int32() + dy;
00438                 m_num_spans = unsigned(read_int32());
00439                 m_dx        = dx;
00440             }
00441 
00442         private:
00443             const int8u* m_ptr;
00444             int          m_y;
00445             unsigned     m_num_spans;
00446             int          m_dx;
00447         };
00448 
00449 
00450 
00451     public:
00452         //--------------------------------------------------------------------
00453         serialized_scanlines_adaptor_bin() :
00454             m_data(0),
00455             m_end(0),
00456             m_ptr(0),
00457             m_dx(0),
00458             m_dy(0),
00459             m_min_x(0x7FFFFFFF),
00460             m_min_y(0x7FFFFFFF),
00461             m_max_x(-0x7FFFFFFF),
00462             m_max_y(-0x7FFFFFFF)
00463         {}
00464 
00465         //--------------------------------------------------------------------
00466         serialized_scanlines_adaptor_bin(const int8u* data, unsigned size,
00467                                          double dx, double dy) :
00468             m_data(data),
00469             m_end(data + size),
00470             m_ptr(data),
00471             m_dx(iround(dx)),
00472             m_dy(iround(dy)),
00473             m_min_x(0x7FFFFFFF),
00474             m_min_y(0x7FFFFFFF),
00475             m_max_x(-0x7FFFFFFF),
00476             m_max_y(-0x7FFFFFFF)
00477         {}
00478 
00479         //--------------------------------------------------------------------
00480         void init(const int8u* data, unsigned size, double dx, double dy)
00481         {
00482             m_data  = data;
00483             m_end   = data + size;
00484             m_ptr   = data;
00485             m_dx    = iround(dx);
00486             m_dy    = iround(dy);
00487             m_min_x = 0x7FFFFFFF;
00488             m_min_y = 0x7FFFFFFF;
00489             m_max_x = -0x7FFFFFFF;
00490             m_max_y = -0x7FFFFFFF;
00491         }
00492 
00493     private:
00494         //--------------------------------------------------------------------
00495         int read_int32()
00496         {
00497             int32 val;
00498             ((int8u*)&val)[0] = *m_ptr++;
00499             ((int8u*)&val)[1] = *m_ptr++;
00500             ((int8u*)&val)[2] = *m_ptr++;
00501             ((int8u*)&val)[3] = *m_ptr++;
00502             return val;
00503         }
00504        
00505     public:
00506         // Iterate scanlines interface
00507         //--------------------------------------------------------------------
00508         bool rewind_scanlines()
00509         {
00510             m_ptr = m_data;
00511             if(m_ptr < m_end)
00512             {
00513                 m_min_x = read_int32() + m_dx; 
00514                 m_min_y = read_int32() + m_dy;
00515                 m_max_x = read_int32() + m_dx;
00516                 m_max_y = read_int32() + m_dy;
00517             }
00518             return m_ptr < m_end;
00519         }
00520 
00521         //--------------------------------------------------------------------
00522         int min_x() const { return m_min_x; }
00523         int min_y() const { return m_min_y; }
00524         int max_x() const { return m_max_x; }
00525         int max_y() const { return m_max_y; }
00526 
00527         //--------------------------------------------------------------------
00528         template<class Scanline> bool sweep_scanline(Scanline& sl)
00529         {
00530             sl.reset_spans();
00531             for(;;)
00532             {
00533                 if(m_ptr >= m_end) return false;
00534 
00535                 int y = read_int32() + m_dy;
00536                 unsigned num_spans = read_int32();
00537 
00538                 do
00539                 {
00540                     int x = read_int32() + m_dx;
00541                     int len = read_int32();
00542 
00543                     if(len < 0) len = -len;
00544                     sl.add_span(x, unsigned(len), cover_full);
00545                 }
00546                 while(--num_spans);
00547 
00548                 if(sl.num_spans())
00549                 {
00550                     sl.finalize(y);
00551                     break;
00552                 }
00553             }
00554             return true;
00555         }
00556 
00557 
00558         //--------------------------------------------------------------------
00559         // Specialization for embedded_scanline
00560         bool sweep_scanline(embedded_scanline& sl)
00561         {
00562             do
00563             {
00564                 if(m_ptr >= m_end) return false;
00565 
00566                 sl.init(m_ptr, m_dx, m_dy);
00567 
00568                 // Jump to the next scanline
00569                 //--------------------------
00570                 read_int32();                    // Y
00571                 int num_spans = read_int32();    // num_spans
00572                 m_ptr += num_spans * sizeof(int32) * 2;
00573             }
00574             while(sl.num_spans() == 0);
00575             return true;
00576         }
00577 
00578     private:
00579         const int8u* m_data;
00580         const int8u* m_end;
00581         const int8u* m_ptr;
00582         int          m_dx;
00583         int          m_dy;
00584         int          m_min_x;
00585         int          m_min_y;
00586         int          m_max_x;
00587         int          m_max_y;
00588     };
00589 
00590 
00591 
00592 }
00593 
00594 #endif
00595 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines