213 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			213 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * Id: fbfill.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
 | |
|  *
 | |
|  * Copyright © 1998 Keith Packard
 | |
|  *
 | |
|  * Permission to use, copy, modify, distribute, and sell this software and its
 | |
|  * documentation for any purpose is hereby granted without fee, provided that
 | |
|  * the above copyright notice appear in all copies and that both that
 | |
|  * copyright notice and this permission notice appear in supporting
 | |
|  * documentation, and that the name of Keith Packard not be used in
 | |
|  * advertising or publicity pertaining to distribution of the software without
 | |
|  * specific, written prior permission.  Keith Packard makes no
 | |
|  * representations about the suitability of this software for any purpose.  It
 | |
|  * is provided "as is" without express or implied warranty.
 | |
|  *
 | |
|  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | |
|  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | |
|  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | |
|  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | |
|  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | |
|  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | |
|  * PERFORMANCE OF THIS SOFTWARE.
 | |
|  */
 | |
| /* $XFree86: xc/programs/Xserver/fb/fbfill.c,v 1.5 2003/01/29 00:43:33 torrey Exp $ */
 | |
| 
 | |
| #include "fb.h"
 | |
| 
 | |
| void
 | |
| fbFill (DrawablePtr pDrawable,
 | |
| 	GCPtr	    pGC,
 | |
| 	int	    x,
 | |
| 	int	    y,
 | |
| 	int	    width,
 | |
| 	int	    height)
 | |
| {
 | |
|     FbBits	    *dst;
 | |
|     FbStride	    dstStride;
 | |
|     int		    dstBpp;
 | |
|     int		    dstXoff, dstYoff;
 | |
|     FbGCPrivPtr	    pPriv = fbGetGCPrivate(pGC);
 | |
|     
 | |
|     fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
 | |
| 
 | |
|     switch (pGC->fillStyle) {
 | |
|     case FillSolid:
 | |
| 	fbSolid (dst + (y + dstYoff) * dstStride, 
 | |
| 		 dstStride, 
 | |
| 		 (x + dstXoff) * dstBpp,
 | |
| 		 dstBpp,
 | |
| 		 width * dstBpp, height,
 | |
| 		 pPriv->and, pPriv->xor);
 | |
| 	break;
 | |
|     case FillStippled:
 | |
|     case FillOpaqueStippled: {
 | |
| 	PixmapPtr   pStip = pGC->stipple;
 | |
| 	int	    stipWidth = pStip->drawable.width;
 | |
| 	int	    stipHeight = pStip->drawable.height;
 | |
| 	
 | |
| 	if (dstBpp == 1)
 | |
| 	{
 | |
| 	    int		alu;
 | |
| 	    FbBits	*stip;
 | |
| 	    FbStride    stipStride;
 | |
| 	    int		stipBpp;
 | |
| 	    int		stipXoff, stipYoff; /* XXX assumed to be zero */
 | |
| 
 | |
| 	    if (pGC->fillStyle == FillStippled)
 | |
| 		alu = FbStipple1Rop(pGC->alu,pGC->fgPixel);
 | |
| 	    else
 | |
| 		alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel);
 | |
| 	    fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
 | |
| 	    fbTile (dst + (y + dstYoff) * dstStride,
 | |
| 		    dstStride,
 | |
| 		    x + dstXoff,
 | |
| 		    width, height,
 | |
| 		    stip,
 | |
| 		    stipStride,
 | |
| 		    stipWidth,
 | |
| 		    stipHeight,
 | |
| 		    alu,
 | |
| 		    pPriv->pm,
 | |
| 		    dstBpp,
 | |
| 		    
 | |
| 		    (pGC->patOrg.x + pDrawable->x + dstXoff),
 | |
| 		    pGC->patOrg.y + pDrawable->y + dstYoff - y);
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 	    FbStip	*stip;
 | |
| 	    FbStride    stipStride;
 | |
| 	    int		stipBpp;
 | |
| 	    int		stipXoff, stipYoff; /* XXX assumed to be zero */
 | |
| 	    FbBits	fgand, fgxor, bgand, bgxor;
 | |
| 
 | |
| 	    fgand = pPriv->and;
 | |
| 	    fgxor = pPriv->xor;
 | |
| 	    if (pGC->fillStyle == FillStippled)
 | |
| 	    {
 | |
| 		bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES);
 | |
| 		bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES);
 | |
| 	    }
 | |
| 	    else
 | |
| 	    {
 | |
| 		bgand = pPriv->bgand;
 | |
| 		bgxor = pPriv->bgxor;
 | |
| 	    }
 | |
| 
 | |
| 	    fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
 | |
| 	    fbStipple (dst + (y + dstYoff) * dstStride, 
 | |
| 		       dstStride, 
 | |
| 		       (x + dstXoff) * dstBpp,
 | |
| 		       dstBpp,
 | |
| 		       width * dstBpp, height,
 | |
| 		       stip,
 | |
| 		       stipStride,
 | |
| 		       stipWidth,
 | |
| 		       stipHeight,
 | |
| 		       pPriv->evenStipple,
 | |
| 		       fgand, fgxor,
 | |
| 		       bgand, bgxor,
 | |
| 		       pGC->patOrg.x + pDrawable->x + dstXoff,
 | |
| 		       pGC->patOrg.y + pDrawable->y + dstYoff - y);
 | |
| 	}
 | |
| 	break;
 | |
|     }
 | |
|     case FillTiled: {
 | |
| 	PixmapPtr   pTile = pGC->tile.pixmap;
 | |
| 	FbBits	    *tile;
 | |
| 	FbStride    tileStride;
 | |
| 	int	    tileBpp;
 | |
| 	int	    tileWidth;
 | |
| 	int	    tileHeight;
 | |
| 	int	    tileXoff, tileYoff; /* XXX assumed to be zero */
 | |
| 	
 | |
| 	fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff);
 | |
| 	tileWidth = pTile->drawable.width;
 | |
| 	tileHeight = pTile->drawable.height;
 | |
| 	fbTile (dst + (y + dstYoff) * dstStride, 
 | |
| 		dstStride, 
 | |
| 		(x + dstXoff) * dstBpp, 
 | |
| 		width * dstBpp, height,
 | |
| 		tile,
 | |
| 		tileStride,
 | |
| 		tileWidth * tileBpp,
 | |
| 		tileHeight,
 | |
| 		pGC->alu,
 | |
| 		pPriv->pm,
 | |
| 		dstBpp,
 | |
| 		(pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp,
 | |
| 		pGC->patOrg.y + pDrawable->y + dstYoff - y);
 | |
| 	break;
 | |
|     }
 | |
|     }
 | |
|     fbValidateDrawable (pDrawable);
 | |
| }
 | |
| 
 | |
| void
 | |
| fbSolidBoxClipped (DrawablePtr	pDrawable,
 | |
| 		   RegionPtr	pClip,
 | |
| 		   int		x1,
 | |
| 		   int		y1,
 | |
| 		   int		x2,
 | |
| 		   int		y2,
 | |
| 		   FbBits	and,
 | |
| 		   FbBits	xor)
 | |
| {
 | |
|     FbBits	*dst;
 | |
|     FbStride	dstStride;
 | |
|     int		dstBpp;
 | |
|     int		dstXoff, dstYoff;
 | |
|     BoxPtr	pbox;
 | |
|     int		nbox;
 | |
|     int		partX1, partX2, partY1, partY2;
 | |
| 
 | |
|     fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
 | |
|     
 | |
|     for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip); 
 | |
| 	 nbox--; 
 | |
| 	 pbox++)
 | |
|     {
 | |
| 	partX1 = pbox->x1;
 | |
| 	if (partX1 < x1)
 | |
| 	    partX1 = x1;
 | |
| 	
 | |
| 	partX2 = pbox->x2;
 | |
| 	if (partX2 > x2)
 | |
| 	    partX2 = x2;
 | |
| 	
 | |
| 	if (partX2 <= partX1)
 | |
| 	    continue;
 | |
| 	
 | |
| 	partY1 = pbox->y1;
 | |
| 	if (partY1 < y1)
 | |
| 	    partY1 = y1;
 | |
| 	
 | |
| 	partY2 = pbox->y2;
 | |
| 	if (partY2 > y2)
 | |
| 	    partY2 = y2;
 | |
| 	
 | |
| 	if (partY2 <= partY1)
 | |
| 	    continue;
 | |
| 	
 | |
| 	fbSolid (dst + (partY1 + dstYoff) * dstStride,
 | |
| 		 dstStride,
 | |
| 		 (partX1 + dstXoff) * dstBpp,
 | |
| 		 dstBpp,
 | |
| 
 | |
| 		 (partX2 - partX1) * dstBpp,
 | |
| 		 (partY2 - partY1),
 | |
| 		 and, xor);
 | |
|     }
 | |
| }
 |