Anti-Grain Geometry - AGG (libagg)
2.5
|
00001 //---------------------------------------------------------------------------- 00002 // Anti-Grain Geometry (AGG) - Version 2.5 00003 // A high quality rendering engine for C++ 00004 // Copyright (C) 2002-2006 Maxim Shemanarev 00005 // Contact: mcseem@antigrain.com 00006 // mcseemagg@yahoo.com 00007 // http://antigrain.com 00008 // 00009 // AGG is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU General Public License 00011 // as published by the Free Software Foundation; either version 2 00012 // of the License, or (at your option) any later version. 00013 // 00014 // AGG is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with AGG; if not, write to the Free Software 00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00022 // MA 02110-1301, USA. 00023 //---------------------------------------------------------------------------- 00024 00025 #ifndef AGG_CONV_MARKER_INCLUDED 00026 #define AGG_CONV_MARKER_INCLUDED 00027 00028 #include "agg_basics.h" 00029 #include "agg_trans_affine.h" 00030 00031 namespace agg 00032 { 00033 //-------------------------------------------------------------conv_marker 00034 template<class MarkerLocator, class MarkerShapes> 00035 class conv_marker 00036 { 00037 public: 00038 conv_marker(MarkerLocator& ml, MarkerShapes& ms); 00039 00040 trans_affine& transform() { return m_transform; } 00041 const trans_affine& transform() const { return m_transform; } 00042 00043 void rewind(unsigned path_id); 00044 unsigned vertex(double* x, double* y); 00045 00046 private: 00047 conv_marker(const conv_marker<MarkerLocator, MarkerShapes>&); 00048 const conv_marker<MarkerLocator, MarkerShapes>& 00049 operator = (const conv_marker<MarkerLocator, MarkerShapes>&); 00050 00051 enum status_e 00052 { 00053 initial, 00054 markers, 00055 polygon, 00056 stop 00057 }; 00058 00059 MarkerLocator* m_marker_locator; 00060 MarkerShapes* m_marker_shapes; 00061 trans_affine m_transform; 00062 trans_affine m_mtx; 00063 status_e m_status; 00064 unsigned m_marker; 00065 unsigned m_num_markers; 00066 }; 00067 00068 00069 //------------------------------------------------------------------------ 00070 template<class MarkerLocator, class MarkerShapes> 00071 conv_marker<MarkerLocator, MarkerShapes>::conv_marker(MarkerLocator& ml, MarkerShapes& ms) : 00072 m_marker_locator(&ml), 00073 m_marker_shapes(&ms), 00074 m_status(initial), 00075 m_marker(0), 00076 m_num_markers(1) 00077 { 00078 } 00079 00080 00081 //------------------------------------------------------------------------ 00082 template<class MarkerLocator, class MarkerShapes> 00083 void conv_marker<MarkerLocator, MarkerShapes>::rewind(unsigned) 00084 { 00085 m_status = initial; 00086 m_marker = 0; 00087 m_num_markers = 1; 00088 } 00089 00090 00091 //------------------------------------------------------------------------ 00092 template<class MarkerLocator, class MarkerShapes> 00093 unsigned conv_marker<MarkerLocator, MarkerShapes>::vertex(double* x, double* y) 00094 { 00095 unsigned cmd = path_cmd_move_to; 00096 double x1, y1, x2, y2; 00097 00098 while(!is_stop(cmd)) 00099 { 00100 switch(m_status) 00101 { 00102 case initial: 00103 if(m_num_markers == 0) 00104 { 00105 cmd = path_cmd_stop; 00106 break; 00107 } 00108 m_marker_locator->rewind(m_marker); 00109 ++m_marker; 00110 m_num_markers = 0; 00111 m_status = markers; 00112 00113 case markers: 00114 if(is_stop(m_marker_locator->vertex(&x1, &y1))) 00115 { 00116 m_status = initial; 00117 break; 00118 } 00119 if(is_stop(m_marker_locator->vertex(&x2, &y2))) 00120 { 00121 m_status = initial; 00122 break; 00123 } 00124 ++m_num_markers; 00125 m_mtx = m_transform; 00126 m_mtx *= trans_affine_rotation(atan2(y2 - y1, x2 - x1)); 00127 m_mtx *= trans_affine_translation(x1, y1); 00128 m_marker_shapes->rewind(m_marker - 1); 00129 m_status = polygon; 00130 00131 case polygon: 00132 cmd = m_marker_shapes->vertex(x, y); 00133 if(is_stop(cmd)) 00134 { 00135 cmd = path_cmd_move_to; 00136 m_status = markers; 00137 break; 00138 } 00139 m_mtx.transform(x, y); 00140 return cmd; 00141 00142 case stop: 00143 cmd = path_cmd_stop; 00144 break; 00145 } 00146 } 00147 return cmd; 00148 } 00149 00150 } 00151 00152 00153 #endif 00154