diff --git a/reactos/subsystems/win32/win32k/dib/dib.c b/reactos/subsystems/win32/win32k/dib/dib.c index bfae1569677..eaa9566d199 100644 --- a/reactos/subsystems/win32/win32k/dib/dib.c +++ b/reactos/subsystems/win32/win32k/dib/dib.c @@ -224,7 +224,7 @@ BOOLEAN Dummy_BitBlt(PBLTINFO BltInfo) } BOOLEAN Dummy_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, - SURFOBJ *PatternSurface, + SURFOBJ *PatternSurface, SURFOBJ *MaskSurf, RECTL* DestRect, RECTL *SourceRect, POINTL* MaskOrigin, BRUSHOBJ* Brush, POINTL* BrushOrign, diff --git a/reactos/subsystems/win32/win32k/dib/dib.h b/reactos/subsystems/win32/win32k/dib/dib.h index 4ba6827d2a0..5c2549ee04a 100644 --- a/reactos/subsystems/win32/win32k/dib/dib.h +++ b/reactos/subsystems/win32/win32k/dib/dib.h @@ -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_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 @@ ULONG Dummy_GetPixel(SURFOBJ*,LONG,LONG); 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_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULON 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]; diff --git a/reactos/subsystems/win32/win32k/dib/dibXXbpp.c b/reactos/subsystems/win32/win32k/dib/dibXXbpp.c index 579edb40ccc..d615bbde46a 100644 --- a/reactos/subsystems/win32/win32k/dib/dibXXbpp.c +++ b/reactos/subsystems/win32/win32k/dib/dibXXbpp.c @@ -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 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, 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 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, 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,7 +126,19 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, 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 && diff --git a/reactos/subsystems/win32/win32k/eng/bitblt.c b/reactos/subsystems/win32/win32k/eng/bitblt.c index 21f0633648d..0bebfce1c33 100644 --- a/reactos/subsystems/win32/win32k/eng/bitblt.c +++ b/reactos/subsystems/win32/win32k/eng/bitblt.c @@ -808,7 +808,7 @@ CallDibStretchBlt(SURFOBJ* psoDest, } return DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_StretchBlt( - psoDest, psoSource, PatternSurface, + psoDest, psoSource, Mask, PatternSurface, OutputRect, InputRect, MaskOrigin, pbo, &RealBrushOrigin, ColorTranslation, XlatePatternToDest, Rop4); @@ -1021,21 +1021,7 @@ EngStretchBltROP( 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; diff --git a/reactos/subsystems/win32/win32k/include/intgdi.h b/reactos/subsystems/win32/win32k/include/intgdi.h index d04a3f86195..de58b832d4b 100644 --- a/reactos/subsystems/win32/win32k/include/intgdi.h +++ b/reactos/subsystems/win32/win32k/include/intgdi.h @@ -253,5 +253,20 @@ IntGetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, RGBQUAD *Colors); UINT APIENTRY IntSetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, CONST RGBQUAD *Colors); +BOOL APIENTRY +GreStretchBltMask(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_INTGDI_H */ diff --git a/reactos/subsystems/win32/win32k/objects/bitblt.c b/reactos/subsystems/win32/win32k/objects/bitblt.c index ff9c09122fa..478f86affcc 100644 --- a/reactos/subsystems/win32/win32k/objects/bitblt.c +++ b/reactos/subsystems/win32/win32k/objects/bitblt.c @@ -720,7 +720,7 @@ NtGdiPlgBlt( } BOOL APIENTRY -NtGdiStretchBlt( +GreStretchBltMask( HDC hDCDest, INT XOriginDest, INT YOriginDest, @@ -732,12 +732,15 @@ NtGdiStretchBlt( INT WidthSrc, INT HeightSrc, DWORD ROP, - IN DWORD dwBackColor) + IN DWORD dwBackColor, + HDC hDCMask) { PDC DCDest; PDC DCSrc = NULL; + PDC DCMask = NULL; PDC_ATTR pdcattr; SURFACE *BitmapDest, *BitmapSrc = NULL; + SURFACE *BitmapMask = NULL; RECTL DestRect; RECTL SourceRect; BOOL Status = FALSE; @@ -853,6 +856,23 @@ NtGdiStretchBlt( 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("Mask and bitmap sizes don't match!\n"); + goto failed; + } + } + } + /* Perform the bitblt operation */ Status = IntEngStretchBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, @@ -879,15 +899,56 @@ failed: { 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 GreStretchBltMask( + hDCDest, + XOriginDest, + YOriginDest, + WidthDest, + HeightDest, + hDCSrc, + XOriginSrc, + YOriginSrc, + WidthSrc, + HeightSrc, + ROP, + dwBackColor, + NULL); +} + + BOOL FASTCALL IntPatBlt( PDC dc,