xenocara/xserver/render/mirect.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:
;
}
}