|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: Brush.c ! 3: * ! 4: * Brush support. ! 5: * ! 6: * Copyright (c) 1992-1993 Microsoft Corporation ! 7: * ! 8: \**************************************************************************/ ! 9: ! 10: #include "driver.h" ! 11: ! 12: /**************************************************************************** ! 13: * DrvRealizeBrush ! 14: ***************************************************************************/ ! 15: ! 16: BOOL DrvRealizeBrush( ! 17: BRUSHOBJ* pbo, ! 18: SURFOBJ* psoTarget, ! 19: SURFOBJ* psoPattern, ! 20: SURFOBJ* psoMask, ! 21: XLATEOBJ* pxlo, ! 22: ULONG iHatch) ! 23: { ! 24: RBRUSH* prb; // Pointer to where realization goes ! 25: ULONG* pulSrc; // Temporary pointer ! 26: ULONG* pulDst; // Temporary pointer ! 27: BYTE* pjSrc; ! 28: BYTE* pjDst; ! 29: ULONG* pulRBits; // Points to RBRUSH pattern bits ! 30: BYTE jBkColor; ! 31: BYTE jFgColor; ! 32: LONG i; ! 33: LONG j; ! 34: ! 35: PPDEV ppdev = (PPDEV) psoTarget->dhsurf; ! 36: ! 37: // For now, we only accelerate patterns using the latches, and we ! 38: // sometimes need offscreen memory as a temporary work space to ! 39: // initialize the latches for 2-color patterns: ! 40: ! 41: if ((ppdev->fl & (DRIVER_PLANAR_CAPABLE | DRIVER_HAS_OFFSCREEN)) != ! 42: (DRIVER_PLANAR_CAPABLE | DRIVER_HAS_OFFSCREEN) ) ! 43: { ! 44: return(FALSE); ! 45: } ! 46: ! 47: // See if it's a default hatch brush: ! 48: ! 49: if (iHatch < HS_DDI_MAX) ! 50: { ! 51: DISPDBG((1, "\n RBrush: Default")); ! 52: ! 53: prb = BRUSHOBJ_pvAllocRbrush(pbo, sizeof(RBRUSH)); ! 54: if (prb == NULL) ! 55: return(FALSE); ! 56: ! 57: prb->xBrush = 0; ! 58: prb->ulBkColor = (pxlo->pulXlate[0] & 0xff); ! 59: prb->ulFgColor = (pxlo->pulXlate[1] & 0xff); ! 60: ! 61: if (prb->ulFgColor == 0xff && prb->ulBkColor == 0x00) ! 62: { ! 63: prb->fl = RBRUSH_BLACKWHITE; ! 64: memcpy(&prb->aulPattern[0], ! 65: &gaaulPlanarPat[iHatch][0], ! 66: 8 * sizeof(DWORD)); ! 67: } ! 68: else if (prb->ulFgColor == 0x00 && prb->ulBkColor == 0xff) ! 69: { ! 70: // We have to invert the brush: ! 71: ! 72: prb->fl = RBRUSH_BLACKWHITE; ! 73: for (i = 0; i < 8; i++) ! 74: { ! 75: prb->aulPattern[i] = ~gaaulPlanarPat[iHatch][i]; ! 76: } ! 77: } ! 78: else ! 79: { ! 80: prb->fl = RBRUSH_2COLOR; ! 81: memmove(&prb->aulPattern[0], &gaaulPlanarPat[iHatch][0], 32); ! 82: } ! 83: ! 84: return(TRUE); ! 85: } ! 86: ! 87: // We only accelerate 8x8 patterns: ! 88: ! 89: if (psoPattern->sizlBitmap.cx != 8 || psoPattern->sizlBitmap.cy != 8) ! 90: return(FALSE); ! 91: ! 92: // We only implement n-color patterns on devices that have multiple ! 93: // or separate read/write banks: ! 94: ! 95: if (ppdev->vbtPlanarType == VideoBanked1RW) ! 96: return(FALSE); ! 97: ! 98: // We also only handle 1bpp, 4bpp and 8bpp patterns: ! 99: ! 100: if (psoPattern->iBitmapFormat > BMF_8BPP) ! 101: return(FALSE); ! 102: ! 103: // At this point, we're definitely going to realize the brush: ! 104: ! 105: prb = BRUSHOBJ_pvAllocRbrush(pbo, sizeof(RBRUSH)); ! 106: if (prb == NULL) ! 107: return(FALSE); ! 108: ! 109: pulRBits = &prb->aulPattern[0]; ! 110: ! 111: DISPDBG((1, "\n RBrush: ")); ! 112: ! 113: // If 8bpp or 4bpp, copy the bitmap to our local buffer: ! 114: ! 115: if (psoPattern->iBitmapFormat == BMF_1BPP) ! 116: { ! 117: ULONG ulFlippedGlyph; ! 118: ! 119: DISPDBG((1, "1bpp ")); ! 120: ! 121: // First, convert the bits to our desired format: ! 122: ! 123: pjSrc = psoPattern->pvScan0; ! 124: pulDst = pulRBits; ! 125: for (i = 8; i > 0; i--) ! 126: { ! 127: // We want to take the byte with bits 76543210 and convert it ! 128: // to the word 4567012301234567. The pjGlyphFlipTable gives ! 129: // us 45670123 from 76543210. ! 130: ! 131: ulFlippedGlyph = (ULONG) ppdev->pjGlyphFlipTable[*pjSrc]; ! 132: *pulDst = (ulFlippedGlyph << 8) | ((ulFlippedGlyph & 15) << 4) | ! 133: (ulFlippedGlyph >> 4); ! 134: ! 135: pulDst++; ! 136: pjSrc += psoPattern->lDelta; ! 137: } ! 138: ! 139: // Now initialize the rest of the RBrush fields: ! 140: ! 141: prb->xBrush = 0; ! 142: prb->ulBkColor = (pxlo->pulXlate[0] & 0xff); ! 143: prb->ulFgColor = (pxlo->pulXlate[1] & 0xff); ! 144: ! 145: if (prb->ulFgColor == 0xff && prb->ulBkColor == 0x00) ! 146: { ! 147: prb->fl = RBRUSH_BLACKWHITE; ! 148: } ! 149: else if (prb->ulFgColor == 0x00 && prb->ulBkColor == 0xff) ! 150: { ! 151: // We have to invert the brush: ! 152: ! 153: prb->fl = RBRUSH_BLACKWHITE; ! 154: for (i = 0; i < 8; i++) ! 155: { ! 156: prb->aulPattern[i] = ~prb->aulPattern[i]; ! 157: } ! 158: } ! 159: else ! 160: { ! 161: prb->fl = RBRUSH_2COLOR; ! 162: } ! 163: ! 164: return(TRUE); ! 165: } ! 166: else if (psoPattern->iBitmapFormat == BMF_8BPP) ! 167: { ! 168: ! 169: if (pxlo == NULL || pxlo->flXlate & XO_TRIVIAL) ! 170: { ! 171: pulSrc = psoPattern->pvScan0; ! 172: pulDst = pulRBits; ! 173: ! 174: DISPDBG((1, "8bpp noxlate ")); ! 175: ! 176: // 8bpp no translate case: ! 177: ! 178: for (i = 4; i > 0; i--) ! 179: { ! 180: *(pulDst) = *(pulSrc); ! 181: *(pulDst + 1) = *(pulSrc + 1); ! 182: pulSrc = (ULONG*) ((BYTE*) pulSrc + psoPattern->lDelta); ! 183: ! 184: *(pulDst + 2) = *(pulSrc); ! 185: *(pulDst + 3) = *(pulSrc + 1); ! 186: ! 187: pulSrc = (ULONG*) ((BYTE*) pulSrc + psoPattern->lDelta); ! 188: pulDst += 4; ! 189: } ! 190: } ! 191: else ! 192: { ! 193: pjSrc = (BYTE*) psoPattern->pvScan0; ! 194: pjDst = (BYTE*) pulRBits; ! 195: ! 196: DISPDBG((1, "8bpp xlate ")); ! 197: ! 198: // 8bpp translate case: ! 199: ! 200: for (i = 8; i > 0; i--) ! 201: { ! 202: for (j = 8; j > 0; j--) ! 203: { ! 204: *pjDst++ = (BYTE) pxlo->pulXlate[*pjSrc++]; ! 205: } ! 206: ! 207: pjSrc += psoPattern->lDelta - 8; ! 208: } ! 209: } ! 210: } ! 211: else ! 212: { ! 213: DISPDBG((1, "4bpp xlate ")); ! 214: ! 215: ASSERTVGA(psoPattern->iBitmapFormat == BMF_4BPP, "Extra case added?"); ! 216: ! 217: // 4bpp case: ! 218: ! 219: pjSrc = (BYTE*) psoPattern->pvScan0; ! 220: pjDst = (BYTE*) pulRBits; ! 221: ! 222: for (i = 8; i > 0; i--) ! 223: { ! 224: // Inner loop is repeated only 4 times because each loop handles ! 225: // 2 pixels: ! 226: ! 227: for (j = 4; j > 0; j--) ! 228: { ! 229: *pjDst++ = (BYTE) pxlo->pulXlate[*pjSrc >> 4]; ! 230: *pjDst++ = (BYTE) pxlo->pulXlate[*pjSrc & 15]; ! 231: pjSrc++; ! 232: } ! 233: ! 234: pjSrc += psoPattern->lDelta - 4; ! 235: } ! 236: } ! 237: ! 238: // We want to check if the 4bpp or 8bpp patterns are actually ! 239: // only two colors: ! 240: ! 241: if (b2ColorBrush(pulRBits, &jFgColor, &jBkColor)) ! 242: { ! 243: DISPDBG((1, "2 color ")); ! 244: ! 245: // ??? We could actually also handle this case even if we have only ! 246: // 1 r/w window in planar format: ! 247: ! 248: prb->xBrush = 0; ! 249: prb->ulBkColor = (ULONG) jBkColor; ! 250: prb->ulFgColor = (ULONG) jFgColor; ! 251: prb->fl = RBRUSH_2COLOR; ! 252: ! 253: if (jFgColor == 0x00 && jBkColor == 0xff) ! 254: { ! 255: // Monochrome brushes always have to have the '0' bits ! 256: // as black and the '1' bits as white, so we'll have to ! 257: // invert the 1bpp pattern: ! 258: ! 259: prb->fl = RBRUSH_BLACKWHITE; ! 260: for (i = 0; i < 8; i++) ! 261: { ! 262: prb->aulPattern[i] = ~prb->aulPattern[i]; ! 263: } ! 264: } ! 265: ! 266: return(TRUE); ! 267: } ! 268: ! 269: // For n-color brushes, we maintain a brush cache in offscreen memory. ! 270: // If the DRIVER_USE_OFFSCREEN flag isn't set (i.e., the offscreen ! 271: // memory isn't being refreshed), the cache is pretty useless. In that ! 272: // case, we simply disable n-color patterns: ! 273: ! 274: if ((ppdev->fl & DRIVER_USE_OFFSCREEN) == 0) ! 275: { ! 276: return(FALSE); ! 277: } ! 278: ! 279: prb->fl = RBRUSH_NCOLOR; ! 280: prb->cy = 8; ! 281: prb->cyLog2 = 3; ! 282: ! 283: // xBrush is the brush alignment for the cached brush, and this value ! 284: // will get compared to (pptlBrush->x & 7) to see if the cache brush ! 285: // is correctly aligned with the brush requested. Since it will never ! 286: // match with -1, the brush will be correctly aligned and placed in ! 287: // the cache (which, of course, is what we want to finish our ! 288: // initialization): ! 289: ! 290: prb->xBrush = -1; ! 291: ! 292: // Copy those bitmap bits: ! 293: ! 294: // See if pattern is really only 4 scans long: ! 295: ! 296: if (pulRBits[0] == pulRBits[8] && pulRBits[1] == pulRBits[9] && ! 297: pulRBits[2] == pulRBits[10] && pulRBits[3] == pulRBits[11] && ! 298: pulRBits[4] == pulRBits[12] && pulRBits[5] == pulRBits[13] && ! 299: pulRBits[6] == pulRBits[14] && pulRBits[7] == pulRBits[15]) ! 300: { ! 301: prb->cy = 4; ! 302: prb->cyLog2 = 2; ! 303: ! 304: // See if pattern is really only 2 scans long: ! 305: ! 306: if (pulRBits[0] == pulRBits[4] && pulRBits[1] == pulRBits[5] && ! 307: pulRBits[2] == pulRBits[6] && pulRBits[3] == pulRBits[7]) ! 308: { ! 309: DISPDBG((1, "cy = 2 ")); ! 310: ! 311: prb->cy = 2; ! 312: prb->cyLog2 = 1; ! 313: } ! 314: else ! 315: { ! 316: DISPDBG((1, "cy = 4 ")); ! 317: } ! 318: } ! 319: ! 320: // See if pattern is really only 4 pels wide: ! 321: ! 322: pulDst = pulRBits; ! 323: for (i = prb->cy / 2; i > 0; i--) ! 324: { ! 325: if (*(pulDst ) != *(pulDst + 1) || ! 326: *(pulDst + 2) != *(pulDst + 3)) ! 327: goto done_this_realize_brush_stuff; ! 328: ! 329: pulDst += 4; ! 330: } ! 331: ! 332: DISPDBG((1, "4pels wide")); ! 333: ! 334: prb->fl |= RBRUSH_4PELS_WIDE; ! 335: ! 336: done_this_realize_brush_stuff: ! 337: ! 338: return(TRUE); ! 339: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.