- 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
This commit is contained in:
Gregor Schneider 2009-04-09 00:40:37 +00:00
parent f1e2788dc6
commit bc89d1efbd
4 changed files with 81 additions and 60 deletions

View file

@ -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;

View file

@ -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! */

View file

@ -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,

View file

@ -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;