Anti-Grain Geometry - AGG (libagg)
2.5
|
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