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

  1 dawes 1.1 /************************************************************
  2           
  3           Copyright (c) 1989  X Consortium
  4           
  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:
 11           
 12           The above copyright notice and this permission notice shall be included in
 13           all copies or substantial portions of the Software.
 14           
 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.
 21           
 22 dawes 1.1 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.
 25           
 26           ********************************************************/
 27           
 28 dawes 1.1.1.2 /* $XConsortium: cfbfillarc.c /main/17 1995/12/06 16:57:18 dpw $ */
 29 dawes 1.1     
 30               #include "X.h"
 31               #include "Xprotostr.h"
 32               #include "miscstruct.h"
 33               #include "gcstruct.h"
 34               #include "pixmapstr.h"
 35               #include "scrnintstr.h"
 36               #include "cfb.h"
 37               #include "cfbmskbits.h"
 38               #include "mifillarc.h"
 39               #include "cfbrrop.h"
 40               #include "mi.h"
 41               
 42               /* gcc 1.35 is stupid */
 43               #if defined(__GNUC__) && defined(mc68020)
 44               #define STUPID volatile
 45               #else
 46               #define STUPID
 47               #endif
 48               
 49               static void
 50 dawes 1.1     RROP_NAME(cfbFillEllipseSolid) (pDraw, pGC, arc)
 51                   DrawablePtr pDraw;
 52                   GCPtr pGC;
 53                   xArc *arc;
 54               {
 55                   STUPID int x, y, e;
 56                   STUPID int yk, xk, ym, xm, dx, dy, xorg, yorg;
 57                   miFillArcRec info;
 58                   unsigned long *addrlt, *addrlb;
 59                   register unsigned long *addrl;
 60                   register int n;
 61                   int nlwidth;
 62                   RROP_DECLARE
 63                   register int xpos;
 64                   register int slw;
 65                   unsigned long startmask, endmask;
 66                   int	nlmiddle;
 67               
 68                   cfbGetLongWidthAndPointer (pDraw, nlwidth, addrlt)
 69               
 70                   RROP_FETCH_GC(pGC);
 71 dawes 1.1         miFillArcSetup(arc, &info);
 72                   MIFILLARCSETUP();
 73                   xorg += pDraw->x;
 74                   yorg += pDraw->y;
 75                   addrlb = addrlt;
 76                   addrlt += nlwidth * (yorg - y);
 77                   addrlb += nlwidth * (yorg + y + dy);
 78                   while (y)
 79                   {
 80               	addrlt += nlwidth;
 81               	addrlb -= nlwidth;
 82               	MIFILLARCSTEP(slw);
 83               	if (!slw)
 84               	    continue;
 85               	xpos = xorg - x;
 86               	addrl = addrlt + (xpos >> PWSH);
 87               	if (((xpos & PIM) + slw) <= PPW)
 88               	{
 89               	    maskpartialbits(xpos, slw, startmask);
 90               	    RROP_SOLID_MASK(addrl,startmask);
 91               	    if (miFillArcLower(slw))
 92 dawes 1.1     	    {
 93               		addrl = addrlb + (xpos >> PWSH);
 94               		RROP_SOLID_MASK(addrl, startmask);
 95               	    }
 96               	    continue;
 97               	}
 98               	maskbits(xpos, slw, startmask, endmask, nlmiddle);
 99               	if (startmask)
100               	{
101               	    RROP_SOLID_MASK(addrl, startmask);
102               	    addrl++;
103               	}
104               	n = nlmiddle;
105               	RROP_SPAN(addrl,n)
106               
107               	if (endmask)
108               	    RROP_SOLID_MASK(addrl, endmask);
109               	if (!miFillArcLower(slw))
110               	    continue;
111               	addrl = addrlb + (xpos >> PWSH);
112               	if (startmask)
113 dawes 1.1     	{
114               	    RROP_SOLID_MASK(addrl, startmask);
115               	    addrl++;
116               	}
117               	n = nlmiddle;
118               	RROP_SPAN(addrl, n);
119               	if (endmask)
120               	    RROP_SOLID_MASK(addrl, endmask);
121                   }
122               }
123               
124               #define FILLSPAN(xl,xr,addr) \
125                   if (xr >= xl) \
126                   { \
127               	n = xr - xl + 1; \
128               	addrl = addr + (xl >> PWSH); \
129               	if (((xl & PIM) + n) <= PPW) \
130               	{ \
131               	    maskpartialbits(xl, n, startmask); \
132               	    RROP_SOLID_MASK(addrl, startmask); \
133               	} \
134 dawes 1.1     	else \
135               	{ \
136               	    maskbits(xl, n, startmask, endmask, n); \
137               	    if (startmask) \
138               	    { \
139               		RROP_SOLID_MASK(addrl, startmask); \
140               		addrl++; \
141               	    } \
142               	    while (n--) \
143               	    { \
144               		RROP_SOLID(addrl); \
145               		++addrl; \
146               	    } \
147               	    if (endmask) \
148               		RROP_SOLID_MASK(addrl, endmask); \
149               	} \
150                   }
151               
152               #define FILLSLICESPANS(flip,addr) \
153                   if (!flip) \
154                   { \
155 dawes 1.1     	FILLSPAN(xl, xr, addr); \
156                   } \
157                   else \
158                   { \
159               	xc = xorg - x; \
160               	FILLSPAN(xc, xr, addr); \
161               	xc += slw - 1; \
162               	FILLSPAN(xl, xc, addr); \
163                   }
164               
165               static void
166               RROP_NAME(cfbFillArcSliceSolid)(pDraw, pGC, arc)
167                   DrawablePtr pDraw;
168                   GCPtr pGC;
169                   xArc *arc;
170               {
171                   int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
172                   register int x, y, e;
173                   miFillArcRec info;
174                   miArcSliceRec slice;
175                   int xl, xr, xc;
176 dawes 1.1         unsigned long *addrlt, *addrlb;
177                   register unsigned long *addrl;
178                   register int n;
179                   int nlwidth;
180                   RROP_DECLARE
181                   unsigned long startmask, endmask;
182               
183                   cfbGetLongWidthAndPointer (pDraw, nlwidth, addrlt)
184               
185                   RROP_FETCH_GC(pGC);
186                   miFillArcSetup(arc, &info);
187                   miFillArcSliceSetup(arc, &slice, pGC);
188                   MIFILLARCSETUP();
189                   xorg += pDraw->x;
190                   yorg += pDraw->y;
191                   addrlb = addrlt;
192                   addrlt += nlwidth * (yorg - y);
193                   addrlb += nlwidth * (yorg + y + dy);
194                   slice.edge1.x += pDraw->x;
195                   slice.edge2.x += pDraw->x;
196                   while (y > 0)
197 dawes 1.1         {
198               	addrlt += nlwidth;
199               	addrlb -= nlwidth;
200               	MIFILLARCSTEP(slw);
201               	MIARCSLICESTEP(slice.edge1);
202               	MIARCSLICESTEP(slice.edge2);
203               	if (miFillSliceUpper(slice))
204               	{
205               	    MIARCSLICEUPPER(xl, xr, slice, slw);
206               	    FILLSLICESPANS(slice.flip_top, addrlt);
207               	}
208               	if (miFillSliceLower(slice))
209               	{
210               	    MIARCSLICELOWER(xl, xr, slice, slw);
211               	    FILLSLICESPANS(slice.flip_bot, addrlb);
212               	}
213                   }
214               }
215               
216               void
217               RROP_NAME(cfbPolyFillArcSolid) (pDraw, pGC, narcs, parcs)
218 dawes 1.1         DrawablePtr	pDraw;
219                   GCPtr	pGC;
220                   int		narcs;
221                   xArc	*parcs;
222               {
223                   register xArc *arc;
224                   register int i;
225 dawes 1.1.1.2     int x2, y2;
226 dawes 1.1         BoxRec box;
227                   RegionPtr cclip;
228               
229                   cclip = cfbGetCompositeClip(pGC);
230                   for (arc = parcs, i = narcs; --i >= 0; arc++)
231                   {
232               	if (miFillArcEmpty(arc))
233               	    continue;
234               	if (miCanFillArc(arc))
235               	{
236               	    box.x1 = arc->x + pDraw->x;
237               	    box.y1 = arc->y + pDraw->y;
238 dawes 1.1.1.2  	    /*
239                	     * Because box.x2 and box.y2 get truncated to 16 bits, and the
240                	     * RECT_IN_REGION test treats the resulting number as a signed
241                	     * integer, the RECT_IN_REGION test alone can go the wrong way.
242                	     * This can result in a server crash because the rendering
243                	     * routines in this file deal directly with cpu addresses
244                	     * of pixels to be stored, and do not clip or otherwise check
245                	     * that all such addresses are within their respective pixmaps.
246                	     * So we only allow the RECT_IN_REGION test to be used for
247                	     * values that can be expressed correctly in a signed short.
248                	     */
249                	    x2 = box.x1 + (int)arc->width + 1;
250                	    box.x2 = x2;
251                	    y2 = box.y1 + (int)arc->height + 1;
252                	    box.y2 = y2;
253                	    if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
254                		    (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
255 dawes 1.1     	    {
256               		if ((arc->angle2 >= FULLCIRCLE) ||
257               		    (arc->angle2 <= -FULLCIRCLE))
258               		    RROP_NAME(cfbFillEllipseSolid)(pDraw, pGC, arc);
259               		else
260               		    RROP_NAME(cfbFillArcSliceSolid)(pDraw, pGC, arc);
261               		continue;
262               	    }
263               	}
264               	miPolyFillArc(pDraw, pGC, 1, arc);
265                   }
266               }

Powered by
ViewCVS 0.9.2