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

  1 dawes 1.1 /*
  2            * Fill rectangles.
  3            */
  4 dawes 3.5 /* $XFree86: xc/programs/Xserver/cfb/cfbfillrct.c,v 3.4tsi Exp $ */
  5 dawes 1.1 
  6           /*
  7           
  8 dawes 3.4 Copyright 1989, 1998  The Open Group
  9 dawes 1.1 
 10 dawes 3.4 All Rights Reserved.
 11 dawes 1.1 
 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 dawes 3.4 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 19 dawes 1.1 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 3.4 Except as contained in this notice, the name of The Open Group shall not be
 23 dawes 1.1 used in advertising or otherwise to promote the sale, use or other dealings
 24 dawes 3.4 in this Software without prior written authorization from The Open Group.
 25 dawes 1.1 */
 26           
 27 dawes 3.4 /* $TOG: cfbfillrct.c /main/20 1998/02/09 14:05:17 kaleb $ */
 28 dawes 1.1 
 29           #include "X.h"
 30           #include "Xmd.h"
 31           #include "servermd.h"
 32           #include "gcstruct.h"
 33           #include "window.h"
 34           #include "pixmapstr.h"
 35           #include "scrnintstr.h"
 36           #include "windowstr.h"
 37 dawes 3.5 #include "mi.h"
 38 dawes 1.1 #include "cfb.h"
 39           #include "cfbmskbits.h"
 40           #include "mergerop.h"
 41           
 42           
 43           void
 44           cfbFillBoxTileOdd (pDrawable, n, rects, tile, xrot, yrot)
 45               DrawablePtr	pDrawable;
 46               int		n;
 47               BoxPtr	rects;
 48               PixmapPtr	tile;
 49               int		xrot, yrot;
 50           {
 51 dawes 3.1 #if PSZ == 24
 52               if (tile->drawable.width & 3)
 53           #else
 54 dawes 1.1     if (tile->drawable.width & PIM)
 55 dawes 3.1 #endif
 56 dawes 1.1 	cfbFillBoxTileOddCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
 57               else
 58           	cfbFillBoxTile32sCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
 59           }
 60           
 61           void
 62           cfbFillRectTileOdd (pDrawable, pGC, nBox, pBox)
 63               DrawablePtr	pDrawable;
 64               GCPtr	pGC;
 65               int		nBox;
 66               BoxPtr	pBox;
 67           {
 68               int	xrot, yrot;
 69               void    (*fill)();
 70           
 71               xrot = pDrawable->x + pGC->patOrg.x;
 72               yrot = pDrawable->y + pGC->patOrg.y;
 73 hohndel 3.2 #if PSZ == 24
 74                 if (pGC->tile.pixmap->drawable.width & 3)
 75             #else
 76 dawes   1.1     if (pGC->tile.pixmap->drawable.width & PIM)
 77 hohndel 3.2 #endif
 78 dawes   1.1     {
 79                 	fill = cfbFillBoxTileOddGeneral;
 80                 	if ((pGC->planemask & PMSK) == PMSK)
 81                 	{
 82             	    if (pGC->alu == GXcopy)
 83             	    	fill = cfbFillBoxTileOddCopy;
 84                 	}
 85                 }
 86                 else
 87                 {
 88                 	fill = cfbFillBoxTile32sGeneral;
 89                 	if ((pGC->planemask & PMSK) == PMSK)
 90                 	{
 91             	    if (pGC->alu == GXcopy)
 92             	    	fill = cfbFillBoxTile32sCopy;
 93                 	}
 94                 }
 95                 (*fill) (pDrawable, nBox, pBox, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
 96             }
 97             
 98             #define NUM_STACK_RECTS	1024
 99 dawes   1.1 
100             void
101             cfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
102                 DrawablePtr pDrawable;
103                 register GCPtr pGC;
104                 int		nrectFill; 	/* number of rectangles to fill */
105                 xRectangle	*prectInit;  	/* Pointer to first rectangle to fill */
106             {
107                 xRectangle	    *prect;
108                 RegionPtr	    prgnClip;
109                 register BoxPtr pbox;
110                 register BoxPtr pboxClipped;
111                 BoxPtr	    pboxClippedBase;
112                 BoxPtr	    pextent;
113                 BoxRec	    stackRects[NUM_STACK_RECTS];
114                 cfbPrivGC	    *priv;
115                 int		    numRects;
116                 void	    (*BoxFill)();
117                 int		    n;
118                 int		    xorg, yorg;
119 dawes   3.0 
120             #if PSZ != 8
121                 if ((pGC->fillStyle == FillStippled) ||
122             	(pGC->fillStyle == FillOpaqueStippled)) {
123                    miPolyFillRect(pDrawable, pGC, nrectFill, prectInit);
124                    return;
125                 }
126             #endif
127 dawes   1.1 
128                 priv = cfbGetGCPrivate(pGC);
129 hohndel 3.3     prgnClip = pGC->pCompositeClip;
130 dawes   1.1 
131                 BoxFill = 0;
132                 switch (pGC->fillStyle)
133                 {
134                 case FillSolid:
135             	switch (priv->rop) {
136             	case GXcopy:
137             	    BoxFill = cfbFillRectSolidCopy;
138             	    break;
139             	case GXxor:
140             	    BoxFill = cfbFillRectSolidXor;
141             	    break;
142             	default:
143             	    BoxFill = cfbFillRectSolidGeneral;
144             	    break;
145             	}
146             	break;
147                 case FillTiled:
148 hohndel 3.3 	if (!pGC->pRotatedPixmap)
149 dawes   1.1 	    BoxFill = cfbFillRectTileOdd;
150             	else
151             	{
152             	    if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK)
153             		BoxFill = cfbFillRectTile32Copy;
154             	    else
155             		BoxFill = cfbFillRectTile32General;
156             	}
157             	break;
158             #if PSZ == 8
159                 case FillStippled:
160 hohndel 3.3 	if (!pGC->pRotatedPixmap)
161 dawes   1.1 	    BoxFill = cfb8FillRectStippledUnnatural;
162             	else
163             	    BoxFill = cfb8FillRectTransparentStippled32;
164             	break;
165                 case FillOpaqueStippled:
166 hohndel 3.3 	if (!pGC->pRotatedPixmap)
167 dawes   1.1 	    BoxFill = cfb8FillRectStippledUnnatural;
168             	else
169             	    BoxFill = cfb8FillRectOpaqueStippled32;
170             	break;
171             #endif
172                 }
173                 prect = prectInit;
174                 xorg = pDrawable->x;
175                 yorg = pDrawable->y;
176                 if (xorg || yorg)
177                 {
178             	prect = prectInit;
179             	n = nrectFill;
180             	while(n--)
181             	{
182             	    prect->x += xorg;
183             	    prect->y += yorg;
184             	    prect++;
185             	}
186                 }
187             
188 dawes   1.1     prect = prectInit;
189             
190                 numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
191                 if (numRects > NUM_STACK_RECTS)
192                 {
193             	pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
194             	if (!pboxClippedBase)
195             	    return;
196                 }
197                 else
198             	pboxClippedBase = stackRects;
199             
200                 pboxClipped = pboxClippedBase;
201             	
202                 if (REGION_NUM_RECTS(prgnClip) == 1)
203                 {
204             	int x1, y1, x2, y2, bx2, by2;
205             
206             	pextent = REGION_RECTS(prgnClip);
207             	x1 = pextent->x1;
208             	y1 = pextent->y1;
209 dawes   1.1 	x2 = pextent->x2;
210             	y2 = pextent->y2;
211                 	while (nrectFill--)
212                 	{
213             	    if ((pboxClipped->x1 = prect->x) < x1)
214             		pboxClipped->x1 = x1;
215                 
216             	    if ((pboxClipped->y1 = prect->y) < y1)
217             		pboxClipped->y1 = y1;
218                 
219             	    bx2 = (int) prect->x + (int) prect->width;
220             	    if (bx2 > x2)
221             		bx2 = x2;
222             	    pboxClipped->x2 = bx2;
223                 
224             	    by2 = (int) prect->y + (int) prect->height;
225             	    if (by2 > y2)
226             		by2 = y2;
227             	    pboxClipped->y2 = by2;
228             
229             	    prect++;
230 dawes   1.1 	    if ((pboxClipped->x1 < pboxClipped->x2) &&
231             		(pboxClipped->y1 < pboxClipped->y2))
232             	    {
233             		pboxClipped++;
234             	    }
235                 	}
236                 }
237                 else
238                 {
239             	int x1, y1, x2, y2, bx2, by2;
240             
241             	pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
242             	x1 = pextent->x1;
243             	y1 = pextent->y1;
244             	x2 = pextent->x2;
245             	y2 = pextent->y2;
246                 	while (nrectFill--)
247                 	{
248             	    BoxRec box;
249                 
250             	    if ((box.x1 = prect->x) < x1)
251 dawes   1.1 		box.x1 = x1;
252                 
253             	    if ((box.y1 = prect->y) < y1)
254             		box.y1 = y1;
255                 
256             	    bx2 = (int) prect->x + (int) prect->width;
257             	    if (bx2 > x2)
258             		bx2 = x2;
259             	    box.x2 = bx2;
260                 
261             	    by2 = (int) prect->y + (int) prect->height;
262             	    if (by2 > y2)
263             		by2 = y2;
264             	    box.y2 = by2;
265                 
266             	    prect++;
267                 
268             	    if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
269             	    	continue;
270                 
271             	    n = REGION_NUM_RECTS (prgnClip);
272 dawes   1.1 	    pbox = REGION_RECTS(prgnClip);
273                 
274             	    /* clip the rectangle to each box in the clip region
275             	       this is logically equivalent to calling Intersect()
276             	    */
277             	    while(n--)
278             	    {
279             		pboxClipped->x1 = max(box.x1, pbox->x1);
280             		pboxClipped->y1 = max(box.y1, pbox->y1);
281             		pboxClipped->x2 = min(box.x2, pbox->x2);
282             		pboxClipped->y2 = min(box.y2, pbox->y2);
283             		pbox++;
284             
285             		/* see if clipping left anything */
286             		if(pboxClipped->x1 < pboxClipped->x2 && 
287             		   pboxClipped->y1 < pboxClipped->y2)
288             		{
289             		    pboxClipped++;
290             		}
291             	    }
292                 	}
293 dawes   1.1     }
294                 if (pboxClipped != pboxClippedBase)
295             	(*BoxFill) (pDrawable, pGC,
296             		    pboxClipped-pboxClippedBase, pboxClippedBase);
297                 if (pboxClippedBase != stackRects)
298                 	DEALLOCATE_LOCAL(pboxClippedBase);
299             }

Powered by
ViewCVS 0.9.2