update dev300-m58
[ooovba.git] / agg / inc / agg_path_storage_integer.h
blob4b21fc6746afd56543cc9ab870705f08f18240ba
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 #ifndef AGG_PATH_STORAGE_INTEGER_INCLUDED
17 #define AGG_PATH_STORAGE_INTEGER_INCLUDED
19 #include <string.h>
20 #include "agg_array.h"
22 namespace agg
25 //---------------------------------------------------------vertex_integer
26 template<class T, unsigned CoordShift=6> struct vertex_integer
28 enum path_cmd
30 cmd_move_to = 0,
31 cmd_line_to = 1,
32 cmd_curve3 = 2,
33 cmd_curve4 = 3
36 enum
38 coord_shift = CoordShift,
39 coord_mult = 1 << coord_shift
42 T x,y;
43 vertex_integer() {}
44 vertex_integer(T x_, T y_, unsigned flag) :
45 x(((x_ << 1) & ~1) | (flag & 1)),
46 y(((y_ << 1) & ~1) | (flag >> 1)) {}
48 unsigned vertex(double* x_, double* y_,
49 double dx=0, double dy=0,
50 double scale=1.0) const
52 *x_ = dx + (double(x >> 1) / coord_mult) * scale;
53 *y_ = dy + (double(y >> 1) / coord_mult) * scale;
54 switch(((y & 1) << 1) | (x & 1))
56 case cmd_move_to: return path_cmd_move_to;
57 case cmd_line_to: return path_cmd_line_to;
58 case cmd_curve3: return path_cmd_curve3;
59 case cmd_curve4: return path_cmd_curve4;
61 return path_cmd_stop;
66 //---------------------------------------------------path_storage_integer
67 template<class T, unsigned CoordShift=6> class path_storage_integer
69 public:
70 typedef vertex_integer<T, CoordShift> vertex_integer_type;
72 //--------------------------------------------------------------------
73 path_storage_integer() : m_storage(), m_vertex_idx(0), m_closed(true) {}
75 //--------------------------------------------------------------------
76 void remove_all() { m_storage.remove_all(); }
78 //--------------------------------------------------------------------
79 void move_to(T x, T y)
81 m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_move_to));
84 //--------------------------------------------------------------------
85 void line_to(T x, T y)
87 m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_line_to));
90 //--------------------------------------------------------------------
91 void curve3(T x_ctrl, T y_ctrl,
92 T x_to, T y_to)
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));
98 //--------------------------------------------------------------------
99 void curve4(T x_ctrl1, T y_ctrl1,
100 T x_ctrl2, T y_ctrl2,
101 T x_to, T y_to)
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));
108 //--------------------------------------------------------------------
109 void close_polygon() {}
111 //--------------------------------------------------------------------
112 unsigned size() const { return m_storage.size(); }
113 unsigned vertex(unsigned idx, T* x, T* y) const
115 const vertex_integer_type& v = m_storage[idx];
116 *x = v.x >> 1;
117 *y = v.y >> 1;
118 return ((v.y & 1) << 1) | (v.x & 1);
121 //--------------------------------------------------------------------
122 unsigned byte_size() const { return m_storage.size() * sizeof(vertex_integer_type); }
123 void serialize(int8u* ptr) const
125 unsigned i;
126 for(i = 0; i < m_storage.size(); i++)
128 memcpy(ptr, &m_storage[i], sizeof(vertex_integer_type));
129 ptr += sizeof(vertex_integer_type);
134 //--------------------------------------------------------------------
135 void rewind(unsigned)
137 m_vertex_idx = 0;
138 m_closed = true;
141 //--------------------------------------------------------------------
142 unsigned vertex(double* x, double* y)
144 if(m_storage.size() < 2 || m_vertex_idx > m_storage.size())
146 *x = 0;
147 *y = 0;
148 return path_cmd_stop;
150 if(m_vertex_idx == m_storage.size())
152 *x = 0;
153 *y = 0;
154 ++m_vertex_idx;
155 return path_cmd_end_poly | path_flags_close;
157 unsigned cmd = m_storage[m_vertex_idx].vertex(x, y);
158 if(is_move_to(cmd) && !m_closed)
160 *x = 0;
161 *y = 0;
162 m_closed = true;
163 return path_cmd_end_poly | path_flags_close;
165 m_closed = false;
166 ++m_vertex_idx;
167 return cmd;
170 //--------------------------------------------------------------------
171 rect_d bounding_rect() const
173 rect_d bounds(1e100, 1e100, -1e100, -1e100);
174 if(m_storage.size() == 0)
176 bounds.x1 = bounds.y1 = bounds.x2 = bounds.y2 = 0.0;
178 else
180 unsigned i;
181 for(i = 0; i < m_storage.size(); i++)
183 double x, y;
184 m_storage[i].vertex(&x, &y);
185 if(x < bounds.x1) bounds.x1 = x;
186 if(y < bounds.y1) bounds.y1 = y;
187 if(x > bounds.x2) bounds.x2 = x;
188 if(y > bounds.y2) bounds.y2 = y;
191 return bounds;
195 private:
196 pod_deque<vertex_integer_type, 6> m_storage;
197 unsigned m_vertex_idx;
198 bool m_closed;
204 //-----------------------------------------serialized_integer_path_adaptor
205 template<class T, unsigned CoordShift=6> class serialized_integer_path_adaptor
207 public:
208 typedef vertex_integer<T, CoordShift> vertex_integer_type;
210 //--------------------------------------------------------------------
211 serialized_integer_path_adaptor() :
212 m_data(0),
213 m_end(0),
214 m_ptr(0),
215 m_dx(0.0),
216 m_dy(0.0),
217 m_scale(1.0),
218 m_vertices(0)
221 //--------------------------------------------------------------------
222 serialized_integer_path_adaptor(const int8u* data, unsigned size,
223 double dx, double dy) :
224 m_data(data),
225 m_end(data + size),
226 m_ptr(data),
227 m_dx(dx),
228 m_dy(dy),
229 m_vertices(0)
232 //--------------------------------------------------------------------
233 void init(const int8u* data, unsigned size,
234 double dx, double dy, double scale=1.0)
236 m_data = data;
237 m_end = data + size;
238 m_ptr = data;
239 m_dx = dx;
240 m_dy = dy;
241 m_scale = scale;
242 m_vertices = 0;
246 //--------------------------------------------------------------------
247 void rewind(unsigned)
249 m_ptr = m_data;
250 m_vertices = 0;
253 //--------------------------------------------------------------------
254 unsigned vertex(double* x, double* y)
256 if(m_data == 0 || m_ptr > m_end)
258 *x = 0;
259 *y = 0;
260 return path_cmd_stop;
263 if(m_ptr == m_end)
265 *x = 0;
266 *y = 0;
267 m_ptr += sizeof(vertex_integer_type);
268 return path_cmd_end_poly | path_flags_close;
271 vertex_integer_type v;
272 memcpy(&v, m_ptr, sizeof(vertex_integer_type));
273 unsigned cmd = v.vertex(x, y, m_dx, m_dy, m_scale);
274 if(is_move_to(cmd) && m_vertices > 2)
276 *x = 0;
277 *y = 0;
278 m_vertices = 0;
279 return path_cmd_end_poly | path_flags_close;
281 ++m_vertices;
282 m_ptr += sizeof(vertex_integer_type);
283 return cmd;
286 private:
287 const int8u* m_data;
288 const int8u* m_end;
289 const int8u* m_ptr;
290 double m_dx;
291 double m_dy;
292 double m_scale;
293 unsigned m_vertices;
299 #endif