1 2 //---------------------------------------------------------------------------- 3 // Anti-Grain Geometry - Version 2.3 4 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 5 // Copyright (C) 2005 Tony Juricic (tonygeek (at) yahoo.com) 6 // 7 // Permission to copy, use, modify, sell and distribute this software 8 // is granted provided this copyright notice appears in all copies. 9 // This software is provided "as is" without express or implied 10 // warranty, and with no claim as to its suitability for any purpose. 11 // 12 //---------------------------------------------------------------------------- 13 // Contact: mcseem (at) antigrain.com 14 // mcseemagg (at) yahoo.com 15 // http://www.antigrain.com 16 //---------------------------------------------------------------------------- 17 #ifndef AGG_CURVES_INCLUDED 18 #define AGG_CURVES_INCLUDED 19 #include "agg_array.h" 20 namespace agg 21 { 22 struct curve4_points { 23 FX_FLOAT cp[8]; 24 curve4_points() {} 25 curve4_points(FX_FLOAT x1, FX_FLOAT y1, 26 FX_FLOAT x2, FX_FLOAT y2, 27 FX_FLOAT x3, FX_FLOAT y3, 28 FX_FLOAT x4, FX_FLOAT y4) 29 { 30 cp[0] = x1; 31 cp[1] = y1; 32 cp[2] = x2; 33 cp[3] = y2; 34 cp[4] = x3; 35 cp[5] = y3; 36 cp[6] = x4; 37 cp[7] = y4; 38 } 39 void init(FX_FLOAT x1, FX_FLOAT y1, 40 FX_FLOAT x2, FX_FLOAT y2, 41 FX_FLOAT x3, FX_FLOAT y3, 42 FX_FLOAT x4, FX_FLOAT y4) 43 { 44 cp[0] = x1; 45 cp[1] = y1; 46 cp[2] = x2; 47 cp[3] = y2; 48 cp[4] = x3; 49 cp[5] = y3; 50 cp[6] = x4; 51 cp[7] = y4; 52 } 53 FX_FLOAT operator [] (unsigned i) const 54 { 55 return cp[i]; 56 } 57 FX_FLOAT& operator [] (unsigned i) 58 { 59 return cp[i]; 60 } 61 }; 62 class curve4_div 63 { 64 public: 65 curve4_div() : 66 m_count(0) 67 {} 68 curve4_div(FX_FLOAT x1, FX_FLOAT y1, 69 FX_FLOAT x2, FX_FLOAT y2, 70 FX_FLOAT x3, FX_FLOAT y3, 71 FX_FLOAT x4, FX_FLOAT y4) : 72 m_count(0) 73 { 74 init(x1, y1, x2, y2, x3, y3, x4, y4); 75 } 76 curve4_div(const curve4_points& cp) : 77 m_count(0) 78 { 79 init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); 80 } 81 void reset() 82 { 83 m_points.remove_all(); 84 m_count = 0; 85 } 86 void init(FX_FLOAT x1, FX_FLOAT y1, 87 FX_FLOAT x2, FX_FLOAT y2, 88 FX_FLOAT x3, FX_FLOAT y3, 89 FX_FLOAT x4, FX_FLOAT y4); 90 void init(const curve4_points& cp) 91 { 92 init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); 93 } 94 void rewind(unsigned) 95 { 96 m_count = 0; 97 } 98 unsigned vertex(FX_FLOAT* x, FX_FLOAT* y) 99 { 100 if(m_count >= m_points.size()) { 101 return path_cmd_stop; 102 } 103 const point_type& p = m_points[m_count++]; 104 *x = p.x; 105 *y = p.y; 106 return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to; 107 } 108 unsigned vertex_flag(FX_FLOAT* x, FX_FLOAT* y, int& flag) 109 { 110 if(m_count >= m_points.size()) { 111 return path_cmd_stop; 112 } 113 const point_type& p = m_points[m_count++]; 114 *x = p.x; 115 *y = p.y; 116 flag = p.flag; 117 return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to; 118 } 119 int count() 120 { 121 return m_points.size(); 122 } 123 private: 124 void bezier(FX_FLOAT x1, FX_FLOAT y1, 125 FX_FLOAT x2, FX_FLOAT y2, 126 FX_FLOAT x3, FX_FLOAT y3, 127 FX_FLOAT x4, FX_FLOAT y4); 128 void recursive_bezier(FX_FLOAT x1, FX_FLOAT y1, 129 FX_FLOAT x2, FX_FLOAT y2, 130 FX_FLOAT x3, FX_FLOAT y3, 131 FX_FLOAT x4, FX_FLOAT y4, 132 unsigned level); 133 FX_FLOAT m_distance_tolerance_square; 134 FX_FLOAT m_distance_tolerance_manhattan; 135 unsigned m_count; 136 pod_deque<point_type> m_points; 137 }; 138 class curve4 139 { 140 public: 141 curve4() {} 142 curve4(FX_FLOAT x1, FX_FLOAT y1, 143 FX_FLOAT x2, FX_FLOAT y2, 144 FX_FLOAT x3, FX_FLOAT y3, 145 FX_FLOAT x4, FX_FLOAT y4) 146 { 147 init(x1, y1, x2, y2, x3, y3, x4, y4); 148 } 149 curve4(const curve4_points& cp) 150 { 151 init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); 152 } 153 void reset() 154 { 155 m_curve_div.reset(); 156 } 157 void init(FX_FLOAT x1, FX_FLOAT y1, 158 FX_FLOAT x2, FX_FLOAT y2, 159 FX_FLOAT x3, FX_FLOAT y3, 160 FX_FLOAT x4, FX_FLOAT y4) 161 { 162 m_curve_div.init(x1, y1, x2, y2, x3, y3, x4, y4); 163 } 164 void init(const curve4_points& cp) 165 { 166 init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); 167 } 168 void rewind(unsigned path_id) 169 { 170 m_curve_div.rewind(path_id); 171 } 172 unsigned vertex(FX_FLOAT* x, FX_FLOAT* y) 173 { 174 return m_curve_div.vertex(x, y); 175 } 176 unsigned vertex_curve_flag(FX_FLOAT* x, FX_FLOAT* y, int& flag) 177 { 178 return m_curve_div.vertex_flag(x, y, flag); 179 } 180 int count() 181 { 182 return m_curve_div.count(); 183 } 184 private: 185 curve4_div m_curve_div; 186 }; 187 } 188 #endif 189