Anti-Grain Geometry Tutorial
agg_conv_adaptor_vpgen.h
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 #ifndef AGG_CONV_ADAPTOR_VPGEN_INCLUDED
17 #define AGG_CONV_ADAPTOR_VPGEN_INCLUDED
18 
19 #include "agg_basics.h"
20 
21 namespace agg
22 {
23 
24  //======================================================conv_adaptor_vpgen
25  template<class VertexSource, class VPGen> class conv_adaptor_vpgen
26  {
27  public:
28  explicit conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {}
29  void attach(VertexSource& source) { m_source = &source; }
30 
31  VPGen& vpgen() { return m_vpgen; }
32  const VPGen& vpgen() const { return m_vpgen; }
33 
34  void rewind(unsigned path_id);
35  unsigned vertex(double* x, double* y);
36 
37  private:
40  operator = (const conv_adaptor_vpgen<VertexSource, VPGen>&);
41 
42  VertexSource* m_source;
43  VPGen m_vpgen;
44  double m_start_x;
45  double m_start_y;
46  unsigned m_poly_flags;
47  int m_vertices;
48  };
49 
50 
51 
52  //------------------------------------------------------------------------
53  template<class VertexSource, class VPGen>
55  {
56  m_source->rewind(path_id);
57  m_vpgen.reset();
58  m_start_x = 0;
59  m_start_y = 0;
60  m_poly_flags = 0;
61  m_vertices = 0;
62  }
63 
64 
65  //------------------------------------------------------------------------
66  template<class VertexSource, class VPGen>
67  unsigned conv_adaptor_vpgen<VertexSource, VPGen>::vertex(double* x, double* y)
68  {
69  unsigned cmd = path_cmd_stop;
70  for(;;)
71  {
72  cmd = m_vpgen.vertex(x, y);
73  if(!is_stop(cmd)) break;
74 
75  if(m_poly_flags && !m_vpgen.auto_unclose())
76  {
77  *x = 0.0;
78  *y = 0.0;
79  cmd = m_poly_flags;
80  m_poly_flags = 0;
81  break;
82  }
83 
84  if(m_vertices < 0)
85  {
86  if(m_vertices < -1)
87  {
88  m_vertices = 0;
89  return path_cmd_stop;
90  }
91  m_vpgen.move_to(m_start_x, m_start_y);
92  m_vertices = 1;
93  continue;
94  }
95 
96  double tx, ty;
97  cmd = m_source->vertex(&tx, &ty);
98  if(is_vertex(cmd))
99  {
100  if(is_move_to(cmd))
101  {
102  if(m_vpgen.auto_close() && m_vertices > 2)
103  {
104  m_vpgen.line_to(m_start_x, m_start_y);
105  m_poly_flags = path_cmd_end_poly | path_flags_close;
106  m_start_x = tx;
107  m_start_y = ty;
108  m_vertices = -1;
109  continue;
110  }
111  m_vpgen.move_to(tx, ty);
112  m_start_x = tx;
113  m_start_y = ty;
114  m_vertices = 1;
115  }
116  else
117  {
118  m_vpgen.line_to(tx, ty);
119  ++m_vertices;
120  }
121  }
122  else
123  {
124  if(is_end_poly(cmd))
125  {
126  m_poly_flags = cmd;
127  if(is_closed(cmd) || m_vpgen.auto_close())
128  {
129  if(m_vpgen.auto_close()) m_poly_flags |= path_flags_close;
130  if(m_vertices > 2)
131  {
132  m_vpgen.line_to(m_start_x, m_start_y);
133  }
134  m_vertices = 0;
135  }
136  }
137  else
138  {
139  // path_cmd_stop
140  if(m_vpgen.auto_close() && m_vertices > 2)
141  {
142  m_vpgen.line_to(m_start_x, m_start_y);
143  m_poly_flags = path_cmd_end_poly | path_flags_close;
144  m_vertices = -2;
145  continue;
146  }
147  break;
148  }
149  }
150  }
151  return cmd;
152  }
153 
154 
155 }
156 
157 
158 #endif
159 
Definition: agg_arc.cpp:24