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: mfbfillarc.c /main/16 1995/12/06 16:54:28 dpw $ */
31 #include "Xprotostr.h"
32 #include "miscstruct.h"
34 #include "pixmapstr.h"
35 #include "scrnintstr.h"
38 #include "mifillarc.h"
42 mfbFillEllipseSolid(pDraw, arc, rop)
48 int yk, xk, ym, xm, dx, dy, xorg, yorg;
51 PixelType *addrlt, *addrlb;
52 register PixelType *addrl;
56 PixelType startmask, endmask;
59 mfbGetPixelWidthAndPointer(pDraw, nlwidth, addrlt);
60 miFillArcSetup(arc, &info);
65 addrlt += nlwidth * (yorg - y);
66 addrlb += nlwidth * (yorg + y + dy);
75 addrl = mfbScanlineOffset(addrlt, (xpos >> PWSH));
76 if (((xpos & PIM) + slw) < PPW)
78 maskpartialbits(xpos, slw, startmask);
79 if (rop == RROP_BLACK)
81 else if (rop == RROP_WHITE)
85 if (miFillArcLower(slw))
87 addrl = mfbScanlineOffset(addrlb, (xpos >> PWSH));
88 if (rop == RROP_BLACK)
90 else if (rop == RROP_WHITE)
97 maskbits(xpos, slw, startmask, endmask, nlmiddle);
100 if (rop == RROP_BLACK)
101 *addrl++ &= ~startmask;
102 else if (rop == RROP_WHITE)
103 *addrl++ |= startmask;
105 *addrl++ ^= startmask;
108 if (rop == RROP_BLACK)
111 else if (rop == RROP_WHITE)
119 if (rop == RROP_BLACK)
121 else if (rop == RROP_WHITE)
126 if (!miFillArcLower(slw))
128 addrl = mfbScanlineOffset(addrlb, (xpos >> PWSH));
131 if (rop == RROP_BLACK)
132 *addrl++ &= ~startmask;
133 else if (rop == RROP_WHITE)
134 *addrl++ |= startmask;
136 *addrl++ ^= startmask;
139 if (rop == RROP_BLACK)
142 else if (rop == RROP_WHITE)
150 if (rop == RROP_BLACK)
152 else if (rop == RROP_WHITE)
160 #define FILLSPAN(xl,xr,addr) \
163 width = xr - xl + 1; \
164 addrl = mfbScanlineOffset(addr, (xl >> PWSH)); \
165 if (((xl & PIM) + width) < PPW) \
167 maskpartialbits(xl, width, startmask); \
168 if (rop == RROP_BLACK) \
169 *addrl &= ~startmask; \
170 else if (rop == RROP_WHITE) \
171 *addrl |= startmask; \
173 *addrl ^= startmask; \
177 maskbits(xl, width, startmask, endmask, nlmiddle); \
180 if (rop == RROP_BLACK) \
181 *addrl++ &= ~startmask; \
182 else if (rop == RROP_WHITE) \
183 *addrl++ |= startmask; \
185 *addrl++ ^= startmask; \
188 if (rop == RROP_BLACK) \
191 else if (rop == RROP_WHITE) \
199 if (rop == RROP_BLACK) \
200 *addrl &= ~endmask; \
201 else if (rop == RROP_WHITE) \
209 #define FILLSLICESPANS(flip,addr) \
212 FILLSPAN(xl, xr, addr); \
217 FILLSPAN(xc, xr, addr); \
219 FILLSPAN(xl, xc, addr); \
223 mfbFillArcSliceSolidCopy(pDraw, pGC, arc, rop)
229 register PixelType *addrl;
231 int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
232 register int x, y, e;
236 PixelType *addrlt, *addrlb;
239 PixelType startmask, endmask;
242 mfbGetPixelWidthAndPointer(pDraw, nlwidth, addrlt);
243 miFillArcSetup(arc, &info);
244 miFillArcSliceSetup(arc, &slice, pGC);
249 addrlt = mfbScanlineDeltaNoBankSwitch(addrlt, yorg - y, nlwidth);
250 addrlb = mfbScanlineDeltaNoBankSwitch(addrlb, yorg + y + dy, nlwidth);
251 slice.edge1.x += pDraw->x;
252 slice.edge2.x += pDraw->x;
255 mfbScanlineIncNoBankSwitch(addrlt, nlwidth);
256 mfbScanlineIncNoBankSwitch(addrlb, -nlwidth);
258 MIARCSLICESTEP(slice.edge1);
259 MIARCSLICESTEP(slice.edge2);
260 if (miFillSliceUpper(slice))
262 MIARCSLICEUPPER(xl, xr, slice, slw);
263 FILLSLICESPANS(slice.flip_top, addrlt);
265 if (miFillSliceLower(slice))
267 MIARCSLICELOWER(xl, xr, slice, slw);
268 FILLSLICESPANS(slice.flip_bot, addrlb);
274 mfbPolyFillArcSolid(pDraw, pGC, narcs, parcs)
275 register DrawablePtr pDraw;
288 priv = (mfbPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
290 if ((rop == RROP_NOP) || !(pGC->planemask & 1))
292 cclip = priv->pCompositeClip;
293 for (arc = parcs, i = narcs; --i >= 0; arc++)
295 if (miFillArcEmpty(arc))
297 if (miCanFillArc(arc))
299 box.x1 = arc->x + pDraw->x;
300 box.y1 = arc->y + pDraw->y;
302 * Because box.x2 and box.y2 get truncated to 16 bits, and the
303 * RECT_IN_REGION test treats the resulting number as a signed
304 * integer, the RECT_IN_REGION test alone can go the wrong way.
305 * This can result in a server crash because the rendering
306 * routines in this file deal directly with cpu addresses
307 * of pixels to be stored, and do not clip or otherwise check
308 * that all such addresses are within their respective pixmaps.
309 * So we only allow the RECT_IN_REGION test to be used for
310 * values that can be expressed correctly in a signed short.
312 x2 = box.x1 + (int)arc->width + 1;
314 y2 = box.y1 + (int)arc->height + 1;
316 if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
317 (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
319 if ((arc->angle2 >= FULLCIRCLE) ||
320 (arc->angle2 <= -FULLCIRCLE))
321 mfbFillEllipseSolid(pDraw, arc, rop);
323 mfbFillArcSliceSolidCopy(pDraw, pGC, arc, rop);
327 miPolyFillArc(pDraw, pGC, 1, arc);