Anti-Grain Geometry Tutorial
agg_vcgen_contour.cpp
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
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 //----------------------------------------------------------------------------
15 //
16 // Contour generator
17 //
18 //----------------------------------------------------------------------------
19 
20 #include "agg_vcgen_contour.h"
21 
22 namespace agg
23 {
24 
25  //------------------------------------------------------------------------
26  vcgen_contour::vcgen_contour() :
27  m_stroker(),
28  m_width(1),
29  m_src_vertices(),
30  m_out_vertices(),
31  m_status(initial),
32  m_src_vertex(0),
33  m_closed(0),
34  m_orientation(0),
35  m_auto_detect(false)
36  {
37  }
38 
39  //------------------------------------------------------------------------
40  void vcgen_contour::remove_all()
41  {
42  m_src_vertices.remove_all();
43  m_closed = 0;
44  m_orientation = 0;
45  m_status = initial;
46  }
47 
48  //------------------------------------------------------------------------
49  void vcgen_contour::add_vertex(double x, double y, unsigned cmd)
50  {
51  m_status = initial;
52  if(is_move_to(cmd))
53  {
54  m_src_vertices.modify_last(vertex_dist(x, y));
55  }
56  else
57  {
58  if(is_vertex(cmd))
59  {
60  m_src_vertices.add(vertex_dist(x, y));
61  }
62  else
63  {
64  if(is_end_poly(cmd))
65  {
66  m_closed = get_close_flag(cmd);
67  if(m_orientation == path_flags_none)
68  {
69  m_orientation = get_orientation(cmd);
70  }
71  }
72  }
73  }
74  }
75 
76  //------------------------------------------------------------------------
77  void vcgen_contour::rewind(unsigned)
78  {
79  if(m_status == initial)
80  {
81  m_src_vertices.close(true);
82  if(m_auto_detect)
83  {
84  if(!is_oriented(m_orientation))
85  {
86  m_orientation = (calc_polygon_area(m_src_vertices) > 0.0) ?
87  path_flags_ccw :
88  path_flags_cw;
89  }
90  }
91  if(is_oriented(m_orientation))
92  {
93  m_stroker.width(is_ccw(m_orientation) ? m_width : -m_width);
94  }
95  }
96  m_status = ready;
97  m_src_vertex = 0;
98  }
99 
100  //------------------------------------------------------------------------
101  unsigned vcgen_contour::vertex(double* x, double* y)
102  {
103  unsigned cmd = path_cmd_line_to;
104  while(!is_stop(cmd))
105  {
106  switch(m_status)
107  {
108  case initial:
109  rewind(0);
110 
111  case ready:
112  if(m_src_vertices.size() < 2 + unsigned(m_closed != 0))
113  {
114  cmd = path_cmd_stop;
115  break;
116  }
117  m_status = outline;
118  cmd = path_cmd_move_to;
119  m_src_vertex = 0;
120  m_out_vertex = 0;
121 
122  case outline:
123  if(m_src_vertex >= m_src_vertices.size())
124  {
125  m_status = end_poly;
126  break;
127  }
128  m_stroker.calc_join(m_out_vertices,
129  m_src_vertices.prev(m_src_vertex),
130  m_src_vertices.curr(m_src_vertex),
131  m_src_vertices.next(m_src_vertex),
132  m_src_vertices.prev(m_src_vertex).dist,
133  m_src_vertices.curr(m_src_vertex).dist);
134  ++m_src_vertex;
135  m_status = out_vertices;
136  m_out_vertex = 0;
137 
138  case out_vertices:
139  if(m_out_vertex >= m_out_vertices.size())
140  {
141  m_status = outline;
142  }
143  else
144  {
145  const point_d& c = m_out_vertices[m_out_vertex++];
146  *x = c.x;
147  *y = c.y;
148  return cmd;
149  }
150  break;
151 
152  case end_poly:
153  if(!m_closed) return path_cmd_stop;
154  m_status = stop;
155  return path_cmd_end_poly | path_flags_close | path_flags_ccw;
156 
157  case stop:
158  return path_cmd_stop;
159  }
160  }
161  return cmd;
162  }
163 
164 }
Definition: agg_arc.cpp:24