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 25namespace 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 34 trans_affine& transform() { return m_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> 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> 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> 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