1
//----------------------------------------------------------------------------
2
// Anti-Grain Geometry - Version 2.4 (Public License)
3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5
// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
6
// Pascal Port By: Milan Marusinec alias Milano
8
// http://www.aggpas.org
9
// Copyright (c) 2005-2006
11
// Permission to copy, use, modify, sell and distribute this software
12
// is granted provided this copyright notice appears in all copies.
13
// This software is provided "as is" without express or implied
14
// warranty, and with no claim as to its suitability for any purpose.
16
//----------------------------------------------------------------------------
17
// Contact: mcseem@antigrain.com
18
// mcseemagg@yahoo.com
19
// http://www.antigrain.com
21
//----------------------------------------------------------------------------
23
// General Polygon Clipper based on the GPC library by Alan Murta
24
// Union, Intersection, XOR, A-B, B-A
25
// Contact the author if you intend to use it in commercial applications!
26
// http://www.cs.man.ac.uk/aig/staff/alan/software/
27
// Alan Murta (email: gpc@cs.man.ac.uk)
29
// [Pascal Port History] -----------------------------------------------------
31
// 23.06.2006-Milano: ptrcomp adjustments
32
// 22.02.2006-Milano: Unit port establishment
60
status = (status_move_to ,status_line_to ,status_stop );
62
gpc_vertex_ptr = ^Tgpc_vertex;
64
contour_header_type_ptr = ^contour_header_type;
65
contour_header_type = record
69
vertices : gpc_vertex_ptr;
73
conv_gpc_ptr = ^conv_gpc;
74
conv_gpc = object(vertex_source )
76
m_src_b : vertex_source_ptr;
81
m_operation : gpc_op_e;
83
m_vertex_accumulator ,
84
m_contour_accumulator : pod_deque;
88
m_result : Tgpc_polygon;
90
constructor Construct(a ,b : vertex_source_ptr; op : gpc_op_e = gpc_or );
91
destructor Destruct; virtual;
93
procedure set_source1(source : vertex_source_ptr );
94
procedure set_source2(source : vertex_source_ptr );
96
procedure operation(v : gpc_op_e );
98
// Vertex Source Interface
99
procedure rewind(path_id : unsigned ); virtual;
100
function vertex(x ,y : double_ptr ) : unsigned; virtual;
103
procedure free_polygon(p : Pgpc_polygon );
104
procedure free_result;
105
procedure free_gpc_data;
106
procedure start_contour;
107
procedure add_vertex_ (x ,y : double );
108
procedure end_contour (orientation : unsigned );
109
procedure make_polygon(p : Pgpc_polygon );
110
procedure start_extracting;
112
function next_contour : boolean;
113
function next_vertex(x ,y : double_ptr ) : boolean;
115
procedure add(src : vertex_source_ptr; p : Pgpc_polygon );
119
{ GLOBAL PROCEDURES }
123
{ LOCAL VARIABLES & CONSTANTS }
124
{ UNIT IMPLEMENTATION }
126
constructor conv_gpc.Construct;
128
m_vertex_accumulator.Construct (sizeof(Tgpc_vertex ) ,8 );
129
m_contour_accumulator.Construct(sizeof(contour_header_type ) ,6 );
134
m_status :=status_move_to;
139
fillchar(m_poly_a ,sizeof(m_poly_a ) ,0 );
140
fillchar(m_poly_b ,sizeof(m_poly_b ) ,0 );
141
fillchar(m_result ,sizeof(m_result ) ,0 );
146
destructor conv_gpc.Destruct;
150
m_vertex_accumulator.Destruct;
151
m_contour_accumulator.Destruct;
156
procedure conv_gpc.set_source1;
163
procedure conv_gpc.set_source2;
170
procedure conv_gpc.operation;
177
procedure conv_gpc.rewind;
181
m_src_a.rewind(path_id );
182
m_src_b.rewind(path_id );
184
add(m_src_a ,@m_poly_a );
185
add(m_src_b ,@m_poly_b );
189
gpc_polygon_clip(gpc.GPC_UNION ,@m_poly_a ,@m_poly_b ,@m_result );
192
gpc_polygon_clip(gpc.GPC_INT ,@m_poly_a ,@m_poly_b ,@m_result );
195
gpc_polygon_clip(gpc.GPC_XOR ,@m_poly_a ,@m_poly_b ,@m_result );
198
gpc_polygon_clip(gpc.GPC_DIFF ,@m_poly_a ,@m_poly_b ,@m_result );
201
gpc_polygon_clip(gpc.GPC_DIFF ,@m_poly_b ,@m_poly_a ,@m_result );
210
function conv_gpc.vertex;
212
if m_status = status_move_to then
215
if next_vertex(x ,y ) then
217
m_status:=status_line_to;
218
result :=path_cmd_move_to;
224
m_status:=status_stop;
225
result :=path_cmd_end_poly or path_flags_close;
233
if next_vertex(x ,y ) then
235
result:=path_cmd_line_to;
241
m_status:=status_move_to;
243
result:=path_cmd_end_poly or path_flags_close;
249
result:=path_cmd_stop;
254
procedure conv_gpc.free_polygon;
261
while i < p.num_contours do
263
agg_freemem(pointer(p.contour[i ].vertex ) ,p.contour[i].num_vertices * sizeof(Tgpc_vertex ) );
269
//agg_freemem(pointer(p.hole ) ,? );
270
agg_freemem(pointer(p.contour ) ,p.num_contours * sizeof(Tgpc_vertex_list ) );
272
fillchar(p^ ,sizeof(Tgpc_polygon ) ,0 );
277
procedure conv_gpc.free_result;
279
if m_result.contour <> NIL then
280
gpc_free_polygon(@m_result );
282
fillchar(m_result ,sizeof(m_result ) ,0 );
287
procedure conv_gpc.free_gpc_data;
289
free_polygon(@m_poly_a );
290
free_polygon(@m_poly_b );
296
procedure conv_gpc.start_contour;
298
h : contour_header_type;
301
fillchar(h ,sizeof(h ) ,0 );
302
m_contour_accumulator.add(@h );
303
m_vertex_accumulator.remove_all;
308
procedure conv_gpc.add_vertex_;
316
m_vertex_accumulator.add(@v );
321
procedure conv_gpc.end_contour;
323
h : contour_header_type_ptr;
329
if m_contour_accumulator.size <> 0 then
330
if m_vertex_accumulator.size > 2 then
332
h:=m_contour_accumulator.array_operator(m_contour_accumulator.size - 1 );
334
h.num_vertices:=m_vertex_accumulator.size;
337
// TO DO: Clarify the "holes"
338
// if is_cw(orientation ) then h.hole_flag:=1;
340
agg_getmem(pointer(h.vertices ) ,h.num_vertices * sizeof(Tgpc_vertex ) );
344
for i:=0 to h.num_vertices - 1 do
346
s:=m_vertex_accumulator.array_operator(i );
351
inc(ptrcomp(d ) ,sizeof(Tgpc_vertex ) );
357
m_vertex_accumulator.remove_last;
362
procedure conv_gpc.make_polygon;
365
h : contour_header_type_ptr;
368
pv : Pgpc_vertex_list;
373
if m_contour_accumulator.size <> 0 then
375
p.num_contours:=m_contour_accumulator.size;
377
// TO DO: Clarify the "holes"
378
// p.hole = new int[p.num_contours];
382
agg_getmem(pointer(p.contour ) ,p.num_contours * sizeof(Tgpc_vertex_list ) );
385
pv:=Pgpc_vertex_list(p.contour );
387
if p.num_contours > 0 then
388
for i:=0 to p.num_contours - 1 do
390
h:=m_contour_accumulator.array_operator(i );
392
//*ph++ = h.hole_flag;
393
pv.num_vertices:=h.num_vertices;
394
pv.vertex :=Pgpc_vertex_array(h.vertices );
396
inc(ptrcomp(pv ) ,sizeof(Tgpc_vertex_list ) );
405
procedure conv_gpc.start_extracting;
407
m_status :=status_move_to;
414
function conv_gpc.next_contour;
418
if m_contour < m_result.num_contours then
431
function conv_gpc.next_vertex;
433
vlist : Pgpc_vertex_list;
438
vlist:=@m_result.contour[m_contour ];
442
if m_vertex < vlist.num_vertices then
444
v:=@vlist.vertex[m_vertex ];
458
procedure conv_gpc.add;
460
cmd ,orientation : unsigned;
462
x ,y ,start_x ,start_y : double;
473
m_contour_accumulator.remove_all;
475
cmd:=src.vertex(@x ,@y );
477
while not is_stop(cmd ) do
479
if is_vertex(cmd ) then
481
if is_move_to(cmd ) then
485
end_contour(orientation );
504
if is_end_poly(cmd ) then
506
orientation:=get_orientation(cmd );
510
add_vertex_(start_x ,start_y );
514
cmd:=src.vertex(@x ,@y );
519
end_contour(orientation );