merge the formfield patch from ooo-build
[ooovba.git] / agg / source / agg_vcgen_stroke.cpp
blob93f6c04bf2cc1e66dbc4bbb6e783f888392d1ab1
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 // Stroke generator
18 //----------------------------------------------------------------------------
19 #include <math.h>
20 #include "agg_vcgen_stroke.h"
21 #include "agg_shorten_path.h"
23 namespace agg
26 //------------------------------------------------------------------------
27 vcgen_stroke::vcgen_stroke() :
28 m_src_vertices(),
29 m_out_vertices(),
30 m_width(0.5),
31 m_miter_limit(4.0),
32 m_inner_miter_limit(1.0 + 1.0/64.0),
33 m_approx_scale(1.0),
34 m_shorten(0.0),
35 m_line_cap(butt_cap),
36 m_line_join(miter_join),
37 m_inner_line_join(miter_join_revert),
38 m_closed(0),
39 m_status(initial),
40 m_src_vertex(0),
41 m_out_vertex(0)
46 //------------------------------------------------------------------------
47 void vcgen_stroke::miter_limit_theta(double t)
49 m_miter_limit = 1.0 / sin(t * 0.5) ;
53 //------------------------------------------------------------------------
54 void vcgen_stroke::remove_all()
56 m_src_vertices.remove_all();
57 m_closed = 0;
58 m_status = initial;
62 //------------------------------------------------------------------------
63 void vcgen_stroke::add_vertex(double x, double y, unsigned cmd)
65 m_status = initial;
66 if(is_move_to(cmd))
68 m_src_vertices.modify_last(vertex_dist(x, y));
70 else
72 if(is_vertex(cmd))
74 m_src_vertices.add(vertex_dist(x, y));
76 else
78 m_closed = get_close_flag(cmd);
84 //------------------------------------------------------------------------
85 void vcgen_stroke::rewind(unsigned)
87 if(m_status == initial)
89 m_src_vertices.close(m_closed != 0);
90 shorten_path(m_src_vertices, m_shorten, m_closed);
91 if(m_src_vertices.size() < 3) m_closed = 0;
93 m_status = ready;
94 m_src_vertex = 0;
95 m_out_vertex = 0;
99 //------------------------------------------------------------------------
100 unsigned vcgen_stroke::vertex(double* x, double* y)
102 unsigned cmd = path_cmd_line_to;
103 while(!is_stop(cmd))
105 switch(m_status)
107 case initial:
108 rewind(0);
110 case ready:
111 if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
113 cmd = path_cmd_stop;
114 break;
116 m_status = m_closed ? outline1 : cap1;
117 cmd = path_cmd_move_to;
118 m_src_vertex = 0;
119 m_out_vertex = 0;
120 break;
122 case cap1:
123 stroke_calc_cap(m_out_vertices,
124 m_src_vertices[0],
125 m_src_vertices[1],
126 m_src_vertices[0].dist,
127 m_line_cap,
128 m_width,
129 m_approx_scale);
130 m_src_vertex = 1;
131 m_prev_status = outline1;
132 m_status = out_vertices;
133 m_out_vertex = 0;
134 break;
136 case cap2:
137 stroke_calc_cap(m_out_vertices,
138 m_src_vertices[m_src_vertices.size() - 1],
139 m_src_vertices[m_src_vertices.size() - 2],
140 m_src_vertices[m_src_vertices.size() - 2].dist,
141 m_line_cap,
142 m_width,
143 m_approx_scale);
144 m_prev_status = outline2;
145 m_status = out_vertices;
146 m_out_vertex = 0;
147 break;
149 case outline1:
150 if(m_closed)
152 if(m_src_vertex >= m_src_vertices.size())
154 m_prev_status = close_first;
155 m_status = end_poly1;
156 break;
159 else
161 if(m_src_vertex >= m_src_vertices.size() - 1)
163 m_status = cap2;
164 break;
167 stroke_calc_join(m_out_vertices,
168 m_src_vertices.prev(m_src_vertex),
169 m_src_vertices.curr(m_src_vertex),
170 m_src_vertices.next(m_src_vertex),
171 m_src_vertices.prev(m_src_vertex).dist,
172 m_src_vertices.curr(m_src_vertex).dist,
173 m_width,
174 m_line_join,
175 m_inner_line_join,
176 m_miter_limit,
177 m_inner_miter_limit,
178 m_approx_scale);
179 ++m_src_vertex;
180 m_prev_status = m_status;
181 m_status = out_vertices;
182 m_out_vertex = 0;
183 break;
185 case close_first:
186 m_status = outline2;
187 cmd = path_cmd_move_to;
189 case outline2:
190 if(m_src_vertex <= unsigned(m_closed == 0))
192 m_status = end_poly2;
193 m_prev_status = stop;
194 break;
197 --m_src_vertex;
198 stroke_calc_join(m_out_vertices,
199 m_src_vertices.next(m_src_vertex),
200 m_src_vertices.curr(m_src_vertex),
201 m_src_vertices.prev(m_src_vertex),
202 m_src_vertices.curr(m_src_vertex).dist,
203 m_src_vertices.prev(m_src_vertex).dist,
204 m_width,
205 m_line_join,
206 m_inner_line_join,
207 m_miter_limit,
208 m_inner_miter_limit,
209 m_approx_scale);
211 m_prev_status = m_status;
212 m_status = out_vertices;
213 m_out_vertex = 0;
214 break;
216 case out_vertices:
217 if(m_out_vertex >= m_out_vertices.size())
219 m_status = m_prev_status;
221 else
223 const point_type& c = m_out_vertices[m_out_vertex++];
224 *x = c.x;
225 *y = c.y;
226 return cmd;
228 break;
230 case end_poly1:
231 m_status = m_prev_status;
232 return (unsigned)path_cmd_end_poly | (unsigned)path_flags_close | (unsigned)path_flags_ccw;
234 case end_poly2:
235 m_status = m_prev_status;
236 return (unsigned)path_cmd_end_poly | (unsigned)path_flags_close | (unsigned)path_flags_cw;
238 case stop:
239 cmd = path_cmd_stop;
240 break;
243 return cmd;