66#define INVERT_TRISTRIPS FALSE
75#define EQ(a, b) (fabs((a) - (b)) <= GPC_EPSILON)
77#define PREV_INDEX(i, n) ((i - 1 + n) % n)
78#define NEXT_INDEX(i, n) ((i + 1 ) % n)
80#define OPTIMAL(v, i, n) ((v[PREV_INDEX(i, n)].y != v[i].y) || \
81 (v[NEXT_INDEX(i, n)].y != v[i].y))
83#define FWD_MIN(v, i, n) ((v[PREV_INDEX(i, n)].vertex.y >= v[i].vertex.y) \
84 && (v[NEXT_INDEX(i, n)].vertex.y > v[i].vertex.y))
86#define NOT_FMAX(v, i, n) (v[NEXT_INDEX(i, n)].vertex.y > v[i].vertex.y)
88#define REV_MIN(v, i, n) ((v[PREV_INDEX(i, n)].vertex.y > v[i].vertex.y) \
89 && (v[NEXT_INDEX(i, n)].vertex.y >= v[i].vertex.y))
91#define NOT_RMAX(v, i, n) (v[PREV_INDEX(i, n)].vertex.y > v[i].vertex.y)
93#define VERTEX(e,p,s,x,y) {add_vertex(&((e)->outp[(p)]->v[(s)]), x, y); \
94 (e)->outp[(p)]->active++;}
96#define P_EDGE(d,e,p,i,j) {(d)= (e); \
97 do {(d)= (d)->prev;} while (!(d)->outp[(p)]); \
98 (i)= (d)->bot.x + (d)->dx * ((j)-(d)->bot.y);}
100#define N_EDGE(d,e,p,i,j) {(d)= (e); \
101 do {(d)= (d)->next;} while (!(d)->outp[(p)]); \
102 (i)= (d)->bot.x + (d)->dx * ((j)-(d)->bot.y);}
104#define MALLOC(p, b, s, t) {if ((b) > 0) { \
105 p= (t*)malloc(b); if (!(p)) { \
106 fprintf(stderr, "gpc malloc failure: %s\n", s); \
107 exit(0);}} else p= NULL;}
109#define FREE(p) {if (p) {free(p); (p)= NULL;}}
250static void reset_it(
it_node **it)
263static void reset_lmt(
lmt_node **lmt)
288 if (e[0].bot.x < (*b)[0].bot.x)
297 if (e[0].bot.x == (*b)[0].bot.x)
300 if (e[0].dx < (*b)[0].dx)
310 insert_bound(&((*b)->next_bound), e);
316 insert_bound(&((*b)->next_bound), e);
332 (*lmt)->first_bound= NULL;
334 return &((*lmt)->first_bound);
343 (*lmt)->first_bound= NULL;
344 (*lmt)->next= existing_node;
345 return &((*lmt)->first_bound);
350 return bound_list(&((*lmt)->next), y);
353 return &((*lmt)->first_bound);
357static void add_to_sbtree(
int *entries,
sb_tree **sbtree,
double y)
364 (*sbtree)->less= NULL;
365 (*sbtree)->more= NULL;
370 if ((*sbtree)->y > y)
373 add_to_sbtree(entries, &((*sbtree)->less), y);
377 if ((*sbtree)->y < y)
380 add_to_sbtree(entries, &((*sbtree)->more), y);
387static void build_sbt(
int *entries,
double *sbt,
sb_tree *sbtree)
390 build_sbt(entries, sbt, sbtree->
less);
391 sbt[*entries]= sbtree->
y;
394 build_sbt(entries, sbt, sbtree->
more);
398static void free_sbtree(
sb_tree **sbtree)
402 free_sbtree(&((*sbtree)->less));
403 free_sbtree(&((*sbtree)->more));
429 int c, i, min, max, num_edges, v, num_vertices;
430 int total_vertices= 0, e_index=0;
434 total_vertices+= count_optimal_vertices(p->
contour[c]);
458 add_to_sbtree(sbt_entries, sbtree,
459 edge_table[num_vertices].vertex.y);
465 for (min= 0; min < num_vertices; min++)
468 if (
FWD_MIN(edge_table, min, num_vertices))
473 while (
NOT_FMAX(edge_table, max, num_vertices))
480 e= &edge_table[e_index];
486 for (i= 0; i < num_edges; i++)
497 (e[i].top.y - e[i].bot.y);
503 e[i].
succ= ((num_edges > 1) && (i < (num_edges - 1))) ?
505 e[i].
pred= ((num_edges > 1) && (i > 0)) ? &(e[i - 1]) : NULL;
510 insert_bound(bound_list(lmt, edge_table[min].vertex.y), e);
515 for (min= 0; min < num_vertices; min++)
518 if (
REV_MIN(edge_table, min, num_vertices))
523 while (
NOT_RMAX(edge_table, max, num_vertices))
530 e= &edge_table[e_index];
536 for (i= 0; i < num_edges; i++)
547 (e[i].top.y - e[i].bot.y);
553 e[i].
succ= ((num_edges > 1) && (i < (num_edges - 1))) ?
555 e[i].
pred= ((num_edges > 1) && (i > 0)) ? &(e[i - 1]) : NULL;
560 insert_bound(bound_list(lmt, edge_table[min].vertex.y), e);
581 if (edge->
xb < (*aet)->xb)
591 if (edge->
xb == (*aet)->xb)
594 if (edge->
dx < (*aet)->dx)
605 add_edge_to_aet(&((*aet)->next), edge, *aet);
611 add_edge_to_aet(&((*aet)->next), edge, *aet);
635 if ((*it)->point.y > y)
644 (*it)->
next= existing_node;
648 add_intersection(&((*it)->next), edge0, edge1, x, y);
671 den= ((*st)->xt - (*st)->xb) - (edge->
xt - edge->
xb);
674 if ((edge->
xt >= (*st)->xt) || (edge->
dx == (*st)->dx) ||
675 (fabs(den) <= DBL_EPSILON))
684 (*st)->prev= existing_node;
689 r= (edge->
xb - (*st)->xb) / den;
690 x= (*st)->xb + r * ((*st)->xt - (*st)->xb);
694 add_intersection(it, (*st)->edge, edge, x, y);
697 add_st_edge(&((*st)->prev), it, edge, dy);
703static void build_intersection_table(
it_node **it,
edge_node *aet,
double dy)
713 for (edge= aet; edge; edge= edge->
next)
717 add_st_edge(&st, it, edge, dy);
734 for (nc= 0; polygon; polygon= polygon->
next)
763static void add_left(
polygon_node *p,
double x,
double y)
795 for (target= p->
proxy; list; list= list->
next)
797 if (list->
proxy == target)
807static void add_right(
polygon_node *p,
double x,
double y)
839 for (target= p->
proxy; list; list= list->
next)
841 if (list->
proxy == target)
870 (*p)->next= existing_min;
885 for (total= 0; tn; tn= tn->
next)
892static void add_vertex(
vertex_node **t,
double x,
double y)
903 add_vertex(&((*t)->next), x, y);
914 (*tn)->v[
LEFT]= NULL;
915 (*tn)->v[
RIGHT]= NULL;
917 add_vertex(&((*tn)->v[
LEFT]), x, y);
922 new_tristrip(&((*tn)->next), edge, x, y);
937 box[c].
xmin= DBL_MAX;
938 box[c].
ymin= DBL_MAX;
939 box[c].
xmax= -DBL_MAX;
940 box[c].
ymax= -DBL_MAX;
961 bbox *s_bbox, *c_bbox;
962 int s, c, *o_table, overlap;
964 s_bbox= create_contour_bboxes(subj);
965 c_bbox= create_contour_bboxes(clip);
968 "overlap table creation",
int);
974 (!((s_bbox[s].xmax < c_bbox[c].xmin) ||
975 (s_bbox[s].xmin > c_bbox[c].xmax))) &&
976 (!((s_bbox[s].
ymax < c_bbox[c].
ymin) ||
977 (s_bbox[s].
ymin > c_bbox[c].
ymax)));
1036 "hole flag array creation",
int);
1043 if (read_hole_flags)
1044 fscanf(fp,
"%d", &(p->
hole[c]));
1066 if (write_hole_flags)
1067 fprintf(fp,
"%d\n", p->
hole[c]);
1070 fprintf(fp,
"% .*lf % .*lf\n",
1079 int *extended_hole, c, v;
1084 *
sizeof(
int),
"contour hole addition",
int);
1093 extended_hole[c]= p->
hole[c];
1094 extended_contour[c]= p->
contour[c];
1099 extended_hole[c]= hole;
1104 extended_contour[c].vertex[v]= new_contour->
vertex[v];
1112 p->
hole= extended_hole;
1121 it_node *it= NULL, *intersect;
1122 edge_node *edge, *prev_edge, *next_edge, *succ_edge, *e0, *e1;
1123 edge_node *aet= NULL, *c_heap= NULL, *s_heap= NULL;
1125 polygon_node *out_poly= NULL, *p, *q, *poly, *npoly, *cf= NULL;
1128 int in[2], exists[2], parity[2]= {
LEFT,
LEFT};
1129 int c, v, contributing, search, scanbeam= 0, sbt_entries= 0;
1130 int vclass, bl, br, tl, tr;
1131 double *sbt= NULL, xb, px, yb, yt, dy, ix, iy;
1147 minimax_test(subj, clip, op);
1151 s_heap= build_lmt(&lmt, &sbtree, &sbt_entries, subj,
SUBJ, op);
1153 c_heap= build_lmt(&lmt, &sbtree, &sbt_entries, clip,
CLIP, op);
1168 MALLOC(sbt, sbt_entries *
sizeof(
double),
"sbt creation",
double);
1169 build_sbt(&scanbeam, sbt, sbtree);
1171 free_sbtree(&sbtree);
1186 while (scanbeam < sbt_entries)
1189 yb= sbt[scanbeam++];
1190 if (scanbeam < sbt_entries)
1201 if (local_min->y == yb)
1204 for (edge= local_min->first_bound; edge; edge= edge->
next_bound)
1205 add_edge_to_aet(&aet, edge, NULL);
1207 local_min= local_min->next;
1223 for (next_edge= aet->
next; next_edge; next_edge= next_edge->
next)
1233 if (
EQ(e0->
xb, next_edge->
xb) &&
EQ(e0->
dx, next_edge->
dx)
1234 && (e0->
top.
y != yb))
1253 for (edge= aet; edge; edge= edge->
next)
1271 contributing= (exists[
CLIP] && (parity[
SUBJ] || horiz[
SUBJ]))
1274 && (parity[
CLIP] == parity[
SUBJ]));
1285 contributing= exists[
CLIP] || exists[
SUBJ];
1296 contributing= (exists[
CLIP] && (!parity[
SUBJ] || horiz[
SUBJ]))
1299 && (parity[
CLIP] == parity[
SUBJ]));
1319 [((exists[
CLIP] - 1) << 1) + parity[
CLIP]];
1323 [((exists[
SUBJ] - 1) << 1) + parity[
SUBJ]];
1325 vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
1335 add_local_min(&out_poly, edge, xb, yb);
1342 add_right(cf, xb, yb);
1356 add_left(cf, xb, yb);
1359 merge_right(cf, edge->
outp[
BELOW], out_poly);
1365 add_left(cf, xb, yb);
1380 add_right(cf, xb, yb);
1383 merge_left(cf, edge->
outp[
BELOW], out_poly);
1390 add_right(cf, xb, yb);
1393 merge_left(cf, edge->
outp[
BELOW], out_poly);
1395 add_local_min(&out_poly, edge, xb, yb);
1401 add_left(cf, xb, yb);
1404 merge_right(cf, edge->
outp[
BELOW], out_poly);
1406 add_local_min(&out_poly, edge, xb, yb);
1410 if (edge->
bot.
y == yb)
1416 if (edge->
bot.
y == yb)
1429 for (edge= aet; edge; edge= edge->
next)
1431 if (edge->
top.
y == yb)
1433 prev_edge= edge->
prev;
1434 next_edge= edge->
next;
1436 prev_edge->
next= next_edge;
1440 next_edge->
prev= prev_edge;
1449 if (prev_edge->
prev)
1457 if (edge->
top.
y == yt)
1464 if (scanbeam < sbt_entries)
1468 build_intersection_table(&it, aet, dy);
1471 for (intersect= it; intersect; intersect= intersect->
next)
1473 e0= intersect->ie[0];
1474 e1= intersect->ie[1];
1482 ix= intersect->point.x;
1483 iy= intersect->point.y + yb;
1530 vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
1535 add_local_min(&out_poly, e0, ix, iy);
1541 add_right(p, ix, iy);
1549 add_left(q, ix, iy);
1557 add_left(p, ix, iy);
1558 merge_right(p, q, out_poly);
1564 add_local_min(&out_poly, e0, ix, iy);
1570 add_left(p, ix, iy);
1578 add_right(q, ix, iy);
1586 add_right(p, ix, iy);
1587 merge_left(p, q, out_poly);
1595 add_right(p, ix, iy);
1596 merge_left(p, q, out_poly);
1597 add_local_min(&out_poly, e0, ix, iy);
1604 add_left(p, ix, iy);
1605 merge_right(p, q, out_poly);
1606 add_local_min(&out_poly, e0, ix, iy);
1626 prev_edge= e0->
prev;
1627 next_edge= e1->
next;
1629 next_edge->
prev= e0;
1636 prev_edge= prev_edge->
prev;
1660 e0->
next= next_edge;
1664 for (edge= aet; edge; edge= next_edge)
1666 next_edge= edge->
next;
1667 succ_edge= edge->
succ;
1669 if ((edge->
top.
y == yt) && succ_edge)
1676 prev_edge= edge->
prev;
1678 prev_edge->
next= succ_edge;
1682 next_edge->
prev= succ_edge;
1683 succ_edge->
prev= prev_edge;
1684 succ_edge->
next= next_edge;
1707 *
sizeof(
int),
"hole flag table creation",
int);
1712 for (poly= out_poly; poly; poly= npoly)
1717 result->
hole[c]= poly->proxy->hole;
1724 for (vtx= poly->proxy->v[
LEFT]; vtx; vtx= nv)
1739 for (poly= out_poly; poly; poly= npoly)
1781 it_node *it= NULL, *intersect;
1782 edge_node *edge, *prev_edge, *next_edge, *succ_edge, *e0, *e1;
1783 edge_node *aet= NULL, *c_heap= NULL, *s_heap= NULL, *cf;
1789 int in[2], exists[2], parity[2]= {
LEFT,
LEFT};
1790 int s, v, contributing, search, scanbeam= 0, sbt_entries= 0;
1791 int vclass, bl, br, tl, tr;
1792 double *sbt= NULL, xb, px, nx, yb, yt, dy, ix, iy;
1800 result->
strip= NULL;
1807 minimax_test(subj, clip, op);
1811 s_heap= build_lmt(&lmt, &sbtree, &sbt_entries, subj,
SUBJ, op);
1813 c_heap= build_lmt(&lmt, &sbtree, &sbt_entries, clip,
CLIP, op);
1819 result->
strip= NULL;
1827 MALLOC(sbt, sbt_entries *
sizeof(
double),
"sbt creation",
double);
1828 build_sbt(&scanbeam, sbt, sbtree);
1830 free_sbtree(&sbtree);
1839 while (scanbeam < sbt_entries)
1842 yb= sbt[scanbeam++];
1843 if (scanbeam < sbt_entries)
1854 if (local_min->y == yb)
1857 for (edge= local_min->first_bound; edge; edge= edge->
next_bound)
1858 add_edge_to_aet(&aet, edge, NULL);
1860 local_min= local_min->next;
1876 for (next_edge= aet->
next; next_edge; next_edge= next_edge->
next)
1886 if (
EQ(e0->
xb, next_edge->
xb) &&
EQ(e0->
dx, next_edge->
dx)
1887 && (e0->
top.
y != yb))
1906 for (edge= aet; edge; edge= edge->
next)
1924 contributing= (exists[
CLIP] && (parity[
SUBJ] || horiz[
SUBJ]))
1927 && (parity[
CLIP] == parity[
SUBJ]));
1938 contributing= exists[
CLIP] || exists[
SUBJ];
1949 contributing= (exists[
CLIP] && (!parity[
SUBJ] || horiz[
SUBJ]))
1952 && (parity[
CLIP] == parity[
SUBJ]));
1972 [((exists[
CLIP] - 1) << 1) + parity[
CLIP]];
1976 [((exists[
SUBJ] - 1) << 1) + parity[
SUBJ]];
1978 vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
1987 new_tristrip(&tlist, edge, xb, yb);
2010 if (cf->bot.y != yb)
2012 new_tristrip(&tlist, cf, cf->xb, yb);
2018 new_tristrip(&tlist, edge, xb, yb);
2025 if (cf->bot.y != yb)
2027 new_tristrip(&tlist, cf, cf->xb, yb);
2047 new_tristrip(&tlist, edge, xb, yb);
2051 if (edge->
bot.
y == yb)
2061 if (cf->bot.y == yb)
2067 if (edge->
bot.
y == yb)
2089 for (edge= aet; edge; edge= edge->
next)
2091 if (edge->
top.
y == yb)
2093 prev_edge= edge->
prev;
2094 next_edge= edge->
next;
2096 prev_edge->
next= next_edge;
2100 next_edge->
prev= prev_edge;
2109 if (prev_edge->
prev)
2117 if (edge->
top.
y == yt)
2124 if (scanbeam < sbt_entries)
2128 build_intersection_table(&it, aet, dy);
2131 for (intersect= it; intersect; intersect= intersect->
next)
2133 e0= intersect->ie[0];
2134 e1= intersect->ie[1];
2142 ix= intersect->point.x;
2143 iy= intersect->point.y + yb;
2190 vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
2195 new_tristrip(&tlist, e1, ix, iy);
2231 new_tristrip(&tlist, prev_edge, px, iy);
2234 new_tristrip(&tlist, e0, ix, iy);
2267 new_tristrip(&tlist, prev_edge, px, iy);
2281 new_tristrip(&tlist, prev_edge, px, iy);
2286 new_tristrip(&tlist, e0, ix, iy);
2295 new_tristrip(&tlist, e1, ix, iy);
2315 prev_edge= e0->
prev;
2316 next_edge= e1->
next;
2325 prev_edge= prev_edge->
prev;
2349 e0->
next= next_edge;
2353 for (edge= aet; edge; edge= next_edge)
2355 next_edge= edge->
next;
2356 succ_edge= edge->
succ;
2358 if ((edge->
top.
y == yt) && succ_edge)
2365 prev_edge= edge->
prev;
2367 prev_edge->
next= succ_edge;
2371 next_edge->
prev= succ_edge;
2372 succ_edge->
prev= prev_edge;
2373 succ_edge->
next= next_edge;
2390 result->
strip= NULL;
2398 for (tn= tlist; tn; tn= tnn)
2445 for (lt= tn->v[
LEFT]; lt; lt= ltn)
2450 for (rt= tn->v[
RIGHT]; rt; rt=rtn)
void gpc_free_tristrip(gpc_tristrip *t)
void gpc_polygon_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, gpc_polygon *result)
#define NOT_FMAX(v, i, n)
void gpc_write_polygon(FILE *fp, int write_hole_flags, gpc_polygon *p)
#define N_EDGE(d, e, p, i, j)
#define VERTEX(e, p, s, x, y)
void gpc_read_polygon(FILE *fp, int read_hole_flags, gpc_polygon *p)
void gpc_tristrip_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, gpc_tristrip *result)
#define P_EDGE(d, e, p, i, j)
struct v_shape vertex_node
void gpc_free_polygon(gpc_polygon *p)
const h_state next_h_state[3][6]
struct p_shape polygon_node
void gpc_add_contour(gpc_polygon *p, gpc_vertex_list *new_contour, int hole)
struct sbt_t_shape sb_tree
struct edge_shape edge_node
struct lmt_shape lmt_node
void gpc_polygon_to_tristrip(gpc_polygon *s, gpc_tristrip *t)
#define MALLOC(p, b, s, t)
#define NOT_RMAX(v, i, n)
struct edge_shape * next_bound
gpc_vertex_list * contour
struct sbt_t_shape * more
struct sbt_t_shape * less