mirror of
https://github.com/reactos/reactos.git
synced 2025-05-08 19:27:00 +00:00
[WIN32K]
- Add support for pattern brushes and bottom-to-top blt in new EngBitblt - implement a new much simpler EngCopyBits - improve clip enumeration code The code now generally works very well now, only has a few bugs left svn path=/trunk/; revision=56219
This commit is contained in:
parent
720cab7b58
commit
4ffc097ef2
1 changed files with 136 additions and 72 deletions
|
@ -23,22 +23,26 @@ CalculateCoordinates(
|
||||||
{
|
{
|
||||||
ULONG cx, cy;
|
ULONG cx, cy;
|
||||||
|
|
||||||
/* Copy the target start point */
|
|
||||||
pbltdata->siDst.ptOrig.x = prclClipped->left;
|
|
||||||
pbltdata->siDst.ptOrig.y = prclClipped->top;
|
|
||||||
|
|
||||||
/* Calculate width and height of this rect */
|
/* Calculate width and height of this rect */
|
||||||
pbltdata->ulWidth = prclClipped->right - prclClipped->left;
|
pbltdata->ulWidth = prclClipped->right - prclClipped->left;
|
||||||
pbltdata->ulHeight = prclClipped->bottom - prclClipped->top;
|
pbltdata->ulHeight = prclClipped->bottom - prclClipped->top;
|
||||||
|
|
||||||
|
/* Calculate the offset to the origin coordinates */
|
||||||
|
cx = (prclClipped->left - prclOrg->left);
|
||||||
|
if (pbltdata->dy < 0)
|
||||||
|
cy = (prclClipped->bottom - 1 - prclOrg->top);
|
||||||
|
else
|
||||||
|
cy = (prclClipped->top - prclOrg->top);
|
||||||
|
|
||||||
|
/* Calculate the target start point */
|
||||||
|
pbltdata->siDst.ptOrig.x = prclOrg->left + cx;
|
||||||
|
pbltdata->siDst.ptOrig.y = prclOrg->top + cy;
|
||||||
|
|
||||||
/* Calculate start position for target */
|
/* Calculate start position for target */
|
||||||
pbltdata->siDst.pjBase = pbltdata->siDst.pvScan0;
|
pbltdata->siDst.pjBase = pbltdata->siDst.pvScan0;
|
||||||
pbltdata->siDst.pjBase += pbltdata->siDst.ptOrig.y * pbltdata->siDst.lDelta;
|
pbltdata->siDst.pjBase += pbltdata->siDst.ptOrig.y * pbltdata->siDst.lDelta;
|
||||||
pbltdata->siDst.pjBase += pbltdata->siDst.ptOrig.x * pbltdata->siDst.jBpp / 8;
|
pbltdata->siDst.pjBase += pbltdata->siDst.ptOrig.x * pbltdata->siDst.jBpp / 8;
|
||||||
|
|
||||||
/* Calculate the offset from the original coordinates */
|
|
||||||
cx = (prclClipped->left - prclOrg->left);
|
|
||||||
cy = (prclClipped->top - prclOrg->top);
|
|
||||||
|
|
||||||
if (pptlSrc)
|
if (pptlSrc)
|
||||||
{
|
{
|
||||||
|
@ -97,8 +101,12 @@ EngBitBlt(
|
||||||
BOOL bEnumMore;
|
BOOL bEnumMore;
|
||||||
RECT_ENUM rcenum;
|
RECT_ENUM rcenum;
|
||||||
PSIZEL psizlPat;
|
PSIZEL psizlPat;
|
||||||
|
SURFOBJ *psoPattern;
|
||||||
|
|
||||||
|
//static int count = 0;
|
||||||
|
//if (++count >= 1230) __debugbreak();
|
||||||
|
|
||||||
|
/* Sanity checks */
|
||||||
ASSERT(psoTrg);
|
ASSERT(psoTrg);
|
||||||
ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP);
|
ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP);
|
||||||
ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP);
|
ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP);
|
||||||
|
@ -110,15 +118,14 @@ EngBitBlt(
|
||||||
|
|
||||||
rcTrg = *prclTrg;
|
rcTrg = *prclTrg;
|
||||||
|
|
||||||
|
bltdata.dy = 1;
|
||||||
bltdata.rop4 = rop4;
|
bltdata.rop4 = rop4;
|
||||||
|
bltdata.apfnDoRop[0] = gapfnRop[ROP4_BKGND(rop4)];
|
||||||
|
bltdata.apfnDoRop[1] = gapfnRop[ROP4_FGND(rop4)];
|
||||||
if (!pxlo) pxlo = &gexloTrivial.xlo;
|
if (!pxlo) pxlo = &gexloTrivial.xlo;
|
||||||
bltdata.pxlo = pxlo;
|
bltdata.pxlo = pxlo;
|
||||||
bltdata.pfnXlate = XLATEOBJ_pfnXlate(pxlo);
|
bltdata.pfnXlate = XLATEOBJ_pfnXlate(pxlo);
|
||||||
|
|
||||||
bltdata.siDst.pvScan0 = psoTrg->pvScan0;
|
|
||||||
bltdata.siDst.lDelta = psoTrg->lDelta;
|
|
||||||
bltdata.siDst.jBpp = gajBitsPerFormat[psoTrg->iBitmapFormat];
|
|
||||||
|
|
||||||
/* Check if the ROP uses a source */
|
/* Check if the ROP uses a source */
|
||||||
if (ROP4_USES_SOURCE(rop4))
|
if (ROP4_USES_SOURCE(rop4))
|
||||||
{
|
{
|
||||||
|
@ -132,18 +139,18 @@ EngBitBlt(
|
||||||
ASSERT(pptlSrc->x <= psoSrc->sizlBitmap.cx);
|
ASSERT(pptlSrc->x <= psoSrc->sizlBitmap.cx);
|
||||||
ASSERT(pptlSrc->y <= psoSrc->sizlBitmap.cy);
|
ASSERT(pptlSrc->y <= psoSrc->sizlBitmap.cy);
|
||||||
|
|
||||||
bltdata.siSrc.pvScan0 = psoSrc->pvScan0;
|
|
||||||
bltdata.siSrc.lDelta = psoSrc->lDelta;
|
|
||||||
bltdata.siSrc.jBpp = gajBitsPerFormat[psoSrc->iBitmapFormat];
|
|
||||||
|
|
||||||
/* Check if source and target are equal */
|
/* Check if source and target are equal */
|
||||||
if (psoSrc == psoTrg)
|
if (psoSrc == psoTrg)
|
||||||
{
|
{
|
||||||
/* Analyze the copying direction */
|
/* Analyze the copying direction */
|
||||||
if (rcTrg.top < pptlSrc->y)
|
if (rcTrg.top > pptlSrc->y)
|
||||||
iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTDOWN : CD_LEFTDOWN;
|
{
|
||||||
else
|
/* Need to copy from bottom to top */
|
||||||
iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTUP : CD_LEFTUP;
|
iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTUP : CD_LEFTUP;
|
||||||
|
bltdata.dy = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTDOWN : CD_LEFTDOWN;
|
||||||
|
|
||||||
/* Check for special right to left case */
|
/* Check for special right to left case */
|
||||||
if ((rcTrg.top == pptlSrc->y) && (rcTrg.left > pptlSrc->x))
|
if ((rcTrg.top == pptlSrc->y) && (rcTrg.left > pptlSrc->x))
|
||||||
|
@ -151,6 +158,7 @@ EngBitBlt(
|
||||||
/* Use 0 as target format to get special right to left versions */
|
/* Use 0 as target format to get special right to left versions */
|
||||||
bltdata.siDst.iFormat = 0;
|
bltdata.siDst.iFormat = 0;
|
||||||
bltdata.siSrc.iFormat = psoSrc->iBitmapFormat;
|
bltdata.siSrc.iFormat = psoSrc->iBitmapFormat;
|
||||||
|
__debugbreak();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -164,12 +172,24 @@ EngBitBlt(
|
||||||
bltdata.siDst.iFormat = psoTrg->iBitmapFormat;
|
bltdata.siDst.iFormat = psoTrg->iBitmapFormat;
|
||||||
bltdata.siSrc.iFormat = psoSrc->iBitmapFormat;
|
bltdata.siSrc.iFormat = psoSrc->iBitmapFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the source format info */
|
||||||
|
bltdata.siSrc.pvScan0 = psoSrc->pvScan0;
|
||||||
|
bltdata.siSrc.lDelta = psoSrc->lDelta;
|
||||||
|
bltdata.siSrc.cjAdvanceY = bltdata.dy * psoSrc->lDelta;
|
||||||
|
bltdata.siSrc.jBpp = gajBitsPerFormat[psoSrc->iBitmapFormat];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bltdata.siDst.iFormat = psoTrg->iBitmapFormat;
|
bltdata.siDst.iFormat = psoTrg->iBitmapFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the destination format info */
|
||||||
|
bltdata.siDst.pvScan0 = psoTrg->pvScan0;
|
||||||
|
bltdata.siDst.lDelta = psoTrg->lDelta;
|
||||||
|
bltdata.siDst.cjAdvanceY = bltdata.dy * psoTrg->lDelta;
|
||||||
|
bltdata.siDst.jBpp = gajBitsPerFormat[psoTrg->iBitmapFormat];
|
||||||
|
|
||||||
/* Check if the ROP uses a pattern / brush */
|
/* Check if the ROP uses a pattern / brush */
|
||||||
if (ROP4_USES_PATTERN(rop4))
|
if (ROP4_USES_PATTERN(rop4))
|
||||||
{
|
{
|
||||||
|
@ -182,17 +202,25 @@ EngBitBlt(
|
||||||
/* Check if this is a pattern brush */
|
/* Check if this is a pattern brush */
|
||||||
if (pbo->iSolidColor == 0xFFFFFFFF)
|
if (pbo->iSolidColor == 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
__debugbreak();
|
/* Get the realized pattern bitmap */
|
||||||
|
psoPattern = BRUSHOBJ_psoPattern(pbo);
|
||||||
|
if (!psoPattern)
|
||||||
|
{
|
||||||
|
__debugbreak();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME
|
/* Set the pattern format info */
|
||||||
bltdata.siPat.iFormat = 0;//psoPat->iBitmapFormat;
|
bltdata.siPat.iFormat = psoPattern->iBitmapFormat;
|
||||||
bltdata.siPat.pvScan0 = 0;//psoPat->pvScan0;
|
bltdata.siPat.pvScan0 = psoPattern->pvScan0;
|
||||||
bltdata.siPat.lDelta = 0;//psoPat->lDelta;
|
bltdata.siPat.lDelta = psoPattern->lDelta;
|
||||||
|
bltdata.siPat.cjAdvanceY = bltdata.dy * psoPattern->lDelta;
|
||||||
|
bltdata.siPat.jBpp = gajBitsPerFormat[psoPattern->iBitmapFormat];
|
||||||
|
|
||||||
bltdata.ulPatWidth = 0;
|
bltdata.ulPatWidth = psoPattern->sizlBitmap.cx;
|
||||||
bltdata.ulPatHeight = 0;
|
bltdata.ulPatHeight = psoPattern->sizlBitmap.cy;
|
||||||
|
|
||||||
psizlPat = 0;// fixme
|
psizlPat = &psoPattern->sizlBitmap;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -218,9 +246,8 @@ EngBitBlt(
|
||||||
bltdata.siMsk.iFormat = psoMask->iBitmapFormat;
|
bltdata.siMsk.iFormat = psoMask->iBitmapFormat;
|
||||||
bltdata.siMsk.pvScan0 = psoMask->pvScan0;
|
bltdata.siMsk.pvScan0 = psoMask->pvScan0;
|
||||||
bltdata.siMsk.lDelta = psoMask->lDelta;
|
bltdata.siMsk.lDelta = psoMask->lDelta;
|
||||||
|
bltdata.siMsk.cjAdvanceY = bltdata.dy * psoMask->lDelta;
|
||||||
bltdata.apfnDoRop[0] = gapfnRop[ROP4_BKGND(rop4)];
|
bltdata.siMsk.jBpp = 1;
|
||||||
bltdata.apfnDoRop[1] = gapfnRop[ROP4_FGND(rop4)];
|
|
||||||
|
|
||||||
/* Calculate the masking function index */
|
/* Calculate the masking function index */
|
||||||
iFunctionIndex = ROP4_USES_PATTERN(rop4) ? 1 : 0;
|
iFunctionIndex = ROP4_USES_PATTERN(rop4) ? 1 : 0;
|
||||||
|
@ -247,56 +274,54 @@ EngBitBlt(
|
||||||
{
|
{
|
||||||
/* Start the enumeration of the clip object */
|
/* Start the enumeration of the clip object */
|
||||||
CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, iDirection, 0);
|
CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, iDirection, 0);
|
||||||
do
|
bEnumMore = CLIPOBJ_bEnum(pco, sizeof(rcenum), (ULONG*)&rcenum);
|
||||||
{
|
}
|
||||||
/* Enumerate a set of rectangles */
|
else if (pco->iDComplexity == DC_RECT)
|
||||||
bEnumMore = CLIPOBJ_bEnum(pco, sizeof(rcenum), (ULONG*)&rcenum);
|
{
|
||||||
|
/* Use the clip bounds */
|
||||||
/* Loop all rectangles we got */
|
rcenum.arcl[0] = pco->rclBounds;
|
||||||
for (i = 0; i < rcenum.c; i++)
|
rcenum.c = 1;
|
||||||
{
|
bEnumMore = FALSE;
|
||||||
/* Intersect this rect with the target rect */
|
|
||||||
if (!RECTL_bIntersectRect(&rcenum.arcl[i], &rcenum.arcl[i], &rcTrg))
|
|
||||||
{
|
|
||||||
/* This rect is outside the bounds, continue */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate the coordinates */
|
|
||||||
CalculateCoordinates(&bltdata,
|
|
||||||
&rcenum.arcl[i],
|
|
||||||
prclTrg,
|
|
||||||
pptlSrc,
|
|
||||||
pptlMask,
|
|
||||||
pptlBrush,
|
|
||||||
psizlPat);
|
|
||||||
|
|
||||||
/* Call the dib function */
|
|
||||||
pfnBitBlt(&bltdata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (bEnumMore);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Check if there is something to clip */
|
/* Use the target rect */
|
||||||
if (pco->iDComplexity == DC_RECT)
|
rcenum.arcl[0] = rcTrg;
|
||||||
|
rcenum.c = 1;
|
||||||
|
bEnumMore = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enter enumeration loop */
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
/* Loop all rectangles we got */
|
||||||
|
for (i = 0; i < rcenum.c; i++)
|
||||||
{
|
{
|
||||||
/* Clip the target rect to the bounds of the clipping region */
|
/* Intersect this rect with the target rect */
|
||||||
RECTL_bIntersectRect(&rcTrg, &rcTrg, &pco->rclBounds);
|
if (!RECTL_bIntersectRect(&rcenum.arcl[i], &rcenum.arcl[i], &rcTrg))
|
||||||
|
{
|
||||||
|
/* This rect is outside the bounds, continue */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate coordinates and pointers */
|
||||||
|
CalculateCoordinates(&bltdata,
|
||||||
|
&rcenum.arcl[i],
|
||||||
|
prclTrg,
|
||||||
|
pptlSrc,
|
||||||
|
pptlMask,
|
||||||
|
pptlBrush,
|
||||||
|
psizlPat);
|
||||||
|
|
||||||
|
/* Call the dib function */
|
||||||
|
pfnBitBlt(&bltdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the coordinates */
|
/* Bail out, when there's nothing more to do */
|
||||||
CalculateCoordinates(&bltdata,
|
if(!bEnumMore) break;
|
||||||
&rcTrg,
|
|
||||||
prclTrg,
|
|
||||||
pptlSrc,
|
|
||||||
pptlMask,
|
|
||||||
pptlBrush,
|
|
||||||
psizlPat);
|
|
||||||
|
|
||||||
/* Call the dib function */
|
/* Enumerate more rectangles */
|
||||||
pfnBitBlt(&bltdata);
|
bEnumMore = CLIPOBJ_bEnum(pco, sizeof(rcenum), (ULONG*)&rcenum);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -563,4 +588,43 @@ NtGdiEngBitBlt(
|
||||||
return bResult;
|
return bResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
APIENTRY
|
||||||
|
EngCopyBits(
|
||||||
|
SURFOBJ *psoTrg,
|
||||||
|
SURFOBJ *psoSrc,
|
||||||
|
CLIPOBJ *pco,
|
||||||
|
XLATEOBJ *pxlo,
|
||||||
|
RECTL *prclTrg,
|
||||||
|
POINTL *pptlSrc)
|
||||||
|
{
|
||||||
|
PFN_DrvCopyBits pfnCopyBits;
|
||||||
|
|
||||||
|
/* Is the target surface device managed? */
|
||||||
|
if (SURFOBJ_flags(psoTrg) & HOOK_COPYBITS)
|
||||||
|
{
|
||||||
|
pfnCopyBits = GDIDEVFUNCS(psoTrg).CopyBits;
|
||||||
|
}
|
||||||
|
if (SURFOBJ_flags(psoSrc) & HOOK_COPYBITS)
|
||||||
|
{
|
||||||
|
pfnCopyBits = GDIDEVFUNCS(psoSrc).CopyBits;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Use SRCCOPY for 2 bitmaps */
|
||||||
|
return EngBitBlt(psoTrg,
|
||||||
|
psoSrc,
|
||||||
|
NULL,
|
||||||
|
pco,
|
||||||
|
pxlo,
|
||||||
|
prclTrg,
|
||||||
|
pptlSrc,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
ROP4_SRCCOPY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forward to the driver */
|
||||||
|
return pfnCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue