1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.2 3 // Copyright (C) 2002-2004 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_CLOSE_POLYGON_INCLUDED 17 #define AGG_CONV_CLOSE_POLYGON_INCLUDED 18 19 #include "agg_basics.h" 20 #include "agg_vertex_iterator.h" 21 22 namespace agg 23 { 24 25 //======================================================conv_close_polygon 26 template<class VertexSource> class conv_close_polygon 27 { 28 public: 29 conv_close_polygon(VertexSource& vs) : m_source(&vs) {} 30 31 void set_source(VertexSource& source) { m_source = &source; } 32 33 void rewind(unsigned path_id); 34 unsigned vertex(double* x, double* y); 35 36 typedef conv_close_polygon<VertexSource> source_type; 37 typedef vertex_iterator<source_type> iterator; 38 iterator begin(unsigned id) { return iterator(*this, id); } 39 iterator end() { return iterator(path_cmd_stop); } 40 41 private: 42 conv_close_polygon(const conv_close_polygon<VertexSource>&); 43 const conv_close_polygon<VertexSource>& 44 operator = (const conv_close_polygon<VertexSource>&); 45 46 VertexSource* m_source; 47 unsigned m_cmd[2]; 48 double m_x[2]; 49 double m_y[2]; 50 unsigned m_vertex; 51 bool m_line_to; 52 }; 53 54 55 56 //------------------------------------------------------------------------ 57 template<class VertexSource> 58 void conv_close_polygon<VertexSource>::rewind(unsigned path_id) 59 { 60 m_source->rewind(path_id); 61 m_vertex = 2; 62 m_line_to = false; 63 } 64 65 66 67 //------------------------------------------------------------------------ 68 template<class VertexSource> 69 unsigned conv_close_polygon<VertexSource>::vertex(double* x, double* y) 70 { 71 unsigned cmd = path_cmd_stop; 72 for(;;) 73 { 74 if(m_vertex < 2) 75 { 76 *x = m_x[m_vertex]; 77 *y = m_y[m_vertex]; 78 cmd = m_cmd[m_vertex]; 79 ++m_vertex; 80 break; 81 } 82 83 cmd = m_source->vertex(x, y); 84 85 if(is_end_poly(cmd)) 86 { 87 cmd |= path_flags_close; 88 break; 89 } 90 91 if(is_stop(cmd)) 92 { 93 if(m_line_to) 94 { 95 m_cmd[0] = path_cmd_end_poly | path_flags_close; 96 m_cmd[1] = path_cmd_stop; 97 m_vertex = 0; 98 m_line_to = false; 99 continue; 100 } 101 break; 102 } 103 104 if(is_move_to(cmd)) 105 { 106 if(m_line_to) 107 { 108 m_x[0] = 0.0; 109 m_y[0] = 0.0; 110 m_cmd[0] = path_cmd_end_poly | path_flags_close; 111 m_x[1] = *x; 112 m_y[1] = *y; 113 m_cmd[1] = cmd; 114 m_vertex = 0; 115 m_line_to = false; 116 continue; 117 } 118 break; 119 } 120 121 if(is_vertex(cmd)) 122 { 123 m_line_to = true; 124 break; 125 } 126 } 127 return cmd; 128 } 129 130 } 131 132 #endif 133