Anti-Grain Geometry Tutorial
agg_path_storage_integer.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_PATH_STORAGE_INTEGER_INCLUDED
17 #define AGG_PATH_STORAGE_INTEGER_INCLUDED
18 
19 #include <cstring>
20 #include "agg_array.h"
21 
22 namespace agg
23 {
24  //---------------------------------------------------------vertex_integer
25  template<class T, unsigned CoordShift=6> struct vertex_integer
26  {
27  enum path_cmd
28  {
29  cmd_move_to = 0,
30  cmd_line_to = 1,
31  cmd_curve3 = 2,
32  cmd_curve4 = 3
33  };
34 
35  enum coord_scale_e
36  {
37  coord_shift = CoordShift,
38  coord_scale = 1 << coord_shift
39  };
40 
41  T x,y;
42  vertex_integer() {}
43  vertex_integer(T x_, T y_, unsigned flag) :
44  x(((x_ << 1) & ~1) | (flag & 1)),
45  y(((y_ << 1) & ~1) | (flag >> 1)) {}
46 
47  unsigned vertex(double* x_, double* y_,
48  double dx=0, double dy=0,
49  double scale=1.0) const
50  {
51  *x_ = dx + (double(x >> 1) / coord_scale) * scale;
52  *y_ = dy + (double(y >> 1) / coord_scale) * scale;
53  switch(((y & 1) << 1) | (x & 1))
54  {
55  case cmd_move_to: return path_cmd_move_to;
56  case cmd_line_to: return path_cmd_line_to;
57  case cmd_curve3: return path_cmd_curve3;
58  case cmd_curve4: return path_cmd_curve4;
59  }
60  return path_cmd_stop;
61  }
62  };
63 
64 
65  //---------------------------------------------------path_storage_integer
66  template<class T, unsigned CoordShift=6> class path_storage_integer
67  {
68  public:
69  typedef T value_type;
71 
72  //--------------------------------------------------------------------
73  path_storage_integer() : m_storage(), m_vertex_idx(0), m_closed(true) {}
74 
75  //--------------------------------------------------------------------
76  void remove_all() { m_storage.remove_all(); }
77 
78  //--------------------------------------------------------------------
79  void move_to(T x, T y)
80  {
81  m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_move_to));
82  }
83 
84  //--------------------------------------------------------------------
85  void line_to(T x, T y)
86  {
87  m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_line_to));
88  }
89 
90  //--------------------------------------------------------------------
91  void curve3(T x_ctrl, T y_ctrl,
92  T x_to, T y_to)
93  {
94  m_storage.add(vertex_integer_type(x_ctrl, y_ctrl, vertex_integer_type::cmd_curve3));
95  m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve3));
96  }
97 
98  //--------------------------------------------------------------------
99  void curve4(T x_ctrl1, T y_ctrl1,
100  T x_ctrl2, T y_ctrl2,
101  T x_to, T y_to)
102  {
103  m_storage.add(vertex_integer_type(x_ctrl1, y_ctrl1, vertex_integer_type::cmd_curve4));
104  m_storage.add(vertex_integer_type(x_ctrl2, y_ctrl2, vertex_integer_type::cmd_curve4));
105  m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve4));
106  }
107 
108  //--------------------------------------------------------------------
109  void close_polygon() {}
110 
111  //--------------------------------------------------------------------
112  unsigned size() const { return m_storage.size(); }
113  unsigned vertex(unsigned idx, double* x, double* y) const
114  {
115  return m_storage[idx].vertex(x, y);
116  }
117 
118  //--------------------------------------------------------------------
119  unsigned byte_size() const { return m_storage.size() * sizeof(vertex_integer_type); }
120  void serialize(int8u* ptr) const
121  {
122  unsigned i;
123  for(i = 0; i < m_storage.size(); i++)
124  {
125  std::memcpy(ptr, &m_storage[i], sizeof(vertex_integer_type));
126  ptr += sizeof(vertex_integer_type);
127  }
128  }
129 
130  //--------------------------------------------------------------------
131  void rewind(unsigned)
132  {
133  m_vertex_idx = 0;
134  m_closed = true;
135  }
136 
137  //--------------------------------------------------------------------
138  unsigned vertex(double* x, double* y)
139  {
140  if(m_storage.size() < 2 || m_vertex_idx > m_storage.size())
141  {
142  *x = 0;
143  *y = 0;
144  return path_cmd_stop;
145  }
146  if(m_vertex_idx == m_storage.size())
147  {
148  *x = 0;
149  *y = 0;
150  ++m_vertex_idx;
151  return path_cmd_end_poly | path_flags_close;
152  }
153  unsigned cmd = m_storage[m_vertex_idx].vertex(x, y);
154  if(is_move_to(cmd) && !m_closed)
155  {
156  *x = 0;
157  *y = 0;
158  m_closed = true;
159  return path_cmd_end_poly | path_flags_close;
160  }
161  m_closed = false;
162  ++m_vertex_idx;
163  return cmd;
164  }
165 
166  //--------------------------------------------------------------------
167  rect_d bounding_rect() const
168  {
169  rect_d bounds(1e100, 1e100, -1e100, -1e100);
170  if(m_storage.size() == 0)
171  {
172  bounds.x1 = bounds.y1 = bounds.x2 = bounds.y2 = 0.0;
173  }
174  else
175  {
176  unsigned i;
177  for(i = 0; i < m_storage.size(); i++)
178  {
179  double x, y;
180  m_storage[i].vertex(&x, &y);
181  if(x < bounds.x1) bounds.x1 = x;
182  if(y < bounds.y1) bounds.y1 = y;
183  if(x > bounds.x2) bounds.x2 = x;
184  if(y > bounds.y2) bounds.y2 = y;
185  }
186  }
187  return bounds;
188  }
189 
190  private:
192  unsigned m_vertex_idx;
193  bool m_closed;
194  };
195 
196 
197 
198 
199  //-----------------------------------------serialized_integer_path_adaptor
200  template<class T, unsigned CoordShift=6> class serialized_integer_path_adaptor
201  {
202  public:
204 
205  //--------------------------------------------------------------------
207  m_data(0),
208  m_end(0),
209  m_ptr(0),
210  m_dx(0.0),
211  m_dy(0.0),
212  m_scale(1.0),
213  m_vertices(0)
214  {}
215 
216  //--------------------------------------------------------------------
217  serialized_integer_path_adaptor(const int8u* data, unsigned size,
218  double dx, double dy) :
219  m_data(data),
220  m_end(data + size),
221  m_ptr(data),
222  m_dx(dx),
223  m_dy(dy),
224  m_vertices(0)
225  {}
226 
227  //--------------------------------------------------------------------
228  void init(const int8u* data, unsigned size,
229  double dx, double dy, double scale=1.0)
230  {
231  m_data = data;
232  m_end = data + size;
233  m_ptr = data;
234  m_dx = dx;
235  m_dy = dy;
236  m_scale = scale;
237  m_vertices = 0;
238  }
239 
240 
241  //--------------------------------------------------------------------
242  void rewind(unsigned)
243  {
244  m_ptr = m_data;
245  m_vertices = 0;
246  }
247 
248  //--------------------------------------------------------------------
249  unsigned vertex(double* x, double* y)
250  {
251  if(m_data == 0 || m_ptr > m_end)
252  {
253  *x = 0;
254  *y = 0;
255  return path_cmd_stop;
256  }
257 
258  if(m_ptr == m_end)
259  {
260  *x = 0;
261  *y = 0;
262  m_ptr += sizeof(vertex_integer_type);
263  return path_cmd_end_poly | path_flags_close;
264  }
265 
266  vertex_integer_type v;
267  std::memcpy(&v, m_ptr, sizeof(vertex_integer_type));
268  unsigned cmd = v.vertex(x, y, m_dx, m_dy, m_scale);
269  if(is_move_to(cmd) && m_vertices > 2)
270  {
271  *x = 0;
272  *y = 0;
273  m_vertices = 0;
274  return path_cmd_end_poly | path_flags_close;
275  }
276  ++m_vertices;
277  m_ptr += sizeof(vertex_integer_type);
278  return cmd;
279  }
280 
281  private:
282  const int8u* m_data;
283  const int8u* m_end;
284  const int8u* m_ptr;
285  double m_dx;
286  double m_dy;
287  double m_scale;
288  unsigned m_vertices;
289  };
290 
291 }
292 
293 
294 #endif
295 
Definition: agg_arc.cpp:24