First import
[xorg_rtime.git] / xorg-server-1.4 / mfb / mfbzerarc.c
blob964e2f100855d02bd18797542b4d422485511ff1
1 /************************************************************
3 Copyright 1989, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
25 ********************************************************/
28 /* Derived from:
29 * "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
30 * by M. L. V. Pitteway
31 * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
34 #ifdef HAVE_DIX_CONFIG_H
35 #include <dix-config.h>
36 #endif
38 #include <limits.h>
40 #include <X11/X.h>
41 #include <X11/Xprotostr.h>
42 #include "regionstr.h"
43 #include "gcstruct.h"
44 #include "pixmapstr.h"
45 #include "scrnintstr.h"
46 #include "mfb.h"
47 #include "maskbits.h"
48 #include "mizerarc.h"
49 #include "mi.h"
52 * Note: LEFTMOST must be the bit leftmost in the actual screen
53 * representation. This depends also on the IMAGE_BYTE_ORDER.
54 * LONG2CHARS() takes care of the re-ordering as required. (DHD)
56 #if (BITMAP_BIT_ORDER == MSBFirst)
57 #define LEFTMOST ((PixelType) LONG2CHARS(((MfbBits)1 << PLST)))
58 #else
59 #define LEFTMOST ((PixelType) LONG2CHARS(1))
60 #endif
62 #define PixelateWhite(addr,yoff,xoff) \
63 *mfbScanlineOffset(addr, (yoff)+((xoff)>>PWSH)) |= \
64 SCRRIGHT (LEFTMOST, ((xoff) & PIM))
65 #define PixelateBlack(addr,yoff,xoff) \
66 *mfbScanlineOffset(addr, (yoff)+((xoff)>>PWSH)) &= \
67 ~(SCRRIGHT (LEFTMOST, ((xoff) & PIM)))
69 #define Pixelate(base,yoff,xoff) \
70 { \
71 paddr = mfbScanlineOffset(base, (yoff) + ((xoff)>>PWSH)); \
72 pmask = SCRRIGHT(LEFTMOST, (xoff) & PIM); \
73 *paddr = (*paddr & ~pmask) | (pixel & pmask); \
76 #define DoPix(bit,base,yoff,xoff) if (mask & bit) Pixelate(base,yoff,xoff);
78 static void
79 mfbZeroArcSS(
80 DrawablePtr pDraw,
81 GCPtr pGC,
82 xArc *arc)
84 miZeroArcRec info;
85 Bool do360;
86 register int x, y, a, b, d, mask;
87 register int k1, k3, dx, dy;
88 PixelType *addrl;
89 PixelType *yorgl, *yorgol;
90 PixelType pixel;
91 int nlwidth, yoffset, dyoffset;
92 PixelType pmask;
93 register PixelType *paddr;
95 if (((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop ==
96 RROP_BLACK)
97 pixel = 0;
98 else
99 pixel = ~0;
101 mfbGetPixelWidthAndPointer(pDraw, nlwidth, addrl);
102 do360 = miZeroArcSetup(arc, &info, TRUE);
103 yorgl = addrl + ((info.yorg + pDraw->y) * nlwidth);
104 yorgol = addrl + ((info.yorgo + pDraw->y) * nlwidth);
105 info.xorg += pDraw->x;
106 info.xorgo += pDraw->x;
107 MIARCSETUP();
108 yoffset = y ? nlwidth : 0;
109 dyoffset = 0;
110 mask = info.initialMask;
111 if (!(arc->width & 1))
113 DoPix(2, yorgl, 0, info.xorgo);
114 DoPix(8, yorgol, 0, info.xorgo);
116 if (!info.end.x || !info.end.y)
118 mask = info.end.mask;
119 info.end = info.altend;
121 if (do360 && (arc->width == arc->height) && !(arc->width & 1))
123 int xoffset = nlwidth;
124 PixelType *yorghl = mfbScanlineDeltaNoBankSwitch(yorgl, info.h, nlwidth);
125 int xorghp = info.xorg + info.h;
126 int xorghn = info.xorg - info.h;
128 if (pixel)
130 while (1)
132 PixelateWhite(yorgl, yoffset, info.xorg + x);
133 PixelateWhite(yorgl, yoffset, info.xorg - x);
134 PixelateWhite(yorgol, -yoffset, info.xorg - x);
135 PixelateWhite(yorgol, -yoffset, info.xorg + x);
136 if (a < 0)
137 break;
138 PixelateWhite(yorghl, -xoffset, xorghp - y);
139 PixelateWhite(yorghl, -xoffset, xorghn + y);
140 PixelateWhite(yorghl, xoffset, xorghn + y);
141 PixelateWhite(yorghl, xoffset, xorghp - y);
142 xoffset += nlwidth;
143 MIARCCIRCLESTEP(yoffset += nlwidth;);
146 else
148 while (1)
150 PixelateBlack(yorgl, yoffset, info.xorg + x);
151 PixelateBlack(yorgl, yoffset, info.xorg - x);
152 PixelateBlack(yorgol, -yoffset, info.xorg - x);
153 PixelateBlack(yorgol, -yoffset, info.xorg + x);
154 if (a < 0)
155 break;
156 PixelateBlack(yorghl, -xoffset, xorghp - y);
157 PixelateBlack(yorghl, -xoffset, xorghn + y);
158 PixelateBlack(yorghl, xoffset, xorghn + y);
159 PixelateBlack(yorghl, xoffset, xorghp - y);
160 xoffset += nlwidth;
161 MIARCCIRCLESTEP(yoffset += nlwidth;);
164 x = info.w;
165 yoffset = info.h * nlwidth;
167 else if (do360)
169 while (y < info.h || x < info.w)
171 MIARCOCTANTSHIFT(dyoffset = nlwidth;);
172 Pixelate(yorgl, yoffset, info.xorg + x);
173 Pixelate(yorgl, yoffset, info.xorgo - x);
174 Pixelate(yorgol, -yoffset, info.xorgo - x);
175 Pixelate(yorgol, -yoffset, info.xorg + x);
176 MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;);
179 else
181 while (y < info.h || x < info.w)
183 MIARCOCTANTSHIFT(dyoffset = nlwidth;);
184 if ((x == info.start.x) || (y == info.start.y))
186 mask = info.start.mask;
187 info.start = info.altstart;
189 DoPix(1, yorgl, yoffset, info.xorg + x);
190 DoPix(2, yorgl, yoffset, info.xorgo - x);
191 DoPix(4, yorgol, -yoffset, info.xorgo - x);
192 DoPix(8, yorgol, -yoffset, info.xorg + x);
193 if ((x == info.end.x) || (y == info.end.y))
195 mask = info.end.mask;
196 info.end = info.altend;
198 MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;);
201 if ((x == info.start.x) || (y == info.start.y))
202 mask = info.start.mask;
203 DoPix(1, yorgl, yoffset, info.xorg + x);
204 DoPix(4, yorgol, -yoffset, info.xorgo - x);
205 if (arc->height & 1)
207 DoPix(2, yorgl, yoffset, info.xorgo - x);
208 DoPix(8, yorgol, -yoffset, info.xorg + x);
212 void
213 mfbZeroPolyArcSS(pDraw, pGC, narcs, parcs)
214 DrawablePtr pDraw;
215 GCPtr pGC;
216 int narcs;
217 xArc *parcs;
219 register xArc *arc;
220 register int i;
221 BoxRec box;
222 int x2, y2;
223 RegionPtr cclip;
225 if (!(pGC->planemask & 1))
226 return;
227 cclip = pGC->pCompositeClip;
228 for (arc = parcs, i = narcs; --i >= 0; arc++)
230 if (miCanZeroArc(arc))
232 box.x1 = arc->x + pDraw->x;
233 box.y1 = arc->y + pDraw->y;
235 * Because box.x2 and box.y2 get truncated to 16 bits, and the
236 * RECT_IN_REGION test treats the resulting number as a signed
237 * integer, the RECT_IN_REGION test alone can go the wrong way.
238 * This can result in a server crash because the rendering
239 * routines in this file deal directly with cpu addresses
240 * of pixels to be stored, and do not clip or otherwise check
241 * that all such addresses are within their respective pixmaps.
242 * So we only allow the RECT_IN_REGION test to be used for
243 * values that can be expressed correctly in a signed short.
245 x2 = box.x1 + (int)arc->width + 1;
246 box.x2 = x2;
247 y2 = box.y1 + (int)arc->height + 1;
248 box.y2 = y2;
249 if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
250 (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
251 mfbZeroArcSS(pDraw, pGC, arc);
252 else
253 miZeroPolyArc(pDraw, pGC, 1, arc);
255 else
256 miPolyArc(pDraw, pGC, 1, arc);