From 6e88da2b6e33b8a30c43cfd76a13656258e06b96 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 24 Mar 2012 21:07:46 +0000 Subject: [PATCH] [WIN32K] - Fix right-to-left support the new EngBitBlt code - Remove an ASSERT that we don't support - Fix clipping in IntEngBitBlt by bailing out when the target rect got empty - Delete obsolete file You can use the code now, but there is a bug in the clipping code somewhere, sometimes causing the taskbar to be overwritten svn path=/trunk/; revision=56224 --- .../win32/win32k/diblib/engbitblt.c | 282 ------------------ .../subsystems/win32/win32k/eng/bitblt_new.c | 53 +++- 2 files changed, 37 insertions(+), 298 deletions(-) delete mode 100644 reactos/subsystems/win32/win32k/diblib/engbitblt.c diff --git a/reactos/subsystems/win32/win32k/diblib/engbitblt.c b/reactos/subsystems/win32/win32k/diblib/engbitblt.c deleted file mode 100644 index df0cca7afe8..00000000000 --- a/reactos/subsystems/win32/win32k/diblib/engbitblt.c +++ /dev/null @@ -1,282 +0,0 @@ - -#include "DibLib.h" - -#define ROP4_FGND(Rop4) ((Rop4) & 0x00FF) -#define ROP4_BKGND(Rop4) (((Rop4) & 0xFF00) >> 8) - -#define ROP4_USES_SOURCE(Rop4) (((((Rop4) & 0xCC00) >> 2) != ((Rop4) & 0x3300)) || ((((Rop4) & 0xCC) >> 2) != ((Rop4) & 0x33))) -#define ROP4_USES_MASK(Rop4) (((Rop4) & 0xFF00) != (((Rop4) & 0xff) << 8)) -#define ROP4_USES_DEST(Rop4) (((((Rop4) & 0xAA) >> 1) != ((Rop4) & 0x55)) || ((((Rop4) & 0xAA00) >> 1) != ((Rop4) & 0x5500))) -#define ROP4_USES_PATTERN(Rop4) (((((Rop4) & 0xF0) >> 4) != ((Rop4) & 0x0F)) || ((((Rop4) & 0xF000) >> 4) != ((Rop4) & 0x0F00))) - - -typedef struct -{ - ULONG c; - RECTL arcl[5]; -} RECT_ENUM; - -static -VOID -AdjustOffsetAndSize( - _Out_ PPOINTL pptOffset, - _Out_ PSIZEL psizTrg, - _In_ PPOINTL pptlSrc, - _In_ PSIZEL psizSrc) -{ - ULONG x, y, cxMax, cyMax; - - x = pptlSrc->x + pptOffset->x; - if (x < 0) pptOffset->x -= x, x = 0; - - cxMax = psizSrc->cx - x; - if (psizTrg->cx > cxMax) psizTrg->cx= cxMax; - - y = pptlSrc->y + pptOffset->y; - if (y < 0) pptOffset->y -= y, y = 0; - - cyMax = psizSrc->cy - y; - if (psizTrg->cy > cyMax) psizTrg->cy = cyMax; -} - -BOOL -APIENTRY -EngBitBlt( - _Inout_ SURFOBJ *psoTrg, - _In_opt_ SURFOBJ *psoSrc, - _In_opt_ SURFOBJ *psoMask, - _In_opt_ CLIPOBJ *pco, - _In_opt_ XLATEOBJ *pxlo, - _In_ RECTL *prclTrg, - _When_(psoSrc, _In_) POINTL *pptlSrc, - _When_(psoMask, _In_) POINTL *pptlMask, - _In_opt_ BRUSHOBJ *pbo, - _When_(pbo, _In_) POINTL *pptlBrush, - _In_ ROP4 rop4) -{ - BLTDATA bltdata; - ULONG i, iDComplexity, iDirection, rop3Fg, iFunctionIndex; - RECTL rcTrg; - POINTL ptOffset, ptSrc, ptMask; - SIZEL sizTrg; - PFN_DIBFUNCTION pfnBitBlt; - BOOL bEnumMore; - RECT_ENUM rcenum; - - /* Clip the target rect to the extents of the target surface */ - rcTrg.left = min(prclTrg->left, 0); - rcTrg.top = min(prclTrg->top, 0); - rcTrg.right = min(prclTrg->right, psoTrg->sizlBitmap.cx); - rcTrg.bottom = min(prclTrg->bottom, psoTrg->sizlBitmap.cy); - - /* Check if there is a clipping region */ - iDComplexity = pco ? pco->iDComplexity : DC_TRIVIAL; - if (iDComplexity != DC_TRIVIAL) - { - /* Clip the target rect to the bounds of the clipping region */ - RECTL_bIntersectRect(&rcTrg, prclTrg, &pco->rclBounds); - } - - /* Calculate initial offset and size */ - ptOffset.x = rcTrg.left - prclTrg->left; - ptOffset.y = rcTrg.top - prclTrg->top; - sizTrg.cx = rcTrg.right - rcTrg.left; - sizTrg.cy = rcTrg.bottom - rcTrg.top; - - /* Check if the ROP uses a source */ - if (ROP4_USES_SOURCE(rop4)) - { - /* Must have a source surface and point */ - if (!psoSrc || !pptlSrc) return FALSE; - - /* Get the source point */ - ptSrc = *pptlSrc; - - /* Clip against the extents of the source surface */ - AdjustOffsetAndSize(&ptOffset, &sizTrg, &ptSrc, &psoSrc->sizlBitmap); - - /* Check if source and target are equal */ - if (psoSrc == psoTrg) - { - /* Use 0 to mark source as equal to target */ - bltdata.siSrc.iFormat = 0; - - } - else - { - bltdata.siSrc.iFormat = psoSrc->iBitmapFormat; - } - bltdata.siSrc.pjBase = psoSrc->pvScan0; - bltdata.siSrc.lDelta = psoSrc->lDelta; - } - else - { - ptSrc.x = 0; - ptSrc.y = 0; - } - - /* Check if the ROP uses a mask */ - if (ROP4_USES_MASK(rop4)) - { - /* Must have a mask surface and point */ - if (!psoMask || !pptlMask) return FALSE; - - /* Get the mask point */ - ptMask = *pptlMask; - - /* Clip against the extents of the mask surface */ - AdjustOffsetAndSize(&ptOffset, &sizTrg, &ptMask, &psoMask->sizlBitmap); - - bltdata.siMsk.iFormat = psoMask->iBitmapFormat; - bltdata.siMsk.pjBase = psoMask->pvScan0; - bltdata.siMsk.lDelta = psoMask->lDelta; - } - else - { - ptMask.x = 0; - ptMask.y = 0; - } - - /* Adjust the points */ - ptSrc.x += ptOffset.x; - ptSrc.y += ptOffset.y; - ptMask.x += ptOffset.x; - ptMask.y += ptOffset.y; - - /* Recalculate the target rect */ - rcTrg.left = prclTrg->left + ptOffset.x; - rcTrg.top = prclTrg->top + ptOffset.y; - rcTrg.right = rcTrg.left + sizTrg.cx; - rcTrg.bottom = rcTrg.top + sizTrg.cy; - - bltdata.ulWidth = prclTrg->right - prclTrg->left; - bltdata.ulHeight = prclTrg->bottom - prclTrg->top; - bltdata.pxlo = pxlo; - bltdata.rop4 = rop4; - - bltdata.siDst.iFormat = psoTrg->iBitmapFormat; - bltdata.siDst.pjBase = psoTrg->pvScan0; - bltdata.siDst.lDelta = psoTrg->lDelta; - bltdata.siDst.ptOrig.x = prclTrg->left; - bltdata.siDst.ptOrig.y = prclTrg->top; - - - /* Check of the ROP uses a pattern / brush */ - if (ROP4_USES_PATTERN(rop4)) - { - /* Must have a brush */ - if (!pbo) return FALSE; - - /* Copy the solid color */ - bltdata.ulSolidColor = pbo->iSolidColor; - - /* Check if this is a pattern brush */ - if (pbo->iSolidColor == 0xFFFFFFFF) - { - // FIXME: use EBRUSHOBJ - - bltdata.siPat.iFormat = 0;//psoPat->iBitmapFormat; - bltdata.siPat.pjBase = 0;//psoPat->pvScan0; - bltdata.siPat.lDelta = 0;//psoPat->lDelta; - bltdata.siPat.ptOrig = *pptlBrush; - - bltdata.ulPatWidth = 0; - bltdata.ulPatHeight = 0; - } - } - - /* Analyze the copying direction */ - if (psoTrg == psoSrc) - { - if (rcTrg.top < ptSrc.y) - iDirection = rcTrg.left < ptSrc.x ? CD_RIGHTDOWN : CD_LEFTDOWN; - else - iDirection = rcTrg.left < ptSrc.x ? CD_RIGHTUP : CD_LEFTUP; - } - else - iDirection = CD_ANY; - - /* Check if this is a masking ROP */ - if (ROP4_USES_MASK(rop4)) - { - bltdata.apfnDoRop[0] = gapfnRop[ROP4_BKGND(rop4)]; - bltdata.apfnDoRop[1] = gapfnRop[ROP4_FGND(rop4)]; - } - - /* Get the foreground ROP index */ - rop3Fg = ROP4_FGND(rop4); - - /* Get the function index */ - iFunctionIndex = aiIndexPerRop[rop3Fg]; - - /* Get the dib function */ - pfnBitBlt = apfnDibFunction[iFunctionIndex]; - - /* Check if we need to enumerate rects */ - if (iDComplexity == DC_COMPLEX) - { - /* Start the enumeration of the clip object */ - CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, iDirection, 0); - do - { - /* Enumerate a set of rectangles */ - bEnumMore = CLIPOBJ_bEnum(pco, sizeof(rcenum), (ULONG*)&rcenum); - - /* Loop all rectangles we got */ - for (i = 0; i < rcenum.c; i++) - { - /* Intersect this rect with the already calculated bounds rect */ - if (!RECTL_bIntersectRect(&rcenum.arcl[i], &rcenum.arcl[i], &rcTrg)) - { - /* This rect is outside the valid bounds, continue */ - continue; - } - - /* Copy the target start point */ - bltdata.siDst.ptOrig.x = rcenum.arcl[i].left; - bltdata.siDst.ptOrig.x = rcenum.arcl[i].top; - - /* Calculate width and height of this rect */ - bltdata.ulWidth = rcenum.arcl[i].right - rcenum.arcl[i].left; - bltdata.ulHeight = rcenum.arcl[i].bottom - rcenum.arcl[i].top; - - /* Calculate the offset of this rect from the original coordinates */ - ptOffset.x = rcenum.arcl[i].left - prclTrg->left; - ptOffset.y = rcenum.arcl[i].top - prclTrg->top; - - /* Calculate current origin for source and mask */ - bltdata.siSrc.ptOrig.x = pptlSrc->x + ptOffset.x; - bltdata.siSrc.ptOrig.y = pptlSrc->y + ptOffset.y; - bltdata.siMsk.ptOrig.x = pptlMask->x + ptOffset.x; - bltdata.siMsk.ptOrig.y = pptlMask->y + ptOffset.y; - - //bltdata.siPat.ptOrig.x = (pptlMask->x + ptOffset.x) % psoMask->sizlBitmap.cx; - //bltdata.siPat.ptOrig.y = (pptlMask->y + ptOffset.y) % psoMask->sizlBitmap.cx; - - } - } - while (bEnumMore); - } - else - { - /* Call the dib function */ - pfnBitBlt(&bltdata); - } - - return TRUE; -} - -ULONG -NTAPI -XLATEOBJ_iXlate(XLATEOBJ *pxlo, ULONG ulColor) -{ - return ulColor; -} - -BOOL -//__fastcall -RECTL_bIntersectRect(RECTL* prclDst, const RECTL* prcl1, const RECTL* prcl2) -{ - return TRUE; -} - diff --git a/reactos/subsystems/win32/win32k/eng/bitblt_new.c b/reactos/subsystems/win32/win32k/eng/bitblt_new.c index d73667435d6..f2ae3cde4ad 100644 --- a/reactos/subsystems/win32/win32k/eng/bitblt_new.c +++ b/reactos/subsystems/win32/win32k/eng/bitblt_new.c @@ -27,8 +27,13 @@ CalculateCoordinates( pbltdata->ulWidth = prclClipped->right - prclClipped->left; pbltdata->ulHeight = prclClipped->bottom - prclClipped->top; - /* Calculate the offset to the origin coordinates */ - cx = (prclClipped->left - prclOrg->left); + /* Calculate the x offset to the origin coordinates */ + if (pbltdata->siDst.iFormat == 0) + cx = (prclClipped->right - 1 - prclOrg->left); + else + cx = (prclClipped->left - prclOrg->left); + + /* Calculate the y offset to the origin coordinates */ if (pbltdata->dy < 0) cy = (prclClipped->bottom - 1 - prclOrg->top); else @@ -43,14 +48,11 @@ CalculateCoordinates( pbltdata->siDst.pjBase += pbltdata->siDst.ptOrig.y * pbltdata->siDst.lDelta; pbltdata->siDst.pjBase += pbltdata->siDst.ptOrig.x * pbltdata->siDst.jBpp / 8; - if (pptlSrc) { - /* Calculate current origin for the source */ + /* Calculate start point and bitpointer for source */ pbltdata->siSrc.ptOrig.x = pptlSrc->x + cx; pbltdata->siSrc.ptOrig.y = pptlSrc->y + cy; - - /* Calculate start position for source */ pbltdata->siSrc.pjBase = pbltdata->siSrc.pvScan0; pbltdata->siSrc.pjBase += pbltdata->siSrc.ptOrig.y * pbltdata->siSrc.lDelta; pbltdata->siSrc.pjBase += pbltdata->siSrc.ptOrig.x * pbltdata->siSrc.jBpp / 8; @@ -58,10 +60,9 @@ CalculateCoordinates( if (pptlMask) { + /* Calculate start point and bitpointer for mask */ pbltdata->siMsk.ptOrig.x = pptlMask->x + cx; pbltdata->siMsk.ptOrig.y = pptlMask->y + cy; - - /* Calculate start position for mask */ pbltdata->siMsk.pjBase = pbltdata->siMsk.pvScan0; pbltdata->siMsk.pjBase += pbltdata->siMsk.ptOrig.y * pbltdata->siMsk.lDelta; pbltdata->siMsk.pjBase += pbltdata->siMsk.ptOrig.x * pbltdata->siMsk.jBpp / 8; @@ -69,10 +70,9 @@ CalculateCoordinates( if (pptlPat) { + /* Calculate start point and bitpointer for pattern */ pbltdata->siPat.ptOrig.x = (pptlPat->x + cx) % psizlPat->cx; pbltdata->siPat.ptOrig.y = (pptlPat->x + cy) % psizlPat->cy; - - /* Calculate start position for pattern */ pbltdata->siPat.pjBase = pbltdata->siPat.pvScan0; pbltdata->siPat.pjBase += pbltdata->siPat.ptOrig.y * pbltdata->siPat.lDelta; pbltdata->siPat.pjBase += pbltdata->siPat.ptOrig.x * pbltdata->siPat.jBpp / 8; @@ -158,7 +158,7 @@ EngBitBlt( /* Use 0 as target format to get special right to left versions */ bltdata.siDst.iFormat = 0; bltdata.siSrc.iFormat = psoSrc->iBitmapFormat; - __debugbreak(); + //__debugbreak(); } else { @@ -241,8 +241,9 @@ EngBitBlt( ASSERT(psoMask); ASSERT(pptlMask); - __debugbreak(); + //__debugbreak(); + /* Set the mask format info */ bltdata.siMsk.iFormat = psoMask->iBitmapFormat; bltdata.siMsk.pvScan0 = psoMask->pvScan0; bltdata.siMsk.lDelta = psoMask->lDelta; @@ -342,7 +343,7 @@ AdjustOffsetAndSize( if (x < 0) pptOffset->x -= x, x = 0; cxMax = psizSrc->cx - x; - if (psizTrg->cx > cxMax) psizTrg->cx= cxMax; + if (psizTrg->cx > cxMax) psizTrg->cx = cxMax; y = pptlSrc->y + pptOffset->y; if (y < 0) pptOffset->y -= y, y = 0; @@ -380,7 +381,6 @@ IntEngBitBlt( ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP); ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP); ASSERT(prclTrg); - ASSERT(RECTL_bIsWellOrdered(prclTrg)); /* Clip the target rect to the extents of the target surface */ rcClipped.left = max(prclTrg->left, 0); @@ -395,11 +395,15 @@ IntEngBitBlt( if (pco->iDComplexity != DC_TRIVIAL) { /* Clip the target rect to the bounds of the clipping region */ - RECTL_bIntersectRect(&rcClipped, &rcClipped, &pco->rclBounds); + if (!RECTL_bIntersectRect(&rcClipped, &rcClipped, &pco->rclBounds)) + { + /* Nothing left */ + return TRUE; + } } /* Don't pass a clip object with a single rectangle */ -// if (pco->iDComplexity == DC_RECT) pco = (CLIPOBJ*)&gxcoTrivial; + if (pco->iDComplexity == DC_RECT) pco = (CLIPOBJ*)&gxcoTrivial; /* Calculate initial offset and size */ ptOffset.x = rcClipped.left - prclTrg->left; @@ -447,6 +451,10 @@ IntEngBitBlt( ptMask.y = 0; } + /* Check if all has been clipped away */ + if ((sizTrg.cx <= 0) || (sizTrg.cy <= 0)) + return TRUE; + /* Adjust the points */ ptSrc.x += ptOffset.x; ptSrc.y += ptOffset.y; @@ -628,3 +636,16 @@ EngCopyBits( /* Forward to the driver */ return pfnCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc); } + +BOOL +APIENTRY +IntEngCopyBits( + SURFOBJ *psoTrg, + SURFOBJ *psoSrc, + CLIPOBJ *pco, + XLATEOBJ *pxlo, + RECTL *prclTrg, + POINTL *pptlSrc) +{ + return EngCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc); +}