1 dawes 3.3 /* $XFree86: xc/programs/Xserver/afb/afbfillarc.c,v 3.2 2003/07/16 01:38:35 dawes Exp $ */
|
2 dawes 3.0 /************************************************************
3
4 Copyright (c) 1989 X Consortium
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 dawes 3.0 Except as contained in this notice, the name of the X Consortium shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from the X Consortium.
26
27 ********************************************************/
28
29 #include "X.h"
30 #include "Xprotostr.h"
|
31 dawes 3.2 #include "regionstr.h"
|
32 dawes 3.0 #include "gcstruct.h"
33 #include "pixmapstr.h"
34 #include "scrnintstr.h"
35 #include "afb.h"
36 #include "maskbits.h"
37 #include "mifillarc.h"
38 #include "mi.h"
39
40 static void
|
41 dawes 3.3 afbFillEllipseSolid(DrawablePtr pDraw, xArc *arc, unsigned char *rrops)
|
42 dawes 3.0 {
43 int x, y, e;
44 int yk, xk, ym, xm, dx, dy, xorg, yorg;
|
45 dawes 3.3 int slw;
|
46 dawes 3.0 miFillArcRec info;
47 PixelType *addrlt, *addrlb;
|
48 dawes 3.3 PixelType *pdst;
|
49 dawes 3.0 PixelType *addrl;
|
50 dawes 3.3 int n;
51 int d;
|
52 dawes 3.0 int nlwidth;
|
53 dawes 3.3 int xpos;
|
54 dawes 3.0 PixelType startmask, endmask;
55 int nlmiddle;
56 int depthDst;
57 int sizeDst;
58
59 afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
60 addrlt);
61 miFillArcSetup(arc, &info);
62 MIFILLARCSETUP();
63 xorg += pDraw->x;
64 yorg += pDraw->y;
65 addrlb = addrlt;
66 addrlt += nlwidth * (yorg - y);
67 addrlb += nlwidth * (yorg + y + dy);
68 while (y) {
69 addrlt += nlwidth;
70 addrlb -= nlwidth;
71 MIFILLARCSTEP(slw);
72 if (!slw)
73 continue;
74 xpos = xorg - x;
75 dawes 3.0 pdst = addrl = afbScanlineOffset(addrlt, (xpos >> PWSH));
76 if (((xpos & PIM) + slw) < PPW) {
77 maskpartialbits(xpos, slw, startmask);
78 for (d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */
79 switch (rrops[d]) {
80 case RROP_BLACK:
81 *pdst &= ~startmask;
82 break;
83 case RROP_WHITE:
84 *pdst |= startmask;
85 break;
86 case RROP_INVERT:
87 *pdst ^= startmask;
88 break;
89 case RROP_NOP:
90 break;
91 }
92 }
93 if (miFillArcLower(slw)) {
94 pdst = afbScanlineOffset(addrlb, (xpos >> PWSH));
95
96 dawes 3.0 for (d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */
97 switch (rrops[d]) {
98 case RROP_BLACK:
99 *pdst &= ~startmask;
100 break;
101 case RROP_WHITE:
102 *pdst |= startmask;
103 break;
104 case RROP_INVERT:
105 *pdst ^= startmask;
106 break;
107 case RROP_NOP:
108 break;
109 }
110 }
111 }
112 continue;
113 }
114 maskbits(xpos, slw, startmask, endmask, nlmiddle);
115 for (d = 0; d < depthDst; d++, addrl += sizeDst) { /* @@@ NEXT PLANE @@@ */
116 n = nlmiddle;
117 dawes 3.0 pdst = addrl;
118
119 switch (rrops[d]) {
120 case RROP_BLACK:
121 if (startmask)
122 *pdst++ &= ~startmask;
123 while (n--)
124 *pdst++ = 0;
125 if (endmask)
126 *pdst &= ~endmask;
127 break;
128
129 case RROP_WHITE:
130 if (startmask)
131 *pdst++ |= startmask;
132 while (n--)
133 *pdst++ = ~0;
134 if (endmask)
135 *pdst |= endmask;
136 break;
137
138 dawes 3.0 case RROP_INVERT:
139 if (startmask)
140 *pdst++ ^= startmask;
141 while (n--)
142 *pdst++ ^= ~0;
143 if (endmask)
144 *pdst ^= endmask;
145 break;
146
147 case RROP_NOP:
148 break;
149 }
150 }
151 if (!miFillArcLower(slw))
152 continue;
153 addrl = afbScanlineOffset(addrlb, (xpos >> PWSH));
154 for (d = 0; d < depthDst; d++, addrl += sizeDst) { /* @@@ NEXT PLANE @@@ */
155 n = nlmiddle;
156 pdst = addrl;
157
158 switch (rrops[d]) {
159 dawes 3.0 case RROP_BLACK:
160 if (startmask)
161 *pdst++ &= ~startmask;
162 while (n--)
163 *pdst++ = 0;
164 if (endmask)
165 *pdst &= ~endmask;
166 break;
167
168 case RROP_WHITE:
169 if (startmask)
170 *pdst++ |= startmask;
171 while (n--)
172 *pdst++ = ~0;
173 if (endmask)
174 *pdst |= endmask;
175 break;
176
177 case RROP_INVERT:
178 if (startmask)
179 *pdst++ ^= startmask;
180 dawes 3.0 while (n--)
181 *pdst++ ^= ~0;
182 if (endmask)
183 *pdst ^= endmask;
184 break;
185
186 case RROP_NOP:
187 break;
188 }
189 }
190 }
191 }
192
193 #define FILLSPAN(xl,xr,addr) \
194 if (xr >= xl) { \
195 width = xr - xl + 1; \
196 addrl = afbScanlineOffset(addr, (xl >> PWSH)); \
197 if (((xl & PIM) + width) < PPW) { \
198 maskpartialbits(xl, width, startmask); \
199 for (pdst = addrl, d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */ \
200 switch (rrops[d]) { \
201 dawes 3.0 case RROP_BLACK: \
202 *pdst &= ~startmask; \
203 break; \
204 case RROP_WHITE: \
205 *pdst |= startmask; \
206 break; \
207 case RROP_INVERT: \
208 *pdst ^= startmask; \
209 break; \
210 case RROP_NOP: \
211 break; \
212 } \
213 } \
214 } else { \
215 maskbits(xl, width, startmask, endmask, nlmiddle); \
216 for (d = 0; d < depthDst; d++, addrl += sizeDst) { /* @@@ NEXT PLANE @@@ */ \
217 n = nlmiddle; \
218 pdst = addrl; \
219 switch (rrops[d]) { \
220 case RROP_BLACK: \
221 if (startmask) \
222 dawes 3.0 *pdst++ &= ~startmask; \
223 while (n--) \
224 *pdst++ = 0; \
225 if (endmask) \
226 *pdst &= ~endmask; \
227 break; \
228 case RROP_WHITE: \
229 if (startmask) \
230 *pdst++ |= startmask; \
231 while (n--) \
232 *pdst++ = ~0; \
233 if (endmask) \
234 *pdst |= endmask; \
235 break; \
236 case RROP_INVERT: \
237 if (startmask) \
238 *pdst++ ^= startmask; \
239 while (n--) \
240 *pdst++ ^= ~0; \
241 if (endmask) \
242 *pdst ^= endmask; \
243 dawes 3.0 break; \
244 case RROP_NOP: \
245 break; \
246 } \
247 } \
248 } \
249 }
250
251 #define FILLSLICESPANS(flip,addr) \
252 if (!flip) { \
253 FILLSPAN(xl, xr, addr); \
254 } else { \
255 xc = xorg - x; \
256 FILLSPAN(xc, xr, addr); \
257 xc += slw - 1; \
258 FILLSPAN(xl, xc, addr); \
259 }
260
261 static void
|
262 dawes 3.3 afbFillArcSliceSolidCopy(DrawablePtr pDraw, GCPtr pGC, xArc *arc,
263 unsigned char *rrops)
|
264 dawes 3.0 {
265 PixelType *addrl;
|
266 dawes 3.3 PixelType *pdst;
267 int n;
268 int d;
|
269 dawes 3.0 int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
|
270 dawes 3.3 int x, y, e;
|
271 dawes 3.0 miFillArcRec info;
272 miArcSliceRec slice;
273 int xl, xr, xc;
274 PixelType *addrlt, *addrlb;
275 int nlwidth;
276 int width;
277 PixelType startmask, endmask;
278 int nlmiddle;
279 int sizeDst;
280 int depthDst;
281
282 afbGetPixelWidthSizeDepthAndPointer(pDraw, nlwidth, sizeDst, depthDst,
283 addrlt);
284 miFillArcSetup(arc, &info);
285 miFillArcSliceSetup(arc, &slice, pGC);
286 MIFILLARCSETUP();
287 xorg += pDraw->x;
288 yorg += pDraw->y;
289 addrlb = addrlt;
290 addrlt = afbScanlineDeltaNoBankSwitch(addrlt, yorg - y, nlwidth);
291 addrlb = afbScanlineDeltaNoBankSwitch(addrlb, yorg + y + dy, nlwidth);
292 dawes 3.0 slice.edge1.x += pDraw->x;
293 slice.edge2.x += pDraw->x;
294 while (y > 0) {
295 afbScanlineIncNoBankSwitch(addrlt, nlwidth);
296 afbScanlineIncNoBankSwitch(addrlb, -nlwidth);
297 MIFILLARCSTEP(slw);
298 MIARCSLICESTEP(slice.edge1);
299 MIARCSLICESTEP(slice.edge2);
300 if (miFillSliceUpper(slice)) {
301 MIARCSLICEUPPER(xl, xr, slice, slw);
302 FILLSLICESPANS(slice.flip_top, addrlt);
303 }
304 if (miFillSliceLower(slice)) {
305 MIARCSLICELOWER(xl, xr, slice, slw);
306 FILLSLICESPANS(slice.flip_bot, addrlb);
307 }
308 }
309 }
310
311 void
|
312 dawes 3.3 afbPolyFillArcSolid(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs)
|
313 dawes 3.0 {
314 afbPrivGC *priv;
|
315 dawes 3.3 xArc *arc;
316 int i;
|
317 dawes 3.0 BoxRec box;
318 RegionPtr cclip;
319 unsigned char *rrops;
320
321 priv = (afbPrivGC *) pGC->devPrivates[afbGCPrivateIndex].ptr;
322 rrops = priv->rrops;
|
323 hohndel 3.1 cclip = pGC->pCompositeClip;
|
324 dawes 3.0 for (arc = parcs, i = narcs; --i >= 0; arc++) {
325 if (miFillArcEmpty(arc))
326 continue;
327 if (miCanFillArc(arc)) {
328 box.x1 = arc->x + pDraw->x;
329 box.y1 = arc->y + pDraw->y;
330 box.x2 = box.x1 + (int)arc->width + 1;
331 box.y2 = box.y1 + (int)arc->height + 1;
332 if (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) {
333 if ((arc->angle2 >= FULLCIRCLE) ||
334 (arc->angle2 <= -FULLCIRCLE))
335 afbFillEllipseSolid(pDraw, arc, rrops);
336 else
337 afbFillArcSliceSolidCopy(pDraw, pGC, arc, rrops);
338 continue;
339 }
340 }
341 miPolyFillArc(pDraw, pGC, 1, arc);
342 }
343 }
|