commit 14f8b5ad5afed343063345ebc122dfdc6d4d3c16 Author: Pierre Willenbrock Date: Mon Sep 24 21:43:16 2007 +0200 add clipping for fbCopy-Functions diff --git a/fb/fbcopy.c b/fb/fbcopy.c index 68f403f..96bb5ea 100644 --- a/fb/fbcopy.c +++ b/fb/fbcopy.c @@ -57,33 +57,81 @@ fbCopyNtoN (DrawablePtr pSrcDrawable, while (nbox--) { + int src_x = (pbox->x1 + dx + srcXoff); + int src_y = (pbox->y1 + dy + srcYoff); + int dst_x = (pbox->x1 + dstXoff); + int dst_y = (pbox->y1 + dstYoff); + int width = (pbox->x2 - pbox->x1); + int height = (pbox->y2 - pbox->y1); + if (src_x < 0) + { + width += src_x; + dst_x -= src_x; + src_x = 0; + } + if (src_y < 0) + { + height += src_y; + dst_y -= src_y; + src_y = 0; + } + if (dst_x < 0) + { + width += dst_x; + src_x -= dst_x; + dst_x = 0; + } + if (dst_y < 0) + { + height += dst_y; + src_y -= dst_y; + dst_y = 0; + } + if (pSrcDrawable->type == DRAWABLE_PIXMAP) + { + if (src_x + width > pSrcDrawable->width) + width = pSrcDrawable->width - src_x; + if (src_y + height > pSrcDrawable->height) + height = pSrcDrawable->height - src_y; + } + if (pDstDrawable->type == DRAWABLE_PIXMAP) + { + if (dst_x + width > pDstDrawable->width) + width = pDstDrawable->width - dst_x; + if (dst_y + height > pDstDrawable->height) + height = pDstDrawable->height - dst_y; + } + + if (height <= 0 || width <= 0) + goto next; + #ifndef FB_ACCESS_WRAPPER /* pixman_blt() doesn't support accessors yet */ if (pm == FB_ALLONES && alu == GXcopy && !reverse && !upsidedown) { if (!pixman_blt ((uint32_t *)src, (uint32_t *)dst, srcStride, dstStride, srcBpp, dstBpp, - (pbox->x1 + dx + srcXoff), - (pbox->y1 + dy + srcYoff), - (pbox->x1 + dstXoff), - (pbox->y1 + dstYoff), - (pbox->x2 - pbox->x1), - (pbox->y2 - pbox->y1))) + src_x, + src_y, + dst_x, + dst_y, + width, + height)) goto fallback; else goto next; } fallback: #endif - fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride, + fbBlt (src + src_y * srcStride, srcStride, - (pbox->x1 + dx + srcXoff) * srcBpp, + src_x * srcBpp, - dst + (pbox->y1 + dstYoff) * dstStride, + dst + dst_y * dstStride, dstStride, - (pbox->x1 + dstXoff) * dstBpp, + dst_x * dstBpp, - (pbox->x2 - pbox->x1) * dstBpp, - (pbox->y2 - pbox->y1), + width * dstBpp, + height, alu, pm, @@ -91,9 +139,7 @@ fbCopyNtoN (DrawablePtr pSrcDrawable, reverse, upsidedown); -#ifndef FB_ACCESS_WRAPPER next: -#endif pbox++; } fbFinishAccess (pDstDrawable); @@ -128,18 +174,67 @@ fbCopy1toN (DrawablePtr pSrcDrawable, while (nbox--) { + int src_x = (pbox->x1 + dx + srcXoff); + int src_y = (pbox->y1 + dy + srcYoff); + int dst_x = (pbox->x1 + dstXoff); + int dst_y = (pbox->y1 + dstYoff); + int width = (pbox->x2 - pbox->x1); + int height = (pbox->y2 - pbox->y1); + if (src_x < 0) + { + width += src_x; + dst_x -= src_x; + src_x = 0; + } + if (src_y < 0) + { + height += src_y; + dst_y -= src_y; + src_y = 0; + } + if (dst_x < 0) + { + width += dst_x; + src_x -= dst_x; + dst_x = 0; + } + if (dst_y < 0) + { + height += dst_y; + src_y -= dst_y; + dst_y = 0; + } + + if (pSrcDrawable->type == DRAWABLE_PIXMAP) + { + if (src_x + width > pSrcDrawable->width) + width = pSrcDrawable->width - src_x; + if (src_y + height > pSrcDrawable->height) + height = pSrcDrawable->height - src_y; + } + if (pDstDrawable->type == DRAWABLE_PIXMAP) + { + if (dst_x + width > pDstDrawable->width) + width = pDstDrawable->width - dst_x; + if (dst_y + height > pDstDrawable->height) + height = pDstDrawable->height - dst_y; + } + + if (height <= 0 || width <= 0) + goto next; + if (dstBpp == 1) { - fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride, + fbBlt (src + src_y * srcStride, srcStride, - (pbox->x1 + dx + srcXoff) * srcBpp, + src_x * srcBpp, - dst + (pbox->y1 + dstYoff) * dstStride, + dst + dst_y * dstStride, dstStride, - (pbox->x1 + dstXoff) * dstBpp, + dst_x * dstBpp, - (pbox->x2 - pbox->x1) * dstBpp, - (pbox->y2 - pbox->y1), + width * dstBpp, + height, FbOpaqueStipple1Rop(pGC->alu, pGC->fgPixel,pGC->bgPixel), @@ -151,21 +246,22 @@ fbCopy1toN (DrawablePtr pSrcDrawable, } else { - fbBltOne ((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride), + fbBltOne ((FbStip *) (src + src_y * srcStride), srcStride*(FB_UNIT/FB_STIP_UNIT), - (pbox->x1 + dx + srcXoff), + src_x, - dst + (pbox->y1 + dstYoff) * dstStride, + dst + dst_y * dstStride, dstStride, - (pbox->x1 + dstXoff) * dstBpp, + dst_x * dstBpp, dstBpp, - (pbox->x2 - pbox->x1) * dstBpp, - (pbox->y2 - pbox->y1), + width * dstBpp, + height, pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor); } + next: pbox++; } @@ -201,9 +297,10 @@ fbCopyNto1 (DrawablePtr pSrcDrawable, FbStride dstStride; int dstBpp; int dstXoff, dstYoff; - + fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); fbGetStipDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + fbBltPlane (src + (pbox->y1+ dy + srcYoff) * srcStride, srcStride, (pbox->x1 + dx + srcXoff) * srcBpp,