Evgeniy Boltik <bstsoft@narod.ru>

- Move clipping from StretchBlt to Eng.
- Add ROP support to StretchBlt.
- Fix alphablend support (alphablend.exe produces same result as tested on Windows XP).

See issue #4156 for more details.

svn path=/trunk/; revision=40048
This commit is contained in:
Aleksey Bragin 2009-03-15 20:13:10 +00:00
parent 1ed252413b
commit 6bd4c18a13
4 changed files with 233 additions and 145 deletions

View file

@ -224,10 +224,12 @@ BOOLEAN Dummy_BitBlt(PBLTINFO BltInfo)
} }
BOOLEAN Dummy_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, BOOLEAN Dummy_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFOBJ *PatternSurface,
RECTL* DestRect, RECTL *SourceRect, RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, BRUSHOBJ* Brush, POINTL* MaskOrigin, BRUSHOBJ* Brush,
POINTL* BrushOrign, CLIPOBJ *ClipRegion, POINTL* BrushOrign,
XLATEOBJ *ColorTranslation, ROP4 Rop) XLATEOBJ *ColorTranslation,
XLATEOBJ *XlatePatternToDest, ROP4 Rop)
{ {
return FALSE; return FALSE;
} }

View file

@ -41,7 +41,7 @@ typedef ULONG (*PFN_DIB_GetPixel)(SURFOBJ*,LONG,LONG);
typedef VOID (*PFN_DIB_HLine)(SURFOBJ*,LONG,LONG,LONG,ULONG); typedef VOID (*PFN_DIB_HLine)(SURFOBJ*,LONG,LONG,LONG,ULONG);
typedef VOID (*PFN_DIB_VLine)(SURFOBJ*,LONG,LONG,LONG,ULONG); typedef VOID (*PFN_DIB_VLine)(SURFOBJ*,LONG,LONG,LONG,ULONG);
typedef BOOLEAN (*PFN_DIB_BitBlt)(PBLTINFO); typedef BOOLEAN (*PFN_DIB_BitBlt)(PBLTINFO);
typedef BOOLEAN (*PFN_DIB_StretchBlt)(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,CLIPOBJ*,XLATEOBJ*,ROP4); typedef BOOLEAN (*PFN_DIB_StretchBlt)(SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4);
typedef BOOLEAN (*PFN_DIB_TransparentBlt)(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); typedef BOOLEAN (*PFN_DIB_TransparentBlt)(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
typedef BOOLEAN (*PFN_DIB_ColorFill)(SURFOBJ*, RECTL*, ULONG); typedef BOOLEAN (*PFN_DIB_ColorFill)(SURFOBJ*, RECTL*, ULONG);
typedef BOOLEAN (*PFN_DIB_AlphaBlend)(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); typedef BOOLEAN (*PFN_DIB_AlphaBlend)(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -67,7 +67,7 @@ ULONG Dummy_GetPixel(SURFOBJ*,LONG,LONG);
VOID Dummy_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG); VOID Dummy_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID Dummy_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG); VOID Dummy_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN Dummy_BitBlt(PBLTINFO); BOOLEAN Dummy_BitBlt(PBLTINFO);
BOOLEAN Dummy_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,CLIPOBJ*,XLATEOBJ*,ROP4); BOOLEAN Dummy_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4);
BOOLEAN Dummy_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); BOOLEAN Dummy_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
BOOLEAN Dummy_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN Dummy_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN Dummy_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); BOOLEAN Dummy_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -132,7 +132,7 @@ BOOLEAN DIB_32BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULON
BOOLEAN DIB_32BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN DIB_32BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,CLIPOBJ*,XLATEOBJ*,ROP4); BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4);
extern unsigned char notmask[2]; extern unsigned char notmask[2];
extern unsigned char altnotmask[2]; extern unsigned char altnotmask[2];

View file

@ -23,42 +23,33 @@
#include <debug.h> #include <debug.h>
BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFOBJ *PatternSurface,
RECTL *DestRect, RECTL *SourceRect, RECTL *DestRect, RECTL *SourceRect,
POINTL *MaskOrigin, BRUSHOBJ *Brush, POINTL *MaskOrigin, BRUSHOBJ *Brush,
POINTL *BrushOrigin, CLIPOBJ *ClipRegion, POINTL *BrushOrigin, XLATEOBJ *ColorTranslation,
XLATEOBJ *ColorTranslation, ROP4 ROP) XLATEOBJ *XlatePatternToDest, ROP4 ROP)
{ {
LONG SrcSizeY;
LONG SrcSizeX;
LONG DesSizeY;
LONG DesSizeX;
LONG sx = 0; LONG sx = 0;
LONG sy = 0; LONG sy = 0;
LONG DesX; LONG DesX;
LONG DesY; LONG DesY;
LONG SrcZoomXHight; LONG DstHeight;
LONG SrcZoomXLow; LONG DstWidth;
LONG SrcZoomYHight; LONG SrcHeight;
LONG SrcZoomYLow; LONG SrcWidth;
LONG sy_dec = 0; ULONG Color;
LONG sy_max;
LONG sx_dec = 0;
LONG sx_max;
ULONG color;
ULONG Dest, Source = 0, Pattern = 0; ULONG Dest, Source = 0, Pattern = 0;
ULONG xxBPPMask; ULONG xxBPPMask;
BOOLEAN CanDraw;
PFN_DIB_GetPixel fnSource_GetPixel = NULL; PFN_DIB_GetPixel fnSource_GetPixel = NULL;
PFN_DIB_GetPixel fnDest_GetPixel = NULL; PFN_DIB_GetPixel fnDest_GetPixel = NULL;
PFN_DIB_PutPixel fnDest_PutPixel = NULL; PFN_DIB_PutPixel fnDest_PutPixel = NULL;
PFN_DIB_GetPixel fnPattern_GetPixel = NULL;
RECT_ENUM RectEnum; ULONG PatternX = 0, PatternY = 0;
BOOL EnumMore;
unsigned i;
RECTL OutputRect;
BOOL UsesSource = ROP4_USES_SOURCE(ROP); BOOL UsesSource = ROP4_USES_SOURCE(ROP);
BOOL UsesPattern = ROP4_USES_PATTERN(ROP); BOOL UsesPattern = ROP4_USES_PATTERN(ROP);
@ -76,30 +67,12 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom); BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom);
} }
/* Calc the Zoom height of Source */ DstHeight = DestRect->bottom - DestRect->top;
SrcSizeY = SourceRect->bottom - SourceRect->top; DstWidth = DestRect->right - DestRect->left;
SrcHeight = SourceRect->bottom - SourceRect->top;
SrcWidth = SourceRect->right - SourceRect->left;
/* Calc the Zoom Width of Source */ /* FIXME : MaskOrigin? */
SrcSizeX = SourceRect->right - SourceRect->left;
/* Calc the Zoom height of Destinations */
DesSizeY = DestRect->bottom - DestRect->top;
/* Calc the Zoom width of Destinations */
DesSizeX = DestRect->right - DestRect->left;
/* Calc the zoom factor of source height */
SrcZoomYHight = SrcSizeY / DesSizeY;
SrcZoomYLow = SrcSizeY - (SrcZoomYHight * DesSizeY);
/* Calc the zoom factor of source width */
SrcZoomXHight = SrcSizeX / DesSizeX;
SrcZoomXLow = SrcSizeX - (SrcZoomXHight * DesSizeX);
sx_max = DesSizeX;
sy_max = DesSizeY;
/* FIXME : MaskOrigin, BrushOrigin? */
switch(DestSurf->iBitmapFormat) switch(DestSurf->iBitmapFormat)
{ {
@ -114,74 +87,77 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
if (UsesPattern) if (UsesPattern)
{ {
DPRINT1("StretchBlt does not support pattern ROPs yet\n"); if (PatternSurface)
return TRUE; {
PatternY = (DestRect->top - BrushOrigin->y) % PatternSurface->sizlBitmap.cy;
if (PatternY < 0)
{
PatternY += PatternSurface->sizlBitmap.cy;
}
fnPattern_GetPixel = DibFunctionsForBitmapFormat[PatternSurface->iBitmapFormat].DIB_GetPixel;
}
else
{
if (Brush)
Pattern = Brush->iSolidColor;
}
} }
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0);
do
{
EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
for (i = 0; i < RectEnum.c; i++)
{
OutputRect.left = RectEnum.arcl[i].left;
OutputRect.right = RectEnum.arcl[i].right;
OutputRect.top = RectEnum.arcl[i].top;
OutputRect.bottom = RectEnum.arcl[i].bottom;
sy = SourceRect->top;
sy_dec = 0;
for (DesY = DestRect->top; DesY < DestRect->bottom; DesY++) for (DesY = DestRect->top; DesY < DestRect->bottom; DesY++)
{ {
sx = SourceRect->left; if (PatternSurface)
sx_dec = 0; {
PatternX = (DestRect->left - BrushOrigin->x) % PatternSurface->sizlBitmap.cx;
if (PatternX < 0)
{
PatternX += PatternSurface->sizlBitmap.cx;
}
}
if (UsesSource)
sy = SourceRect->top+(DesY - DestRect->top) * SrcHeight / DstHeight;
for (DesX = DestRect->left; DesX < DestRect->right; DesX++) for (DesX = DestRect->left; DesX < DestRect->right; DesX++)
{ {
/* Check if inside clip region */ CanDraw = TRUE;
if (DesX >= OutputRect.left &&
DesX < OutputRect.right &&
DesY >= OutputRect.top &&
DesY < OutputRect.bottom)
{
if (UsesSource) if (UsesSource)
{
sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth;
if (sx >= 0 && sy >= 0 &&
SourceSurf->sizlBitmap.cx > sx && SourceSurf->sizlBitmap.cy > sy)
{ {
Source = XLATEOBJ_iXlate(ColorTranslation, fnSource_GetPixel(SourceSurf, sx, sy)); Source = XLATEOBJ_iXlate(ColorTranslation, fnSource_GetPixel(SourceSurf, sx, sy));
} }
else
if (UsesPattern)
{ {
/* TBD as soon as BRUSHOBJ is available */ Source = 0;
CanDraw = (ROP3_TO_ROP4(SRCCOPY) != ROP);
}
}
if (CanDraw)
{
if (PatternSurface)
{
Pattern = XLATEOBJ_iXlate(XlatePatternToDest, fnPattern_GetPixel(PatternSurface, PatternX, PatternY));
PatternX++;
PatternX %= PatternSurface->sizlBitmap.cx;
} }
Dest = fnDest_GetPixel(DestSurf, DesX, DesY); Dest = fnDest_GetPixel(DestSurf, DesX, DesY);
color = DIB_DoRop(ROP, Dest, Source, Pattern) & xxBPPMask; Color = DIB_DoRop(ROP, Dest, Source, Pattern) & xxBPPMask;
fnDest_PutPixel(DestSurf, DesX, DesY, color);
fnDest_PutPixel(DestSurf, DesX, DesY, Color);
} }
sx += SrcZoomXHight; }
sx_dec += SrcZoomXLow;
if (sx_dec >= sx_max) if (PatternSurface)
{ {
sx++; PatternY++;
sx_dec -= sx_max; PatternY %= PatternSurface->sizlBitmap.cy;
} }
} }
sy += SrcZoomYHight;
sy_dec += SrcZoomYLow;
if (sy_dec >= sy_max)
{
sy++;
sy_dec -= sy_max;
}
}
}
}
while (EnumMore);
return TRUE; return TRUE;
} }

View file

@ -45,7 +45,6 @@ typedef BOOLEAN (APIENTRY *PBLTRECTFUNC)(SURFOBJ* OutputObj,
typedef BOOLEAN (APIENTRY *PSTRETCHRECTFUNC)(SURFOBJ* OutputObj, typedef BOOLEAN (APIENTRY *PSTRETCHRECTFUNC)(SURFOBJ* OutputObj,
SURFOBJ* InputObj, SURFOBJ* InputObj,
SURFOBJ* Mask, SURFOBJ* Mask,
CLIPOBJ* ClipRegion,
XLATEOBJ* ColorTranslation, XLATEOBJ* ColorTranslation,
RECTL* OutputRect, RECTL* OutputRect,
RECTL* InputRect, RECTL* InputRect,
@ -737,7 +736,6 @@ static BOOLEAN APIENTRY
CallDibStretchBlt(SURFOBJ* psoDest, CallDibStretchBlt(SURFOBJ* psoDest,
SURFOBJ* psoSource, SURFOBJ* psoSource,
SURFOBJ* Mask, SURFOBJ* Mask,
CLIPOBJ* ClipRegion,
XLATEOBJ* ColorTranslation, XLATEOBJ* ColorTranslation,
RECTL* OutputRect, RECTL* OutputRect,
RECTL* InputRect, RECTL* InputRect,
@ -747,6 +745,11 @@ CallDibStretchBlt(SURFOBJ* psoDest,
ROP4 Rop4) ROP4 Rop4)
{ {
POINTL RealBrushOrigin; POINTL RealBrushOrigin;
SURFACE* psurfPattern;
PGDIBRUSHINST GdiBrush = NULL;
SURFOBJ* PatternSurface = NULL;
XLATEOBJ* XlatePatternToDest = NULL;
if (BrushOrigin == NULL) if (BrushOrigin == NULL)
{ {
RealBrushOrigin.x = RealBrushOrigin.y = 0; RealBrushOrigin.x = RealBrushOrigin.y = 0;
@ -755,8 +758,37 @@ CallDibStretchBlt(SURFOBJ* psoDest,
{ {
RealBrushOrigin = *BrushOrigin; RealBrushOrigin = *BrushOrigin;
} }
/* Pattern brush */
if (ROP4_USES_PATTERN(Rop4) && Brush && Brush->iSolidColor == 0xFFFFFFFF)
{
GdiBrush = CONTAINING_RECORD(Brush, GDIBRUSHINST, BrushObject);
psurfPattern = SURFACE_LockSurface(GdiBrush->GdiBrushObject->hbmPattern);
if (psurfPattern)
{
PatternSurface = &psurfPattern->SurfObj;
}
else
{
/* FIXME - What to do here? */
}
XlatePatternToDest = GdiBrush->XlateObject;
}
else
{
psurfPattern = NULL;
}
return DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_StretchBlt( return DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_StretchBlt(
psoDest, psoSource, OutputRect, InputRect, MaskOrigin, Brush, &RealBrushOrigin, ClipRegion, ColorTranslation, Rop4); psoDest, psoSource, PatternSurface,
OutputRect, InputRect, MaskOrigin, Brush, &RealBrushOrigin,
ColorTranslation, XlatePatternToDest, Rop4);
/* Pattern brush */
if (psurfPattern)
{
SURFACE_UnlockSurface(psurfPattern);
}
} }
@ -836,10 +868,34 @@ EngStretchBltROP(
SURFOBJ* psoInput; SURFOBJ* psoInput;
SURFOBJ* psoOutput; SURFOBJ* psoOutput;
PSTRETCHRECTFUNC BltRectFunc; PSTRETCHRECTFUNC BltRectFunc;
BOOLEAN Ret; BOOLEAN Ret = TRUE;
POINTL AdjustedBrushOrigin; POINTL AdjustedBrushOrigin;
BOOL UsesSource = ROP4_USES_SOURCE(ROP4); BOOL UsesSource = ROP4_USES_SOURCE(ROP4);
BYTE clippingType;
RECTL ClipRect;
RECT_ENUM RectEnum;
BOOL EnumMore;
ULONG Direction;
RECTL CombinedRect;
RECTL InputToCombinedRect;
unsigned i;
LONG DstHeight;
LONG DstWidth;
LONG SrcHeight;
LONG SrcWidth;
/* Determine clipping type */
if (ClipRegion == (CLIPOBJ *) NULL)
{
clippingType = DC_TRIVIAL;
}
else
{
clippingType = ClipRegion->iDComplexity;
}
if (ROP4 == R4_NOOP) if (ROP4 == R4_NOOP)
{ {
/* Copy destination onto itself: nop */ /* Copy destination onto itself: nop */
@ -866,18 +922,6 @@ EngStretchBltROP(
return FALSE; return FALSE;
} }
/* Make sure we don't try to copy anything outside the valid source region */
if (InputRect.left < 0)
{
OutputRect.left -= InputRect.left;
InputRect.left = 0;
}
if (InputRect.top < 0)
{
OutputRect.top -= InputRect.top;
InputRect.top = 0;
}
if (! IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, if (! IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE,
&Translate, &psoInput)) &Translate, &psoInput))
{ {
@ -965,9 +1009,88 @@ EngStretchBltROP(
BltRectFunc = CallDibStretchBlt; BltRectFunc = CallDibStretchBlt;
} }
Ret = (*BltRectFunc)(psoOutput, psoInput, Mask, ClipRegion, DstHeight = OutputRect.bottom - OutputRect.top;
DstWidth = OutputRect.right - OutputRect.left;
SrcHeight = InputRect.bottom - InputRect.top;
SrcWidth = InputRect.right - InputRect.left;
switch (clippingType)
{
case DC_TRIVIAL:
Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
ColorTranslation, &OutputRect, &InputRect, MaskOrigin, ColorTranslation, &OutputRect, &InputRect, MaskOrigin,
Brush, &AdjustedBrushOrigin, ROP4); Brush, &AdjustedBrushOrigin, ROP4);
break;
case DC_RECT:
// Clip the blt to the clip rectangle
ClipRect.left = ClipRegion->rclBounds.left + Translate.x;
ClipRect.right = ClipRegion->rclBounds.right + Translate.x;
ClipRect.top = ClipRegion->rclBounds.top + Translate.y;
ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y;
if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
{
InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
ColorTranslation,
&CombinedRect,
&InputToCombinedRect,
MaskOrigin,
Brush,
&AdjustedBrushOrigin,
ROP4);
}
break;
case DC_COMPLEX:
if (psoOutput == psoInput)
{
if (OutputRect.top < InputRect.top)
{
Direction = OutputRect.left < InputRect.left ?
CD_RIGHTDOWN : CD_LEFTDOWN;
}
else
{
Direction = OutputRect.left < InputRect.left ?
CD_RIGHTUP : CD_LEFTUP;
}
}
else
{
Direction = CD_ANY;
}
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, Direction, 0);
do
{
EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum),
(PVOID) &RectEnum);
for (i = 0; i < RectEnum.c; i++)
{
ClipRect.left = RectEnum.arcl[i].left + Translate.x;
ClipRect.right = RectEnum.arcl[i].right + Translate.x;
ClipRect.top = RectEnum.arcl[i].top + Translate.y;
ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y;
if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect))
{
InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight;
InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight;
InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth;
InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth;
Ret = (*BltRectFunc)(psoOutput, psoInput, Mask,
ColorTranslation,
&CombinedRect,
&InputToCombinedRect,
MaskOrigin,
Brush,
&AdjustedBrushOrigin,
ROP4);
}
}
}
while (EnumMore);
break;
}
IntEngLeave(&EnterLeaveDest); IntEngLeave(&EnterLeaveDest);
if (UsesSource) if (UsesSource)
@ -1061,18 +1184,6 @@ IntEngStretchBlt(SURFOBJ *psoDest,
} }
InputRect = *SourceRect; InputRect = *SourceRect;
/* Make sure we don't try to copy anything outside the valid source region */
if (InputRect.left < 0)
{
InputClippedRect.left -= InputRect.left;
InputRect.left = 0;
}
if (InputRect.top < 0)
{
InputClippedRect.top -= InputRect.top;
InputRect.top = 0;
}
if (InputClippedRect.right < InputClippedRect.left || if (InputClippedRect.right < InputClippedRect.left ||
InputClippedRect.bottom < InputClippedRect.top) InputClippedRect.bottom < InputClippedRect.top)
{ {
@ -1129,19 +1240,18 @@ IntEngStretchBlt(SURFOBJ *psoDest,
/* Prepare color adjustment */ /* Prepare color adjustment */
/* Call the driver's DrvStretchBlt if available */ /* Call the driver's DrvStretchBlt if available */
if (psurfDest->flHooks & HOOK_STRETCHBLT) if (psurfDest->flHooks & HOOK_STRETCHBLTROP)
{ {
/* Drv->StretchBlt (look at http://www.osr.com/ddk/graphics/ddifncs_3ew7.htm ) */ /* Drv->StretchBltROP (look at http://www.osronline.com/ddkx/graphics/ddifncs_0z3b.htm ) */
// FIXME: MaskOrigin is always NULL ! // FIXME: MaskOrigin is always NULL !
ret = GDIDEVFUNCS(psoDest).StretchBlt( ret = GDIDEVFUNCS(psoDest).StretchBltROP(psoDest, (UsesSource) ? psoSource : NULL, MaskSurf, ClipRegion, ColorTranslation,
psoDest, (UsesSource) ? psoSource : NULL, MaskSurf, ClipRegion, ColorTranslation, &ca, BrushOrigin, &OutputRect, &InputRect, NULL, COLORONCOLOR, Brush, ROP);
&ca, BrushOrigin, &OutputRect, &InputRect, NULL, ROP);
} }
if (! ret) if (! ret)
{ {
// FIXME: see previous fixme // FIXME: see previous fixme
ret = EngStretchBltROP(psoDest, psoSource, MaskSurf, ClipRegion, ColorTranslation, ret = EngStretchBltROP(psoDest, (UsesSource) ? psoSource : NULL, MaskSurf, ClipRegion, ColorTranslation,
&ca, BrushOrigin, &OutputRect, &InputRect, NULL, COLORONCOLOR, Brush, ROP); &ca, BrushOrigin, &OutputRect, &InputRect, NULL, COLORONCOLOR, Brush, ROP);
} }