update dev300-m58
[ooovba.git] / agg / source / agg_vcgen_contour.cpp
blob0242d7a86eb509f4caad46504a21bb034efd7596
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 // Contour generator
18 //----------------------------------------------------------------------------
20 #include <math.h>
21 #include "agg_vcgen_contour.h"
23 namespace agg
26 //------------------------------------------------------------------------
27 vcgen_contour::vcgen_contour() :
28 m_src_vertices(),
29 m_out_vertices(),
30 m_width(1.0),
31 m_line_join(bevel_join),
32 m_inner_line_join(miter_join_revert),
33 m_approx_scale(1.0),
34 m_abs_width(1.0),
35 m_signed_width(1.0),
36 m_miter_limit(4.0),
37 m_inner_miter_limit(1.0 + 1.0/64.0),
38 m_status(initial),
39 m_src_vertex(0),
40 m_closed(0),
41 m_orientation(0),
42 m_auto_detect(false)
47 //------------------------------------------------------------------------
48 void vcgen_contour::remove_all()
50 m_src_vertices.remove_all();
51 m_closed = 0;
52 m_orientation = 0;
53 m_abs_width = fabs(m_width);
54 m_signed_width = m_width;
55 m_status = initial;
59 //------------------------------------------------------------------------
60 void vcgen_contour::miter_limit_theta(double t)
62 m_miter_limit = 1.0 / sin(t * 0.5) ;
66 //------------------------------------------------------------------------
67 void vcgen_contour::add_vertex(double x, double y, unsigned cmd)
69 m_status = initial;
70 if(is_move_to(cmd))
72 m_src_vertices.modify_last(vertex_dist(x, y));
74 else
76 if(is_vertex(cmd))
78 m_src_vertices.add(vertex_dist(x, y));
80 else
82 if(is_end_poly(cmd))
84 m_closed = get_close_flag(cmd);
85 if(m_orientation == path_flags_none)
87 m_orientation = get_orientation(cmd);
95 //------------------------------------------------------------------------
96 void vcgen_contour::rewind(unsigned)
98 if(m_status == initial)
100 m_src_vertices.close(true);
101 m_signed_width = m_width;
102 if(m_auto_detect)
104 if(!is_oriented(m_orientation))
106 m_orientation = (calc_polygon_area(m_src_vertices) > 0.0) ?
107 path_flags_ccw :
108 path_flags_cw;
111 if(is_oriented(m_orientation))
113 m_signed_width = is_ccw(m_orientation) ? m_width : -m_width;
116 m_status = ready;
117 m_src_vertex = 0;
121 //------------------------------------------------------------------------
122 unsigned vcgen_contour::vertex(double* x, double* y)
124 unsigned cmd = path_cmd_line_to;
125 while(!is_stop(cmd))
127 switch(m_status)
129 case initial:
130 rewind(0);
132 case ready:
133 if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
135 cmd = path_cmd_stop;
136 break;
138 m_status = outline;
139 cmd = path_cmd_move_to;
140 m_src_vertex = 0;
141 m_out_vertex = 0;
143 case outline:
144 if(m_src_vertex >= m_src_vertices.size())
146 m_status = end_poly;
147 break;
149 stroke_calc_join(m_out_vertices,
150 m_src_vertices.prev(m_src_vertex),
151 m_src_vertices.curr(m_src_vertex),
152 m_src_vertices.next(m_src_vertex),
153 m_src_vertices.prev(m_src_vertex).dist,
154 m_src_vertices.curr(m_src_vertex).dist,
155 m_signed_width,
156 m_line_join,
157 m_inner_line_join,
158 m_miter_limit,
159 m_inner_miter_limit,
160 m_approx_scale);
161 ++m_src_vertex;
162 m_status = out_vertices;
163 m_out_vertex = 0;
165 case out_vertices:
166 if(m_out_vertex >= m_out_vertices.size())
168 m_status = outline;
170 else
172 const point_type& c = m_out_vertices[m_out_vertex++];
173 *x = c.x;
174 *y = c.y;
175 return cmd;
177 break;
179 case end_poly:
180 if(!m_closed) return path_cmd_stop;
181 m_status = stop;
182 return (unsigned)path_cmd_end_poly | (unsigned)path_flags_close | (unsigned)path_flags_ccw;
184 case stop:
185 return path_cmd_stop;
188 return cmd;