Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_conv_adaptor_vcgen.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_CONV_ADAPTOR_VCGEN_INCLUDED
00026 #define AGG_CONV_ADAPTOR_VCGEN_INCLUDED
00027 
00028 #include "agg_basics.h"
00029 
00030 namespace agg
00031 {
00032     //------------------------------------------------------------null_markers
00033     struct null_markers
00034     {
00035         void remove_all() {}
00036         void add_vertex(double, double, unsigned) {}
00037         void prepare_src() {}
00038 
00039         void rewind(unsigned) {}
00040         unsigned vertex(double*, double*) { return path_cmd_stop; }
00041     };
00042 
00043 
00044     //------------------------------------------------------conv_adaptor_vcgen
00045     template<class VertexSource, 
00046              class Generator, 
00047              class Markers=null_markers> class conv_adaptor_vcgen
00048     {
00049         enum status
00050         {
00051             initial,
00052             accumulate,
00053             generate
00054         };
00055 
00056     public:
00057         explicit conv_adaptor_vcgen(VertexSource& source) :
00058             m_source(&source), 
00059             m_status(initial)
00060         {}
00061         void attach(VertexSource& source) { m_source = &source; }
00062 
00063         Generator& generator() { return m_generator; }
00064         const Generator& generator() const { return m_generator; }
00065 
00066         Markers& markers() { return m_markers; }
00067         const Markers& markers() const { return m_markers; }
00068         
00069         void rewind(unsigned path_id) 
00070         { 
00071             m_source->rewind(path_id); 
00072             m_status = initial;
00073         }
00074 
00075         unsigned vertex(double* x, double* y);
00076 
00077     private:
00078         // Prohibit copying
00079         conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
00080         const conv_adaptor_vcgen<VertexSource, Generator, Markers>& 
00081             operator = (const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
00082 
00083         VertexSource* m_source;
00084         Generator     m_generator;
00085         Markers       m_markers;
00086         status        m_status;
00087         unsigned      m_last_cmd;
00088         double        m_start_x;
00089         double        m_start_y;
00090     };
00091 
00092 
00093 
00094 
00095 
00096     //------------------------------------------------------------------------
00097     template<class VertexSource, class Generator, class Markers> 
00098     unsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(double* x, double* y)
00099     {
00100         unsigned cmd = path_cmd_stop;
00101         bool done = false;
00102         while(!done)
00103         {
00104             switch(m_status)
00105             {
00106             case initial:
00107                 m_markers.remove_all();
00108                 m_last_cmd = m_source->vertex(&m_start_x, &m_start_y);
00109                 m_status = accumulate;
00110 
00111             case accumulate:
00112                 if(is_stop(m_last_cmd)) return path_cmd_stop;
00113 
00114                 m_generator.remove_all();
00115                 m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
00116                 m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to);
00117 
00118                 for(;;)
00119                 {
00120                     cmd = m_source->vertex(x, y);
00121                     if(is_vertex(cmd))
00122                     {
00123                         m_last_cmd = cmd;
00124                         if(is_move_to(cmd))
00125                         {
00126                             m_start_x = *x;
00127                             m_start_y = *y;
00128                             break;
00129                         }
00130                         m_generator.add_vertex(*x, *y, cmd);
00131                         m_markers.add_vertex(*x, *y, path_cmd_line_to);
00132                     }
00133                     else
00134                     {
00135                         if(is_stop(cmd))
00136                         {
00137                             m_last_cmd = path_cmd_stop;
00138                             break;
00139                         }
00140                         if(is_end_poly(cmd))
00141                         {
00142                             m_generator.add_vertex(*x, *y, cmd);
00143                             break;
00144                         }
00145                     }
00146                 }
00147                 m_generator.rewind(0);
00148                 m_status = generate;
00149 
00150             case generate:
00151                 cmd = m_generator.vertex(x, y);
00152                 if(is_stop(cmd))
00153                 {
00154                     m_status = accumulate;
00155                     break;
00156                 }
00157                 done = true;
00158                 break;
00159             }
00160         }
00161         return cmd;
00162     }
00163 
00164 }
00165 
00166 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines