231 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			231 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * 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.
 | 
						|
 */
 | 
						|
 | 
						|
#ifdef HAVE_DIX_CONFIG_H
 | 
						|
#include <dix-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#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:
 | 
						|
#ifndef FB_ACCESS_WRAPPER
 | 
						|
	if (pPriv->and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
 | 
						|
					x + dstXoff, y + dstYoff,
 | 
						|
					width, height,
 | 
						|
					pPriv->xor))
 | 
						|
#endif	    
 | 
						|
	    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 - y);
 | 
						|
	    fbFinishAccess (&pStip->drawable);
 | 
						|
	}
 | 
						|
	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 - y);
 | 
						|
	    fbFinishAccess (&pStip->drawable);
 | 
						|
	}
 | 
						|
	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 - y);
 | 
						|
	fbFinishAccess (&pTile->drawable);
 | 
						|
	break;
 | 
						|
    }
 | 
						|
    }
 | 
						|
    fbValidateDrawable (pDrawable);
 | 
						|
    fbFinishAccess (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 = RegionNumRects(pClip), pbox = RegionRects(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;
 | 
						|
 | 
						|
#ifndef FB_ACCESS_WRAPPER
 | 
						|
	if (and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
 | 
						|
				 partX1 + dstXoff, partY1 + dstYoff,
 | 
						|
				 (partX2 - partX1), (partY2 - partY1),
 | 
						|
				 xor))
 | 
						|
#endif
 | 
						|
	    fbSolid (dst + (partY1 + dstYoff) * dstStride,
 | 
						|
		     dstStride,
 | 
						|
		     (partX1 + dstXoff) * dstBpp,
 | 
						|
		     dstBpp,
 | 
						|
		     
 | 
						|
		     (partX2 - partX1) * dstBpp,
 | 
						|
		     (partY2 - partY1),
 | 
						|
		     and, xor);
 | 
						|
    }
 | 
						|
    fbFinishAccess (pDrawable);
 | 
						|
}
 |