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