From bc89d1efbda412ce223c26c1e274d0ae2c2f8586 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Thu, 9 Apr 2009 00:40:37 +0000 Subject: [PATCH] - Fix the coordinate manipulation order for AlphaBlend, BitBlt, GradientFill, ExtTextOutW, PatBlt, StretchBltMask and TransparentBlt - The correct setting order is: calculation of base coordinates, conversion to device units, offset by dc origin; thanks to Timo for this hint - Misc: remove unused variable in BitBlt, fix a comment in PolyLine svn path=/trunk/; revision=40426 --- .../subsystems/win32/win32k/objects/bitblt.c | 109 ++++++++++-------- .../win32/win32k/objects/fillshap.c | 15 ++- .../win32/win32k/objects/freetype.c | 15 ++- .../subsystems/win32/win32k/objects/line.c | 2 +- 4 files changed, 81 insertions(+), 60 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/bitblt.c b/reactos/subsystems/win32/win32k/objects/bitblt.c index 8c73cfbf963..99a3476cf5b 100644 --- a/reactos/subsystems/win32/win32k/objects/bitblt.c +++ b/reactos/subsystems/win32/win32k/objects/bitblt.c @@ -86,24 +86,28 @@ NtGdiAlphaBlend( DCSrc = DCDest; } - /* Offset the destination and source by the origin of their DCs. */ - XOriginDest += DCDest->ptlDCOrig.x; - YOriginDest += DCDest->ptlDCOrig.y; - XOriginSrc += DCSrc->ptlDCOrig.x; - YOriginSrc += DCSrc->ptlDCOrig.y; - DestRect.left = XOriginDest; DestRect.top = YOriginDest; DestRect.right = XOriginDest + WidthDest; DestRect.bottom = YOriginDest + HeightDest; IntLPtoDP(DCDest, (LPPOINT)&DestRect, 2); + DestRect.left += DCDest->ptlDCOrig.x; + DestRect.top += DCDest->ptlDCOrig.y; + DestRect.right += DCDest->ptlDCOrig.x; + DestRect.bottom += DCDest->ptlDCOrig.y; + SourceRect.left = XOriginSrc; SourceRect.top = YOriginSrc; SourceRect.right = XOriginSrc + WidthSrc; SourceRect.bottom = YOriginSrc + HeightSrc; IntLPtoDP(DCSrc, (LPPOINT)&SourceRect, 2); + SourceRect.left += DCSrc->ptlDCOrig.x; + SourceRect.top += DCSrc->ptlDCOrig.y; + SourceRect.right += DCSrc->ptlDCOrig.x; + SourceRect.bottom += DCSrc->ptlDCOrig.y; + if (!DestRect.right || !DestRect.bottom || !SourceRect.right || @@ -189,7 +193,7 @@ NtGdiBitBlt( PDC_ATTR pdcattr = NULL; SURFACE *BitmapDest, *BitmapSrc = NULL; RECTL DestRect; - POINTL SourcePoint, BrushOrigin; + POINTL SourcePoint; BOOL Status = FALSE; XLATEOBJ *XlateObj = NULL; BOOL UsesSource = ROP3_USES_SOURCE(ROP); @@ -237,31 +241,27 @@ NtGdiBitBlt( if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) DC_vUpdateFillBrush(DCDest); - /* Offset the destination and source by the origin of their DCs. */ - XDest += DCDest->ptlDCOrig.x; - YDest += DCDest->ptlDCOrig.y; - if (UsesSource) - { - XSrc += DCSrc->ptlDCOrig.x; - YSrc += DCSrc->ptlDCOrig.y; - } - DestRect.left = XDest; DestRect.top = YDest; DestRect.right = XDest+Width; DestRect.bottom = YDest+Height; - IntLPtoDP(DCDest, (LPPOINT)&DestRect, 2); + DestRect.left += DCDest->ptlDCOrig.x; + DestRect.top += DCDest->ptlDCOrig.y; + DestRect.right += DCDest->ptlDCOrig.x; + DestRect.bottom += DCDest->ptlDCOrig.y; + SourcePoint.x = XSrc; SourcePoint.y = YSrc; + if (UsesSource) { IntLPtoDP(DCSrc, (LPPOINT)&SourcePoint, 1); - } - BrushOrigin.x = 0; - BrushOrigin.y = 0; + SourcePoint.x += DCSrc->ptlDCOrig.x; + SourcePoint.y += DCSrc->ptlDCOrig.y; + } /* Determine surfaces to be used in the bitblt */ BitmapDest = SURFACE_LockSurface(DCDest->rosdc.hBitmap); @@ -387,12 +387,6 @@ NtGdiTransparentBlt( return TRUE; } - /* Offset positions */ - xDst += DCDest->ptlDCOrig.x; - yDst += DCDest->ptlDCOrig.y; - xSrc += DCSrc->ptlDCOrig.x; - ySrc += DCSrc->ptlDCOrig.y; - BitmapDest = SURFACE_LockSurface(DCDest->rosdc.hBitmap); if (!BitmapDest) { @@ -444,18 +438,28 @@ NtGdiTransparentBlt( /* Create the XLATE object to convert colors between source and destination */ XlateObj = (XLATEOBJ*)IntEngCreateXlate(PalDestMode, PalSrcMode, DestPalette, SourcePalette); - rcDest.left = xDst; - rcDest.top = yDst; - rcDest.right = rcDest.left + cxDst; + rcDest.left = xDst; + rcDest.top = yDst; + rcDest.right = rcDest.left + cxDst; rcDest.bottom = rcDest.top + cyDst; IntLPtoDP(DCDest, (LPPOINT)&rcDest, 2); - rcSrc.left = xSrc; - rcSrc.top = ySrc; - rcSrc.right = rcSrc.left + cxSrc; + rcDest.left += DCDest->ptlDCOrig.x; + rcDest.top += DCDest->ptlDCOrig.y; + rcDest.right += DCDest->ptlDCOrig.x; + rcDest.bottom += DCDest->ptlDCOrig.y; + + rcSrc.left = xSrc; + rcSrc.top = ySrc; + rcSrc.right = rcSrc.left + cxSrc; rcSrc.bottom = rcSrc.top + cySrc; IntLPtoDP(DCSrc, (LPPOINT)&rcSrc, 2); + rcSrc.left += DCSrc->ptlDCOrig.x; + rcSrc.top += DCSrc->ptlDCOrig.y; + rcSrc.right += DCSrc->ptlDCOrig.x; + rcSrc.bottom += DCSrc->ptlDCOrig.y; + Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, DCDest->rosdc.CombinedClip, XlateObj, &rcDest, &rcSrc, TransparentColor, 0); @@ -792,28 +796,30 @@ GreStretchBltMask( if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) DC_vUpdateFillBrush(DCDest); - /* Offset the destination and source by the origin of their DCs. */ - XOriginDest += DCDest->ptlDCOrig.x; - YOriginDest += DCDest->ptlDCOrig.y; - if (UsesSource) - { - XOriginSrc += DCSrc->ptlDCOrig.x; - YOriginSrc += DCSrc->ptlDCOrig.y; - } - DestRect.left = XOriginDest; DestRect.top = YOriginDest; DestRect.right = XOriginDest+WidthDest; DestRect.bottom = YOriginDest+HeightDest; IntLPtoDP(DCDest, (LPPOINT)&DestRect, 2); + DestRect.left += DCDest->ptlDCOrig.x; + DestRect.top += DCDest->ptlDCOrig.y; + DestRect.right += DCDest->ptlDCOrig.x; + DestRect.bottom += DCDest->ptlDCOrig.y; + SourceRect.left = XOriginSrc; SourceRect.top = YOriginSrc; SourceRect.right = XOriginSrc+WidthSrc; SourceRect.bottom = YOriginSrc+HeightSrc; + if (UsesSource) { IntLPtoDP(DCSrc, (LPPOINT)&SourceRect, 2); + + SourceRect.left += DCSrc->ptlDCOrig.x; + SourceRect.top += DCSrc->ptlDCOrig.y; + SourceRect.right += DCSrc->ptlDCOrig.x; + SourceRect.bottom += DCSrc->ptlDCOrig.y; } BrushOrigin.x = 0; @@ -972,28 +978,33 @@ IntPatBlt( { if (Width > 0) { - DestRect.left = XLeft + dc->ptlDCOrig.x; - DestRect.right = XLeft + Width + dc->ptlDCOrig.x; + DestRect.left = XLeft; + DestRect.right = XLeft + Width; } else { - DestRect.left = XLeft + Width + 1 + dc->ptlDCOrig.x; - DestRect.right = XLeft + dc->ptlDCOrig.x + 1; + DestRect.left = XLeft + Width + 1; + DestRect.right = XLeft + 1; } if (Height > 0) { - DestRect.top = YLeft + dc->ptlDCOrig.y; - DestRect.bottom = YLeft + Height + dc->ptlDCOrig.y; + DestRect.top = YLeft; + DestRect.bottom = YLeft + Height; } else { - DestRect.top = YLeft + Height + dc->ptlDCOrig.y + 1; - DestRect.bottom = YLeft + dc->ptlDCOrig.y + 1; + DestRect.top = YLeft + Height + 1; + DestRect.bottom = YLeft + 1; } IntLPtoDP(dc, (LPPOINT)&DestRect, 2); + DestRect.left += dc->ptlDCOrig.x; + DestRect.top += dc->ptlDCOrig.y; + DestRect.right += dc->ptlDCOrig.x; + DestRect.bottom += dc->ptlDCOrig.y; + BrushOrigin.x = BrushObj->ptOrigin.x + dc->ptlDCOrig.x; BrushOrigin.y = BrushObj->ptOrigin.y + dc->ptlDCOrig.y; diff --git a/reactos/subsystems/win32/win32k/objects/fillshap.c b/reactos/subsystems/win32/win32k/objects/fillshap.c index 15458fb15da..fc56958549f 100644 --- a/reactos/subsystems/win32/win32k/objects/fillshap.c +++ b/reactos/subsystems/win32/win32k/objects/fillshap.c @@ -904,15 +904,18 @@ IntGdiGradientFill( Extent.top = min(Extent.top, (pVertex + i)->y); Extent.bottom = max(Extent.bottom, (pVertex + i)->y); } + IntLPtoDP(dc, (LPPOINT)&Extent, 2); - DitherOrg.x = dc->ptlDCOrig.x; - DitherOrg.y = dc->ptlDCOrig.y; + Extent.left += dc->ptlDCOrig.x; + Extent.right += dc->ptlDCOrig.x; + Extent.top += dc->ptlDCOrig.y; + Extent.bottom += dc->ptlDCOrig.y; + + DitherOrg.x = DitherOrg.y = 0; IntLPtoDP(dc, (LPPOINT)&DitherOrg, 1); - Extent.left += DitherOrg.x; - Extent.right += DitherOrg.x; - Extent.top += DitherOrg.y; - Extent.bottom += DitherOrg.y; + DitherOrg.x += dc->ptlDCOrig.x; + DitherOrg.y += dc->ptlDCOrig.y; psurf = SURFACE_LockSurface(dc->rosdc.hBitmap); /* FIXME - psurf can be NULL!!! Don't assert but handle this case gracefully! */ diff --git a/reactos/subsystems/win32/win32k/objects/freetype.c b/reactos/subsystems/win32/win32k/objects/freetype.c index f867386a5e6..abfb59bd053 100644 --- a/reactos/subsystems/win32/win32k/objects/freetype.c +++ b/reactos/subsystems/win32/win32k/objects/freetype.c @@ -3234,11 +3234,18 @@ GreExtTextOutW( if ((fuOptions & ETO_OPAQUE) && lprc) { - DestRect.left = lprc->left + dc->ptlDCOrig.x; - DestRect.top = lprc->top + dc->ptlDCOrig.y; - DestRect.right = lprc->right + dc->ptlDCOrig.x; - DestRect.bottom = lprc->bottom + dc->ptlDCOrig.y; + DestRect.left = lprc->left; + DestRect.top = lprc->top; + DestRect.right = lprc->right; + DestRect.bottom = lprc->bottom; + IntLPtoDP(dc, (LPPOINT)&DestRect, 2); + + DestRect.left += dc->ptlDCOrig.x; + DestRect.top += dc->ptlDCOrig.y; + DestRect.right += dc->ptlDCOrig.x; + DestRect.bottom += dc->ptlDCOrig.y; + IntEngBitBlt( &psurf->SurfObj, NULL, diff --git a/reactos/subsystems/win32/win32k/objects/line.c b/reactos/subsystems/win32/win32k/objects/line.c index a7feceef4ca..b2fbad6e110 100644 --- a/reactos/subsystems/win32/win32k/objects/line.c +++ b/reactos/subsystems/win32/win32k/objects/line.c @@ -271,7 +271,7 @@ IntGdiPolyline(DC *dc, RtlCopyMemory(Points, pt, Count * sizeof(POINT)); IntLPtoDP(dc, Points, Count); - /* Offset the array of point by the dc->rosdc.DCOrg */ + /* Offset the array of points by the DC origin */ for (i = 0; i < Count; i++) { Points[i].x += dc->ptlDCOrig.x;