mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
682 lines
21 KiB
682 lines
21 KiB
/******************************Public*Routine******************************\
|
|
* bbddi.cxx
|
|
*
|
|
* This contains the bitblt simulations code.
|
|
*
|
|
* Copyright (c) 1993-1995 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
#define ROP4NEEDPAT(rop4) \
|
|
((gajRop3[rop4 & 0x000000FF] | gajRop3[(rop4 >> 8) & 0x000000ff]) & AVEC_NEED_PATTERN)
|
|
|
|
#define ROP4NEEDSRC(rop4) \
|
|
((gajRop3[rop4 & 0x000000FF] | gajRop3[(rop4 >> 8) & 0x000000ff]) & AVEC_NEED_SOURCE)
|
|
|
|
/******************************Public*Routine******************************\
|
|
* EngBitBlt
|
|
*
|
|
* DDI entry point. Blts to a engine managed surface.
|
|
*
|
|
* History:
|
|
* 16-Feb-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL
|
|
EngBitBlt(
|
|
SURFOBJ *psoDst, // Target surface
|
|
SURFOBJ *psoSrc, // Source surface
|
|
SURFOBJ *psoMask, // Mask
|
|
CLIPOBJ *pco, // Clip through this
|
|
XLATEOBJ *pxlo, // Color translation
|
|
RECTL *prclDst, // Target offset and extent
|
|
POINTL *pptlSrc, // Source offset
|
|
POINTL *pptlMask, // Mask offset
|
|
BRUSHOBJ *pdbrush, // Brush data (from cbRealizeBrush)
|
|
POINTL *pptlBrush, // Brush offset (origin)
|
|
ROP4 rop4 // Raster operation
|
|
)
|
|
{
|
|
|
|
//
|
|
// Validate the ROP
|
|
//
|
|
|
|
ASSERTGDI((rop4 & 0xffff0000) == 0, "Invalid ROP");
|
|
ASSERTGDI(psoDst != (SURFOBJ *) NULL, "NULL target passed in");
|
|
ASSERTGDI(prclDst != (PRECTL) NULL, "Target range\n");
|
|
ASSERTGDI(prclDst->left <= prclDst->right, "ERROR Target width not ordered");
|
|
ASSERTGDI(prclDst->top <= prclDst->bottom, "ERROR Target height not ordered");
|
|
ASSERTGDI(!(ROP4NEEDPAT(rop4) && (pdbrush == (BRUSHOBJ *) NULL)), "EngBitBlt: Pattern");
|
|
ASSERTGDI(!(ROP4NEEDPAT(rop4) && (pdbrush->iSolidColor == 0xFFFFFFFF) && (pptlBrush == (PPOINTL) NULL)), "EngBitBlt: Pattern offset");
|
|
ASSERTGDI(!((psoSrc == (SURFOBJ *) NULL) && ROP4NEEDSRC(rop4)), "EngBitBlt: Source\n");
|
|
ASSERTGDI(!((pptlSrc == (PPOINTL) NULL) && ROP4NEEDSRC(rop4)), "EngBitBlt: Source offset\n");
|
|
|
|
PSURFACE pSurfDst = SURFOBJ_TO_SURFACE(psoDst);
|
|
PSURFACE pSurfSrc = SURFOBJ_TO_SURFACE(psoSrc);
|
|
PSURFACE pSurfMask = SURFOBJ_TO_SURFACE(psoMask);
|
|
|
|
if (psoDst->iType == STYPE_BITMAP)
|
|
{
|
|
//
|
|
// Synchronize with the device driver before touching the device surface.
|
|
//
|
|
|
|
if (pSurfDst->flags() & HOOK_SYNCHRONIZE)
|
|
{
|
|
PDEVOBJ po(pSurfDst->hdev());
|
|
(po.pfnSync())(psoDst->dhpdev,NULL);
|
|
}
|
|
|
|
//
|
|
// inc surface uniq for all cases
|
|
//
|
|
|
|
INC_SURF_UNIQ(pSurfDst);
|
|
|
|
//
|
|
// Quick check for dst and pattern rops, and source copy
|
|
//
|
|
|
|
switch(rop4)
|
|
{
|
|
case 0x00000000: // DDx (BLACKNESS)
|
|
case 0x0000FFFF: // DDxn (WHITENESS)
|
|
|
|
vDIBSolidBlt(pSurfDst,
|
|
prclDst,
|
|
pco,
|
|
((rop4 != 0) ? ~0 : 0),
|
|
0);
|
|
return(TRUE);
|
|
|
|
case 0x0000F0F0: // P (PATCOPY)
|
|
case 0x00000F0F: // Pn (NOTPATCOPY)
|
|
|
|
if (pdbrush->iSolidColor != 0xFFFFFFFF)
|
|
{
|
|
vDIBSolidBlt(pSurfDst,
|
|
prclDst,
|
|
pco,
|
|
(rop4 & 0x00000001) ? ~(pdbrush->iSolidColor) : pdbrush->iSolidColor,
|
|
0);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
if ((pSurfDst->iFormat() == BMF_8BPP) &&
|
|
(rop4 == 0x0000F0F0))
|
|
{
|
|
|
|
//
|
|
// We only support 8x8 DIB8 patterns with SRCCOPY right now
|
|
//
|
|
|
|
if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
|
|
{
|
|
if ((((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat == 8) &&
|
|
(((EBRUSHOBJ *) pdbrush)->pengbrush()->cyPat == 8))
|
|
|
|
{
|
|
vDIBPatBltSrccopy8x8( pSurfDst,
|
|
pco,
|
|
prclDst,
|
|
pdbrush,
|
|
pptlBrush,
|
|
vPatCpyRect8_8x8 );
|
|
|
|
return(TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pSurfDst->iFormat() >= BMF_8BPP)
|
|
{
|
|
if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
|
|
{
|
|
if (((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat >= 4)
|
|
{
|
|
vDIBPatBlt(pSurfDst,
|
|
pco,
|
|
prclDst,
|
|
pdbrush,
|
|
pptlBrush,
|
|
(rop4 == 0x0000F0F0) ? DPA_PATCOPY : DPA_PATNOT);
|
|
|
|
return(TRUE);
|
|
}
|
|
}
|
|
}
|
|
else if ((pSurfDst->iFormat() == BMF_4BPP) &&
|
|
(rop4 == 0x0000F0F0))
|
|
{
|
|
|
|
//
|
|
// We only support 8x8 DIB4 patterns with SRCCOPY right now
|
|
//
|
|
|
|
if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
|
|
{
|
|
if ((((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat == 8) &&
|
|
(((EBRUSHOBJ *) pdbrush)->pengbrush()->cyPat == 8))
|
|
{
|
|
ASSERTGDI(((EBRUSHOBJ *) pdbrush)->pengbrush()->lDeltaPat == 4,
|
|
"BBDDI.CXX: lDeltaPat != 4");
|
|
|
|
vDIBPatBltSrccopy8x8(pSurfDst,
|
|
pco,
|
|
prclDst,
|
|
pdbrush,
|
|
pptlBrush,
|
|
vPatCpyRect4_8x8);
|
|
|
|
return(TRUE);
|
|
}
|
|
}
|
|
}
|
|
else if ((pSurfDst->iFormat() == BMF_1BPP) &&
|
|
(rop4 == 0x0000F0F0))
|
|
{
|
|
|
|
//
|
|
// We support 8x8 and 6x6 DIB1 patterns with SRCCOPY
|
|
//
|
|
|
|
if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
|
|
{
|
|
//
|
|
// Look for 8x8 patterns
|
|
//
|
|
|
|
if ((((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat == 8) &&
|
|
(((EBRUSHOBJ *) pdbrush)->pengbrush()->cyPat == 8) )
|
|
{
|
|
ASSERTGDI(((EBRUSHOBJ *) pdbrush)->pengbrush()->lDeltaPat == 4,
|
|
"BBDDI.CXX: lDeltaPat != 4");
|
|
|
|
vDIBPatBltSrccopy8x8(pSurfDst,
|
|
pco,
|
|
prclDst,
|
|
pdbrush,
|
|
pptlBrush,
|
|
vPatCpyRect1_8x8 );
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
//
|
|
// Look for 6x6 patterns
|
|
//
|
|
|
|
if ((((EBRUSHOBJ *)pdbrush)->pengbrush()->cxPat == 6) &&
|
|
(((EBRUSHOBJ *)pdbrush)->pengbrush()->cyPat == 6) )
|
|
{
|
|
|
|
|
|
ASSERTGDI(((EBRUSHOBJ *) pdbrush)->pengbrush()->lDeltaPat == 8,
|
|
"BBDDI.CXX: lDeltaPat != 8");
|
|
|
|
vDIBnPatBltSrccopy6x6(pSurfDst,
|
|
pco,
|
|
prclDst,
|
|
pdbrush,
|
|
pptlBrush,
|
|
vPatCpyRect1_6x6 );
|
|
|
|
return(TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x00005A5A: // DPx
|
|
|
|
if (pdbrush->iSolidColor != 0xFFFFFFFF)
|
|
{
|
|
vDIBSolidBlt(pSurfDst,
|
|
prclDst,
|
|
pco,
|
|
pdbrush->iSolidColor,
|
|
1);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
if (pSurfDst->iFormat() >= BMF_8BPP)
|
|
{
|
|
if (pvGetEngRbrush(pdbrush)) // Can we use this brush?
|
|
{
|
|
if (((EBRUSHOBJ *) pdbrush)->pengbrush()->cxPat >= 4)
|
|
{
|
|
vDIBPatBlt(pSurfDst,
|
|
pco,
|
|
prclDst,
|
|
pdbrush,
|
|
pptlBrush,
|
|
DPA_PATXOR);
|
|
|
|
return(TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
//
|
|
// Dn degenerates to DPx with a pattern of all ones (0xFFFFFFFF)
|
|
//
|
|
|
|
case 0x00005555: // Dn (DSTINVERT)
|
|
|
|
vDIBSolidBlt(pSurfDst, prclDst, pco, (ULONG)~0, 1);
|
|
return(TRUE);
|
|
|
|
//
|
|
// We special case source copy since it must be one of the two following cases:
|
|
// a) DIB to DIB, which will just call EngCopyBits.
|
|
// b) Device format to DIB, which will just call DrvCopyBits.
|
|
//
|
|
// We also expect source copy to occur A LOT!
|
|
//
|
|
|
|
case 0x0000CCCC:
|
|
|
|
if (pSurfSrc->iType() == STYPE_BITMAP)
|
|
{
|
|
|
|
return(EngCopyBits(psoDst,
|
|
psoSrc,
|
|
pco,
|
|
pxlo,
|
|
prclDst,
|
|
pptlSrc));
|
|
}
|
|
else
|
|
{
|
|
PDEVOBJ pdoSrc(pSurfSrc->hdev());
|
|
|
|
return((*PPFNDRV(pdoSrc,CopyBits)) (psoDst,
|
|
psoSrc,
|
|
pco,
|
|
pxlo,
|
|
prclDst,
|
|
pptlSrc));
|
|
}
|
|
}
|
|
|
|
//
|
|
// Synchronize with the device driver before touching the device surface.
|
|
//
|
|
|
|
if ((psoSrc != (SURFOBJ *) NULL) &&
|
|
(pSurfSrc->flags() & HOOK_SYNCHRONIZE))
|
|
{
|
|
PDEVOBJ po(pSurfSrc->hdev());
|
|
(po.pfnSync())(psoSrc->dhpdev,NULL);
|
|
}
|
|
|
|
//
|
|
// We have to create an empty DIB incase DrvCopyBits needs to be performed.
|
|
// We also have to have a POINTL for the final blt for use as the source org.
|
|
//
|
|
|
|
SURFMEM SurfDimo;
|
|
|
|
//
|
|
// Handle the Device ==> DIB conversion if required
|
|
//
|
|
|
|
if (ROP4NEEDSRC(rop4) && (pSurfSrc->iType() != STYPE_BITMAP))
|
|
{
|
|
PDEVOBJ pdoSrc(pSurfSrc->hdev());
|
|
|
|
//
|
|
// Allocate an intermediate DIB for a source.
|
|
//
|
|
|
|
ERECTL erclTmp(0L,
|
|
0L,
|
|
prclDst->right - prclDst->left,
|
|
prclDst->bottom - prclDst->top);
|
|
|
|
DEVBITMAPINFO dbmi;
|
|
dbmi.iFormat = pSurfDst->iFormat();
|
|
dbmi.cxBitmap = erclTmp.right;
|
|
dbmi.cyBitmap = erclTmp.bottom;
|
|
dbmi.hpal = 0;
|
|
dbmi.fl = 0;
|
|
|
|
if (!SurfDimo.bCreateDIB(&dbmi, NULL))
|
|
{
|
|
WARNING("bCreateDIB failed in EngBitBlt\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
(*PPFNDRV(pdoSrc,CopyBits)) ( (SURFOBJ *) SurfDimo.pSurfobj(),
|
|
psoSrc,
|
|
(CLIPOBJ *) NULL,
|
|
pxlo,
|
|
(PRECTL) &erclTmp,
|
|
pptlSrc);
|
|
|
|
|
|
//
|
|
// Make psoSrc and pptlSrc point to the correct thing.
|
|
//
|
|
|
|
pptlSrc = (POINTL *) &gptl00;
|
|
pSurfSrc = SurfDimo.ps;
|
|
|
|
//
|
|
// Color translation has already been performed, so make
|
|
// the XLATE an identity.
|
|
//
|
|
|
|
pxlo = &xloIdent;
|
|
}
|
|
|
|
//
|
|
// Call BltLnk to perform the ROP
|
|
//
|
|
|
|
if (!BltLnk(pSurfDst,
|
|
pSurfSrc,
|
|
pSurfMask,
|
|
(ECLIPOBJ *) pco,
|
|
(XLATE *) pxlo,
|
|
prclDst,
|
|
pptlSrc,
|
|
pptlMask,
|
|
pdbrush,
|
|
pptlBrush,
|
|
rop4)
|
|
)
|
|
{
|
|
WARNING1("BltLnk Returns FALSE\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
//
|
|
// We have to do simulations on a device surface
|
|
//
|
|
|
|
return(SimBitBlt(psoDst,psoSrc,psoMask,
|
|
pco,pxlo,
|
|
prclDst,pptlSrc,pptlMask,
|
|
pdbrush,pptlBrush,rop4));
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* EngEraseSurface
|
|
*
|
|
* Asks GDI to erase the surface. The rcl will be filled with
|
|
* iColor.
|
|
*
|
|
* History:
|
|
* 02-May-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL
|
|
EngEraseSurface(
|
|
SURFOBJ *pso,
|
|
PRECTL prcl,
|
|
ULONG iColor
|
|
)
|
|
{
|
|
|
|
PSURFACE pSurf = (SURFACE *)(SURFOBJ_TO_SURFACE(pso));
|
|
|
|
ASSERTGDI(prcl != (PRECTL) NULL, "ERROR EngEraseSurface1");
|
|
ASSERTGDI(prcl->left >= 0, "ERROR EngEraseSurface2");
|
|
ASSERTGDI(prcl->top >= 0, "ERROR EngEraseSurface3");
|
|
ASSERTGDI(prcl->right <= pSurf->sizl().cx, "ERROR EngEraseSurface4");
|
|
ASSERTGDI(prcl->bottom <= pSurf->sizl().cy, "ERROR EngEraseSurface5");
|
|
|
|
//
|
|
// Synchronize with the device driver before touching the device surface.
|
|
//
|
|
|
|
if (pSurf->flags() & HOOK_SYNCHRONIZE)
|
|
{
|
|
PDEVOBJ po(pSurf->hdev());
|
|
(po.pfnSync())(pso->dhpdev,NULL);
|
|
}
|
|
|
|
vDIBSolidBlt(pSurf, prcl, (CLIPOBJ *) NULL, iColor, 0);
|
|
return(TRUE);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* SimBitBlt
|
|
*
|
|
* The engine sends EngBitBlt here if a DEVICE surface is passed as psoTrg
|
|
*
|
|
* History:
|
|
* 23-Feb-1994 -by- Eric Kutter [erick]
|
|
* Made it callable from other functions - allow device to device blts.
|
|
*
|
|
* 09-Sep-1992 -by- Donald Sidoroff [donalds]
|
|
* Made it callable from EngBitBlt only.
|
|
*
|
|
* 07-Sep-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL
|
|
SimBitBlt(
|
|
SURFOBJ *psoDst, // Target surface
|
|
SURFOBJ *psoSrc, // Source surface
|
|
SURFOBJ *psoMask, // Mask
|
|
CLIPOBJ *pco, // Clip through this
|
|
XLATEOBJ *pxlo, // Color translation
|
|
RECTL *prclDst, // Target offset and extent
|
|
POINTL *pptlSrc, // Source offset
|
|
POINTL *pptlMask, // Mask offset
|
|
BRUSHOBJ *pdbrush, // Brush data (from cbRealizeBrush)
|
|
POINTL *pptlBrush, // Brush offset (origin)
|
|
ROP4 rop4 // Raster operation
|
|
)
|
|
{
|
|
BOOL bNeedSrc = ROP4NEEDSRC(rop4);
|
|
|
|
PSURFACE pSurfDst = (SURFACE *)(SURFOBJ_TO_SURFACE(psoDst));
|
|
PSURFACE pSurfSrc = (SURFACE *)(SURFOBJ_TO_SURFACE(psoSrc));
|
|
|
|
//
|
|
// Set up new rectangle clipped to destination surface. Clip source
|
|
// pointl and mask pointl accordingly.
|
|
//
|
|
|
|
RECTL rclReduced = *prclDst;
|
|
POINTL ptlSrc;
|
|
POINTL ptlMask;
|
|
|
|
if (bNeedSrc)
|
|
{
|
|
ptlSrc = *pptlSrc;
|
|
}
|
|
|
|
if (psoMask != NULL)
|
|
{
|
|
ptlMask = *pptlMask;
|
|
}
|
|
|
|
if (rclReduced.top < 0)
|
|
{
|
|
ptlSrc.y += (-rclReduced.top);
|
|
ptlMask.y += (-rclReduced.top);
|
|
rclReduced.top = 0;
|
|
}
|
|
|
|
if (rclReduced.left < 0)
|
|
{
|
|
ptlSrc.x += (-rclReduced.left);
|
|
ptlMask.x += (-rclReduced.left);
|
|
rclReduced.left = 0;
|
|
}
|
|
|
|
if (rclReduced.bottom > psoDst->sizlBitmap.cy)
|
|
{
|
|
rclReduced.bottom = psoDst->sizlBitmap.cy;
|
|
}
|
|
|
|
if (rclReduced.right > psoDst->sizlBitmap.cx)
|
|
{
|
|
rclReduced.right = psoDst->sizlBitmap.cx;
|
|
}
|
|
|
|
//
|
|
// Ok we clipped everything to our reduced rectangle, now use the clipped offsets.
|
|
//
|
|
|
|
prclDst = &rclReduced;
|
|
pptlSrc = &ptlSrc;
|
|
pptlMask = &ptlMask;
|
|
|
|
//
|
|
// Set up our temporary DIB rectangle to blt to.
|
|
//
|
|
|
|
ERECTL erclDst(0, 0, prclDst->right - prclDst->left,
|
|
prclDst->bottom - prclDst->top);
|
|
|
|
PDEVOBJ pdoDst(pSurfDst->hdev());
|
|
|
|
ASSERTGDI(pdoDst.bValid(), "EngPuntBlt poDst.bValid");
|
|
|
|
DEVBITMAPINFO dbmiDst;
|
|
dbmiDst.iFormat = pdoDst.iDitherFormat();
|
|
dbmiDst.cxBitmap = erclDst.right;
|
|
dbmiDst.cyBitmap = erclDst.bottom;
|
|
dbmiDst.hpal = 0;
|
|
dbmiDst.fl = 0;
|
|
|
|
SURFMEM SurfDimoDst;
|
|
|
|
SurfDimoDst.bCreateDIB(&dbmiDst, NULL);
|
|
|
|
if (!SurfDimoDst.bValid())
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
POINTL ptlDst;
|
|
ptlDst.x = prclDst->left;
|
|
ptlDst.y = prclDst->top;
|
|
|
|
POINTL ptlBrush;
|
|
|
|
if (pptlBrush != (POINTL *) NULL)
|
|
{
|
|
ptlBrush.x = pptlBrush->x - prclDst->left;
|
|
ptlBrush.y = pptlBrush->y - prclDst->top;
|
|
}
|
|
|
|
(*PPFNGET(pdoDst,CopyBits,pSurfDst->flags())) (SurfDimoDst.pSurfobj(),
|
|
psoDst,
|
|
(CLIPOBJ *) NULL,
|
|
&xloIdent,
|
|
&erclDst,
|
|
&ptlDst);
|
|
|
|
//
|
|
// We have to create an empty DIB incase DrvCopyBits needs to be performed.
|
|
// We also have to have a POINTL for the final blt for use as the source org.
|
|
//
|
|
|
|
SURFMEM SurfDimoSrc;
|
|
|
|
//
|
|
// Handle the Device ==> DIB conversion if required
|
|
//
|
|
|
|
if (bNeedSrc && (pSurfSrc->iType() != STYPE_BITMAP))
|
|
{
|
|
ASSERTGDI(pptlSrc->x >= 0, "ERROR x not big enough");
|
|
ASSERTGDI(pptlSrc->y >= 0, "ERROR y not big enough");
|
|
ASSERTGDI((pptlSrc->x + erclDst.right) <= psoSrc->sizlBitmap.cx, "ERROR x too big");
|
|
ASSERTGDI((pptlSrc->y + erclDst.bottom) <= psoSrc->sizlBitmap.cy, "ERROR y too big");
|
|
|
|
PDEVOBJ pdoSrc(pSurfSrc->hdev());
|
|
|
|
//
|
|
// Allocate an intermediate DIB for a source.
|
|
//
|
|
|
|
DEVBITMAPINFO dbmiSrc;
|
|
dbmiSrc.iFormat = SurfDimoDst.ps->iFormat();
|
|
dbmiSrc.cxBitmap = erclDst.right;
|
|
dbmiSrc.cyBitmap = erclDst.bottom;
|
|
dbmiSrc.hpal = 0;
|
|
dbmiSrc.fl = 0;
|
|
|
|
if (!SurfDimoSrc.bCreateDIB(&dbmiSrc, NULL))
|
|
{
|
|
WARNING("Failed dimoSrc memory alloc in EngPuntBlt\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
(*PPFNGET(pdoSrc,CopyBits,pSurfSrc->flags())) (SurfDimoSrc.pSurfobj(),
|
|
psoSrc,
|
|
(CLIPOBJ *) NULL,
|
|
pxlo,
|
|
(PRECTL) &erclDst,
|
|
pptlSrc);
|
|
|
|
//
|
|
// Make psoSrc and pptlSrc point to the correct thing.
|
|
//
|
|
|
|
pptlSrc = &gptl00;
|
|
psoSrc = SurfDimoSrc.pSurfobj();
|
|
|
|
//
|
|
// Color translation has already been performed, so make
|
|
// the XLATEOBJ an identity.
|
|
//
|
|
|
|
pxlo = &xloIdent;
|
|
}
|
|
|
|
ASSERTGDI(SurfDimoDst.ps->iType() == STYPE_BITMAP, "ERROR dimoDst.iType 1");
|
|
|
|
//
|
|
// Call off to BitBlt, if it fails who cares.
|
|
//
|
|
|
|
EngBitBlt(SurfDimoDst.pSurfobj(),
|
|
psoSrc,
|
|
psoMask,
|
|
(ECLIPOBJ *) NULL,
|
|
pxlo,
|
|
&erclDst,
|
|
pptlSrc,
|
|
pptlMask,
|
|
pdbrush,
|
|
&ptlBrush,
|
|
rop4);
|
|
|
|
//
|
|
// Inc output surface uniqueness
|
|
//
|
|
|
|
INC_SURF_UNIQ(pSurfDst);
|
|
|
|
return((*PPFNGET(pdoDst,CopyBits,pSurfDst->flags())) (
|
|
psoDst,
|
|
SurfDimoDst.pSurfobj(),
|
|
pco,
|
|
&xloIdent,
|
|
prclDst,
|
|
&gptl00));
|
|
}
|