Author: tkreuzer
Date: Sun Jul 21 20:33:10 2013
New Revision: 59550
URL:
http://svn.reactos.org/svn/reactos?rev=59550&view=rev
Log:
[DIBLIB] Fix right-to-left SRCCOPY, silence a warning
[WIN32K] Improve EngBitBlt and EndCopyBits to properly handle device managed surfaces and
support RLE compression.
Modified:
branches/dib_rewrite/win32ss/gdi/diblib/BitBlt_SRCCOPY.c
branches/dib_rewrite/win32ss/gdi/diblib/DibLib.h
branches/dib_rewrite/win32ss/gdi/eng/bitblt_new.c
Modified: branches/dib_rewrite/win32ss/gdi/diblib/BitBlt_SRCCOPY.c
URL:
http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/diblib/…
==============================================================================
--- branches/dib_rewrite/win32ss/gdi/diblib/BitBlt_SRCCOPY.c [iso-8859-1] (original)
+++ branches/dib_rewrite/win32ss/gdi/diblib/BitBlt_SRCCOPY.c [iso-8859-1] Sun Jul 21
20:33:10 2013
@@ -24,13 +24,38 @@
}
}
+VOID
+FASTCALL
+Dib_BitBlt_SRCCOPY_EqSurfR2L(PBLTDATA pBltData)
+{
+ ULONG cLines, cjWidth;
+ PBYTE pjDestBase = pBltData->siDst.pjBase;
+ PBYTE pjSrcBase = pBltData->siSrc.pjBase;
+
+ /* Calculate the width in bytes */
+ cjWidth = pBltData->ulWidth * pBltData->siDst.jBpp / 8;
+
+ pjDestBase -= (cjWidth - 1);
+ pjSrcBase -= (cjWidth - 1);
+
+ /* Loop all lines */
+ cLines = pBltData->ulHeight;
+ while (cLines--)
+ {
+ /* Use memmove to handle copying right-to-left with overlap */
+ memmove(pjDestBase, pjSrcBase, cjWidth);
+ pjDestBase += pBltData->siDst.cjAdvanceY;
+ pjSrcBase += pBltData->siSrc.cjAdvanceY;
+ }
+}
+
#define Dib_BitBlt_SRCCOPY_S8_D8_EqSurf Dib_BitBlt_SRCCOPY_EqSurf
#define Dib_BitBlt_SRCCOPY_S16_D16_EqSurf Dib_BitBlt_SRCCOPY_EqSurf
#define Dib_BitBlt_SRCCOPY_S24_D24_EqSurf Dib_BitBlt_SRCCOPY_EqSurf
-#define Dib_BitBlt_SRCCOPY_S8_D8_EqSurfR2L Dib_BitBlt_SRCCOPY_EqSurf
-#define Dib_BitBlt_SRCCOPY_S16_D16_EqSurfR2L Dib_BitBlt_SRCCOPY_EqSurf
-#define Dib_BitBlt_SRCCOPY_S24_D24_EqSurfR2L Dib_BitBlt_SRCCOPY_EqSurf
-#define Dib_BitBlt_SRCCOPY_S32_D32_EqSurfR2L Dib_BitBlt_SRCCOPY_EqSurf
+#define Dib_BitBlt_SRCCOPY_S8_D8_EqSurfR2L Dib_BitBlt_SRCCOPY_EqSurfR2L
+#define Dib_BitBlt_SRCCOPY_S16_D16_EqSurfR2L Dib_BitBlt_SRCCOPY_EqSurfR2L
+#define Dib_BitBlt_SRCCOPY_S24_D24_EqSurfR2L Dib_BitBlt_SRCCOPY_EqSurfR2L
+#define Dib_BitBlt_SRCCOPY_S32_D32_EqSurfR2L Dib_BitBlt_SRCCOPY_EqSurfR2L
/* special movsd optimization on x86, only for left-to-right */
#if defined(_M_IX86) || defined(_M_AMD64)
@@ -60,6 +85,7 @@
/* This definition will be checked against in DibLib_BitBlt.h
for all "redirected" functions */
#define Dib_BitBlt_SRCCOPY_EqSurf_manual 1
+#define Dib_BitBlt_SRCCOPY_EqSurfR2L_manual 1
#define __USES_SOURCE 1
#define __USES_PATTERN 0
Modified: branches/dib_rewrite/win32ss/gdi/diblib/DibLib.h
URL:
http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/diblib/…
==============================================================================
--- branches/dib_rewrite/win32ss/gdi/diblib/DibLib.h [iso-8859-1] (original)
+++ branches/dib_rewrite/win32ss/gdi/diblib/DibLib.h [iso-8859-1] Sun Jul 21 20:33:10
2013
@@ -8,6 +8,7 @@
#include <stdarg.h>
#include <windef.h>
#include <wingdi.h>
+#define _ENGINE_EXPORT_
#include <winddi.h>
#ifdef _OPTIMIZE_DIBLIB
Modified: branches/dib_rewrite/win32ss/gdi/eng/bitblt_new.c
URL:
http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/eng/bit…
==============================================================================
--- branches/dib_rewrite/win32ss/gdi/eng/bitblt_new.c [iso-8859-1] (original)
+++ branches/dib_rewrite/win32ss/gdi/eng/bitblt_new.c [iso-8859-1] Sun Jul 21 20:33:10
2013
@@ -14,6 +14,184 @@
};
#endif
+
+BOOL
+APIENTRY
+EngSrcBufferedBitBlt (
+ _Inout_ SURFOBJ *psoTrg,
+ _In_ 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)
+{
+ BOOL bResult;
+ PSURFACE psurfTmp;
+ SURFOBJ* psoTmp;
+ RECTL rclTmp;
+ ULONG iTmpBitmapFormat;
+
+ /* Setup the target rect for the temp surface */
+ rclTmp.left = 0;
+ rclTmp.top = 0;
+ rclTmp.right = prclTrg->right - prclTrg->left;
+ rclTmp.bottom = prclTrg->bottom - prclTrg->top;
+
+ /* Get the bitmap format for the temp surface */
+ iTmpBitmapFormat = psoSrc->iBitmapFormat;
+ if (iTmpBitmapFormat == BMF_4RLE) iTmpBitmapFormat = BMF_4BPP;
+ if (iTmpBitmapFormat == BMF_8RLE) iTmpBitmapFormat = BMF_8BPP;
+
+ /* Allocate a surface */
+ psurfTmp = SURFACE_AllocSurface(STYPE_BITMAP,
+ rclTmp.right,
+ rclTmp.bottom,
+ iTmpBitmapFormat,
+ 0,
+ 0,
+ NULL);
+ if (psurfTmp == NULL)
+ {
+ ERR("Failed to allocate a surface\n");
+ return FALSE;
+ }
+
+ psoTmp = &psurfTmp->SurfObj;
+
+ /* Check if we have an RLE compressed source */
+ if ((psoSrc->iBitmapFormat == BMF_4RLE) ||
+ (psoSrc->iBitmapFormat == BMF_8RLE))
+ {
+ SIZEL sizl;
+
+ /* Decompress the bitmap */
+ sizl.cx = rclTmp.right;
+ sizl.cy = rclTmp.bottom;
+ DecompressBitmap(sizl,
+ psoSrc->pvBits,
+ psoTmp->pvBits,
+ psoTmp->lDelta,
+ psoSrc->iBitmapFormat);
+ bResult = TRUE;
+ }
+ else if ((psoSrc->iBitmapFormat > BMF_8RLE))
+ {
+ ERR("Bitmap format %d is not supported!\n", psoSrc->iBitmapFormat);
+ return FALSE;
+ }
+ else
+ {
+ /* Copy the bits to the temp surface */
+ bResult = EngCopyBits(psoTmp, psoSrc, NULL, NULL, &rclTmp, pptlSrc);
+ }
+
+ if (bResult)
+ {
+ /* Do the actual operation from the temp surface */
+ bResult = IntEngBitBlt(psoTrg,
+ psoTmp,
+ psoMask,
+ pco,
+ pxlo,
+ prclTrg,
+ (PPOINTL)&rclTmp,
+ pptlMask,
+ pbo,
+ pptlBrush,
+ rop4);
+ }
+
+ /* Delete the temp surface */
+ GDIOBJ_vDeleteObject(&psurfTmp->BaseObject);
+
+ return bResult;
+}
+
+BOOL
+APIENTRY
+EngTrgBufferedBitBlt (
+ _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)
+{
+ BOOL bResult = TRUE;
+ PSURFACE psurfTmp;
+ SURFOBJ* psoTmp;
+ RECTL rclTmp;
+ ULONG iTmpBitmapFormat;
+
+ /* Setup the target rect for the temp surface */
+ rclTmp.left = 0;
+ rclTmp.top = 0;
+ rclTmp.right = prclTrg->right - prclTrg->left;
+ rclTmp.bottom = prclTrg->bottom - prclTrg->top;
+
+ /* Get the bitmap format for the temp surface */
+ iTmpBitmapFormat = psoTrg->iBitmapFormat;
+
+ /* Allocate a surface */
+ psurfTmp = SURFACE_AllocSurface(STYPE_BITMAP,
+ rclTmp.right,
+ rclTmp.bottom,
+ iTmpBitmapFormat,
+ 0,
+ 0,
+ NULL);
+ if (psurfTmp == NULL)
+ {
+ ERR("Failed to allocate a surface\n");
+ return FALSE;
+ }
+
+ psoTmp = &psurfTmp->SurfObj;
+
+ /* Check if the ROP uses the target pixels */
+ if (ROP4_USES_DEST(rop4))
+ {
+ /* Copy the target bits to the target surface */
+ bResult = EngCopyBits(psoTmp, psoSrc, NULL, NULL, &rclTmp,
(PPOINTL)prclTrg);
+ }
+
+ if (bResult)
+ {
+ /* Do the actual operation to the temp surface */
+ bResult = IntEngBitBlt(psoTmp,
+ psoSrc,
+ psoMask,
+ pco,
+ pxlo,
+ &rclTmp,
+ pptlSrc,
+ pptlMask,
+ pbo,
+ pptlBrush,
+ rop4);
+ }
+
+ if (bResult)
+ {
+ /* Copy the bits to the target surface */
+ bResult = EngCopyBits(psoTrg, psoTmp, NULL, NULL, prclTrg,
(PPOINTL)&rclTmp);
+ }
+
+ /* Delete the temp surface */
+ GDIOBJ_vDeleteObject(&psurfTmp->BaseObject);
+
+ return bResult;
+}
static
void
@@ -98,7 +276,7 @@
BOOL
APIENTRY
-EngBitBlt(
+EngBitBlt (
_Inout_ SURFOBJ *psoTrg,
_In_opt_ SURFOBJ *psoSrc,
_In_opt_ SURFOBJ *psoMask,
@@ -112,37 +290,63 @@
_In_ ROP4 rop4)
{
BLTDATA bltdata;
- ULONG i, iFunctionIndex, iDirection = CD_ANY;
- RECTL rcTrg;
+ ULONG i, iFunctionIndex, iDirection;
PFN_DIBFUNCTION pfnBitBlt;
BOOL bEnumMore;
RECT_ENUM rcenum;
PSIZEL psizlPat;
SURFOBJ *psoPattern;
+ PFN_DrvCopyBits pfnCopyBits;
//static int count = 0;
//if (++count >= 1230) __debugbreak();
/* Sanity checks */
- ASSERT(psoTrg);
- ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP);
- ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP);
- ASSERT(prclTrg);
- ASSERT(prclTrg->left >= 0);
- ASSERT(prclTrg->top >= 0);
- ASSERT(prclTrg->right <= psoTrg->sizlBitmap.cx);
- ASSERT(prclTrg->bottom <= psoTrg->sizlBitmap.cy);
+ NT_ASSERT(psoTrg);
+ NT_ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP);
+ NT_ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP);
+ NT_ASSERT(prclTrg);
+ NT_ASSERT(prclTrg->left >= 0);
+ NT_ASSERT(prclTrg->top >= 0);
+ NT_ASSERT(prclTrg->right <= psoTrg->sizlBitmap.cx);
+ NT_ASSERT(prclTrg->bottom <= psoTrg->sizlBitmap.cy);
ASSERT_DEVLOCK(psoTrg);
ASSERT_DEVLOCK(psoSrc);
ASSERT_DEVLOCK(psoMask);
- rcTrg = *prclTrg;
-
+ /* Check if the target is not a bitmap */
+ if (psoTrg->iType != STYPE_BITMAP)
+ {
+ /* Check for special case SRCCOPY to device */
+ if ((rop4 == ROP4_SRCCOPY) &&
+ ((psoSrc->iType == STYPE_BITMAP) || (psoSrc->hdev ==
psoTrg->hdev)))
+ {
+ /* Use the driver's DrvCopyBits */
+ pfnCopyBits = GDIDEVFUNCS(psoTrg).CopyBits;
+ return pfnCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc);
+ }
+
+ /* We need to do a buffered bitblt */
+ return EngTrgBufferedBitBlt(psoTrg,
+ psoSrc,
+ psoMask,
+ pco,
+ pxlo,
+ prclTrg,
+ pptlSrc,
+ pptlMask,
+ pbo,
+ pptlBrush,
+ rop4);
+ }
+
+ if (!pxlo) pxlo = &gexloTrivial.xlo;
+
+ /* Initialize the BLTINFO structure */
bltdata.dy = 1;
bltdata.rop4 = rop4;
bltdata.apfnDoRop[0] = gapfnRop[ROP4_BKGND(rop4)];
bltdata.apfnDoRop[1] = gapfnRop[ROP4_FGND(rop4)];
- if (!pxlo) pxlo = &gexloTrivial.xlo;
bltdata.pxlo = pxlo;
bltdata.pfnXlate = XLATEOBJ_pfnXlate(pxlo);
@@ -150,30 +354,61 @@
if (ROP4_USES_SOURCE(rop4))
{
/* Sanity checks */
- ASSERT(psoSrc);
- ASSERT(psoSrc->iBitmapFormat >= BMF_1BPP);
- ASSERT(psoSrc->iBitmapFormat <= BMF_32BPP);
- ASSERT(pptlSrc);
- ASSERT(pptlSrc->x >= 0);
- ASSERT(pptlSrc->y >= 0);
- ASSERT(pptlSrc->x <= psoSrc->sizlBitmap.cx);
- ASSERT(pptlSrc->y <= psoSrc->sizlBitmap.cy);
-
- /* Check if source and target are equal */
+ NT_ASSERT(psoSrc);
+ NT_ASSERT(psoSrc->iBitmapFormat >= BMF_1BPP);
+ NT_ASSERT(psoSrc->iBitmapFormat <= BMF_8RLE);
+ NT_ASSERT(pptlSrc);
+ NT_ASSERT(pptlSrc->x >= 0);
+ NT_ASSERT(pptlSrc->y >= 0);
+ NT_ASSERT(pptlSrc->x <= psoSrc->sizlBitmap.cx);
+ NT_ASSERT(pptlSrc->y <= psoSrc->sizlBitmap.cy);
+
+ /* Check for special case SRCCOPY from device */
+ if ((rop4 == ROP4_SRCCOPY) &&
+ (psoSrc->iType != STYPE_BITMAP) &&
+ ((psoTrg->iType == STYPE_BITMAP) || (psoSrc->hdev ==
psoTrg->hdev)))
+ {
+ /* Use the driver's DrvCopyBits */
+ pfnCopyBits = GDIDEVFUNCS(psoSrc).CopyBits;
+ return pfnCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc);
+ }
+
+ /* Check if the source is not a normal bitmap */
+ if ((psoSrc->iType != STYPE_BITMAP) ||
+ (psoSrc->iBitmapFormat > BMF_32BPP))
+ {
+ /* We need to do a buffered bitblt */
+ return EngSrcBufferedBitBlt(psoTrg,
+ psoSrc,
+ psoMask,
+ pco,
+ pxlo,
+ prclTrg,
+ pptlSrc,
+ pptlMask,
+ pbo,
+ pptlBrush,
+ rop4);
+ }
+
+ /* Check if source and target surface are equal */
if (psoSrc == psoTrg)
{
/* Analyze the copying direction */
- if (rcTrg.top > pptlSrc->y)
+ if (prclTrg->top > pptlSrc->y)
{
/* Need to copy from bottom to top */
- iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTUP : CD_LEFTUP;
+ iDirection = prclTrg->left < pptlSrc->x ? CD_RIGHTUP :
CD_LEFTUP;
bltdata.dy = -1;
}
else
- iDirection = rcTrg.left < pptlSrc->x ? CD_RIGHTDOWN : CD_LEFTDOWN;
+ {
+ /* We copy from top to bottom */
+ iDirection = prclTrg->left < pptlSrc->x ? CD_RIGHTDOWN :
CD_LEFTDOWN;
+ }
/* Check for special right to left case */
- if ((rcTrg.top == pptlSrc->y) && (rcTrg.left > pptlSrc->x))
+ if ((prclTrg->top == pptlSrc->y) && (prclTrg->left >
pptlSrc->x))
{
/* Use 0 as target format to get special right to left versions */
bltdata.siDst.iFormat = 0;
@@ -189,11 +424,12 @@
}
else
{
+ iDirection = CD_ANY;
bltdata.siDst.iFormat = psoTrg->iBitmapFormat;
bltdata.siSrc.iFormat = psoSrc->iBitmapFormat;
}
- /* Set the source format info */
+ /* Set the rest of the source format info */
bltdata.siSrc.pvScan0 = psoSrc->pvScan0;
bltdata.siSrc.lDelta = psoSrc->lDelta;
bltdata.siSrc.cjAdvanceY = bltdata.dy * psoSrc->lDelta;
@@ -201,10 +437,11 @@
}
else
{
+ iDirection = CD_ANY;
bltdata.siDst.iFormat = psoTrg->iBitmapFormat;
}
- /* Set the destination format info */
+ /* Set the rest of the destination format info */
bltdata.siDst.pvScan0 = psoTrg->pvScan0;
bltdata.siDst.lDelta = psoTrg->lDelta;
bltdata.siDst.cjAdvanceY = bltdata.dy * psoTrg->lDelta;
@@ -214,7 +451,7 @@
if (ROP4_USES_PATTERN(rop4))
{
/* Must have a brush */
- ASSERT(pbo); // FIXME: test this!
+ NT_ASSERT(pbo); // FIXME: test this!
/* Copy the solid color */
bltdata.ulSolidColor = pbo->iSolidColor;
@@ -258,8 +495,8 @@
if (ROP4_USES_MASK(rop4))
{
/* Must have a mask surface and point */
- ASSERT(psoMask);
- ASSERT(pptlMask);
+ NT_ASSERT(psoMask);
+ NT_ASSERT(pptlMask);
//__debugbreak();
@@ -307,7 +544,7 @@
else
{
/* Use the target rect */
- rcenum.arcl[0] = rcTrg;
+ rcenum.arcl[0] = *prclTrg;
rcenum.c = 1;
bEnumMore = FALSE;
}
@@ -319,7 +556,7 @@
for (i = 0; i < rcenum.c; i++)
{
/* Intersect this rect with the target rect */
- if (!RECTL_bIntersectRect(&rcenum.arcl[i], &rcenum.arcl[i],
&rcTrg))
+ if (!RECTL_bIntersectRect(&rcenum.arcl[i], &rcenum.arcl[i],
prclTrg))
{
/* This rect is outside the bounds, continue */
continue;
@@ -396,11 +633,11 @@
//__debugbreak();
/* Sanity checks */
- ASSERT(IS_VALID_ROP4(rop4));
- ASSERT(psoTrg);
- ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP);
- ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP);
- ASSERT(prclTrg);
+ NT_ASSERT(IS_VALID_ROP4(rop4));
+ NT_ASSERT(psoTrg);
+ NT_ASSERT(psoTrg->iBitmapFormat >= BMF_1BPP);
+ NT_ASSERT(psoTrg->iBitmapFormat <= BMF_32BPP);
+ NT_ASSERT(prclTrg);
/* Clip the target rect to the extents of the target surface */
rcClipped.left = max(prclTrg->left, 0);
@@ -409,10 +646,11 @@
rcClipped.bottom = min(prclTrg->bottom, psoTrg->sizlBitmap.cy);
/* If no clip object is given, use trivial one */
- if (!pco) pco = (CLIPOBJ*)&gxcoTrivial;
-
- /* Check if there is something to clip */
- if (pco->iDComplexity != DC_TRIVIAL)
+ if (pco == NULL)
+ pco = (CLIPOBJ*)&gxcoTrivial;
+
+ /* Check if there is anything to clip */
+ else if (pco->iDComplexity != DC_TRIVIAL)
{
/* Clip the target rect to the bounds of the clipping region */
if (!RECTL_bIntersectRect(&rcClipped, &rcClipped,
&pco->rclBounds))
@@ -420,10 +658,11 @@
/* Nothing left */
return TRUE;
}
- }
-
- /* Don't pass a clip object with a single rectangle */
- if (pco->iDComplexity == DC_RECT) pco = (CLIPOBJ*)&gxcoTrivial;
+
+ /* Don't pass a clip object with a single rectangle */
+ if (pco->iDComplexity == DC_RECT)
+ pco = (CLIPOBJ*)&gxcoTrivial;
+ }
/* Calculate initial offset and size */
ptOffset.x = rcClipped.left - prclTrg->left;
@@ -435,8 +674,8 @@
if (ROP4_USES_SOURCE(rop4))
{
/* Must have a source surface and point */
- ASSERT(psoSrc);
- ASSERT(pptlSrc);
+ NT_ASSERT(psoSrc);
+ NT_ASSERT(pptlSrc);
/* Get the source point */
ptSrc = *pptlSrc;
@@ -455,8 +694,8 @@
if (ROP4_USES_MASK(rop4))
{
/* Must have a mask surface and point */
- ASSERT(psoMask);
- ASSERT(pptlMask);
+ NT_ASSERT(psoMask);
+ NT_ASSERT(pptlMask);
/* Get the mask point */
ptMask = *pptlMask;
@@ -503,7 +742,7 @@
(SURFOBJ_flags(psoSrc) & HOOK_BITBLT))
{
ERR("Need to copy to standard bitmap format!\n");
- ASSERT(FALSE);
+ NT_ASSERT(FALSE);
}
pfnBitBlt = GDIDEVFUNCS(psoTrg).BitBlt;
@@ -636,12 +875,33 @@
{
PFN_DrvCopyBits pfnCopyBits;
+ /* Check if we have 2 incompatible non-bitmap surfaces */
+ if ((psoSrc->iType != STYPE_BITMAP) &&
+ (psoTrg->iType != STYPE_BITMAP) &&
+ (psoSrc->hdev != psoTrg->hdev))
+ {
+ /* We need to create a temp bitmap */
+ return EngSrcBufferedBitBlt(psoTrg,
+ psoSrc,
+ NULL,
+ pco,
+ pxlo,
+ prclTrg,
+ pptlSrc,
+ NULL,
+ NULL,
+ NULL,
+ ROP4_SRCCOPY);
+ }
+
/* Is the target surface device managed? */
- if (SURFOBJ_flags(psoTrg) & HOOK_COPYBITS)
+ if ((psoTrg->iType != STYPE_BITMAP) ||
+ (SURFOBJ_flags(psoTrg) & HOOK_COPYBITS))
{
pfnCopyBits = GDIDEVFUNCS(psoTrg).CopyBits;
}
- if (SURFOBJ_flags(psoSrc) & HOOK_COPYBITS)
+ else if ((psoSrc->iType != STYPE_BITMAP) ||
+ (SURFOBJ_flags(psoSrc) & HOOK_COPYBITS))
{
pfnCopyBits = GDIDEVFUNCS(psoSrc).CopyBits;
}