You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
4.9 KiB

/*
*
* 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(NULL, 1);
REGION_COPY(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);
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, 0, &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:
;
}
}