|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: brush.c ! 3: * ! 4: * Contains the brush realization and dithering code. ! 5: * ! 6: * Copyright (c) 1992 Microsoft Corporation ! 7: \**************************************************************************/ ! 8: #include "driver.h" ! 9: ! 10: #define OBR_REALIZED 1 ! 11: #define OBR_4BPP 2 ! 12: ! 13: // aulDefBitMapping is used to translate packed pel into Planar ! 14: ! 15: extern ULONG aulDefBitMapping[8]; ! 16: extern ULONG gRealizedBrushHeight[HS_DDI_MAX*2]; ! 17: extern BYTE gaajRealizedPat[HS_DDI_MAX][32]; ! 18: ! 19: // Asm routines ! 20: ! 21: ULONG CountColors(VOID *, ULONG, WORD *, DWORD); ! 22: BOOL bQuickPattern(BYTE *, ULONG); ! 23: BOOL bShrinkPattern(BYTE *, ULONG); ! 24: ! 25: VOID vMono16Wide(DWORD *, DWORD *, DWORD); ! 26: VOID vMono8Wide(DWORD *, DWORD *, DWORD); ! 27: VOID vMono4Wide(DWORD *, DWORD *, DWORD); ! 28: VOID vMono2Wide(DWORD *, DWORD *, DWORD); ! 29: VOID vBrush2ColorToMono(BYTE *, BYTE *, DWORD, DWORD, BYTE); ! 30: VOID vConvert4BppToPlanar(BYTE *, BYTE *, DWORD, DWORD *); ! 31: VOID vConvert8BppToPlanar(BYTE *, BYTE *, DWORD, DWORD *); ! 32: VOID vCopyOrgBrush(BYTE *pDest, BYTE *pSrc, LONG lScan, XLATEOBJ *pxlo); ! 33: VOID vCreatePlaneMasks(BYTE *, BYTE *); ! 34: SURFOBJ *DrvConvertBrush(SURFOBJ *psoPattern, HBITMAP *phbmTmp, XLATEOBJ *pxlo, ! 35: ULONG cx, ULONG cy); ! 36: ! 37: typedef VOID (*PFNV)(); ! 38: ! 39: /******************************Public*Routine******************************\ ! 40: * DrvRealizeBrush ! 41: * ! 42: * ! 43: \**************************************************************************/ ! 44: ! 45: BOOL DrvRealizeBrush( ! 46: BRUSHOBJ *pbo, ! 47: SURFOBJ *psoTarget, ! 48: SURFOBJ *psoPattern, ! 49: SURFOBJ *psoMask, ! 50: XLATEOBJ *pxlo, ! 51: ULONG iHatch) ! 52: { ! 53: ULONG cx; // Height of pattern surface ! 54: ULONG cy; // Width of pattern surface ! 55: LONG cbScan; // Width in bytes of one scan ! 56: PVOID pvBits; // Source bits ! 57: ULONG *pulXlate; // Color translation ! 58: HBITMAP hbmTmp; // Temp bmp handle for brush conversion ! 59: BRUSHINST *pbri; // pointer to where realization goes ! 60: BYTE jBkColor, jFgColor; // local copies of mono attributes ! 61: PFNV pfnConvert; // function pointer to mono conversion ! 62: BYTE jColors[2]; // place holder for special color->mono ! 63: // conversion. ! 64: BOOL bConversion = FALSE; // True if we converted to 4bpp ! 65: ! 66: cx = psoPattern->sizlBitmap.cx; ! 67: cy = psoPattern->sizlBitmap.cy; ! 68: ! 69: if ((cy != 8) || (cx > 16)) ! 70: { ! 71: return(FALSE); ! 72: } ! 73: ! 74: pbri = BRUSHOBJ_pvAllocRbrush(pbo,sizeof(BRUSHINST)); ! 75: if (pbri == (BRUSHINST *)NULL) ! 76: return(FALSE); ! 77: ! 78: pbri->RealWidth = (BYTE)cx; ! 79: ! 80: switch (psoPattern->iBitmapFormat) ! 81: { ! 82: case BMF_1BPP: ! 83: case BMF_4BPP: ! 84: case BMF_8BPP: ! 85: break; ! 86: ! 87: default: ! 88: if ((cx != 8) && (cx != 16)) ! 89: return(FALSE); ! 90: ! 91: // Convert to 4bpp ! 92: ! 93: psoPattern = DrvConvertBrush(psoPattern, &hbmTmp, pxlo, cx, cy); ! 94: if (psoPattern == (SURFOBJ *)NULL) ! 95: return(FALSE); ! 96: ! 97: bConversion = TRUE; ! 98: break; ! 99: } ! 100: ! 101: // ! 102: // Setup the pointer to the bits, and the scan-to-scan advance direction. ! 103: // ! 104: cbScan = psoPattern->lDelta; ! 105: pvBits = psoPattern->pvScan0; ! 106: ! 107: // ! 108: // If this is a hatch brush, we already have it in realized form. ! 109: // ! 110: if ((iHatch < HS_DDI_MAX) && (psoPattern->iBitmapFormat == BMF_1BPP)) ! 111: { ! 112: pbri->usStyle = BRI_MONO_PATTERN; ! 113: pbri->fjAccel = 0; ! 114: pbri->Width = 16; ! 115: pbri->Height = gRealizedBrushHeight[iHatch*2]; ! 116: pbri->YShiftValue = (BYTE)gRealizedBrushHeight[(iHatch*2)+1]; ! 117: pbri->pPattern = (BYTE *)&(gaajRealizedPat[iHatch]); ! 118: pbri->jBkColor = (BYTE)pxlo->pulXlate[0]; ! 119: pbri->jFgColor = (BYTE)pxlo->pulXlate[1]; ! 120: pbri->jOldBrushRealized = 0; ! 121: ! 122: return(TRUE); ! 123: } ! 124: ! 125: if (psoPattern->iBitmapFormat == BMF_1BPP) ! 126: { ! 127: switch (cx) { ! 128: case 16: ! 129: if ((bShrinkPattern)((BYTE *)pvBits, cbScan)) ! 130: { ! 131: cx = 8; ! 132: pbri->RealWidth = (BYTE)cx; ! 133: } else { ! 134: pfnConvert = vMono16Wide; ! 135: break; ! 136: } ! 137: case 8: ! 138: pfnConvert = vMono8Wide; ! 139: break; ! 140: ! 141: case 2: ! 142: pfnConvert = vMono2Wide; ! 143: break; ! 144: ! 145: case 4: ! 146: pfnConvert = vMono4Wide; ! 147: break; ! 148: ! 149: default: ! 150: return(FALSE); ! 151: } ! 152: ! 153: pbri->usStyle = BRI_MONO_PATTERN; ! 154: pbri->fjAccel = 0; ! 155: pbri->jBkColor = (BYTE)pxlo->pulXlate[0]; ! 156: pbri->jFgColor = (BYTE)pxlo->pulXlate[1]; ! 157: pbri->Width = 16; ! 158: pbri->pPattern = (BYTE *)&(pbri->ajPattern[0]); ! 159: pbri->jOldBrushRealized = 0; ! 160: ! 161: (*pfnConvert)(pbri->pPattern, pvBits, cbScan); ! 162: ! 163: if (bQuickPattern(pbri->pPattern, 8)) ! 164: { ! 165: pbri->Height = 2; ! 166: pbri->YShiftValue = 1; ! 167: } ! 168: else ! 169: { ! 170: pbri->Height = 8; ! 171: pbri->YShiftValue = 3; ! 172: } ! 173: ! 174: return(TRUE); ! 175: } ! 176: ! 177: if ((cx != 8) && (cx != 16)) ! 178: return(FALSE); ! 179: ! 180: if (pxlo->flXlate & XO_TABLE) ! 181: pulXlate = pxlo->pulXlate; ! 182: else ! 183: pulXlate = (PULONG)NULL; ! 184: ! 185: if ((psoPattern->iBitmapFormat == BMF_4BPP) && ! 186: (CountColors(pvBits, cx, (WORD *)&jColors, cbScan) == 2)) { ! 187: ! 188: if ((cx == 16) && (bShrinkPattern)((BYTE *)pvBits, cbScan)) ! 189: { ! 190: cx = 8; ! 191: pbri->RealWidth = (BYTE)cx; ! 192: } ! 193: ! 194: pbri->usStyle = BRI_MONO_PATTERN; ! 195: pbri->Height = 8; ! 196: pbri->YShiftValue = 3; ! 197: pbri->Width = 16; ! 198: pbri->fjAccel = 1; ! 199: pbri->pPattern = (BYTE *)&(pbri->ajPattern[0]); ! 200: pbri->jOldBrushRealized = OBR_4BPP; ! 201: ! 202: if (pulXlate != (PULONG)NULL) { ! 203: ! 204: jBkColor = (BYTE)pulXlate[jColors[0]]; ! 205: jFgColor = (BYTE)pulXlate[jColors[1]]; ! 206: } else { ! 207: ! 208: jBkColor = jColors[0]; ! 209: jFgColor = jColors[1]; ! 210: } ! 211: ! 212: if (jBkColor > jFgColor) { ! 213: pbri->jBkColor = jBkColor; ! 214: pbri->jFgColor = jFgColor; ! 215: } else { ! 216: pbri->jBkColor = jFgColor; ! 217: pbri->jFgColor = jBkColor; ! 218: } ! 219: ! 220: ! 221: vBrush2ColorToMono(pbri->pPattern, (BYTE *)pvBits, cbScan, ! 222: cx, pbri->jBkColor); ! 223: ! 224: if (bQuickPattern(pbri->pPattern, 8)) ! 225: { ! 226: pbri->Height = 2; ! 227: pbri->YShiftValue = 1; ! 228: } ! 229: ! 230: vCopyOrgBrush(&(pbri->ajC0[0]),pvBits, cbScan, pxlo); ! 231: ! 232: if (bConversion) { ! 233: EngUnlockSurface(psoPattern); ! 234: EngDeleteSurface((HSURF)hbmTmp); ! 235: } ! 236: ! 237: return(TRUE); ! 238: } ! 239: else if (cx != 8) ! 240: return(FALSE); ! 241: ! 242: pbri->pPattern = (BYTE *)&(pbri->ajC0[0]); ! 243: ! 244: // At this point we know we have an 8x8 color pattern in either a ! 245: // 4bpp or 8bpp format. ! 246: ! 247: if (psoPattern->iBitmapFormat == BMF_4BPP) ! 248: vConvert4BppToPlanar(pbri->pPattern, (BYTE *)pvBits, cbScan, pulXlate); ! 249: ! 250: else // 8bpp ! 251: vConvert8BppToPlanar(pbri->pPattern, (BYTE *)pvBits, cbScan, pulXlate); ! 252: #ifdef FAST_PLANE ! 253: vCreatePlaneMasks(&(pbri->ajPlaneMasks),pbri->pPattern); ! 254: #endif ! 255: // Set proper accelerators in the brush for the output code. ! 256: ! 257: pbri->usStyle = BRI_COLOR_PATTERN; // Brush style is arbitrary pattern ! 258: pbri->fjAccel = 0; // Accelerator flags - no special casing ! 259: pbri->Height = 8; ! 260: pbri->YShiftValue = 3; ! 261: pbri->Width = 8; ! 262: pbri->fjAccel = 1; ! 263: pbri->jOldBrushRealized = OBR_REALIZED|OBR_4BPP; ! 264: ! 265: if (bConversion) { ! 266: EngUnlockSurface(psoPattern); ! 267: EngDeleteSurface((HSURF)hbmTmp); ! 268: } ! 269: ! 270: return(TRUE); ! 271: } ! 272: ! 273: /****************************************************************************\ ! 274: * DrvvConvertBrush() ! 275: * ! 276: * Converts a brush to a 4bpp bmp ! 277: * ! 278: \****************************************************************************/ ! 279: ! 280: SURFOBJ *DrvConvertBrush( ! 281: SURFOBJ *psoPattern, ! 282: HBITMAP *phbmTmp, ! 283: XLATEOBJ *pxlo, ! 284: ULONG cx, ! 285: ULONG cy) ! 286: { ! 287: SURFOBJ *psoTmp; ! 288: RECTL rclTmp; ! 289: SIZEL sizlTmp; ! 290: POINTL ptl; ! 291: ! 292: ptl.x = 0; ! 293: ptl.y = 0; ! 294: rclTmp.top = 0; ! 295: rclTmp.left = 0; ! 296: rclTmp.right = cx; ! 297: sizlTmp.cx = cx; ! 298: rclTmp.bottom = cy; ! 299: sizlTmp.cy = cy; ! 300: ! 301: // Create bitmap in our compatible format. ! 302: ! 303: *phbmTmp = EngCreateBitmap(sizlTmp, cx / 2, BMF_4BPP, 0, NULL); ! 304: ! 305: if ((*phbmTmp) && ((psoTmp = EngLockSurface((HSURF)*phbmTmp)) != NULL)) ! 306: { ! 307: if (EngCopyBits(psoTmp, psoPattern, NULL, pxlo, &rclTmp, &ptl)) ! 308: return(psoTmp); ! 309: ! 310: EngUnlockSurface(psoTmp); ! 311: EngDeleteSurface((HSURF)*phbmTmp); ! 312: } ! 313: ! 314: return((SURFOBJ *)NULL); ! 315: } ! 316: ! 317: ! 318: /****************************************************************************\ ! 319: * vCopyOrgBrush ! 320: * ! 321: * When we realize a mono or 2 color brush, we copy the original 4bpp brush ! 322: * to the ajC0 area of the realized brush. If we are called to do a ! 323: * rop that we don't directly support, vConvertBrush will be called to ! 324: * convert the orginal 4bpp brush to a planar brush that the blt compiler can ! 325: * use. Since this is a rare event, we do this on request instead of at ! 326: * realization time. ! 327: * ! 328: \****************************************************************************/ ! 329: ! 330: VOID vCopyOrgBrush( ! 331: BYTE *pDest, ! 332: BYTE *pSrc, ! 333: LONG lScan, ! 334: XLATEOBJ *pxlo) ! 335: { ! 336: ULONG *pulXlate, *pulDest; ! 337: BYTE jByte, jColor; ! 338: int i; ! 339: ! 340: if (pxlo->flXlate & XO_TABLE) { ! 341: pulXlate = pxlo->pulXlate; ! 342: ! 343: for (i=0;i<32;i++) { ! 344: ! 345: jColor = *pSrc; // Get Next byte ! 346: jByte = jColor; ! 347: ! 348: jByte = pulXlate[jByte & 0xf]; ! 349: jByte = pulXlate[(jColor >> 4) & 0xf] << 4; ! 350: *pDest = jByte; ! 351: ! 352: pSrc += lScan; ! 353: pDest++; ! 354: } ! 355: } else { ! 356: pulDest = (ULONG *)pDest; ! 357: ! 358: for (i=0;i<8;i++) { ! 359: *pulDest = *(ULONG *)pSrc; ! 360: ! 361: pSrc += lScan; ! 362: pulDest++; ! 363: } ! 364: ! 365: } ! 366: } ! 367: ! 368: ! 369: /****************************************************************************\ ! 370: * vConvertBrush() ! 371: * ! 372: * This called when we are going to do a rop3 with a non-solid brush. We have ! 373: * to convert our brush back to the old blt compiler format in order for this ! 374: * blt to work properly. ! 375: * ! 376: \****************************************************************************/ ! 377: ! 378: BOOL bConvertBrush( ! 379: BRUSHINST *pbri) ! 380: { ! 381: BYTE jPattern[32]; ! 382: if (pbri->jOldBrushRealized & OBR_REALIZED) ! 383: return(TRUE); ! 384: ! 385: // ! 386: // The blt compiler only handles 8x8 ! 387: // ! 388: if (pbri->RealWidth != 8) ! 389: return(FALSE); ! 390: ! 391: if (pbri->jOldBrushRealized & OBR_4BPP) { ! 392: memcpy(&(jPattern[0]), &(pbri->ajC0[0]), 32); ! 393: vConvert4BppToPlanar(&(pbri->ajC0[0]), &(jPattern[0]), 4, NULL); ! 394: pbri->jOldBrushRealized |= OBR_REALIZED; ! 395: ! 396: return(TRUE); ! 397: } ! 398: ! 399: return(FALSE); ! 400: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.