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