24 #ifndef AGG_CONV_GPC_INCLUDED 25 #define AGG_CONV_GPC_INCLUDED 28 #include "agg_basics.h" 29 #include "agg_array.h" 58 struct contour_header_type
70 typedef VSA source_a_type;
71 typedef VSB source_b_type;
79 conv_gpc(source_a_type& a, source_b_type& b, gpc_op_e op = gpc_or) :
82 m_status(status_move_to),
87 std::memset(&m_poly_a, 0,
sizeof(m_poly_a));
88 std::memset(&m_poly_b, 0,
sizeof(m_poly_b));
89 std::memset(&m_result, 0,
sizeof(m_result));
92 void attach1(VSA& source) { m_src_a = &source; }
93 void attach2(VSB& source) { m_src_b = &source; }
95 void operation(gpc_op_e v) { m_operation = v; }
98 void rewind(
unsigned path_id);
99 unsigned vertex(
double* x,
double* y);
106 void free_polygon(gpc_polygon& p);
108 void free_gpc_data();
109 void start_contour();
110 void add_vertex(
double x,
double y);
111 void end_contour(
unsigned orientation);
112 void make_polygon(gpc_polygon& p);
113 void start_extracting();
115 bool next_vertex(
double* x,
double* y);
119 template<
class VS>
void add(VS& src, gpc_polygon& p)
123 double start_x = 0.0;
124 double start_y = 0.0;
125 bool line_to =
false;
126 unsigned orientation = 0;
128 m_contour_accumulator.remove_all();
130 while(!is_stop(cmd = src.vertex(&x, &y)))
138 end_contour(orientation);
152 orientation = get_orientation(cmd);
153 if(line_to && is_closed(cmd))
155 add_vertex(start_x, start_y);
162 end_contour(orientation);
170 source_a_type* m_src_a;
171 source_b_type* m_src_b;
175 gpc_op_e m_operation;
176 vertex_array_type m_vertex_accumulator;
177 contour_header_array_type m_contour_accumulator;
178 gpc_polygon m_poly_a;
179 gpc_polygon m_poly_b;
180 gpc_polygon m_result;
188 template<
class VSA,
class VSB>
192 for(i = 0; i < p.num_contours; i++)
195 p.contour[i].num_vertices);
198 std::memset(&p, 0,
sizeof(gpc_polygon));
203 template<
class VSA,
class VSB>
208 gpc_free_polygon(&m_result);
210 std::memset(&m_result, 0,
sizeof(m_result));
215 template<
class VSA,
class VSB>
218 free_polygon(m_poly_a);
219 free_polygon(m_poly_b);
225 template<
class VSA,
class VSB>
228 contour_header_type h;
229 std::memset(&h, 0,
sizeof(h));
230 m_contour_accumulator.add(h);
231 m_vertex_accumulator.remove_all();
236 template<
class VSA,
class VSB>
242 m_vertex_accumulator.add(v);
247 template<
class VSA,
class VSB>
250 if(m_contour_accumulator.size())
252 if(m_vertex_accumulator.size() > 2)
254 contour_header_type& h =
255 m_contour_accumulator[m_contour_accumulator.size() - 1];
257 h.num_vertices = m_vertex_accumulator.size();
264 gpc_vertex* d = h.vertices;
266 for(i = 0; i < h.num_vertices; i++)
268 const gpc_vertex& s = m_vertex_accumulator[i];
276 m_vertex_accumulator.remove_last();
283 template<
class VSA,
class VSB>
287 if(m_contour_accumulator.size())
289 p.num_contours = m_contour_accumulator.size();
295 gpc_vertex_list* pv = p.contour;
296 for(i = 0; i < p.num_contours; i++)
298 const contour_header_type& h = m_contour_accumulator[i];
299 pv->num_vertices = h.num_vertices;
300 pv->vertex = h.vertices;
308 template<
class VSA,
class VSB>
311 m_status = status_move_to;
318 template<
class VSA,
class VSB>
321 if(++m_contour < m_result.num_contours)
331 template<
class VSA,
class VSB>
334 const gpc_vertex_list& vlist = m_result.contour[m_contour];
335 if(++m_vertex < vlist.num_vertices)
337 const gpc_vertex& v = vlist.vertex[m_vertex];
347 template<
class VSA,
class VSB>
351 m_src_a->rewind(path_id);
352 m_src_b->rewind(path_id);
353 add(*m_src_a, m_poly_a);
354 add(*m_src_b, m_poly_b);
358 gpc_polygon_clip(GPC_UNION,
365 gpc_polygon_clip(GPC_INT,
372 gpc_polygon_clip(GPC_XOR,
379 gpc_polygon_clip(GPC_DIFF,
386 gpc_polygon_clip(GPC_DIFF,
397 template<
class VSA,
class VSB>
400 if(m_status == status_move_to)
404 if(next_vertex(x, y))
406 m_status = status_line_to;
407 return path_cmd_move_to;
409 m_status = status_stop;
410 return path_cmd_end_poly | path_flags_close;
415 if(next_vertex(x, y))
417 return path_cmd_line_to;
421 m_status = status_move_to;
423 return path_cmd_end_poly | path_flags_close;
425 return path_cmd_stop;