186 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			186 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  *
 | |
|  * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
 | |
|  *
 | |
|  * 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 "scrnintstr.h"
 | |
| #include "gcstruct.h"
 | |
| #include "pixmapstr.h"
 | |
| #include "windowstr.h"
 | |
| #include "mi.h"
 | |
| #include "picturestr.h"
 | |
| #include "mipict.h"
 | |
| 
 | |
| static void
 | |
| miColorRects (PicturePtr    pDst,
 | |
| 	      PicturePtr    pClipPict,
 | |
| 	      xRenderColor  *color,
 | |
| 	      int	    nRect,
 | |
| 	      xRectangle    *rects,
 | |
| 	      int	    xoff,
 | |
| 	      int	    yoff)
 | |
| {
 | |
|     ScreenPtr		pScreen = pDst->pDrawable->pScreen;
 | |
|     CARD32		pixel;
 | |
|     GCPtr		pGC;
 | |
|     CARD32		tmpval[5];
 | |
|     RegionPtr		pClip;
 | |
|     unsigned long	mask;
 | |
| 
 | |
|     miRenderColorToPixel (pDst->pFormat, color, &pixel);
 | |
| 
 | |
|     pGC = GetScratchGC (pDst->pDrawable->depth, pScreen);
 | |
|     if (!pGC)
 | |
| 	return;
 | |
|     tmpval[0] = GXcopy;
 | |
|     tmpval[1] = pixel;
 | |
|     tmpval[2] = pDst->subWindowMode;
 | |
|     mask = GCFunction | GCForeground | GCSubwindowMode;
 | |
|     if (pClipPict->clientClipType == CT_REGION)
 | |
|     {
 | |
| 	tmpval[3] = pDst->clipOrigin.x - xoff;
 | |
| 	tmpval[4] = pDst->clipOrigin.y - yoff;
 | |
| 	mask |= GCClipXOrigin|GCClipYOrigin;
 | |
| 	
 | |
| 	pClip = REGION_CREATE (pScreen, NULL, 1);
 | |
| 	REGION_COPY (pScreen, pClip,
 | |
| 		     (RegionPtr) pClipPict->clientClip);
 | |
| 	(*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);
 | |
|     }
 | |
| 
 | |
|     ChangeGC (pGC, mask, tmpval);
 | |
|     ValidateGC (pDst->pDrawable, pGC);
 | |
|     if (xoff || yoff)
 | |
|     {
 | |
| 	int	i;
 | |
| 	for (i = 0; i < nRect; i++)
 | |
| 	{
 | |
| 	    rects[i].x -= xoff;
 | |
| 	    rects[i].y -= yoff;
 | |
| 	}
 | |
|     }
 | |
|     (*pGC->ops->PolyFillRect) (pDst->pDrawable, pGC, nRect, rects);
 | |
|     if (xoff || yoff)
 | |
|     {
 | |
| 	int	i;
 | |
| 	for (i = 0; i < nRect; i++)
 | |
| 	{
 | |
| 	    rects[i].x += xoff;
 | |
| 	    rects[i].y += yoff;
 | |
| 	}
 | |
|     }
 | |
|     FreeScratchGC (pGC);
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| miCompositeRects (CARD8		op,
 | |
| 		  PicturePtr	pDst,
 | |
| 		  xRenderColor  *color,
 | |
| 		  int		nRect,
 | |
| 		  xRectangle    *rects)
 | |
| {
 | |
|     ScreenPtr		pScreen = pDst->pDrawable->pScreen;
 | |
|     
 | |
|     if (color->alpha == 0xffff)
 | |
|     {
 | |
| 	if (op == PictOpOver)
 | |
| 	    op = PictOpSrc;
 | |
|     }
 | |
|     if (op == PictOpClear)
 | |
| 	color->red = color->green = color->blue = color->alpha = 0;
 | |
|     
 | |
|     if (op == PictOpSrc || op == PictOpClear)
 | |
|     {
 | |
| 	miColorRects (pDst, pDst, color, nRect, rects, 0, 0);
 | |
| 	if (pDst->alphaMap)
 | |
| 	    miColorRects (pDst->alphaMap, pDst,
 | |
| 			  color, nRect, rects,
 | |
| 			  pDst->alphaOrigin.x,
 | |
| 			  pDst->alphaOrigin.y);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
| 	PictFormatPtr	rgbaFormat;
 | |
| 	PixmapPtr	pPixmap;
 | |
| 	PicturePtr	pSrc;
 | |
| 	xRectangle	one;
 | |
| 	int		error;
 | |
| 	Pixel		pixel;
 | |
| 	GCPtr		pGC;
 | |
| 	CARD32		tmpval[2];
 | |
| 
 | |
| 	rgbaFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
 | |
| 	if (!rgbaFormat)
 | |
| 	    goto bail1;
 | |
| 	
 | |
| 	pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1, rgbaFormat->depth,
 | |
| 					    CREATE_PIXMAP_USAGE_SCRATCH);
 | |
| 	if (!pPixmap)
 | |
| 	    goto bail2;
 | |
| 	
 | |
| 	miRenderColorToPixel (rgbaFormat, color, &pixel);
 | |
| 
 | |
| 	pGC = GetScratchGC (rgbaFormat->depth, pScreen);
 | |
| 	if (!pGC)
 | |
| 	    goto bail3;
 | |
| 	tmpval[0] = GXcopy;
 | |
| 	tmpval[1] = pixel;
 | |
| 
 | |
| 	ChangeGC (pGC, GCFunction | GCForeground, tmpval);
 | |
| 	ValidateGC (&pPixmap->drawable, pGC);
 | |
| 	one.x = 0;
 | |
| 	one.y = 0;
 | |
| 	one.width = 1;
 | |
| 	one.height = 1;
 | |
| 	(*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &one);
 | |
| 	
 | |
| 	tmpval[0] = xTrue;
 | |
| 	pSrc = CreatePicture (0, &pPixmap->drawable, rgbaFormat,
 | |
| 			      CPRepeat, tmpval, serverClient, &error);
 | |
| 			      
 | |
| 	if (!pSrc)
 | |
| 	    goto bail4;
 | |
| 
 | |
| 	while (nRect--)
 | |
| 	{
 | |
| 	    CompositePicture (op, pSrc, 0, pDst, 0, 0, 0, 0, 
 | |
| 			      rects->x,
 | |
| 			      rects->y,
 | |
| 			      rects->width,
 | |
| 			      rects->height);
 | |
| 	    rects++;
 | |
| 	}
 | |
| 
 | |
| 	FreePicture ((pointer) pSrc, 0);
 | |
| bail4:
 | |
| 	FreeScratchGC (pGC);
 | |
| bail3:
 | |
| 	(*pScreen->DestroyPixmap) (pPixmap);
 | |
| bail2:
 | |
| bail1:
 | |
| 	;
 | |
|     }
 | |
| }
 |