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
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 #ifdef HAVE_DIX_CONFIG_H
29 #include <dix-config.h>
35 #include <X11/Xprotostr.h>
36 #include "regionstr.h"
38 #include "pixmapstr.h"
39 #include "scrnintstr.h"
42 #include "mifillarc.h"
52 int yk
, xk
, ym
, xm
, dx
, dy
, xorg
, yorg
;
55 PixelType
*addrlt
, *addrlb
;
56 register PixelType
*addrl
;
60 PixelType startmask
, endmask
;
63 mfbGetPixelWidthAndPointer(pDraw
, nlwidth
, addrlt
);
64 miFillArcSetup(arc
, &info
);
69 addrlt
+= nlwidth
* (yorg
- y
);
70 addrlb
+= nlwidth
* (yorg
+ y
+ dy
);
79 addrl
= mfbScanlineOffset(addrlt
, (xpos
>> PWSH
));
80 if (((xpos
& PIM
) + slw
) < PPW
)
82 maskpartialbits(xpos
, slw
, startmask
);
83 if (rop
== RROP_BLACK
)
85 else if (rop
== RROP_WHITE
)
89 if (miFillArcLower(slw
))
91 addrl
= mfbScanlineOffset(addrlb
, (xpos
>> PWSH
));
92 if (rop
== RROP_BLACK
)
94 else if (rop
== RROP_WHITE
)
101 maskbits(xpos
, slw
, startmask
, endmask
, nlmiddle
);
104 if (rop
== RROP_BLACK
)
105 *addrl
++ &= ~startmask
;
106 else if (rop
== RROP_WHITE
)
107 *addrl
++ |= startmask
;
109 *addrl
++ ^= startmask
;
112 if (rop
== RROP_BLACK
)
115 else if (rop
== RROP_WHITE
)
123 if (rop
== RROP_BLACK
)
125 else if (rop
== RROP_WHITE
)
130 if (!miFillArcLower(slw
))
132 addrl
= mfbScanlineOffset(addrlb
, (xpos
>> PWSH
));
135 if (rop
== RROP_BLACK
)
136 *addrl
++ &= ~startmask
;
137 else if (rop
== RROP_WHITE
)
138 *addrl
++ |= startmask
;
140 *addrl
++ ^= startmask
;
143 if (rop
== RROP_BLACK
)
146 else if (rop
== RROP_WHITE
)
154 if (rop
== RROP_BLACK
)
156 else if (rop
== RROP_WHITE
)
164 #define FILLSPAN(xl,xr,addr) \
167 width = xr - xl + 1; \
168 addrl = mfbScanlineOffset(addr, (xl >> PWSH)); \
169 if (((xl & PIM) + width) < PPW) \
171 maskpartialbits(xl, width, startmask); \
172 if (rop == RROP_BLACK) \
173 *addrl &= ~startmask; \
174 else if (rop == RROP_WHITE) \
175 *addrl |= startmask; \
177 *addrl ^= startmask; \
181 maskbits(xl, width, startmask, endmask, nlmiddle); \
184 if (rop == RROP_BLACK) \
185 *addrl++ &= ~startmask; \
186 else if (rop == RROP_WHITE) \
187 *addrl++ |= startmask; \
189 *addrl++ ^= startmask; \
192 if (rop == RROP_BLACK) \
195 else if (rop == RROP_WHITE) \
203 if (rop == RROP_BLACK) \
204 *addrl &= ~endmask; \
205 else if (rop == RROP_WHITE) \
213 #define FILLSLICESPANS(flip,addr) \
216 FILLSPAN(xl, xr, addr); \
221 FILLSPAN(xc, xr, addr); \
223 FILLSPAN(xl, xc, addr); \
227 mfbFillArcSliceSolidCopy(
233 register PixelType
*addrl
;
235 int yk
, xk
, ym
, xm
, dx
, dy
, xorg
, yorg
, slw
;
236 register int x
, y
, e
;
240 PixelType
*addrlt
, *addrlb
;
243 PixelType startmask
, endmask
;
246 mfbGetPixelWidthAndPointer(pDraw
, nlwidth
, addrlt
);
247 miFillArcSetup(arc
, &info
);
248 miFillArcSliceSetup(arc
, &slice
, pGC
);
253 addrlt
= mfbScanlineDeltaNoBankSwitch(addrlt
, yorg
- y
, nlwidth
);
254 addrlb
= mfbScanlineDeltaNoBankSwitch(addrlb
, yorg
+ y
+ dy
, nlwidth
);
255 slice
.edge1
.x
+= pDraw
->x
;
256 slice
.edge2
.x
+= pDraw
->x
;
259 mfbScanlineIncNoBankSwitch(addrlt
, nlwidth
);
260 mfbScanlineIncNoBankSwitch(addrlb
, -nlwidth
);
262 MIARCSLICESTEP(slice
.edge1
);
263 MIARCSLICESTEP(slice
.edge2
);
264 if (miFillSliceUpper(slice
))
266 MIARCSLICEUPPER(xl
, xr
, slice
, slw
);
267 FILLSLICESPANS(slice
.flip_top
, addrlt
);
269 if (miFillSliceLower(slice
))
271 MIARCSLICELOWER(xl
, xr
, slice
, slw
);
272 FILLSLICESPANS(slice
.flip_bot
, addrlb
);
278 mfbPolyFillArcSolid(pDraw
, pGC
, narcs
, parcs
)
279 register DrawablePtr pDraw
;
292 priv
= (mfbPrivGC
*) pGC
->devPrivates
[mfbGCPrivateIndex
].ptr
;
294 if ((rop
== RROP_NOP
) || !(pGC
->planemask
& 1))
296 cclip
= pGC
->pCompositeClip
;
297 for (arc
= parcs
, i
= narcs
; --i
>= 0; arc
++)
299 if (miFillArcEmpty(arc
))
301 if (miCanFillArc(arc
))
303 box
.x1
= arc
->x
+ pDraw
->x
;
304 box
.y1
= arc
->y
+ pDraw
->y
;
306 * Because box.x2 and box.y2 get truncated to 16 bits, and the
307 * RECT_IN_REGION test treats the resulting number as a signed
308 * integer, the RECT_IN_REGION test alone can go the wrong way.
309 * This can result in a server crash because the rendering
310 * routines in this file deal directly with cpu addresses
311 * of pixels to be stored, and do not clip or otherwise check
312 * that all such addresses are within their respective pixmaps.
313 * So we only allow the RECT_IN_REGION test to be used for
314 * values that can be expressed correctly in a signed short.
316 x2
= box
.x1
+ (int)arc
->width
+ 1;
318 y2
= box
.y1
+ (int)arc
->height
+ 1;
320 if ( (x2
<= SHRT_MAX
) && (y2
<= SHRT_MAX
) &&
321 (RECT_IN_REGION(pDraw
->pScreen
, cclip
, &box
) == rgnIN
) )
323 if ((arc
->angle2
>= FULLCIRCLE
) ||
324 (arc
->angle2
<= -FULLCIRCLE
))
325 mfbFillEllipseSolid(pDraw
, arc
, rop
);
327 mfbFillArcSliceSolidCopy(pDraw
, pGC
, arc
, rop
);
331 miPolyFillArc(pDraw
, pGC
, 1, arc
);