|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: bitblt.c ! 3: * ! 4: * BitBlt ! 5: * ! 6: * Copyright (c) 1992 Microsoft Corporation ! 7: \**************************************************************************/ ! 8: #include "driver.h" ! 9: #include "bitblt.h" ! 10: ! 11: BOOL bConvertBrush(BRUSHINST *pbri); ! 12: VOID vCompiledBlt(PDEVSURF,LONG,LONG,PDEVSURF,LONG,LONG, ! 13: LONG,LONG,ULONG,BRUSHINST *,ULONG,ULONG,ULONG *,POINTL *); ! 14: ! 15: /******************************Public*Data*********************************\ ! 16: * ROP translation table ! 17: * ! 18: * Translates the usual ternary rop into A-vector notation. Each bit in ! 19: * this new notation corresponds to a term in a polynomial translation of ! 20: * the rop. ! 21: * ! 22: * Rop(D,S,P) = a + a D + a S + a P + a DS + a DP + a SP + a DSP ! 23: * 0 d s p ds dp sp dsp ! 24: * ! 25: * History: ! 26: * 24-Aug-1990 -by- Donald Sidoroff [donalds] ! 27: * Added it as a global table for the VGA driver. ! 28: \**************************************************************************/ ! 29: ! 30: BYTE gajRop[] = ! 31: { ! 32: 0x00, 0xff, 0xb2, 0x4d, 0xd4, 0x2b, 0x66, 0x99, ! 33: 0x90, 0x6f, 0x22, 0xdd, 0x44, 0xbb, 0xf6, 0x09, ! 34: 0xe8, 0x17, 0x5a, 0xa5, 0x3c, 0xc3, 0x8e, 0x71, ! 35: 0x78, 0x87, 0xca, 0x35, 0xac, 0x53, 0x1e, 0xe1, ! 36: 0xa0, 0x5f, 0x12, 0xed, 0x74, 0x8b, 0xc6, 0x39, ! 37: 0x30, 0xcf, 0x82, 0x7d, 0xe4, 0x1b, 0x56, 0xa9, ! 38: 0x48, 0xb7, 0xfa, 0x05, 0x9c, 0x63, 0x2e, 0xd1, ! 39: 0xd8, 0x27, 0x6a, 0x95, 0x0c, 0xf3, 0xbe, 0x41, ! 40: 0xc0, 0x3f, 0x72, 0x8d, 0x14, 0xeb, 0xa6, 0x59, ! 41: 0x50, 0xaf, 0xe2, 0x1d, 0x84, 0x7b, 0x36, 0xc9, ! 42: 0x28, 0xd7, 0x9a, 0x65, 0xfc, 0x03, 0x4e, 0xb1, ! 43: 0xb8, 0x47, 0x0a, 0xf5, 0x6c, 0x93, 0xde, 0x21, ! 44: 0x60, 0x9f, 0xd2, 0x2d, 0xb4, 0x4b, 0x06, 0xf9, ! 45: 0xf0, 0x0f, 0x42, 0xbd, 0x24, 0xdb, 0x96, 0x69, ! 46: 0x88, 0x77, 0x3a, 0xc5, 0x5c, 0xa3, 0xee, 0x11, ! 47: 0x18, 0xe7, 0xaa, 0x55, 0xcc, 0x33, 0x7e, 0x81, ! 48: 0x80, 0x7f, 0x32, 0xcd, 0x54, 0xab, 0xe6, 0x19, ! 49: 0x10, 0xef, 0xa2, 0x5d, 0xc4, 0x3b, 0x76, 0x89, ! 50: 0x68, 0x97, 0xda, 0x25, 0xbc, 0x43, 0x0e, 0xf1, ! 51: 0xf8, 0x07, 0x4a, 0xb5, 0x2c, 0xd3, 0x9e, 0x61, ! 52: 0x20, 0xdf, 0x92, 0x6d, 0xf4, 0x0b, 0x46, 0xb9, ! 53: 0xb0, 0x4f, 0x02, 0xfd, 0x64, 0x9b, 0xd6, 0x29, ! 54: 0xc8, 0x37, 0x7a, 0x85, 0x1c, 0xe3, 0xae, 0x51, ! 55: 0x58, 0xa7, 0xea, 0x15, 0x8c, 0x73, 0x3e, 0xc1, ! 56: 0x40, 0xbf, 0xf2, 0x0d, 0x94, 0x6b, 0x26, 0xd9, ! 57: 0xd0, 0x2f, 0x62, 0x9d, 0x04, 0xfb, 0xb6, 0x49, ! 58: 0xa8, 0x57, 0x1a, 0xe5, 0x7c, 0x83, 0xce, 0x31, ! 59: 0x38, 0xc7, 0x8a, 0x75, 0xec, 0x13, 0x5e, 0xa1, ! 60: 0xe0, 0x1f, 0x52, 0xad, 0x34, 0xcb, 0x86, 0x79, ! 61: 0x70, 0x8f, 0xc2, 0x3d, 0xa4, 0x5b, 0x16, 0xe9, ! 62: 0x08, 0xf7, 0xba, 0x45, 0xdc, 0x23, 0x6e, 0x91, ! 63: 0x98, 0x67, 0x2a, 0xd5, 0x4c, 0xb3, 0xfe, 0x01 ! 64: }; ! 65: ! 66: ! 67: /******************************Public*Data*********************************\ ! 68: * ROP to mix translation table ! 69: * ! 70: * Table to translate ternary raster ops to mixes (binary raster ops). Ternary ! 71: * raster ops that can't be translated to mixes are translated to 0 (0 is not ! 72: * a valid mix). ! 73: * ! 74: \**************************************************************************/ ! 75: ! 76: UCHAR jRop3ToMix[256] = { ! 77: R2_BLACK, 0, 0, 0, 0, R2_NOTMERGEPEN, 0, 0, ! 78: 0, 0, R2_MASKNOTPEN, 0, 0, 0, 0, R2_NOTCOPYPEN, ! 79: 0, 0, 0, 0, 0, 0, 0, 0, ! 80: 0, 0, 0, 0, 0, 0, 0, 0, ! 81: 0, 0, 0, 0, 0, 0, 0, 0, ! 82: 0, 0, 0, 0, 0, 0, 0, 0, ! 83: 0, 0, 0, 0, 0, 0, 0, 0, ! 84: 0, 0, 0, 0, 0, 0, 0, 0, ! 85: 0, 0, 0, 0, 0, 0, 0, 0, ! 86: 0, 0, 0, 0, 0, 0, 0, 0, ! 87: R2_MASKPENNOT, 0, 0, 0, 0, R2_NOT, 0, 0, ! 88: 0, 0, R2_XORPEN, 0, 0, 0, 0, R2_NOTMASKPEN, ! 89: 0, 0, 0, 0, 0, 0, 0, 0, ! 90: 0, 0, 0, 0, 0, 0, 0, 0, ! 91: 0, 0, 0, 0, 0, 0, 0, 0, ! 92: 0, 0, 0, 0, 0, 0, 0, 0, ! 93: 0, 0, 0, 0, 0, 0, 0, 0, ! 94: 0, 0, 0, 0, 0, 0, 0, 0, ! 95: 0, 0, 0, 0, 0, 0, 0, 0, ! 96: 0, 0, 0, 0, 0, 0, 0, 0, ! 97: R2_MASKPEN, 0, 0, 0, 0, R2_NOTXORPEN, 0, 0, ! 98: 0, 0, R2_NOP, 0, 0, 0, 0, R2_MERGENOTPEN, ! 99: 0, 0, 0, 0, 0, 0, 0, 0, ! 100: 0, 0, 0, 0, 0, 0, 0, 0, ! 101: 0, 0, 0, 0, 0, 0, 0, 0, ! 102: 0, 0, 0, 0, 0, 0, 0, 0, ! 103: 0, 0, 0, 0, 0, 0, 0, 0, ! 104: 0, 0, 0, 0, 0, 0, 0, 0, ! 105: 0, 0, 0, 0, 0, 0, 0, 0, ! 106: 0, 0, 0, 0, 0, 0, 0, 0, ! 107: R2_COPYPEN, 0, 0, 0, 0, R2_MERGEPENNOT, 0, 0, ! 108: 0, 0, R2_MERGEPEN, 0, 0, 0, 0, R2_WHITE ! 109: }; ! 110: ! 111: ! 112: /******************************Public*Routine******************************\ ! 113: * VOID DrvBitBlt(pso,pso,pso,pco,pxlo,prcl,pptl,pptl,pdbrush,pptl,rop4) ! 114: * ! 115: * Bitblt. ! 116: * ! 117: \**************************************************************************/ ! 118: ! 119: BOOL DrvBitBlt ! 120: ( ! 121: SURFOBJ *psoTrg, // Target surface ! 122: SURFOBJ *psoSrc, // Source surface ! 123: SURFOBJ *psoMask, // Mask ! 124: CLIPOBJ *pco, // Clip through this ! 125: XLATEOBJ *pxlo, // Color translation ! 126: RECTL *prclTrg, // Target offset and extent ! 127: POINTL *pptlSrc, // Source offset ! 128: POINTL *pptlMask, // Mask offset ! 129: BRUSHOBJ *pbo, // Pointer to brush object ! 130: POINTL *pptlBrush, // Brush offset ! 131: ROP4 rop4 // Raster operation ! 132: ) ! 133: { ! 134: BYTE jForeRop; // Foreground rop in A-vector notation ! 135: BYTE jBackRop; // Background rop in A-vector notation ! 136: BYTE jORedRops; // jForeRop | jBackRop ! 137: BRUSHINST bri; // Instance of a brush ! 138: BRUSHINST *pbri; // Pointer to a brush instance ! 139: ! 140: DEVSURF dsurfSrc; // For source if a DIB ! 141: PDEVSURF pdsurfTrg; // Pointer for target ! 142: PDEVSURF pdsurfSrc; // Pointer for source if present ! 143: ! 144: ULONG iSolidColor; // Solid color for solid brushes ! 145: BOOL bMore; // Clip continuation flag ! 146: ULONG ircl; // Clip enumeration rectangle index ! 147: RECT_ENUM bben; // Clip enumerator ! 148: ULONG *pulXlate; // Pointer to color xlate vector ! 149: BYTE jClipping; ! 150: MIX mix; // Mix, when solid fill performed ! 151: RECTL rclTemp; ! 152: ULONG ulBkColor; ! 153: ULONG ulFgColor; ! 154: PRECTL prcl; ! 155: POINTL ptlTemp; ! 156: UCHAR *pucDIB4ToVGAConvTables; ! 157: VOID (*pfnPatBlt)(PDEVSURF,ULONG,PRECTL,MIX, BRUSHINST *,PPOINTL); ! 158: ! 159: ! 160: // Let the engine handle the stuff we can't yet do. ! 161: if (psoSrc != (SURFOBJ *) NULL) { ! 162: if ((psoSrc->iBitmapFormat != BMF_1BPP) && ! 163: (psoSrc->iBitmapFormat != BMF_4BPP) && ! 164: (psoSrc->iBitmapFormat != BMF_8BPP)) { ! 165: ! 166: return(EngBitBlt(psoTrg,psoSrc,psoMask, ! 167: pco,pxlo,prclTrg,pptlSrc,pptlMask, ! 168: pbo,pptlBrush,rop4)); ! 169: ! 170: } else { ! 171: // We only handle SRCCOPY screen-to-screen blts right now ! 172: if ((psoSrc->dhsurf == psoTrg->dhsurf) && (rop4 != 0x0000CCCC)) { ! 173: ! 174: return(EngBitBlt(psoTrg,psoSrc,psoMask, ! 175: pco,pxlo,prclTrg,pptlSrc,pptlMask, ! 176: pbo,pptlBrush,rop4)); ! 177: } ! 178: } ! 179: } ! 180: ! 181: if ((rop4 & 0x000000FF) != ((rop4 >> 8) & 0x000000FF)) { ! 182: ! 183: return(EngBitBlt(psoTrg,psoSrc,psoMask, ! 184: pco,pxlo,prclTrg,pptlSrc,pptlMask, ! 185: pbo,pptlBrush,rop4)); ! 186: } ! 187: ! 188: // Get the target surface's pointer. The target must always be a device ! 189: // surface ! 190: ! 191: pdsurfTrg = (PDEVSURF) psoTrg->dhsurf; ! 192: ! 193: // Set up the clipping type ! 194: if (pco == (CLIPOBJ *) NULL) { ! 195: // No CLIPOBJ provided, so we don't have to worry about clipping ! 196: jClipping = DC_TRIVIAL; ! 197: } else { ! 198: // Use the CLIPOBJ-provided clipping ! 199: jClipping = pco->iDComplexity; ! 200: } ! 201: ! 202: ! 203: // Break the rops with the VGA as the destination surface into two classes, ! 204: // those that can call special case static code (currently: vTrgBlt(solid ! 205: // fills) and vAlignedSrcCopy (aligned srccopy blts)), and those that must ! 206: // call the compiled blt code ! 207: ! 208: if (pdsurfTrg->iFormat == BMF_PHYSDEVICE) { ! 209: ! 210: // Masked cases must be handled differently ! 211: ! 212: if ((rop4 & 0xFF) == ((rop4 >> 8) & 0xFF)) { ! 213: ! 214: // Special case static code for no-mask cases ! 215: ! 216: // Calculate mix from ROP if possible (not possible if it's truly a ! 217: // ternary rop or a real rop4, but we can treat all pure binary ! 218: // rops as mixes rather than rop4s) ! 219: mix = jRop3ToMix[rop4 & 0xFF]; ! 220: pbri = (BRUSHINST *)NULL; ! 221: ! 222: switch (mix) { ! 223: case R2_MASKNOTPEN: ! 224: case R2_NOTCOPYPEN: ! 225: case R2_XORPEN: ! 226: case R2_MASKPEN: ! 227: case R2_NOTXORPEN: ! 228: case R2_MERGENOTPEN: ! 229: case R2_COPYPEN: ! 230: case R2_MERGEPEN: ! 231: case R2_NOTMERGEPEN: ! 232: case R2_MASKPENNOT: ! 233: case R2_NOTMASKPEN: ! 234: case R2_MERGEPENNOT: ! 235: // vTrgBlt can only handle solid color fills ! 236: if (pbo->iSolidColor != 0xffffffff) ! 237: { ! 238: iSolidColor = pbo->iSolidColor; ! 239: } ! 240: else ! 241: { ! 242: // TrgBlt can only handle solid brushes, but let's ! 243: // see if we can use our special case pattern code. ! 244: // ! 245: pbri = (BRUSHINST *)pbo->pvRbrush; ! 246: if (pbri == (BRUSHINST *)NULL) ! 247: { ! 248: pbri = (BRUSHINST *)BRUSHOBJ_pvGetRbrush(pbo); ! 249: ! 250: if (pbri == (BRUSHINST *)NULL) ! 251: { ! 252: return(EngBitBlt(psoTrg, psoSrc, psoMask, pco, ! 253: pxlo, prclTrg, pptlSrc, pptlMask, pbo, ! 254: pptlBrush, rop4)); ! 255: } ! 256: } ! 257: ! 258: // We currently only do mono patterns. ! 259: ! 260: pfnPatBlt = vMonoPatBlt; ! 261: ! 262: if (pbri->usStyle != BRI_MONO_PATTERN) ! 263: pfnPatBlt = vClrPatBlt; ! 264: ! 265: // We only support non-8 wide brushes with R2_COPYPEN ! 266: ! 267: if ((mix != R2_COPYPEN) && (pbri->RealWidth != 8)) ! 268: break; ! 269: ! 270: } ! 271: // Rops that are implicit solid colors ! 272: ! 273: case R2_NOT: ! 274: case R2_WHITE: ! 275: case R2_BLACK: ! 276: // We can do a special-case solid fill ! 277: ! 278: switch(jClipping) { ! 279: case DC_TRIVIAL: ! 280: ! 281: // Just fill the rectangle with a solid color ! 282: if (pbri == (BRUSHINST *)NULL) ! 283: { ! 284: vTrgBlt(pdsurfTrg, 1, prclTrg, mix, ! 285: iSolidColor); ! 286: } ! 287: else ! 288: { ! 289: (*pfnPatBlt)(pdsurfTrg, 1, prclTrg, mix, ! 290: pbri, pptlBrush); ! 291: } ! 292: break; ! 293: ! 294: case DC_RECT: ! 295: ! 296: // Clip the solid fill to the clip rectangle ! 297: if (!DrvIntersectRect(&rclTemp, prclTrg, ! 298: &pco->rclBounds)) { ! 299: return(TRUE); ! 300: } ! 301: ! 302: // Fill the clipped rectangle ! 303: if (pbri == (BRUSHINST *)NULL) ! 304: { ! 305: vTrgBlt(pdsurfTrg, 1, &rclTemp, mix, ! 306: iSolidColor); ! 307: } ! 308: else ! 309: { ! 310: (*pfnPatBlt)(pdsurfTrg, 1, &rclTemp, mix, ! 311: pbri, pptlBrush); ! 312: } ! 313: break; ! 314: ! 315: case DC_COMPLEX: ! 316: ! 317: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, ! 318: CD_ANY, ENUM_RECT_LIMIT); ! 319: ! 320: do { ! 321: bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben), ! 322: (PVOID) &bben); ! 323: ! 324: for (ircl = 0; ircl < bben.c; ircl++) { ! 325: PRECTL prcl = &bben.arcl[ircl]; ! 326: ! 327: DrvIntersectRect(prcl,prcl,prclTrg); ! 328: ! 329: if (pbri == (BRUSHINST *)NULL) { ! 330: ! 331: vTrgBlt(pdsurfTrg, 1, prcl, mix, ! 332: iSolidColor); ! 333: } else { ! 334: ! 335: (*pfnPatBlt)(pdsurfTrg, 1, prcl, mix, ! 336: pbri, pptlBrush); ! 337: } ! 338: } ! 339: } while(bMore); ! 340: } ! 341: ! 342: case R2_NOP: ! 343: return TRUE; ! 344: ! 345: default: ! 346: break; ! 347: } ! 348: ! 349: // Not a special-case solid fill; see if it's a screen-to-screen ! 350: // SRCCOPY blt, another of our special cases ! 351: ! 352: if (rop4 == 0x0000CCCC) { ! 353: ! 354: // SRCCOPY blt ! 355: ! 356: if (psoSrc->dhsurf == psoTrg->dhsurf) { ! 357: ! 358: INT iCopyDir; ! 359: PFN_ScreenToScreenBlt pfn_Blt; ! 360: ! 361: // It's a screen-to-screen SRCCOPY; special-case it ! 362: ! 363: // Determine the direction in which the copy must proceed ! 364: // Note that although we could detect cases where the source ! 365: // and dest don't overlap and handle them top to bottom, all ! 366: // copy directions are equally fast, so there's no reason to go ! 367: // top to bottom except possibly that it looks better. But it ! 368: // also takes time to detect non-overlap, so I'm not doing it ! 369: ! 370: if (pptlSrc->y >= prclTrg->top) { ! 371: if (pptlSrc->x >= prclTrg->left) { ! 372: iCopyDir = CD_RIGHTDOWN; ! 373: } else { ! 374: iCopyDir = CD_LEFTDOWN; ! 375: } ! 376: } else { ! 377: if (pptlSrc->x >= prclTrg->left) { ! 378: iCopyDir = CD_RIGHTUP; ! 379: } else { ! 380: iCopyDir = CD_LEFTUP; ! 381: } ! 382: } ! 383: ! 384: // These values are expected by vAlignedSrcCopy ! 385: ! 386: switch(jClipping) { ! 387: ! 388: case DC_TRIVIAL: ! 389: // Just copy the rectangle ! 390: if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) { ! 391: vAlignedSrcCopy(pdsurfTrg, prclTrg, ! 392: pptlSrc, iCopyDir); ! 393: } else { ! 394: vNonAlignedSrcCopy(pdsurfTrg, prclTrg, ! 395: pptlSrc, iCopyDir); ! 396: } ! 397: break; ! 398: ! 399: case DC_RECT: ! 400: // Clip the solid fill to the clip rectangle ! 401: if (!DrvIntersectRect(&rclTemp, prclTrg, &pco->rclBounds)) ! 402: { ! 403: return(TRUE); ! 404: } ! 405: ! 406: // Adjust the source point for clipping too ! 407: ptlTemp.x = pptlSrc->x + rclTemp.left - prclTrg->left; ! 408: ptlTemp.y = pptlSrc->y + rclTemp.top - prclTrg->top; ! 409: ! 410: // Copy the clipped rectangle ! 411: if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) { ! 412: vAlignedSrcCopy(pdsurfTrg, &rclTemp, &ptlTemp, ! 413: iCopyDir); ! 414: } else { ! 415: vNonAlignedSrcCopy(pdsurfTrg, &rclTemp, &ptlTemp, ! 416: iCopyDir); ! 417: } ! 418: break; ! 419: ! 420: case DC_COMPLEX: ! 421: ! 422: if ((((prclTrg->left ^ pptlSrc->x) & 0x07) == 0)) { ! 423: pfn_Blt = vAlignedSrcCopy; ! 424: } else { ! 425: pfn_Blt = vNonAlignedSrcCopy; ! 426: } ! 427: ! 428: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, ! 429: iCopyDir, ENUM_RECT_LIMIT); ! 430: ! 431: do { ! 432: bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben), ! 433: (PVOID) &bben); ! 434: ! 435: for (ircl = 0; ircl < bben.c; ircl++) { ! 436: PRECTL prcl = &bben.arcl[ircl]; ! 437: ! 438: DrvIntersectRect(prcl,prcl,prclTrg); ! 439: ! 440: // Adjust the source point for clipping too ! 441: ptlTemp.x = pptlSrc->x + prcl->left - ! 442: prclTrg->left; ! 443: ptlTemp.y = pptlSrc->y + prcl->top - ! 444: prclTrg->top; ! 445: pfn_Blt(pdsurfTrg, prcl, ! 446: &ptlTemp, iCopyDir); ! 447: } ! 448: } while(bMore); ! 449: break; ! 450: } ! 451: ! 452: return TRUE; ! 453: ! 454: } else if ((psoSrc->iType == STYPE_BITMAP) && ! 455: (psoSrc->iBitmapFormat == BMF_4BPP) && ! 456: ((pxlo == NULL) || (pxlo->flXlate == XO_TRIVIAL))) { ! 457: ! 458: // Special case DIB4 to VGA copy if no translation ! 459: ! 460: pucDIB4ToVGAConvTables = ! 461: ((PDEVSURF) psoTrg->dhsurf)->ppdev-> ! 462: pucDIB4ToVGAConvTables; ! 463: ! 464: // Make just enough of a fake DEVSURF for the source so ! 465: // that the DIB to VGA code can work ! 466: ! 467: dsurfSrc.lNextScan = psoSrc->lDelta; ! 468: dsurfSrc.pvBitmapStart = psoSrc->pvScan0; ! 469: ! 470: // Clip as needed ! 471: ! 472: if ((pco == NULL) || (pco->iDComplexity == DC_TRIVIAL)) { ! 473: ! 474: // No clipping, just copy the DIB to the VGA ! 475: ! 476: vDIB2VGA((PDEVSURF) psoTrg->dhsurf, &dsurfSrc, ! 477: prclTrg, pptlSrc, pucDIB4ToVGAConvTables); ! 478: ! 479: } else if (pco->iDComplexity == DC_RECT) { ! 480: ! 481: // Clip the destination to the clip rectangle; we ! 482: // should never get a NULL result ! 483: if (DrvIntersectRect(&rclTemp, prclTrg, &pco->rclBounds)) { ! 484: ! 485: // Adjust the source point for clipping too ! 486: ptlTemp.x = pptlSrc->x + rclTemp.left - prclTrg->left; ! 487: ptlTemp.y = pptlSrc->y + rclTemp.top - prclTrg->top; ! 488: ! 489: // Blt the clipped rectangle ! 490: vDIB2VGA((PDEVSURF) psoTrg->dhsurf, &dsurfSrc, ! 491: &rclTemp, &ptlTemp, pucDIB4ToVGAConvTables); ! 492: } ! 493: return(TRUE); ! 494: ! 495: } else { // DC_COMPLEX: ! 496: ! 497: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, ! 498: CD_ANY, ENUM_RECT_LIMIT); ! 499: ! 500: do { ! 501: bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben), ! 502: (PVOID) &bben); ! 503: prcl = bben.arcl; ! 504: for (ircl = 0; ircl < bben.c; ircl++, prcl++) { ! 505: ! 506: // Clip the destination to the clip rectangle; ! 507: // we should never get a NULL result ! 508: ! 509: DrvIntersectRect(prcl,prcl,prclTrg); ! 510: ! 511: // Adjust the source point for clipping too ! 512: ptlTemp.x = pptlSrc->x + prcl->left - ! 513: prclTrg->left; ! 514: ptlTemp.y = pptlSrc->y + prcl->top - ! 515: prclTrg->top; ! 516: ! 517: // Blt the clipped rectangle ! 518: vDIB2VGA((PDEVSURF) psoTrg->dhsurf, ! 519: &dsurfSrc, prcl, &ptlTemp, ! 520: pucDIB4ToVGAConvTables); ! 521: } ! 522: } while(bMore); ! 523: } ! 524: ! 525: return(TRUE); ! 526: ! 527: } ! 528: } ! 529: } ! 530: } ! 531: ! 532: ! 533: // Couldn't be special cased. Set up to call the old kludged compiling code. ! 534: ! 535: ! 536: { ! 537: LONG xSrc; ! 538: LONG ySrc; ! 539: RECTL *prcl; ! 540: ! 541: ! 542: // Translate the rop from old notation into two A-vector rops ! 543: ! 544: jForeRop = gajRop[rop4 & 0xff]; ! 545: jBackRop = gajRop[(rop4 >> 8) & 0xff]; ! 546: jORedRops = jForeRop | jBackRop; ! 547: ! 548: ! 549: // Get the source surface if a source is needed. The source may be any of ! 550: // 1) the screen, 2) a device managed bitmap, 3) an engine bitmap ! 551: ! 552: if (jORedRops & AVEC_NEED_SOURCE) { ! 553: ! 554: if (psoSrc->dhsurf == (DHSURF) 0) { ! 555: // Source is an engine bitmap ! 556: #ifdef FIREWALLS ! 557: dsurfSrc.ident = 0x46525354; // "TSRF" ! 558: #endif ! 559: dsurfSrc.flSurf = DS_DIB; // Supporting a DIB ! 560: dsurfSrc.iFormat = (BYTE)psoSrc->iBitmapFormat; ! 561: dsurfSrc.sizlSurf = psoSrc->sizlBitmap; ! 562: dsurfSrc.lNextScan = psoSrc->lDelta; ! 563: dsurfSrc.pvScan0 = psoSrc->pvScan0; ! 564: dsurfSrc.pvBitmapStart = psoSrc->pvScan0; ! 565: dsurfSrc.pvConv = pdsurfTrg->pvConv; ! 566: ! 567: pdsurfSrc = &dsurfSrc; // Construct source into here ! 568: ! 569: } else { ! 570: // Source is a device format bitmap or the device itself ! 571: pdsurfSrc = (PDEVSURF) psoSrc->dhsurf; ! 572: } ! 573: } else { ! 574: pdsurfSrc = (PDEVSURF) NULL; // Assume no source ! 575: } ! 576: ! 577: ! 578: // If a brush is required, do what is necessary to get it. We might be ! 579: // able to just use the solid color accelerator, we might have to force it ! 580: // to be realized (which could fail). ! 581: ! 582: if (jORedRops & AVEC_NEED_PATTERN) { ! 583: ! 584: // See if there is a solid color accelerator for the brush. If so ! 585: // we can just pick it up and use it. ! 586: ! 587: if (pbo->iSolidColor != 0xffffffff) { ! 588: bri.usStyle = BRI_SOLID; ! 589: bri.fjAccel = ! 590: (BYTE)((pbo->iSolidColor & COLOR_BITS) | SOLID_BRUSH); ! 591: pbri = &bri; ! 592: } else { ! 593: // If there is no realization of the brush, we must force it ! 594: ! 595: if (pbo->pvRbrush == (PVOID)NULL) ! 596: { ! 597: pbri = (BRUSHINST *)BRUSHOBJ_pvGetRbrush(pbo); ! 598: ! 599: if (pbri == (BRUSHINST *)NULL) ! 600: { ! 601: return(EngBitBlt(psoTrg, psoSrc, psoMask, pco, pxlo, ! 602: prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, ! 603: rop4)); ! 604: } ! 605: } ! 606: else ! 607: { ! 608: pbri = (BRUSHINST *)pbo->pvRbrush; ! 609: } ! 610: ! 611: if (!bConvertBrush(pbri)) { ! 612: return(EngBitBlt(psoTrg, psoSrc, psoMask, pco, pxlo, ! 613: prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4)); ! 614: } ! 615: } ! 616: } ! 617: ! 618: ! 619: ! 620: // Determine if color translation is required. If so, then get the ! 621: // color translation vector. if no source is involved, then no ! 622: // xlateobj will have been passed. ! 623: ! 624: if ((jORedRops & AVEC_NEED_SOURCE) && ! 625: (pxlo != NULL) && ! 626: (pxlo->flXlate & XO_TABLE)) ! 627: { ! 628: pulXlate = pxlo->pulXlate; ! 629: ulFgColor = pulXlate[0] << 24; // Mono --> color translation ! 630: ulBkColor = pulXlate[1] << 24; ! 631: } ! 632: else ! 633: { ! 634: pulXlate = (PULONG) NULL; // No xlate vector ! 635: } ! 636: ! 637: ! 638: // Note: blts where VGA memory is both the source and the destination ! 639: // should never make it to this point; it's assumed that the VGA is the ! 640: // destination and the destination only ! 641: // BUGBUG this must be changed when we support DFBs, to make VGAs ! 642: // possibly neither source nor destination, and (maybe?) source but DFB ! 643: // dest ! 644: ! 645: // Perform blt with specified clipping. ! 646: // BUGBUG only top->bottom blts are currently supported ! 647: ! 648: switch(jClipping) { ! 649: ! 650: RECTL rclTemp; ! 651: ! 652: case DC_RECT: ! 653: if (!DrvIntersectRect(&rclTemp, prclTrg, &pco->rclBounds)) { ! 654: break; ! 655: } ! 656: ! 657: // Adjust the source (if any) accordingly ! 658: if (jORedRops & AVEC_NEED_SOURCE) { ! 659: pptlSrc->x += rclTemp.left - prclTrg->left; ! 660: pptlSrc->y += rclTemp.top - prclTrg->top; ! 661: } ! 662: ! 663: *prclTrg = rclTemp; ! 664: ! 665: case DC_TRIVIAL: ! 666: ! 667: // Cycle through all banks that the blt dest spans ! 668: ! 669: // If the proper bank for the top scan line of ! 670: // the blt dest isn't mapped in, map it in ! 671: if ((prclTrg->top < pdsurfTrg->rcl1WindowClip.top) || ! 672: (prclTrg->top >= pdsurfTrg->rcl1WindowClip.bottom)) { ! 673: ! 674: // Map in the bank containing the top line of the blt dest ! 675: pdsurfTrg->pfnBankControl(pdsurfTrg, ! 676: prclTrg->top, ! 677: JustifyTop); ! 678: } ! 679: ! 680: // Now draw the part of the rect that's in each bank ! 681: for (;;) { ! 682: ! 683: // Clip the blt dest to the bank ! 684: DrvIntersectRect(&rclTemp, prclTrg, ! 685: &pdsurfTrg->rcl1WindowClip); ! 686: ! 687: // Adjust the source (if any) accordingly ! 688: if (jORedRops & AVEC_NEED_SOURCE) { ! 689: xSrc = pptlSrc->x + rclTemp.left - prclTrg->left; ! 690: ySrc = pptlSrc->y + rclTemp.top - prclTrg->top; ! 691: } ! 692: ! 693: vCompiledBlt(pdsurfTrg, ! 694: rclTemp.left, ! 695: rclTemp.top, ! 696: pdsurfSrc, ! 697: xSrc, ! 698: ySrc, ! 699: rclTemp.right - rclTemp.left, ! 700: rclTemp.bottom - rclTemp.top, ! 701: rop4, ! 702: pbri, ! 703: ulBkColor, ! 704: ulFgColor, ! 705: pulXlate, ! 706: pptlBrush); ! 707: ! 708: // Done if this bank contains the last line of the blt ! 709: if (prclTrg->bottom <= ! 710: pdsurfTrg->rcl1WindowClip.bottom) { ! 711: break; ! 712: } ! 713: ! 714: // Map in the next bank ! 715: pdsurfTrg->pfnBankControl(pdsurfTrg, ! 716: pdsurfTrg->rcl1WindowClip.bottom, ! 717: JustifyTop); ! 718: } ! 719: ! 720: break; ! 721: ! 722: ! 723: case DC_COMPLEX: ! 724: ! 725: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, ENUM_RECT_LIMIT); ! 726: bMore = TRUE; ! 727: ! 728: do { ! 729: if (bMore) { ! 730: // Enumerate more clip rects ! 731: bMore = CLIPOBJ_bEnum(pco,(ULONG) sizeof(bben), ! 732: (PVOID) &bben); ! 733: } ! 734: ! 735: // Draw the portion of the blt dest that intersects each ! 736: // clip rect in turn ! 737: for (ircl = 0; ircl < bben.c; ircl++) { ! 738: ! 739: prcl = &bben.arcl[ircl]; ! 740: ! 741: // Find the intersection of the target rect and the ! 742: // current clip rect, then draw all banks of the ! 743: // clipped target rect, if it's not NULL ! 744: DrvIntersectRect(prcl, prcl, prclTrg); ! 745: ! 746: // Cycle through all banks that the blt dest spans ! 747: ! 748: // If the proper bank for the top scan line of ! 749: // the blt dest isn't mapped in, map it in ! 750: if ((prcl->top < ! 751: pdsurfTrg->rcl1WindowClip.top) || ! 752: (prcl->top >= ! 753: pdsurfTrg->rcl1WindowClip.bottom)) { ! 754: ! 755: // Map in the bank containing the top line of ! 756: // the blt dest ! 757: pdsurfTrg->pfnBankControl(pdsurfTrg, ! 758: prcl->top, ! 759: JustifyTop); ! 760: } ! 761: ! 762: // Now draw the part of the clipped rect that's in ! 763: // each bank ! 764: for (;;) { ! 765: ! 766: RECTL rclTemp; ! 767: ! 768: // Clip the blt dest to the bank ! 769: DrvIntersectRect(&rclTemp, prcl, ! 770: &pdsurfTrg->rcl1WindowClip); ! 771: ! 772: // Adjust the source (if any) accordingly ! 773: if (jORedRops & AVEC_NEED_SOURCE) { ! 774: xSrc = pptlSrc->x + rclTemp.left - ! 775: prclTrg->left; ! 776: ySrc = pptlSrc->y + rclTemp.top - ! 777: prclTrg->top; ! 778: } ! 779: ! 780: vCompiledBlt(pdsurfTrg, ! 781: rclTemp.left, ! 782: rclTemp.top, ! 783: pdsurfSrc, ! 784: xSrc, ! 785: ySrc, ! 786: rclTemp.right - rclTemp.left, ! 787: rclTemp.bottom - rclTemp.top, ! 788: rop4, ! 789: pbri, ! 790: ulBkColor, ! 791: ulFgColor, ! 792: pulXlate, ! 793: pptlBrush); ! 794: ! 795: // Done if this bank contains the last line of ! 796: // the blt ! 797: if (prcl->bottom <= ! 798: pdsurfTrg->rcl1WindowClip.bottom) { ! 799: break; ! 800: } ! 801: ! 802: // Map in the next bank ! 803: pdsurfTrg->pfnBankControl(pdsurfTrg, ! 804: pdsurfTrg->rcl1WindowClip.bottom, ! 805: JustifyTop); ! 806: } ! 807: } ! 808: } while(bMore); ! 809: ! 810: break; ! 811: ! 812: } // switch(jClipping); ! 813: ! 814: } ! 815: ! 816: return TRUE; ! 817: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.