/**************************************************************************** ***************************************************************************** * * ****************************************** * * Copyright (c) 1995, Cirrus Logic, Inc. * * * All Rights Reserved * * ****************************************** * * PROJECT: Laguna I (CL-GD5462) - * * FILE: stretch.c * * AUTHOR: Benny Ng * * DESCRIPTION: * This module implements the DrvStretchBlt() function for the * Laguna NT driver. * * MODULES: * AdjustSrcSize() * bRectIntersect() * cRectIntersect() * Shrink() * Stretch() * CopySrcToOffMem() * bStretchDIB() * HandleCase_1() * DrvStretchBlt() * * REVISION HISTORY: * 7/11/95 Benny Ng Initial version * * $Log: X:/log/laguna/nt35/displays/cl546x/STRETCH.C $ * * Rev 1.14 Nov 03 1997 11:10:48 frido * Added REQUIRE and WRITE_STRING macros. * * Rev 1.13 08 Apr 1997 12:29:06 einkauf * * add SYNC_W_3D to coordinate MCD/2D access * * Rev 1.12 21 Mar 1997 12:22:16 noelv * Combined "do_flag" and "sw_test_flag" together into "pointer_switch" * * Rev 1.11 07 Mar 1997 10:15:58 SueS * Handle NULL pointer in DrvStretchBlt. * * Rev 1.10 06 Sep 1996 15:16:40 noelv * Updated NULL driver for 4.0 * * Rev 1.9 20 Aug 1996 11:04:26 noelv * Bugfix release from Frido 8-19-96 * * Rev 1.1 15 Aug 1996 11:39:42 frido * Added precompiled header. * * Rev 1.0 14 Aug 1996 17:16:30 frido * Initial revision. * * Rev 1.8 16 May 1996 15:01:40 bennyn * * Add PIXEL_ALIGN to allocoffscnmem() * * Rev 1.7 04 Apr 1996 13:20:28 noelv * No change. * * Rev 1.6 15 Mar 1996 09:40:00 andys * * Removed BITMASK setting from code * * Rev 1.5 13 Mar 1996 11:11:20 bennyn * Added device bitmap support * * Rev 1.4 07 Mar 1996 18:23:50 bennyn * * Removed read/modify/write on CONTROL reg * * Rev 1.3 05 Mar 1996 11:59:10 noelv * Frido version 19 * * Rev 1.1 20 Jan 1996 01:16:50 frido * * * Rev 1.5 10 Jan 1996 16:11:12 NOELV * Added NULL driver ability. * * Rev 1.4 18 Oct 1995 14:09:06 NOELV * * Fixed the mess I made of STRETCH.C I was writing to the BLT extents instea * * Rev 1.3 18 Oct 1995 12:10:26 NOELV * * Reworked register writes. * punted 16,24, and 32 bpp * * Rev 1.2 06 Oct 1995 13:50:26 bennyn * * Rev 1.1 22 Aug 1995 16:40:38 bennyn * * Rev 1.3 15 Aug 1995 11:27:28 bennyn * * Rev 1.2 07 Aug 1995 08:02:34 bennyn * * Rev 1.1 02 Aug 1995 12:13:04 bennyn * * Rev 1.0 11 Jul 1995 15:14:16 BENNYN * Initial revision. * **************************************************************************** ****************************************************************************/ /*----------------------------- INCLUDES ----------------------------------*/ #include "precomp.h" /*----------------------------- DEFINES -----------------------------------*/ //#define PUNTBRK //#define DBGBRK #define DBGDISP #define OPTION_1 //#define OPTION_2 //#define OPTION_3 #define X_INTERP_ENABLE 0x1 #define Y_INTERP_ENABLE 0x2 #define X_SHRINK_ENABLE 0x4 #define Y_SHRINK_ENABLE 0x8 #define _32K 32768 #define SF 0x10000L /*--------------------- STATIC FUNCTION PROTOTYPES ------------------------*/ /*--------------------------- ENUMERATIONS --------------------------------*/ /*----------------------------- TYPEDEFS ----------------------------------*/ typedef union _HOST_DATA { BYTE bData[4]; DWORD dwData; } HOST_DATA; /*-------------------------- STATIC VARIABLES -----------------------------*/ /*-------------------------- GLOBAL FUNCTIONS -----------------------------*/ /**************************************************************************** * FUNCTION NAME: AdjustSrcSize() * * DESCRIPTION: If the destination rectange is changed due to the clipping, * the source rectange size need to proportional change. * This routine handles the source size change calcualtion. * * RETURN: TRUE: Punt it. * * REVISION HISTORY: * 7/27/95 Benny Ng Initial version ****************************************************************************/ BOOL AdjustSrcSize(LONG dx, LONG dy, LONG origdx, LONG origdy, LONG dszX, LONG dszY, LONG origdszX, LONG origdszY, LONG *sszX, LONG *sszY, LONG *XsrcOff, LONG *YsrcOff) { LONG ratioX, ratioY; LONG ltemp; UINT orig_sszX, orig_sszY; BOOL bpuntit = FALSE; BOOL bStretchX = FALSE; BOOL bStretchY = FALSE; orig_sszX = *sszX; orig_sszY = *sszY; // ------------------------------------------------------- // Calculate the source to destination size ratio if (*sszX < origdszX) { ratioX = (origdszX * SF) / *sszX; bStretchX = TRUE; } else { ratioX = (*sszX * SF) / origdszX; }; if (*sszY < origdszY) { ratioY = (origdszY * SF) / *sszY; bStretchY = TRUE; } else { ratioY = (*sszY * SF) / origdszY; }; // ------------------------------------------------------- // Calculate the source X offset if (origdx != dx) { if (bStretchX) ltemp = ((dx - origdx) * SF) / ratioX; else ltemp = ((dx - origdx) * ratioX) / SF; *XsrcOff = ltemp; }; // Calculate the source X size change if (origdszX != dszX) { if (bStretchX) ltemp = ((origdszX - dszX) * SF) / ratioX; else ltemp = ((origdszX - dszX) * ratioX) / SF; *sszX = *sszX - ltemp; }; // ------------------------------------------------------- // Calculate the source Y offset if (origdy != dy) { if (bStretchY) ltemp = ((dy - origdy) * SF) / ratioY; else ltemp = ((dy - origdy) * ratioY) / SF; *YsrcOff = ltemp; }; // Calculate the source Y size change if (origdszY != dszY) { if (bStretchY) ltemp = ((origdszY - dszY) * SF) / ratioY; else ltemp = ((origdszY - dszY) * ratioY) / SF; *sszY = *sszY - ltemp; }; #ifdef DBGDISP DISPDBG((1, "AdjustSrcSize - bpuntit= %x, ratioX=%d, ratioY=%d\n", bpuntit, ratioX, ratioY)); DISPDBG((1, "dx=%d, dy=%d, origdx=%d, origdy=%d,\n", dx, dy, origdx, origdy)); DISPDBG((1, "dszX=%d, dszY=%d, origdszX=%d, origdszY=%d,\n", dszX, dszY, origdszX, origdszY)); DISPDBG((1, "*sszX=%d, *sszY=%d, orig_sszX=%d, orig_sszY=%d,\n", *sszX, *sszY, orig_sszX, orig_sszY)); DISPDBG((1, "*XsrcOff=%d, *YsrcOff=%d\n", *XsrcOff, *YsrcOff)); #endif #ifdef DBGBRK DbgBreakPoint(); #endif return(bpuntit); } /**************************************************************************** * FUNCTION NAME: bRectIntersect() * * DESCRIPTION: If 'prcl1' and 'prcl2' intersect, has a return value of * TRUE and returns the intersection in 'prclResult'. * If they don't intersect, has a return value of FALSE, * and 'prclResult' is undefined. * * RETURN: TRUE: Rectange intersect. * * REVISION HISTORY: * 8/01/95 Benny Ng Initial version \**************************************************************************/ BOOL bRectIntersect(RECTL* prcl1, RECTL* prcl2, RECTL* prclResult) { prclResult->left = max(prcl1->left, prcl2->left); prclResult->right = min(prcl1->right, prcl2->right); if (prclResult->left < prclResult->right) { prclResult->top = max(prcl1->top, prcl2->top); prclResult->bottom = min(prcl1->bottom, prcl2->bottom); if (prclResult->top < prclResult->bottom) return(TRUE); }; return(FALSE); } /**************************************************************************** * FUNCTION NAME: cRectIntersect() * * DESCRIPTION: This routine takes a list of rectangles from 'prclIn' * and clips them in-place to the rectangle 'prclClip'. * The input rectangles don't have to intersect 'prclClip'; * the return value will reflect the number of input rectangles * that did intersect, and the intersecting rectangles will * be densely packed. * * RETURN: TRUE: Rectange intersect. * * REVISION HISTORY: * 8/01/95 Benny Ng Initial version \**************************************************************************/ LONG cRectIntersect(RECTL* prclClip, RECTL* prclIn, // List of rectangles LONG c) // Can be zero { LONG cIntersections; RECTL* prclOut; cIntersections = 0; prclOut = prclIn; for (; c != 0; prclIn++, c--) { prclOut->left = max(prclIn->left, prclClip->left); prclOut->right = min(prclIn->right, prclClip->right); if (prclOut->left < prclOut->right) { prclOut->top = max(prclIn->top, prclClip->top); prclOut->bottom = min(prclIn->bottom, prclClip->bottom); if (prclOut->top < prclOut->bottom) { prclOut++; cIntersections++; }; }; } return(cIntersections); } /**************************************************************************** * FUNCTION NAME: Shrink() * * DESCRIPTION: This function calculates the parameters for shrink BLT * operation. * * REVISION HISTORY: * 7/18/95 Benny Ng Initial version ****************************************************************************/ VOID Shrink(PPDEV ppdev, LONG lSrc, LONG lDst, char chCoord, ULONG LnCntl, LONG *sShrinkInc) { LONG maj = 0; LONG min = 0; LONG accum = 0; // Set SHRINKINC value, // for y, SHRINKINC = ratio of src/dst // for x, SHRINKINC = ratio of src/dst if not interpolating // SHRINKINC = (ratio of src/dst minus one) if interpolating // low byte for x coordinate // high byte for y coordinate if (chCoord == 'X') { *sShrinkInc |= (lSrc / lDst); if (LnCntl & X_INTERP_ENABLE) sShrinkInc--; } else { *sShrinkInc |= ((lSrc / lDst) << 8); }; // Compute ACCUM_?, MAJ_? and MIN_? values // MAJ_? = width (for x) or height (for y) of destination // MIN_? = negative of the remainder of src/dst // ACCUM_? = MAJ_? - 1 - ( Src%Dst / (shrink factor + 1)) maj = lDst; min = -(lSrc % lDst); accum = maj - 1 - ((lSrc % lDst) / ((lSrc / lDst) + 1)) ; if (chCoord == 'X') { REQUIRE(3); LL16 (grMAJ_X, maj); LL16 (grMIN_X, min); LL16 (grACCUM_X, accum); } else { REQUIRE(3); LL16 (grMAJ_Y, maj); LL16 (grMIN_Y, min); LL16 (grACCUM_Y, accum); }; #ifdef DBGBRK DISPDBG((1, "DrvStretchBlt - shrink\n")); DbgBreakPoint(); #endif } /**************************************************************************** * FUNCTION NAME: Stretch() * * DESCRIPTION: This function calculates the parameters for stretch BLT * operation. * * REVISION HISTORY: * 7/18/95 Benny Ng Initial version ****************************************************************************/ VOID Stretch(PPDEV ppdev, LONG lSrc, LONG lDst, char chCoord, ULONG LnCntl) { LONG min = 0; LONG maj = 0; LONG accum = 0; // For interpolated stretches registers values differ from values for // replicated stretches if (((chCoord == 'X') && ((LnCntl & X_INTERP_ENABLE) == 0)) || ((chCoord == 'Y') && ((LnCntl & Y_INTERP_ENABLE) == 0))) { // Compute ACCUM_?, MAJ_? and MIN_? for replicated stretch // MAJ_? = width (for x) or height (for y) of destination // MIN_? = negative of width (for x) or height (for y) of source // ACCUM_? = MAJ_? - 1 - ( Dst%Src / (stretch factor + 1)) maj = lDst; min = -lSrc; accum = maj - 1 - ((lDst % lSrc) / ((lDst / lSrc) + 1)); } else { // Compute ACCUM_?, MAJ_? and MIN_? for interpolated stretch // Interpolated strecthes use bits 13 & 14 of ACCUM_? to determine // whether to use pixel A, 3/4 A + 1/4 B, 1/2 A + 1/2 B or // 1/4 A + 3/4 B. // To set DDA values appropriately there are three choices. // 1) Set MAJ_? to 32k and scale MIN_? to keep ratio approximately // correct // MAJ_? = 32k // MIN_? = (negative of ratio of src/dst) scaled up to 32k // ACCUM_? = MAJ_? - 1 - (1/2 * Absolute difference of MAJ and MIN) // // 2) Scale both src and dst appropriately such that the ratio of // src/dst is preserved exactly. // Note: In the following, the division is performed first thus // there is a possiblity of a rounding error which shows the // difference between options 1 & 2. // MAJ_? = (32k / dst) * dst // MIN_? = (32k / dst) * src // ACCUM_? = MAJ_? - 1 - (1/2 * Absolute difference of MAJ and MIN) // // 3) Scale both SRC and Dest in such a manner as to force the last // pixels output on a line to match the last source pixels rather // than the last source interpolated with the pixel past the end // of the line. Option 3 is used here. // NOTE: Options 1 and both oversample Src data and so will replicate // last pixel in X and interpolate past end of data in Y #ifdef OPTION_1 // Option 1 maj = _32K; min = -((_32K * lSrc) / lDst); #endif #ifdef OPTION_2 // Option 2 maj = ((_32K / lDst) * lDst); min = -((_32K / lDst) * lSrc); #else // Option 3 lDst *= 4; lSrc = lSrc * 4 - 3; maj = ((_32K / lDst) * lDst); min = -((_32K / lDst) * lSrc); #endif accum = maj - 1 - ((maj % -min) / (lDst/lSrc + 1)); }; if (chCoord == 'X') { REQUIRE(3); LL16 (grMAJ_X, maj); LL16 (grMIN_X, min); LL16 (grACCUM_X, accum); } else { REQUIRE(3); LL16 (grMAJ_Y, maj); LL16 (grMIN_Y, min); LL16 (grACCUM_Y, accum); }; #ifdef DBGBRK DISPDBG((1, "DrvStretchBlt - stretch\n")); DbgBreakPoint(); #endif } /**************************************************************************** * FUNCTION NAME: CopySrcToOffMem() * * DESCRIPTION: This function copies source data from host memory to * offscreen memory * * REVISION HISTORY: * 7/18/95 Benny Ng Initial version ****************************************************************************/ VOID CopySrcToOffMem(PPDEV ppdev, BYTE *pSrcScan0, LONG sDelta, LONG sszY, POFMHDL SrcHandle) { LONG DWcnt; LONG i, j, k; LONG cnt; BYTE *pSrcScan; PDWORD pSrcData; ULONG ultmp; LONG Ycord; HOST_DATA SrcData; pSrcScan = pSrcScan0; Ycord = SrcHandle->aligned_y; // Clear Laguna Command Control Register SWIZ_CNTL bit ppdev->grCONTROL = ppdev->grCONTROL & ~SWIZ_CNTL; LL16(grCONTROL, ppdev->grCONTROL); pSrcData = &SrcData.dwData; DWcnt = sDelta / sizeof(DWORD); // Setup the laguna registers for byte to byte BLT extents REQUIRE(8); LL16 (grBLTDEF, 0x1020); LL16 (grDRAWDEF, 0x00CC); LL16 (grOP1_opRDRAM.pt.X, 0); // LL (grOP0_opMRDRAM.pt.X, SrcHandle->aligned_x); // LL (grOP0_opMRDRAM.pt.Y, Ycord); LL_OP0_MONO (SrcHandle->aligned_x + ppdev->ptlOffset.x, Ycord + ppdev->ptlOffset.y); // LL (grMBLTEXT_EX.pt.X, sDelta); // LL (grMBLTEXT_EX.pt.Y, sszY); LL_MBLTEXT (sDelta, sszY); cnt = DWcnt; k = 0; for (i=0; i < sszY; i++) { // Pre-fill the 32-bits pattern with default values for (j=0; j < 4; j++) SrcData.bData[j] = 0; // Copy one screen line mask data from source to destination for (j=0; j < sDelta; j++) { SrcData.bData[k++] = *pSrcScan; pSrcScan++; if (k > 3) { REQUIRE(1); LL32 (grHOSTDATA[0], *pSrcData); k = 0; cnt--; }; // endif (k > 3) }; // endfor j // Check whether one screen line of data are written to the // HOSTDATA register. if (cnt == 0) { // Reset the row data count cnt = DWcnt; }; // endif (cnt == 0) }; // end for i #ifdef DBGBRK DISPDBG((0, "DrvStretchBlt-CopySrcToOffMem\n")); DbgBreakPoint(); #endif } /**************************************************************************** * FUNCTION NAME: bStretchDIB() * * DESCRIPTION: StretchBlt using integer math. Must be from one surface * to another surface of the same format. * * RETURN: TRUE: Punt it. * * REVISION HISTORY: * 7/27/95 Benny Ng Initial version ****************************************************************************/ BOOL bStretchDIB(SURFOBJ* psoSrc, SURFOBJ* psoMsk, PDEV* ppdev, VOID* pvDst, LONG lDeltaDst, RECTL* prclDst, VOID* pvSrc, LONG lDeltaSrc, RECTL* prclSrc, RECTL* prclClip) { LONG ltmp; ULONG ultmp; SIZEL reqsz; LONG bpp; BYTE *pSrcScan; RECTL rclRes; BOOL bNoBlt = FALSE; BOOL bpuntit = TRUE; POFMHDL SrcHandle = NULL; long drawdef = 0; long srcx = 0; ULONG LnCntl = 0; LONG sShrinkInc = 0; LONG XsrcOff = 0; LONG YsrcOff = 0; // Calculate the rectange start points and sizes: // LONG WidthDst = prclDst->right - prclDst->left; LONG HeightDst = prclDst->bottom - prclDst->top; LONG WidthSrc = prclSrc->right - prclSrc->left; LONG HeightSrc = prclSrc->bottom - prclSrc->top; LONG XDstStart = prclDst->left; LONG YDstStart = prclDst->top; LONG XSrcStart = prclSrc->left; LONG YSrcStart = prclSrc->top; // ------------------------------------------------------- // Calculate bytes per pixel bpp = ppdev->ulBitCount/8; // Get the informations from source and destination surface pSrcScan = pvSrc; if (psoMsk != NULL) { #ifdef DBGDISP DISPDBG((1, "DrvStretchBlt - HandleCase_1 mask pointer != NULL (punt it)\n")); #endif goto Punt_It; }; // ------------------------------------------------------- // Check whether source is from host or video memory if ((pSrcScan < ppdev->pjScreen) || (pSrcScan > (ppdev->pjScreen + ppdev->lTotalMem))) { #ifdef DBGDISP DISPDBG((1, "DrvStretchBlt - HandleCase_1 - src host\n")); #endif // Allocate the offscreen memory for the source if not enough offscreen // memory available punt it. reqsz.cx = psoSrc->sizlBitmap.cx; reqsz.cy = psoSrc->sizlBitmap.cy; if ((SrcHandle = AllocOffScnMem(ppdev, &reqsz, PIXEL_AlIGN, NULL)) == NULL) { goto Punt_It; }; //?? bbbbbbbbbb // Note: The following lines of code takes care the host data HW problem, // it punt back to GDI when host data size is 29 to 30 to DWORD. // if ((lDeltaSrc >= 116) && (lDeltaSrc <= 120)) { DISPDBG((1, "DrvStretchBlt - src host (punt it)\n")); goto Punt_It; }; //?? eeeeeeeeee // Copy the source data into allocated offscreen memory CopySrcToOffMem(ppdev, pSrcScan, lDeltaSrc, HeightSrc, SrcHandle); XSrcStart = SrcHandle->aligned_x / bpp; YSrcStart = SrcHandle->aligned_y; } else { #ifdef DBGDISP DISPDBG((1, "DrvStretchBlt - HandleCase_1 - src videow\n")); #endif if ((WidthSrc * bpp) > ppdev->lDeltaScreen) WidthSrc = ppdev->lDeltaScreen / bpp; ltmp = ppdev->lTotalMem / ppdev->lDeltaScreen; if (HeightSrc > ltmp) HeightSrc = ltmp; }; // ------------------------------------------------------- if (prclClip != NULL) { // Test for intersection of clipping rectangle and destination // rectangle. If they don't intersect, go on for stretch BLT. // For DC_RECT clipping we have a single clipping rectangle. // We create a new destination rectangle which is the intersection // between the old destination rectangle and the clipping rectangle. // Then we adjust our source rectangle accordingly. // if (!bRectIntersect(prclDst, prclClip, &rclRes)) { #ifdef DBGDISP DISPDBG((1, "DrvStretchBlt - HandleCase_1 - DC_RECT no intersect\n")); #endif goto Punt_It; }; // Adjust the source size bNoBlt = AdjustSrcSize(rclRes.left, rclRes.top, XDstStart, YDstStart, (rclRes.right - rclRes.left), (rclRes.bottom - rclRes.top), WidthDst, HeightDst, &WidthSrc, &HeightSrc, &XsrcOff, &YsrcOff); // Adjust the destination rectange size XDstStart = rclRes.left; YDstStart = rclRes.top; WidthDst = rclRes.right - rclRes.left; HeightDst = rclRes.bottom - rclRes.top; }; // endif (prclClip != NULL) if (!bNoBlt) { // ------------------------------------------------------- // Perform the shrink or stretch operation // Set the shrink or interpolate bit in LNCNTL if (WidthSrc >= WidthDst) { LnCntl |= X_SHRINK_ENABLE; Shrink(ppdev, WidthSrc, WidthDst, 'X', LnCntl, &sShrinkInc); } else { Stretch(ppdev, WidthSrc, WidthDst, 'X', LnCntl); }; if (HeightSrc >= HeightDst) { LnCntl |= Y_SHRINK_ENABLE; Shrink(ppdev, HeightSrc, HeightDst, 'Y', LnCntl, &sShrinkInc); } else { Stretch(ppdev, HeightSrc, HeightDst, 'Y', LnCntl); }; #ifdef DBGBRK DISPDBG((1, "DrvStretchBlt - bStretchDIB - before exec\n")); DbgBreakPoint(); #endif // ------------------------------------------------------- XSrcStart += XsrcOff; YSrcStart += YsrcOff; // LL (grOP1_opRDRAM.pt.X, XSrcStart); // LL (grOP1_opRDRAM.pt.Y, YSrcStart); REQUIRE(12); LL_OP1 (XSrcStart, YSrcStart); LL16 (grSHRINKINC, sShrinkInc); LL16 (grBLTDEF, 0x1010); LL16 (grDRAWDEF, 0x00CC); // Setup the shrink and interpolate bits in LNCNTL ultmp = LLDR_SZ (grLNCNTL.w); ultmp |= LnCntl; LL16 (grLNCNTL, ultmp); srcx = WidthSrc * bpp; LL16 (grSRCX, srcx); // LL (grOP0_opRDRAM.pt.X, XDstStart); // LL (grOP0_opRDRAM.pt.Y, YDstStart); LL_OP0 (XDstStart + ppdev->ptlOffset.x, YDstStart + ppdev->ptlOffset.y); // LL (grBLTEXTR_EX.pt.X, WidthDst); // LL (grBLTEXTR_EX.pt.Y, HeightDst); LL_BLTEXTR (WidthDst, HeightDst); #ifdef DBGBRK DISPDBG((1, "DrvStretchBlt - bStretchDIB - after exec\n")); DbgBreakPoint(); #endif bpuntit = FALSE; }; //endif (!bNoBlt) Punt_It: // ------------------------------------------------------- // Release the offscreen buffer if allocated if (SrcHandle != NULL) FreeOffScnMem(ppdev, SrcHandle); return(bpuntit); } /**************************************************************************** * FUNCTION NAME: HandleCase_1() * * DESCRIPTION: This function handle the case when * Both src and dst surface types are equal to STYPE_BITMAP, * both src and dst surface have same iBitmapFormat, * no color translation. * * RETURN: TRUE: Punt it. * * REVISION HISTORY: * 7/18/95 Benny Ng Initial version ****************************************************************************/ BOOL HandleCase_1(SURFOBJ* psoDst, SURFOBJ* psoSrc, SURFOBJ* psoMsk, CLIPOBJ* pco, RECTL* prclDst, RECTL* prclSrc, POINTL* pptlMsk, BOOL* bRet) { BOOL bpuntit = TRUE; PDEV* ppdev = (PDEV*) psoDst->dhpdev; BYTE iDComplexity; PRECTL prclClip; ENUMRECTS ce; BOOL bMore; LONG c; LONG i; *bRet = FALSE; // ------------------------------------------------------- // CHeck what kind of clipping is it? iDComplexity = (pco ? pco->iDComplexity : DC_TRIVIAL); switch (iDComplexity) { case DC_TRIVIAL: #ifdef DBGDISP DISPDBG((1, "DrvStretchBlt - HandleCase_1 - DC_TRIVIAL\n")); #endif bpuntit = bStretchDIB(psoSrc, psoMsk, ppdev, NULL, psoDst->lDelta, prclDst, psoSrc->pvScan0, psoSrc->lDelta, prclSrc, NULL); break; case DC_RECT: #ifdef DBGDISP DISPDBG((1, "DrvStretchBlt - HandleCase_1 - DC_RECT\n")); #endif // Get the clipping rectangle. prclClip = &pco->rclBounds; bpuntit = bStretchDIB(psoSrc, psoMsk, ppdev, NULL, psoDst->lDelta, prclDst, psoSrc->pvScan0, psoSrc->lDelta, prclSrc, prclClip); break; case DC_COMPLEX: #ifdef DBGDISP DISPDBG((1, "DrvStretchBlt - HandleCase_1 - DC_COMPLEX\n")); #endif bpuntit = FALSE; CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0); do { bMore = CLIPOBJ_bEnum(pco, sizeof(ce), (ULONG*) &ce); c = cRectIntersect(prclDst, ce.arcl, ce.c); if (c != 0) { for (i = 0; i < c; i++) { bpuntit = bStretchDIB(psoSrc, psoMsk, ppdev, NULL, psoDst->lDelta, prclDst, psoSrc->pvScan0, psoSrc->lDelta, prclSrc, &ce.arcl[i]); if (bpuntit) break; }; // enddo }; // endif } while ((bMore) && (!bpuntit)); break; default: break; }; // end switch (iDComplexity) // ------------------------------------------------------- // Check whether the operation was handled successfully if (!bpuntit) *bRet = TRUE; return (bpuntit); } /**************************************************************************** * FUNCTION NAME: DrvStretchBlt() * * DESCRIPTION: This function provides stretching bit-block transfer * capabilities for Laguna NT * * REVISION HISTORY: * 7/11/95 Benny Ng Initial version ****************************************************************************/ #define TSTFRIDO 1 BOOL DrvStretchBlt(SURFOBJ* psoDst, SURFOBJ* psoSrc, SURFOBJ* psoMsk, CLIPOBJ* pco, XLATEOBJ* pxlo, COLORADJUSTMENT* pca, POINTL* pptlHTOrg, RECTL* prclDst, RECTL* prclSrc, POINTL* pptlMsk, ULONG iMode) { BOOL bRet = TRUE; BOOL bPuntIt = TRUE; LONG HandleIt = 0; #if NULL_STRETCH { if (pointer_switch) return TRUE; } #endif #ifdef TSTFRIDO { PPDEV ppdev = (PPDEV) psoDst->dhpdev; SYNC_W_3D(ppdev); if (psoDst->iType == STYPE_DEVBITMAP) { PDSURF pdsurf = (PDSURF)psoDst->dhsurf; if ( pdsurf->pso ) { if ( !bCreateScreenFromDib(ppdev, pdsurf) ) { return EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMsk, iMode); }; }; ppdev->ptlOffset.x = pdsurf->ptl.x; ppdev->ptlOffset.y = pdsurf->ptl.y; } else { if (ppdev != NULL) ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0; else return(EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMsk, iMode)); }; ppdev = (PPDEV) psoSrc->dhpdev; if (psoSrc->iType == STYPE_DEVBITMAP) { PDSURF pdsurf = (PDSURF)psoSrc->dhsurf; if ( pdsurf->pso ) { if ( !bCreateScreenFromDib(ppdev, pdsurf) ) { return EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMsk, iMode); }; }; ppdev->ptlOffset.x = pdsurf->ptl.x; ppdev->ptlOffset.y = pdsurf->ptl.y; } else { if (ppdev != NULL) ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0; else return(EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMsk, iMode)); }; } #else { PPDEV ppdev = (PPDEV) psoDst->dhpdev; SYNC_W_3D(ppdev); } bRet = EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMsk, iMode); return(bRet); #endif #ifdef DBGDISP DISPDBG((1, "DrvStretchBlt - %d\n", iMode)); #endif if ((psoDst->iType == psoSrc->iType) && (psoDst->fjBitmap == psoSrc->fjBitmap) && (psoDst->fjBitmap == BMF_TOPDOWN)) { // If src and dst surface have same iBitmapFormat if (psoDst->iBitmapFormat == psoSrc->iBitmapFormat) { // Check for color translation if (pxlo == NULL) { HandleIt = 1; } else if ((pxlo != NULL) && (pxlo->iSrcType == pxlo->iDstType)) { switch (pxlo->flXlate) { case XO_TRIVIAL: case 0: HandleIt = 1; break; default: #ifdef DBGDISP DISPDBG((1, "DrvStretchBlt - pxlo->flXlate (punt it)\n")); #endif break; }; }; // endif (pxlo == NULL) }; // endif (src and dst surface have same iBitmapFormat) }; // endif (Both src and dst surface types are equal to STYPE_BITMAP) // Check whether we can handle this case, if yes call the case // handle routine to try to handle it. Otherwise punt it back to GDI if (HandleIt != 0) { if (HandleIt == 1) { bPuntIt = HandleCase_1(psoDst, psoSrc, psoMsk, pco, prclDst, prclSrc, pptlMsk, &bRet); } else if (HandleIt == 2) { }; }; // endif (HandleIt) // ------------------------------------------------------- // Punt It back to GDI to handle it if (bPuntIt) { DISPDBG((1, "DrvStretchBlt - punt it\n")); #ifdef PUNTBRK DbgBreakPoint(); #endif bRet = EngStretchBlt(psoDst, psoSrc, psoMsk, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMsk, iMode); }; return(bRet); }