1 /************************************************************
2 
3 Copyright 1989, 1998  The Open Group
4 
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10 
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
24 
25 Author:  Bob Scheifler, MIT X Consortium
26 
27 ********************************************************/
28 
29 #ifdef HAVE_DIX_CONFIG_H
30 #include <dix-config.h>
31 #endif
32 
33 #include <math.h>
34 #include <X11/X.h>
35 #include <X11/Xprotostr.h>
36 #include "regionstr.h"
37 #include "gcstruct.h"
38 #include "pixmapstr.h"
39 #include "mi.h"
40 #include "mifillarc.h"
41 
42 #define QUADRANT (90 * 64)
43 #define HALFCIRCLE (180 * 64)
44 #define QUADRANT3 (270 * 64)
45 
46 #ifndef M_PI
47 #define M_PI	3.14159265358979323846
48 #endif
49 
50 #define Dsin(d)	sin((double)d*(M_PI/11520.0))
51 #define Dcos(d)	cos((double)d*(M_PI/11520.0))
52 
53 static void
miFillArcSetup(xArc * arc,miFillArcRec * info)54 miFillArcSetup(xArc * arc, miFillArcRec * info)
55 {
56     info->y = arc->height >> 1;
57     info->dy = arc->height & 1;
58     info->yorg = arc->y + info->y;
59     info->dx = arc->width & 1;
60     info->xorg = arc->x + (arc->width >> 1) + info->dx;
61     info->dx = 1 - info->dx;
62     if (arc->width == arc->height) {
63         /* (2x - 2xorg)^2 = d^2 - (2y - 2yorg)^2 */
64         /* even: xorg = yorg = 0   odd:  xorg = .5, yorg = -.5 */
65         info->ym = 8;
66         info->xm = 8;
67         info->yk = info->y << 3;
68         if (!info->dx) {
69             info->xk = 0;
70             info->e = -1;
71         }
72         else {
73             info->y++;
74             info->yk += 4;
75             info->xk = -4;
76             info->e = -(info->y << 3);
77         }
78     }
79     else {
80         /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
81         /* even: xorg = yorg = 0   odd:  xorg = .5, yorg = -.5 */
82         info->ym = (arc->width * arc->width) << 3;
83         info->xm = (arc->height * arc->height) << 3;
84         info->yk = info->y * info->ym;
85         if (!info->dy)
86             info->yk -= info->ym >> 1;
87         if (!info->dx) {
88             info->xk = 0;
89             info->e = -(info->xm >> 3);
90         }
91         else {
92             info->y++;
93             info->yk += info->ym;
94             info->xk = -(info->xm >> 1);
95             info->e = info->xk - info->yk;
96         }
97     }
98 }
99 
100 static void
miFillArcDSetup(xArc * arc,miFillArcDRec * info)101 miFillArcDSetup(xArc * arc, miFillArcDRec * info)
102 {
103     /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
104     /* even: xorg = yorg = 0   odd:  xorg = .5, yorg = -.5 */
105     info->y = arc->height >> 1;
106     info->dy = arc->height & 1;
107     info->yorg = arc->y + info->y;
108     info->dx = arc->width & 1;
109     info->xorg = arc->x + (arc->width >> 1) + info->dx;
110     info->dx = 1 - info->dx;
111     info->ym = ((double) arc->width) * (arc->width * 8);
112     info->xm = ((double) arc->height) * (arc->height * 8);
113     info->yk = info->y * info->ym;
114     if (!info->dy)
115         info->yk -= info->ym / 2.0;
116     if (!info->dx) {
117         info->xk = 0;
118         info->e = -(info->xm / 8.0);
119     }
120     else {
121         info->y++;
122         info->yk += info->ym;
123         info->xk = -info->xm / 2.0;
124         info->e = info->xk - info->yk;
125     }
126 }
127 
128 static void
miGetArcEdge(xArc * arc,miSliceEdgePtr edge,int k,Bool top,Bool left)129 miGetArcEdge(xArc * arc, miSliceEdgePtr edge, int k, Bool top, Bool left)
130 {
131     int xady, y;
132 
133     y = arc->height >> 1;
134     if (!(arc->width & 1))
135         y++;
136     if (!top) {
137         y = -y;
138         if (arc->height & 1)
139             y--;
140     }
141     xady = k + y * edge->dx;
142     if (xady <= 0)
143         edge->x = -((-xady) / edge->dy + 1);
144     else
145         edge->x = (xady - 1) / edge->dy;
146     edge->e = xady - edge->x * edge->dy;
147     if ((top && (edge->dx < 0)) || (!top && (edge->dx > 0)))
148         edge->e = edge->dy - edge->e + 1;
149     if (left)
150         edge->x++;
151     edge->x += arc->x + (arc->width >> 1);
152     if (edge->dx > 0) {
153         edge->deltax = 1;
154         edge->stepx = edge->dx / edge->dy;
155         edge->dx = edge->dx % edge->dy;
156     }
157     else {
158         edge->deltax = -1;
159         edge->stepx = -((-edge->dx) / edge->dy);
160         edge->dx = (-edge->dx) % edge->dy;
161     }
162     if (!top) {
163         edge->deltax = -edge->deltax;
164         edge->stepx = -edge->stepx;
165     }
166 }
167 
168 static void
miEllipseAngleToSlope(int angle,int width,int height,int * dxp,int * dyp,double * d_dxp,double * d_dyp)169 miEllipseAngleToSlope(int angle, int width, int height, int *dxp, int *dyp,
170                       double *d_dxp, double *d_dyp)
171 {
172     int dx, dy;
173     double d_dx, d_dy, scale;
174     Bool negative_dx, negative_dy;
175 
176     switch (angle) {
177     case 0:
178         *dxp = -1;
179         *dyp = 0;
180         if (d_dxp) {
181             *d_dxp = width / 2.0;
182             *d_dyp = 0;
183         }
184         break;
185     case QUADRANT:
186         *dxp = 0;
187         *dyp = 1;
188         if (d_dxp) {
189             *d_dxp = 0;
190             *d_dyp = -height / 2.0;
191         }
192         break;
193     case HALFCIRCLE:
194         *dxp = 1;
195         *dyp = 0;
196         if (d_dxp) {
197             *d_dxp = -width / 2.0;
198             *d_dyp = 0;
199         }
200         break;
201     case QUADRANT3:
202         *dxp = 0;
203         *dyp = -1;
204         if (d_dxp) {
205             *d_dxp = 0;
206             *d_dyp = height / 2.0;
207         }
208         break;
209     default:
210         d_dx = Dcos(angle) * width;
211         d_dy = Dsin(angle) * height;
212         if (d_dxp) {
213             *d_dxp = d_dx / 2.0;
214             *d_dyp = -d_dy / 2.0;
215         }
216         negative_dx = FALSE;
217         if (d_dx < 0.0) {
218             d_dx = -d_dx;
219             negative_dx = TRUE;
220         }
221         negative_dy = FALSE;
222         if (d_dy < 0.0) {
223             d_dy = -d_dy;
224             negative_dy = TRUE;
225         }
226         scale = d_dx;
227         if (d_dy > d_dx)
228             scale = d_dy;
229         dx = floor((d_dx * 32768) / scale + 0.5);
230         if (negative_dx)
231             dx = -dx;
232         *dxp = dx;
233         dy = floor((d_dy * 32768) / scale + 0.5);
234         if (negative_dy)
235             dy = -dy;
236         *dyp = dy;
237         break;
238     }
239 }
240 
241 static void
miGetPieEdge(xArc * arc,int angle,miSliceEdgePtr edge,Bool top,Bool left)242 miGetPieEdge(xArc * arc, int angle, miSliceEdgePtr edge, Bool top, Bool left)
243 {
244     int k;
245     int dx, dy;
246 
247     miEllipseAngleToSlope(angle, arc->width, arc->height, &dx, &dy, 0, 0);
248 
249     if (dy == 0) {
250         edge->x = left ? -65536 : 65536;
251         edge->stepx = 0;
252         edge->e = 0;
253         edge->dx = -1;
254         return;
255     }
256     if (dx == 0) {
257         edge->x = arc->x + (arc->width >> 1);
258         if (left && (arc->width & 1))
259             edge->x++;
260         else if (!left && !(arc->width & 1))
261             edge->x--;
262         edge->stepx = 0;
263         edge->e = 0;
264         edge->dx = -1;
265         return;
266     }
267     if (dy < 0) {
268         dx = -dx;
269         dy = -dy;
270     }
271     k = (arc->height & 1) ? dx : 0;
272     if (arc->width & 1)
273         k += dy;
274     edge->dx = dx << 1;
275     edge->dy = dy << 1;
276     miGetArcEdge(arc, edge, k, top, left);
277 }
278 
279 static void
miFillArcSliceSetup(xArc * arc,miArcSliceRec * slice,GCPtr pGC)280 miFillArcSliceSetup(xArc * arc, miArcSliceRec * slice, GCPtr pGC)
281 {
282     int angle1, angle2;
283 
284     angle1 = arc->angle1;
285     if (arc->angle2 < 0) {
286         angle2 = angle1;
287         angle1 += arc->angle2;
288     }
289     else
290         angle2 = angle1 + arc->angle2;
291     while (angle1 < 0)
292         angle1 += FULLCIRCLE;
293     while (angle1 >= FULLCIRCLE)
294         angle1 -= FULLCIRCLE;
295     while (angle2 < 0)
296         angle2 += FULLCIRCLE;
297     while (angle2 >= FULLCIRCLE)
298         angle2 -= FULLCIRCLE;
299     slice->min_top_y = 0;
300     slice->max_top_y = arc->height >> 1;
301     slice->min_bot_y = 1 - (arc->height & 1);
302     slice->max_bot_y = slice->max_top_y - 1;
303     slice->flip_top = FALSE;
304     slice->flip_bot = FALSE;
305     if (pGC->arcMode == ArcPieSlice) {
306         slice->edge1_top = (angle1 < HALFCIRCLE);
307         slice->edge2_top = (angle2 <= HALFCIRCLE);
308         if ((angle2 == 0) || (angle1 == HALFCIRCLE)) {
309             if (angle2 ? slice->edge2_top : slice->edge1_top)
310                 slice->min_top_y = slice->min_bot_y;
311             else
312                 slice->min_top_y = arc->height;
313             slice->min_bot_y = 0;
314         }
315         else if ((angle1 == 0) || (angle2 == HALFCIRCLE)) {
316             slice->min_top_y = slice->min_bot_y;
317             if (angle1 ? slice->edge1_top : slice->edge2_top)
318                 slice->min_bot_y = arc->height;
319             else
320                 slice->min_bot_y = 0;
321         }
322         else if (slice->edge1_top == slice->edge2_top) {
323             if (angle2 < angle1) {
324                 slice->flip_top = slice->edge1_top;
325                 slice->flip_bot = !slice->edge1_top;
326             }
327             else if (slice->edge1_top) {
328                 slice->min_top_y = 1;
329                 slice->min_bot_y = arc->height;
330             }
331             else {
332                 slice->min_bot_y = 0;
333                 slice->min_top_y = arc->height;
334             }
335         }
336         miGetPieEdge(arc, angle1, &slice->edge1,
337                      slice->edge1_top, !slice->edge1_top);
338         miGetPieEdge(arc, angle2, &slice->edge2,
339                      slice->edge2_top, slice->edge2_top);
340     }
341     else {
342         double w2, h2, x1, y1, x2, y2, dx, dy, scale;
343         int signdx, signdy, y, k;
344         Bool isInt1 = TRUE, isInt2 = TRUE;
345 
346         w2 = (double) arc->width / 2.0;
347         h2 = (double) arc->height / 2.0;
348         if ((angle1 == 0) || (angle1 == HALFCIRCLE)) {
349             x1 = angle1 ? -w2 : w2;
350             y1 = 0.0;
351         }
352         else if ((angle1 == QUADRANT) || (angle1 == QUADRANT3)) {
353             x1 = 0.0;
354             y1 = (angle1 == QUADRANT) ? h2 : -h2;
355         }
356         else {
357             isInt1 = FALSE;
358             x1 = Dcos(angle1) * w2;
359             y1 = Dsin(angle1) * h2;
360         }
361         if ((angle2 == 0) || (angle2 == HALFCIRCLE)) {
362             x2 = angle2 ? -w2 : w2;
363             y2 = 0.0;
364         }
365         else if ((angle2 == QUADRANT) || (angle2 == QUADRANT3)) {
366             x2 = 0.0;
367             y2 = (angle2 == QUADRANT) ? h2 : -h2;
368         }
369         else {
370             isInt2 = FALSE;
371             x2 = Dcos(angle2) * w2;
372             y2 = Dsin(angle2) * h2;
373         }
374         dx = x2 - x1;
375         dy = y2 - y1;
376         if (arc->height & 1) {
377             y1 -= 0.5;
378             y2 -= 0.5;
379         }
380         if (arc->width & 1) {
381             x1 += 0.5;
382             x2 += 0.5;
383         }
384         if (dy < 0.0) {
385             dy = -dy;
386             signdy = -1;
387         }
388         else
389             signdy = 1;
390         if (dx < 0.0) {
391             dx = -dx;
392             signdx = -1;
393         }
394         else
395             signdx = 1;
396         if (isInt1 && isInt2) {
397             slice->edge1.dx = dx * 2;
398             slice->edge1.dy = dy * 2;
399         }
400         else {
401             scale = (dx > dy) ? dx : dy;
402             slice->edge1.dx = floor((dx * 32768) / scale + .5);
403             slice->edge1.dy = floor((dy * 32768) / scale + .5);
404         }
405         if (!slice->edge1.dy) {
406             if (signdx < 0) {
407                 y = floor(y1 + 1.0);
408                 if (y >= 0) {
409                     slice->min_top_y = y;
410                     slice->min_bot_y = arc->height;
411                 }
412                 else {
413                     slice->max_bot_y = -y - (arc->height & 1);
414                 }
415             }
416             else {
417                 y = floor(y1);
418                 if (y >= 0)
419                     slice->max_top_y = y;
420                 else {
421                     slice->min_top_y = arc->height;
422                     slice->min_bot_y = -y - (arc->height & 1);
423                 }
424             }
425             slice->edge1_top = TRUE;
426             slice->edge1.x = 65536;
427             slice->edge1.stepx = 0;
428             slice->edge1.e = 0;
429             slice->edge1.dx = -1;
430             slice->edge2 = slice->edge1;
431             slice->edge2_top = FALSE;
432         }
433         else if (!slice->edge1.dx) {
434             if (signdy < 0)
435                 x1 -= 1.0;
436             slice->edge1.x = ceil(x1);
437             slice->edge1_top = signdy < 0;
438             slice->edge1.x += arc->x + (arc->width >> 1);
439             slice->edge1.stepx = 0;
440             slice->edge1.e = 0;
441             slice->edge1.dx = -1;
442             slice->edge2_top = !slice->edge1_top;
443             slice->edge2 = slice->edge1;
444         }
445         else {
446             if (signdx < 0)
447                 slice->edge1.dx = -slice->edge1.dx;
448             if (signdy < 0)
449                 slice->edge1.dx = -slice->edge1.dx;
450             k = ceil(((x1 + x2) * slice->edge1.dy -
451                       (y1 + y2) * slice->edge1.dx) / 2.0);
452             slice->edge2.dx = slice->edge1.dx;
453             slice->edge2.dy = slice->edge1.dy;
454             slice->edge1_top = signdy < 0;
455             slice->edge2_top = !slice->edge1_top;
456             miGetArcEdge(arc, &slice->edge1, k,
457                          slice->edge1_top, !slice->edge1_top);
458             miGetArcEdge(arc, &slice->edge2, k,
459                          slice->edge2_top, slice->edge2_top);
460         }
461     }
462 }
463 
464 #define ADDSPANS() \
465     pts->x = xorg - x; \
466     pts->y = yorg - y; \
467     *wids = slw; \
468     pts++; \
469     wids++; \
470     if (miFillArcLower(slw)) \
471     { \
472 	pts->x = xorg - x; \
473 	pts->y = yorg + y + dy; \
474 	pts++; \
475 	*wids++ = slw; \
476     }
477 
478 static int
miFillEllipseI(DrawablePtr pDraw,GCPtr pGC,xArc * arc,DDXPointPtr points,int * widths)479 miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
480 {
481     int x, y, e;
482     int yk, xk, ym, xm, dx, dy, xorg, yorg;
483     int slw;
484     miFillArcRec info;
485     DDXPointPtr pts;
486     int *wids;
487 
488     miFillArcSetup(arc, &info);
489     MIFILLARCSETUP();
490     if (pGC->miTranslate) {
491         xorg += pDraw->x;
492         yorg += pDraw->y;
493     }
494     pts = points;
495     wids = widths;
496     while (y > 0) {
497         MIFILLARCSTEP(slw);
498         ADDSPANS();
499     }
500     return pts - points;
501 }
502 
503 static int
miFillEllipseD(DrawablePtr pDraw,GCPtr pGC,xArc * arc,DDXPointPtr points,int * widths)504 miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
505 {
506     int x, y;
507     int xorg, yorg, dx, dy, slw;
508     double e, yk, xk, ym, xm;
509     miFillArcDRec info;
510     DDXPointPtr pts;
511     int *wids;
512 
513     miFillArcDSetup(arc, &info);
514     MIFILLARCSETUP();
515     if (pGC->miTranslate) {
516         xorg += pDraw->x;
517         yorg += pDraw->y;
518     }
519     pts = points;
520     wids = widths;
521     while (y > 0) {
522         MIFILLARCSTEP(slw);
523         ADDSPANS();
524     }
525     return pts - points;
526 }
527 
528 #define ADDSPAN(l,r) \
529     if (r >= l) \
530     { \
531 	pts->x = l; \
532 	pts->y = ya; \
533 	pts++; \
534 	*wids++ = r - l + 1; \
535     }
536 
537 #define ADDSLICESPANS(flip) \
538     if (!flip) \
539     { \
540 	ADDSPAN(xl, xr); \
541     } \
542     else \
543     { \
544 	xc = xorg - x; \
545 	ADDSPAN(xc, xr); \
546 	xc += slw - 1; \
547 	ADDSPAN(xl, xc); \
548     }
549 
550 static int
miFillArcSliceI(DrawablePtr pDraw,GCPtr pGC,xArc * arc,DDXPointPtr points,int * widths)551 miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
552 {
553     int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
554     int x, y, e;
555     miFillArcRec info;
556     miArcSliceRec slice;
557     int ya, xl, xr, xc;
558     DDXPointPtr pts;
559     int *wids;
560 
561     miFillArcSetup(arc, &info);
562     miFillArcSliceSetup(arc, &slice, pGC);
563     MIFILLARCSETUP();
564     slw = arc->height;
565     if (slice.flip_top || slice.flip_bot)
566         slw += (arc->height >> 1) + 1;
567     if (pGC->miTranslate) {
568         xorg += pDraw->x;
569         yorg += pDraw->y;
570         slice.edge1.x += pDraw->x;
571         slice.edge2.x += pDraw->x;
572     }
573     pts = points;
574     wids = widths;
575     while (y > 0) {
576         MIFILLARCSTEP(slw);
577         MIARCSLICESTEP(slice.edge1);
578         MIARCSLICESTEP(slice.edge2);
579         if (miFillSliceUpper(slice)) {
580             ya = yorg - y;
581             MIARCSLICEUPPER(xl, xr, slice, slw);
582             ADDSLICESPANS(slice.flip_top);
583         }
584         if (miFillSliceLower(slice)) {
585             ya = yorg + y + dy;
586             MIARCSLICELOWER(xl, xr, slice, slw);
587             ADDSLICESPANS(slice.flip_bot);
588         }
589     }
590     return pts - points;
591 }
592 
593 static int
miFillArcSliceD(DrawablePtr pDraw,GCPtr pGC,xArc * arc,DDXPointPtr points,int * widths)594 miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
595 {
596     int x, y;
597     int dx, dy, xorg, yorg, slw;
598     double e, yk, xk, ym, xm;
599     miFillArcDRec info;
600     miArcSliceRec slice;
601     int ya, xl, xr, xc;
602     DDXPointPtr pts;
603     int *wids;
604 
605     miFillArcDSetup(arc, &info);
606     miFillArcSliceSetup(arc, &slice, pGC);
607     MIFILLARCSETUP();
608     slw = arc->height;
609     if (slice.flip_top || slice.flip_bot)
610         slw += (arc->height >> 1) + 1;
611     if (pGC->miTranslate) {
612         xorg += pDraw->x;
613         yorg += pDraw->y;
614         slice.edge1.x += pDraw->x;
615         slice.edge2.x += pDraw->x;
616     }
617     pts = points;
618     wids = widths;
619     while (y > 0) {
620         MIFILLARCSTEP(slw);
621         MIARCSLICESTEP(slice.edge1);
622         MIARCSLICESTEP(slice.edge2);
623         if (miFillSliceUpper(slice)) {
624             ya = yorg - y;
625             MIARCSLICEUPPER(xl, xr, slice, slw);
626             ADDSLICESPANS(slice.flip_top);
627         }
628         if (miFillSliceLower(slice)) {
629             ya = yorg + y + dy;
630             MIARCSLICELOWER(xl, xr, slice, slw);
631             ADDSLICESPANS(slice.flip_bot);
632         }
633     }
634     return pts - points;
635 }
636 
637 /* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
638  * Since we don't have to worry about overlapping segments, we can just
639  * fill each arc as it comes.
640  */
641 
642 /* Limit the number of spans in a single draw request to avoid integer
643  * overflow in the computation of the span buffer size.
644  */
645 #define MAX_SPANS_PER_LOOP      (4 * 1024 * 1024)
646 
647 void
miPolyFillArc(DrawablePtr pDraw,GCPtr pGC,int narcs_all,xArc * parcs)648 miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs_all, xArc * parcs)
649 {
650     while (narcs_all > 0) {
651         int narcs;
652         int i;
653         xArc *arc;
654         int nspans = 0;
655         DDXPointPtr pts, points;
656         int *wids, *widths;
657         int n;
658 
659         for (narcs = 0, arc = parcs; narcs < narcs_all; narcs++, arc++) {
660             if (narcs && nspans + arc->height > MAX_SPANS_PER_LOOP)
661                 break;
662             nspans += arc->height;
663 
664             /* A pie-slice arc may add another pile of spans */
665             if (pGC->arcMode == ArcPieSlice &&
666                 (-FULLCIRCLE < arc->angle2 && arc->angle2 < FULLCIRCLE))
667                 nspans += (arc->height + 1) >> 1;
668         }
669 
670         pts = points = malloc (sizeof (DDXPointRec) * nspans +
671                                sizeof(int) * nspans);
672         if (points) {
673             wids = widths = (int *) (points + nspans);
674 
675             for (i = 0, arc = parcs; i < narcs; arc++, i++) {
676                 if (miFillArcEmpty(arc))
677                     continue;
678                 if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE))
679                 {
680                     if (miCanFillArc(arc))
681                         n = miFillEllipseI(pDraw, pGC, arc, pts, wids);
682                     else
683                         n = miFillEllipseD(pDraw, pGC, arc, pts, wids);
684                 }
685                 else
686                 {
687                     if (miCanFillArc(arc))
688                         n = miFillArcSliceI(pDraw, pGC, arc, pts, wids);
689                     else
690                         n = miFillArcSliceD(pDraw, pGC, arc, pts, wids);
691                 }
692                 pts += n;
693                 wids += n;
694             }
695             nspans = pts - points;
696             if (nspans)
697                 (*pGC->ops->FillSpans) (pDraw, pGC, nspans, points,
698                                         widths, FALSE);
699             free (points);
700         }
701         parcs += narcs;
702         narcs_all -= narcs;
703     }
704 }
705