merge the formfield patch from ooo-build
[ooovba.git] / agg / source / agg_vcgen_smooth_poly1.cpp
blobdca22e0048a8b4ff30b50a20ba7f96f5236851b0
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
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 //----------------------------------------------------------------------------
16 // Smooth polygon generator
18 //----------------------------------------------------------------------------
20 #include "agg_vcgen_smooth_poly1.h"
22 namespace agg
25 //------------------------------------------------------------------------
26 vcgen_smooth_poly1::vcgen_smooth_poly1() :
27 m_src_vertices(),
28 m_smooth_value(0.5),
29 m_closed(0),
30 m_status(initial),
31 m_src_vertex(0)
36 //------------------------------------------------------------------------
37 void vcgen_smooth_poly1::remove_all()
39 m_src_vertices.remove_all();
40 m_closed = 0;
41 m_status = initial;
45 //------------------------------------------------------------------------
46 void vcgen_smooth_poly1::add_vertex(double x, double y, unsigned cmd)
48 m_status = initial;
49 if(is_move_to(cmd))
51 m_src_vertices.modify_last(vertex_dist(x, y));
53 else
55 if(is_vertex(cmd))
57 m_src_vertices.add(vertex_dist(x, y));
59 else
61 m_closed = get_close_flag(cmd);
67 //------------------------------------------------------------------------
68 void vcgen_smooth_poly1::rewind(unsigned)
70 if(m_status == initial)
72 m_src_vertices.close(m_closed != 0);
74 m_status = ready;
75 m_src_vertex = 0;
79 //------------------------------------------------------------------------
80 void vcgen_smooth_poly1::calculate(const vertex_dist& v0,
81 const vertex_dist& v1,
82 const vertex_dist& v2,
83 const vertex_dist& v3)
86 double k1 = v0.dist / (v0.dist + v1.dist);
87 double k2 = v1.dist / (v1.dist + v2.dist);
89 double xm1 = v0.x + (v2.x - v0.x) * k1;
90 double ym1 = v0.y + (v2.y - v0.y) * k1;
91 double xm2 = v1.x + (v3.x - v1.x) * k2;
92 double ym2 = v1.y + (v3.y - v1.y) * k2;
94 m_ctrl1_x = v1.x + m_smooth_value * (v2.x - xm1);
95 m_ctrl1_y = v1.y + m_smooth_value * (v2.y - ym1);
96 m_ctrl2_x = v2.x + m_smooth_value * (v1.x - xm2);
97 m_ctrl2_y = v2.y + m_smooth_value * (v1.y - ym2);
101 //------------------------------------------------------------------------
102 unsigned vcgen_smooth_poly1::vertex(double* x, double* y)
104 unsigned cmd = path_cmd_line_to;
105 while(!is_stop(cmd))
107 switch(m_status)
109 case initial:
110 rewind(0);
112 case ready:
113 if(m_src_vertices.size() < 2)
115 cmd = path_cmd_stop;
116 break;
119 if(m_src_vertices.size() == 2)
121 *x = m_src_vertices[m_src_vertex].x;
122 *y = m_src_vertices[m_src_vertex].y;
123 m_src_vertex++;
124 if(m_src_vertex == 1) return path_cmd_move_to;
125 if(m_src_vertex == 2) return path_cmd_line_to;
126 cmd = path_cmd_stop;
127 break;
130 cmd = path_cmd_move_to;
131 m_status = polygon;
132 m_src_vertex = 0;
134 case polygon:
135 if(m_closed)
137 if(m_src_vertex >= m_src_vertices.size())
139 *x = m_src_vertices[0].x;
140 *y = m_src_vertices[0].y;
141 m_status = end_poly;
142 return path_cmd_curve4;
145 else
147 if(m_src_vertex >= m_src_vertices.size() - 1)
149 *x = m_src_vertices[m_src_vertices.size() - 1].x;
150 *y = m_src_vertices[m_src_vertices.size() - 1].y;
151 m_status = end_poly;
152 return path_cmd_curve3;
156 calculate(m_src_vertices.prev(m_src_vertex),
157 m_src_vertices.curr(m_src_vertex),
158 m_src_vertices.next(m_src_vertex),
159 m_src_vertices.next(m_src_vertex + 1));
161 *x = m_src_vertices[m_src_vertex].x;
162 *y = m_src_vertices[m_src_vertex].y;
163 m_src_vertex++;
165 if(m_closed)
167 m_status = ctrl1;
168 return ((m_src_vertex == 1) ?
169 path_cmd_move_to :
170 path_cmd_curve4);
172 else
174 if(m_src_vertex == 1)
176 m_status = ctrl_b;
177 return path_cmd_move_to;
179 if(m_src_vertex >= m_src_vertices.size() - 1)
181 m_status = ctrl_e;
182 return path_cmd_curve3;
184 m_status = ctrl1;
185 return path_cmd_curve4;
187 // statement unreachable
188 //break;
190 case ctrl_b:
191 *x = m_ctrl2_x;
192 *y = m_ctrl2_y;
193 m_status = polygon;
194 return path_cmd_curve3;
196 case ctrl_e:
197 *x = m_ctrl1_x;
198 *y = m_ctrl1_y;
199 m_status = polygon;
200 return path_cmd_curve3;
202 case ctrl1:
203 *x = m_ctrl1_x;
204 *y = m_ctrl1_y;
205 m_status = ctrl2;
206 return path_cmd_curve4;
208 case ctrl2:
209 *x = m_ctrl2_x;
210 *y = m_ctrl2_y;
211 m_status = polygon;
212 return path_cmd_curve4;
214 case end_poly:
215 m_status = stop;
216 return path_cmd_end_poly | m_closed;
218 case stop:
219 return path_cmd_stop;
222 return cmd;