/******************************Module*Header*******************************\ * Module Name: stretch.c * * Copyright (c) 1993-1994 Microsoft Corporation \**************************************************************************/ #include "precomp.h" /******************************Public*Routine******************************\ * BOOL DrvStretchBlt * \**************************************************************************/ BOOL DrvStretchBlt( SURFOBJ* psoDst, SURFOBJ* psoSrc, SURFOBJ* psoMsk, CLIPOBJ* pco, XLATEOBJ* pxlo, COLORADJUSTMENT* pca, POINTL* pptlHTOrg, RECTL* prclDst, RECTL* prclSrc, POINTL* pptlMsk, ULONG iMode) { DSURF* pdsurfSrc; DSURF* pdsurfDst; PDEV* ppdev; ppdev = (PDEV*) psoDst->dhpdev; // It's quicker for GDI to do a StretchBlt when the source surface // is not a device-managed surface, because then it can directly // read the source bits without having to allocate a temporary // buffer and call DrvCopyBits to get a copy that it can use. // // So if the source is one of our off-screen DFBs, we'll immediately // and permanently convert it to a DIB: if (psoSrc->iType == STYPE_DEVBITMAP) { pdsurfSrc = (DSURF*) psoSrc->dhsurf; if (pdsurfSrc->dt == DT_SCREEN) { if (!pohMoveOffscreenDfbToDib(ppdev, pdsurfSrc->poh)) return(FALSE); } ASSERTDD(pdsurfSrc->dt == DT_DIB, "Can only handle DIB DFBs here"); psoSrc = pdsurfSrc->pso; } // Pass the call off to GDI if the destination surface is a device // bitmap that we converted to a DIB: pdsurfDst = (DSURF*) psoDst->dhsurf; if (pdsurfDst->dt == DT_DIB) { psoDst = pdsurfDst->pso; goto Punt_It; } #if 0 // I would enable this chunk of code, except for the fact that { // GDI does byte writes to the screen, which kills us on ISA // buses (it's faster to have GDI write to a temporary DIB, // paying the cost of the DIB allocation, and then doing an // aligned copy of the final result). #if defined(i386) { OH* poh; BANK bnk; BOOL b; RECTL rclDraw; // Make sure we're not doing a screen-to-screen StretchBlt, // because we can't map two banks in at the same time: if (psoSrc->iType == STYPE_BITMAP) { // We'll be drawing to the screen or an off-screen DFB; // copy the surface's offset now so that we won't need // to refer to the DSURF again: poh = pdsurfDst->poh; ppdev->xOffset = poh->x; ppdev->yOffset = poh->y; // The bank manager requires that the 'draw' rectangle be // well-ordered: rclDraw = *prclDst; if (rclDraw.left > rclDraw.right) { rclDraw.left = prclDst->right; rclDraw.right = prclDst->left; } if (rclDraw.top > rclDraw.bottom) { rclDraw.top = prclDst->bottom; rclDraw.bottom = prclDst->top; } vBankStart(ppdev, &rclDraw, pco, &bnk); b = TRUE; do { b &= EngStretchBlt(bnk.pso, psoSrc, psoMsk, bnk.pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMsk, iMode); } while (bBankEnum(&bnk)); return(b); } } #endif // i386 } #endif // 0 Punt_It: // GDI is nice enough to handle the cases where 'psoDst' and/or 'psoSrc' // are device-managed surfaces, but it ain't gonna be fast... return(EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMsk, iMode)); }