1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.4 3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 4 // 5 // Permission to copy, use, modify, sell and distribute this software 6 // is granted provided this copyright notice appears in all copies. 7 // This software is provided "as is" without express or implied 8 // warranty, and with no claim as to its suitability for any purpose. 9 // 10 //---------------------------------------------------------------------------- 11 // Contact: mcseem@antigrain.com 12 // mcseemagg@yahoo.com 13 // http://www.antigrain.com 14 //---------------------------------------------------------------------------- 15 16 #ifndef AGG_CONV_ADAPTOR_VPGEN_INCLUDED 17 #define AGG_CONV_ADAPTOR_VPGEN_INCLUDED 18 19 #include "agg_basics.h" 20 21 namespace agg 22 { 23 24 //======================================================conv_adaptor_vpgen 25 template<class VertexSource, class VPGen> class conv_adaptor_vpgen 26 { 27 public: 28 conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {} 29 void attach(VertexSource& source) { m_source = &source; } 30 31 VPGen& vpgen() { return m_vpgen; } 32 const VPGen& vpgen() const { return m_vpgen; } 33 34 void rewind(unsigned path_id); 35 unsigned vertex(double* x, double* y); 36 37 private: 38 conv_adaptor_vpgen(const conv_adaptor_vpgen<VertexSource, VPGen>&); 39 const conv_adaptor_vpgen<VertexSource, VPGen>& 40 operator = (const conv_adaptor_vpgen<VertexSource, VPGen>&); 41 42 VertexSource* m_source; 43 VPGen m_vpgen; 44 double m_start_x; 45 double m_start_y; 46 unsigned m_poly_flags; 47 int m_vertices; 48 }; 49 50 51 52 //------------------------------------------------------------------------ 53 template<class VertexSource, class VPGen> 54 void conv_adaptor_vpgen<VertexSource, VPGen>::rewind(unsigned path_id) 55 { 56 m_source->rewind(path_id); 57 m_vpgen.reset(); 58 m_start_x = 0; 59 m_start_y = 0; 60 m_poly_flags = 0; 61 m_vertices = 0; 62 } 63 64 65 //------------------------------------------------------------------------ 66 template<class VertexSource, class VPGen> 67 unsigned conv_adaptor_vpgen<VertexSource, VPGen>::vertex(double* x, double* y) 68 { 69 unsigned cmd = path_cmd_stop; 70 for(;;) 71 { 72 cmd = m_vpgen.vertex(x, y); 73 if(!is_stop(cmd)) break; 74 75 if(m_poly_flags && !m_vpgen.auto_unclose()) 76 { 77 *x = 0.0; 78 *y = 0.0; 79 cmd = m_poly_flags; 80 m_poly_flags = 0; 81 break; 82 } 83 84 if(m_vertices < 0) 85 { 86 if(m_vertices < -1) 87 { 88 m_vertices = 0; 89 return path_cmd_stop; 90 } 91 m_vpgen.move_to(m_start_x, m_start_y); 92 m_vertices = 1; 93 continue; 94 } 95 96 double tx, ty; 97 cmd = m_source->vertex(&tx, &ty); 98 if(is_vertex(cmd)) 99 { 100 if(is_move_to(cmd)) 101 { 102 if(m_vpgen.auto_close() && m_vertices > 2) 103 { 104 m_vpgen.line_to(m_start_x, m_start_y); 105 m_poly_flags = path_cmd_end_poly | path_flags_close; 106 m_start_x = tx; 107 m_start_y = ty; 108 m_vertices = -1; 109 continue; 110 } 111 m_vpgen.move_to(tx, ty); 112 m_start_x = tx; 113 m_start_y = ty; 114 m_vertices = 1; 115 } 116 else 117 { 118 m_vpgen.line_to(tx, ty); 119 ++m_vertices; 120 } 121 } 122 else 123 { 124 if(is_end_poly(cmd)) 125 { 126 m_poly_flags = cmd; 127 if(is_closed(cmd) || m_vpgen.auto_close()) 128 { 129 if(m_vpgen.auto_close()) m_poly_flags |= path_flags_close; 130 if(m_vertices > 2) 131 { 132 m_vpgen.line_to(m_start_x, m_start_y); 133 } 134 m_vertices = 0; 135 } 136 } 137 else 138 { 139 // path_cmd_stop 140 if(m_vpgen.auto_close() && m_vertices > 2) 141 { 142 m_vpgen.line_to(m_start_x, m_start_y); 143 m_poly_flags = path_cmd_end_poly | path_flags_close; 144 m_vertices = -2; 145 continue; 146 } 147 break; 148 } 149 } 150 } 151 return cmd; 152 } 153 154 155 } 156 157 158 #endif 159 160