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 // conv_marker 17 // 18 //---------------------------------------------------------------------------- 19 #ifndef AGG_CONV_MARKER_INCLUDED 20 #define AGG_CONV_MARKER_INCLUDED 21 22 #include "agg_basics.h" 23 #include "agg_trans_affine.h" 24 25 namespace agg 26 { 27 //-------------------------------------------------------------conv_marker 28 template<class MarkerLocator, class MarkerShapes> 29 class conv_marker 30 { 31 public: 32 conv_marker(MarkerLocator& ml, MarkerShapes& ms); 33 transform()34 trans_affine& transform() { return m_transform; } transform()35 const trans_affine& transform() const { return m_transform; } 36 37 void rewind(unsigned path_id); 38 unsigned vertex(double* x, double* y); 39 40 private: 41 conv_marker(const conv_marker<MarkerLocator, MarkerShapes>&); 42 const conv_marker<MarkerLocator, MarkerShapes>& 43 operator = (const conv_marker<MarkerLocator, MarkerShapes>&); 44 45 enum status_e 46 { 47 initial, 48 markers, 49 polygon, 50 stop 51 }; 52 53 MarkerLocator* m_marker_locator; 54 MarkerShapes* m_marker_shapes; 55 trans_affine m_transform; 56 trans_affine m_mtx; 57 status_e m_status; 58 unsigned m_marker; 59 unsigned m_num_markers; 60 }; 61 62 63 //------------------------------------------------------------------------ 64 template<class MarkerLocator, class MarkerShapes> conv_marker(MarkerLocator & ml,MarkerShapes & ms)65 conv_marker<MarkerLocator, MarkerShapes>::conv_marker(MarkerLocator& ml, MarkerShapes& ms) : 66 m_marker_locator(&ml), 67 m_marker_shapes(&ms), 68 m_status(initial), 69 m_marker(0), 70 m_num_markers(1) 71 { 72 } 73 74 75 //------------------------------------------------------------------------ 76 template<class MarkerLocator, class MarkerShapes> rewind(unsigned)77 void conv_marker<MarkerLocator, MarkerShapes>::rewind(unsigned) 78 { 79 m_status = initial; 80 m_marker = 0; 81 m_num_markers = 1; 82 } 83 84 85 //------------------------------------------------------------------------ 86 template<class MarkerLocator, class MarkerShapes> vertex(double * x,double * y)87 unsigned conv_marker<MarkerLocator, MarkerShapes>::vertex(double* x, double* y) 88 { 89 unsigned cmd = path_cmd_move_to; 90 double x1, y1, x2, y2; 91 92 while(!is_stop(cmd)) 93 { 94 switch(m_status) 95 { 96 case initial: 97 if(m_num_markers == 0) 98 { 99 cmd = path_cmd_stop; 100 break; 101 } 102 m_marker_locator->rewind(m_marker); 103 ++m_marker; 104 m_num_markers = 0; 105 m_status = markers; 106 107 case markers: 108 if(is_stop(m_marker_locator->vertex(&x1, &y1))) 109 { 110 m_status = initial; 111 break; 112 } 113 if(is_stop(m_marker_locator->vertex(&x2, &y2))) 114 { 115 m_status = initial; 116 break; 117 } 118 ++m_num_markers; 119 m_mtx = m_transform; 120 m_mtx *= trans_affine_rotation(atan2(y2 - y1, x2 - x1)); 121 m_mtx *= trans_affine_translation(x1, y1); 122 m_marker_shapes->rewind(m_marker - 1); 123 m_status = polygon; 124 125 case polygon: 126 cmd = m_marker_shapes->vertex(x, y); 127 if(is_stop(cmd)) 128 { 129 cmd = path_cmd_move_to; 130 m_status = markers; 131 break; 132 } 133 m_mtx.transform(x, y); 134 return cmd; 135 136 case stop: 137 cmd = path_cmd_stop; 138 break; 139 } 140 } 141 return cmd; 142 } 143 144 } 145 146 147 #endif 148 149