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