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_VCGEN_INCLUDED 17 #define AGG_CONV_ADAPTOR_VCGEN_INCLUDED 18 19 #include "agg_basics.h" 20 21 namespace agg 22 { 23 //------------------------------------------------------------null_markers 24 struct null_markers 25 { 26 void remove_all() {} 27 void add_vertex(double, double, unsigned) {} 28 void prepare_src() {} 29 30 void rewind(unsigned) {} 31 unsigned vertex(double*, double*) { return path_cmd_stop; } 32 }; 33 34 35 //------------------------------------------------------conv_adaptor_vcgen 36 template<class VertexSource, 37 class Generator, 38 class Markers=null_markers> class conv_adaptor_vcgen 39 { 40 enum status 41 { 42 initial, 43 accumulate, 44 generate 45 }; 46 47 public: 48 conv_adaptor_vcgen(VertexSource& source) : 49 m_source(&source), 50 m_status(initial) 51 {} 52 void attach(VertexSource& source) { m_source = &source; } 53 54 Generator& generator() { return m_generator; } 55 const Generator& generator() const { return m_generator; } 56 57 Markers& markers() { return m_markers; } 58 const Markers& markers() const { return m_markers; } 59 60 void rewind(unsigned path_id) 61 { 62 m_source->rewind(path_id); 63 m_status = initial; 64 } 65 66 unsigned vertex(double* x, double* y); 67 68 private: 69 // Prohibit copying 70 conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&); 71 const conv_adaptor_vcgen<VertexSource, Generator, Markers>& 72 operator = (const conv_adaptor_vcgen<VertexSource, Generator, Markers>&); 73 74 VertexSource* m_source; 75 Generator m_generator; 76 Markers m_markers; 77 status m_status; 78 unsigned m_last_cmd; 79 double m_start_x; 80 double m_start_y; 81 }; 82 83 84 85 86 87 //------------------------------------------------------------------------ 88 template<class VertexSource, class Generator, class Markers> 89 unsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(double* x, double* y) 90 { 91 unsigned cmd = path_cmd_stop; 92 bool done = false; 93 while(!done) 94 { 95 switch(m_status) 96 { 97 case initial: 98 m_markers.remove_all(); 99 m_last_cmd = m_source->vertex(&m_start_x, &m_start_y); 100 m_status = accumulate; 101 102 case accumulate: 103 if(is_stop(m_last_cmd)) return path_cmd_stop; 104 105 m_generator.remove_all(); 106 m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to); 107 m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to); 108 109 for(;;) 110 { 111 cmd = m_source->vertex(x, y); 112 if(is_vertex(cmd)) 113 { 114 m_last_cmd = cmd; 115 if(is_move_to(cmd)) 116 { 117 m_start_x = *x; 118 m_start_y = *y; 119 break; 120 } 121 m_generator.add_vertex(*x, *y, cmd); 122 m_markers.add_vertex(*x, *y, path_cmd_line_to); 123 } 124 else 125 { 126 if(is_stop(cmd)) 127 { 128 m_last_cmd = path_cmd_stop; 129 break; 130 } 131 if(is_end_poly(cmd)) 132 { 133 m_generator.add_vertex(*x, *y, cmd); 134 break; 135 } 136 } 137 } 138 m_generator.rewind(0); 139 m_status = generate; 140 141 case generate: 142 cmd = m_generator.vertex(x, y); 143 if(is_stop(cmd)) 144 { 145 m_status = accumulate; 146 break; 147 } 148 done = true; 149 break; 150 } 151 } 152 return cmd; 153 } 154 155 } 156 157 #endif 158