First import
[xorg_rtime.git] / xorg-server-1.4 / afb / afbfillarc.c
blobfa685ba9ae74f0d2815fb0a452176f7b0f17f9e8
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 ********************************************************/
29 #ifdef HAVE_DIX_CONFIG_H
30 #include <dix-config.h>
31 #endif
33 #include <X11/X.h>
34 #include <X11/Xprotostr.h>
35 #include "regionstr.h"
36 #include "gcstruct.h"
37 #include "pixmapstr.h"
38 #include "scrnintstr.h"
39 #include "afb.h"
40 #include "maskbits.h"
41 #include "mifillarc.h"
42 #include "mi.h"
44 static void
45 afbFillEllipseSolid(DrawablePtr pDraw, xArc *arc, register unsigned char *rrops)
47 int x, y, e;
48 int yk, xk, ym, xm, dx, dy, xorg, yorg;
49 register int slw;
50 miFillArcRec info;
51 PixelType *addrlt, *addrlb;
52 register PixelType *pdst;
53 PixelType *addrl;
54 register int n;
55 register int d;
56 int nlwidth;
57 register int xpos;
58 PixelType startmask, endmask;
59 int nlmiddle;
60 int depthDst;
61 int sizeDst;
63 afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
64 addrlt);
65 miFillArcSetup(arc, &info);
66 MIFILLARCSETUP();
67 xorg += pDraw->x;
68 yorg += pDraw->y;
69 addrlb = addrlt;
70 addrlt += nlwidth * (yorg - y);
71 addrlb += nlwidth * (yorg + y + dy);
72 while (y) {
73 addrlt += nlwidth;
74 addrlb -= nlwidth;
75 MIFILLARCSTEP(slw);
76 if (!slw)
77 continue;
78 xpos = xorg - x;
79 pdst = addrl = afbScanlineOffset(addrlt, (xpos >> PWSH));
80 if (((xpos & PIM) + slw) < PPW) {
81 maskpartialbits(xpos, slw, startmask);
82 for (d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */
83 switch (rrops[d]) {
84 case RROP_BLACK:
85 *pdst &= ~startmask;
86 break;
87 case RROP_WHITE:
88 *pdst |= startmask;
89 break;
90 case RROP_INVERT:
91 *pdst ^= startmask;
92 break;
93 case RROP_NOP:
94 break;
97 if (miFillArcLower(slw)) {
98 pdst = afbScanlineOffset(addrlb, (xpos >> PWSH));
100 for (d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */
101 switch (rrops[d]) {
102 case RROP_BLACK:
103 *pdst &= ~startmask;
104 break;
105 case RROP_WHITE:
106 *pdst |= startmask;
107 break;
108 case RROP_INVERT:
109 *pdst ^= startmask;
110 break;
111 case RROP_NOP:
112 break;
116 continue;
118 maskbits(xpos, slw, startmask, endmask, nlmiddle);
119 for (d = 0; d < depthDst; d++, addrl += sizeDst) { /* @@@ NEXT PLANE @@@ */
120 n = nlmiddle;
121 pdst = addrl;
123 switch (rrops[d]) {
124 case RROP_BLACK:
125 if (startmask)
126 *pdst++ &= ~startmask;
127 while (n--)
128 *pdst++ = 0;
129 if (endmask)
130 *pdst &= ~endmask;
131 break;
133 case RROP_WHITE:
134 if (startmask)
135 *pdst++ |= startmask;
136 while (n--)
137 *pdst++ = ~0;
138 if (endmask)
139 *pdst |= endmask;
140 break;
142 case RROP_INVERT:
143 if (startmask)
144 *pdst++ ^= startmask;
145 while (n--)
146 *pdst++ ^= ~0;
147 if (endmask)
148 *pdst ^= endmask;
149 break;
151 case RROP_NOP:
152 break;
155 if (!miFillArcLower(slw))
156 continue;
157 addrl = afbScanlineOffset(addrlb, (xpos >> PWSH));
158 for (d = 0; d < depthDst; d++, addrl += sizeDst) { /* @@@ NEXT PLANE @@@ */
159 n = nlmiddle;
160 pdst = addrl;
162 switch (rrops[d]) {
163 case RROP_BLACK:
164 if (startmask)
165 *pdst++ &= ~startmask;
166 while (n--)
167 *pdst++ = 0;
168 if (endmask)
169 *pdst &= ~endmask;
170 break;
172 case RROP_WHITE:
173 if (startmask)
174 *pdst++ |= startmask;
175 while (n--)
176 *pdst++ = ~0;
177 if (endmask)
178 *pdst |= endmask;
179 break;
181 case RROP_INVERT:
182 if (startmask)
183 *pdst++ ^= startmask;
184 while (n--)
185 *pdst++ ^= ~0;
186 if (endmask)
187 *pdst ^= endmask;
188 break;
190 case RROP_NOP:
191 break;
197 #define FILLSPAN(xl,xr,addr) \
198 if (xr >= xl) { \
199 width = xr - xl + 1; \
200 addrl = afbScanlineOffset(addr, (xl >> PWSH)); \
201 if (((xl & PIM) + width) < PPW) { \
202 maskpartialbits(xl, width, startmask); \
203 for (pdst = addrl, d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */ \
204 switch (rrops[d]) { \
205 case RROP_BLACK: \
206 *pdst &= ~startmask; \
207 break; \
208 case RROP_WHITE: \
209 *pdst |= startmask; \
210 break; \
211 case RROP_INVERT: \
212 *pdst ^= startmask; \
213 break; \
214 case RROP_NOP: \
215 break; \
218 } else { \
219 maskbits(xl, width, startmask, endmask, nlmiddle); \
220 for (d = 0; d < depthDst; d++, addrl += sizeDst) { /* @@@ NEXT PLANE @@@ */ \
221 n = nlmiddle; \
222 pdst = addrl; \
223 switch (rrops[d]) { \
224 case RROP_BLACK: \
225 if (startmask) \
226 *pdst++ &= ~startmask; \
227 while (n--) \
228 *pdst++ = 0; \
229 if (endmask) \
230 *pdst &= ~endmask; \
231 break; \
232 case RROP_WHITE: \
233 if (startmask) \
234 *pdst++ |= startmask; \
235 while (n--) \
236 *pdst++ = ~0; \
237 if (endmask) \
238 *pdst |= endmask; \
239 break; \
240 case RROP_INVERT: \
241 if (startmask) \
242 *pdst++ ^= startmask; \
243 while (n--) \
244 *pdst++ ^= ~0; \
245 if (endmask) \
246 *pdst ^= endmask; \
247 break; \
248 case RROP_NOP: \
249 break; \
255 #define FILLSLICESPANS(flip,addr) \
256 if (!flip) { \
257 FILLSPAN(xl, xr, addr); \
258 } else { \
259 xc = xorg - x; \
260 FILLSPAN(xc, xr, addr); \
261 xc += slw - 1; \
262 FILLSPAN(xl, xc, addr); \
265 static void
266 afbFillArcSliceSolidCopy(DrawablePtr pDraw, GCPtr pGC, xArc *arc, register unsigned char *rrops)
268 PixelType *addrl;
269 register PixelType *pdst;
270 register int n;
271 register int d;
272 int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
273 register int x, y, e;
274 miFillArcRec info;
275 miArcSliceRec slice;
276 int xl, xr, xc;
277 PixelType *addrlt, *addrlb;
278 int nlwidth;
279 int width;
280 PixelType startmask, endmask;
281 int nlmiddle;
282 int sizeDst;
283 int depthDst;
285 afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
286 addrlt);
287 miFillArcSetup(arc, &info);
288 miFillArcSliceSetup(arc, &slice, pGC);
289 MIFILLARCSETUP();
290 xorg += pDraw->x;
291 yorg += pDraw->y;
292 addrlb = addrlt;
293 addrlt = afbScanlineDeltaNoBankSwitch(addrlt, yorg - y, nlwidth);
294 addrlb = afbScanlineDeltaNoBankSwitch(addrlb, yorg + y + dy, nlwidth);
295 slice.edge1.x += pDraw->x;
296 slice.edge2.x += pDraw->x;
297 while (y > 0) {
298 afbScanlineIncNoBankSwitch(addrlt, nlwidth);
299 afbScanlineIncNoBankSwitch(addrlb, -nlwidth);
300 MIFILLARCSTEP(slw);
301 MIARCSLICESTEP(slice.edge1);
302 MIARCSLICESTEP(slice.edge2);
303 if (miFillSliceUpper(slice)) {
304 MIARCSLICEUPPER(xl, xr, slice, slw);
305 FILLSLICESPANS(slice.flip_top, addrlt);
307 if (miFillSliceLower(slice)) {
308 MIARCSLICELOWER(xl, xr, slice, slw);
309 FILLSLICESPANS(slice.flip_bot, addrlb);
314 void
315 afbPolyFillArcSolid(register DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs)
317 afbPrivGC *priv;
318 register xArc *arc;
319 register int i;
320 BoxRec box;
321 RegionPtr cclip;
322 unsigned char *rrops;
324 priv = (afbPrivGC *) pGC->devPrivates[afbGCPrivateIndex].ptr;
325 rrops = priv->rrops;
326 cclip = pGC->pCompositeClip;
327 for (arc = parcs, i = narcs; --i >= 0; arc++) {
328 if (miFillArcEmpty(arc))
329 continue;
330 if (miCanFillArc(arc)) {
331 box.x1 = arc->x + pDraw->x;
332 box.y1 = arc->y + pDraw->y;
333 box.x2 = box.x1 + (int)arc->width + 1;
334 box.y2 = box.y1 + (int)arc->height + 1;
335 if (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) {
336 if ((arc->angle2 >= FULLCIRCLE) ||
337 (arc->angle2 <= -FULLCIRCLE))
338 afbFillEllipseSolid(pDraw, arc, rrops);
339 else
340 afbFillArcSliceSolidCopy(pDraw, pGC, arc, rrops);
341 continue;
344 miPolyFillArc(pDraw, pGC, 1, arc);