access to poly_poly from perl as polypolygon()
[imager.git] / polygon.c
1 #include "imager.h"
2 #include "draw.h"
3 #include "log.h"
4 #include "imrender.h"
5 #include "imageri.h"
6
7 #define IMTRUNC(x) ((int)((x)*16))
8
9 #define coarse(x) ((x)/16)
10 #define fine(x)   ((x)%16)
11
12 /*#define DEBUG_POLY*/
13 #ifdef DEBUG_POLY
14 #define POLY_DEB(x) x
15 #else
16 #define POLY_DEB(x)
17 #endif
18
19
20 typedef i_img_dim pcord;
21
22 typedef struct {
23   size_t n;
24   pcord x,y;
25 } p_point;
26
27 typedef struct {
28   size_t n;
29   pcord x1,y1;
30   pcord x2,y2;
31   pcord miny,maxy;
32   pcord minx,maxx;
33   int updown; /* -1 means down, 0 vertical, 1 up */
34   int dir; /* 1 for down, -1 for up */
35 } p_line;
36
37 typedef struct {
38   size_t n;
39   double x;
40 } p_slice;
41
42 typedef struct {
43   int *line;            /* temporary buffer for scanline */
44   i_img_dim linelen;    /* length of scanline */
45 } ss_scanline;
46
47 static
48 int
49 p_compy(const p_point *p1, const p_point *p2) {
50   if (p1->y > p2->y) return 1;
51   if (p1->y < p2->y) return -1;
52   return 0;
53 }
54
55 static
56 int
57 p_compx(const p_slice *p1, const p_slice *p2) {
58   if (p1->x > p2->x) return 1;
59   if (p1->x < p2->x) return -1;
60   return 0;
61 }
62
63 /* Change this to int? and round right goddamn it! */
64
65 static
66 double
67 p_eval_aty(p_line *l, pcord y) {
68   int t;
69   t=l->y2-l->y1;
70   if (t) return ( (y-l->y1)*l->x2 + (l->y2-y)*l->x1 )/t;
71   return (l->x1+l->x2)/2.0;
72 }
73
74 static
75 double
76 p_eval_atx(p_line *l, pcord x) {
77   int t;
78   t = l->x2-l->x1;
79   if (t) return ( (x-l->x1)*l->y2 + (l->x2-x)*l->y1 )/t;
80   return (l->y1+l->y2)/2.0;
81 }
82
83 static
84 p_line *
85 line_set_new(const i_polygon_t *polys, size_t count, size_t *line_count) {
86   size_t i, j, n;
87   p_line *lset, *line;
88   size_t lines = 0;
89   
90   for (i = 0; i < count; ++i)
91     lines += polys[i].count;
92
93   line = lset = mymalloc(sizeof(p_line) * lines);
94
95   n = 0;
96   for (i = 0; i < count; ++i) {
97     const i_polygon_t *p = polys + i;
98
99     for(j = 0; j < p->count; j++) {
100       line->x1 = IMTRUNC(p->x[j]);
101       line->y1 = IMTRUNC(p->y[j]);
102       line->x2 = IMTRUNC(p->x[(j + 1) % p->count]);
103       line->y2 = IMTRUNC(p->y[(j + 1) % p->count]);
104
105       /* don't include purely horizontal lines, we don't usefully
106          intersect with them. */
107       if (line->y1 == line->y2)
108         continue;
109
110       line->miny = i_min(line->y1, line->y2);
111       line->maxy = i_max(line->y1, line->y2);
112       line->minx = i_min(line->x1, line->x2);
113       line->maxx = i_max(line->x1, line->x2);
114       line->n = n++;
115       ++line;
116     }
117   }
118   *line_count = n;
119
120   return lset;
121 }
122
123 static
124 p_point *
125 point_set_new(const i_polygon_t *polys, size_t count, size_t *point_count) {
126   size_t i, j, n;
127   p_point *pset, *pt;
128   size_t points = 0;
129   
130   for (i = 0; i < count; ++i)
131     points += polys[i].count;
132
133   *point_count = points;
134
135   pt = pset = mymalloc(sizeof(p_point) * points);
136
137   n = 0;
138   for (i = 0; i < count; ++i) {
139     const i_polygon_t *p = polys + i;
140
141     for(j = 0; j < p->count; j++) {
142       pt->n = n++;
143       pt->x = IMTRUNC(p->x[j]);
144       pt->y = IMTRUNC(p->y[j]);
145       ++pt;
146     }
147   }
148   return pset;
149 }
150
151 static
152 void
153 ss_scanline_reset(ss_scanline *ss) {
154   memset(ss->line, 0, sizeof(int) * ss->linelen);
155 }
156
157 static
158 void
159 ss_scanline_init(ss_scanline *ss, i_img_dim linelen, int linepairs) {
160   ss->line    = mymalloc( sizeof(int) * linelen );
161   ss->linelen = linelen;
162   ss_scanline_reset(ss);
163 }
164
165 static
166 void
167 ss_scanline_exorcise(ss_scanline *ss) {
168   myfree(ss->line);
169 }
170   
171                      
172
173
174 /* returns the number of matches */
175
176 static
177 int
178 lines_in_interval(p_line *lset, int l, p_slice *tllist, pcord minc, pcord maxc) {
179   int k;
180   int count = 0;
181   for(k=0; k<l; k++) {
182     if (lset[k].maxy > minc && lset[k].miny < maxc) {
183       if (lset[k].miny == lset[k].maxy) {
184         POLY_DEB( printf(" HORIZONTAL - skipped\n") );
185       } else {
186         tllist[count].x=p_eval_aty(&lset[k],(minc+maxc)/2.0 );
187         tllist[count].n=k;
188         count++;
189       }
190     }
191   }
192   return count;
193 }
194
195 /* marks the up variable for all lines in a slice */
196
197 static
198 void
199 mark_updown_slices(p_line *lset, p_slice *tllist, int count) {
200   p_line *l, *r;
201   int k;
202   for(k=0; k<count; k+=2) {
203     l = lset + tllist[k].n;
204
205     if (l->y1 == l->y2) {
206       mm_log((1, "mark_updown_slices: horizontal line being marked: internal error!\n"));
207       exit(3);
208     }
209
210     l->updown = (l->x1 == l->x2) ?
211       0 :
212       (l->x1 > l->x2)
213       ? 
214       (l->y1 > l->y2) ? -1 : 1
215       : 
216       (l->y1 > l->y2) ? 1 : -1;
217     l->dir = l->y1 < l->y2 ? 1 : -1;
218
219     POLY_DEB( printf("marking left line %d as %s(%d)\n", l->n,
220                      l->updown ?  l->updown == 1 ? "up" : "down" : "vert", l->updown, l->updown)
221               );
222
223     if (k+1 >= count) {
224       mm_log((1, "Invalid polygon spec, odd number of line crossings.\n"));
225       return;
226     }
227
228     r = lset + tllist[k+1].n;
229     if (r->y1 == r->y2) {
230       mm_log((1, "mark_updown_slices: horizontal line being marked: internal error!\n"));
231       exit(3);
232     }
233
234     r->updown = (r->x1 == r->x2) ?
235       0 :
236       (r->x1 > r->x2)
237       ? 
238       (r->y1 > r->y2) ? -1 : 1
239       : 
240       (r->y1 > r->y2) ? 1 : -1;
241     r->dir = r->y1 < r->y2 ? 1 : -1;
242     
243     POLY_DEB( printf("marking right line %d as %s(%d)\n", r->n,
244                      r->updown ?  r->updown == 1 ? "up" : "down" : "vert", r->updown, r->updown)
245               );
246   }
247 }
248
249 static
250 unsigned char
251 saturate(int in) {
252   if (in>255) { return 255; }
253   else if (in>0) return in;
254   return 0;
255 }
256
257 typedef void (*scanline_flusher)(i_img *im, ss_scanline *ss, int y, void *ctx);
258
259 /* This function must be modified later to do proper blending */
260
261 static void
262 scanline_flush(i_img *im, ss_scanline *ss, int y, void *ctx) {
263   int x, ch, tv;
264   i_color t;
265   i_color *val = (i_color *)ctx;
266   POLY_DEB( printf("Flushing line %d\n", y) );
267   for(x=0; x<im->xsize; x++) {
268     tv = saturate(ss->line[x]);
269     i_gpix(im, x, y, &t);
270     for(ch=0; ch<im->channels; ch++) 
271       t.channel[ch] = tv/255.0 * val->channel[ch] + (1.0-tv/255.0) * t.channel[ch];
272     i_ppix(im, x, y, &t);
273   }
274 }
275
276
277
278 static
279 int
280 trap_square(pcord xlen, pcord ylen, double xl, double yl) {
281   POLY_DEB( printf("trap_square: %d %d %.2f %.2f\n", xlen, ylen, xl, yl) );
282   return xlen*ylen-(xl*yl)/2.0;
283 }
284
285
286 /* 
287    pixel_coverage calculates the 'left side' pixel coverage of a pixel that is
288    within the min/max ranges.  The shape always corresponds to a square with some
289    sort of a triangle cut from it (which can also yield a triangle).
290 */
291
292
293 static
294 int 
295 pixel_coverage(p_line *line, pcord minx, pcord maxx, pcord  miny, pcord maxy) {
296   double lycross, rycross;
297   int l, r;
298
299   POLY_DEB
300     (
301      printf("    pixel_coverage(..., minx %g, maxx%g, miny %g, maxy %g)\n", 
302             minx/16.0, maxx/16.0, miny/16.0, maxy/16.0)
303      );
304
305   if (!line->updown) {
306     l = r = 0;
307   } else {
308     lycross = p_eval_atx(line, minx);
309     rycross = p_eval_atx(line, maxx);
310     l = lycross <= maxy && lycross >= miny; /* true if it enters through left side */
311     r = rycross <= maxy && rycross >= miny; /* true if it enters through left side */
312   }
313   POLY_DEB(
314            printf("    %4s(%+d): ", line->updown ?  line->updown == 1 ? "up" : "down" : "vert", line->updown);
315            printf(" (%2d,%2d) [%3d-%3d, %3d-%3d] lycross=%.2f rycross=%.2f", coarse(minx), coarse(miny), minx, maxx, miny, maxy, lycross, rycross);
316            printf(" l=%d r=%d\n", l, r)
317            );
318   
319   if (l && r) 
320     return line->updown == 1 ? 
321       (double)(maxx-minx) * (2.0*maxy-lycross-rycross)/2.0  /* up case */
322       :
323       (double)(maxx-minx) * (lycross+rycross-2*miny)/2.0;  /* down case */
324   
325   if (!l && !r) return (maxy-miny)*(maxx*2-p_eval_aty(line, miny)-p_eval_aty(line, maxy))/2.0;
326
327   if (l && !r)
328     return line->updown == 1 ?
329       trap_square(maxx-minx, maxy-miny, p_eval_aty(line, miny)-minx, p_eval_atx(line, minx)-miny) : 
330       trap_square(maxx-minx, maxy-miny, p_eval_aty(line, maxy)-minx, maxy-p_eval_atx(line, minx));
331   
332
333   if (!l && r) {
334     int r = line->updown == 1 ?
335       (maxx-p_eval_aty(line, maxy))*(maxy-p_eval_atx(line, maxx))/2.0 : 
336       (maxx-p_eval_aty(line, miny))*(p_eval_atx(line, maxx)-miny)/2.0;
337     return r;
338   }
339
340   return 0; /* silence compiler warning */
341 }
342
343
344
345
346
347 /* 
348    handle the scanline slice in three steps 
349    
350    1.  Where only the left edge is inside a pixel
351    2a. Where both left and right edge are inside a pixel
352    2b. Where neither left or right edge are inside a pixel
353    3.  Where only the right edge is inside a pixel
354 */
355
356 static
357 void
358 render_slice_scanline(ss_scanline *ss, int y, p_line *l, p_line *r, pcord miny, pcord maxy) {
359   
360   pcord lminx, lmaxx;   /* left line min/max within y bounds in fine coords */
361   pcord rminx, rmaxx;   /* right line min/max within y bounds in fine coords */
362   i_img_dim cpix;       /* x-coordinate of current pixel */
363   i_img_dim startpix;   /* temporary variable for "start of this interval" */
364   i_img_dim stoppix;    /* temporary variable for "end of this interval" */
365
366   /* Find the y bounds of scanline_slice */
367
368   POLY_DEB
369     (
370      printf("render_slice_scanline(..., y=%d)\n");
371      printf("  left  n=%d p1(%.2g, %.2g) p2(%.2g,%.2g) min(%.2g, %.2g) max(%.2g,%.2g) updown(%d)\n",
372             l->n, l->x1/16.0, l->y1/16.0, l->x2/16.0, l->y2/16.0, 
373             l->minx/16.0, l->miny/16.0, l->maxx/16.0, l->maxy/16.0,
374             l->updown);
375      printf("  right n=%d p1(%.2g, %.2g) p2(%.2g,%.2g) min(%.2g, %.2g) max(%.2g,%.2g) updown(%d)\n",
376             r->n, r->x1/16.0, r->y1/16.0, r->x2/16.0, r->y2/16.0, 
377             r->minx/16.0, r->miny/16.0, r->maxx/16.0, r->maxy/16.0,
378             r->updown);
379      );
380   
381   lminx = i_min( p_eval_aty(l, maxy), p_eval_aty(l, miny) );
382   lmaxx = i_max( p_eval_aty(l, maxy), p_eval_aty(l, miny) );
383
384   rminx = i_min( p_eval_aty(r, maxy), p_eval_aty(r, miny) );
385   rmaxx = i_max( p_eval_aty(r, maxy), p_eval_aty(r, miny) );
386
387   startpix = i_max( coarse(lminx), 0 );
388   stoppix  = i_min( coarse(rmaxx-1), ss->linelen-1 );
389
390   POLY_DEB(  printf("  miny=%g maxy=%g\n", miny/16.0, maxy/16.0)  );
391   
392   for(cpix=startpix; cpix<=stoppix; cpix++) {
393     int lt = coarse(lmaxx-1) >= cpix;
394     int rt = coarse(rminx) <= cpix;
395     
396     int A, B, C;
397     
398     POLY_DEB( printf("  (%d,%d) lt=%d rt=%d\n", cpix, y, lt, rt) );
399
400     A = lt ? pixel_coverage(l, cpix*16, cpix*16+16, miny, maxy) : 0;
401     B = lt ? 0 : 16*(maxy-miny);
402     C = rt ? pixel_coverage(r, cpix*16, cpix*16+16, miny, maxy) : 0;
403
404     POLY_DEB( printf("  A=%d B=%d C=%d\n", A, B, C) );
405
406     ss->line[cpix] += A+B-C;
407
408   }
409   POLY_DEB( printf("end render_slice_scanline()\n") );
410 }
411
412 /* Antialiasing polygon algorithm 
413    specs:
414    1. only nice polygons - no crossovers
415    2. 1/16 pixel resolution
416    3. full antialiasing ( complete spectrum of blends )
417    4. uses hardly any memory
418    5. no subsampling phase
419    
420
421    Algorithm outline:
422    1. Split into vertical intervals.
423    2. handle each interval 
424
425    For each interval we must: 
426    1. find which lines are in it
427    2. order the lines from in increasing x order.
428       since we are assuming no crossovers it is sufficent
429       to check a single point on each line.
430 */
431
432 /*
433   Definitions:
434   
435   1. Interval:  A vertical segment in which no lines cross nor end.
436   2. Scanline:  A physical line, contains 16 subpixels in the horizontal direction
437   3. Slice:     A start stop line pair.
438   
439  */
440
441
442 static int
443 i_poly_poly_aa_low(i_img *im, int count, const i_polygon_t *polys,
444                    i_poly_fill_mode_t mode, void *ctx,
445                    scanline_flusher flusher) {
446   int i ,k;                     /* Index variables */
447   i_img_dim clc;                /* Lines inside current interval */
448   /* initialize to avoid compiler warnings */
449   pcord tempy = 0;
450   i_img_dim cscl = 0;                   /* Current scanline */
451
452   ss_scanline templine;         /* scanline accumulator */
453   p_point *pset;                /* List of points in polygon */
454   p_line  *lset;                /* List of lines in polygon */
455   p_slice *tllist;              /* List of slices */
456   size_t pcount, lcount;
457
458   mm_log((1, "i_poly_poly_aa_low(im %p, count %d, polys %p, ctx %p, flusher %p)\n", im, count, polys, ctx, flusher));
459
460   for (k = 0; k < count; ++k) {
461     const i_polygon_t *p = polys + k;
462     mm_log((2, "poly %d\n", k));
463     for(i = 0; i < p->count; i++) {
464       mm_log((2, " (%.2f, %.2f)\n", p->x[i], p->y[i]));
465     }
466   }
467
468
469   POLY_DEB(
470            fflush(stdout);
471            setbuf(stdout, NULL);
472            );
473
474   pset     = point_set_new(polys, count, &pcount);
475   lset     = line_set_new(polys, count, &lcount);
476
477   ss_scanline_init(&templine, im->xsize, lcount);
478
479   tllist   = mymalloc(sizeof(p_slice) * lcount);
480   
481   qsort(pset, pcount, sizeof(p_point), (int(*)(const void *,const void *))p_compy);
482   
483   POLY_DEB(
484            for(i=0;i<lcount;i++) {
485              printf("%d [ %d ] (%d , %d) -> (%d , %d) yspan ( %d , %d )\n",
486                     i, lset[i].n, lset[i].x1, lset[i].y1, lset[i].x2, lset[i].y2, lset[i].miny, lset[i].maxy);
487            }
488            printf("MAIN LOOP\n\n");
489            );
490   
491
492   /* loop on intervals */
493   for(i=0; i<pcount-1; i++) {
494     i_img_dim startscan = i_max( coarse(pset[i].y), 0);
495     i_img_dim stopscan = i_min( coarse(pset[i+1].y+15), im->ysize);
496     pcord miny, maxy;   /* y bounds in fine coordinates */
497
498     POLY_DEB( pcord cc = (pset[i].y + pset[i+1].y)/2 );
499
500     POLY_DEB(
501              printf("current slice is %d: %d to %d ( cpoint %d ) scanlines %d to %d\n", 
502                     i, pset[i].y, pset[i+1].y, cc, startscan, stopscan)
503              );
504     
505     if (pset[i].y == pset[i+1].y) {
506       POLY_DEB( printf("current slice thickness = 0 => skipping\n") );
507       continue;
508     }
509
510     clc = lines_in_interval(lset, lcount, tllist, pset[i].y, pset[i+1].y);
511     qsort(tllist, clc, sizeof(p_slice), (int(*)(const void *,const void *))p_compx);
512
513     mark_updown_slices(lset, tllist, clc);
514
515     POLY_DEB
516       (
517        printf("Interval contains %d lines\n", clc);
518        for(k=0; k<clc; k++) {
519          int lno = tllist[k].n;
520          p_line *ln = lset+lno;
521          printf("%d:  line #%2d: (%2d, %2d)->(%2d, %2d) (%2d/%2d, %2d/%2d) -> (%2d/%2d, %2d/%2d) alignment=%s\n",
522                 k, lno, ln->x1, ln->y1, ln->x2, ln->y2, 
523                 coarse(ln->x1), fine(ln->x1), 
524                 coarse(ln->y1), fine(ln->y1), 
525                 coarse(ln->x2), fine(ln->x2), 
526                 coarse(ln->y2), fine(ln->y2),
527                 ln->updown == 0 ? "vert" : ln->updown == 1 ? "up" : "down");
528            
529        }
530        );
531     maxy = im->ysize * 16;
532     miny = 0;
533     for (k = 0; k < clc; ++k) {
534       p_line const * line = lset + tllist[k].n;
535       if (line->miny > miny)
536         miny = line->miny;
537       if (line->maxy < maxy)
538         maxy = line->maxy;
539       POLY_DEB( printf(" line miny %g maxy %g\n", line->miny/16.0, line->maxy/16.0) );
540     }
541     POLY_DEB( printf("miny %g maxy %g\n", miny/16.0, maxy/16.0) );
542
543     for(cscl=startscan; cscl<stopscan; cscl++) {
544       pcord scan_miny = i_max(miny, cscl * 16);
545       pcord scan_maxy = i_min(maxy, (cscl + 1 ) * 16);
546       
547       tempy = i_min(cscl*16+16, pset[i+1].y);
548       POLY_DEB( printf("evaluating scan line %d \n", cscl) );
549       if (mode == i_pfm_evenodd) {
550         for(k=0; k<clc-1; k+=2) {
551           POLY_DEB( printf("evaluating slice %d\n", k) );
552           render_slice_scanline(&templine, cscl, lset+tllist[k].n, lset+tllist[k+1].n, scan_miny, scan_maxy);
553         }
554       }
555       else {
556         k = 0;
557         while (k < clc) {
558           p_line *left = lset + tllist[k++].n;
559           p_line *current;
560           int acc = left->dir;
561
562           while (k < clc && acc) {
563             current = lset + tllist[k++].n;
564             acc += current->dir;
565           }
566           if (acc == 0) {
567             render_slice_scanline(&templine, cscl, left, current,
568                                   scan_miny, scan_maxy);
569           }
570         }
571       }
572       if (16*coarse(tempy) == tempy) {
573         POLY_DEB( printf("flushing scan line %d\n", cscl) );
574         flusher(im, &templine, cscl, ctx);
575         ss_scanline_reset(&templine);
576       }
577       /*
578         else {
579         scanline_flush(im, &templine, cscl, val);
580         ss_scanline_reset(&templine);
581         return 0;
582         }
583       */
584     }
585   } /* Intervals */
586   if (16*coarse(tempy) != tempy) 
587     flusher(im, &templine, cscl-1, ctx);
588
589   ss_scanline_exorcise(&templine);
590   myfree(pset);
591   myfree(lset);
592   myfree(tllist);
593
594   return 1;
595 }
596
597 int
598 i_poly_poly_aa(i_img *im, int count, const i_polygon_t *polys,
599                i_poly_fill_mode_t mode, const i_color *val) {
600   i_color c = *val;
601   return i_poly_poly_aa_low(im, count, polys, mode, &c, scanline_flush);
602 }
603
604 int
605 i_poly_aa_m(i_img *im, int l, const double *x, const double *y,
606             i_poly_fill_mode_t mode, const i_color *val) {
607   i_polygon_t poly;
608
609   poly.count = l;
610   poly.x = x;
611   poly.y = y;
612   return i_poly_poly_aa(im, 1, &poly, mode, val);
613 }
614
615 int
616 i_poly_aa(i_img *im, int l, const double *x, const double *y, const i_color *val) {
617   i_polygon_t poly;
618
619   poly.count = l;
620   poly.x = x;
621   poly.y = y;
622   return i_poly_poly_aa(im, 1, &poly, i_pfm_evenodd, val);
623 }
624
625 struct poly_render_state {
626   i_render render;
627   i_fill_t *fill;
628   unsigned char *cover;
629 };
630
631 static void
632 scanline_flush_render(i_img *im, ss_scanline *ss, int y, void *ctx) {
633   i_img_dim x;
634   i_img_dim left, right;
635   struct poly_render_state *state = (struct poly_render_state *)ctx;
636
637   left = 0;
638   while (left < im->xsize && ss->line[left] <= 0)
639     ++left;
640   if (left < im->xsize) {
641     right = im->xsize;
642     /* since going from the left found something, moving from the 
643        right should */
644     while (/* right > left && */ ss->line[right-1] <= 0) 
645       --right;
646     
647     /* convert to the format the render interface wants */
648     for (x = left; x < right; ++x) {
649       state->cover[x-left] = saturate(ss->line[x]);
650     }
651     i_render_fill(&state->render, left, y, right-left, state->cover, 
652                   state->fill);
653   }
654 }
655
656 int
657 i_poly_poly_aa_cfill(i_img *im, int count, const i_polygon_t *polys,
658                      i_poly_fill_mode_t mode, i_fill_t *fill) {
659   struct poly_render_state ctx;
660   int result;
661
662   i_render_init(&ctx.render, im, im->xsize);
663   ctx.fill = fill;
664   ctx.cover = mymalloc(im->xsize);
665
666   result = i_poly_poly_aa_low(im, count, polys, mode, &ctx,
667                               scanline_flush_render);
668
669   myfree(ctx.cover);
670   i_render_done(&ctx.render);
671
672   return result;
673 }
674
675 int
676 i_poly_aa_cfill_m(i_img *im, int l, const double *x, const double *y, 
677                 i_poly_fill_mode_t mode, i_fill_t *fill) {
678   i_polygon_t poly;
679
680   poly.count = l;
681   poly.x = x;
682   poly.y = y;
683
684   return i_poly_poly_aa_cfill(im, 1, &poly, mode, fill);
685 }
686
687 int
688 i_poly_aa_cfill(i_img *im, int l, const double *x, const double *y, 
689                 i_fill_t *fill) {
690   i_polygon_t poly;
691
692   poly.count = l;
693   poly.x = x;
694   poly.y = y;
695
696   return i_poly_poly_aa_cfill(im, 1, &poly, i_pfm_evenodd, fill);
697 }