|
|
/******************************Module*Header*******************************\
* Module Name: trivblt.cxx * * EngCopyBits does the bitmap simulations source copy blts. * The Rop is 0xCCCC, no brush or mask required. Dib src * and Dib dest are required. * * Created: 05-Feb-1991 21:06:12 * Author: Patrick Haluptzok patrickh * * Copyright (c) 1990-1999 Microsoft Corporation \**************************************************************************/
#include "precomp.hxx"
//
// The following table is used to lookup the function to be used for a
// particular type of copy operation. The table is indexed by a loosely
// encoded index composed of the source format, the destination format,
// the direction of the move, and whether the function is an identify
// function.
//
// This table is used in lieu of a doubly nested switch structure that
// not only takes more room, but requires more execution time.
//
// The index is formed as:
//
// Index = (iFormatDst << 5) | (iFormatSrc << 2);
// if (xDir < 0) {
// Index += 2;
// }
//
// if (pxlo->bIsIdentity()) {
// Index += 1;
// }
//
// N.B. The entire table is filled. Entries that are illegal are tested
// for using assertions. In free systems, dummy entries are used.
//
VOID vSrcCopyDummy ( PBLTINFO BltInfo );
PFN_SRCCPY SrcCopyFunctionTable[] = { vSrcCopyDummy, // 000-000-0-0 Dst = ?, Src = ?
vSrcCopyDummy, // 000-000-0-1
vSrcCopyDummy, // 000-000-1-0
vSrcCopyDummy, // 000-000-1-1
vSrcCopyDummy, // 000-001-0-0 Dst = ?, Src = BMF_1BPP
vSrcCopyDummy, // 000-001-0-1
vSrcCopyDummy, // 000-001-1-0
vSrcCopyDummy, // 000-001-1-1
vSrcCopyDummy, // 000-010-0-0 Dst = ?, Src = BMF_4BPP
vSrcCopyDummy, // 000-010-0-1
vSrcCopyDummy, // 000-010-1-0
vSrcCopyDummy, // 000-010-1-1
vSrcCopyDummy, // 000-011-0-0 Dst = ?, Src = BMF_8BPP
vSrcCopyDummy, // 000-011-0-1
vSrcCopyDummy, // 000-011-1-0
vSrcCopyDummy, // 000-011-1-1
vSrcCopyDummy, // 000-100-0-0 Dst = ?, Src = BMF_16BPP
vSrcCopyDummy, // 000-100-0-1
vSrcCopyDummy, // 000-100-1-0
vSrcCopyDummy, // 000-100-1-1
vSrcCopyDummy, // 000-101-0-0 Dst = ?, Src = BMF_24BPP
vSrcCopyDummy, // 000-101-0-1
vSrcCopyDummy, // 000-101-1-0
vSrcCopyDummy, // 000-101-1-1
vSrcCopyDummy, // 000-110-0-0 Dst = ?, Src = BMF_32BPP
vSrcCopyDummy, // 000-110-0-1
vSrcCopyDummy, // 000-110-1-0
vSrcCopyDummy, // 000-110-1-1
vSrcCopyDummy, // 000-111-0-0 Dst = ?, Src = ?
vSrcCopyDummy, // 000-111-0-1
vSrcCopyDummy, // 000-111-1-0
vSrcCopyDummy, // 000-111-1-1
vSrcCopyDummy, // 001-000-0-0 Dst = BMF_1BPP, Src = ?
vSrcCopyDummy, // 001-000-0-1
vSrcCopyDummy, // 001-000-1-0
vSrcCopyDummy, // 001-000-1-1
vSrcCopyS1D1LtoR, // 001-001-0-0 Dst = BMF_1BPP, Src = BMF_1BPP
vSrcCopyS1D1LtoR, // 001-001-0-1
vSrcCopyS1D1RtoL, // 001-001-1-0
vSrcCopyS1D1RtoL, // 001-001-1-1
vSrcCopyS4D1, // 001-010-0-0 Dst = BMF_1BPP, Src = BMF_4BPP
vSrcCopyS4D1, // 001-010-0-1
vSrcCopyS4D1, // 001-010-1-0
vSrcCopyS4D1, // 001-010-1-1
vSrcCopyS8D1, // 001-011-0-0 Dst = BMF_1BPP, Src = BMF_8BPP
vSrcCopyS8D1, // 001-011-0-1
vSrcCopyS8D1, // 001-011-1-0
vSrcCopyS8D1, // 001-011-1-1
vSrcCopyS16D1, // 001-100-0-0 Dst = BMF_1BPP, Src = BMF_16BPP
vSrcCopyS16D1, // 001-100-0-1
vSrcCopyS16D1, // 001-100-1-0
vSrcCopyS16D1, // 001-100-1-1
vSrcCopyS24D1, // 001-101-0-0 Dst = BMF_1BPP, Src = BMF_24BPP
vSrcCopyS24D1, // 001-101-0-1
vSrcCopyS24D1, // 001-101-1-0
vSrcCopyS24D1, // 001-101-1-1
vSrcCopyS32D1, // 001-110-0-0 Dst = BMF_1BPP, Src = BMF_32BPP
vSrcCopyS32D1, // 001-110-0-1
vSrcCopyS32D1, // 001-110-1-0
vSrcCopyS32D1, // 001-110-1-1
vSrcCopyDummy, // 001-111-0-0 Dst = BMF_1BPP, Src = ?
vSrcCopyDummy, // 001-111-0-1
vSrcCopyDummy, // 001-111-1-0
vSrcCopyDummy, // 001-111-1-1
vSrcCopyDummy, // 010-000-0-0 Dst = BMF_4BPP, Src = ?
vSrcCopyDummy, // 010-000-0-1
vSrcCopyDummy, // 010-000-1-0
vSrcCopyDummy, // 010-000-1-1
vSrcCopyS1D4, // 010-001-0-0 Dst = BMF_4BPP, Src = BMF_1BPP
vSrcCopyS1D4, // 010-001-0-1
vSrcCopyS1D4, // 010-001-1-0
vSrcCopyS1D4, // 010-001-1-1
vSrcCopyS4D4, // 010-010-0-0 Dst = BMF_4BPP, Src =BMF_4BPP
vSrcCopyS4D4Identity, // 010-010-0-1
vSrcCopyS4D4, // 010-010-1-0
vSrcCopyS4D4Identity, // 010-010-1-1
vSrcCopyS8D4, // 010-011-0-0 Dst = BMF_4BPP, Src = BMF_8BPP
vSrcCopyS8D4, // 010-011-0-1
vSrcCopyS8D4, // 010-011-1-0
vSrcCopyS8D4, // 010-011-1-1
vSrcCopyS16D4, // 010-100-0-0 Dst = BMF_4BPP, Src = BMF_16BPP
vSrcCopyS16D4, // 010-100-0-1
vSrcCopyS16D4, // 010-100-1-0
vSrcCopyS16D4, // 010-100-1-1
vSrcCopyS24D4, // 010-101-0-0 Dst = BMF_4BPP, Src = BMF_24BPP
vSrcCopyS24D4, // 010-101-0-1
vSrcCopyS24D4, // 010-101-1-0
vSrcCopyS24D4, // 010-101-1-1
vSrcCopyS32D4, // 010-110-0-0 Dst = BMF_4BPP, Src = BMF_32BPP
vSrcCopyS32D4, // 010-110-0-1
vSrcCopyS32D4, // 010-110-1-0
vSrcCopyS32D4, // 010-110-1-1
vSrcCopyDummy, // 010-111-0-0 Dst = BMF_4BPP, Src = ?
vSrcCopyDummy, // 010-111-0-1
vSrcCopyDummy, // 010-111-1-0
vSrcCopyDummy, // 010-111-1-1
vSrcCopyDummy, // 011-000-0-0 Dst = BMF_8BPP, Src = ?
vSrcCopyDummy, // 011-000-0-1
vSrcCopyDummy, // 011-000-1-0
vSrcCopyDummy, // 011-000-1-1
vSrcCopyS1D8, // 011-001-0-0 Dst = BMF_8BPP, Src = BMF_1BPP
vSrcCopyS1D8, // 011-001-0-1
vSrcCopyS1D8, // 011-001-1-0
vSrcCopyS1D8, // 011-001-1-1
vSrcCopyS4D8, // 011-010-0-0 Dst = BMF_8BPP, Src = BMF_4BPP
vSrcCopyS4D8, // 011-010-0-1
vSrcCopyS4D8, // 011-010-1-0
vSrcCopyS4D8, // 011-010-1-1
vSrcCopyS8D8, // 011-011-0-0 Dst = BMF_8BPP, Src = BMF_8BPP
vSrcCopyS8D8IdentityLtoR, // 011-011-0-1
vSrcCopyS8D8, // 011-011-1-0
vSrcCopyS8D8IdentityRtoL, // 011-011-1-1
vSrcCopyS16D8, // 011-100-0-0 Dst = BMF_8BPP, Src = BMF_16BPP
vSrcCopyS16D8, // 011-100-0-1
vSrcCopyS16D8, // 011-100-1-0
vSrcCopyS16D8, // 011-100-1-1
vSrcCopyS24D8, // 011-101-0-0 Dst = BMF_8BPP, Src = BMF_24BPP
vSrcCopyS24D8, // 011-101-0-1
vSrcCopyS24D8, // 011-101-1-0
vSrcCopyS24D8, // 011-101-1-1
vSrcCopyS32D8, // 011-110-0-0 Dst = BMF_8BPP, Src = BMF_32BPP
vSrcCopyS32D8, // 011-110-0-1
vSrcCopyS32D8, // 011-110-1-0
vSrcCopyS32D8, // 011-110-1-1
vSrcCopyDummy, // 011-111-0-0 Dst = BMF_8BPP, Src = ?
vSrcCopyDummy, // 011-111-0-1
vSrcCopyDummy, // 011-111-1-0
vSrcCopyDummy, // 011-111-1-1
vSrcCopyDummy, // 100-000-0-0 Dst = BMF_16BPP, Src = ?
vSrcCopyDummy, // 100-000-0-1
vSrcCopyDummy, // 100-000-1-0
vSrcCopyDummy, // 100-000-1-1
vSrcCopyS1D16, // 100-001-0-0 Dst = BMF_16BPP, Src = BMF_1BPP
vSrcCopyS1D16, // 100-001-0-1
vSrcCopyS1D16, // 100-001-1-0
vSrcCopyS1D16, // 100-001-1-1
vSrcCopyS4D16, // 100-010-0-0 Dst = BMF_16BPP, Src = BMF_4BPP
vSrcCopyS4D16, // 100-010-0-1
vSrcCopyS4D16, // 100-010-1-0
vSrcCopyS4D16, // 100-010-1-1
vSrcCopyS8D16, // 100-011-0-0 Dst = BMF_16BPP, Src = BMF_8BPP
vSrcCopyS8D16, // 100-011-0-1
vSrcCopyS8D16, // 100-011-1-0
vSrcCopyS8D16, // 100-011-1-1
vSrcCopyS16D16, // 100-100-0-0 Dst = BMF_16BPP, Src = BMF_16BPP
vSrcCopyS16D16Identity, // 100-100-0-1
vSrcCopyS16D16, // 100-100-1-0
vSrcCopyS16D16Identity, // 100-100-1-1
vSrcCopyS24D16, // 100-101-0-0 Dst = BMF_16BPP, Src = BMF_24BPP
vSrcCopyS24D16, // 100-101-0-1
vSrcCopyS24D16, // 100-101-1-0
vSrcCopyS24D16, // 100-101-1-1
vSrcCopyS32D16, // 100-110-0-0 Dst = BMF_16BPP, Src = BMF_32BPP
vSrcCopyS32D16, // 100-110-0-1
vSrcCopyS32D16, // 100-110-1-0
vSrcCopyS32D16, // 100-110-1-1
vSrcCopyDummy, // 100-111-0-0 Dst = BMF_16BPP, Src = ?
vSrcCopyDummy, // 100-111-0-1
vSrcCopyDummy, // 100-111-1-0
vSrcCopyDummy, // 100-111-1-1
vSrcCopyDummy, // 101-000-0-0 Dst = BMF_24BPP, Src = ?
vSrcCopyDummy, // 101-000-0-1
vSrcCopyDummy, // 101-000-1-0
vSrcCopyDummy, // 101-000-1-1
vSrcCopyS1D24, // 101-001-0-0 Dst = BMF_24BPP, Src = BMF_1BPP
vSrcCopyS1D24, // 101-001-0-1
vSrcCopyS1D24, // 101-001-1-0
vSrcCopyS1D24, // 101-001-1-1
vSrcCopyS4D24, // 101-010-0-0 Dst = BMF_24BPP, Src = BMF_4BPP
vSrcCopyS4D24, // 101-010-0-1
vSrcCopyS4D24, // 101-010-1-0
vSrcCopyS4D24, // 101-010-1-1
vSrcCopyS8D24, // 101-011-0-0 Dst = BMF_24BPP, Src = BMF_8BPP
vSrcCopyS8D24, // 101-011-0-1
vSrcCopyS8D24, // 101-011-1-0
vSrcCopyS8D24, // 101-011-1-1
vSrcCopyS16D24, // 101-100-0-0 Dst = BMF_24BPP, Src = BMF_16BPP
vSrcCopyS16D24, // 101-100-0-1
vSrcCopyS16D24, // 101-100-1-0
vSrcCopyS16D24, // 101-100-1-1
vSrcCopyS24D24, // 101-101-0-0 Dst = BMF_24BPP, Src = BMF_24BPP
vSrcCopyS24D24Identity, // 101-101-0-1
vSrcCopyS24D24, // 101-101-1-0
vSrcCopyS24D24Identity, // 101-101-1-1
vSrcCopyS32D24, // 101-110-0-0 Dst = BMF_24BPP, Src = BMF_32BPP
vSrcCopyS32D24, // 101-110-0-1
vSrcCopyS32D24, // 101-110-1-0
vSrcCopyS32D24, // 101-110-1-1
vSrcCopyDummy, // 101-111-0-0 Dst = BMF_24BPP, Src = ?
vSrcCopyDummy, // 101-111-0-1
vSrcCopyDummy, // 101-111-1-0
vSrcCopyDummy, // 101-111-1-1
vSrcCopyDummy, // 110-000-0-0 Dst = BMF_32BPP, Src = ?
vSrcCopyDummy, // 110-000-0-1
vSrcCopyDummy, // 110-000-1-0
vSrcCopyDummy, // 110-000-1-1
vSrcCopyS1D32, // 110-001-0-0 Dst = BMF_32BPP, Src = BMF_1BPP
vSrcCopyS1D32, // 110-001-0-1
vSrcCopyS1D32, // 110-001-1-0
vSrcCopyS1D32, // 110-001-1-1
vSrcCopyS4D32, // 110-010-0-0 Dst = BMF_32BPP, Src = BMF_4BPP
vSrcCopyS4D32, // 110-010-0-1
vSrcCopyS4D32, // 110-010-1-0
vSrcCopyS4D32, // 110-010-1-1
vSrcCopyS8D32, // 110-011-0-0 Dst = BMF_32BPP, Src = BMF_8BPP
vSrcCopyS8D32, // 110-011-0-1
vSrcCopyS8D32, // 110-011-1-0
vSrcCopyS8D32, // 110-011-1-1
vSrcCopyS16D32, // 110-100-0-0 Dst = BMF_32BPP, Src = BMF_16BPP
vSrcCopyS16D32, // 110-100-0-1
vSrcCopyS16D32, // 110-100-1-0
vSrcCopyS16D32, // 110-100-1-1
vSrcCopyS24D32, // 110-101-0-0 Dst = BMF_32BPP, Src = BMF_24BPP
vSrcCopyS24D32, // 110-101-0-1
vSrcCopyS24D32, // 110-101-1-0
vSrcCopyS24D32, // 110-101-1-1
vSrcCopyS32D32, // 110-110-0-0 Dst = BMF_32BPP, Src = BMF_32BPP
vSrcCopyS32D32Identity, // 110-110-0-1
vSrcCopyS32D32, // 110-110-1-0
vSrcCopyS32D32Identity, // 110-110-1-1
vSrcCopyDummy, // 110-111-0-0 Dst = BMF_32BPP, Src = ?
vSrcCopyDummy, // 110-111-0-1
vSrcCopyDummy, // 110-111-1-0
vSrcCopyDummy // 110-111-1-1
};
/******************************Public*Routine******************************\
* EngCopyBits * * Purpose: Does all 0xCCCC blts. This includes RLE blts. * * Description: * * Sets up for a blt from <psoSrc> to <psoDst>. The actual copying of * the bits is performed by a function call. The function to be used * is determined by the formats of the source & destination - and is * is selected by making a call to <pfnSrcCpy>. * * The blt setup consists of filling a BLTINFO structure with * - offsets into the source and destination bitmaps * - intial values of the source and destination pointers * - ending points in source and destination. * * This function also controls clipping: In the complex clipping case, * the BLTINFO structure is set up and the blt function is called for * EACH rectangle in the clipping object <pco>. * * NB: RLE Sources are treated as a special case, since we can't cheat * and start copying from inside the source bitmap. We must play * the RLE from the beginning for each clipping region. * An optimization to get around this is coming. * * History: * 22-Jan-1992 - Andrew Milton (w-andym): * Isolated the RLE source cases and provided some RLE play * optimizations. * * 02-May-1991 -by- Patrick Haluptzok patrickh * Wrote it. \**************************************************************************/
BOOL EngCopyBits( SURFOBJ *psoDst, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, PRECTL prclDst, PPOINTL pptlSrc ) { ASSERTGDI(psoDst != NULL, "ERROR EngCopyBits: No Dst. Object\n"); ASSERTGDI(psoSrc != NULL, "ERROR EngCopyBits: No Src. Object\n"); ASSERTGDI(prclDst != (PRECTL) NULL, "ERROR EngCopyBits: No Target Rect.\n"); ASSERTGDI(pptlSrc != (PPOINTL) NULL, "ERROR EngCopyBits: No Start Point.\n"); ASSERTGDI(prclDst->left < prclDst->right, "ERROR EngCopyBits0\n"); ASSERTGDI(prclDst->top < prclDst->bottom, "ERROR EngCopyBits1\n");
ASSERTGDI(psoDst->iType == STYPE_BITMAP, "ERROR EngCopyBits: Dst. Object is not a bitmap.\n");
PSURFACE pSurfDst = SURFOBJ_TO_SURFACE(psoDst); PSURFACE pSurfSrc = SURFOBJ_TO_SURFACE(psoSrc);
ASSERTGDI(pSurfDst->iFormat() != BMF_JPEG, "ERROR EngCopyBits: dst BMF_JPEG\n"); ASSERTGDI(pSurfDst->iFormat() != BMF_PNG, "ERROR EngCopyBits: dst BMF_PNG\n"); ASSERTGDI(pSurfSrc->iFormat() != BMF_JPEG, "ERROR EngCopyBits: src BMF_JPEG\n"); ASSERTGDI(pSurfSrc->iFormat() != BMF_PNG, "ERROR EngCopyBits: src BMF_PNG\n");
// If this is a device surface pass it off to the driver.
if (psoSrc->iType != STYPE_BITMAP) { PDEVOBJ pdoSrc(pSurfSrc->hdev());
PFN_DrvCopyBits pfnCopyBits = PPFNDRV(pdoSrc,CopyBits);
// If the source is a mirrored surface, pass the read request back
// through the DDML. This allows a driver like NetMeeting to read
// from the screen:
EXLATEOBJ xloParent;
if (pSurfSrc->bMirrorSurface() && (pdoSrc.hdev() != pdoSrc.hdevParent())) { PDEVOBJ pdoSrc(pSurfSrc->hdev()); PDEVOBJ pdoParent(pdoSrc.hdevParent()); SURFREF srParent((HSURF)pSurfSrc->hMirrorParent); if (!srParent.bValid()) return (FALSE); if (xloParent.bInitXlateObj( NULL,DC_ICM_OFF, pdoParent.ppalSurf(), pdoSrc.ppalSurf(), ppalDefault, ppalDefault, 0L,0L,0L, XLATE_USE_SURFACE_PAL)) pxlo = xloParent.pxlo(); else return (FALSE);
psoSrc = srParent.ps->pSurfobj(); pfnCopyBits = PPFNDRV(pdoParent, CopyBits); }
return(pfnCopyBits(psoDst, psoSrc, pco, pxlo, prclDst, pptlSrc)); }
// Synchronize with the device driver before touching the device surface.
{ PDEVOBJ po(psoDst->hdev); po.vSync(psoDst,NULL,0); }
{ PDEVOBJ po(psoSrc->hdev); po.vSync(psoSrc,NULL,0); }
// Local Variables required for the blt
BOOL bMore; // True while more clip regions exist
BOOL bRLE = FALSE; // True if the source is an RLE bitmap
ULONG ircl; // Clip region index
BLTINFO bltinfo; // Data passed to our vSrcCopySnDn fxn
/* Compute the directions for the copy and clipping enumeration. There
* are two cases: RLE & not. * * RLE's are always copied Left-Right, Bottom-Top; which is also their * clipping enumeration. * * For non-RLE's, the copy direction is dependant on overlap. The * X and Y directions must be chosen so ensure no portion of the source * is clobbered by the copy operation. If there is no overlap, the * copy and clipping enumeration is Left-Right, Top-Bottom. */
LONG xDir = 1L, yDir = 1L; /* X, Y Directions. Positive = Left, Down */ LONG iDir; // Order to fetch clip region rectangles
/*
* Are we going to do reads from BMF_NOTSYSMEM ie Video memory ? * If so set up bltinfo so the blitting routine wil do source aligned reads. */
if ((psoSrc->iBitmapFormat == BMF_8RLE) || (psoSrc->iBitmapFormat == BMF_4RLE)) { /* RLE Case. */
iDir = CD_RIGHTUP; xDir = 1L; yDir = -1L;
bltinfo.lDeltaDst = -psoDst->lDelta; bltinfo.lDeltaSrc = 0;
bRLE = TRUE; } else { /* Non-RLE Case.
* * Check whether source and destination are the same by comparing * the pvScan0 pointers. We can't simply compare surface pointers or * handles because some drivers punt this call to GDI, but pass us * different SURFOBJs for the source and destination even when * they're really the same surface. */
if (psoSrc->pvScan0 == psoDst->pvScan0) { if (pptlSrc->x < prclDst->left) { xDir = -1L; /* Copy Right to Left */ if (pptlSrc->y < prclDst->top) { yDir = -1L; /* Copy Bottom to Top */ iDir = CD_LEFTUP; /* Clip Left-Right, Bottom-Top */ } else { iDir = CD_LEFTDOWN; /* Clip Left-Right, Top-Bottom */ } } else { if (pptlSrc->y < prclDst->top) { yDir = -1L; /* Copy Bottom to Top */ iDir = CD_RIGHTUP; /* Clip Right-Left, Bottom-Top */ } else iDir = CD_RIGHTDOWN; } } else iDir = CD_ANY;
bltinfo.lDeltaSrc = (yDir > 0) ? psoSrc->lDelta : -psoSrc->lDelta; bltinfo.lDeltaDst = (yDir > 0) ? psoDst->lDelta : -psoDst->lDelta; }
/* Determine the clipping region complexity. */
CLIPENUMRECT clenr; /* buffer for storing clip rectangles */ if (pco != (CLIPOBJ *) NULL) { switch(pco->iDComplexity) { case DC_TRIVIAL: bMore = FALSE; clenr.c = 1; clenr.arcl[0] = *prclDst; // Use the target for clipping
break;
case DC_RECT: bMore = FALSE; clenr.c = 1; clenr.arcl[0] = pco->rclBounds; break;
case DC_COMPLEX: bMore = TRUE; ((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, iDir, CLIPOBJ_ENUM_LIMIT); break;
default: RIP("ERROR EngCopyBits bad clipping type");
} /* switch */ } else { bMore = FALSE; /* Default to TRIVIAL for no clip */ clenr.c = 1; clenr.arcl[0] = *prclDst; // Use the target for clipping
} /* if */
/* Set up the static blt information into the BLTINFO structure -
* The colour translation, & the copy directions. */
/* pxlo is NULL implies identity colour translation. */ if (pxlo == NULL) bltinfo.pxlo = &xloIdent; else bltinfo.pxlo = (XLATE *) pxlo;
bltinfo.xDir = xDir; bltinfo.yDir = yDir;
/* Use a seperate loop for RLE bitmaps. This way, we won't slow down
* an iteration with an IF on each pass. The trade-off is to duplicate * a portion of the code. */
if (bRLE) { /* Fetch our blt function. Die if NULL */
PFN_RLECPY pfnRLECopy = pfnGetRLESrcCopy(psoSrc->iBitmapFormat, psoDst->iBitmapFormat); if (pfnRLECopy == (PFN_RLECPY) NULL) return (FALSE);
BOOL bBytesRemain = TRUE;
/* Since an RLE bitmap must be played from its beginning,
* we do not need to calculate offsets into the source bitmap. * This way, most of the information required for the BLTINFO * can be read off the Source & Destination objects. */
bltinfo.ptlSrc = *pptlSrc; bltinfo.pdioSrc = pSurfSrc; bltinfo.yDstStart = (LONG)(prclDst->top + psoSrc->sizlBitmap.cy - pptlSrc->y - 1);
bltinfo.xDstStart = (LONG)(prclDst->left - pptlSrc->x); bltinfo.ulOutCol = bltinfo.xDstStart;
bltinfo.pjSrc = (PBYTE) psoSrc->pvScan0; bltinfo.pjDst = (PBYTE) (((PBYTE) psoDst->pvScan0) + bltinfo.yDstStart*psoDst->lDelta); bltinfo.ulConsumed = 0; bltinfo.rclDst.top = 0;
do { PRECTL prcl; if (bMore) bMore = ((ECLIPOBJ *) pco)->bEnum(sizeof(clenr), (PVOID) &clenr);
for (ircl = 0; ircl < clenr.c; ircl++) {
prcl = &clenr.arcl[ircl];
/* Insersect the clip rectangle with the target rectangle to
* determine our visible rectangle */
if (prcl->left < prclDst->left) prcl->left = prclDst->left; if (prcl->right > prclDst->right) prcl->right = prclDst->right; if (prcl->top < prclDst->top) prcl->top = prclDst->top; if (prcl->bottom > prclDst->bottom) prcl->bottom = prclDst->bottom;
/* Process the result if it's a valid rectangle. */
if ((prcl->top < prcl->bottom) && (prcl->left < prcl->right)) { /* Adjust our starting position based on previous clips */
if (prcl->bottom <= bltinfo.rclDst.top) { if ((ULONG)prcl->top > bltinfo.ulEndRow) continue;
if (!bBytesRemain) { bMore = FALSE; // Force us out of the outer loop
break; // Force us out of the inner loop
}
bltinfo.pjSrc = bltinfo.pjSrcEnd; bltinfo.pjDst = bltinfo.pjDstEnd; bltinfo.yDstStart = bltinfo.ulEndRow; bltinfo.ulOutCol = bltinfo.ulEndCol; bltinfo.ulConsumed = bltinfo.ulEndConsumed; }
bltinfo.rclDst = *prcl; bBytesRemain = (*pfnRLECopy)(&bltinfo);
}
} /* for */
} while(bMore);
} else { /* Non-RLE Case */
ULONG Index; PFN_SRCCPY pfnSrcCopy;
ASSERTGDI(BMF_1BPP == 1, "ERROR EngCopyBits: BMF_1BPP not eq 1"); ASSERTGDI(BMF_4BPP == 2, "ERROR EngCopyBits: BMF_1BPP not eq 2"); ASSERTGDI(BMF_8BPP == 3, "ERROR EngCopyBits: BMF_1BPP not eq 3"); ASSERTGDI(BMF_16BPP == 4, "ERROR EngCopyBits: BMF_1BPP not eq 4"); ASSERTGDI(BMF_24BPP == 5, "ERROR EngCopyBits: BMF_1BPP not eq 5"); ASSERTGDI(BMF_32BPP == 6, "ERROR EngCopyBits: BMF_1BPP not eq 6"); ASSERTGDI(psoDst->iBitmapFormat <= BMF_32BPP, "ERROR EngCopyBits: bad destination format"); ASSERTGDI(psoSrc->iBitmapFormat <= BMF_32BPP, "ERROR EngCopyBits: bad source format"); ASSERTGDI(psoDst->iBitmapFormat != 0, "ERROR EngCopyBits: bad destination format"); ASSERTGDI(psoSrc->iBitmapFormat != 0, "ERROR EngCopyBits: bad source format");
//
// Compute the function table index and select the source copy
// function.
//
Index = (psoDst->iBitmapFormat << 5) | (psoSrc->iBitmapFormat << 2); if (xDir < 0) { Index += 2; }
KFLOATING_SAVE fpState; BOOL bRestoreFP = FALSE; if (((XLATE *)(bltinfo.pxlo))->bIsIdentity()) { Index += 1; if(psoSrc->fjBitmap & BMF_NOTSYSMEM) { bltinfo.fSrcAlignedRd = TRUE; #if i386
if(HasMMX) { bRestoreFP = TRUE; if(!NT_SUCCESS(KeSaveFloatingPointState(&fpState))) { bltinfo.fSrcAlignedRd = FALSE; bRestoreFP = FALSE; } } #endif
} }
pfnSrcCopy = SrcCopyFunctionTable[Index]; do {
if (bMore) bMore = ((ECLIPOBJ *) pco)->bEnum(sizeof(clenr), (PVOID) &clenr);
for (ircl = 0; ircl < clenr.c; ircl++) { PRECTL prcl = &clenr.arcl[ircl];
/* Insersect the clip rectangle with the target rectangle to
* determine our visible recangle */
if (prcl->left < prclDst->left) prcl->left = prclDst->left; if (prcl->right > prclDst->right) prcl->right = prclDst->right; if (prcl->top < prclDst->top) prcl->top = prclDst->top; if (prcl->bottom > prclDst->bottom) prcl->bottom = prclDst->bottom;
/* Process the result if it's a valid rectangle. */
if ((prcl->top < prcl->bottom) && (prcl->left < prcl->right)) { /* These variables are used for computing where the
* scanlines start. */ LONG xSrc; LONG ySrc; LONG xDst; LONG yDst;
// Figure out the upper-left coordinates of rects to blt
xDst = prcl->left; yDst = prcl->top; xSrc = pptlSrc->x + xDst - prclDst->left; ySrc = pptlSrc->y + yDst - prclDst->top;
// Figure out the width and height of this rectangle
bltinfo.cx = prcl->right - xDst; bltinfo.cy = prcl->bottom - yDst;
/* # of pixels offset to first pixel for src and dst
* from start of scan */ bltinfo.xSrcStart = (xDir > 0) ? xSrc : (xSrc + bltinfo.cx - 1); bltinfo.xSrcEnd = bltinfo.xSrcStart + (bltinfo.cx * xDir); bltinfo.xDstStart = (xDir > 0) ? xDst : (xDst + bltinfo.cx - 1); bltinfo.yDstStart = prcl->top;
// Src scanline begining
// Destination scanline begining
if (yDir > 0) { bltinfo.pjSrc = ((PBYTE) psoSrc->pvScan0) + ySrc*(psoSrc->lDelta); bltinfo.pjDst = ((PBYTE) psoDst->pvScan0) + yDst * (psoDst->lDelta); } else { bltinfo.pjSrc = ((PBYTE) psoSrc->pvScan0) + (ySrc + bltinfo.cy - 1) * (psoSrc->lDelta); bltinfo.pjDst = ((PBYTE) psoDst->pvScan0) + (yDst + bltinfo.cy - 1) * (psoDst->lDelta); } /* if */
/* Do the blt */
(*pfnSrcCopy)(&bltinfo);
} /* if */
} /* for */
} while (bMore); #if i386
if(HasMMX) { if(bRestoreFP) { KeRestoreFloatingPointState(&fpState); } } #endif
} /* if */ return(TRUE);
} /* EngCopyBits */
/******************************Private*Routine*****************************\
* vSrcCopyDummy * * This gets the correct function to dispatch to for Src Copy Bitblt. * * History: * 02-Sep-1992 -by- David N. Cutler davec * Wrote it. \**************************************************************************/
VOID vSrcCopyDummy ( PBLTINFO BltInfo )
{
ASSERTGDI(FALSE, "ERROR EngCopyBits: dummy function called"); return; }
/******************************Public*Routine******************************\
* pfnGetRLESrcCopy * * This gets the correct function to dispatch to for Src Copy Bitblt, * assuming that the source is an RLE bitmap. * * History: * * 05 Mar 1992 - Andrew Milton (w-andym): * Creation. * \**************************************************************************/
PFN_RLECPY pfnGetRLESrcCopy( ULONG iFormatSrc, ULONG iFormatDst) {
switch(iFormatDst) {
case BMF_1BPP:
switch(iFormatSrc) { case BMF_8RLE: return(bSrcCopySRLE8D1);
case BMF_4RLE: return(bSrcCopySRLE4D1);
default: RIP("ERROR: Invalid iFormatSrc in XlateList"); }
case BMF_4BPP:
switch(iFormatSrc) { case BMF_8RLE: return(bSrcCopySRLE8D4);
case BMF_4RLE: return(bSrcCopySRLE4D4);
default: RIP("ERROR: Invalid iFormatSrc in XlateList"); }
case BMF_8BPP:
switch(iFormatSrc) { case BMF_8RLE: return(bSrcCopySRLE8D8);
case BMF_4RLE: return(bSrcCopySRLE4D8);
default: RIP("ERROR: Invalid iFormatSrc in XlateList"); }
case BMF_16BPP:
switch(iFormatSrc) { case BMF_8RLE: return(bSrcCopySRLE8D16);
case BMF_4RLE: return(bSrcCopySRLE4D16);
default: RIP("ERROR: Invalid iFormatSrc in XlateList"); }
case BMF_24BPP:
switch(iFormatSrc) { case BMF_8RLE: return(bSrcCopySRLE8D24);
case BMF_4RLE: return(bSrcCopySRLE4D24);
default: RIP("ERROR: Invalid iFormatSrc in XlateList"); }
case BMF_32BPP: switch(iFormatSrc) { case BMF_8RLE: return(bSrcCopySRLE8D32);
case BMF_4RLE: return(bSrcCopySRLE4D32);
default: RIP("ERROR: Invalid iFormatSrc in XlateList"); }
default: RIP("ERROR: Invalid iFormatDst in XlateList"); } /* switch */
return(NULL); } /* pfnGetRLESrcCopy */
|