1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
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.
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
20 #include "agg_array.h"
24 //---------------------------------------------------------vertex_integer
25 template<class T
, unsigned CoordShift
=6> struct vertex_integer
37 coord_shift
= CoordShift
,
38 coord_scale
= 1 << coord_shift
43 vertex_integer(T x_
, T y_
, unsigned flag
) :
44 x(((x_
<< 1) & ~1) | (flag
& 1)),
45 y(((y_
<< 1) & ~1) | (flag
>> 1)) {}
47 unsigned vertex(double* x_
, double* y_
,
48 double dx
=0, double dy
=0,
49 double scale
=1.0) const
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))
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
;
65 //---------------------------------------------------path_storage_integer
66 template<class T
, unsigned CoordShift
=6> class path_storage_integer
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
,
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
,
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
, double* x
, double* y
) const
115 return m_storage
[idx
].vertex(x
, y
);
118 //--------------------------------------------------------------------
119 unsigned byte_size() const { return m_storage
.size() * sizeof(vertex_integer_type
); }
120 void serialize(int8u
* ptr
) const
123 for(i
= 0; i
< m_storage
.size(); i
++)
125 memcpy(ptr
, &m_storage
[i
], sizeof(vertex_integer_type
));
126 ptr
+= sizeof(vertex_integer_type
);
130 //--------------------------------------------------------------------
131 void rewind(unsigned)
137 //--------------------------------------------------------------------
138 unsigned vertex(double* x
, double* y
)
140 if(m_storage
.size() < 2 || m_vertex_idx
> m_storage
.size())
144 return path_cmd_stop
;
146 if(m_vertex_idx
== m_storage
.size())
151 return path_cmd_end_poly
| path_flags_close
;
153 unsigned cmd
= m_storage
[m_vertex_idx
].vertex(x
, y
);
154 if(is_move_to(cmd
) && !m_closed
)
159 return path_cmd_end_poly
| path_flags_close
;
166 //--------------------------------------------------------------------
167 rect_d
bounding_rect() const
169 rect_d
bounds(1e100
, 1e100
, -1e100
, -1e100
);
170 if(m_storage
.size() == 0)
172 bounds
.x1
= bounds
.y1
= bounds
.x2
= bounds
.y2
= 0.0;
177 for(i
= 0; i
< m_storage
.size(); i
++)
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
;
191 pod_bvector
<vertex_integer_type
, 6> m_storage
;
192 unsigned m_vertex_idx
;
199 //-----------------------------------------serialized_integer_path_adaptor
200 template<class T
, unsigned CoordShift
=6> class serialized_integer_path_adaptor
203 typedef vertex_integer
<T
, CoordShift
> vertex_integer_type
;
205 //--------------------------------------------------------------------
206 serialized_integer_path_adaptor() :
216 //--------------------------------------------------------------------
217 serialized_integer_path_adaptor(const int8u
* data
, unsigned size
,
218 double dx
, double dy
) :
227 //--------------------------------------------------------------------
228 void init(const int8u
* data
, unsigned size
,
229 double dx
, double dy
, double scale
=1.0)
241 //--------------------------------------------------------------------
242 void rewind(unsigned)
248 //--------------------------------------------------------------------
249 unsigned vertex(double* x
, double* y
)
251 if(m_data
== 0 || m_ptr
> m_end
)
255 return path_cmd_stop
;
262 m_ptr
+= sizeof(vertex_integer_type
);
263 return path_cmd_end_poly
| path_flags_close
;
266 vertex_integer_type v
;
267 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)
274 return path_cmd_end_poly
| path_flags_close
;
277 m_ptr
+= sizeof(vertex_integer_type
);