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_VPGEN_INCLUDED 00026 #define AGG_CONV_ADAPTOR_VPGEN_INCLUDED 00027 00028 #include "agg_basics.h" 00029 00030 namespace agg 00031 { 00032 00033 //======================================================conv_adaptor_vpgen 00034 template<class VertexSource, class VPGen> class conv_adaptor_vpgen 00035 { 00036 public: 00037 explicit conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {} 00038 void attach(VertexSource& source) { m_source = &source; } 00039 00040 VPGen& vpgen() { return m_vpgen; } 00041 const VPGen& vpgen() const { return m_vpgen; } 00042 00043 void rewind(unsigned path_id); 00044 unsigned vertex(double* x, double* y); 00045 00046 private: 00047 conv_adaptor_vpgen(const conv_adaptor_vpgen<VertexSource, VPGen>&); 00048 const conv_adaptor_vpgen<VertexSource, VPGen>& 00049 operator = (const conv_adaptor_vpgen<VertexSource, VPGen>&); 00050 00051 VertexSource* m_source; 00052 VPGen m_vpgen; 00053 double m_start_x; 00054 double m_start_y; 00055 unsigned m_poly_flags; 00056 int m_vertices; 00057 }; 00058 00059 00060 00061 //------------------------------------------------------------------------ 00062 template<class VertexSource, class VPGen> 00063 void conv_adaptor_vpgen<VertexSource, VPGen>::rewind(unsigned path_id) 00064 { 00065 m_source->rewind(path_id); 00066 m_vpgen.reset(); 00067 m_start_x = 0; 00068 m_start_y = 0; 00069 m_poly_flags = 0; 00070 m_vertices = 0; 00071 } 00072 00073 00074 //------------------------------------------------------------------------ 00075 template<class VertexSource, class VPGen> 00076 unsigned conv_adaptor_vpgen<VertexSource, VPGen>::vertex(double* x, double* y) 00077 { 00078 unsigned cmd = path_cmd_stop; 00079 for(;;) 00080 { 00081 cmd = m_vpgen.vertex(x, y); 00082 if(!is_stop(cmd)) break; 00083 00084 if(m_poly_flags && !m_vpgen.auto_unclose()) 00085 { 00086 *x = 0.0; 00087 *y = 0.0; 00088 cmd = m_poly_flags; 00089 m_poly_flags = 0; 00090 break; 00091 } 00092 00093 if(m_vertices < 0) 00094 { 00095 if(m_vertices < -1) 00096 { 00097 m_vertices = 0; 00098 return path_cmd_stop; 00099 } 00100 m_vpgen.move_to(m_start_x, m_start_y); 00101 m_vertices = 1; 00102 continue; 00103 } 00104 00105 double tx, ty; 00106 cmd = m_source->vertex(&tx, &ty); 00107 if(is_vertex(cmd)) 00108 { 00109 if(is_move_to(cmd)) 00110 { 00111 if(m_vpgen.auto_close() && m_vertices > 2) 00112 { 00113 m_vpgen.line_to(m_start_x, m_start_y); 00114 m_poly_flags = path_cmd_end_poly | path_flags_close; 00115 m_start_x = tx; 00116 m_start_y = ty; 00117 m_vertices = -1; 00118 continue; 00119 } 00120 m_vpgen.move_to(tx, ty); 00121 m_start_x = tx; 00122 m_start_y = ty; 00123 m_vertices = 1; 00124 } 00125 else 00126 { 00127 m_vpgen.line_to(tx, ty); 00128 ++m_vertices; 00129 } 00130 } 00131 else 00132 { 00133 if(is_end_poly(cmd)) 00134 { 00135 m_poly_flags = cmd; 00136 if(is_closed(cmd) || m_vpgen.auto_close()) 00137 { 00138 if(m_vpgen.auto_close()) m_poly_flags |= path_flags_close; 00139 if(m_vertices > 2) 00140 { 00141 m_vpgen.line_to(m_start_x, m_start_y); 00142 } 00143 m_vertices = 0; 00144 } 00145 } 00146 else 00147 { 00148 // path_cmd_stop 00149 if(m_vpgen.auto_close() && m_vertices > 2) 00150 { 00151 m_vpgen.line_to(m_start_x, m_start_y); 00152 m_poly_flags = path_cmd_end_poly | path_flags_close; 00153 m_vertices = -2; 00154 continue; 00155 } 00156 break; 00157 } 00158 } 00159 } 00160 return cmd; 00161 } 00162 00163 00164 } 00165 00166 00167 #endif 00168