From 9c5376d81c4518cc4459dabea26008d20867fc04 Mon Sep 17 00:00:00 2001 From: Mart Raudsepp Date: Tue, 18 Sep 2012 07:45:37 +0300 Subject: [PATCH] Preliminary patch for negative srcX and/or srcY PictOpSrc operations Adds handling of negative srcX or srcY coordinates, which is used by gtk3 GtkTrayIcon implementation via cairo for centering icons on top of the destination area (e.g negative srcX takes transparency from out of bounds from the left and as such the icon itself is shifted right). The completely out of bounds special case check (which need further checking if they are warranted at all per spec) didn't work correctly for negative srcX or srcY because exaScratch.srcWidth/Height are unsigned types, so the negative srcX or srcY got casted to unsigned, which resulted in a big number, so srcX >= 0 was always true (but GCC managed to not warn of the cast). Modified check to be what I believe it was meant to be, but will be double checked later. Various special cases for accelerating more complex cases made the compositing loop not exit out immediately in case of no repeat modes, so we would end up looping a lot and causing misrendering because the tracking variables aren't suitable in this case anymore due to the modifications to shift the coordinates. So exit again immediately for REPEAT_NONE, but this needs a different approach still, as it likely breaks these other complex special cases where the looping is supposedly needed even without repeat mode. Should fix bug 51360, but due to the above may cause other misrendering instead until corrected. --- src/lx_exa.c | 28 ++++++++++++++++++++++++---- 1 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/lx_exa.c b/src/lx_exa.c index bcff23e..9e548ff 100644 --- a/src/lx_exa.c +++ b/src/lx_exa.c @@ -1295,8 +1295,8 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, if (exaScratch.type == COMP_TYPE_ONEPASS) { /* This is the condition srcX or/and srcY is/are out of source * region */ - if (((srcX >= 0 && srcY >= exaScratch.srcHeight) - || (srcX >= exaScratch.srcWidth && srcY >= 0)) && + if (((srcY >= 0 && srcY >= exaScratch.srcHeight) + || (srcX >= 0 && srcX >= exaScratch.srcWidth)) && (exaScratch.op == PictOpOver || exaScratch.op == PictOpSrc)) { if (exaScratch.repeat == 1) { opWidth = width; @@ -1337,8 +1337,25 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, opHeight = height; } else { - /* Have not met this condition till now */ - return; + if (srcX < 0) { + opX -= srcX; + opWidth -= srcX; + width -= srcX; + srcX = -srcX; + } + if (srcY < 0) { + opY -= srcY; + opHeight -= srcY; + height -= srcY; + srcY = -srcY; + } + + if (exaScratch.srcWidth < opWidth) + opWidth = exaScratch.srcWidth; + + if (exaScratch.srcHeight < opHeight) { + opHeight = exaScratch.srcHeight; + } } } else { @@ -1407,6 +1424,9 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, break; } + if (!exaScratch.repeat && !exaScratch.maskrepeat) + break; + opX += opWidth; if (opX >= dstX + width) { -- 1.7.8.6