|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: copybits.c ! 3: * ! 4: * DrvCopyBits ! 5: * ! 6: * Copyright (c) 1992 Microsoft Corporation ! 7: \**************************************************************************/ ! 8: #include "driver.h" ! 9: #include "bitblt.h" ! 10: ! 11: BOOL DrvCopyBits ! 12: ( ! 13: SURFOBJ *psoTrg, ! 14: SURFOBJ *psoSrc, ! 15: CLIPOBJ *pco, ! 16: XLATEOBJ *pxlo, ! 17: PRECTL prclTrg, ! 18: PPOINTL pptlSrc ! 19: ) ! 20: { ! 21: PDEVSURF pdsurf; // Pointer to a device surface ! 22: ! 23: LONG lDelta; // Delta to next scan of destination ! 24: PVOID pjDstScan0; // Pointer to scan 0 of destination DIB ! 25: ULONG *pulXlate; // Pointer to color xlate vector ! 26: ! 27: BOOL bMore; // Clip continuation flag ! 28: ULONG ircl; // Clip enumeration rectangle index ! 29: RECT_ENUM cben; // Clip enumerator ! 30: RECTL rclTemp; ! 31: PRECTL prcl; ! 32: POINTL ptlTemp; ! 33: DEVSURF dsurfSrc; ! 34: PDEVSURF pdsurfTrg; // Pointer for target ! 35: PDEVSURF pdsurfSrc; // Pointer for source if present ! 36: INT iCopyDir; ! 37: PFN_ScreenToScreenBlt pfn_Blt; ! 38: RECT_ENUM bben; // Clip enumerator ! 39: BYTE jClipping; ! 40: UCHAR *pucDIB4ToVGAConvTables; ! 41: ! 42: ! 43: // ASSERT(psoTrg != (SURFOBJ *) NULL, "DrvCopyBits: NULL Pointer for Target\n"); ! 44: // ASSERT(psoSrc != (SURFOBJ *) NULL, "DrvCopyBits: NULL Pointer for Source\n"); ! 45: // ASSERT(prclTrg != (RECTL *) NULL, "DrvCopyBits: NULL Pointer for Rect\n"); ! 46: // ASSERT(pptlSrc != (POINTL *) NULL, "DrvCopyBits: NULL Pointer for Point\n"); ! 47: ! 48: // ASSERT(((psoTrg->dhsurf != (DHSURF) 0) || (psoSrc->dhsurf != (DHSURF) 0)), ! 49: // "DrvCopyBits: No device surface involved\n"); ! 50: ! 51: // Check for device surface to device surface ! 52: ! 53: if ((psoTrg->iType == STYPE_DEVICE) && (psoSrc->iType == STYPE_DEVICE)) ! 54: { ! 55: pdsurfTrg = (PDEVSURF) psoTrg->dhsurf; ! 56: pdsurfSrc = (PDEVSURF) psoSrc->dhsurf; ! 57: ! 58: // It's a screen-to-screen aligned SRCCOPY; special-case it ! 59: ! 60: // Determine the direction in which the copy must proceed ! 61: // Note that although we could detect cases where the source ! 62: // and dest don't overlap and handle them top to bottom, all ! 63: // copy directions are equally fast, so there's no reason to go ! 64: // top to bottom except possibly that it looks better. But it ! 65: // also takes time to detect non-overlap, so I'm not doing it ! 66: ! 67: // Set up the clipping type ! 68: ! 69: if (pco == (CLIPOBJ *) NULL) ! 70: { ! 71: // No CLIPOBJ provided, so we don't have to worry about clipping ! 72: ! 73: jClipping = DC_TRIVIAL; ! 74: } ! 75: else ! 76: { ! 77: // Use the CLIPOBJ-provided clipping ! 78: ! 79: jClipping = pco->iDComplexity; ! 80: } ! 81: ! 82: ! 83: if (pptlSrc->y >= prclTrg->top) { ! 84: if (pptlSrc->x >= prclTrg->left) { ! 85: iCopyDir = CD_RIGHTDOWN; ! 86: } else { ! 87: iCopyDir = CD_LEFTDOWN; ! 88: } ! 89: } else { ! 90: if (pptlSrc->x >= prclTrg->left) { ! 91: iCopyDir = CD_RIGHTUP; ! 92: } else { ! 93: iCopyDir = CD_LEFTUP; ! 94: } ! 95: } ! 96: ! 97: // These values are expected by vAlignedSrcCopy ! 98: // ASSERT(((CD_RIGHTDOWN == 0) && (CD_LEFTDOWN == 1) && ! 99: // (CD_RIGHTUP == 2) && (CD_LEFTUP == 3)), ! 100: // "DrvBitBlt: Bad clip enumeration direction constants"); ! 101: ! 102: switch(jClipping) { ! 103: ! 104: case DC_TRIVIAL: ! 105: // Just copy the rectangle ! 106: if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) { ! 107: vAlignedSrcCopy(pdsurfTrg, prclTrg, ! 108: pptlSrc, iCopyDir); ! 109: } else { ! 110: vNonAlignedSrcCopy(pdsurfTrg, prclTrg, ! 111: pptlSrc, iCopyDir); ! 112: } ! 113: break; ! 114: ! 115: case DC_RECT: ! 116: // Clip the solid fill to the clip rectangle ! 117: if (!DrvIntersectRect(&rclTemp, prclTrg, ! 118: &pco->rclBounds)) { ! 119: // Nothing to draw; completely clipped ! 120: return TRUE; ! 121: } ! 122: ! 123: // Adjust the source point for clipping too ! 124: ptlTemp.x = pptlSrc->x + rclTemp.left - prclTrg->left; ! 125: ptlTemp.y = pptlSrc->y + rclTemp.top - prclTrg->top; ! 126: ! 127: // Copy the clipped rectangle ! 128: if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) { ! 129: vAlignedSrcCopy(pdsurfTrg, &rclTemp, &ptlTemp, ! 130: iCopyDir); ! 131: } else { ! 132: vNonAlignedSrcCopy(pdsurfTrg, &rclTemp, &ptlTemp, ! 133: iCopyDir); ! 134: } ! 135: break; ! 136: ! 137: case DC_COMPLEX: ! 138: ! 139: if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) { ! 140: pfn_Blt = vAlignedSrcCopy; ! 141: } else { ! 142: pfn_Blt = vNonAlignedSrcCopy; ! 143: } ! 144: ! 145: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, ! 146: iCopyDir, ENUM_RECT_LIMIT); ! 147: ! 148: do { ! 149: bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben), ! 150: (PVOID) &bben); ! 151: ! 152: prcl = bben.arcl; ! 153: for (ircl = 0; ircl < bben.c; ircl++, prcl++) { ! 154: ! 155: DrvIntersectRect(prcl,prcl,prclTrg); ! 156: // Adjust the source point for clipping too ! 157: ptlTemp.x = pptlSrc->x + prcl->left - ! 158: prclTrg->left; ! 159: ptlTemp.y = pptlSrc->y + prcl->top - ! 160: prclTrg->top; ! 161: pfn_Blt(pdsurfTrg, prcl, ! 162: &ptlTemp, iCopyDir); ! 163: ! 164: } ! 165: } while(bMore); ! 166: break; ! 167: } ! 168: return TRUE; ! 169: } ! 170: ! 171: if (psoSrc->iType == STYPE_BITMAP) { ! 172: ! 173: // DIB to screen ! 174: ! 175: switch(psoSrc->iBitmapFormat) ! 176: { ! 177: case BMF_4BPP: // special case compatible DIBs with no translation ! 178: ! 179: if ((pxlo == NULL) || (pxlo->flXlate == XO_TRIVIAL)) { ! 180: ! 181: pucDIB4ToVGAConvTables = ! 182: ((PDEVSURF) psoTrg->dhsurf)->ppdev-> ! 183: pucDIB4ToVGAConvTables; ! 184: ! 185: // Make just enough of a fake DEVSURF for the source so that ! 186: // the DIB to VGA code can work ! 187: ! 188: dsurfSrc.lNextScan = psoSrc->lDelta; ! 189: dsurfSrc.pvBitmapStart = psoSrc->pvScan0; ! 190: ! 191: // Clip as needed ! 192: ! 193: if ((pco == NULL) || (pco->iDComplexity == DC_TRIVIAL)) { ! 194: ! 195: // No clipping, just copy the DIB to the VGA ! 196: ! 197: vDIB2VGA((PDEVSURF) psoTrg->dhsurf, &dsurfSrc, prclTrg, ! 198: pptlSrc, pucDIB4ToVGAConvTables); ! 199: ! 200: } else if (pco->iDComplexity == DC_RECT) { ! 201: ! 202: // Clip the destination to the clip rectangle; we ! 203: // should never get a NULL result ! 204: if (DrvIntersectRect(&rclTemp, prclTrg, &pco->rclBounds)) { ! 205: ! 206: // Adjust the source point for clipping too ! 207: ptlTemp.x = pptlSrc->x + rclTemp.left - prclTrg->left; ! 208: ptlTemp.y = pptlSrc->y + rclTemp.top - prclTrg->top; ! 209: ! 210: // Blt the clipped rectangle ! 211: vDIB2VGA((PDEVSURF) psoTrg->dhsurf, &dsurfSrc, ! 212: &rclTemp, &ptlTemp, pucDIB4ToVGAConvTables); ! 213: } ! 214: return(TRUE); ! 215: ! 216: } else { // DC_COMPLEX: ! 217: ! 218: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, ! 219: CD_ANY, ENUM_RECT_LIMIT); ! 220: ! 221: do { ! 222: bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben), ! 223: (PVOID) &bben); ! 224: prcl = bben.arcl; ! 225: for (ircl = 0; ircl < bben.c; ircl++, prcl++) { ! 226: ! 227: // Clip the destination to the clip rectangle; ! 228: // we should never get a NULL result ! 229: DrvIntersectRect(prcl,prcl,prclTrg); ! 230: ! 231: // Adjust the source point for clipping too ! 232: ptlTemp.x = pptlSrc->x + prcl->left - ! 233: prclTrg->left; ! 234: ptlTemp.y = pptlSrc->y + prcl->top - ! 235: prclTrg->top; ! 236: ! 237: // Blt the clipped rectangle ! 238: vDIB2VGA((PDEVSURF) psoTrg->dhsurf, ! 239: &dsurfSrc, prcl, &ptlTemp, ! 240: pucDIB4ToVGAConvTables); ! 241: } ! 242: } while(bMore); ! 243: ! 244: } ! 245: ! 246: return(TRUE); ! 247: } ! 248: ! 249: case BMF_1BPP: ! 250: case BMF_8BPP: ! 251: ! 252: return(DrvBitBlt(psoTrg, ! 253: psoSrc, ! 254: (SURFOBJ *) NULL, ! 255: pco, ! 256: pxlo, ! 257: prclTrg, ! 258: pptlSrc, ! 259: (POINTL *) NULL, ! 260: (BRUSHOBJ *) NULL, ! 261: (POINTL *) NULL, ! 262: 0x0000cccc)); ! 263: ! 264: case BMF_8RLE: ! 265: case BMF_4RLE: ! 266: return(bRleBlt(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc)); ! 267: ! 268: } ! 269: } ! 270: else ! 271: { ! 272: // screen to DIB ! 273: ! 274: // ASSERT(psoTrg->iType == STYPE_BITMAP, "ERROR CopyBits got 2 DIBs"); ! 275: ! 276: if (psoTrg->iBitmapFormat == BMF_4BPP) ! 277: { ! 278: pdsurf = (PDEVSURF) psoSrc->dhsurf; ! 279: ! 280: // Get the data for the destination DIB. ! 281: ! 282: lDelta = psoTrg->lDelta; ! 283: pjDstScan0 = (PBYTE) psoTrg->pvScan0; ! 284: ! 285: // Setup for any color translation which may be needed !!! Is any needed at all? ! 286: ! 287: if (pxlo == NULL) ! 288: { ! 289: pulXlate = NULL; ! 290: } ! 291: else ! 292: { ! 293: if (pxlo->flXlate & XO_TABLE) ! 294: pulXlate = pxlo->pulXlate; ! 295: else ! 296: { ! 297: // ASSERT(pxlo->flXlate & XO_TRIVIAL, "DrvCopyBits: Hopelessly complex translation\n"); ! 298: pulXlate = (PULONG) NULL; ! 299: } ! 300: } ! 301: ! 302: // Set up for clip enumeration. ! 303: ! 304: if (pco != (CLIPOBJ *) NULL) ! 305: { ! 306: switch(pco->iDComplexity) ! 307: { ! 308: case DC_TRIVIAL: ! 309: bMore = FALSE; ! 310: cben.c = 1; ! 311: cben.arcl[0] = *prclTrg; // Use the target for clipping ! 312: break; ! 313: ! 314: case DC_RECT: ! 315: bMore = FALSE; ! 316: cben.c = 1; ! 317: cben.arcl[0] = pco->rclBounds; // Use the bounds for clipping ! 318: break; ! 319: ! 320: case DC_COMPLEX: ! 321: bMore = TRUE; ! 322: cben.c = 0; ! 323: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT); ! 324: break; ! 325: } ! 326: } ! 327: else ! 328: { ! 329: bMore = FALSE; ! 330: cben.c = 1; ! 331: cben.arcl[0] = *prclTrg; // Use the target for clipping ! 332: } ! 333: ! 334: // Call the VGA conversion routine, adjusted for each rectangle ! 335: ! 336: do ! 337: { ! 338: LONG xSrc; ! 339: LONG ySrc; ! 340: RECTL *prcl; ! 341: ! 342: if (bMore) ! 343: bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(cben), (PVOID) &cben); ! 344: ! 345: for (ircl = 0; ircl < cben.c; ircl++) ! 346: { ! 347: prcl = &cben.arcl[ircl]; ! 348: ! 349: xSrc = pptlSrc->x + prcl->left - prclTrg->left; ! 350: ySrc = pptlSrc->y + prcl->top - prclTrg->top; ! 351: ! 352: vConvertVGA2DIB(pdsurf, ! 353: xSrc, ! 354: ySrc, ! 355: pjDstScan0, ! 356: prcl->left, ! 357: prcl->top, ! 358: prcl->right - prcl->left, ! 359: prcl->bottom - prcl->top, ! 360: lDelta, ! 361: psoTrg->iBitmapFormat, ! 362: pulXlate); ! 363: } ! 364: } while (bMore); ! 365: ! 366: return(TRUE); ! 367: } ! 368: } ! 369: ! 370: // This is how we do any formats that we don't support in our inner loops. ! 371: ! 372: return(SimCopyBits(psoTrg, psoSrc, pco, pxlo, prclTrg, pptlSrc)); ! 373: } ! 374: ! 375: /******************************Public*Routine******************************\ ! 376: * SimCopyBits ! 377: * ! 378: * This function simulates CopyBits for the driver when the driver is asked ! 379: * to blt to formats it does not support. It converts any blt to be between ! 380: * the device's preferred format and the screen. ! 381: * ! 382: \**************************************************************************/ ! 383: ! 384: BOOL SimCopyBits ! 385: ( ! 386: SURFOBJ *psoTrg, ! 387: SURFOBJ *psoSrc, ! 388: CLIPOBJ *pco, ! 389: XLATEOBJ *pxlo, ! 390: PRECTL prclTrg, ! 391: PPOINTL pptlSrc ! 392: ) ! 393: { ! 394: HBITMAP hbmTmp; ! 395: SURFOBJ *psoTmp; ! 396: RECTL rclTmp; ! 397: SIZEL sizlTmp; ! 398: BOOL bReturn = FALSE; ! 399: static POINTL ptl00 = {0,0}; ! 400: ! 401: rclTmp.top = rclTmp.left = 0; ! 402: rclTmp.right = sizlTmp.cx = prclTrg->right - prclTrg->left; ! 403: rclTmp.bottom = sizlTmp.cy = prclTrg->bottom - prclTrg->top; ! 404: ! 405: // Create bitmap in our compatible format. ! 406: ! 407: hbmTmp = EngCreateBitmap(sizlTmp, sizlTmp.cx / 2, BMF_4BPP, 0, NULL); ! 408: ! 409: if (hbmTmp) ! 410: { ! 411: if ((psoTmp = EngLockSurface((HSURF)hbmTmp)) != NULL) ! 412: { ! 413: if (psoSrc->iType == STYPE_BITMAP) ! 414: { ! 415: // blting from DIB to screen ! 416: ! 417: if (EngCopyBits(psoTmp, psoSrc, NULL, pxlo, &rclTmp, pptlSrc)) ! 418: { ! 419: // Let DrvCopyBits do this easy case copy to screen. ! 420: ! 421: bReturn = DrvCopyBits(psoTrg, psoTmp, pco, NULL, prclTrg, &ptl00); ! 422: } ! 423: } ! 424: else ! 425: { ! 426: // blting from screen to DIB ! 427: ! 428: if (DrvCopyBits(psoTmp, psoSrc, NULL, NULL, &rclTmp, pptlSrc)) ! 429: { ! 430: // Let EngCopyBits copy between DIBS ! 431: ! 432: bReturn = EngCopyBits(psoTrg, psoTmp, pco, pxlo, prclTrg, &ptl00); ! 433: } ! 434: } ! 435: ! 436: EngUnlockSurface(psoTmp); ! 437: } ! 438: ! 439: EngDeleteSurface((HSURF)hbmTmp); ! 440: } ! 441: ! 442: return(bReturn); ! 443: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.