diff options
Diffstat (limited to 'xorg-server/hw/xgl/xglpict.c')
-rw-r--r-- | xorg-server/hw/xgl/xglpict.c | 787 |
1 files changed, 787 insertions, 0 deletions
diff --git a/xorg-server/hw/xgl/xglpict.c b/xorg-server/hw/xgl/xglpict.c new file mode 100644 index 000000000..fee2431b7 --- /dev/null +++ b/xorg-server/hw/xgl/xglpict.c @@ -0,0 +1,787 @@ +/* + * Copyright © 2004 David Reveman + * + * 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 + * David Reveman not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * David Reveman makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL DAVID REVEMAN 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. + * + * Author: David Reveman <davidr@novell.com> + */ + +#include "xgl.h" +#include "fb.h" + +#ifdef RENDER + +#include "fbpict.h" + +#define XGL_PICTURE_FALLBACK_PROLOGUE(pPicture, func) \ + xglSyncDamageBoxBits (pPicture->pDrawable); \ + XGL_PICTURE_SCREEN_UNWRAP (func) + +#define XGL_PICTURE_FALLBACK_EPILOGUE(pPicture, func, xglfunc) \ + XGL_PICTURE_SCREEN_WRAP (func, xglfunc); \ + xglAddCurrentSurfaceDamage (pPicture->pDrawable) + +void +xglComposite (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + PictureScreenPtr pPictureScreen; + ScreenPtr pScreen = pDst->pDrawable->pScreen; + + XGL_SCREEN_PRIV (pScreen); + + if (xglCompositeGeneral (op, + pSrc, pMask, pDst, NULL, + xSrc, ySrc, + xMask, yMask, + xDst + pDst->pDrawable->x, + yDst + pDst->pDrawable->y, + width, height)) + { + xglAddCurrentBitDamage (pDst->pDrawable); + return; + } + + pPictureScreen = GetPictureScreen (pScreen); + + if (pSrc->pDrawable) + { + if (!xglSyncBits (pSrc->pDrawable, NullBox)) + FatalError (XGL_SW_FAILURE_STRING); + } + + if (pMask && pMask->pDrawable) + { + if (!xglSyncBits (pMask->pDrawable, NullBox)) + FatalError (XGL_SW_FAILURE_STRING); + } + + if (op == PictOpSrc) + { + XGL_DRAWABLE_PIXMAP (pDst->pDrawable); + + if (!xglMapPixmapBits (pPixmap)) + FatalError (XGL_SW_FAILURE_STRING); + } else + xglSyncDamageBoxBits (pDst->pDrawable); + + XGL_PICTURE_SCREEN_UNWRAP (Composite); + (*pPictureScreen->Composite) (op, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height); + XGL_PICTURE_SCREEN_WRAP (Composite, xglComposite); + + if (op == PictOpSrc) + { + RegionRec region; + + xDst += pDst->pDrawable->x; + yDst += pDst->pDrawable->y; + + if (pSrc->pDrawable) + { + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + } + + if (pMask && pMask->pDrawable) + { + xMask += pMask->pDrawable->x; + yMask += pMask->pDrawable->y; + } + + if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height)) + return; + + xglAddSurfaceDamage (pDst->pDrawable, ®ion); + REGION_UNINIT (pDst->pDrawable->pScreen, ®ion); + } else + xglAddCurrentSurfaceDamage (pDst->pDrawable); +} + +void +xglAddTriangles (PicturePtr pDst, + INT16 xOff, + INT16 yOff, + int ntri, + xTriangle *tris) +{ + PictureScreenPtr pPictureScreen; + ScreenPtr pScreen = pDst->pDrawable->pScreen; + + XGL_SCREEN_PRIV (pScreen); + XGL_DRAWABLE_PIXMAP_PRIV (pDst->pDrawable); + + pPictureScreen = GetPictureScreen (pScreen); + + pPixmapPriv->damageBox.x1 = 0; + pPixmapPriv->damageBox.y1 = 0; + pPixmapPriv->damageBox.x2 = pDst->pDrawable->width; + pPixmapPriv->damageBox.y2 = pDst->pDrawable->height; + + XGL_PICTURE_FALLBACK_PROLOGUE (pDst, AddTriangles); + (*pPictureScreen->AddTriangles) (pDst, xOff, yOff, ntri, tris); + XGL_PICTURE_FALLBACK_EPILOGUE (pDst, AddTriangles, xglAddTriangles); +} + + +void +xglChangePicture (PicturePtr pPicture, + Mask mask) +{ + PictureScreenPtr pPictureScreen; + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + + XGL_SCREEN_PRIV (pScreen); + XGL_DRAWABLE_PIXMAP_PRIV (pPicture->pDrawable); + + pPictureScreen = GetPictureScreen (pScreen); + + if (pPicture->stateChanges & CPRepeat) + pPixmapPriv->pictureMask |= xglPCFillMask; + + if (pPicture->stateChanges & CPComponentAlpha) + pPixmapPriv->pictureMask |= xglPCComponentAlphaMask; + + if (pPicture->stateChanges & CPDither) + pPixmapPriv->pictureMask |= xglPCDitherMask; + + XGL_PICTURE_SCREEN_UNWRAP (ChangePicture); + (*pPictureScreen->ChangePicture) (pPicture, mask); + XGL_PICTURE_SCREEN_WRAP (ChangePicture, xglChangePicture); +} + +int +xglChangePictureTransform (PicturePtr pPicture, + PictTransform *transform) +{ + PictureScreenPtr pPictureScreen; + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + int ret; + + XGL_SCREEN_PRIV (pScreen); + XGL_DRAWABLE_PIXMAP_PRIV (pPicture->pDrawable); + + pPictureScreen = GetPictureScreen (pScreen); + + if (transform != pPicture->transform || + (transform && memcmp (transform, &pPicture->transform, + sizeof (PictTransform)))) + pPixmapPriv->pictureMask |= xglPCTransformMask; + + XGL_PICTURE_SCREEN_UNWRAP (ChangePictureTransform); + ret = (*pPictureScreen->ChangePictureTransform) (pPicture, transform); + XGL_PICTURE_SCREEN_WRAP (ChangePictureTransform, + xglChangePictureTransform); + + return ret; +} + +int +xglChangePictureFilter (PicturePtr pPicture, + int filter, + xFixed *params, + int nparams) +{ + PictureScreenPtr pPictureScreen; + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + int ret; + + XGL_SCREEN_PRIV (pScreen); + XGL_DRAWABLE_PIXMAP_PRIV (pPicture->pDrawable); + + pPictureScreen = GetPictureScreen (pScreen); + + pPixmapPriv->pictureMask |= xglPCFilterMask; + + XGL_PICTURE_SCREEN_UNWRAP (ChangePictureFilter); + ret = (*pPictureScreen->ChangePictureFilter) (pPicture, filter, + params, nparams); + XGL_PICTURE_SCREEN_WRAP (ChangePictureFilter, xglChangePictureFilter); + + return ret; +} + +static void +xglDestroyDevicePicture (PicturePtr pPicture) +{ + if (pPicture->pSourcePict->source.devPrivate.ptr) + glitz_surface_destroy (pPicture->pSourcePict->source.devPrivate.ptr); +} + +PicturePtr +xglCreateDevicePicture (pointer data) +{ + PicturePtr pPicture; + int error; + + pPicture = CreateDevicePicture (0, &error); + if (!pPicture) + return 0; + + pPicture->pSourcePict->source.devPrivate.ptr = data; + pPicture->pSourcePict->source.Destroy = xglDestroyDevicePicture; + + return pPicture; +} + +static int fillMode[] = { + GLITZ_FILL_TRANSPARENT, /* RepeatNone */ + GLITZ_FILL_REPEAT, /* RepeatNormal */ + GLITZ_FILL_NEAREST, /* RepeatPad */ + GLITZ_FILL_REFLECT /* RepeatReflect */ +}; + +static void +xglUpdatePicture (PicturePtr pPicture) +{ + glitz_surface_t *surface; + + XGL_DRAWABLE_PIXMAP_PRIV (pPicture->pDrawable); + + surface = pPixmapPriv->surface; + + if (pPixmapPriv->pictureMask & xglPCFillMask) + { + glitz_surface_set_fill (surface, fillMode[pPicture->repeat]); + } + + if (pPixmapPriv->pictureMask & xglPCFilterMask) + { + switch (pPicture->filter) { + case PictFilterNearest: + case PictFilterFast: + glitz_surface_set_filter (surface, GLITZ_FILTER_NEAREST, NULL, 0); + break; + case PictFilterGood: + case PictFilterBest: + case PictFilterBilinear: + glitz_surface_set_filter (surface, GLITZ_FILTER_BILINEAR, NULL, 0); + break; + case PictFilterConvolution: + glitz_surface_set_filter (surface, GLITZ_FILTER_CONVOLUTION, + (glitz_fixed16_16_t *) + pPicture->filter_params, + pPicture->filter_nparams); + break; + } + } + + if (pPixmapPriv->pictureMask & xglPCTransformMask) + { + glitz_surface_set_transform (surface, (glitz_transform_t *) + pPicture->transform); + } + + if (pPixmapPriv->pictureMask & xglPCComponentAlphaMask) + { + glitz_surface_set_component_alpha (surface, pPicture->componentAlpha); + } + + if (pPixmapPriv->pictureMask & xglPCDitherMask) + { + glitz_surface_set_dither (surface, pPicture->dither); + } + + pPixmapPriv->pictureMask &= ~XGL_PICTURE_CHANGES (~0); +} + +#define N_STACK_PARAM 256 + +static int gradientNParam[] = { + 0, /* SourcePictTypeSolidFill */ + 4, /* SourcePictTypeLinear */ + 6, /* SourcePictTypeRadial */ + 4, /* SourcePictTypeConical */ +}; + +Bool +xglSyncPicture (ScreenPtr pScreen, + PicturePtr pPicture, + INT16 x, + INT16 y, + CARD16 width, + CARD16 height, + INT16 *xOff, + INT16 *yOff) +{ + xglPixmapPtr pPixmapPriv; + + XGL_SCREEN_PRIV (pScreen); + + *xOff = *yOff = 0; + + if (pPicture->pSourcePict) + { + if (pPicture->pSourcePict->source.devPrivate.ptr) + return TRUE; + + if (pPicture->pDrawable) + { + (*pScreen->DestroyPixmap) ((PixmapPtr) pPicture->pDrawable); + pPicture->pDrawable = (DrawablePtr) 0; + } + + switch (pPicture->pSourcePict->source.type) { + case SourcePictTypeSolidFill: + x = y = 0; + width = height = 1; + break; + case SourcePictTypeLinear: + case SourcePictTypeRadial: { + glitz_fixed16_16_t stackParam[N_STACK_PARAM]; + glitz_fixed16_16_t *param; + int nParam, nStop, size, i; + CARD32 *pixel; + PictGradientStopPtr pStop; + glitz_buffer_t *buffer; + glitz_format_t *format; + glitz_surface_t *surface; + static glitz_pixel_format_t pixelFormat = { + GLITZ_FOURCC_RGB, + { + 32, + 0xff000000, + 0x00ff0000, + 0x0000ff00, + 0x000000ff + }, + 0, 0, 0, + GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP + }; + + if (!(pScreenPriv->features & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK)) + break; + + format = glitz_find_standard_format (pScreenPriv->drawable, + GLITZ_STANDARD_ARGB32); + if (!format) + break; + + nParam = gradientNParam[pPicture->pSourcePict->gradient.type]; + pStop = pPicture->pSourcePict->gradient.stops; + nStop = pPicture->pSourcePict->gradient.nstops; + + size = nParam + nStop * 4; + if (size > N_STACK_PARAM) + { + param = malloc (sizeof (xFixed) * size); + if (!param) + break; + } + else + { + param = stackParam; + } + + pixel = (CARD32 *) (param + nParam + nStop * 3); + + buffer = glitz_buffer_create_for_data (pixel); + if (!buffer) + { + if (size > N_STACK_PARAM) + free (param); + + break; + } + + surface = glitz_surface_create (pScreenPriv->drawable, + format, nStop, 1, 0, NULL); + if (!surface) + { + glitz_buffer_destroy (buffer); + if (size > N_STACK_PARAM) + free (param); + + break; + } + + for (i = 0; i < nStop; i++) + { + pixel[i] = pStop[i].color; + + param[nParam + 3 * i + 0] = pStop[i].x; + param[nParam + 3 * i + 1] = i << 16; + param[nParam + 3 * i + 2] = 0; + } + + glitz_set_pixels (surface, 0, 0, nStop, 1, &pixelFormat, buffer); + + glitz_buffer_destroy (buffer); + + switch (pPicture->pSourcePict->source.type) { + case SourcePictTypeLinear: + param[0] = pPicture->pSourcePict->linear.p1.x; + param[1] = pPicture->pSourcePict->linear.p1.y; + param[2] = pPicture->pSourcePict->linear.p2.x; + param[3] = pPicture->pSourcePict->linear.p2.y; + + glitz_surface_set_filter (surface, + GLITZ_FILTER_LINEAR_GRADIENT, + param, nParam + nStop * 3); + break; + case SourcePictTypeRadial: + param[0] = pPicture->pSourcePict->radial.inner.x; + param[1] = pPicture->pSourcePict->radial.inner.y; + param[2] = pPicture->pSourcePict->radial.inner_radius; + param[3] = pPicture->pSourcePict->radial.outer.x; + param[4] = pPicture->pSourcePict->radial.outer.y; + param[5] = pPicture->pSourcePict->radial.outer_radius; + + glitz_surface_set_filter (surface, + GLITZ_FILTER_RADIAL_GRADIENT, + param, nParam + nStop * 3); + break; + } + + glitz_surface_set_fill (surface, fillMode[pPicture->repeat]); + glitz_surface_set_transform (surface, (glitz_transform_t *) + pPicture->transform); + + pPicture->pSourcePict->gradient.devPrivate.ptr = surface; + pPicture->pSourcePict->gradient.Destroy = xglDestroyDevicePicture; + + if (size > N_STACK_PARAM) + free (param); + + return TRUE; + } break; + case SourcePictTypeConical: + default: + break; + } + + if (!pPicture->pDrawable) + { + PictFormatPtr pFormat; + PixmapPtr pPixmap; + PicturePtr pTmp; + RegionRec region; + BoxRec box; + int error; + + pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8); + if (!pFormat) + return FALSE; + + pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, + pFormat->depth, 0); + if (!pPixmap) + return FALSE; + + pTmp = CreatePicture (0, &pPixmap->drawable, pFormat, 0, NULL, + serverClient, &error); + if (!pTmp) + { + (*pScreen->DestroyPixmap) (pPixmap); + return FALSE; + } + + ValidatePicture (pTmp); + + if (!xglSyncBits (pTmp->pDrawable, NullBox)) + FatalError (XGL_SW_FAILURE_STRING); + + fbCompositeGeneral (PictOpSrc, + pPicture, 0, pTmp, + x, y, 0, 0, 0, 0, + width, height); + + FreePicture ((pointer) pTmp, (XID) 0); + + box.x1 = 0; + box.y1 = 0; + box.x2 = width; + box.y2 = height; + + REGION_INIT (pScreen, ®ion, &box, 1); + xglAddSurfaceDamage (&pPixmap->drawable, ®ion); + REGION_UNINIT (pDrawable->pScreen, ®ion); + + pPicture->pDrawable = &pPixmap->drawable; + + *xOff = x; + *yOff = y; + + XGL_GET_PIXMAP_PRIV (pPixmap)->pictureMask &= + ~(xglPCFillMask | xglPCFilterMask | xglPCTransformMask); + } + } + +#ifdef XV + switch (pPicture->format) { + case PICT_yuy2: + xglSetPixmapVisual ((PixmapPtr) pPicture->pDrawable, + &pScreenPriv->pXvVisual[XGL_XV_FORMAT_YUY2]); + break; + case PICT_yv12: + xglSetPixmapVisual ((PixmapPtr) pPicture->pDrawable, + &pScreenPriv->pXvVisual[XGL_XV_FORMAT_YV12]); + default: + break; + } +#endif + + if (!xglSyncSurface (pPicture->pDrawable)) + return FALSE; + + pPixmapPriv = XGL_GET_PIXMAP_PRIV ((PixmapPtr) pPicture->pDrawable); + if (XGL_PICTURE_CHANGES (pPixmapPriv->pictureMask)) + xglUpdatePicture (pPicture); + + return TRUE; +} + +static int +xglVisualDepth (ScreenPtr pScreen, VisualPtr pVisual) +{ + DepthPtr pDepth; + int d, v; + + for (d = 0; d < pScreen->numDepths; d++) + { + pDepth = &pScreen->allowedDepths[d]; + for (v = 0; v < pDepth->numVids; v++) + if (pDepth->vids[v] == pVisual->vid) + return pDepth->depth; + } + + return 0; +} + +typedef struct _xglformatInit { + CARD32 format; + CARD8 depth; +} xglFormatInitRec, *xglFormatInitPtr; + +static int +xglAddFormat (xglFormatInitPtr formats, + int nformat, + CARD32 format, + CARD8 depth) +{ + int n; + + for (n = 0; n < nformat; n++) + if (formats[n].format == format && formats[n].depth == depth) + return nformat; + + formats[nformat].format = format; + formats[nformat].depth = depth; + + return ++nformat; +} + +#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n)) - 1)) + +Bool +xglPictureInit (ScreenPtr pScreen) +{ + int f, nformats = 0; + PictFormatPtr pFormats; + xglFormatInitRec formats[64]; + CARD32 format; + CARD8 depth; + VisualPtr pVisual; + int v; + int bpp; + int r, g, b; + int d; + DepthPtr pDepth; + + /* formats required by protocol */ + formats[nformats].format = PICT_a1; + formats[nformats].depth = 1; + nformats++; + formats[nformats].format = PICT_a4; + formats[nformats].depth = 4; + nformats++; + formats[nformats].format = PICT_a8; + formats[nformats].depth = 8; + nformats++; + formats[nformats].format = PICT_a8r8g8b8; + formats[nformats].depth = 32; + nformats++; + + /* now look through the depths and visuals adding other formats */ + for (v = 0; v < pScreen->numVisuals; v++) + { + pVisual = &pScreen->visuals[v]; + depth = xglVisualDepth (pScreen, pVisual); + if (!depth) + continue; + + bpp = BitsPerPixel (depth); + switch (pVisual->class) { + case DirectColor: + case TrueColor: + r = Ones (pVisual->redMask); + g = Ones (pVisual->greenMask); + b = Ones (pVisual->blueMask); + if (pVisual->offsetBlue == 0 && + pVisual->offsetGreen == b && + pVisual->offsetRed == b + g) + { + format = PICT_FORMAT (bpp, PICT_TYPE_ARGB, 0, r, g, b); + nformats = xglAddFormat (formats, nformats, format, depth); + } + break; + case StaticColor: + case PseudoColor: + case StaticGray: + case GrayScale: + break; + } + } + + /* walk supported depths and add missing Direct formats */ + for (d = 0; d < pScreen->numDepths; d++) + { + pDepth = &pScreen->allowedDepths[d]; + bpp = BitsPerPixel (pDepth->depth); + format = 0; + switch (bpp) { + case 16: + if (pDepth->depth == 15) + nformats = xglAddFormat (formats, nformats, + PICT_x1r5g5b5, pDepth->depth); + if (pDepth->depth == 16) + nformats = xglAddFormat (formats, nformats, + PICT_r5g6b5, pDepth->depth); + break; + case 24: + if (pDepth->depth == 24) + nformats = xglAddFormat (formats, nformats, + PICT_r8g8b8, pDepth->depth); + break; + case 32: + if (pDepth->depth == 24) + nformats = xglAddFormat (formats, nformats, + PICT_x8r8g8b8, pDepth->depth); + break; + } + } + + /* add YUV formats */ + nformats = xglAddFormat (formats, nformats, PICT_yuy2, 16); + nformats = xglAddFormat (formats, nformats, PICT_yv12, 12); + + pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec)); + if (!pFormats) + return 0; + + memset (pFormats, '\0', nformats * sizeof (PictFormatRec)); + for (f = 0; f < nformats; f++) + { + pFormats[f].id = FakeClientID (0); + pFormats[f].depth = formats[f].depth; + format = formats[f].format; + pFormats[f].format = format; + switch (PICT_FORMAT_TYPE (format)) { + case PICT_TYPE_ARGB: + pFormats[f].type = PictTypeDirect; + pFormats[f].direct.alphaMask = Mask (PICT_FORMAT_A (format)); + if (pFormats[f].direct.alphaMask) + pFormats[f].direct.alpha = (PICT_FORMAT_R (format) + + PICT_FORMAT_G (format) + + PICT_FORMAT_B (format)); + + pFormats[f].direct.redMask = Mask (PICT_FORMAT_R (format)); + pFormats[f].direct.red = (PICT_FORMAT_G (format) + + PICT_FORMAT_B (format)); + + pFormats[f].direct.greenMask = Mask (PICT_FORMAT_G (format)); + pFormats[f].direct.green = PICT_FORMAT_B (format); + + pFormats[f].direct.blueMask = Mask (PICT_FORMAT_B (format)); + pFormats[f].direct.blue = 0; + break; + case PICT_TYPE_A: + pFormats[f].type = PictTypeDirect; + pFormats[f].direct.alpha = 0; + pFormats[f].direct.alphaMask = Mask (PICT_FORMAT_A (format)); + break; + case PICT_TYPE_COLOR: + case PICT_TYPE_GRAY: + pFormats[f].type = PictTypeDirect; + break; + case PICT_TYPE_YUY2: + case PICT_TYPE_YV12: + pFormats[f].type = PictTypeOther; + break; + } + } + + if (!fbPictureInit (pScreen, pFormats, nformats)) + return FALSE; + + return TRUE; +} + +void +xglPictureClipExtents (PicturePtr pPicture, + BoxPtr extents) +{ + if (pPicture->clientClipType != CT_NONE) + { + BoxPtr clip = REGION_EXTENTS (pPicture->pDrawable->pScreen, + (RegionPtr) pPicture->clientClip); + + if (extents->x1 < pPicture->clipOrigin.x + clip->x1) + extents->x1 = pPicture->clipOrigin.x + clip->x1; + + if (extents->y1 < pPicture->clipOrigin.y + clip->y1) + extents->y1 = pPicture->clipOrigin.y + clip->y1; + + if (extents->x2 > pPicture->clipOrigin.x + clip->x2) + extents->x2 = pPicture->clipOrigin.x + clip->x2; + + if (extents->y2 > pPicture->clipOrigin.y + clip->y2) + extents->y2 = pPicture->clipOrigin.y + clip->y2; + } + else + { + if (extents->x1 < 0) + extents->x1 = 0; + + if (extents->y1 < 0) + extents->y1 = 0; + + if (extents->x2 > pPicture->pDrawable->width) + extents->x2 = pPicture->pDrawable->width; + + if (extents->y2 > pPicture->pDrawable->height) + extents->y2 = pPicture->pDrawable->height; + } +} + +#endif |