Update ooo320-m1
[ooovba.git] / agg / source / agg_vcgen_bspline.cpp
blob8fa1f574532fdb0bf4138d08e2eb56f57b333cf7
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 #include "agg_vcgen_bspline.h"
18 namespace agg
21 //------------------------------------------------------------------------
22 vcgen_bspline::vcgen_bspline() :
23 m_src_vertices(),
24 m_spline_x(),
25 m_spline_y(),
26 m_interpolation_step(1.0/50.0),
27 m_closed(0),
28 m_status(initial),
29 m_src_vertex(0)
34 //------------------------------------------------------------------------
35 void vcgen_bspline::remove_all()
37 m_src_vertices.remove_all();
38 m_closed = 0;
39 m_status = initial;
40 m_src_vertex = 0;
44 //------------------------------------------------------------------------
45 void vcgen_bspline::add_vertex(double x, double y, unsigned cmd)
47 m_status = initial;
48 if(is_move_to(cmd))
50 m_src_vertices.modify_last(point_type(x, y));
52 else
54 if(is_vertex(cmd))
56 m_src_vertices.add(point_type(x, y));
58 else
60 m_closed = get_close_flag(cmd);
66 //------------------------------------------------------------------------
67 void vcgen_bspline::rewind(unsigned)
69 m_cur_abscissa = 0.0;
70 m_max_abscissa = 0.0;
71 m_src_vertex = 0;
72 if(m_status == initial && m_src_vertices.size() > 2)
74 if(m_closed)
76 m_spline_x.init(m_src_vertices.size() + 8);
77 m_spline_y.init(m_src_vertices.size() + 8);
78 m_spline_x.add_point(0.0, m_src_vertices.prev(m_src_vertices.size() - 3).x);
79 m_spline_y.add_point(0.0, m_src_vertices.prev(m_src_vertices.size() - 3).y);
80 m_spline_x.add_point(1.0, m_src_vertices[m_src_vertices.size() - 3].x);
81 m_spline_y.add_point(1.0, m_src_vertices[m_src_vertices.size() - 3].y);
82 m_spline_x.add_point(2.0, m_src_vertices[m_src_vertices.size() - 2].x);
83 m_spline_y.add_point(2.0, m_src_vertices[m_src_vertices.size() - 2].y);
84 m_spline_x.add_point(3.0, m_src_vertices[m_src_vertices.size() - 1].x);
85 m_spline_y.add_point(3.0, m_src_vertices[m_src_vertices.size() - 1].y);
87 else
89 m_spline_x.init(m_src_vertices.size());
90 m_spline_y.init(m_src_vertices.size());
92 unsigned i;
93 for(i = 0; i < m_src_vertices.size(); i++)
95 double x = m_closed ? i + 4 : i;
96 m_spline_x.add_point(x, m_src_vertices[i].x);
97 m_spline_y.add_point(x, m_src_vertices[i].y);
99 m_cur_abscissa = 0.0;
100 m_max_abscissa = m_src_vertices.size() - 1;
101 if(m_closed)
103 m_cur_abscissa = 4.0;
104 m_max_abscissa += 5.0;
105 m_spline_x.add_point(m_src_vertices.size() + 4, m_src_vertices[0].x);
106 m_spline_y.add_point(m_src_vertices.size() + 4, m_src_vertices[0].y);
107 m_spline_x.add_point(m_src_vertices.size() + 5, m_src_vertices[1].x);
108 m_spline_y.add_point(m_src_vertices.size() + 5, m_src_vertices[1].y);
109 m_spline_x.add_point(m_src_vertices.size() + 6, m_src_vertices[2].x);
110 m_spline_y.add_point(m_src_vertices.size() + 6, m_src_vertices[2].y);
111 m_spline_x.add_point(m_src_vertices.size() + 7, m_src_vertices.next(2).x);
112 m_spline_y.add_point(m_src_vertices.size() + 7, m_src_vertices.next(2).y);
114 m_spline_x.prepare();
115 m_spline_y.prepare();
116 m_status = ready;
125 //------------------------------------------------------------------------
126 unsigned vcgen_bspline::vertex(double* x, double* y)
128 unsigned cmd = path_cmd_line_to;
129 while(!is_stop(cmd))
131 switch(m_status)
133 case initial:
134 rewind(0);
136 case ready:
137 if(m_src_vertices.size() < 2)
139 cmd = path_cmd_stop;
140 break;
143 if(m_src_vertices.size() == 2)
145 *x = m_src_vertices[m_src_vertex].x;
146 *y = m_src_vertices[m_src_vertex].y;
147 m_src_vertex++;
148 if(m_src_vertex == 1) return path_cmd_move_to;
149 if(m_src_vertex == 2) return path_cmd_line_to;
150 cmd = path_cmd_stop;
151 break;
154 cmd = path_cmd_move_to;
155 m_status = polygon;
156 m_src_vertex = 0;
158 case polygon:
159 if(m_cur_abscissa >= m_max_abscissa)
161 if(m_closed)
163 m_status = end_poly;
164 break;
166 else
168 *x = m_src_vertices[m_src_vertices.size() - 1].x;
169 *y = m_src_vertices[m_src_vertices.size() - 1].y;
170 m_status = end_poly;
171 return path_cmd_line_to;
175 *x = m_spline_x.get_stateful(m_cur_abscissa);
176 *y = m_spline_y.get_stateful(m_cur_abscissa);
177 m_src_vertex++;
178 m_cur_abscissa += m_interpolation_step;
179 return (m_src_vertex == 1) ? path_cmd_move_to : path_cmd_line_to;
181 case end_poly:
182 m_status = stop;
183 return path_cmd_end_poly | m_closed;
185 case stop:
186 return path_cmd_stop;
189 return cmd;