1 /************************************************************
3 Copyright (c) 1989 X Consortium
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:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
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.
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.
26 ********************************************************/
28 /* $XConsortium: cfbfillarc.c /main/17 1995/12/06 16:57:18 dpw $ */
29 /* $XFree86: xc/programs/Xserver/cfb/cfbfillarc.c,v 3.1 1996/08/13 11:27:33 dawes Exp $ */
32 #include "Xprotostr.h"
33 #include "miscstruct.h"
35 #include "pixmapstr.h"
36 #include "scrnintstr.h"
38 #include "cfbmskbits.h"
39 #include "mifillarc.h"
43 /* gcc 1.35 is stupid */
44 #if defined(__GNUC__) && __GNUC__ < 2 && defined(mc68020)
45 #define STUPID volatile
51 RROP_NAME(cfbFillEllipseSolid) (pDraw, pGC, arc)
57 STUPID int yk, xk, ym, xm, dx, dy, xorg, yorg;
60 unsigned char *addrlt, *addrlb;
62 unsigned long *addrlt, *addrlb;
64 register unsigned long *addrl;
70 unsigned long startmask, endmask;
78 cfbGetByteWidthAndPointer (pDraw, nlwidth, addrlt)
80 cfbGetLongWidthAndPointer (pDraw, nlwidth, addrlt)
84 miFillArcSetup(arc, &info);
89 addrlt += nlwidth * (yorg - y);
90 addrlb += nlwidth * (yorg + y + dy);
100 xpos3 = (xpos * 3) & ~0x03;
101 addrl = (unsigned long *)((char *)addrlt + xpos3);
103 RROP_SOLID24(addrl, xpos);
104 if (miFillArcLower(slw)){
105 addrl = (unsigned long *)((char *)addrlb + xpos3);
106 RROP_SOLID24(addrl, xpos);
110 maskbits(xpos, slw, startmask, endmask, nlmiddle);
114 RROP_SOLID_MASK(addrl, startmask, pidx-1);
121 RROP_SOLID(addrl, pidx);
127 RROP_SOLID_MASK(addrl, endmask, pidx);
128 if (!miFillArcLower(slw))
130 addrl = (unsigned long *)((char *)addrlb + xpos3);
133 RROP_SOLID_MASK(addrl, startmask, pidx-1);
140 RROP_SOLID(addrl, pidx);
146 RROP_SOLID_MASK(addrl, endmask, pidx);
147 #else /* PSZ == 24 */
148 addrl = addrlt + (xpos >> PWSH);
149 if (((xpos & PIM) + slw) <= PPW)
151 maskpartialbits(xpos, slw, startmask);
152 RROP_SOLID_MASK(addrl,startmask);
153 if (miFillArcLower(slw))
155 addrl = addrlb + (xpos >> PWSH);
156 RROP_SOLID_MASK(addrl, startmask);
160 maskbits(xpos, slw, startmask, endmask, nlmiddle);
163 RROP_SOLID_MASK(addrl, startmask);
170 RROP_SOLID_MASK(addrl, endmask);
171 if (!miFillArcLower(slw))
173 addrl = addrlb + (xpos >> PWSH);
176 RROP_SOLID_MASK(addrl, startmask);
182 RROP_SOLID_MASK(addrl, endmask);
183 #endif /* PSZ == 24 */
188 #define FILLSPAN(xl,xr,addr) \
191 addrl = (unsigned long *)((char *)addr + ((xl * 3) & ~0x03)); \
194 RROP_SOLID24(addrl, xl); \
196 maskbits(xl, n, startmask, endmask, n); \
199 RROP_SOLID_MASK(addrl, startmask, pidx-1); \
205 RROP_SOLID(addrl, pidx); \
211 RROP_SOLID_MASK(addrl, endmask, pidx); \
214 #else /* PSZ == 24 */
215 #define FILLSPAN(xl,xr,addr) \
219 addrl = addr + (xl >> PWSH); \
220 if (((xl & PIM) + n) <= PPW) \
222 maskpartialbits(xl, n, startmask); \
223 RROP_SOLID_MASK(addrl, startmask); \
227 maskbits(xl, n, startmask, endmask, n); \
230 RROP_SOLID_MASK(addrl, startmask); \
239 RROP_SOLID_MASK(addrl, endmask); \
242 #endif /* PSZ == 24 */
244 #define FILLSLICESPANS(flip,addr) \
247 FILLSPAN(xl, xr, addr); \
252 FILLSPAN(xc, xr, addr); \
254 FILLSPAN(xl, xc, addr); \
258 RROP_NAME(cfbFillArcSliceSolid)(pDraw, pGC, arc)
263 int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
264 register int x, y, e;
269 unsigned char *addrlt, *addrlb;
271 unsigned long *addrlt, *addrlb;
273 register unsigned long *addrl;
277 unsigned long startmask, endmask;
280 #endif /* PSZ == 24 */
283 cfbGetByteWidthAndPointer (pDraw, nlwidth, addrlt)
285 cfbGetLongWidthAndPointer (pDraw, nlwidth, addrlt)
289 miFillArcSetup(arc, &info);
290 miFillArcSliceSetup(arc, &slice, pGC);
295 addrlt += nlwidth * (yorg - y);
296 addrlb += nlwidth * (yorg + y + dy);
297 slice.edge1.x += pDraw->x;
298 slice.edge2.x += pDraw->x;
304 MIARCSLICESTEP(slice.edge1);
305 MIARCSLICESTEP(slice.edge2);
306 if (miFillSliceUpper(slice))
308 MIARCSLICEUPPER(xl, xr, slice, slw);
309 FILLSLICESPANS(slice.flip_top, addrlt);
311 if (miFillSliceLower(slice))
313 MIARCSLICELOWER(xl, xr, slice, slw);
314 FILLSLICESPANS(slice.flip_bot, addrlb);
320 RROP_NAME(cfbPolyFillArcSolid) (pDraw, pGC, narcs, parcs)
332 cclip = cfbGetCompositeClip(pGC);
333 for (arc = parcs, i = narcs; --i >= 0; arc++)
335 if (miFillArcEmpty(arc))
337 if (miCanFillArc(arc))
339 box.x1 = arc->x + pDraw->x;
340 box.y1 = arc->y + pDraw->y;
342 * Because box.x2 and box.y2 get truncated to 16 bits, and the
343 * RECT_IN_REGION test treats the resulting number as a signed
344 * integer, the RECT_IN_REGION test alone can go the wrong way.
345 * This can result in a server crash because the rendering
346 * routines in this file deal directly with cpu addresses
347 * of pixels to be stored, and do not clip or otherwise check
348 * that all such addresses are within their respective pixmaps.
349 * So we only allow the RECT_IN_REGION test to be used for
350 * values that can be expressed correctly in a signed short.
352 x2 = box.x1 + (int)arc->width + 1;
354 y2 = box.y1 + (int)arc->height + 1;
356 if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
357 (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
359 if ((arc->angle2 >= FULLCIRCLE) ||
360 (arc->angle2 <= -FULLCIRCLE))
361 RROP_NAME(cfbFillEllipseSolid)(pDraw, pGC, arc);
363 RROP_NAME(cfbFillArcSliceSolid)(pDraw, pGC, arc);
367 miPolyFillArc(pDraw, pGC, 1, arc);