Index: subsystems/win32/win32k/dib/dib.h =================================================================== --- subsystems/win32/win32k/dib/dib.h (revision 40114) +++ subsystems/win32/win32k/dib/dib.h (working copy) @@ -41,7 +41,7 @@ typedef VOID (*PFN_DIB_HLine)(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_StretchBlt)(SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4); +typedef BOOLEAN (*PFN_DIB_StretchBlt)(SURFOBJ*,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_ColorFill)(SURFOBJ*, RECTL*, ULONG); typedef BOOLEAN (*PFN_DIB_AlphaBlend)(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); @@ -67,7 +67,7 @@ VOID Dummy_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG); VOID Dummy_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG); BOOLEAN Dummy_BitBlt(PBLTINFO); -BOOLEAN Dummy_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4); +BOOLEAN Dummy_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4); BOOLEAN Dummy_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); BOOLEAN Dummy_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN Dummy_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); @@ -132,7 +132,7 @@ BOOLEAN DIB_32BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); -BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4); +BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4); extern unsigned char notmask[2]; extern unsigned char altnotmask[2]; Index: subsystems/win32/win32k/dib/dibXXbpp.c =================================================================== --- subsystems/win32/win32k/dib/dibXXbpp.c (revision 40114) +++ subsystems/win32/win32k/dib/dibXXbpp.c (working copy) @@ -22,7 +22,7 @@ #define NDEBUG #include -BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, +BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *MaskSurf, SURFOBJ *PatternSurface, RECTL *DestRect, RECTL *SourceRect, POINTL *MaskOrigin, BRUSHOBJ *Brush, @@ -48,6 +48,7 @@ PFN_DIB_GetPixel fnDest_GetPixel = NULL; PFN_DIB_PutPixel fnDest_PutPixel = NULL; PFN_DIB_GetPixel fnPattern_GetPixel = NULL; + PFN_DIB_GetPixel fnMask_GetPixel = NULL; ULONG PatternX = 0, PatternY = 0; @@ -67,6 +68,11 @@ BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom); } + if (MaskSurf) + { + fnMask_GetPixel = DibFunctionsForBitmapFormat[MaskSurf->iBitmapFormat].DIB_GetPixel; + } + DstHeight = DestRect->bottom - DestRect->top; DstWidth = DestRect->right - DestRect->left; SrcHeight = SourceRect->bottom - SourceRect->top; @@ -120,9 +126,21 @@ for (DesX = DestRect->left; DesX < DestRect->right; DesX++) { CanDraw = TRUE; - if (UsesSource) + + if (fnMask_GetPixel) { sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth; + if (sx < 0 || sy < 0 || + MaskSurf->sizlBitmap.cx < sx || MaskSurf->sizlBitmap.cy < sy || + fnMask_GetPixel(MaskSurf, sx, sy) != 0) + { + CanDraw = FALSE; + } + } + + if (UsesSource && CanDraw) + { + sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth; if (sx >= 0 && sy >= 0 && SourceSurf->sizlBitmap.cx > sx && SourceSurf->sizlBitmap.cy > sy) { Index: subsystems/win32/win32k/eng/bitblt.c =================================================================== --- subsystems/win32/win32k/eng/bitblt.c (revision 40114) +++ subsystems/win32/win32k/eng/bitblt.c (working copy) @@ -780,7 +780,7 @@ } return DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_StretchBlt( - psoDest, psoSource, PatternSurface, + psoDest, psoSource, Mask, PatternSurface, OutputRect, InputRect, MaskOrigin, Brush, &RealBrushOrigin, ColorTranslation, XlatePatternToDest, Rop4); @@ -993,21 +993,7 @@ AdjustedBrushOrigin = Translate; } - if (Mask != NULL) - { - //BltRectFunc = BltMask; - DPRINT("EngStretchBlt isn't capable of handling mask yet.\n"); - IntEngLeave(&EnterLeaveDest); - if (UsesSource) - { - IntEngLeave(&EnterLeaveSource); - } - return FALSE; - } - else - { - BltRectFunc = CallDibStretchBlt; - } + BltRectFunc = CallDibStretchBlt; DstHeight = OutputRect.bottom - OutputRect.top; DstWidth = OutputRect.right - OutputRect.left; Index: subsystems/win32/win32k/include/bitblt.h =================================================================== --- subsystems/win32/win32k/include/bitblt.h (revision 0) +++ subsystems/win32/win32k/include/bitblt.h (revision 0) @@ -0,0 +1,22 @@ +#ifndef _WIN32K_BITBLT_H +#define _WIN32K_BITBLT_H + +BOOL +APIENTRY +IntNtGdiStretchBlt( + IN HDC hdcDst, + IN INT xDst, + IN INT yDst, + IN INT cxDst, + IN INT cyDst, + IN HDC hdcSrc, + IN INT xSrc, + IN INT ySrc, + IN INT cxSrc, + IN INT cySrc, + IN DWORD dwRop, + IN DWORD dwBackColor, + IN HDC hdcMask +); + +#endif /* _WIN32K_BITBLT_H */ Index: subsystems/win32/win32k/include/win32k.h =================================================================== --- subsystems/win32/win32k/include/win32k.h (revision 40114) +++ subsystems/win32/win32k/include/win32k.h (working copy) @@ -41,6 +41,7 @@ #include #include +#include #include #include #include Index: subsystems/win32/win32k/objects/bitblt.c =================================================================== --- subsystems/win32/win32k/objects/bitblt.c (revision 40114) +++ subsystems/win32/win32k/objects/bitblt.c (working copy) @@ -734,7 +734,7 @@ } BOOL APIENTRY -NtGdiStretchBlt( +IntNtGdiStretchBlt( HDC hDCDest, INT XOriginDest, INT YOriginDest, @@ -746,12 +746,15 @@ INT WidthSrc, INT HeightSrc, DWORD ROP, - IN DWORD dwBackColor) + IN DWORD dwBackColor, + HDC hDCMask) { PDC DCDest; PDC DCSrc = NULL; + PDC DCMask = NULL; PDC_ATTR Dc_Attr; - SURFACE *BitmapDest, *BitmapSrc = NULL; + SURFACE *BitmapDest = NULL, *BitmapSrc = NULL; + SURFACE *BitmapMask = NULL; RECTL DestRect; RECTL SourceRect; BOOL Status = FALSE; @@ -883,9 +886,26 @@ BrushOrigin.x += DCDest->ptlDCOrig.x; BrushOrigin.y += DCDest->ptlDCOrig.y; + //Make mask surface for source surface + if (BitmapSrc && hDCMask) + { + DCMask = DC_LockDc(hDCMask); + if (DCMask) + { + BitmapMask = SURFACE_LockSurface(DCMask->rosdc.hBitmap); + if (BitmapMask && + (BitmapMask->SurfObj.sizlBitmap.cx != WidthSrc || + BitmapMask->SurfObj.sizlBitmap.cy != HeightSrc)) + { + DPRINT1("Size mask not compatable size source.\n"); + goto failed; + } + } + } + /* Perform the bitblt operation */ Status = IntEngStretchBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, - NULL, DCDest->rosdc.CombinedClip, XlateObj, + BitmapMask ? &BitmapMask->SurfObj : NULL, DCDest->rosdc.CombinedClip, XlateObj, &DestRect, &SourceRect, NULL, BrushObj ? &BrushInst.BrushObject : NULL, &BrushOrigin, ROP3_TO_ROP4(ROP)); @@ -907,15 +927,56 @@ { SURFACE_UnlockSurface(BitmapDest); } + if (BitmapMask) + { + SURFACE_UnlockSurface(BitmapMask); + } if (UsesSource && hDCSrc != hDCDest) { DC_UnlockDc(DCSrc); } + if (DCMask) + { + DC_UnlockDc(DCMask); + } DC_UnlockDc(DCDest); return Status; } + +BOOL APIENTRY +NtGdiStretchBlt( + HDC hDCDest, + INT XOriginDest, + INT YOriginDest, + INT WidthDest, + INT HeightDest, + HDC hDCSrc, + INT XOriginSrc, + INT YOriginSrc, + INT WidthSrc, + INT HeightSrc, + DWORD ROP, + IN DWORD dwBackColor) +{ + return IntNtGdiStretchBlt( + hDCDest, + XOriginDest, + YOriginDest, + WidthDest, + HeightDest, + hDCSrc, + XOriginSrc, + YOriginSrc, + WidthSrc, + HeightSrc, + ROP, + dwBackColor, + NULL); +} + + BOOL FASTCALL IntPatBlt( PDC dc,