(file) Return to afbfillarc.c CVS log (file) (dir) Up to [XFree86 CVS] / xc / programs / Xserver / afb

  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             }

Powered by
ViewCVS 0.9.2