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"
41 #include "cfbmskbits.h"
42 #include "mifillarc.h"
46 /* gcc 1.35 is stupid */
47 #if defined(__GNUC__) && __GNUC__ < 2 && defined(mc68020)
48 #define STUPID volatile
54 RROP_NAME(cfbFillEllipseSolid
)(
60 STUPID
int yk
, xk
, ym
, xm
, dx
, dy
, xorg
, yorg
;
63 unsigned char *addrlt
, *addrlb
;
65 CfbBits
*addrlt
, *addrlb
;
67 register CfbBits
*addrl
;
73 CfbBits startmask
, endmask
;
81 cfbGetByteWidthAndPointer (pDraw
, nlwidth
, addrlt
)
83 cfbGetLongWidthAndPointer (pDraw
, nlwidth
, addrlt
)
87 miFillArcSetup(arc
, &info
);
92 addrlt
+= nlwidth
* (yorg
- y
);
93 addrlb
+= nlwidth
* (yorg
+ y
+ dy
);
103 xpos3
= (xpos
* 3) & ~0x03;
104 addrl
= (CfbBits
*)((char *)addrlt
+ xpos3
);
106 RROP_SOLID24(addrl
, xpos
);
107 if (miFillArcLower(slw
)){
108 addrl
= (CfbBits
*)((char *)addrlb
+ xpos3
);
109 RROP_SOLID24(addrl
, xpos
);
113 maskbits(xpos
, slw
, startmask
, endmask
, nlmiddle
);
117 RROP_SOLID_MASK(addrl
, startmask
, pidx
-1);
124 RROP_SOLID(addrl
, pidx
);
130 RROP_SOLID_MASK(addrl
, endmask
, pidx
);
131 if (!miFillArcLower(slw
))
133 addrl
= (CfbBits
*)((char *)addrlb
+ xpos3
);
136 RROP_SOLID_MASK(addrl
, startmask
, pidx
-1);
143 RROP_SOLID(addrl
, pidx
);
149 RROP_SOLID_MASK(addrl
, endmask
, pidx
);
150 #else /* PSZ == 24 */
151 addrl
= addrlt
+ (xpos
>> PWSH
);
152 if (((xpos
& PIM
) + slw
) <= PPW
)
154 maskpartialbits(xpos
, slw
, startmask
);
155 RROP_SOLID_MASK(addrl
,startmask
);
156 if (miFillArcLower(slw
))
158 addrl
= addrlb
+ (xpos
>> PWSH
);
159 RROP_SOLID_MASK(addrl
, startmask
);
163 maskbits(xpos
, slw
, startmask
, endmask
, nlmiddle
);
166 RROP_SOLID_MASK(addrl
, startmask
);
173 RROP_SOLID_MASK(addrl
, endmask
);
174 if (!miFillArcLower(slw
))
176 addrl
= addrlb
+ (xpos
>> PWSH
);
179 RROP_SOLID_MASK(addrl
, startmask
);
185 RROP_SOLID_MASK(addrl
, endmask
);
186 #endif /* PSZ == 24 */
192 #define FILLSPAN(xl,xr,addr) \
195 addrl = (CfbBits *)((char *)addr + ((xl * 3) & ~0x03)); \
198 RROP_SOLID24(addrl, xl); \
200 maskbits(xl, n, startmask, endmask, n); \
203 RROP_SOLID_MASK(addrl, startmask, pidx-1); \
209 RROP_SOLID(addrl, pidx); \
215 RROP_SOLID_MASK(addrl, endmask, pidx); \
218 #else /* PSZ == 24 */
219 #define FILLSPAN(xl,xr,addr) \
223 addrl = addr + (xl >> PWSH); \
224 if (((xl & PIM) + n) <= PPW) \
226 maskpartialbits(xl, n, startmask); \
227 RROP_SOLID_MASK(addrl, startmask); \
231 maskbits(xl, n, startmask, endmask, n); \
234 RROP_SOLID_MASK(addrl, startmask); \
243 RROP_SOLID_MASK(addrl, endmask); \
246 #endif /* PSZ == 24 */
248 #define FILLSLICESPANS(flip,addr) \
251 FILLSPAN(xl, xr, addr); \
256 FILLSPAN(xc, xr, addr); \
258 FILLSPAN(xl, xc, addr); \
262 RROP_NAME(cfbFillArcSliceSolid
)(
267 int yk
, xk
, ym
, xm
, dx
, dy
, xorg
, yorg
, slw
;
268 register int x
, y
, e
;
273 unsigned char *addrlt
, *addrlb
;
275 CfbBits
*addrlt
, *addrlb
;
277 register CfbBits
*addrl
;
281 CfbBits startmask
, endmask
;
284 #endif /* PSZ == 24 */
287 cfbGetByteWidthAndPointer (pDraw
, nlwidth
, addrlt
)
289 cfbGetLongWidthAndPointer (pDraw
, nlwidth
, addrlt
)
293 miFillArcSetup(arc
, &info
);
294 miFillArcSliceSetup(arc
, &slice
, pGC
);
299 addrlt
+= nlwidth
* (yorg
- y
);
300 addrlb
+= nlwidth
* (yorg
+ y
+ dy
);
301 slice
.edge1
.x
+= pDraw
->x
;
302 slice
.edge2
.x
+= pDraw
->x
;
308 MIARCSLICESTEP(slice
.edge1
);
309 MIARCSLICESTEP(slice
.edge2
);
310 if (miFillSliceUpper(slice
))
312 MIARCSLICEUPPER(xl
, xr
, slice
, slw
);
313 FILLSLICESPANS(slice
.flip_top
, addrlt
);
315 if (miFillSliceLower(slice
))
317 MIARCSLICELOWER(xl
, xr
, slice
, slw
);
318 FILLSLICESPANS(slice
.flip_bot
, addrlb
);
325 RROP_NAME(cfbPolyFillArcSolid
) (pDraw
, pGC
, narcs
, parcs
)
337 cclip
= cfbGetCompositeClip(pGC
);
338 for (arc
= parcs
, i
= narcs
; --i
>= 0; arc
++)
340 if (miFillArcEmpty(arc
))
342 if (miCanFillArc(arc
))
344 box
.x1
= arc
->x
+ pDraw
->x
;
345 box
.y1
= arc
->y
+ pDraw
->y
;
347 * Because box.x2 and box.y2 get truncated to 16 bits, and the
348 * RECT_IN_REGION test treats the resulting number as a signed
349 * integer, the RECT_IN_REGION test alone can go the wrong way.
350 * This can result in a server crash because the rendering
351 * routines in this file deal directly with cpu addresses
352 * of pixels to be stored, and do not clip or otherwise check
353 * that all such addresses are within their respective pixmaps.
354 * So we only allow the RECT_IN_REGION test to be used for
355 * values that can be expressed correctly in a signed short.
357 x2
= box
.x1
+ (int)arc
->width
+ 1;
359 y2
= box
.y1
+ (int)arc
->height
+ 1;
361 if ( (x2
<= SHRT_MAX
) && (y2
<= SHRT_MAX
) &&
362 (RECT_IN_REGION(pDraw
->pScreen
, cclip
, &box
) == rgnIN
) )
364 if ((arc
->angle2
>= FULLCIRCLE
) ||
365 (arc
->angle2
<= -FULLCIRCLE
))
366 RROP_NAME(cfbFillEllipseSolid
)(pDraw
, pGC
, arc
);
368 RROP_NAME(cfbFillArcSliceSolid
)(pDraw
, pGC
, arc
);
372 miPolyFillArc(pDraw
, pGC
, 1, arc
);