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: mfbzerarc.c /main/21 1995/12/06 16:55:48 dpw $ */
29 /* $XFree86: xc/programs/Xserver/mfb/mfbzerarc.c,v 3.1 1996/01/05 13:19:46 dawes Exp $ */
32 * "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
33 * by M. L. V. Pitteway
34 * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
38 #include "Xprotostr.h"
39 #include "miscstruct.h"
41 #include "pixmapstr.h"
42 #include "scrnintstr.h"
49 * Note: LEFTMOST must be the bit leftmost in the actual screen
50 * representation. This depends also on the IMAGE_BYTE_ORDER.
51 * LONG2CHARS() takes care of the re-ordering as required. (DHD)
53 #if (BITMAP_BIT_ORDER == MSBFirst)
54 #define LEFTMOST ((PixelType) LONG2CHARS(((unsigned long)1 << PLST)))
56 #define LEFTMOST ((PixelType) LONG2CHARS(1))
59 #define PixelateWhite(addr,yoff,xoff) \
60 *mfbScanlineOffset(addr, (yoff)+((xoff)>>PWSH)) |= \
61 SCRRIGHT (LEFTMOST, ((xoff) & PIM))
62 #define PixelateBlack(addr,yoff,xoff) \
63 *mfbScanlineOffset(addr, (yoff)+((xoff)>>PWSH)) &= \
64 ~(SCRRIGHT (LEFTMOST, ((xoff) & PIM)))
66 #define Pixelate(base,yoff,xoff) \
68 paddr = mfbScanlineOffset(base, (yoff) + ((xoff)>>PWSH)); \
69 pmask = SCRRIGHT(LEFTMOST, (xoff) & PIM); \
70 *paddr = (*paddr & ~pmask) | (pixel & pmask); \
73 #define DoPix(bit,base,yoff,xoff) if (mask & bit) Pixelate(base,yoff,xoff);
76 mfbZeroArcSS(pDraw, pGC, arc)
83 register int x, y, a, b, d, mask;
84 register int k1, k3, dx, dy;
86 PixelType *yorgl, *yorgol;
88 int nlwidth, yoffset, dyoffset;
90 register PixelType *paddr;
92 if (((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop ==
98 mfbGetPixelWidthAndPointer(pDraw, nlwidth, addrl);
99 do360 = miZeroArcSetup(arc, &info, TRUE);
100 yorgl = addrl + ((info.yorg + pDraw->y) * nlwidth);
101 yorgol = addrl + ((info.yorgo + pDraw->y) * nlwidth);
102 info.xorg += pDraw->x;
103 info.xorgo += pDraw->x;
105 yoffset = y ? nlwidth : 0;
107 mask = info.initialMask;
108 if (!(arc->width & 1))
110 DoPix(2, yorgl, 0, info.xorgo);
111 DoPix(8, yorgol, 0, info.xorgo);
113 if (!info.end.x || !info.end.y)
115 mask = info.end.mask;
116 info.end = info.altend;
118 if (do360 && (arc->width == arc->height) && !(arc->width & 1))
120 int xoffset = nlwidth;
121 PixelType *yorghl = mfbScanlineDeltaNoBankSwitch(yorgl, info.h, nlwidth);
122 int xorghp = info.xorg + info.h;
123 int xorghn = info.xorg - info.h;
129 PixelateWhite(yorgl, yoffset, info.xorg + x);
130 PixelateWhite(yorgl, yoffset, info.xorg - x);
131 PixelateWhite(yorgol, -yoffset, info.xorg - x);
132 PixelateWhite(yorgol, -yoffset, info.xorg + x);
135 PixelateWhite(yorghl, -xoffset, xorghp - y);
136 PixelateWhite(yorghl, -xoffset, xorghn + y);
137 PixelateWhite(yorghl, xoffset, xorghn + y);
138 PixelateWhite(yorghl, xoffset, xorghp - y);
140 MIARCCIRCLESTEP(yoffset += nlwidth;);
147 PixelateBlack(yorgl, yoffset, info.xorg + x);
148 PixelateBlack(yorgl, yoffset, info.xorg - x);
149 PixelateBlack(yorgol, -yoffset, info.xorg - x);
150 PixelateBlack(yorgol, -yoffset, info.xorg + x);
153 PixelateBlack(yorghl, -xoffset, xorghp - y);
154 PixelateBlack(yorghl, -xoffset, xorghn + y);
155 PixelateBlack(yorghl, xoffset, xorghn + y);
156 PixelateBlack(yorghl, xoffset, xorghp - y);
158 MIARCCIRCLESTEP(yoffset += nlwidth;);
162 yoffset = info.h * nlwidth;
166 while (y < info.h || x < info.w)
168 MIARCOCTANTSHIFT(dyoffset = nlwidth;);
169 Pixelate(yorgl, yoffset, info.xorg + x);
170 Pixelate(yorgl, yoffset, info.xorgo - x);
171 Pixelate(yorgol, -yoffset, info.xorgo - x);
172 Pixelate(yorgol, -yoffset, info.xorg + x);
173 MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;);
178 while (y < info.h || x < info.w)
180 MIARCOCTANTSHIFT(dyoffset = nlwidth;);
181 if ((x == info.start.x) || (y == info.start.y))
183 mask = info.start.mask;
184 info.start = info.altstart;
186 DoPix(1, yorgl, yoffset, info.xorg + x);
187 DoPix(2, yorgl, yoffset, info.xorgo - x);
188 DoPix(4, yorgol, -yoffset, info.xorgo - x);
189 DoPix(8, yorgol, -yoffset, info.xorg + x);
190 if ((x == info.end.x) || (y == info.end.y))
192 mask = info.end.mask;
193 info.end = info.altend;
195 MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;);
198 if ((x == info.start.x) || (y == info.start.y))
199 mask = info.start.mask;
200 DoPix(1, yorgl, yoffset, info.xorg + x);
201 DoPix(4, yorgol, -yoffset, info.xorgo - x);
204 DoPix(2, yorgl, yoffset, info.xorgo - x);
205 DoPix(8, yorgol, -yoffset, info.xorg + x);
210 mfbZeroPolyArcSS(pDraw, pGC, narcs, parcs)
222 if (!pGC->planemask & 1)
224 cclip = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip;
225 for (arc = parcs, i = narcs; --i >= 0; arc++)
227 if (miCanZeroArc(arc))
229 box.x1 = arc->x + pDraw->x;
230 box.y1 = arc->y + pDraw->y;
232 * Because box.x2 and box.y2 get truncated to 16 bits, and the
233 * RECT_IN_REGION test treats the resulting number as a signed
234 * integer, the RECT_IN_REGION test alone can go the wrong way.
235 * This can result in a server crash because the rendering
236 * routines in this file deal directly with cpu addresses
237 * of pixels to be stored, and do not clip or otherwise check
238 * that all such addresses are within their respective pixmaps.
239 * So we only allow the RECT_IN_REGION test to be used for
240 * values that can be expressed correctly in a signed short.
242 x2 = box.x1 + (int)arc->width + 1;
244 y2 = box.y1 + (int)arc->height + 1;
246 if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
247 (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
248 mfbZeroArcSS(pDraw, pGC, arc);
250 miZeroPolyArc(pDraw, pGC, 1, arc);
253 miPolyArc(pDraw, pGC, 1, arc);