Jspice3
polyclip.c
Go to the documentation of this file.
1 /*************************************************************************
2  MFB graphics and miscellaneous library
3  Copyright (c) Stephen R. Whiteley 1994
4  Author: Stephen R. Whiteley
5  *************************************************************************/
6 
7 #include "spice.h"
8 #include "sced.h"
9 #include "scedmacs.h"
10 
11 /* A new polygon clipping routine. Unlike the old routine, this one
12  * keeps track of severed polygons by means of a linked list.
13  * First call PolygonClip(), which will perform clipping and
14  * create a list of polygons. The polygons are then extracted with
15  * NextPolygon() until 0 is returned. A suitably large xy buffer
16  * must be supplied in the POLYGON structure passed to NextPolygon().
17  */
18 
19 /* Undefine DO_FLOAT below if there is no chance of integer overflow,
20  * avoiding floating point for efficiency.
21  */
22 #define DO_FLOAT
23 
24 /* We represent individual polygons with a circular doubly linked list */
25 struct pair {
26  long pa_x,pa_y;
27  struct pair *pa_next;
28  struct pair *pa_prev;
29 };
30 
31 /* List of circularly linked polygons */
32 struct plist {
33  struct pair *pl_pair;
34  struct pair *pl_start;
35 };
36 
37 static struct plist *Polybuf; /* head of polygon list */
38 static struct plist *Newpoly; /* free structure to allocate */
39 static struct plist *Polycurrent; /* current polygon to return */
40 static int Numpolys; /* size of poly storage */
41 
42 static struct pair *Linkbuf; /* polygon point storage */
43 static struct pair *Newlink; /* free structure to allocate */
44 static int Numlinks; /* size of link storage */
45 
46 
47 #ifdef __STDC__
48 static void clip_right(long);
49 static void clip_left(long);
50 static void clip_bottom(long);
51 static void clip_top(long);
52 static void linkpolys(struct plist*,int);
53 static int polycmpX(const void*,const void*);
54 static int polycmpY(const void*,const void*);
55 static void newlink(void);
56 static void newpoly(void);
57 #else
58 static void clip_right();
59 static void clip_left();
60 static void clip_bottom();
61 static void clip_top();
62 static void linkpolys();
63 static int polycmpX();
64 static int polycmpY();
65 static void newlink();
66 static void newpoly();
67 #endif
68 
69 
70 void
71 PolygonClip(poly,left,bottom,right,top)
72 
73 POLYGON *poly;
74 long left, bottom, right, top;
75 {
76  struct plist *pl;
77  struct pair *pa;
78  int i, n;
79  long tmp;
80 
81  if (left > right) {
82  tmp = left;
83  left = right;
84  right = tmp;
85  }
86  if (bottom > top) {
87  tmp = bottom;
88  bottom = top;
89  top = tmp;
90  }
91 
92  if (Linkbuf == NULL)
93  newlink();
94  if (Polybuf == NULL)
95  newpoly();
96 
97  Newlink = Linkbuf;
98  Newpoly = Polybuf;
99 
100  n = (poly->nvertices << 1) - 2;
101  for (i = 0; i < n; i += 2) {
102  Newlink->pa_x = poly->xy[i];
103  Newlink->pa_y = poly->xy[i+1];
104  Newlink->pa_prev = Newlink-1;
105  Newlink->pa_next = Newlink+1;
106  newlink();
107  }
108  pa = Linkbuf;
109 
110  if (pa->pa_x != poly->xy[i] || pa->pa_y != poly->xy[i+1]) {
111  Newlink->pa_x = poly->xy[i];
112  Newlink->pa_y = poly->xy[i+1];
113  Newlink->pa_prev = Newlink-1;
114  Newlink->pa_next = Newlink+1;
115  newlink();
116  }
117  Newlink--;
118  Newlink->pa_next = pa;
119  pa->pa_prev = Newlink;
120  Newlink++;
121 
122  Newpoly->pl_pair = pa;
123  newpoly();
124 
125  clip_left(left);
126  clip_bottom(bottom);
127  clip_right(right);
128  clip_top(top);
129 
130  Polycurrent = Polybuf;
131 }
132 
133 
134 int
136 
137 POLYGON *p;
138 {
139  long *xy;
140  int i;
141  struct pair *pp, *pa;
142 
143  for (;;) {
144  xy = (long*)p->xy;
145  i = 1;
146  if (Polycurrent == Newpoly) {
147  Newlink = Linkbuf;
148  Newpoly = Polybuf;
149  Polycurrent = Newpoly;
150  return (0);
151  }
152  pp = pa = Polycurrent->pl_pair;
153  if (pp) {
154  *xy++ = pp->pa_x;
155  *xy++ = pp->pa_y;
156 
157  for (pp = pp->pa_next; ; pp = pp->pa_next) {
158  i++;
159  *xy++ = pp->pa_x;
160  *xy++ = pp->pa_y;
161  if (pp == pa) break;
162  }
163  }
164 
165  Polycurrent++;
166  if (i >= 4)
167  break;
168  }
169  p->nvertices = i;
170  return (1);
171 }
172 
173 
174 static void
176 
177 long right;
178 {
179  struct pair *pa, *pp, *pfirst, *plast, *pnext;
180  struct plist *list, *end, *pointer;
181  long x, y, xnext, ynext;
182 
183  end = Newpoly;
184  for (list = Polybuf; list < end; list++) {
185  pointer = Newpoly;
186  pa = list->pl_pair;
187  /*
188  * First, find a vertex outside of the clipping
189  * region.
190  */
191 
192  for (pp = pa;;) {
193  if (pp->pa_x > right)
194  break;
195  pp = pp->pa_next;
196  if (pp == pa) {
197  /* no clipping needed */
198  Newpoly->pl_pair = pa;
199  newpoly();
200  goto next;
201  }
202  }
203  /* start with an "outside" point */
204 
205  for (pa = pp;;) {
206  x = pp->pa_x;
207  y = pp->pa_y;
208  pnext = pp->pa_next;
209  xnext = pnext->pa_x;
210  ynext = pnext->pa_y;
211 
212  if (xnext <= right && x > right) {
213  /* poly edge crosses bounding clip line */
214 #ifdef DO_FLOAT
215  y += (ynext - y)*(((double)(right - x))/(xnext - x));
216 #else
217  y += ((right-x)*(ynext-y))/(xnext-x);
218 #endif
219  x = right;
220 
221  if (x != xnext || y != ynext) {
222  pfirst = Newlink;
223  pfirst->pa_x = x;
224  pfirst->pa_y = y;
225  pfirst->pa_prev = NULL;
226  newlink();
227  pp = pnext;
228  pfirst->pa_next = pp;
229  pp->pa_prev = pfirst;
230  }
231  else {
232  pp = pnext;
233  pfirst = pnext;
234  pfirst->pa_prev = NULL;
235  }
236 
237  /* walk along inside points, find the last one */
238  for (;;) {
239  if (pp->pa_x > right) {
240  pnext = pp;
241  pp = pp->pa_prev;
242  break;
243  }
244  pp = pp->pa_next;
245  }
246  x = pp->pa_x;
247  y = pp->pa_y;
248  xnext = pnext->pa_x;
249  ynext = pnext->pa_y;
250 #ifdef DO_FLOAT
251  y += (ynext - y)*(((double)(right - x))/(xnext - x));
252 #else
253  y += ((right-x)*(ynext-y))/(xnext-x);
254 #endif
255  x = right;
256 
257  if (x != xnext || y != ynext) {
258  plast = Newlink;
259  plast->pa_x = x;
260  plast->pa_y = y;
261  pp->pa_next = plast;
262  plast->pa_prev = pp;
263  plast->pa_next = NULL;
264  newlink();
265  }
266  else {
267  plast = pp;
268  plast->pa_next = NULL;
269  }
270  if (pfirst->pa_next != plast) {
271 
272  /* note that we are saving poly fragments */
273  Newpoly->pl_pair = pfirst;
274  Newpoly->pl_start = pfirst;
275  newpoly();
276  Newpoly->pl_pair = plast;
277  Newpoly->pl_start = pfirst;
278  newpoly();
279  }
280  }
281  pp = pnext;
282  if (pp == pa)
283  break;
284  }
285  if (pointer < Newpoly)
286  linkpolys(pointer,'Y');
287 next:
288  ;
289  }
290  for (list = end, end = Polybuf; list < Newpoly; list++) {
291  if (list->pl_pair) {
292  end->pl_pair = list->pl_pair;
293  end->pl_start = NULL;
294  end++;
295  }
296  }
297  Newpoly = end;
298 }
299 
300 
301 static void
303 
304 long left;
305 {
306  struct pair *pa, *pp, *pfirst, *plast, *pnext;
307  struct plist *list, *end, *pointer;
308  long x, y, xnext, ynext;
309 
310  end = Newpoly;
311  for (list = Polybuf; list < end; list++) {
312  pointer = Newpoly;
313  pa = list->pl_pair;
314  /*
315  * First, find a vertex outside of the clipping
316  * region.
317  */
318 
319  for (pp = pa;;) {
320  if (pp->pa_x < left)
321  break;
322  pp = pp->pa_next;
323  if (pp == pa) {
324  /* no clipping needed */
325  Newpoly->pl_pair = pa;
326  newpoly();
327  goto next;
328  }
329  }
330  /* start with an "outside" point */
331 
332  for (pa = pp;;) {
333  x = pp->pa_x;
334  y = pp->pa_y;
335  pnext = pp->pa_next;
336  xnext = pnext->pa_x;
337  ynext = pnext->pa_y;
338 
339  if (xnext >= left && x < left) {
340  /* poly edge crosses bounding clip line */
341 #ifdef DO_FLOAT
342  y += (ynext - y)*(((double)(left - x))/(xnext - x));
343 #else
344  y += ((left - x) * (ynext - y))/(xnext - x);
345 #endif
346  x = left;
347 
348  if (x != xnext || y != ynext) {
349  pfirst = Newlink;
350  pfirst->pa_x = x;
351  pfirst->pa_y = y;
352  pfirst->pa_prev = NULL;
353  newlink();
354  pp = pnext;
355  pfirst->pa_next = pp;
356  pp->pa_prev = pfirst;
357  }
358  else {
359  pp = pnext;
360  pfirst = pnext;
361  pfirst->pa_prev = NULL;
362  }
363 
364  /* walk along inside points, find the last one */
365  for (;;) {
366  if (pp->pa_x < left) {
367  pnext = pp;
368  pp = pp->pa_prev;
369  break;
370  }
371  pp = pp->pa_next;
372  }
373  x = pp->pa_x;
374  y = pp->pa_y;
375  xnext = pnext->pa_x;
376  ynext = pnext->pa_y;
377 #ifdef DO_FLOAT
378  y += (ynext - y)*(((double)(left - x))/(xnext - x));
379 #else
380  y += ((left - x) * (ynext - y))/(xnext - x);
381 #endif
382  x = left;
383 
384  if (x != xnext || y != ynext) {
385  plast = Newlink;
386  plast->pa_x = x;
387  plast->pa_y = y;
388  pp->pa_next = plast;
389  plast->pa_prev = pp;
390  plast->pa_next = NULL;
391  newlink();
392  }
393  else {
394  plast = pp;
395  plast->pa_next = NULL;
396  }
397  if (pfirst->pa_next != plast) {
398 
399  /* note that we are saving poly fragments */
400  Newpoly->pl_pair = pfirst;
401  Newpoly->pl_start = pfirst;
402  newpoly();
403  Newpoly->pl_pair = plast;
404  Newpoly->pl_start = pfirst;
405  newpoly();
406  }
407  }
408  pp = pnext;
409  if (pp == pa)
410  break;
411  }
412  if (pointer < Newpoly)
413  linkpolys(pointer,'Y');
414 next:
415  ;
416  }
417  for (list = end, end = Polybuf; list < Newpoly; list++) {
418  if (list->pl_pair) {
419  end->pl_pair = list->pl_pair;
420  end->pl_start = NULL;
421  end++;
422  }
423  }
424  Newpoly = end;
425 }
426 
427 
428 static void
429 clip_bottom(bottom)
430 
431 long bottom;
432 {
433  struct pair *pa, *pp, *pfirst, *plast, *pnext;
434  struct plist *list, *end, *pointer;
435  long x, y, xnext, ynext;
436 
437  end = Newpoly;
438  for (list = Polybuf; list < end; list++) {
439  pointer = Newpoly;
440  pa = list->pl_pair;
441  /*
442  * First, find a vertex outside of the clipping
443  * region.
444  */
445 
446  for (pp = pa;;) {
447  if (pp->pa_y < bottom)
448  break;
449  pp = pp->pa_next;
450  if (pp == pa) {
451  /* no clipping needed */
452  Newpoly->pl_pair = pa;
453  newpoly();
454  goto next;
455  }
456  }
457  /* start with an "outside" point */
458 
459  for (pa = pp;;) {
460  x = pp->pa_x;
461  y = pp->pa_y;
462  pnext = pp->pa_next;
463  xnext = pnext->pa_x;
464  ynext = pnext->pa_y;
465 
466  if (ynext >= bottom && y < bottom) {
467  /* poly edge crosses bounding clip line */
468 #ifdef DO_FLOAT
469  x += (xnext - x)*(((double)(bottom - y))/(ynext - y));
470 #else
471  x += ((bottom - y) * (xnext - x))/(ynext - y);
472 #endif
473  y = bottom;
474 
475  if (x != xnext || y != ynext) {
476  pfirst = Newlink;
477  pfirst->pa_x = x;
478  pfirst->pa_y = y;
479  pfirst->pa_prev = NULL;
480  newlink();
481  pp = pnext;
482  pfirst->pa_next = pp;
483  pp->pa_prev = pfirst;
484  }
485  else {
486  pp = pnext;
487  pfirst = pnext;
488  pfirst->pa_prev = NULL;
489  }
490 
491  /* walk along inside points, find the last one */
492  for (;;) {
493  if (pp->pa_y < bottom) {
494  pnext = pp;
495  pp = pp->pa_prev;
496  break;
497  }
498  pp = pp->pa_next;
499  }
500  x = pp->pa_x;
501  y = pp->pa_y;
502  xnext = pnext->pa_x;
503  ynext = pnext->pa_y;
504 #ifdef DO_FLOAT
505  x += (xnext - x)*(((double)(bottom - y))/(ynext - y));
506 #else
507  x += ((bottom - y) * (xnext - x))/(ynext - y);
508 #endif
509  y = bottom;
510 
511  if (x != xnext || y != ynext) {
512  plast = Newlink;
513  plast->pa_x = x;
514  plast->pa_y = y;
515  pp->pa_next = plast;
516  plast->pa_prev = pp;
517  plast->pa_next = NULL;
518  newlink();
519  }
520  else {
521  plast = pp;
522  plast->pa_next = NULL;
523  }
524  if (pfirst->pa_next != plast) {
525 
526  /* note that we are saving poly fragments */
527  Newpoly->pl_pair = pfirst;
528  Newpoly->pl_start = pfirst;
529  newpoly();
530  Newpoly->pl_pair = plast;
531  Newpoly->pl_start = pfirst;
532  newpoly();
533  }
534  }
535  pp = pnext;
536  if (pp == pa)
537  break;
538  }
539  if (pointer < Newpoly)
540  linkpolys(pointer,'X');
541 next:
542  ;
543  }
544  for (list = end, end = Polybuf; list < Newpoly; list++) {
545  if (list->pl_pair) {
546  end->pl_pair = list->pl_pair;
547  end->pl_start = NULL;
548  end++;
549  }
550  }
551  Newpoly = end;
552 }
553 
554 
555 static void
557 
558 long top;
559 {
560  struct pair *pa, *pp, *pfirst, *plast, *pnext;
561  struct plist *list, *end, *pointer;
562  long x, y, xnext, ynext;
563 
564  end = Newpoly;
565  for (list = Polybuf; list < end; list++) {
566  pointer = Newpoly;
567  pa = list->pl_pair;
568  /*
569  * First, find a vertex outside of the clipping
570  * region.
571  */
572 
573  for (pp = pa;;) {
574  if (pp->pa_y > top)
575  break;
576  pp = pp->pa_next;
577  if (pp == pa) {
578  /* no clipping needed */
579  Newpoly->pl_pair = pa;
580  newpoly();
581  goto next;
582  }
583  }
584  /* start with an "outside" point */
585 
586  for (pa = pp;;) {
587  x = pp->pa_x;
588  y = pp->pa_y;
589  pnext = pp->pa_next;
590  xnext = pnext->pa_x;
591  ynext = pnext->pa_y;
592 
593  if (ynext <= top && y > top) {
594  /* poly edge crosses bounding clip line */
595 #ifdef DO_FLOAT
596  x += (xnext - x)*(((double)(top - y))/(ynext - y));
597 #else
598  x += ((top - y) * (xnext - x))/(ynext - y);
599 #endif
600  y = top;
601 
602  if (x != xnext || y != ynext) {
603  pfirst = Newlink;
604  pfirst->pa_x = x;
605  pfirst->pa_y = y;
606  pfirst->pa_prev = NULL;
607  newlink();
608  pp = pnext;
609  pfirst->pa_next = pp;
610  pp->pa_prev = pfirst;
611  }
612  else {
613  pp = pnext;
614  pfirst = pnext;
615  pfirst->pa_prev = NULL;
616  }
617 
618  /* walk along inside points, find the last one */
619  for (;;) {
620  if (pp->pa_y > top) {
621  pnext = pp;
622  pp = pp->pa_prev;
623  break;
624  }
625  pp = pp->pa_next;
626  }
627  x = pp->pa_x;
628  y = pp->pa_y;
629  xnext = pnext->pa_x;
630  ynext = pnext->pa_y;
631 #ifdef DO_FLOAT
632  x += (xnext - x)*(((double)(top - y))/(ynext - y));
633 #else
634  x += ((top - y) * (xnext - x))/(ynext - y);
635 #endif
636  y = top;
637 
638  if (x != xnext || y != ynext) {
639  plast = Newlink;
640  plast->pa_x = x;
641  plast->pa_y = y;
642  pp->pa_next = plast;
643  plast->pa_prev = pp;
644  plast->pa_next = NULL;
645  newlink();
646  }
647  else {
648  plast = pp;
649  plast->pa_next = NULL;
650  }
651  if (pfirst->pa_next != plast) {
652 
653  /* note that we are saving poly fragments */
654  Newpoly->pl_pair = pfirst;
655  Newpoly->pl_start = pfirst;
656  newpoly();
657  Newpoly->pl_pair = plast;
658  Newpoly->pl_start = pfirst;
659  newpoly();
660  }
661  }
662  pp = pnext;
663  if (pp == pa)
664  break;
665  }
666  if (pointer < Newpoly)
667  linkpolys(pointer,'X');
668 next:
669  ;
670  }
671  for (list = end, end = Polybuf; list < Newpoly; list++) {
672  if (list->pl_pair) {
673  end->pl_pair = list->pl_pair;
674  end->pl_start = NULL;
675  end++;
676  }
677  }
678  Newpoly = end;
679 }
680 
681 
682 static void
683 linkpolys(base,XorY)
684 
685 struct plist *base;
686 int XorY;
687 {
688  struct plist tmp, *b, *bb;
689 
690  if (XorY == 'X')
691  qsort(base,Newpoly-base,sizeof(struct plist),polycmpX);
692  else
693  qsort(base,Newpoly-base,sizeof(struct plist),polycmpY);
694 
695  for (b = base; b < Newpoly; b += 2) {
696  /* link adjacent vertices */
697  if (b->pl_pair == b->pl_start) {
698  if ((b+1)->pl_pair == (b+1)->pl_start) {
699  tmp = *(b+1);
700  *(b+1) = *(b+2);
701  *(b+2) = tmp;
702  }
703  b->pl_pair->pa_prev = (b+1)->pl_pair;
704  (b+1)->pl_pair->pa_next = b->pl_pair;
705  (b+1)->pl_pair = NULL;
706  if (b->pl_start != (b+1)->pl_start) {
707  for (bb = b+2; bb < Newpoly; bb++) {
708  if (bb->pl_start == b->pl_start) {
709  bb->pl_start = (b+1)->pl_start;
710  break;
711  }
712  }
713  b->pl_pair = NULL;
714  }
715  }
716  else {
717  if ((b+1)->pl_pair != (b+1)->pl_start) {
718  tmp = *(b+1);
719  *(b+1) = *(b+2);
720  *(b+2) = tmp;
721  }
722  b->pl_pair->pa_next = (b+1)->pl_pair;
723  (b+1)->pl_pair->pa_prev = b->pl_pair;
724  (b+1)->pl_pair = NULL;
725  if (b->pl_start != (b+1)->pl_start) {
726  for (bb = b+2; bb < Newpoly; bb++) {
727  if (bb->pl_start == (b+1)->pl_start) {
728  bb->pl_start = b->pl_start;
729  break;
730  }
731  }
732  b->pl_pair = NULL;
733  }
734  }
735  }
736 }
737 
738 
739 static int
740 polycmpX(p1,p2)
741 
742 #ifdef __STDC__
743 const void *p1, *p2;
744 #else
745 char *p1, *p2;
746 #endif
747 {
748  return (((struct plist *)p1)->pl_pair->pa_x -
749  ((struct plist *)p2)->pl_pair->pa_x);
750 }
751 
752 
753 static int
754 polycmpY(p1,p2)
755 
756 #ifdef __STDC__
757 const void *p1, *p2;
758 #else
759 char *p1, *p2;
760 #endif
761 {
762  return (((struct plist *)p1)->pl_pair->pa_y -
763  ((struct plist *)p2)->pl_pair->pa_y);
764 }
765 
766 
767 /* The next two routines support dynamic memory. Structures are expanded
768  * as necessary but never freed.
769  */
770 
771 static void
773 
774 {
775  struct pair *oldbuf;
776  int i, num;
777 
778  if (Linkbuf == NULL) {
779  Linkbuf = (struct pair *)malloc(400*sizeof(struct pair));
780  if (Linkbuf == NULL)
781  MallocFailed();
782  Newlink = Linkbuf;
783  Numlinks = 400;
784  return;
785  }
786 
787  Newlink++;
788  num = Newlink - Linkbuf;
789  if (num > Numlinks) {
790  Numlinks = num + 200;
791  oldbuf = Linkbuf;
792  Linkbuf = (struct pair *)
793  realloc((char*)Linkbuf,Numlinks*sizeof(struct pair));
794  if (Linkbuf == NULL)
795  MallocFailed();
796  Newlink = Linkbuf + num;
797  for (i = 0; i < num; i++) {
798  (Linkbuf+i)->pa_next = ((Linkbuf+i)->pa_next - oldbuf) + Linkbuf;
799  (Linkbuf+i)->pa_prev = ((Linkbuf+i)->pa_prev - oldbuf) + Linkbuf;
800  }
801  num = Newpoly - Polybuf;
802  for (i = 0; i < num; i++) {
803  (Polybuf+i)->pl_pair = ((Polybuf+i)->pl_pair - oldbuf) + Linkbuf;
804  }
805  }
806 }
807 
808 
809 static void
811 
812 {
813  struct plist *pp;
814  int num;
815 
816  if (Polybuf == NULL) {
817  Polybuf = (struct plist *)malloc(100*sizeof(struct plist));
818  if (Polybuf == NULL)
819  MallocFailed();
820  Newpoly = Polybuf;
821  Numpolys = 100;
822  return;
823  }
824 
825  Newpoly++;
826  num = Newpoly - Polybuf;
827  if (num > Numpolys) {
828  Numpolys = num + 100;
829  Polybuf = (struct plist *)
830  realloc((char*)Polybuf,Numpolys*sizeof(struct plist));
831  if (Polybuf == NULL)
832  MallocFailed();
833  Newpoly = Polybuf + num;
834  }
835 }
static struct plist * Newpoly
Definition: polyclip.c:38
static struct pair * Newlink
Definition: polyclip.c:43
static void clip_top()
static void clip_bottom()
static void linkpolys()
static struct plist * Polybuf
Definition: polyclip.c:37
static void clip_left()
Definition: objects.c:1183
if(TDesc==NULL)
Definition: cd.c:1326
char * malloc()
static int polycmpY()
struct pair * pa_prev
Definition: polyclip.c:28
Definition: cddefs.h:215
static void newpoly()
Definition: polyclip.c:810
Definition: plotdev.h:14
long pa_x
Definition: polyclip.c:26
void MallocFailed()
Definition: scedintr.c:857
struct pair * pl_start
Definition: polyclip.c:34
struct pair * pa_next
Definition: polyclip.c:27
Definition: polyclip.c:32
#define NULL
Definition: spdefs.h:121
static void newlink()
Definition: polyclip.c:772
static struct pair * Linkbuf
Definition: polyclip.c:42
static int Numlinks
Definition: polyclip.c:44
int NextPolygon(POLYGON *p)
Definition: polyclip.c:135
qsort()
Definition: string.c:375
char * realloc()
static int polycmpX()
static struct plist * Polycurrent
Definition: polyclip.c:39
Definition: dir.c:53
static void clip_right()
Definition: polyclip.c:25
long pa_y
Definition: polyclip.c:26
struct pair * pl_pair
Definition: polyclip.c:33
static int Numpolys
Definition: polyclip.c:40
void PolygonClip(POLYGON *poly, long left, long bottom, long right, long top)
Definition: polyclip.c:71