|
|
1.1 ! root 1: //-------------------------------------------------------------------------- ! 2: // ! 3: // Module Name: PATFILL.C ! 4: // ! 5: // Brief Description: This module contains the PSCRIPT driver's pattern ! 6: // filling routines. ! 7: // ! 8: // Author: Kent Settle (kentse) ! 9: // Created: 12-Dec-1990 ! 10: // ! 11: // Copyright (c) 1990 - 1992 Microsoft Corporation ! 12: // ! 13: //-------------------------------------------------------------------------- ! 14: ! 15: #include "pscript.h" ! 16: #include "patfill.h" ! 17: #include "enable.h" ! 18: ! 19: VOID vPatfill_Base(PDEVDATA, FLONG, BGR_PAL_ENTRY *, MIX); ! 20: ! 21: #ifdef INDEX_PAL ! 22: extern ULONG PSMonoPalette[]; ! 23: extern ULONG PSColorPalette[]; ! 24: #endif ! 25: ! 26: //-------------------------------------------------------------------------- ! 27: // BOOL ps_patfill(pdev, pso, flFillMethod, pbo, pptlBrushOrg, mix, ! 28: // prclBound, bInvertPat, bFillPath) ! 29: // PDEVDATA pdev; ! 30: // SURFOBJ *pso; ! 31: // FLONG flFillMethod; ! 32: // BRUSHOBJ *pbo; ! 33: // PPOINTL pptlBrushOrg; ! 34: // MIX mix; ! 35: // RECTL *prclBound; ! 36: // BOOL bInvertPat; ! 37: // BOOL bFillPath; // TRUE if fill path is defined in printer. ! 38: // ! 39: // Parameters: ! 40: // ! 41: // Returns: ! 42: // This function returns no value. ! 43: // ! 44: // History: ! 45: // 17-Mar-1993 updated -by- Rob Kiesler ! 46: // For non-1BPP pattern brushes, create the target bitmap to be passed ! 47: // to the engine in the same format as the brush pattern. ! 48: // 10-Feb-1993 updated -by- Rob Kiesler ! 49: // Let the PS Interpreter perform tiling of 1BPP Pattern Brushes. ! 50: // 03-May-1991 -by- Kent Settle [kentse] ! 51: // Wrote it. ! 52: //-------------------------------------------------------------------------- ! 53: ! 54: BOOL ps_patfill(pdev, pso, flFillMethod, pbo, pptlBrushOrg, mix, ! 55: prclBound, bInvertPat, bFillPath) ! 56: PDEVDATA pdev; ! 57: SURFOBJ *pso; ! 58: FLONG flFillMethod; ! 59: BRUSHOBJ *pbo; ! 60: PPOINTL pptlBrushOrg; ! 61: MIX mix; ! 62: RECTL *prclBound; ! 63: BOOL bInvertPat; ! 64: BOOL bFillPath; // TRUE if fill path is defined in printer. ! 65: { ! 66: DEVBRUSH *pBrush; ! 67: ULONG iPatternIndex; ! 68: BGR_PAL_ENTRY bgr; ! 69: BGR_PAL_ENTRY *pbgr; ! 70: BGR_PAL_ENTRY *pbgrTmp; ! 71: ULONG ulRed, ulGreen, ulBlue; ! 72: PSZ pszFill; ! 73: SIZEL sizlMem; ! 74: HBITMAP hbmMem; ! 75: SURFOBJ *psoMem; ! 76: RECTL rclTarget; ! 77: POINTL ptl, ptlOrg; ! 78: LPSTR *plpstr; ! 79: ROP4 rop4; ! 80: RECTPSFX rectpsfx; ! 81: ULONG ulNextScan; ! 82: ULONG ulWidthBytes; ! 83: ULONG ulStartByte; ! 84: ULONG cCnt; ! 85: ULONG cCurScan; ! 86: ULONG cCurByte; ! 87: ULONG cBytes; ! 88: LONG ShiftBits; ! 89: BYTE curByte; ! 90: PBYTE pbPat; ! 91: ULONG ulbpp; ! 92: #ifdef INDEX_PAL ! 93: ULONG *pulColors; ! 94: ULONG iFormat; ! 95: #endif ! 96: ! 97: // just output the solid color if there is one. ! 98: ! 99: #ifdef INDEX_PAL ! 100: if ((pdev->pntpd->flFlags & COLOR_DEVICE) && ! 101: (pdev->psdm.dm.dmColor == DMCOLOR_COLOR)) ! 102: pulColors = PSColorPalette; ! 103: else ! 104: pulColors = PSMonoPalette; ! 105: ! 106: if (pbo->iSolidColor != NOT_SOLID_COLOR) ! 107: { ! 108: prgb = (PALETTEENTRY *)pulColors + pbo->iSolidColor; ! 109: iPatternIndex = HS_SOLID; ! 110: } ! 111: else ! 112: { ! 113: // get the device brush to draw with. ! 114: ! 115: pBrush = (DEVBRUSH *)BRUSHOBJ_pvGetRbrush(pbo); ! 116: ! 117: if (!pBrush) ! 118: { ! 119: RIP("ps_patfill: pBrush is NULL.\n"); ! 120: return(FALSE); ! 121: } ! 122: else ! 123: { ! 124: if (pBrush->iSolidColor == NOT_SOLID_COLOR) ! 125: { ! 126: // get the foreground color. ! 127: ! 128: prgb = (PALETTEENTRY *)pulColors + ! 129: *(ULONG *)((PBYTE)pBrush + pBrush->offsetXlate + ! 130: sizeof(ULONG)); ! 131: ! 132: // get the index for the pattern. ! 133: ! 134: iPatternIndex = pBrush->iPatIndex; ! 135: } ! 136: else ! 137: { ! 138: prgb = (PALETTEENTRY *)&pBrush->iSolidColor; ! 139: iPatternIndex = HS_SOLID; ! 140: } ! 141: } ! 142: } ! 143: #else ! 144: pbgr = (BGR_PAL_ENTRY *)&pbo->iSolidColor; ! 145: iPatternIndex = HS_SOLID; ! 146: ! 147: if (pbo->iSolidColor == NOT_SOLID_COLOR) ! 148: { ! 149: // get the device brush to draw with. ! 150: ! 151: pBrush = (DEVBRUSH *)BRUSHOBJ_pvGetRbrush(pbo); ! 152: ! 153: if (!pBrush) ! 154: { ! 155: RIP("ps_patfill: pBrush is NULL.\n"); ! 156: return(FALSE); ! 157: } ! 158: ! 159: // get the foreground color. ! 160: ! 161: pbgr = (BGR_PAL_ENTRY *)((PBYTE)pBrush + pBrush->offsetXlate + ! 162: sizeof(ULONG)); ! 163: ! 164: // get the index for the pattern. ! 165: ! 166: iPatternIndex = pBrush->iPatIndex; ! 167: } ! 168: #endif ! 169: ! 170: // now handle the different patterns. the PostScript driver handles ! 171: // patterns in the following manner: at DrvEnablePDEV time we created ! 172: // bitmaps for each of the patterns, in the event that someone actually ! 173: // wants to draw with the pattern in a compatible bitmap. assuming ! 174: // someone is not doing something silly like that, we have been called ! 175: // here to handle the pattern filling. at DrvRealizeBrush time, the ! 176: // driver does a lookup in our internal table to determine the pattern ! 177: // index from the bitmap handle (pBrush->iPatIndex). since bltting ! 178: // these patterns would be SLOW, we will draw them in reasonable ! 179: // ways, depeding on the pattern. ! 180: ! 181: switch(iPatternIndex) ! 182: { ! 183: case HS_DENSE1: ! 184: case HS_DENSE2: ! 185: case HS_DENSE3: ! 186: case HS_DENSE4: ! 187: case HS_DENSE5: ! 188: case HS_DENSE6: ! 189: case HS_DENSE7: ! 190: case HS_DENSE8: ! 191: // Seperate the Red, Green, and Blue color planes. ! 192: ! 193: #ifdef INDEX_PAL ! 194: ulRed = (ULONG)prgb->peRed; ! 195: ulGreen = (ULONG)prgb->peGreen; ! 196: ulBlue = (ULONG)prgb->peBlue; ! 197: #else ! 198: ulRed = (ULONG)pbgr->bgrRed; ! 199: ulGreen = (ULONG)pbgr->bgrGreen; ! 200: ulBlue = (ULONG)pbgr->bgrBlue; ! 201: #endif ! 202: ! 203: // adjust their intensities by the pattern percentage. ! 204: ! 205: ulRed += PSFXTOL((255L - ulRed) * ! 206: apsfxPatGray[iPatternIndex - HS_DENSE1]); ! 207: ulGreen += PSFXTOL((255L - ulGreen) * ! 208: apsfxPatGray[iPatternIndex - HS_DENSE1]); ! 209: ulBlue += PSFXTOL((255L - ulBlue) * ! 210: apsfxPatGray[iPatternIndex - HS_DENSE1]); ! 211: ! 212: // Recombine the Red, Green, and Blue values into an RGB color ! 213: ! 214: #ifdef INDEX_PAL ! 215: rgb.peRed = (BYTE)ulRed; ! 216: rgb.peGreen = (BYTE)ulGreen; ! 217: rgb.peBlue = (BYTE)ulBlue; ! 218: #else ! 219: bgr.bgrRed = (BYTE)ulRed; ! 220: bgr.bgrGreen = (BYTE)ulGreen; ! 221: bgr.bgrBlue = (BYTE)ulBlue; ! 222: #endif ! 223: ! 224: pbgr = &bgr; ! 225: ! 226: // fall through to the HS_SOLID code, with pe set up for ! 227: // the shading. ! 228: ! 229: case HS_SOLID: ! 230: ps_setrgbcolor(pdev, pbgr); ! 231: ps_fill(pdev, flFillMethod); ! 232: break; ! 233: ! 234: case HS_NOSHADE: ! 235: // just destroy the path. there is no filling to do. ! 236: ! 237: ps_newpath(pdev); ! 238: break; ! 239: ! 240: case HS_HALFTONE: ! 241: // Seperate the Red, Green, and Blue color planes. ! 242: ! 243: #ifdef INDEX_PAL ! 244: ulRed = (ULONG)prgb->peRed; ! 245: ulGreen = (ULONG)prgb->peGreen; ! 246: ulBlue = (ULONG)prgb->peBlue; ! 247: #else ! 248: ulRed = (ULONG)pbgr->bgrRed; ! 249: ulGreen = (ULONG)pbgr->bgrGreen; ! 250: ulBlue = (ULONG)pbgr->bgrBlue; ! 251: #endif ! 252: // adjust their intensities by one half. ! 253: ! 254: ulRed += PSFXTOL((255L - ulRed) * PSFXONEHALF); ! 255: ulGreen += PSFXTOL((255L - ulGreen) * PSFXONEHALF); ! 256: ulBlue += PSFXTOL((255L - ulBlue) * PSFXONEHALF); ! 257: ! 258: // Recombine the Red, Green, and Blue values into an RGB color ! 259: ! 260: #ifdef INDEX_PAL ! 261: rgb.peRed = (BYTE)ulRed; ! 262: rgb.peGreen = (BYTE)ulGreen; ! 263: rgb.peBlue = (BYTE)ulBlue; ! 264: #else ! 265: bgr.bgrRed = (BYTE)ulRed; ! 266: bgr.bgrGreen = (BYTE)ulGreen; ! 267: bgr.bgrBlue = (BYTE)ulBlue; ! 268: #endif ! 269: ps_setrgbcolor(pdev, &bgr); ! 270: ps_fill(pdev, flFillMethod); ! 271: break; ! 272: ! 273: // if we get this far, we either have one of the hatched brushes, ! 274: // or a user defined bitmap pattern. ! 275: ! 276: case HS_HORIZONTAL: ! 277: case HS_VERTICAL: ! 278: case HS_BDIAGONAL1: ! 279: case HS_BDIAGONAL: ! 280: case HS_FDIAGONAL1: ! 281: case HS_FDIAGONAL: ! 282: case HS_CROSS: ! 283: case HS_DIAGCROSS: ! 284: // set the foreground color. check to see if the invert pattern ! 285: // flag is set, and reverse the colors if so. ! 286: ! 287: if (bInvertPat) ! 288: { ! 289: #ifdef INDEX_PAL ! 290: prgbTmp = prgb; ! 291: prgb = (BGR_PAL_ENTRY *)pulColors + ! 292: *(ULONG *)((PBYTE)pBrush + pBrush->offsetXlate); ! 293: #else ! 294: pbgrTmp = pbgr; ! 295: pbgr = (BGR_PAL_ENTRY *)((PBYTE)pBrush + pBrush->offsetXlate); ! 296: #endif ! 297: } ! 298: ! 299: ps_setrgbcolor(pdev, pbgr); ! 300: ! 301: // if the background is not transparent, save the path, fill the path ! 302: // with the background color, then restore the path. ! 303: ! 304: if (((mix >> 8) & 0xFF) != R2_NOP) ! 305: { ! 306: // this section of code does a gsave, fills the background ! 307: // color, and then a grestore. it does this so that the ! 308: // foreground pattern can then be drawn. TRUE means to do ! 309: // a gsave, not a save command. ! 310: ! 311: if (!ps_save(pdev, TRUE)) ! 312: return(FALSE); ! 313: ! 314: #ifdef INDEX_PAL ! 315: if (bInvertPat) ! 316: prgb = prgbTmp; ! 317: else ! 318: prgb = (BGR_PAL_ENTRY *)pulColors + ! 319: *(ULONG *)((PBYTE)pBrush + pBrush->offsetXlate); ! 320: #else ! 321: if (bInvertPat) ! 322: pbgr = pbgrTmp; ! 323: else ! 324: pbgr = (BGR_PAL_ENTRY *)((PBYTE)pBrush + pBrush->offsetXlate); ! 325: #endif ! 326: ! 327: ps_setrgbcolor(pdev, pbgr); ! 328: ps_fill(pdev, flFillMethod); ! 329: ! 330: if (!ps_restore(pdev, TRUE)) ! 331: return(FALSE); ! 332: } ! 333: ! 334: // if the base pattern definitions code has not yet been downloaded ! 335: // to the printer, do it now. ! 336: ! 337: if(!(pdev->cgs.dwFlags & CGS_BASEPATSENT)) ! 338: { ! 339: plpstr = apszBase; ! 340: while (*plpstr) ! 341: { ! 342: PrintString(pdev, (PSZ)*plpstr++); ! 343: PrintString(pdev, "\n"); ! 344: } ! 345: pdev->cgs.dwFlags |= CGS_BASEPATSENT; ! 346: } ! 347: ! 348: // we will do a gsave/grestore around the pattern fill. TRUE ! 349: // means to do a gsave, not a save command. ! 350: ! 351: if (!ps_save(pdev, TRUE)) ! 352: return(FALSE); ! 353: ! 354: // let the printer know which fill method to use. ! 355: ! 356: if (flFillMethod & FP_WINDINGMODE) ! 357: pszFill = "psize"; ! 358: else ! 359: pszFill = "eopsize"; ! 360: ! 361: // make sure the linewidth for the patterns is .01 inch. ! 362: ! 363: ps_setlinewidth(pdev, PSFX_DEFAULT_LINEWIDTH); ! 364: ! 365: // output the specific command for each pattern. ! 366: ! 367: switch(iPatternIndex) ! 368: { ! 369: case HS_HORIZONTAL: ! 370: PrintString(pdev, pszFill); ! 371: PrintString(pdev, " phoriz "); ! 372: break; ! 373: ! 374: case HS_VERTICAL: ! 375: PrintString(pdev, "90 rotate "); ! 376: PrintString(pdev, pszFill); ! 377: PrintString(pdev, " phoriz "); ! 378: break; ! 379: ! 380: case HS_BDIAGONAL1: ! 381: PrintString(pdev, "30 rotate "); ! 382: PrintString(pdev, pszFill); ! 383: PrintString(pdev, " phoriz "); ! 384: break; ! 385: ! 386: case HS_BDIAGONAL: ! 387: PrintString(pdev, "45 rotate "); ! 388: PrintString(pdev, pszFill); ! 389: PrintString(pdev, " phoriz "); ! 390: break; ! 391: ! 392: case HS_FDIAGONAL1: ! 393: PrintString(pdev, "-30 rotate "); ! 394: PrintString(pdev, pszFill); ! 395: PrintString(pdev, " phoriz "); ! 396: break; ! 397: ! 398: case HS_FDIAGONAL: ! 399: PrintString(pdev, "-45 rotate "); ! 400: PrintString(pdev, pszFill); ! 401: PrintString(pdev, " phoriz "); ! 402: break; ! 403: ! 404: case HS_CROSS: ! 405: PrintString(pdev, "gs "); ! 406: PrintString(pdev, pszFill); ! 407: PrintString(pdev, " phoriz gr 90 rotate "); ! 408: PrintString(pdev, pszFill); ! 409: PrintString(pdev, " phoriz "); ! 410: break; ! 411: ! 412: case HS_DIAGCROSS: ! 413: PrintString(pdev, "gs 45 rotate "); ! 414: PrintString(pdev, pszFill); ! 415: PrintString(pdev, " phoriz gr -45 rotate "); ! 416: PrintString(pdev, pszFill); ! 417: PrintString(pdev, " phoriz "); ! 418: break; ! 419: } ! 420: ! 421: if (!ps_restore(pdev, TRUE)) ! 422: return(FALSE); ! 423: ! 424: ps_newpath(pdev); ! 425: break; ! 426: ! 427: default: ! 428: // we have a user defined bitmap pattern. the bitmap ! 429: // can be monochrome or color. the initial method for ! 430: // filling with a bitmap pattern will be as follows: ! 431: // ! 432: // ! 433: // If the bitmap is 1BPP, download the PS pattern ! 434: // tiling procest if neccessary and invoke the "prf" ! 435: // operator which will tile the bitmap pattern into the ! 436: // destination rectangle. ! 437: // ! 438: // If the bitmap is >1BPP, a memory bitmap the size of the ! 439: // bounding rectangle will be created, and filled with the ! 440: // pattern. this memory bitmap will then be blted to the ! 441: // printer which will handle clipping to the path. ! 442: // ! 443: // NOTE: current windows implementation uses only the ! 444: // upper/lower left 8x8 bits of the bitmap for the pattern, ! 445: // no matter what size the bitmap itself is. for now we ! 446: // will print the entire bitmap as the pattern. supposedly, ! 447: // future engine functionality will support this. ! 448: ! 449: // since we have a user defined pattern, and we will be ! 450: // calling BitBlt to do the work, we want to clip to the ! 451: // path which was defined in DrvCommonPath. ! 452: ! 453: if (bFillPath) ! 454: { ! 455: if (flFillMethod & FP_WINDINGMODE) ! 456: ps_clip(pdev, TRUE); ! 457: else ! 458: ps_clip(pdev, FALSE); ! 459: } ! 460: ! 461: // a path will have been defined in the printer before calling ! 462: // ps_patfill to fill to. since user defined patterns do not ! 463: // use the fill command, we do not want a path sitting around ! 464: // in the printer. ! 465: ! 466: ps_newpath(pdev); ! 467: ! 468: //!!! OPTIMIZATION !!! ! 469: //!!! perhaps if we have a monochrome bitmap, we should ! 470: //!!! define it as a character of a font, then tile that ! 471: //!!! character over the clip path. ! 472: ! 473: sizlMem.cx = prclBound->right - prclBound->left; ! 474: sizlMem.cy = prclBound->bottom - prclBound->top; ! 475: ! 476: // ! 477: // If this is a 1BPP Bitmap Brush, generate PS code ! 478: // to handle it. ! 479: // ! 480: ! 481: if (pBrush->iFormat == BMF_1BPP) ! 482: { ! 483: // ! 484: // Check to see if any of the PS bitmap pattern code ! 485: // has been downloaded. ! 486: // ! 487: if(!(pdev->dwFlags & PDEV_UTILSSENT)) ! 488: { ! 489: // ! 490: // Download the Adobe PS Utilities Procset. ! 491: // ! 492: PrintString(pdev, "/Adobe_WinNT_Driver_Gfx 175 dict dup begin\n"); ! 493: if (!bSendPSProcSet(pdev, UTILS)) ! 494: { ! 495: RIP("PSCRIPT!ps_patfill: Couldn't download Utils Procset.\n"); ! 496: return(FALSE); ! 497: } ! 498: PrintString(pdev, "end def\n[ 1.000 0 0 1.000 0 0 ] Adobe_WinNT_Driver_Gfx dup /initialize get exec\n"); ! 499: pdev->dwFlags |= PDEV_UTILSSENT; ! 500: } ! 501: ! 502: if(!(pdev->dwFlags & PDEV_BMPPATSENT)) ! 503: { ! 504: // ! 505: // Download the Adobe PS Pattern Bitmap Procset. ! 506: // ! 507: PrintString(pdev, "Adobe_WinNT_Driver_Gfx begin\n"); ! 508: if (!bSendPSProcSet(pdev, PATTERN)) ! 509: { ! 510: RIP("PSCRIPT!ps_patfill: Couldn't download Pattern Bmp Procset.\n"); ! 511: return(FALSE); ! 512: } ! 513: PrintString(pdev, "end reinitialize\n"); ! 514: pdev->dwFlags |= PDEV_BMPPATSENT; ! 515: ! 516: } ! 517: ! 518: // ! 519: // First Convert Destination Rect Coordinates to fixed ! 520: // point. ! 521: // ! 522: rectpsfx.xLeft = X72DPI(prclBound->left); ! 523: rectpsfx.yBottom = Y72DPI(prclBound->bottom); ! 524: ! 525: // ! 526: // Compute the destination rectangle extents, and convert ! 527: // to fixed point. ! 528: // ! 529: rectpsfx.xRight = ((prclBound->right - prclBound->left) ! 530: * PS_FIX_RESOLUTION) / pdev->psdm.dm.dmPrintQuality; ! 531: rectpsfx.yTop = ((prclBound->bottom - prclBound->top) ! 532: * PS_FIX_RESOLUTION) / pdev->psdm.dm.dmPrintQuality; ! 533: ! 534: PrintPSFIX(pdev, 4, rectpsfx.xLeft, rectpsfx.yBottom, ! 535: rectpsfx.xRight, rectpsfx.yTop); ! 536: ! 537: // ! 538: // Get the bg color from the pBrush and convert to ! 539: // PS format. ! 540: // ! 541: #ifdef INDEX_PAL ! 542: prgb = (BGR_PAL_ENTRY *)pulColors + ! 543: *(ULONG *)((PBYTE)pBrush + pBrush->offsetXlate); ! 544: #else ! 545: pbgr = (BGR_PAL_ENTRY *)((PBYTE)pBrush + pBrush->offsetXlate); ! 546: #endif ! 547: ! 548: PrintString(pdev, " ["); ! 549: PrintPSFIX(pdev, 3, LTOPSFX((ULONG)pbgr->bgrRed) / 255, ! 550: LTOPSFX((ULONG)pbgr->bgrGreen) / 255, ! 551: LTOPSFX((ULONG)pbgr->bgrBlue) / 255); ! 552: PrintString(pdev, " false]"); ! 553: ! 554: // ! 555: // Get the fg color from the pBrush and convert to ! 556: // PS format. ! 557: // ! 558: ! 559: #ifdef INDEX_PAL ! 560: prgb = (BGR_PAL_ENTRY *)pulColors + ! 561: *(ULONG *)((PBYTE)pBrush + pBrush->offsetXlate + ! 562: sizeof(ULONG)); ! 563: #else ! 564: pbgr = (BGR_PAL_ENTRY *)((PBYTE)pBrush + pBrush->offsetXlate + ! 565: sizeof(ULONG)); ! 566: #endif ! 567: ! 568: PrintString(pdev, " ["); ! 569: ! 570: PrintPSFIX(pdev, 3, LTOPSFX((ULONG)pbgr->bgrRed) / 255, ! 571: LTOPSFX((ULONG)pbgr->bgrGreen) / 255, ! 572: LTOPSFX((ULONG)pbgr->bgrBlue) / 255); ! 573: PrintString(pdev, " false] "); ! 574: ! 575: // ! 576: // Send down the pattern x and y extents. ! 577: // ! 578: PrintDecimal(pdev, 2, pBrush->sizlBitmap.cx, ! 579: pBrush->sizlBitmap.cy); ! 580: ! 581: // ! 582: // Compute the width in bytes of each scanline in the ! 583: // pattern bitmap, rounded to the nearest dword boundary. ! 584: // ! 585: ulWidthBytes = (pBrush->sizlBitmap.cx + 7) / 8; ! 586: ulNextScan = ((pBrush->sizlBitmap.cx + 31) / 32) << 2; ! 587: ! 588: PrintString(pdev," <"); ! 589: ! 590: // ! 591: // Send the pattern bitmap. The PS pattern fill operator ! 592: // doesn't need the padding bytes at the end of each ! 593: // scanline. ! 594: // ! 595: pbPat = pBrush->ajBits; ! 596: ! 597: if (!pptlBrushOrg->y && !pptlBrushOrg->x) ! 598: { ! 599: // ! 600: // The brush pattern doesn't require rotation, ! 601: // send it down a scanline at a time. ! 602: // ! 603: for (cCnt = 0;cCnt < (ULONG)pBrush->sizlBitmap.cy;cCnt++) ! 604: { ! 605: vHexOut(pdev, pbPat, ulWidthBytes); ! 606: pbPat += ulNextScan; ! 607: } ! 608: } ! 609: else ! 610: { ! 611: ! 612: // ! 613: // The Brush pattern requires rotation. Calculate the ! 614: // byte offset of the x origin. ! 615: // ! 616: ! 617: // let's first yank the origin to somewhere inside our ! 618: // bitmap. ! 619: ! 620: ptlOrg.x = pptlBrushOrg->x % pBrush->sizlBitmap.cx; ! 621: if (ptlOrg.x < 0) ! 622: ptlOrg.x = ptlOrg.x + pBrush->sizlBitmap.cx; ! 623: ! 624: ptlOrg.y = pptlBrushOrg->y % pBrush->sizlBitmap.cy; ! 625: if (ptlOrg.y < 0) ! 626: ptlOrg.y = ptlOrg.y + pBrush->sizlBitmap.cy; ! 627: ! 628: ulStartByte = ptlOrg.x / 8; ! 629: ! 630: if (!(ShiftBits = ptlOrg.x % 8)) ! 631: { ! 632: // ! 633: // The x origin is byte aligned. Apply the proper ! 634: // byte rotation and send a scanline (or a partial ! 635: // scanline) at a time. ! 636: // ! 637: for (cCnt = 0;cCnt < (ULONG)pBrush->sizlBitmap.cy;cCnt++) ! 638: { ! 639: cCurScan = ((cCnt + ptlOrg.y) % pBrush->sizlBitmap.cy) ! 640: * ulNextScan; ! 641: vHexOut(pdev, &(pbPat[cCurScan + ulStartByte]), ! 642: ulWidthBytes - ulStartByte); ! 643: if (ulStartByte) ! 644: vHexOut(pdev, &(pbPat[cCurScan]), ulStartByte); ! 645: } ! 646: } ! 647: else ! 648: { ! 649: // ! 650: // The x origin is not byte aligned, rotate and send ! 651: // the pattern bitmap a byte at a time. ! 652: // ! 653: for (cCnt = 0;cCnt < (ULONG)pBrush->sizlBitmap.cy;cCnt++) ! 654: { ! 655: cCurScan = ((cCnt + ptlOrg.y) % pBrush->sizlBitmap.cy) ! 656: * ulNextScan; ! 657: for (cBytes = 0;cBytes < ulWidthBytes;cBytes++) ! 658: { ! 659: cCurByte = (cBytes + ulStartByte) % ulWidthBytes; ! 660: curByte = pbPat[cCurScan + cCurByte] >> ShiftBits; ! 661: cCurByte = ++cCurByte % ulWidthBytes; ! 662: curByte |= (pbPat[cCurScan + cCurByte] << (8 - ShiftBits)); ! 663: vHexOut(pdev, &curByte, 1); ! 664: } ! 665: } ! 666: } ! 667: } ! 668: ! 669: // ! 670: // Close the pattern data array object, and invoke the ! 671: // prf (pattern rect fill) operator. ! 672: // ! 673: PrintString(pdev,"> prf\n"); ! 674: break; ! 675: } ! 676: ! 677: // create a memory bitmap which is the size of the ! 678: // bounding box of the current path, and is compatible ! 679: // with the pattern bitmap. ! 680: ! 681: ! 682: // ! 683: // Compute the scanline delta. First get then number of ! 684: // pels/scanline. ! 685: // ! 686: ulNextScan = sizlMem.cx; ! 687: ! 688: // ! 689: // times how many bits per pel. ! 690: // ! 691: switch (pBrush->iFormat) ! 692: { ! 693: case BMF_4BPP: ! 694: ulbpp = 4; ! 695: break; ! 696: ! 697: case BMF_8BPP: ! 698: ulbpp = 8; ! 699: break; ! 700: ! 701: case BMF_16BPP: ! 702: ulbpp = 16; ! 703: break; ! 704: ! 705: case BMF_24BPP: ! 706: ulbpp = 24; ! 707: break; ! 708: ! 709: case BMF_32BPP: ! 710: ulbpp = 32; ! 711: break; ! 712: } ! 713: ! 714: ulNextScan *= ulbpp; ! 715: ! 716: // ! 717: // Now convert ulNextScan to the number of bytes per scanline, ! 718: // taking into account that scanlines are padded out to 32 bit ! 719: // boundaries. ! 720: // ! 721: ulNextScan = ((ulNextScan + 31) / 32) * 4; ! 722: ! 723: #ifdef INDEX_PAL ! 724: if ((pdev->pntpd->flFlags & COLOR_DEVICE) && ! 725: (pdev->psdm.dm.dmColor == DMCOLOR_COLOR)) ! 726: iFormat = BMF_4BPP; ! 727: else ! 728: iFormat = BMF_1BPP; ! 729: ! 730: hbmMem = EngCreateBitmap(sizlMem, ulNextScan, iFormat, ! 731: pBrush->flBitmap, (PVOID)NULL); ! 732: #else ! 733: hbmMem = EngCreateBitmap(sizlMem, ulNextScan, BMF_24BPP, ! 734: pBrush->flBitmap, (PVOID)NULL); ! 735: #endif ! 736: ! 737: if (hbmMem == 0) ! 738: { ! 739: RIP("PSCRIPT!ps_patfill: EngCreateBitmap for hbmMem failed.\n"); ! 740: return(FALSE); ! 741: } ! 742: ! 743: // get the SURFOBJ for the memory bitmap. ! 744: ! 745: psoMem = (SURFOBJ *)EngLockSurface((HSURF)hbmMem); ! 746: ! 747: if (psoMem == (SURFOBJ *)NULL) ! 748: { ! 749: RIP("ps_patfill: EngLockSurface for psoMem failed.\n"); ! 750: EngDeleteSurface((HSURF)hbmMem); ! 751: return(FALSE); ! 752: } ! 753: ! 754: // do a patcopy into the memory bitmap. ! 755: ! 756: rclTarget.left = 0; ! 757: rclTarget.top = 0; ! 758: rclTarget.right = sizlMem.cx; ! 759: rclTarget.bottom = sizlMem.cy; ! 760: ! 761: if (bInvertPat) ! 762: rop4 = 0x5A5A; // invert pattern. ! 763: else ! 764: rop4 = 0xF0F0; // patcopy. ! 765: ! 766: if (!(EngBitBlt(psoMem, (SURFOBJ *)NULL, (SURFOBJ *)NULL, ! 767: (CLIPOBJ *)NULL, (XLATEOBJ *)NULL, &rclTarget, ! 768: (PPOINTL)NULL, (PPOINTL)NULL, pbo, ! 769: pptlBrushOrg, rop4))) ! 770: { ! 771: RIP("ps_patfill: EngBitBlt pat to mem failed.\n"); ! 772: EngUnlockSurface(psoMem); ! 773: EngDeleteSurface((HSURF)hbmMem); ! 774: return(FALSE); ! 775: } ! 776: ! 777: // now that the memory bitmap is filled with the pattern, ! 778: // bitblt it to the printer. the printer will handle clipping. ! 779: ! 780: // source origin. ! 781: ! 782: ptl.x = 0; ! 783: ptl.y = 0; ! 784: ! 785: if (!(DrvBitBlt(pso, psoMem, (SURFOBJ *)NULL, ! 786: (CLIPOBJ *)NULL, (XLATEOBJ *)NULL, prclBound, ! 787: &ptl, (PPOINTL)NULL, pbo, ! 788: pptlBrushOrg, 0xCCCC))) ! 789: { ! 790: RIP("ps_patfill: EngBitBlt mem to printer failed.\n"); ! 791: EngUnlockSurface(psoMem); ! 792: EngDeleteSurface((HSURF)hbmMem); ! 793: return(FALSE); ! 794: } ! 795: ! 796: // release stuff. ! 797: ! 798: if (psoMem) ! 799: { ! 800: EngUnlockSurface(psoMem); ! 801: EngDeleteSurface((HSURF)hbmMem); ! 802: } ! 803: } ! 804: ! 805: return(TRUE); ! 806: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.