Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_path_storage_integer.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 #ifndef AGG_PATH_STORAGE_INTEGER_INCLUDED
00026 #define AGG_PATH_STORAGE_INTEGER_INCLUDED
00027 
00028 #include <string.h>
00029 #include "agg_array.h"
00030 
00031 namespace agg
00032 {
00033     //---------------------------------------------------------vertex_integer
00034     template<class T, unsigned CoordShift=6> struct vertex_integer
00035     {
00036         enum path_cmd
00037         {
00038             cmd_move_to = 0,
00039             cmd_line_to = 1,
00040             cmd_curve3  = 2,
00041             cmd_curve4  = 3
00042         };
00043 
00044         enum coord_scale_e
00045         {
00046             coord_shift = CoordShift,
00047             coord_scale  = 1 << coord_shift
00048         };
00049 
00050         T x,y;
00051         vertex_integer() {}
00052         vertex_integer(T x_, T y_, unsigned flag) :
00053             x(((x_ << 1) & ~1) | (flag &  1)),
00054             y(((y_ << 1) & ~1) | (flag >> 1)) {}
00055 
00056         unsigned vertex(double* x_, double* y_, 
00057                         double dx=0, double dy=0,
00058                         double scale=1.0) const
00059         {
00060             *x_ = dx + (double(x >> 1) / coord_scale) * scale;
00061             *y_ = dy + (double(y >> 1) / coord_scale) * scale;
00062             switch(((y & 1) << 1) | (x & 1))
00063             {
00064                 case cmd_move_to: return path_cmd_move_to;
00065                 case cmd_line_to: return path_cmd_line_to;
00066                 case cmd_curve3:  return path_cmd_curve3;
00067                 case cmd_curve4:  return path_cmd_curve4;
00068             }
00069             return path_cmd_stop;
00070         }
00071     };
00072 
00073 
00074     //---------------------------------------------------path_storage_integer
00075     template<class T, unsigned CoordShift=6> class path_storage_integer
00076     {
00077     public:
00078         typedef T value_type;
00079         typedef vertex_integer<T, CoordShift> vertex_integer_type;
00080 
00081         //--------------------------------------------------------------------
00082         path_storage_integer() : m_storage(), m_vertex_idx(0), m_closed(true) {}
00083 
00084         //--------------------------------------------------------------------
00085         void remove_all() { m_storage.remove_all(); }
00086 
00087         //--------------------------------------------------------------------
00088         void move_to(T x, T y)
00089         {
00090             m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_move_to));
00091         }
00092 
00093         //--------------------------------------------------------------------
00094         void line_to(T x, T y)
00095         {
00096             m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_line_to));
00097         }
00098 
00099         //--------------------------------------------------------------------
00100         void curve3(T x_ctrl,  T y_ctrl, 
00101                     T x_to,    T y_to)
00102         {
00103             m_storage.add(vertex_integer_type(x_ctrl, y_ctrl, vertex_integer_type::cmd_curve3));
00104             m_storage.add(vertex_integer_type(x_to,   y_to,   vertex_integer_type::cmd_curve3));
00105         }
00106 
00107         //--------------------------------------------------------------------
00108         void curve4(T x_ctrl1, T y_ctrl1, 
00109                     T x_ctrl2, T y_ctrl2, 
00110                     T x_to,    T y_to)
00111         {
00112             m_storage.add(vertex_integer_type(x_ctrl1, y_ctrl1, vertex_integer_type::cmd_curve4));
00113             m_storage.add(vertex_integer_type(x_ctrl2, y_ctrl2, vertex_integer_type::cmd_curve4));
00114             m_storage.add(vertex_integer_type(x_to,    y_to,    vertex_integer_type::cmd_curve4));
00115         }
00116 
00117         //--------------------------------------------------------------------
00118         void close_polygon() {}
00119 
00120         //--------------------------------------------------------------------
00121         unsigned size() const { return m_storage.size(); }
00122         unsigned vertex(unsigned idx, double* x, double* y) const
00123         {
00124             return m_storage[idx].vertex(x, y);
00125         }
00126 
00127         //--------------------------------------------------------------------
00128         unsigned byte_size() const { return m_storage.size() * sizeof(vertex_integer_type); }
00129         void serialize(int8u* ptr) const
00130         {
00131             unsigned i;
00132             for(i = 0; i < m_storage.size(); i++)
00133             {
00134                 memcpy(ptr, &m_storage[i], sizeof(vertex_integer_type));
00135                 ptr += sizeof(vertex_integer_type);
00136             }
00137         }
00138 
00139         //--------------------------------------------------------------------
00140         void rewind(unsigned) 
00141         { 
00142             m_vertex_idx = 0; 
00143             m_closed = true;
00144         }
00145 
00146         //--------------------------------------------------------------------
00147         unsigned vertex(double* x, double* y)
00148         {
00149             if(m_storage.size() < 2 || m_vertex_idx > m_storage.size()) 
00150             {
00151                 *x = 0;
00152                 *y = 0;
00153                 return path_cmd_stop;
00154             }
00155             if(m_vertex_idx == m_storage.size())
00156             {
00157                 *x = 0;
00158                 *y = 0;
00159                 ++m_vertex_idx;
00160                 return path_cmd_end_poly | path_flags_close;
00161             }
00162             unsigned cmd = m_storage[m_vertex_idx].vertex(x, y);
00163             if(is_move_to(cmd) && !m_closed)
00164             {
00165                 *x = 0;
00166                 *y = 0;
00167                 m_closed = true;
00168                 return path_cmd_end_poly | path_flags_close;
00169             }
00170             m_closed = false;
00171             ++m_vertex_idx;
00172             return cmd;
00173         }
00174 
00175         //--------------------------------------------------------------------
00176         rect_d bounding_rect() const
00177         {
00178             rect_d bounds(1e100, 1e100, -1e100, -1e100);
00179             if(m_storage.size() == 0)
00180             {
00181                 bounds.x1 = bounds.y1 = bounds.x2 = bounds.y2 = 0.0;
00182             }
00183             else
00184             {
00185                 unsigned i;
00186                 for(i = 0; i < m_storage.size(); i++)
00187                 {
00188                     double x, y;
00189                     m_storage[i].vertex(&x, &y);
00190                     if(x < bounds.x1) bounds.x1 = x;
00191                     if(y < bounds.y1) bounds.y1 = y;
00192                     if(x > bounds.x2) bounds.x2 = x;
00193                     if(y > bounds.y2) bounds.y2 = y;
00194                 }
00195             }
00196             return bounds;
00197         }
00198 
00199     private:
00200         pod_bvector<vertex_integer_type, 6> m_storage;
00201         unsigned                            m_vertex_idx;
00202         bool                                m_closed;
00203     };
00204 
00205 
00206 
00207 
00208     //-----------------------------------------serialized_integer_path_adaptor
00209     template<class T, unsigned CoordShift=6> class serialized_integer_path_adaptor
00210     {
00211     public:
00212         typedef vertex_integer<T, CoordShift> vertex_integer_type;
00213 
00214         //--------------------------------------------------------------------
00215         serialized_integer_path_adaptor() :
00216             m_data(0),
00217             m_end(0),
00218             m_ptr(0),
00219             m_dx(0.0),
00220             m_dy(0.0),
00221             m_scale(1.0),
00222             m_vertices(0)
00223         {}
00224 
00225         //--------------------------------------------------------------------
00226         serialized_integer_path_adaptor(const int8u* data, unsigned size,
00227                                         double dx, double dy) :
00228             m_data(data),
00229             m_end(data + size),
00230             m_ptr(data),
00231             m_dx(dx),
00232             m_dy(dy),
00233             m_vertices(0)
00234         {}
00235 
00236         //--------------------------------------------------------------------
00237         void init(const int8u* data, unsigned size, 
00238                   double dx, double dy, double scale=1.0)
00239         {
00240             m_data     = data;
00241             m_end      = data + size;
00242             m_ptr      = data;
00243             m_dx       = dx;
00244             m_dy       = dy;
00245             m_scale    = scale;
00246             m_vertices = 0;
00247         }
00248 
00249 
00250         //--------------------------------------------------------------------
00251         void rewind(unsigned) 
00252         { 
00253             m_ptr      = m_data; 
00254             m_vertices = 0;
00255         }
00256 
00257         //--------------------------------------------------------------------
00258         unsigned vertex(double* x, double* y)
00259         {
00260             if(m_data == 0 || m_ptr > m_end) 
00261             {
00262                 *x = 0;
00263                 *y = 0;
00264                 return path_cmd_stop;
00265             }
00266 
00267             if(m_ptr == m_end)
00268             {
00269                 *x = 0;
00270                 *y = 0;
00271                 m_ptr += sizeof(vertex_integer_type);
00272                 return path_cmd_end_poly | path_flags_close;
00273             }
00274 
00275             vertex_integer_type v;
00276             memcpy(&v, m_ptr, sizeof(vertex_integer_type));
00277             unsigned cmd = v.vertex(x, y, m_dx, m_dy, m_scale);
00278             if(is_move_to(cmd) && m_vertices > 2)
00279             {
00280                 *x = 0;
00281                 *y = 0;
00282                 m_vertices = 0;
00283                 return path_cmd_end_poly | path_flags_close;
00284             }
00285             ++m_vertices;
00286             m_ptr += sizeof(vertex_integer_type);
00287             return cmd;
00288         }
00289 
00290     private:
00291         const int8u* m_data;
00292         const int8u* m_end;
00293         const int8u* m_ptr;
00294         double       m_dx;
00295         double       m_dy;
00296         double       m_scale;
00297         unsigned     m_vertices;
00298     };
00299 
00300 }
00301 
00302 
00303 #endif
00304 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines