https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2170901e6ac6f0565bfd8…
commit 2170901e6ac6f0565bfd854d4a3ddc19d87a0050
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Sun Mar 11 23:03:38 2018 +0100
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Sat Jun 30 16:40:04 2018 +0200
[WIN32K] Implement RECTL_bClipRectBySize() and use it in IntEngBitBlt() to clip the
target rect against the bounds of the target surface. Also clip the source rect against
the source surface. Fixes remaining part of CORE-14463
---
win32ss/gdi/eng/bitblt.c | 32 ++++++++++++++++++++++++++------
win32ss/gdi/eng/bitblt_new.c | 9 +++++----
win32ss/gdi/ntgdi/rect.h | 14 ++++++++++++++
3 files changed, 45 insertions(+), 10 deletions(-)
diff --git a/win32ss/gdi/eng/bitblt.c b/win32ss/gdi/eng/bitblt.c
index 9c3e1d1183..8eea77535b 100644
--- a/win32ss/gdi/eng/bitblt.c
+++ b/win32ss/gdi/eng/bitblt.c
@@ -619,20 +619,26 @@ IntEngBitBlt(
BOOL bResult;
RECTL rclClipped;
RECTL rclSrc;
+ RECTL rclSrcClipped;
POINTL ptlBrush;
PFN_DrvBitBlt pfnBitBlt;
+ /* Sanity checks */
+ ASSERT(IS_VALID_ROP4(Rop4));
ASSERT(psoTrg);
+
psurfTrg = CONTAINING_RECORD(psoTrg, SURFACE, SurfObj);
- /* FIXME: Should we really allow to pass non-well-ordered rects? */
+ /* Get the target rect and make it well ordered */
rclClipped = *prclTrg;
RECTL_vMakeWellOrdered(&rclClipped);
- //DPRINT1("Rop4 : 0x%08x\n", Rop4);
-
- /* Sanity check */
- ASSERT(IS_VALID_ROP4(Rop4));
+ /* Clip the target rect against the bounds of the target surface */
+ if (!RECTL_bClipRectBySize(&rclClipped, &rclClipped,
&psoTrg->sizlBitmap))
+ {
+ /* Nothing left */
+ return TRUE;
+ }
if (pco)
{
@@ -660,7 +666,21 @@ IntEngBitBlt(
rclSrc.top = pptlSrc->y + rclClipped.top - prclTrg->top;
rclSrc.right = rclSrc.left + rclClipped.right - rclClipped.left;
rclSrc.bottom = rclSrc.top + rclClipped.bottom - rclClipped.top;
- pptlSrc = (PPOINTL)&rclSrc;
+
+ /* Clip the source rect against the size of the source surface */
+ if (!RECTL_bClipRectBySize(&rclSrcClipped, &rclSrc,
&psoSrc->sizlBitmap))
+ {
+ /* Nothing left */
+ return TRUE;
+ }
+
+ /* Fix up target rect */
+ rclClipped.left += (rclSrcClipped.left - rclSrc.left);
+ rclClipped.top += (rclSrcClipped.top - rclSrc.top);
+ rclClipped.right -= (rclSrc.right - rclSrcClipped.right);
+ rclClipped.bottom -= (rclSrc.bottom - rclSrcClipped.bottom);
+
+ pptlSrc = (PPOINTL)&rclSrcClipped;
}
else
{
diff --git a/win32ss/gdi/eng/bitblt_new.c b/win32ss/gdi/eng/bitblt_new.c
index 56bfade89f..d97886626a 100644
--- a/win32ss/gdi/eng/bitblt_new.c
+++ b/win32ss/gdi/eng/bitblt_new.c
@@ -410,10 +410,11 @@ IntEngBitBlt(
ASSERT(prclTrg);
/* Clip the target rect to the extents of the target surface */
- rcClipped.left = max(prclTrg->left, 0);
- rcClipped.top = max(prclTrg->top, 0);
- rcClipped.right = min(prclTrg->right, psoTrg->sizlBitmap.cx);
- rcClipped.bottom = min(prclTrg->bottom, psoTrg->sizlBitmap.cy);
+ if (!RECTL_bClipRectBySize(&rcClipped, prclTrg, &psoTrg->sizlBitmap))
+ {
+ /* Nothing left */
+ return TRUE;
+ }
/* If no clip object is given, use trivial one */
if (!pco) pco = (CLIPOBJ*)&gxcoTrivial;
diff --git a/win32ss/gdi/ntgdi/rect.h b/win32ss/gdi/ntgdi/rect.h
index 6e975c5f94..a268311ad2 100644
--- a/win32ss/gdi/ntgdi/rect.h
+++ b/win32ss/gdi/ntgdi/rect.h
@@ -67,6 +67,20 @@ RECTL_bIsWellOrdered(
(prcl->top <= prcl->bottom));
}
+FORCEINLINE
+BOOL
+RECTL_bClipRectBySize(
+ _Out_ RECTL *prclDst,
+ _In_ const RECTL *prclSrc,
+ _In_ const SIZEL *pszl)
+{
+ prclDst->left = max(prclSrc->left, 0);
+ prclDst->top = max(prclSrc->top, 0);
+ prclDst->right = min(prclSrc->right, pszl->cx);
+ prclDst->bottom = min(prclSrc->bottom, pszl->cy);
+ return !RECTL_bIsEmptyRect(prclDst);
+}
+
BOOL
FASTCALL
RECTL_bUnionRect(