First import
[xorg_rtime.git] / xorg-server-1.4 / cfb / cfbfillarc.c
blob0eb5ff4694ce08ad6f9ca7162d6231fd04f77446
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 #ifdef HAVE_DIX_CONFIG_H
29 #include <dix-config.h>
30 #endif
32 #include <limits.h>
34 #include <X11/X.h>
35 #include <X11/Xprotostr.h>
36 #include "regionstr.h"
37 #include "gcstruct.h"
38 #include "pixmapstr.h"
39 #include "scrnintstr.h"
40 #include "cfb.h"
41 #include "cfbmskbits.h"
42 #include "mifillarc.h"
43 #include "cfbrrop.h"
44 #include "mi.h"
46 /* gcc 1.35 is stupid */
47 #if defined(__GNUC__) && __GNUC__ < 2 && defined(mc68020)
48 #define STUPID volatile
49 #else
50 #define STUPID
51 #endif
53 static void
54 RROP_NAME(cfbFillEllipseSolid)(
55 DrawablePtr pDraw,
56 GCPtr pGC,
57 xArc *arc)
59 STUPID int x, y, e;
60 STUPID int yk, xk, ym, xm, dx, dy, xorg, yorg;
61 miFillArcRec info;
62 #if PSZ == 24
63 unsigned char *addrlt, *addrlb;
64 #else
65 CfbBits *addrlt, *addrlb;
66 #endif
67 register CfbBits *addrl;
68 register int n;
69 int nlwidth;
70 RROP_DECLARE
71 register int xpos;
72 register int slw;
73 CfbBits startmask, endmask;
74 int nlmiddle;
75 #if PSZ == 24
76 register int pidx;
77 int xpos3;
78 #endif
80 #if PSZ == 24
81 cfbGetByteWidthAndPointer (pDraw, nlwidth, addrlt)
82 #else
83 cfbGetLongWidthAndPointer (pDraw, nlwidth, addrlt)
84 #endif
86 RROP_FETCH_GC(pGC);
87 miFillArcSetup(arc, &info);
88 MIFILLARCSETUP();
89 xorg += pDraw->x;
90 yorg += pDraw->y;
91 addrlb = addrlt;
92 addrlt += nlwidth * (yorg - y);
93 addrlb += nlwidth * (yorg + y + dy);
94 while (y)
96 addrlt += nlwidth;
97 addrlb -= nlwidth;
98 MIFILLARCSTEP(slw);
99 if (!slw)
100 continue;
101 xpos = xorg - x;
102 #if PSZ == 24
103 xpos3 = (xpos * 3) & ~0x03;
104 addrl = (CfbBits *)((char *)addrlt + xpos3);
105 if (slw == 1){
106 RROP_SOLID24(addrl, xpos);
107 if (miFillArcLower(slw)){
108 addrl = (CfbBits *)((char *)addrlb + xpos3);
109 RROP_SOLID24(addrl, xpos);
111 continue;
113 maskbits(xpos, slw, startmask, endmask, nlmiddle);
114 xpos &= 3;
115 pidx = xpos;
116 if (startmask){
117 RROP_SOLID_MASK(addrl, startmask, pidx-1);
118 addrl++;
119 if (pidx == 3)
120 pidx = 0;
122 n = nlmiddle;
123 while (--n >= 0){
124 RROP_SOLID(addrl, pidx);
125 addrl++;
126 if (++pidx == 3)
127 pidx = 0;
129 if (endmask)
130 RROP_SOLID_MASK(addrl, endmask, pidx);
131 if (!miFillArcLower(slw))
132 continue;
133 addrl = (CfbBits *)((char *)addrlb + xpos3);
134 pidx = xpos;
135 if (startmask){
136 RROP_SOLID_MASK(addrl, startmask, pidx-1);
137 addrl++;
138 if (pidx == 3)
139 pidx = 0;
141 n = nlmiddle;
142 while (--n >= 0){
143 RROP_SOLID(addrl, pidx);
144 addrl++;
145 if (++pidx == 3)
146 pidx = 0;
148 if (endmask)
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);
161 continue;
163 maskbits(xpos, slw, startmask, endmask, nlmiddle);
164 if (startmask)
166 RROP_SOLID_MASK(addrl, startmask);
167 addrl++;
169 n = nlmiddle;
170 RROP_SPAN(addrl,n)
172 if (endmask)
173 RROP_SOLID_MASK(addrl, endmask);
174 if (!miFillArcLower(slw))
175 continue;
176 addrl = addrlb + (xpos >> PWSH);
177 if (startmask)
179 RROP_SOLID_MASK(addrl, startmask);
180 addrl++;
182 n = nlmiddle;
183 RROP_SPAN(addrl, n);
184 if (endmask)
185 RROP_SOLID_MASK(addrl, endmask);
186 #endif /* PSZ == 24 */
188 RROP_UNDECLARE
191 #if PSZ == 24
192 #define FILLSPAN(xl,xr,addr) \
193 if (xr >= xl){ \
194 n = xr - xl + 1; \
195 addrl = (CfbBits *)((char *)addr + ((xl * 3) & ~0x03)); \
196 if (n <= 1){ \
197 if (n) \
198 RROP_SOLID24(addrl, xl); \
199 } else { \
200 maskbits(xl, n, startmask, endmask, n); \
201 pidx = xl & 3; \
202 if (startmask){ \
203 RROP_SOLID_MASK(addrl, startmask, pidx-1); \
204 addrl++; \
205 if (pidx == 3) \
206 pidx = 0; \
208 while (--n >= 0){ \
209 RROP_SOLID(addrl, pidx); \
210 addrl++; \
211 if (++pidx == 3) \
212 pidx = 0; \
214 if (endmask) \
215 RROP_SOLID_MASK(addrl, endmask, pidx); \
218 #else /* PSZ == 24 */
219 #define FILLSPAN(xl,xr,addr) \
220 if (xr >= xl) \
222 n = xr - xl + 1; \
223 addrl = addr + (xl >> PWSH); \
224 if (((xl & PIM) + n) <= PPW) \
226 maskpartialbits(xl, n, startmask); \
227 RROP_SOLID_MASK(addrl, startmask); \
229 else \
231 maskbits(xl, n, startmask, endmask, n); \
232 if (startmask) \
234 RROP_SOLID_MASK(addrl, startmask); \
235 addrl++; \
237 while (n--) \
239 RROP_SOLID(addrl); \
240 ++addrl; \
242 if (endmask) \
243 RROP_SOLID_MASK(addrl, endmask); \
246 #endif /* PSZ == 24 */
248 #define FILLSLICESPANS(flip,addr) \
249 if (!flip) \
251 FILLSPAN(xl, xr, addr); \
253 else \
255 xc = xorg - x; \
256 FILLSPAN(xc, xr, addr); \
257 xc += slw - 1; \
258 FILLSPAN(xl, xc, addr); \
261 static void
262 RROP_NAME(cfbFillArcSliceSolid)(
263 DrawablePtr pDraw,
264 GCPtr pGC,
265 xArc *arc)
267 int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
268 register int x, y, e;
269 miFillArcRec info;
270 miArcSliceRec slice;
271 int xl, xr, xc;
272 #if PSZ == 24
273 unsigned char *addrlt, *addrlb;
274 #else
275 CfbBits *addrlt, *addrlb;
276 #endif
277 register CfbBits *addrl;
278 register int n;
279 int nlwidth;
280 RROP_DECLARE
281 CfbBits startmask, endmask;
282 #if PSZ == 24
283 register int pidx;
284 #endif /* PSZ == 24 */
286 #if PSZ == 24
287 cfbGetByteWidthAndPointer (pDraw, nlwidth, addrlt)
288 #else
289 cfbGetLongWidthAndPointer (pDraw, nlwidth, addrlt)
290 #endif
292 RROP_FETCH_GC(pGC);
293 miFillArcSetup(arc, &info);
294 miFillArcSliceSetup(arc, &slice, pGC);
295 MIFILLARCSETUP();
296 xorg += pDraw->x;
297 yorg += pDraw->y;
298 addrlb = addrlt;
299 addrlt += nlwidth * (yorg - y);
300 addrlb += nlwidth * (yorg + y + dy);
301 slice.edge1.x += pDraw->x;
302 slice.edge2.x += pDraw->x;
303 while (y > 0)
305 addrlt += nlwidth;
306 addrlb -= nlwidth;
307 MIFILLARCSTEP(slw);
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);
321 RROP_UNDECLARE
324 void
325 RROP_NAME(cfbPolyFillArcSolid) (pDraw, pGC, narcs, parcs)
326 DrawablePtr pDraw;
327 GCPtr pGC;
328 int narcs;
329 xArc *parcs;
331 register xArc *arc;
332 register int i;
333 int x2, y2;
334 BoxRec box;
335 RegionPtr cclip;
337 cclip = cfbGetCompositeClip(pGC);
338 for (arc = parcs, i = narcs; --i >= 0; arc++)
340 if (miFillArcEmpty(arc))
341 continue;
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;
358 box.x2 = x2;
359 y2 = box.y1 + (int)arc->height + 1;
360 box.y2 = y2;
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);
367 else
368 RROP_NAME(cfbFillArcSliceSolid)(pDraw, pGC, arc);
369 continue;
372 miPolyFillArc(pDraw, pGC, 1, arc);