xref: /OK3568_Linux_fs/external/xserver/mi/mizerarc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /************************************************************
2*4882a593Smuzhiyun 
3*4882a593Smuzhiyun Copyright 1989, 1998  The Open Group
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software and its
6*4882a593Smuzhiyun documentation for any purpose is hereby granted without fee, provided that
7*4882a593Smuzhiyun the above copyright notice appear in all copies and that both that
8*4882a593Smuzhiyun copyright notice and this permission notice appear in supporting
9*4882a593Smuzhiyun documentation.
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included in
12*4882a593Smuzhiyun all copies or substantial portions of the Software.
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17*4882a593Smuzhiyun OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18*4882a593Smuzhiyun AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19*4882a593Smuzhiyun CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall not be
22*4882a593Smuzhiyun used in advertising or otherwise to promote the sale, use or other dealings
23*4882a593Smuzhiyun in this Software without prior written authorization from The Open Group.
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun Author:  Bob Scheifler, MIT X Consortium
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun ********************************************************/
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /* Derived from:
30*4882a593Smuzhiyun  * "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
31*4882a593Smuzhiyun  * by M. L. V. Pitteway
32*4882a593Smuzhiyun  * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
33*4882a593Smuzhiyun  */
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
36*4882a593Smuzhiyun #include <dix-config.h>
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #include <math.h>
40*4882a593Smuzhiyun #include <X11/X.h>
41*4882a593Smuzhiyun #include <X11/Xprotostr.h>
42*4882a593Smuzhiyun #include "regionstr.h"
43*4882a593Smuzhiyun #include "gcstruct.h"
44*4882a593Smuzhiyun #include "pixmapstr.h"
45*4882a593Smuzhiyun #include "mi.h"
46*4882a593Smuzhiyun #include "mizerarc.h"
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun #define FULLCIRCLE (360 * 64)
49*4882a593Smuzhiyun #define OCTANT (45 * 64)
50*4882a593Smuzhiyun #define QUADRANT (90 * 64)
51*4882a593Smuzhiyun #define HALFCIRCLE (180 * 64)
52*4882a593Smuzhiyun #define QUADRANT3 (270 * 64)
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #ifndef M_PI
55*4882a593Smuzhiyun #define M_PI	3.14159265358979323846
56*4882a593Smuzhiyun #endif
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun #define Dsin(d)	((d) == 0 ? 0.0 : ((d) == QUADRANT ? 1.0 : \
59*4882a593Smuzhiyun 		 ((d) == HALFCIRCLE ? 0.0 : \
60*4882a593Smuzhiyun 		 ((d) == QUADRANT3 ? -1.0 : sin((double)d*(M_PI/11520.0))))))
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun #define Dcos(d)	((d) == 0 ? 1.0 : ((d) == QUADRANT ? 0.0 : \
63*4882a593Smuzhiyun 		 ((d) == HALFCIRCLE ? -1.0 : \
64*4882a593Smuzhiyun 		 ((d) == QUADRANT3 ? 0.0 : cos((double)d*(M_PI/11520.0))))))
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun #define EPSILON45 64
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun typedef struct {
69*4882a593Smuzhiyun     int skipStart;
70*4882a593Smuzhiyun     int haveStart;
71*4882a593Smuzhiyun     DDXPointRec startPt;
72*4882a593Smuzhiyun     int haveLast;
73*4882a593Smuzhiyun     int skipLast;
74*4882a593Smuzhiyun     DDXPointRec endPt;
75*4882a593Smuzhiyun     int dashIndex;
76*4882a593Smuzhiyun     int dashOffset;
77*4882a593Smuzhiyun     int dashIndexInit;
78*4882a593Smuzhiyun     int dashOffsetInit;
79*4882a593Smuzhiyun } DashInfo;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun static miZeroArcPtRec oob = { 65536, 65536, 0 };
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun /*
84*4882a593Smuzhiyun  * (x - l)^2 / (W/2)^2  + (y + H/2)^2 / (H/2)^2 = 1
85*4882a593Smuzhiyun  *
86*4882a593Smuzhiyun  * where l is either 0 or .5
87*4882a593Smuzhiyun  *
88*4882a593Smuzhiyun  * alpha = 4(W^2)
89*4882a593Smuzhiyun  * beta = 4(H^2)
90*4882a593Smuzhiyun  * gamma = 0
91*4882a593Smuzhiyun  * u = 2(W^2)H
92*4882a593Smuzhiyun  * v = 4(H^2)l
93*4882a593Smuzhiyun  * k = -4(H^2)(l^2)
94*4882a593Smuzhiyun  *
95*4882a593Smuzhiyun  */
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun Bool
miZeroArcSetup(xArc * arc,miZeroArcRec * info,Bool ok360)98*4882a593Smuzhiyun miZeroArcSetup(xArc * arc, miZeroArcRec * info, Bool ok360)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun     int l;
101*4882a593Smuzhiyun     int angle1, angle2;
102*4882a593Smuzhiyun     int startseg, endseg;
103*4882a593Smuzhiyun     int startAngle, endAngle;
104*4882a593Smuzhiyun     int i, overlap;
105*4882a593Smuzhiyun     miZeroArcPtRec start, end;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun     l = arc->width & 1;
108*4882a593Smuzhiyun     if (arc->width == arc->height) {
109*4882a593Smuzhiyun         info->alpha = 4;
110*4882a593Smuzhiyun         info->beta = 4;
111*4882a593Smuzhiyun         info->k1 = -8;
112*4882a593Smuzhiyun         info->k3 = -16;
113*4882a593Smuzhiyun         info->b = 12;
114*4882a593Smuzhiyun         info->a = (arc->width << 2) - 12;
115*4882a593Smuzhiyun         info->d = 17 - (arc->width << 1);
116*4882a593Smuzhiyun         if (l) {
117*4882a593Smuzhiyun             info->b -= 4;
118*4882a593Smuzhiyun             info->a += 4;
119*4882a593Smuzhiyun             info->d -= 7;
120*4882a593Smuzhiyun         }
121*4882a593Smuzhiyun     }
122*4882a593Smuzhiyun     else if (!arc->width || !arc->height) {
123*4882a593Smuzhiyun         info->alpha = 0;
124*4882a593Smuzhiyun         info->beta = 0;
125*4882a593Smuzhiyun         info->k1 = 0;
126*4882a593Smuzhiyun         info->k3 = 0;
127*4882a593Smuzhiyun         info->a = -(int) arc->height;
128*4882a593Smuzhiyun         info->b = 0;
129*4882a593Smuzhiyun         info->d = -1;
130*4882a593Smuzhiyun     }
131*4882a593Smuzhiyun     else {
132*4882a593Smuzhiyun         /* initial conditions */
133*4882a593Smuzhiyun         info->alpha = (arc->width * arc->width) << 2;
134*4882a593Smuzhiyun         info->beta = (arc->height * arc->height) << 2;
135*4882a593Smuzhiyun         info->k1 = info->beta << 1;
136*4882a593Smuzhiyun         info->k3 = info->k1 + (info->alpha << 1);
137*4882a593Smuzhiyun         info->b = l ? 0 : -info->beta;
138*4882a593Smuzhiyun         info->a = info->alpha * arc->height;
139*4882a593Smuzhiyun         info->d = info->b - (info->a >> 1) - (info->alpha >> 2);
140*4882a593Smuzhiyun         if (l)
141*4882a593Smuzhiyun             info->d -= info->beta >> 2;
142*4882a593Smuzhiyun         info->a -= info->b;
143*4882a593Smuzhiyun         /* take first step, d < 0 always */
144*4882a593Smuzhiyun         info->b -= info->k1;
145*4882a593Smuzhiyun         info->a += info->k1;
146*4882a593Smuzhiyun         info->d += info->b;
147*4882a593Smuzhiyun         /* octant change, b < 0 always */
148*4882a593Smuzhiyun         info->k1 = -info->k1;
149*4882a593Smuzhiyun         info->k3 = -info->k3;
150*4882a593Smuzhiyun         info->b = -info->b;
151*4882a593Smuzhiyun         info->d = info->b - info->a - info->d;
152*4882a593Smuzhiyun         info->a = info->a - (info->b << 1);
153*4882a593Smuzhiyun     }
154*4882a593Smuzhiyun     info->dx = 1;
155*4882a593Smuzhiyun     info->dy = 0;
156*4882a593Smuzhiyun     info->w = (arc->width + 1) >> 1;
157*4882a593Smuzhiyun     info->h = arc->height >> 1;
158*4882a593Smuzhiyun     info->xorg = arc->x + (arc->width >> 1);
159*4882a593Smuzhiyun     info->yorg = arc->y;
160*4882a593Smuzhiyun     info->xorgo = info->xorg + l;
161*4882a593Smuzhiyun     info->yorgo = info->yorg + arc->height;
162*4882a593Smuzhiyun     if (!arc->width) {
163*4882a593Smuzhiyun         if (!arc->height) {
164*4882a593Smuzhiyun             info->x = 0;
165*4882a593Smuzhiyun             info->y = 0;
166*4882a593Smuzhiyun             info->initialMask = 0;
167*4882a593Smuzhiyun             info->startAngle = 0;
168*4882a593Smuzhiyun             info->endAngle = 0;
169*4882a593Smuzhiyun             info->start = oob;
170*4882a593Smuzhiyun             info->end = oob;
171*4882a593Smuzhiyun             return FALSE;
172*4882a593Smuzhiyun         }
173*4882a593Smuzhiyun         info->x = 0;
174*4882a593Smuzhiyun         info->y = 1;
175*4882a593Smuzhiyun     }
176*4882a593Smuzhiyun     else {
177*4882a593Smuzhiyun         info->x = 1;
178*4882a593Smuzhiyun         info->y = 0;
179*4882a593Smuzhiyun     }
180*4882a593Smuzhiyun     angle1 = arc->angle1;
181*4882a593Smuzhiyun     angle2 = arc->angle2;
182*4882a593Smuzhiyun     if ((angle1 == 0) && (angle2 >= FULLCIRCLE)) {
183*4882a593Smuzhiyun         startAngle = 0;
184*4882a593Smuzhiyun         endAngle = 0;
185*4882a593Smuzhiyun     }
186*4882a593Smuzhiyun     else {
187*4882a593Smuzhiyun         if (angle2 > FULLCIRCLE)
188*4882a593Smuzhiyun             angle2 = FULLCIRCLE;
189*4882a593Smuzhiyun         else if (angle2 < -FULLCIRCLE)
190*4882a593Smuzhiyun             angle2 = -FULLCIRCLE;
191*4882a593Smuzhiyun         if (angle2 < 0) {
192*4882a593Smuzhiyun             startAngle = angle1 + angle2;
193*4882a593Smuzhiyun             endAngle = angle1;
194*4882a593Smuzhiyun         }
195*4882a593Smuzhiyun         else {
196*4882a593Smuzhiyun             startAngle = angle1;
197*4882a593Smuzhiyun             endAngle = angle1 + angle2;
198*4882a593Smuzhiyun         }
199*4882a593Smuzhiyun         if (startAngle < 0)
200*4882a593Smuzhiyun             startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE;
201*4882a593Smuzhiyun         if (startAngle >= FULLCIRCLE)
202*4882a593Smuzhiyun             startAngle = startAngle % FULLCIRCLE;
203*4882a593Smuzhiyun         if (endAngle < 0)
204*4882a593Smuzhiyun             endAngle = FULLCIRCLE - (-endAngle) % FULLCIRCLE;
205*4882a593Smuzhiyun         if (endAngle >= FULLCIRCLE)
206*4882a593Smuzhiyun             endAngle = endAngle % FULLCIRCLE;
207*4882a593Smuzhiyun     }
208*4882a593Smuzhiyun     info->startAngle = startAngle;
209*4882a593Smuzhiyun     info->endAngle = endAngle;
210*4882a593Smuzhiyun     if (ok360 && (startAngle == endAngle) && arc->angle2 &&
211*4882a593Smuzhiyun         arc->width && arc->height) {
212*4882a593Smuzhiyun         info->initialMask = 0xf;
213*4882a593Smuzhiyun         info->start = oob;
214*4882a593Smuzhiyun         info->end = oob;
215*4882a593Smuzhiyun         return TRUE;
216*4882a593Smuzhiyun     }
217*4882a593Smuzhiyun     startseg = startAngle / OCTANT;
218*4882a593Smuzhiyun     if (!arc->height || (((startseg + 1) & 2) && arc->width)) {
219*4882a593Smuzhiyun         start.x = Dcos(startAngle) * ((arc->width + 1) / 2.0);
220*4882a593Smuzhiyun         if (start.x < 0)
221*4882a593Smuzhiyun             start.x = -start.x;
222*4882a593Smuzhiyun         start.y = -1;
223*4882a593Smuzhiyun     }
224*4882a593Smuzhiyun     else {
225*4882a593Smuzhiyun         start.y = Dsin(startAngle) * (arc->height / 2.0);
226*4882a593Smuzhiyun         if (start.y < 0)
227*4882a593Smuzhiyun             start.y = -start.y;
228*4882a593Smuzhiyun         start.y = info->h - start.y;
229*4882a593Smuzhiyun         start.x = 65536;
230*4882a593Smuzhiyun     }
231*4882a593Smuzhiyun     endseg = endAngle / OCTANT;
232*4882a593Smuzhiyun     if (!arc->height || (((endseg + 1) & 2) && arc->width)) {
233*4882a593Smuzhiyun         end.x = Dcos(endAngle) * ((arc->width + 1) / 2.0);
234*4882a593Smuzhiyun         if (end.x < 0)
235*4882a593Smuzhiyun             end.x = -end.x;
236*4882a593Smuzhiyun         end.y = -1;
237*4882a593Smuzhiyun     }
238*4882a593Smuzhiyun     else {
239*4882a593Smuzhiyun         end.y = Dsin(endAngle) * (arc->height / 2.0);
240*4882a593Smuzhiyun         if (end.y < 0)
241*4882a593Smuzhiyun             end.y = -end.y;
242*4882a593Smuzhiyun         end.y = info->h - end.y;
243*4882a593Smuzhiyun         end.x = 65536;
244*4882a593Smuzhiyun     }
245*4882a593Smuzhiyun     info->firstx = start.x;
246*4882a593Smuzhiyun     info->firsty = start.y;
247*4882a593Smuzhiyun     info->initialMask = 0;
248*4882a593Smuzhiyun     overlap = arc->angle2 && (endAngle <= startAngle);
249*4882a593Smuzhiyun     for (i = 0; i < 4; i++) {
250*4882a593Smuzhiyun         if (overlap ?
251*4882a593Smuzhiyun             ((i * QUADRANT <= endAngle) || ((i + 1) * QUADRANT > startAngle)) :
252*4882a593Smuzhiyun             ((i * QUADRANT <= endAngle) && ((i + 1) * QUADRANT > startAngle)))
253*4882a593Smuzhiyun             info->initialMask |= (1 << i);
254*4882a593Smuzhiyun     }
255*4882a593Smuzhiyun     start.mask = info->initialMask;
256*4882a593Smuzhiyun     end.mask = info->initialMask;
257*4882a593Smuzhiyun     startseg >>= 1;
258*4882a593Smuzhiyun     endseg >>= 1;
259*4882a593Smuzhiyun     overlap = overlap && (endseg == startseg);
260*4882a593Smuzhiyun     if (start.x != end.x || start.y != end.y || !overlap) {
261*4882a593Smuzhiyun         if (startseg & 1) {
262*4882a593Smuzhiyun             if (!overlap)
263*4882a593Smuzhiyun                 info->initialMask &= ~(1 << startseg);
264*4882a593Smuzhiyun             if (start.x > end.x || start.y > end.y)
265*4882a593Smuzhiyun                 end.mask &= ~(1 << startseg);
266*4882a593Smuzhiyun         }
267*4882a593Smuzhiyun         else {
268*4882a593Smuzhiyun             start.mask &= ~(1 << startseg);
269*4882a593Smuzhiyun             if (((start.x < end.x || start.y < end.y) ||
270*4882a593Smuzhiyun                  (start.x == end.x && start.y == end.y && (endseg & 1))) &&
271*4882a593Smuzhiyun                 !overlap)
272*4882a593Smuzhiyun                 end.mask &= ~(1 << startseg);
273*4882a593Smuzhiyun         }
274*4882a593Smuzhiyun         if (endseg & 1) {
275*4882a593Smuzhiyun             end.mask &= ~(1 << endseg);
276*4882a593Smuzhiyun             if (((start.x > end.x || start.y > end.y) ||
277*4882a593Smuzhiyun                  (start.x == end.x && start.y == end.y && !(startseg & 1))) &&
278*4882a593Smuzhiyun                 !overlap)
279*4882a593Smuzhiyun                 start.mask &= ~(1 << endseg);
280*4882a593Smuzhiyun         }
281*4882a593Smuzhiyun         else {
282*4882a593Smuzhiyun             if (!overlap)
283*4882a593Smuzhiyun                 info->initialMask &= ~(1 << endseg);
284*4882a593Smuzhiyun             if (start.x < end.x || start.y < end.y)
285*4882a593Smuzhiyun                 start.mask &= ~(1 << endseg);
286*4882a593Smuzhiyun         }
287*4882a593Smuzhiyun     }
288*4882a593Smuzhiyun     /* take care of case when start and stop are both near 45 */
289*4882a593Smuzhiyun     /* handle here rather than adding extra code to pixelization loops */
290*4882a593Smuzhiyun     if (startAngle &&
291*4882a593Smuzhiyun         ((start.y < 0 && end.y >= 0) || (start.y >= 0 && end.y < 0))) {
292*4882a593Smuzhiyun         i = (startAngle + OCTANT) % OCTANT;
293*4882a593Smuzhiyun         if (i < EPSILON45 || i > OCTANT - EPSILON45) {
294*4882a593Smuzhiyun             i = (endAngle + OCTANT) % OCTANT;
295*4882a593Smuzhiyun             if (i < EPSILON45 || i > OCTANT - EPSILON45) {
296*4882a593Smuzhiyun                 if (start.y < 0) {
297*4882a593Smuzhiyun                     i = Dsin(startAngle) * (arc->height / 2.0);
298*4882a593Smuzhiyun                     if (i < 0)
299*4882a593Smuzhiyun                         i = -i;
300*4882a593Smuzhiyun                     if (info->h - i == end.y)
301*4882a593Smuzhiyun                         start.mask = end.mask;
302*4882a593Smuzhiyun                 }
303*4882a593Smuzhiyun                 else {
304*4882a593Smuzhiyun                     i = Dsin(endAngle) * (arc->height / 2.0);
305*4882a593Smuzhiyun                     if (i < 0)
306*4882a593Smuzhiyun                         i = -i;
307*4882a593Smuzhiyun                     if (info->h - i == start.y)
308*4882a593Smuzhiyun                         end.mask = start.mask;
309*4882a593Smuzhiyun                 }
310*4882a593Smuzhiyun             }
311*4882a593Smuzhiyun         }
312*4882a593Smuzhiyun     }
313*4882a593Smuzhiyun     if (startseg & 1) {
314*4882a593Smuzhiyun         info->start = start;
315*4882a593Smuzhiyun         info->end = oob;
316*4882a593Smuzhiyun     }
317*4882a593Smuzhiyun     else {
318*4882a593Smuzhiyun         info->end = start;
319*4882a593Smuzhiyun         info->start = oob;
320*4882a593Smuzhiyun     }
321*4882a593Smuzhiyun     if (endseg & 1) {
322*4882a593Smuzhiyun         info->altend = end;
323*4882a593Smuzhiyun         if (info->altend.x < info->end.x || info->altend.y < info->end.y) {
324*4882a593Smuzhiyun             miZeroArcPtRec tmp;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun             tmp = info->altend;
327*4882a593Smuzhiyun             info->altend = info->end;
328*4882a593Smuzhiyun             info->end = tmp;
329*4882a593Smuzhiyun         }
330*4882a593Smuzhiyun         info->altstart = oob;
331*4882a593Smuzhiyun     }
332*4882a593Smuzhiyun     else {
333*4882a593Smuzhiyun         info->altstart = end;
334*4882a593Smuzhiyun         if (info->altstart.x < info->start.x ||
335*4882a593Smuzhiyun             info->altstart.y < info->start.y) {
336*4882a593Smuzhiyun             miZeroArcPtRec tmp;
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun             tmp = info->altstart;
339*4882a593Smuzhiyun             info->altstart = info->start;
340*4882a593Smuzhiyun             info->start = tmp;
341*4882a593Smuzhiyun         }
342*4882a593Smuzhiyun         info->altend = oob;
343*4882a593Smuzhiyun     }
344*4882a593Smuzhiyun     if (!info->start.x || !info->start.y) {
345*4882a593Smuzhiyun         info->initialMask = info->start.mask;
346*4882a593Smuzhiyun         info->start = info->altstart;
347*4882a593Smuzhiyun     }
348*4882a593Smuzhiyun     if (!arc->width && (arc->height == 1)) {
349*4882a593Smuzhiyun         /* kludge! */
350*4882a593Smuzhiyun         info->initialMask |= info->end.mask;
351*4882a593Smuzhiyun         info->initialMask |= info->initialMask << 1;
352*4882a593Smuzhiyun         info->end.x = 0;
353*4882a593Smuzhiyun         info->end.mask = 0;
354*4882a593Smuzhiyun     }
355*4882a593Smuzhiyun     return FALSE;
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun #define Pixelate(xval,yval) \
359*4882a593Smuzhiyun     { \
360*4882a593Smuzhiyun 	pts->x = xval; \
361*4882a593Smuzhiyun 	pts->y = yval; \
362*4882a593Smuzhiyun 	pts++; \
363*4882a593Smuzhiyun     }
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun #define DoPix(idx,xval,yval) if (mask & (1 << idx)) Pixelate(xval, yval);
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun static DDXPointPtr
miZeroArcPts(xArc * arc,DDXPointPtr pts)368*4882a593Smuzhiyun miZeroArcPts(xArc * arc, DDXPointPtr pts)
369*4882a593Smuzhiyun {
370*4882a593Smuzhiyun     miZeroArcRec info;
371*4882a593Smuzhiyun     int x, y, a, b, d, mask;
372*4882a593Smuzhiyun     int k1, k3, dx, dy;
373*4882a593Smuzhiyun     Bool do360;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun     do360 = miZeroArcSetup(arc, &info, TRUE);
376*4882a593Smuzhiyun     MIARCSETUP();
377*4882a593Smuzhiyun     mask = info.initialMask;
378*4882a593Smuzhiyun     if (!(arc->width & 1)) {
379*4882a593Smuzhiyun         DoPix(1, info.xorgo, info.yorg);
380*4882a593Smuzhiyun         DoPix(3, info.xorgo, info.yorgo);
381*4882a593Smuzhiyun     }
382*4882a593Smuzhiyun     if (!info.end.x || !info.end.y) {
383*4882a593Smuzhiyun         mask = info.end.mask;
384*4882a593Smuzhiyun         info.end = info.altend;
385*4882a593Smuzhiyun     }
386*4882a593Smuzhiyun     if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
387*4882a593Smuzhiyun         int yorgh = info.yorg + info.h;
388*4882a593Smuzhiyun         int xorghp = info.xorg + info.h;
389*4882a593Smuzhiyun         int xorghn = info.xorg - info.h;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun         while (1) {
392*4882a593Smuzhiyun             Pixelate(info.xorg + x, info.yorg + y);
393*4882a593Smuzhiyun             Pixelate(info.xorg - x, info.yorg + y);
394*4882a593Smuzhiyun             Pixelate(info.xorg - x, info.yorgo - y);
395*4882a593Smuzhiyun             Pixelate(info.xorg + x, info.yorgo - y);
396*4882a593Smuzhiyun             if (a < 0)
397*4882a593Smuzhiyun                 break;
398*4882a593Smuzhiyun             Pixelate(xorghp - y, yorgh - x);
399*4882a593Smuzhiyun             Pixelate(xorghn + y, yorgh - x);
400*4882a593Smuzhiyun             Pixelate(xorghn + y, yorgh + x);
401*4882a593Smuzhiyun             Pixelate(xorghp - y, yorgh + x);
402*4882a593Smuzhiyun             MIARCCIRCLESTEP(;
403*4882a593Smuzhiyun                 );
404*4882a593Smuzhiyun         }
405*4882a593Smuzhiyun         if (x > 1 && pts[-1].x == pts[-5].x && pts[-1].y == pts[-5].y)
406*4882a593Smuzhiyun             pts -= 4;
407*4882a593Smuzhiyun         x = info.w;
408*4882a593Smuzhiyun         y = info.h;
409*4882a593Smuzhiyun     }
410*4882a593Smuzhiyun     else if (do360) {
411*4882a593Smuzhiyun         while (y < info.h || x < info.w) {
412*4882a593Smuzhiyun             MIARCOCTANTSHIFT(;
413*4882a593Smuzhiyun                 );
414*4882a593Smuzhiyun             Pixelate(info.xorg + x, info.yorg + y);
415*4882a593Smuzhiyun             Pixelate(info.xorgo - x, info.yorg + y);
416*4882a593Smuzhiyun             Pixelate(info.xorgo - x, info.yorgo - y);
417*4882a593Smuzhiyun             Pixelate(info.xorg + x, info.yorgo - y);
418*4882a593Smuzhiyun             MIARCSTEP(;
419*4882a593Smuzhiyun                       ,;
420*4882a593Smuzhiyun                 );
421*4882a593Smuzhiyun         }
422*4882a593Smuzhiyun     }
423*4882a593Smuzhiyun     else {
424*4882a593Smuzhiyun         while (y < info.h || x < info.w) {
425*4882a593Smuzhiyun             MIARCOCTANTSHIFT(;
426*4882a593Smuzhiyun                 );
427*4882a593Smuzhiyun             if ((x == info.start.x) || (y == info.start.y)) {
428*4882a593Smuzhiyun                 mask = info.start.mask;
429*4882a593Smuzhiyun                 info.start = info.altstart;
430*4882a593Smuzhiyun             }
431*4882a593Smuzhiyun             DoPix(0, info.xorg + x, info.yorg + y);
432*4882a593Smuzhiyun             DoPix(1, info.xorgo - x, info.yorg + y);
433*4882a593Smuzhiyun             DoPix(2, info.xorgo - x, info.yorgo - y);
434*4882a593Smuzhiyun             DoPix(3, info.xorg + x, info.yorgo - y);
435*4882a593Smuzhiyun             if ((x == info.end.x) || (y == info.end.y)) {
436*4882a593Smuzhiyun                 mask = info.end.mask;
437*4882a593Smuzhiyun                 info.end = info.altend;
438*4882a593Smuzhiyun             }
439*4882a593Smuzhiyun             MIARCSTEP(;
440*4882a593Smuzhiyun                       ,;
441*4882a593Smuzhiyun                 );
442*4882a593Smuzhiyun         }
443*4882a593Smuzhiyun     }
444*4882a593Smuzhiyun     if ((x == info.start.x) || (y == info.start.y))
445*4882a593Smuzhiyun         mask = info.start.mask;
446*4882a593Smuzhiyun     DoPix(0, info.xorg + x, info.yorg + y);
447*4882a593Smuzhiyun     DoPix(2, info.xorgo - x, info.yorgo - y);
448*4882a593Smuzhiyun     if (arc->height & 1) {
449*4882a593Smuzhiyun         DoPix(1, info.xorgo - x, info.yorg + y);
450*4882a593Smuzhiyun         DoPix(3, info.xorg + x, info.yorgo - y);
451*4882a593Smuzhiyun     }
452*4882a593Smuzhiyun     return pts;
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun #undef DoPix
456*4882a593Smuzhiyun #define DoPix(idx,xval,yval) \
457*4882a593Smuzhiyun     if (mask & (1 << idx)) \
458*4882a593Smuzhiyun     { \
459*4882a593Smuzhiyun 	arcPts[idx]->x = xval; \
460*4882a593Smuzhiyun 	arcPts[idx]->y = yval; \
461*4882a593Smuzhiyun 	arcPts[idx]++; \
462*4882a593Smuzhiyun     }
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun static void
miZeroArcDashPts(GCPtr pGC,xArc * arc,DashInfo * dinfo,DDXPointPtr points,int maxPts,DDXPointPtr * evenPts,DDXPointPtr * oddPts)465*4882a593Smuzhiyun miZeroArcDashPts(GCPtr pGC,
466*4882a593Smuzhiyun                  xArc * arc,
467*4882a593Smuzhiyun                  DashInfo * dinfo,
468*4882a593Smuzhiyun                  DDXPointPtr points,
469*4882a593Smuzhiyun                  int maxPts, DDXPointPtr * evenPts, DDXPointPtr * oddPts)
470*4882a593Smuzhiyun {
471*4882a593Smuzhiyun     miZeroArcRec info;
472*4882a593Smuzhiyun     int x, y, a, b, d, mask;
473*4882a593Smuzhiyun     int k1, k3, dx, dy;
474*4882a593Smuzhiyun     int dashRemaining;
475*4882a593Smuzhiyun     DDXPointPtr arcPts[4];
476*4882a593Smuzhiyun     DDXPointPtr startPts[5], endPts[5];
477*4882a593Smuzhiyun     int deltas[5];
478*4882a593Smuzhiyun     DDXPointPtr startPt, pt, lastPt, pts;
479*4882a593Smuzhiyun     int i, j, delta, ptsdelta, seg, startseg;
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun     for (i = 0; i < 4; i++)
482*4882a593Smuzhiyun         arcPts[i] = points + (i * maxPts);
483*4882a593Smuzhiyun     (void) miZeroArcSetup(arc, &info, FALSE);
484*4882a593Smuzhiyun     MIARCSETUP();
485*4882a593Smuzhiyun     mask = info.initialMask;
486*4882a593Smuzhiyun     startseg = info.startAngle / QUADRANT;
487*4882a593Smuzhiyun     startPt = arcPts[startseg];
488*4882a593Smuzhiyun     if (!(arc->width & 1)) {
489*4882a593Smuzhiyun         DoPix(1, info.xorgo, info.yorg);
490*4882a593Smuzhiyun         DoPix(3, info.xorgo, info.yorgo);
491*4882a593Smuzhiyun     }
492*4882a593Smuzhiyun     if (!info.end.x || !info.end.y) {
493*4882a593Smuzhiyun         mask = info.end.mask;
494*4882a593Smuzhiyun         info.end = info.altend;
495*4882a593Smuzhiyun     }
496*4882a593Smuzhiyun     while (y < info.h || x < info.w) {
497*4882a593Smuzhiyun         MIARCOCTANTSHIFT(;
498*4882a593Smuzhiyun             );
499*4882a593Smuzhiyun         if ((x == info.firstx) || (y == info.firsty))
500*4882a593Smuzhiyun             startPt = arcPts[startseg];
501*4882a593Smuzhiyun         if ((x == info.start.x) || (y == info.start.y)) {
502*4882a593Smuzhiyun             mask = info.start.mask;
503*4882a593Smuzhiyun             info.start = info.altstart;
504*4882a593Smuzhiyun         }
505*4882a593Smuzhiyun         DoPix(0, info.xorg + x, info.yorg + y);
506*4882a593Smuzhiyun         DoPix(1, info.xorgo - x, info.yorg + y);
507*4882a593Smuzhiyun         DoPix(2, info.xorgo - x, info.yorgo - y);
508*4882a593Smuzhiyun         DoPix(3, info.xorg + x, info.yorgo - y);
509*4882a593Smuzhiyun         if ((x == info.end.x) || (y == info.end.y)) {
510*4882a593Smuzhiyun             mask = info.end.mask;
511*4882a593Smuzhiyun             info.end = info.altend;
512*4882a593Smuzhiyun         }
513*4882a593Smuzhiyun         MIARCSTEP(;
514*4882a593Smuzhiyun                   ,;
515*4882a593Smuzhiyun             );
516*4882a593Smuzhiyun     }
517*4882a593Smuzhiyun     if ((x == info.firstx) || (y == info.firsty))
518*4882a593Smuzhiyun         startPt = arcPts[startseg];
519*4882a593Smuzhiyun     if ((x == info.start.x) || (y == info.start.y))
520*4882a593Smuzhiyun         mask = info.start.mask;
521*4882a593Smuzhiyun     DoPix(0, info.xorg + x, info.yorg + y);
522*4882a593Smuzhiyun     DoPix(2, info.xorgo - x, info.yorgo - y);
523*4882a593Smuzhiyun     if (arc->height & 1) {
524*4882a593Smuzhiyun         DoPix(1, info.xorgo - x, info.yorg + y);
525*4882a593Smuzhiyun         DoPix(3, info.xorg + x, info.yorgo - y);
526*4882a593Smuzhiyun     }
527*4882a593Smuzhiyun     for (i = 0; i < 4; i++) {
528*4882a593Smuzhiyun         seg = (startseg + i) & 3;
529*4882a593Smuzhiyun         pt = points + (seg * maxPts);
530*4882a593Smuzhiyun         if (seg & 1) {
531*4882a593Smuzhiyun             startPts[i] = pt;
532*4882a593Smuzhiyun             endPts[i] = arcPts[seg];
533*4882a593Smuzhiyun             deltas[i] = 1;
534*4882a593Smuzhiyun         }
535*4882a593Smuzhiyun         else {
536*4882a593Smuzhiyun             startPts[i] = arcPts[seg] - 1;
537*4882a593Smuzhiyun             endPts[i] = pt - 1;
538*4882a593Smuzhiyun             deltas[i] = -1;
539*4882a593Smuzhiyun         }
540*4882a593Smuzhiyun     }
541*4882a593Smuzhiyun     startPts[4] = startPts[0];
542*4882a593Smuzhiyun     endPts[4] = startPt;
543*4882a593Smuzhiyun     startPts[0] = startPt;
544*4882a593Smuzhiyun     if (startseg & 1) {
545*4882a593Smuzhiyun         if (startPts[4] != endPts[4])
546*4882a593Smuzhiyun             endPts[4]--;
547*4882a593Smuzhiyun         deltas[4] = 1;
548*4882a593Smuzhiyun     }
549*4882a593Smuzhiyun     else {
550*4882a593Smuzhiyun         if (startPts[0] > startPts[4])
551*4882a593Smuzhiyun             startPts[0]--;
552*4882a593Smuzhiyun         if (startPts[4] < endPts[4])
553*4882a593Smuzhiyun             endPts[4]--;
554*4882a593Smuzhiyun         deltas[4] = -1;
555*4882a593Smuzhiyun     }
556*4882a593Smuzhiyun     if (arc->angle2 < 0) {
557*4882a593Smuzhiyun         DDXPointPtr tmps, tmpe;
558*4882a593Smuzhiyun         int tmpd;
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun         tmpd = deltas[0];
561*4882a593Smuzhiyun         tmps = startPts[0] - tmpd;
562*4882a593Smuzhiyun         tmpe = endPts[0] - tmpd;
563*4882a593Smuzhiyun         startPts[0] = endPts[4] - deltas[4];
564*4882a593Smuzhiyun         endPts[0] = startPts[4] - deltas[4];
565*4882a593Smuzhiyun         deltas[0] = -deltas[4];
566*4882a593Smuzhiyun         startPts[4] = tmpe;
567*4882a593Smuzhiyun         endPts[4] = tmps;
568*4882a593Smuzhiyun         deltas[4] = -tmpd;
569*4882a593Smuzhiyun         tmpd = deltas[1];
570*4882a593Smuzhiyun         tmps = startPts[1] - tmpd;
571*4882a593Smuzhiyun         tmpe = endPts[1] - tmpd;
572*4882a593Smuzhiyun         startPts[1] = endPts[3] - deltas[3];
573*4882a593Smuzhiyun         endPts[1] = startPts[3] - deltas[3];
574*4882a593Smuzhiyun         deltas[1] = -deltas[3];
575*4882a593Smuzhiyun         startPts[3] = tmpe;
576*4882a593Smuzhiyun         endPts[3] = tmps;
577*4882a593Smuzhiyun         deltas[3] = -tmpd;
578*4882a593Smuzhiyun         tmps = startPts[2] - deltas[2];
579*4882a593Smuzhiyun         startPts[2] = endPts[2] - deltas[2];
580*4882a593Smuzhiyun         endPts[2] = tmps;
581*4882a593Smuzhiyun         deltas[2] = -deltas[2];
582*4882a593Smuzhiyun     }
583*4882a593Smuzhiyun     for (i = 0; i < 5 && startPts[i] == endPts[i]; i++);
584*4882a593Smuzhiyun     if (i == 5)
585*4882a593Smuzhiyun         return;
586*4882a593Smuzhiyun     pt = startPts[i];
587*4882a593Smuzhiyun     for (j = 4; startPts[j] == endPts[j]; j--);
588*4882a593Smuzhiyun     lastPt = endPts[j] - deltas[j];
589*4882a593Smuzhiyun     if (dinfo->haveLast &&
590*4882a593Smuzhiyun         (pt->x == dinfo->endPt.x) && (pt->y == dinfo->endPt.y)) {
591*4882a593Smuzhiyun         startPts[i] += deltas[i];
592*4882a593Smuzhiyun     }
593*4882a593Smuzhiyun     else {
594*4882a593Smuzhiyun         dinfo->dashIndex = dinfo->dashIndexInit;
595*4882a593Smuzhiyun         dinfo->dashOffset = dinfo->dashOffsetInit;
596*4882a593Smuzhiyun     }
597*4882a593Smuzhiyun     if (!dinfo->skipStart && (info.startAngle != info.endAngle)) {
598*4882a593Smuzhiyun         dinfo->startPt = *pt;
599*4882a593Smuzhiyun         dinfo->haveStart = TRUE;
600*4882a593Smuzhiyun     }
601*4882a593Smuzhiyun     else if (!dinfo->skipLast && dinfo->haveStart &&
602*4882a593Smuzhiyun              (lastPt->x == dinfo->startPt.x) &&
603*4882a593Smuzhiyun              (lastPt->y == dinfo->startPt.y) && (lastPt != startPts[i]))
604*4882a593Smuzhiyun         endPts[j] = lastPt;
605*4882a593Smuzhiyun     if (info.startAngle != info.endAngle) {
606*4882a593Smuzhiyun         dinfo->haveLast = TRUE;
607*4882a593Smuzhiyun         dinfo->endPt = *lastPt;
608*4882a593Smuzhiyun     }
609*4882a593Smuzhiyun     dashRemaining = pGC->dash[dinfo->dashIndex] - dinfo->dashOffset;
610*4882a593Smuzhiyun     for (i = 0; i < 5; i++) {
611*4882a593Smuzhiyun         pt = startPts[i];
612*4882a593Smuzhiyun         lastPt = endPts[i];
613*4882a593Smuzhiyun         delta = deltas[i];
614*4882a593Smuzhiyun         while (pt != lastPt) {
615*4882a593Smuzhiyun             if (dinfo->dashIndex & 1) {
616*4882a593Smuzhiyun                 pts = *oddPts;
617*4882a593Smuzhiyun                 ptsdelta = -1;
618*4882a593Smuzhiyun             }
619*4882a593Smuzhiyun             else {
620*4882a593Smuzhiyun                 pts = *evenPts;
621*4882a593Smuzhiyun                 ptsdelta = 1;
622*4882a593Smuzhiyun             }
623*4882a593Smuzhiyun             while ((pt != lastPt) && --dashRemaining >= 0) {
624*4882a593Smuzhiyun                 *pts = *pt;
625*4882a593Smuzhiyun                 pts += ptsdelta;
626*4882a593Smuzhiyun                 pt += delta;
627*4882a593Smuzhiyun             }
628*4882a593Smuzhiyun             if (dinfo->dashIndex & 1)
629*4882a593Smuzhiyun                 *oddPts = pts;
630*4882a593Smuzhiyun             else
631*4882a593Smuzhiyun                 *evenPts = pts;
632*4882a593Smuzhiyun             if (dashRemaining <= 0) {
633*4882a593Smuzhiyun                 if (++(dinfo->dashIndex) == pGC->numInDashList)
634*4882a593Smuzhiyun                     dinfo->dashIndex = 0;
635*4882a593Smuzhiyun                 dashRemaining = pGC->dash[dinfo->dashIndex];
636*4882a593Smuzhiyun             }
637*4882a593Smuzhiyun         }
638*4882a593Smuzhiyun     }
639*4882a593Smuzhiyun     dinfo->dashOffset = pGC->dash[dinfo->dashIndex] - dashRemaining;
640*4882a593Smuzhiyun }
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun void
miZeroPolyArc(DrawablePtr pDraw,GCPtr pGC,int narcs,xArc * parcs)643*4882a593Smuzhiyun miZeroPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
644*4882a593Smuzhiyun {
645*4882a593Smuzhiyun     int maxPts = 0;
646*4882a593Smuzhiyun     int n, maxw = 0;
647*4882a593Smuzhiyun     xArc *arc;
648*4882a593Smuzhiyun     int i;
649*4882a593Smuzhiyun     DDXPointPtr points, pts, oddPts = NULL;
650*4882a593Smuzhiyun     DDXPointPtr pt;
651*4882a593Smuzhiyun     int numPts;
652*4882a593Smuzhiyun     Bool dospans;
653*4882a593Smuzhiyun     int *widths = NULL;
654*4882a593Smuzhiyun     XID fgPixel = pGC->fgPixel;
655*4882a593Smuzhiyun     DashInfo dinfo;
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun     for (arc = parcs, i = narcs; --i >= 0; arc++) {
658*4882a593Smuzhiyun         if (!miCanZeroArc(arc))
659*4882a593Smuzhiyun             miWideArc(pDraw, pGC, 1, arc);
660*4882a593Smuzhiyun         else {
661*4882a593Smuzhiyun             if (arc->width > arc->height)
662*4882a593Smuzhiyun                 n = arc->width + (arc->height >> 1);
663*4882a593Smuzhiyun             else
664*4882a593Smuzhiyun                 n = arc->height + (arc->width >> 1);
665*4882a593Smuzhiyun             if (n > maxPts)
666*4882a593Smuzhiyun                 maxPts = n;
667*4882a593Smuzhiyun         }
668*4882a593Smuzhiyun     }
669*4882a593Smuzhiyun     if (!maxPts)
670*4882a593Smuzhiyun         return;
671*4882a593Smuzhiyun     numPts = maxPts << 2;
672*4882a593Smuzhiyun     dospans = (pGC->fillStyle != FillSolid);
673*4882a593Smuzhiyun     if (dospans) {
674*4882a593Smuzhiyun         widths = xallocarray(numPts, sizeof(int));
675*4882a593Smuzhiyun         if (!widths)
676*4882a593Smuzhiyun             return;
677*4882a593Smuzhiyun         maxw = 0;
678*4882a593Smuzhiyun     }
679*4882a593Smuzhiyun     if (pGC->lineStyle != LineSolid) {
680*4882a593Smuzhiyun         numPts <<= 1;
681*4882a593Smuzhiyun         dinfo.haveStart = FALSE;
682*4882a593Smuzhiyun         dinfo.skipStart = FALSE;
683*4882a593Smuzhiyun         dinfo.haveLast = FALSE;
684*4882a593Smuzhiyun         dinfo.dashIndexInit = 0;
685*4882a593Smuzhiyun         dinfo.dashOffsetInit = 0;
686*4882a593Smuzhiyun         miStepDash((int) pGC->dashOffset, &dinfo.dashIndexInit,
687*4882a593Smuzhiyun                    (unsigned char *) pGC->dash, (int) pGC->numInDashList,
688*4882a593Smuzhiyun                    &dinfo.dashOffsetInit);
689*4882a593Smuzhiyun     }
690*4882a593Smuzhiyun     points = xallocarray(numPts, sizeof(DDXPointRec));
691*4882a593Smuzhiyun     if (!points) {
692*4882a593Smuzhiyun         if (dospans) {
693*4882a593Smuzhiyun             free(widths);
694*4882a593Smuzhiyun         }
695*4882a593Smuzhiyun         return;
696*4882a593Smuzhiyun     }
697*4882a593Smuzhiyun     for (arc = parcs, i = narcs; --i >= 0; arc++) {
698*4882a593Smuzhiyun         if (miCanZeroArc(arc)) {
699*4882a593Smuzhiyun             if (pGC->lineStyle == LineSolid)
700*4882a593Smuzhiyun                 pts = miZeroArcPts(arc, points);
701*4882a593Smuzhiyun             else {
702*4882a593Smuzhiyun                 pts = points;
703*4882a593Smuzhiyun                 oddPts = &points[(numPts >> 1) - 1];
704*4882a593Smuzhiyun                 dinfo.skipLast = i;
705*4882a593Smuzhiyun                 miZeroArcDashPts(pGC, arc, &dinfo,
706*4882a593Smuzhiyun                                  oddPts + 1, maxPts, &pts, &oddPts);
707*4882a593Smuzhiyun                 dinfo.skipStart = TRUE;
708*4882a593Smuzhiyun             }
709*4882a593Smuzhiyun             n = pts - points;
710*4882a593Smuzhiyun             if (!dospans)
711*4882a593Smuzhiyun                 (*pGC->ops->PolyPoint) (pDraw, pGC, CoordModeOrigin, n, points);
712*4882a593Smuzhiyun             else {
713*4882a593Smuzhiyun                 if (n > maxw) {
714*4882a593Smuzhiyun                     while (maxw < n)
715*4882a593Smuzhiyun                         widths[maxw++] = 1;
716*4882a593Smuzhiyun                 }
717*4882a593Smuzhiyun                 if (pGC->miTranslate) {
718*4882a593Smuzhiyun                     for (pt = points; pt != pts; pt++) {
719*4882a593Smuzhiyun                         pt->x += pDraw->x;
720*4882a593Smuzhiyun                         pt->y += pDraw->y;
721*4882a593Smuzhiyun                     }
722*4882a593Smuzhiyun                 }
723*4882a593Smuzhiyun                 (*pGC->ops->FillSpans) (pDraw, pGC, n, points, widths, FALSE);
724*4882a593Smuzhiyun             }
725*4882a593Smuzhiyun             if (pGC->lineStyle != LineDoubleDash)
726*4882a593Smuzhiyun                 continue;
727*4882a593Smuzhiyun             if ((pGC->fillStyle == FillSolid) ||
728*4882a593Smuzhiyun                 (pGC->fillStyle == FillStippled)) {
729*4882a593Smuzhiyun                 ChangeGCVal gcval;
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun                 gcval.val = pGC->bgPixel;
732*4882a593Smuzhiyun                 ChangeGC(NullClient, pGC, GCForeground, &gcval);
733*4882a593Smuzhiyun                 ValidateGC(pDraw, pGC);
734*4882a593Smuzhiyun             }
735*4882a593Smuzhiyun             pts = &points[numPts >> 1];
736*4882a593Smuzhiyun             oddPts++;
737*4882a593Smuzhiyun             n = pts - oddPts;
738*4882a593Smuzhiyun             if (!dospans)
739*4882a593Smuzhiyun                 (*pGC->ops->PolyPoint) (pDraw, pGC, CoordModeOrigin, n, oddPts);
740*4882a593Smuzhiyun             else {
741*4882a593Smuzhiyun                 if (n > maxw) {
742*4882a593Smuzhiyun                     while (maxw < n)
743*4882a593Smuzhiyun                         widths[maxw++] = 1;
744*4882a593Smuzhiyun                 }
745*4882a593Smuzhiyun                 if (pGC->miTranslate) {
746*4882a593Smuzhiyun                     for (pt = oddPts; pt != pts; pt++) {
747*4882a593Smuzhiyun                         pt->x += pDraw->x;
748*4882a593Smuzhiyun                         pt->y += pDraw->y;
749*4882a593Smuzhiyun                     }
750*4882a593Smuzhiyun                 }
751*4882a593Smuzhiyun                 (*pGC->ops->FillSpans) (pDraw, pGC, n, oddPts, widths, FALSE);
752*4882a593Smuzhiyun             }
753*4882a593Smuzhiyun             if ((pGC->fillStyle == FillSolid) ||
754*4882a593Smuzhiyun                 (pGC->fillStyle == FillStippled)) {
755*4882a593Smuzhiyun                 ChangeGCVal gcval;
756*4882a593Smuzhiyun 
757*4882a593Smuzhiyun                 gcval.val = fgPixel;
758*4882a593Smuzhiyun                 ChangeGC(NullClient, pGC, GCForeground, &gcval);
759*4882a593Smuzhiyun                 ValidateGC(pDraw, pGC);
760*4882a593Smuzhiyun             }
761*4882a593Smuzhiyun         }
762*4882a593Smuzhiyun     }
763*4882a593Smuzhiyun     free(points);
764*4882a593Smuzhiyun     if (dospans) {
765*4882a593Smuzhiyun         free(widths);
766*4882a593Smuzhiyun     }
767*4882a593Smuzhiyun }
768