|
|
1.1 ! root 1: //-------------------------------------------------------------------------- ! 2: // ! 3: // Module Name: BITBLT.C ! 4: // ! 5: // Brief Description: This module contains the PSCRIPT driver's BitBlt ! 6: // functions and related routines. ! 7: // ! 8: // Author: Kent Settle (kentse) ! 9: // Created: 03-Dec-1990 ! 10: // ! 11: // 26-Mar-1992 Thu 23:54:07 updated -by- Daniel Chou (danielc) ! 12: // 1) add the prclBound parameter to the bDoClipObj() ! 13: // 2) Remove 'pco' parameter and replaced it with prclClipBound parameter, ! 14: // since pco is never referenced, prclClipBound is used for the ! 15: // halftone. ! 16: // 3) Add another parameter to do NOTSRCCOPY ! 17: // ! 18: // 11-Feb-1993 Thu 21:32:07 updated -by- Daniel Chou (danielc) ! 19: // Major re-write to have DrvStretchBlt(), DrvCopyBits() do the right ! 20: // things. ! 21: // ! 22: // Copyright (c) 1990-1992 Microsoft Corporation ! 23: // ! 24: // This module contains DrvBitBlt, DrvStretchBlt and related routines. ! 25: //-------------------------------------------------------------------------- ! 26: ! 27: #include "stdlib.h" ! 28: #include "pscript.h" ! 29: #include "enable.h" ! 30: #include "halftone.h" ! 31: ! 32: extern VOID vHexOut(PDEVDATA, PBYTE, LONG); ! 33: extern BOOL bDoClipObj(PDEVDATA, CLIPOBJ *, RECTL *, RECTL *, BOOL *, BOOL *, DWORD); ! 34: extern SHORT PSBitMapType(PDEVDATA pdev, BOOL BinaryClearChannel); ! 35: ! 36: #ifdef INDEX_PAL ! 37: extern ULONG PSMonoPalette[]; ! 38: extern ULONG PSColorPalette[]; ! 39: #endif ! 40: ! 41: #if DBG ! 42: BOOL DbgPSBitBlt = 0; ! 43: #endif ! 44: ! 45: #define PRINT_TOPDOWN 0x02 ! 46: #define PRINT_SRCAND 0x04 ! 47: ! 48: #define SWAP(a,b,tmp) tmp=a; a=b; b=tmp ! 49: ! 50: ! 51: #define PAL_MIN_I 0x00 ! 52: #define PAL_MAX_I 0xff ! 53: ! 54: #define HTXB_R(htxb) htxb.b4.b1st ! 55: #define HTXB_G(htxb) htxb.b4.b2nd ! 56: #define HTXB_B(htxb) htxb.b4.b3rd ! 57: #define HTXB_I(htxb) htxb.b4.b4th ! 58: ! 59: #define SRC8PELS_TO_3P_DW(dwRet,pHTXB,pSrc8Pels) \ ! 60: (dwRet) = (DWORD)((pHTXB[pSrc8Pels->b4.b1st].dw & (DWORD)0xc0c0c0c0) | \ ! 61: (pHTXB[pSrc8Pels->b4.b2nd].dw & (DWORD)0x30303030) | \ ! 62: (pHTXB[pSrc8Pels->b4.b3rd].dw & (DWORD)0x0c0c0c0c) | \ ! 63: (pHTXB[pSrc8Pels->b4.b4th].dw & (DWORD)0x03030303)); \ ! 64: ++pSrc8Pels ! 65: ! 66: #define INTENSITY(r,g,b) (BYTE)(((WORD)((r)*30) + (WORD)((g)*59) + (WORD)((b)*11))/100) ! 67: ! 68: // ! 69: // declarations of routines residing within this module. ! 70: // ! 71: ! 72: VOID ! 73: BeginImage( ! 74: PDEVDATA pdev, ! 75: BOOL Mono, ! 76: int x, ! 77: int y, ! 78: int cx, ! 79: int cy, ! 80: int cxBytes ! 81: ); ! 82: ! 83: BOOL DoPatCopy(PDEVDATA, SURFOBJ *, PRECTL, BRUSHOBJ *, PPOINTL, ROP4, BOOL); ! 84: ! 85: BOOL ! 86: HalftoneBlt( ! 87: PDEVDATA pdev, ! 88: SURFOBJ *psoDest, ! 89: SURFOBJ *psoSrc, ! 90: SURFOBJ *psoMask, ! 91: CLIPOBJ *pco, ! 92: XLATEOBJ *pxlo, ! 93: COLORADJUSTMENT *pca, ! 94: POINTL *pptlBrushOrg, ! 95: PRECTL prclDest, ! 96: PRECTL prclSrc, ! 97: PPOINTL pptlMask, ! 98: BOOL NotSrcCopy ! 99: ); ! 100: ! 101: BOOL ! 102: IsHTCompatibleSurfObj( ! 103: PDEVDATA pdev, ! 104: SURFOBJ *pso, ! 105: XLATEOBJ *pxlo ! 106: ); ! 107: ! 108: BOOL ! 109: OutputHTCompatibleBits( ! 110: PDEVDATA pdev, ! 111: SURFOBJ *psoHT, ! 112: CLIPOBJ *pco, ! 113: DWORD xDest, ! 114: DWORD yDest ! 115: ); ! 116: ! 117: ! 118: BOOL BeginImageEx( ! 119: PDEVDATA pdev, ! 120: SIZEL sizlSrc, ! 121: ULONG ulSrcFormat, ! 122: DWORD cbSrcWidth, ! 123: PRECTL prclDest, ! 124: BOOL bNotSrcCopy, ! 125: XLATEOBJ *pxlo); ! 126: ! 127: BOOL DoSourceCopy( ! 128: PDEVDATA pdev, ! 129: SURFOBJ *psoSrc, ! 130: PRECTL prclSrc, ! 131: PRECTL prclDest, ! 132: XLATEOBJ *pxlo, ! 133: RECTL *prclClipBound, ! 134: BOOL bNotSrcCopy); ! 135: ! 136: // ! 137: //********** Code start here ! 138: // ! 139: ! 140: ! 141: ! 142: ! 143: ! 144: BOOL ! 145: HalftoneBlt( ! 146: PDEVDATA pdev, ! 147: SURFOBJ *psoDest, ! 148: SURFOBJ *psoSrc, ! 149: SURFOBJ *psoMask, ! 150: CLIPOBJ *pco, ! 151: XLATEOBJ *pxlo, ! 152: COLORADJUSTMENT *pca, ! 153: POINTL *pptlBrushOrg, ! 154: PRECTL prclDest, ! 155: PRECTL prclSrc, ! 156: PPOINTL pptlMask, ! 157: BOOL NotSrcCopy ! 158: ) ! 159: ! 160: /*++ ! 161: ! 162: Routine Description: ! 163: ! 164: This function blt the soruces bitmap using halftone mode ! 165: ! 166: Arguments: ! 167: ! 168: Same as DrvStretchBlt() except pdev and NotSrcCopy flag ! 169: ! 170: ! 171: Return Value: ! 172: ! 173: BOOLEAN ! 174: ! 175: ! 176: Author: ! 177: ! 178: 17-Feb-1993 Wed 21:31:24 created -by- Daniel Chou (danielc) ! 179: ! 180: ! 181: Revision History: ! 182: ! 183: ! 184: --*/ ! 185: ! 186: { ! 187: PDRVHTINFO pDrvHTInfo; ! 188: POINTL ZeroOrigin = {0, 0}; ! 189: BOOL Ok; ! 190: ! 191: ! 192: ! 193: if (!(pDrvHTInfo = (PDRVHTINFO)(pdev->pvDrvHTData))) { ! 194: ! 195: DbgPrint("\nPSCRIPT!HalftoneBlt: pDrvHTInfo = NULL ???\n"); ! 196: return(FALSE); ! 197: } ! 198: ! 199: if (pDrvHTInfo->Flags & DHIF_IN_STRETCHBLT) { ! 200: ! 201: #if DBG ! 202: DbgPrint("\nPSCRIPT!HalftoneBlt: EngStretchBlt() RECURSIVE CALLS NOT ALLOWED!!!\n"); ! 203: #endif ! 204: return(FALSE); ! 205: } ! 206: ! 207: // ! 208: // Setup these data before calling EngStretchBlt(), these are used at later ! 209: // DrvCopyBits() call ! 210: // ! 211: ! 212: pDrvHTInfo->Flags |= DHIF_IN_STRETCHBLT; ! 213: pDrvHTInfo->HTPalXor = (NotSrcCopy) ? HTPALXOR_NOTSRCCOPY : ! 214: HTPALXOR_SRCCOPY; ! 215: ! 216: if (!pptlBrushOrg) { ! 217: ! 218: pptlBrushOrg = &ZeroOrigin; ! 219: } ! 220: ! 221: if (!pca) { ! 222: ! 223: pca = &(pDrvHTInfo->ca); ! 224: } ! 225: ! 226: #if DBG ! 227: if (DbgPSBitBlt) { ! 228: ! 229: if (pco) { ! 230: ! 231: DbgPrint("\nPSCRIPT!HalftoneBlt: CLIP: Complex=%ld", ! 232: (DWORD)pco->iDComplexity); ! 233: DbgPrint("\nClip rclBounds = (%ld, %ld) - (%ld, %ld)", ! 234: pco->rclBounds.left, ! 235: pco->rclBounds.top, ! 236: pco->rclBounds.right, ! 237: pco->rclBounds.bottom); ! 238: } else { ! 239: ! 240: DbgPrint("\nPSCRIPT!HalftoneBlt: pco = NULL\n"); ! 241: } ! 242: } ! 243: #endif ! 244: ! 245: if (!(Ok = EngStretchBlt(psoDest, // Dest ! 246: psoSrc, // SRC ! 247: psoMask, // MASK ! 248: pco, // CLIPOBJ ! 249: pxlo, // XLATEOBJ ! 250: pca, // COLORADJUSTMENT ! 251: pptlBrushOrg, // BRUSH ORG ! 252: prclDest, // DEST RECT ! 253: prclSrc, // SRC RECT ! 254: pptlMask, // MASK POINT ! 255: HALFTONE))) { // HALFTONE MODE ! 256: #if DBG ! 257: DbgPrint("\nPSCRIPT!HalftoneBlt: EngStretchBlt(HALFTONE) Failed\n"); ! 258: #endif ! 259: } ! 260: ! 261: // ! 262: // Clear These before we return ! 263: // ! 264: ! 265: pDrvHTInfo->HTPalXor = HTPALXOR_SRCCOPY; ! 266: pDrvHTInfo->Flags &= ~DHIF_IN_STRETCHBLT; ! 267: ! 268: return(Ok); ! 269: ! 270: } ! 271: ! 272: ! 273: ! 274: ! 275: BOOL ! 276: IsHTCompatibleSurfObj( ! 277: PDEVDATA pdev, ! 278: SURFOBJ *pso, ! 279: XLATEOBJ *pxlo ! 280: ) ! 281: ! 282: /*++ ! 283: ! 284: Routine Description: ! 285: ! 286: This function determine if the surface obj is compatble with postscript ! 287: halftone output format. ! 288: ! 289: Arguments: ! 290: ! 291: pdev - Pointer to the PDEVDATA data structure to determine what ! 292: type of postscript output for current device ! 293: ! 294: pso - engine SURFOBJ to be examine ! 295: ! 296: pxlo - engine XLATEOBJ for source -> postscript translation ! 297: ! 298: Return Value: ! 299: ! 300: BOOLEAN true if the pso is compatible with halftone output format, if ! 301: return value is true, the pDrvHTInfo->pHTXB is a valid trnaslation from ! 302: indices to 3 planes ! 303: ! 304: Author: ! 305: ! 306: 11-Feb-1993 Thu 18:49:55 created -by- Daniel Chou (danielc) ! 307: ! 308: ! 309: Revision History: ! 310: ! 311: ! 312: --*/ ! 313: ! 314: { ! 315: #ifdef INDEX_PAL ! 316: PALETTEENTRY *prgb; ! 317: PALETTEENTRY *ppalette; ! 318: ULONG *pulColors; ! 319: #else ! 320: BGR_PAL_ENTRY *pbgr; ! 321: #endif ! 322: PDRVHTINFO pDrvHTInfo; ! 323: UINT BmpFormat; ! 324: UINT cPal; ! 325: ! 326: if (!(pDrvHTInfo = (PDRVHTINFO)(pdev->pvDrvHTData))) { ! 327: ! 328: DbgPrint("\nPSCRIPT!IsHTCompatibleSurfObj: pDrvHTInfo = NULL ???\n"); ! 329: return(FALSE); ! 330: } ! 331: ! 332: #if DBG ! 333: if (DbgPSBitBlt) { ! 334: ! 335: DbgPrint("\n** IsHTCompatibleSurfObj **"); ! 336: DbgPrint("\niType=%ld, BmpFormat=%ld", ! 337: (DWORD)pso->iType, ! 338: (DWORD)pso->iBitmapFormat); ! 339: ! 340: if (pxlo) { ! 341: ! 342: DbgPrint("\npxlo: flXlate=%08lx, cPal=%ld, pulXlate=%08lx", ! 343: (DWORD)pxlo->flXlate, ! 344: (DWORD)pxlo->cEntries, ! 345: (DWORD)pxlo->pulXlate); ! 346: } else { ! 347: ! 348: DbgPrint("\npxlo = NULL"); ! 349: } ! 350: } ! 351: #endif ! 352: ! 353: // ! 354: // Make sure these fields' value are valid before create translation ! 355: // ! 356: // 1. pso->iBitmapFormat is one of 1BPP or 4BPP depends on current ! 357: // pscript's surface ! 358: // 2. pxlo is non null ! 359: // 3. pxlo->fXlate is XO_TABLE ! 360: // 4. pxlo->cPal is less or equal to the halftone palette count ! 361: // 5. pxlo->pulXlate is valid ! 362: // 6. source color table is within the range of halftone palette ! 363: // ! 364: ! 365: #if DBG ! 366: if (DbgPSBitBlt) { ! 367: ! 368: DbgPrint("\npso->iType = %x, pso->iBitmapFormat = %x.\n", ! 369: pso->iType, pso->iBitmapFormat); ! 370: DbgPrint("pDrvHTInfo->HTBmpFormat = %x.\n", ! 371: pDrvHTInfo->HTBmpFormat); ! 372: DbgPrint("pDrvHTInfo->AltBmpFormat = %x, pxlo = %x.\n", ! 373: pDrvHTInfo->AltBmpFormat, pxlo); ! 374: DbgPrint("pxlo->flXlate = %x, pxlo->cEntries = %d.\n", ! 375: pxlo->flXlate, pxlo->cEntries); ! 376: DbgPrint("pxlo->pulXlate = %x.\n", pxlo->pulXlate); ! 377: } ! 378: #endif ! 379: ! 380: if ((pso->iType == STYPE_BITMAP) && ! 381: (((BmpFormat = (UINT)pso->iBitmapFormat) == ! 382: (UINT)pDrvHTInfo->HTBmpFormat) || ! 383: (BmpFormat == (UINT)pDrvHTInfo->AltBmpFormat)) && ! 384: (pxlo) && ! 385: #ifdef INDEX_PAL ! 386: ((pxlo->flXlate & XO_TRIVIAL) || ! 387: ((pxlo->flXlate & XO_TABLE) && ! 388: #else ! 389: (pxlo->flXlate & XO_TABLE) && ! 390: #endif ! 391: ((cPal = (UINT)pxlo->cEntries) <= (UINT)pDrvHTInfo->HTPalCount) && ! 392: #ifdef INDEX_PAL ! 393: (ppalette = (PALETTEENTRY *)pxlo->pulXlate)))) { ! 394: #else ! 395: (pbgr = (BGR_PAL_ENTRY *)pxlo->pulXlate)) { ! 396: #endif ! 397: ! 398: ! 399: ULONG HTPalXor; ! 400: UINT i; ! 401: HTXB htXB; ! 402: HTXB PalNibble[HTPAL_XLATE_COUNT]; ! 403: BOOL GenHTXB = FALSE; ! 404: BYTE PalXlate[HTPAL_XLATE_COUNT]; ! 405: ! 406: ! 407: HTPalXor = pDrvHTInfo->HTPalXor; ! 408: pDrvHTInfo->HTPalXor = HTPALXOR_SRCCOPY; ! 409: ! 410: #if DBG ! 411: if (DbgPSBitBlt) { ! 412: ! 413: DbgPrint("\nHTPalXor=%08lx", HTPalXor); ! 414: } ! 415: #endif ! 416: ! 417: #ifdef INDEX_PAL ! 418: // if the TRIVIAL color translation flag is set, then fill in ! 419: // halftoning palette from our hardcoded palettes. ! 420: ! 421: if (BmpFormat == (UINT)BMF_1BPP) { ! 422: ! 423: pulColors = PSMonoPalette; ! 424: ! 425: } else { ! 426: ! 427: pulColors = PSColorPalette; ! 428: } ! 429: ! 430: if (pxlo->flXlate & XO_TRIVIAL) { ! 431: ! 432: if (BmpFormat == (UINT)BMF_1BPP) { ! 433: ! 434: cPal = 2; ! 435: ppalette = (PALETTEENTRY *)PSMonoPalette; ! 436: ! 437: } else { ! 438: ! 439: cPal = 8; ! 440: ppalette = (PALETTEENTRY *)PSColorPalette; ! 441: } ! 442: } ! 443: ! 444: for (i = 0; i < cPal; i++, ppalette++) { ! 445: ! 446: if (pxlo->flXlate & XO_TRIVIAL) { ! 447: ! 448: prgb = ppalette; ! 449: } ! 450: ! 451: else if (pxlo->flXlate & XO_TABLE) { ! 452: ! 453: if (BmpFormat == BMF_24BPP) { ! 454: ! 455: prgb = ppalette; ! 456: ! 457: } else { ! 458: ! 459: prgb = (PALETTEENTRY *)(pulColors + ! 460: XLATEOBJ_iXlate(pxlo, *(ULONG *)ppalette)); ! 461: } ! 462: } ! 463: ! 464: HTXB_R(htXB) = prgb->peRed; ! 465: HTXB_G(htXB) = prgb->peGreen; ! 466: HTXB_B(htXB) = prgb->peBlue; ! 467: #else ! 468: for (i = 0; i < cPal; i++, pbgr++) { ! 469: ! 470: HTXB_R(htXB) = pbgr->bgrRed; ! 471: HTXB_G(htXB) = pbgr->bgrGreen; ! 472: HTXB_B(htXB) = pbgr->bgrBlue; ! 473: #endif ! 474: htXB.dw ^= HTPalXor; ! 475: ! 476: ! 477: if (((HTXB_R(htXB) != PAL_MAX_I) && ! 478: (HTXB_R(htXB) != PAL_MIN_I)) || ! 479: ((HTXB_G(htXB) != PAL_MAX_I) && ! 480: (HTXB_G(htXB) != PAL_MIN_I)) || ! 481: ((HTXB_B(htXB) != PAL_MAX_I) && ! 482: (HTXB_B(htXB) != PAL_MIN_I))) { ! 483: ! 484: #if DBG ! 485: if (DbgPSBitBlt) { ! 486: ! 487: DbgPrint("\nSrcPal has NON 0xff/0x00 intensity, NOT HTPalette"); ! 488: } ! 489: #endif ! 490: return(FALSE); ! 491: } ! 492: ! 493: PalXlate[i] = ! 494: HTXB_I(htXB) = (BYTE)((HTXB_R(htXB) & 0x01) | ! 495: (HTXB_G(htXB) & 0x02) | ! 496: (HTXB_B(htXB) & 0x04)); ! 497: PalNibble[i] = htXB; ! 498: ! 499: if (pDrvHTInfo->PalXlate[i] != HTXB_I(htXB)) { ! 500: ! 501: GenHTXB = TRUE; ! 502: } ! 503: ! 504: #if DBG ! 505: if (DbgPSBitBlt) { ! 506: ! 507: DbgPrint("\n%d - %02x:%02x:%02x -> %02x:%02x:%02x, Idx=%d, PalXlate=%d", ! 508: i, ! 509: #ifdef INDEX_PAL ! 510: (BYTE)prgb->peRed, ! 511: (BYTE)prgb->peGreen, ! 512: (BYTE)prgb->peBlue, ! 513: #else ! 514: (BYTE)pbgr->bgrRed, ! 515: (BYTE)pbgr->bgrGreen, ! 516: (BYTE)pbgr->bgrBlue, ! 517: #endif ! 518: (BYTE)HTXB_R(htXB), ! 519: (BYTE)HTXB_G(htXB), ! 520: (BYTE)HTXB_B(htXB), ! 521: (INT)PalXlate[i], ! 522: (INT)pDrvHTInfo->PalXlate[i]); ! 523: } ! 524: #endif ! 525: } ! 526: ! 527: if (BmpFormat == (UINT)BMF_1BPP) { ! 528: ! 529: if (((PalXlate[0] != 0) && (PalXlate[0] != 7)) || ! 530: ((PalXlate[1] != 0) && (PalXlate[1] != 7))) { ! 531: ! 532: #if DBG ! 533: if (DbgPSBitBlt) { ! 534: ! 535: DbgPrint("\nNON-BLACK/WHITE MONO BITMAP, NOT HTPalette"); ! 536: } ! 537: #endif ! 538: return(FALSE); ! 539: } ! 540: } ! 541: ! 542: if (GenHTXB) { ! 543: ! 544: // ! 545: // Copy down the pal xlate ! 546: // ! 547: ! 548: #if DBG ! 549: if (DbgPSBitBlt) { ! 550: ! 551: DbgPrint("\n --- Copy XLATE TABLE ---"); ! 552: } ! 553: #endif ! 554: ! 555: CopyMemory(pDrvHTInfo->PalXlate, PalXlate, sizeof(PalXlate)); ! 556: ! 557: // ! 558: // We only really generate 4bpp to 3 planes if the destination ! 559: // format is BMF_4BPP ! 560: // ! 561: ! 562: if (BmpFormat == (UINT)BMF_4BPP) { ! 563: ! 564: PHTXB pTmpHTXB; ! 565: UINT h; ! 566: UINT l; ! 567: DWORD HighNibble; ! 568: ! 569: #if DBG ! 570: if (DbgPSBitBlt) { ! 571: ! 572: DbgPrint("\n --- Generate 4bpp --> 3 planes xlate ---"); ! 573: } ! 574: #endif ! 575: ! 576: if (!(pDrvHTInfo->pHTXB)) { ! 577: ! 578: RIP("PSCRIPT!IsHTCompatibleSurfObj: NULL pDrvHTInfo->pHTXB\n"); ! 579: ! 580: if (!(pDrvHTInfo->pHTXB = (PHTXB) ! 581: HeapAlloc(pdev->hheap, 0, HTXB_TABLE_SIZE))) { ! 582: ! 583: RIP("PSCRIPT!IsHTCompatibleSurfObj: HeapAlloc(HTXB_TABLE_SIZE) failed\n"); ! 584: return(FALSE); ! 585: } ! 586: } ! 587: ! 588: // ! 589: // Generate 4bpp to 3 planes xlate table ! 590: // ! 591: ! 592: for (h = 0, pTmpHTXB = pDrvHTInfo->pHTXB; ! 593: h < HTXB_H_NIBBLE_MAX; ! 594: h++, pTmpHTXB += HTXB_L_NIBBLE_DUP) { ! 595: ! 596: HighNibble = (DWORD)(PalNibble[h].dw & 0xaaaaaaaaL); ! 597: ! 598: for (l = 0; l < HTXB_L_NIBBLE_MAX; l++, pTmpHTXB++) { ! 599: ! 600: pTmpHTXB->dw = (DWORD)((HighNibble) | ! 601: (PalNibble[l].dw & 0x55555555L)); ! 602: } ! 603: ! 604: // ! 605: // Duplicate low nibble high order bit, 8 of them ! 606: // ! 607: ! 608: CopyMemory(pTmpHTXB, ! 609: pTmpHTXB - HTXB_L_NIBBLE_MAX, ! 610: sizeof(HTXB) * HTXB_L_NIBBLE_DUP); ! 611: } ! 612: ! 613: // ! 614: // Copy high nibble duplication, 128 of them ! 615: // ! 616: ! 617: CopyMemory(pTmpHTXB, ! 618: pDrvHTInfo->pHTXB, ! 619: sizeof(HTXB) * HTXB_H_NIBBLE_DUP); ! 620: } ! 621: } ! 622: ! 623: #if DBG ! 624: if (DbgPSBitBlt) { ! 625: ! 626: DbgPrint("\n******* IsHTCompatibleSurfObj = YES *******"); ! 627: } ! 628: #endif ! 629: ! 630: return(TRUE); ! 631: ! 632: } else { ! 633: ! 634: return(FALSE); ! 635: } ! 636: } ! 637: ! 638: ! 639: ! 640: ! 641: BOOL ! 642: OutputHTCompatibleBits( ! 643: PDEVDATA pdev, ! 644: SURFOBJ *psoHT, ! 645: CLIPOBJ *pco, ! 646: DWORD xDest, ! 647: DWORD yDest ! 648: ) ! 649: ! 650: /*++ ! 651: ! 652: Routine Description: ! 653: ! 654: This function output a compatible halftoned surface to the pscript device ! 655: ! 656: Arguments: ! 657: ! 658: ! 659: pdev - Pointer to the PDEVDATA data structure to determine what ! 660: type of postscript output for current device ! 661: ! 662: pso - engine SURFOBJ to be examine ! 663: ! 664: psoHT - compatible halftoned surface object ! 665: ! 666: xDest - the X bitmap start on the destination ! 667: ! 668: yDest - the Y bitmap start on the destination ! 669: ! 670: Return Value: ! 671: ! 672: BOOLEAN if function sucessful, failed if cannot allocate memory to do ! 673: the otuput. ! 674: ! 675: Author: ! 676: ! 677: 09-Feb-1993 Tue 20:45:37 created -by- Daniel Chou (danielc) ! 678: ! 679: ! 680: Revision History: ! 681: ! 682: ! 683: --*/ ! 684: ! 685: { ! 686: PDRVHTINFO pDrvHTInfo; ! 687: LPBYTE pbHTBits; ! 688: LPBYTE pbOutput; ! 689: SIZEL SizeBlt; ! 690: RECTL rclBounds; ! 691: LONG cbToNextScan; ! 692: DWORD AllocSize; ! 693: DWORD cxDestBytes; ! 694: DWORD cxDestDW; ! 695: DWORD xLoop; ! 696: DWORD yLoop; ! 697: BOOL Mono; ! 698: BOOL bMoreClipping; ! 699: BOOL bFirstClipPass; ! 700: DWORD dwBlack = RGB_BLACK; ! 701: ! 702: pDrvHTInfo = (PDRVHTINFO)(pdev->pvDrvHTData); ! 703: SizeBlt = psoHT->sizlBitmap; ! 704: cxDestBytes = (DWORD)((SizeBlt.cx + 7) >> 3); ! 705: ! 706: if (Mono = (BOOL)(psoHT->iBitmapFormat == BMF_1BPP)) { ! 707: ! 708: // ! 709: // Our 1bpp bit 0 is BLACK, so if it is a WHITE then allocate memory ! 710: // and flip the outcome ! 711: // ! 712: ! 713: if (pDrvHTInfo->PalXlate[0]) { ! 714: ! 715: cxDestDW = (DWORD)((cxDestBytes + 3) >> 2); ! 716: AllocSize = cxDestDW * sizeof(DWORD); ! 717: ! 718: #if DBG ! 719: if (DbgPSBitBlt) { ! 720: ! 721: DbgPrint("\nOutputHTCompatibleBits: MONO -- INVERT"); ! 722: } ! 723: #endif ! 724: ! 725: } else { ! 726: ! 727: #if DBG ! 728: if (DbgPSBitBlt) { ! 729: ! 730: DbgPrint("\nOutputHTCompatibleBits: MONO"); ! 731: } ! 732: #endif ! 733: AllocSize = 0; ! 734: } ! 735: ! 736: } else { ! 737: ! 738: #if DBG ! 739: if (DbgPSBitBlt) { ! 740: ! 741: DbgPrint("\nOutputHTCompatibleBits: 4 BIT --> 3 PLANES"); ! 742: } ! 743: #endif ! 744: ! 745: AllocSize = (DWORD)(cxDestBytes * 3); ! 746: } ! 747: ! 748: if (AllocSize) { ! 749: ! 750: if (!(pbOutput = (LPBYTE)HeapAlloc(pdev->hheap, 0, AllocSize))) { ! 751: #if DBG ! 752: DbgPrint("\nOutputHTCompatibleBits: HeapAlloc(HT CopyBits Buffer) Failed\n"); ! 753: #endif ! 754: return(FALSE); ! 755: } ! 756: ! 757: } else { ! 758: ! 759: pbOutput = NULL; ! 760: } ! 761: ! 762: // ! 763: // 1. Must clip the bitmap if 'pco' has clipping, and will send it down ! 764: // to the printer ! 765: // 2. Must do ps_save() before sending the image to the printer ! 766: ! 767: #if DBG ! 768: if (DbgPSBitBlt) { ! 769: ! 770: DbgPrint("\nOutputHTCompatibleBits: pco = %08lx", (DWORD)pco); ! 771: } ! 772: #endif ! 773: ! 774: bMoreClipping = TRUE; ! 775: bFirstClipPass = TRUE; ! 776: ! 777: while (bMoreClipping) ! 778: { ! 779: if (pdev->dwFlags & PDEV_CANCELDOC) ! 780: break; ! 781: ! 782: pbHTBits = (LPBYTE)psoHT->pvScan0; ! 783: ! 784: if ((bDoClipObj(pdev, pco, &rclBounds, NULL, &bMoreClipping, ! 785: &bFirstClipPass, MAX_CLIP_RECTS)) && (pco)) { ! 786: ! 787: // ! 788: // If clipping is send to the printer then ps_save() already done ! 789: // at bDoClipObj() ! 790: // ! 791: ! 792: #if DBG ! 793: if (DbgPSBitBlt) { ! 794: ! 795: DbgPrint("\nOutputHTCompatibleBits: PS_CLIP: Complex=%ld", ! 796: (DWORD)pco->iDComplexity); ! 797: DbgPrint("\nClip rclBounds = (%ld, %ld) - (%ld, %ld)", ! 798: rclBounds.left, ! 799: rclBounds.top, ! 800: rclBounds.right, ! 801: rclBounds.bottom); ! 802: } ! 803: #endif ! 804: ! 805: ps_clip(pdev, TRUE); ! 806: ! 807: } else { ! 808: ! 809: ps_save(pdev, TRUE); ! 810: } ! 811: ! 812: // ! 813: // Now we can start xlate the bits into 3 planes ! 814: // ! 815: ! 816: cbToNextScan = (LONG)psoHT->lDelta; ! 817: yLoop = (DWORD)SizeBlt.cy; ! 818: ! 819: #if DBG ! 820: if (DbgPSBitBlt) { ! 821: ! 822: DbgPrint("\n**** OutputHTCompatibleBits *****"); ! 823: DbgPrint("\nSizeBlt = %ld x %ld, Left/Top = (%ld, %ld)", ! 824: SizeBlt.cx, SizeBlt.cy, xDest, yDest); ! 825: DbgPrint("\ncxDestBytes = %ld, AllocSize = %ld", cxDestBytes, AllocSize); ! 826: ! 827: ! 828: } ! 829: #endif ! 830: // if we are doing the SourceOr hack, then we need to output the ! 831: // foreground color now. ! 832: ! 833: if (pdev->dwFlags & PDEV_SOURCEORHACK) ! 834: #ifdef INDEX_PAL ! 835: ps_setrgbcolor(pdev, (PALETTEENTRY *)&dwBlack); ! 836: #else ! 837: ps_setrgbcolor(pdev, (BGR_PAL_ENTRY *)&dwBlack); ! 838: #endif ! 839: BeginImage(pdev, Mono, xDest, yDest, SizeBlt.cx, SizeBlt.cy, ! 840: cxDestBytes); ! 841: ! 842: // clear the flag now. ! 843: ! 844: pdev->dwFlags &= ~PDEV_SOURCEORHACK; ! 845: ! 846: if (Mono) { ! 847: ! 848: // ! 849: // For 1BPP we output directly from the source bitmap buffer ! 850: // ! 851: ! 852: if (pbOutput) { ! 853: ! 854: // ! 855: // We need to invert each bit, since each scan line is DW aligned ! 856: // we can do it in 32-bit increment ! 857: // ! 858: ! 859: LPDWORD pdwMonoBits; ! 860: LPDWORD pdwFlipBits; ! 861: ! 862: while (yLoop--) { ! 863: ! 864: pdwFlipBits = (LPDWORD)pbOutput; ! 865: pdwMonoBits = (LPDWORD)pbHTBits; ! 866: pbHTBits += cbToNextScan; ! 867: xLoop = cxDestDW; ! 868: ! 869: while (xLoop--) { ! 870: ! 871: *pdwFlipBits++ = (DWORD)~(*pdwMonoBits++); ! 872: } ! 873: ! 874: if (pdev->dwFlags & PDEV_CANCELDOC) ! 875: break; ! 876: ! 877: vHexOut(pdev, (PBYTE)pbOutput, cxDestBytes); ! 878: PrintString(pdev, "\n"); ! 879: } ! 880: ! 881: } else { ! 882: ! 883: while (yLoop--) { ! 884: ! 885: if (pdev->dwFlags & PDEV_CANCELDOC) ! 886: break; ! 887: ! 888: vHexOut(pdev, pbHTBits, cxDestBytes); ! 889: PrintString(pdev, "\n"); ! 890: ! 891: pbHTBits += cbToNextScan; ! 892: } ! 893: } ! 894: ! 895: } else { ! 896: ! 897: PHTXB pHTXB; ! 898: PHTXB pSrc8Pels; ! 899: LPBYTE pbScanR0; ! 900: LPBYTE pbScanG0; ! 901: LPBYTE pbScanB0; ! 902: LPBYTE pbScanR; ! 903: LPBYTE pbScanG; ! 904: LPBYTE pbScanB; ! 905: HTXB htXB; ! 906: ! 907: ! 908: pHTXB = pDrvHTInfo->pHTXB; ! 909: pbScanR0 = pbOutput; ! 910: pbScanG0 = pbScanR0 + cxDestBytes; ! 911: pbScanB0 = pbScanG0 + cxDestBytes; ! 912: ! 913: while (yLoop--) { ! 914: ! 915: pSrc8Pels = (PHTXB)pbHTBits; ! 916: pbHTBits += cbToNextScan; ! 917: pbScanR = pbScanR0; ! 918: pbScanG = pbScanG0; ! 919: pbScanB = pbScanB0; ! 920: xLoop = cxDestBytes; ! 921: ! 922: while (xLoop--) { ! 923: ! 924: SRC8PELS_TO_3P_DW(htXB.dw, pHTXB, pSrc8Pels); ! 925: ! 926: *pbScanR++ = HTXB_R(htXB); ! 927: *pbScanG++ = HTXB_G(htXB); ! 928: *pbScanB++ = HTXB_B(htXB); ! 929: } ! 930: ! 931: if (pdev->dwFlags & PDEV_CANCELDOC) ! 932: break; ! 933: ! 934: vHexOut(pdev, pbScanR0, cxDestBytes); ! 935: PrintString(pdev, "\n"); ! 936: ! 937: vHexOut(pdev, pbScanG0, cxDestBytes); ! 938: PrintString(pdev, "\n"); ! 939: ! 940: vHexOut(pdev, pbScanB0, cxDestBytes); ! 941: PrintString(pdev, "\n"); ! 942: } ! 943: } ! 944: ! 945: // ! 946: // After ps_save() we better have ps_restore() to match it ! 947: // ! 948: ! 949: ps_restore(pdev, TRUE); ! 950: } ! 951: ! 952: // ! 953: // Release scan line buffers if we did allocate one ! 954: // ! 955: ! 956: if (pbOutput) { ! 957: ! 958: HeapFree(pdev->hheap, 0, (PVOID)pbOutput); ! 959: } ! 960: ! 961: return(TRUE); ! 962: } ! 963: ! 964: ! 965: ! 966: ! 967: BOOL ! 968: DrvCopyBits( ! 969: SURFOBJ *psoDest, ! 970: SURFOBJ *psoSrc, ! 971: CLIPOBJ *pco, ! 972: XLATEOBJ *pxlo, ! 973: RECTL *prclDest, ! 974: POINTL *pptlSrc ! 975: ) ! 976: ! 977: /*++ ! 978: ! 979: Routine Description: ! 980: ! 981: Convert between two bitmap formats ! 982: ! 983: Arguments: ! 984: ! 985: Per Engine spec. ! 986: ! 987: Return Value: ! 988: ! 989: BOOLEAN ! 990: ! 991: ! 992: Author: ! 993: ! 994: 11-Feb-1993 Thu 21:00:43 created -by- Daniel Chou (danielc) ! 995: ! 996: ! 997: Revision History: ! 998: ! 999: ! 1000: --*/ ! 1001: ! 1002: { ! 1003: PDEVDATA pdev; ! 1004: RECTL rclSrc; ! 1005: RECTL rclDest; ! 1006: RECTL rclClip; ! 1007: PRECTL prclClip; ! 1008: BOOL bClipping; ! 1009: BOOL bMoreClipping; ! 1010: BOOL bFirstClipPass; ! 1011: ! 1012: // ! 1013: // The DrvCopyBits() function let application convert between bitmap and ! 1014: // device format. ! 1015: // ! 1016: // BUT... for our postscript device we cannot read the printer surface ! 1017: // bitmap back, so tell the caller that we cannot do it if they ! 1018: // really called with these type of operations. ! 1019: // ! 1020: ! 1021: if (psoSrc->iType != STYPE_BITMAP) ! 1022: { ! 1023: return(EngEraseSurface(psoDest, prclDest, 0xffffffff)); ! 1024: } ! 1025: ! 1026: ! 1027: if (psoDest->iType != STYPE_DEVICE) { ! 1028: ! 1029: // ! 1030: // Someone try to copy to bitmap surface, ie STYPE_BITMAP ! 1031: // ! 1032: ! 1033: #if DBG ! 1034: DbgPrint("\nPSCRIPT!DrvCopyBits: Cannot copy to NON-DEVICE destination\n"); ! 1035: #endif ! 1036: SetLastError(ERROR_INVALID_PARAMETER); ! 1037: return(FALSE); ! 1038: } ! 1039: ! 1040: pdev = (PDEVDATA)psoDest->dhpdev; ! 1041: ! 1042: if (!bValidatePDEV(pdev)) { ! 1043: ! 1044: #if DBG ! 1045: DbgPrint("\nPSCRIPT!DrvCopyBits: Invalid PDEV for destination passed.\n"); ! 1046: #endif ! 1047: SetLastError(ERROR_INVALID_PARAMETER); ! 1048: return(FALSE); ! 1049: } ! 1050: ! 1051: if (pdev->dwFlags & PDEV_PSHALFTONE) ! 1052: { ! 1053: // ! 1054: // Let the Postscript interpreter do the halftoning. ! 1055: // ! 1056: rclSrc.left = pptlSrc->x; ! 1057: rclSrc.top = pptlSrc->y; ! 1058: rclSrc.right = pptlSrc->x + psoSrc->sizlBitmap.cx; ! 1059: rclSrc.bottom = pptlSrc->y + psoSrc->sizlBitmap.cy; ! 1060: ! 1061: prclClip = &rclClip; ! 1062: ! 1063: bMoreClipping = TRUE; ! 1064: bFirstClipPass = TRUE; ! 1065: ! 1066: while (bMoreClipping) ! 1067: { ! 1068: if (!(bClipping = bDoClipObj(pdev, pco, &rclClip, prclDest, ! 1069: &bMoreClipping, &bFirstClipPass, ! 1070: MAX_CLIP_RECTS))) ! 1071: prclClip = NULL; ! 1072: else ! 1073: ps_clip(pdev, TRUE); ! 1074: ! 1075: // DoSourceCopy does not know how to use prclClip, so don't give it one. ! 1076: // if (!DoSourceCopy(pdev, psoSrc, &rclSrc, prclDest, pxlo, prclClip, ! 1077: if (!DoSourceCopy(pdev, psoSrc, &rclSrc, prclDest, pxlo, NULL, ! 1078: FALSE)) ! 1079: return(FALSE); ! 1080: ! 1081: if (bClipping) ! 1082: ps_restore(pdev, TRUE); ! 1083: } ! 1084: } ! 1085: else ! 1086: { ! 1087: // ! 1088: // First validate everything to see if this one is the halftoned result ! 1089: // or compatible with halftoned result, otherwise call HalftoneBlt() to ! 1090: // halftone the sources then it will eventually come back to this ! 1091: // function to output the halftoned result. ! 1092: // ! 1093: ! 1094: if ((pptlSrc->x == 0) && ! 1095: (pptlSrc->y == 0) && ! 1096: (prclDest->left >= 0) && ! 1097: (prclDest->top >= 0) && ! 1098: (prclDest->right <= psoDest->sizlBitmap.cx) && ! 1099: (prclDest->bottom <= psoDest->sizlBitmap.cy) && ! 1100: ((prclDest->right - prclDest->left) == psoSrc->sizlBitmap.cx) && ! 1101: ((prclDest->bottom - prclDest->top) == psoSrc->sizlBitmap.cy) && ! 1102: (IsHTCompatibleSurfObj(pdev, psoSrc, pxlo))) { ! 1103: ! 1104: return(OutputHTCompatibleBits(pdev, ! 1105: psoSrc, ! 1106: pco, ! 1107: prclDest->left, ! 1108: prclDest->top)); ! 1109: ! 1110: } else { ! 1111: ! 1112: ! 1113: rclDest = *prclDest; ! 1114: rclSrc.left = pptlSrc->x; ! 1115: rclSrc.top = pptlSrc->y; ! 1116: rclSrc.right = rclSrc.left + (rclDest.right - rclDest.left); ! 1117: rclSrc.bottom = rclSrc.top + (rclDest.bottom - rclDest.top); ! 1118: ! 1119: // ! 1120: // Validate that we only BLT the available source size ! 1121: // ! 1122: ! 1123: if ((rclSrc.right > psoSrc->sizlBitmap.cx) || ! 1124: (rclSrc.bottom > psoSrc->sizlBitmap.cy)) { ! 1125: ! 1126: #if DBG ! 1127: DbgPrint("\nWARNING: PSCRIPT!DrvCopyBits: Engine passed SOURCE != DEST size, CLIP IT"); ! 1128: #endif ! 1129: rclSrc.right = psoSrc->sizlBitmap.cx; ! 1130: rclSrc.bottom = psoSrc->sizlBitmap.cy; ! 1131: ! 1132: rclDest.right = (LONG)(rclSrc.right - rclSrc.left + rclDest.left); ! 1133: rclDest.bottom = (LONG)(rclSrc.bottom - rclSrc.top + rclDest.top); ! 1134: } ! 1135: ! 1136: #if DBG ! 1137: if (DbgPSBitBlt) { ! 1138: ! 1139: DbgPrint("\nDrvCopyBits CALLING HalftoneBlt()."); ! 1140: } ! 1141: #endif ! 1142: ! 1143: return(HalftoneBlt(pdev, ! 1144: psoDest, ! 1145: psoSrc, ! 1146: NULL, // no source mask ! 1147: pco, ! 1148: pxlo, ! 1149: NULL, // Default color adjustment ! 1150: NULL, // Brush origin at (0,0) ! 1151: &rclDest, ! 1152: &rclSrc, ! 1153: NULL, // No source mask ! 1154: FALSE)); // SRCCOPY ! 1155: } ! 1156: } ! 1157: } ! 1158: ! 1159: ! 1160: ! 1161: ! 1162: BOOL ! 1163: DrvStretchBlt( ! 1164: SURFOBJ *psoDest, ! 1165: SURFOBJ *psoSrc, ! 1166: SURFOBJ *psoMask, ! 1167: CLIPOBJ *pco, ! 1168: XLATEOBJ *pxlo, ! 1169: COLORADJUSTMENT *pca, ! 1170: POINTL *pptlBrushOrg, ! 1171: PRECTL prclDest, ! 1172: PRECTL prclSrc, ! 1173: PPOINTL pptlMask, ! 1174: ULONG iMode ! 1175: ) ! 1176: ! 1177: /*++ ! 1178: ! 1179: Routine Description: ! 1180: ! 1181: This function halfotne a soource rectangle area to the destination ! 1182: rectangle area with options of invver source, and source masking ! 1183: ! 1184: Provides stretching Blt capabilities between any combination of device ! 1185: managed and GDI managed surfaces. We want the device driver to be able ! 1186: to write on GDI bitmaps especially when it can do halftoning. This ! 1187: allows us to get the same halftoning algorithm applied to GDI bitmaps ! 1188: and device surfaces. ! 1189: ! 1190: This function is optional. It can also be provided to handle only some ! 1191: kinds of stretching, for example by integer multiples. This function ! 1192: should return FALSE if it gets called to perform some operation it ! 1193: doesn't know how to do. ! 1194: ! 1195: Arguments: ! 1196: ! 1197: psoDest ! 1198: This is a pointer to a SURFOBJ. It identifies the surface on which ! 1199: to draw. ! 1200: ! 1201: psoSrc ! 1202: This SURFOBJ defines the source for the Blt operation. The driver ! 1203: must call GDI Services to find out if this is a device managed ! 1204: surface or a bitmap managed by GDI. ! 1205: ! 1206: psoMask ! 1207: This optional surface provides a mask for the source. It is defined ! 1208: by a logic map, i.e. a bitmap with one bit per pel. ! 1209: ! 1210: The mask is used to limit the area of the source that is copied. ! 1211: When a mask is provided there is an implicit rop4 of 0xCCAA, which ! 1212: means that the source should be copied wherever the mask is 1, but ! 1213: the destination should be left alone wherever the mask is 0. ! 1214: ! 1215: When this argument is NULL there is an implicit rop4 of 0xCCCC, ! 1216: which means that the source should be copied everywhere in the ! 1217: source rectangle. ! 1218: ! 1219: The mask will always be large enough to contain the source ! 1220: rectangle, tiling does not need to be done. ! 1221: ! 1222: pco ! 1223: This is a pointer to a CLIPOBJ. GDI Services are provided to ! 1224: enumerate the clipping region as a set of rectangles or trapezoids. ! 1225: This limits the area of the destination that will be modified. ! 1226: ! 1227: Whenever possible, GDI will simplify the clipping involved. ! 1228: However, unlike DrvBitBlt, DrvStretchBlt may be called with a ! 1229: single clipping rectangle. This is necessary to prevent roundoff ! 1230: errors in clipping the output. ! 1231: ! 1232: pxlo ! 1233: This is a pointer to an XLATEOBJ. It tells how color indices should ! 1234: be translated between the source and target surfaces. ! 1235: ! 1236: The XLATEOBJ can also be queried to find the RGB color for any source ! 1237: index. A high quality stretching Blt will need to interpolate colors ! 1238: in some cases. ! 1239: ! 1240: pca ! 1241: This is a pointer to COLORADJUSTMENT structure, if NULL it specified ! 1242: that appiclation did not set any color adjustment for this DC, and is ! 1243: up to the driver to provide default adjustment ! 1244: ! 1245: pptlBrushOrg ! 1246: Pointer to the POINT structure to specified the location where halftone ! 1247: brush should alignment to, if this pointer is NULL then it assume that ! 1248: (0, 0) as origin of the brush ! 1249: ! 1250: prclDest ! 1251: This RECTL defines the area in the coordinate system of the ! 1252: destination surface that can be modified. ! 1253: ! 1254: The rectangle is defined by two points. These points are not well ! 1255: ordered, i.e. the coordinates of the second point are not necessarily ! 1256: larger than those of the first point. The rectangle they describe ! 1257: does not include the lower and right edges. DrvStretchBlt will never ! 1258: be called with an empty destination rectangle. ! 1259: ! 1260: DrvStretchBlt can do inversions in both x and y, this happens when ! 1261: the destination rectangle is not well ordered. ! 1262: ! 1263: prclSrc ! 1264: This RECTL defines the area in the coordinate system of the source ! 1265: surface that will be copied. The rectangle is defined by two points, ! 1266: and will map onto the rectangle defined by prclDest. The points of ! 1267: the source rectangle are well ordered. DrvStretch will never be given ! 1268: an empty source rectangle. ! 1269: ! 1270: Note that the mapping to be done is defined by prclSrc and prclDest. ! 1271: To be precise, the given points in prclDest and prclSrc lie on ! 1272: integer coordinates, which we consider to correspond to pel centers. ! 1273: A rectangle defined by two such points should be considered a ! 1274: geometric rectangle with two vertices whose coordinates are the given ! 1275: points, but with 0.5 subtracted from each coordinate. (The POINTLs ! 1276: should just be considered a shorthand notation for specifying these ! 1277: fractional coordinate vertices.) Note thate the edges of any such ! 1278: rectangle never intersect a pel, but go around a set of pels. Note ! 1279: also that the pels that are inside the rectangle are just what you ! 1280: would expect for a "bottom-right exclusive" rectangle. The mapping ! 1281: to be done by DrvStretchBlt will map the geometric source rectangle ! 1282: exactly onto the geometric destination rectangle. ! 1283: ! 1284: pptlMask ! 1285: This POINTL specifies which pel in the given mask corresponds to ! 1286: the upper left pel in the source rectangle. Ignore this argument ! 1287: if there is no given mask. ! 1288: ! 1289: ! 1290: iMode ! 1291: This defines how source pels should be combined to get output pels. ! 1292: The methods SB_OR, SB_AND, and SB_IGNORE are all simple and fast. ! 1293: They provide compatibility for old applications, but don't produce ! 1294: the best looking results for color surfaces. ! 1295: ! 1296: ! 1297: SB_OR On a shrinking Blt the pels should be combined with an ! 1298: OR operation. On a stretching Blt pels should be ! 1299: replicated. ! 1300: SB_AND On a shrinking Blt the pels should be combined with an ! 1301: AND operation. On a stretching Blt pels should be ! 1302: replicated. ! 1303: SB_IGNORE On a shrinking Blt enough pels should be ignored so that ! 1304: pels don't need to be combined. On a stretching Blt pels ! 1305: should be replicated. ! 1306: SB_BLEND RGB colors of output pels should be a linear blending of ! 1307: the RGB colors of the pels that get mapped onto them. ! 1308: SB_HALFTONE The driver may use groups of pels in the output surface ! 1309: to best approximate the color or gray level of the input. ! 1310: ! 1311: ! 1312: For this function we will ignored this parameter and always output ! 1313: the SB_HALFTONE result ! 1314: ! 1315: ! 1316: Return Value: ! 1317: ! 1318: ! 1319: BOOLEAN ! 1320: ! 1321: ! 1322: Author: ! 1323: ! 1324: 11-Feb-1993 Thu 19:52:29 created -by- Daniel Chou (danielc) ! 1325: ! 1326: ! 1327: Revision History: ! 1328: ! 1329: ! 1330: --*/ ! 1331: ! 1332: { ! 1333: PDEVDATA pdev; ! 1334: ! 1335: UNREFERENCED_PARAMETER(iMode); // we always do HALFTONE ! 1336: ! 1337: // ! 1338: // get the pointer to our DEVDATA structure and make sure it is ours. ! 1339: // ! 1340: ! 1341: pdev = (PDEVDATA)psoDest->dhpdev; ! 1342: ! 1343: if (!bValidatePDEV(pdev)) { ! 1344: ! 1345: RIP("PSCRIPT!DrvStretchBlt: invalid pdev.\n"); ! 1346: SetLastError(ERROR_INVALID_PARAMETER); ! 1347: return(FALSE); ! 1348: } ! 1349: ! 1350: // clear the source OR hack bit. ! 1351: ! 1352: pdev->dwFlags &= ~PDEV_SOURCEORHACK; ! 1353: ! 1354: return(HalftoneBlt(pdev, // pdev ! 1355: psoDest, // Dest ! 1356: psoSrc, // SRC ! 1357: psoMask, // ----- psoMask ! 1358: pco, // CLIPOBJ ! 1359: pxlo, // XLATEOBJ ! 1360: pca, // COLORADJUSTMENT ! 1361: pptlBrushOrg, // BRUSH ORG ! 1362: prclDest, // DEST RECT ! 1363: prclSrc, // SRC RECT ! 1364: pptlMask, // ----- pptlMask ! 1365: FALSE)); // SrcCopy ! 1366: } ! 1367: ! 1368: ! 1369: //-------------------------------------------------------------------------- ! 1370: // VOID DrvBitBlt( ! 1371: // PSURFOBJ psoTrg, // Target surface ! 1372: // PSURFOBJ psoSrc, // Source surface ! 1373: // PSURFOBJ psoMask, // Mask ! 1374: // PCLIPOBJ pco, // Clip through this ! 1375: // PXLATEOBJ pxlo, // Color translation ! 1376: // PRECTL prclTrg, // Target offset and extent ! 1377: // PPOINTL pptlSrc, // Source offset ! 1378: // PPOINTL pptlMask, // Mask offset ! 1379: // PBRUSHOBJ pbo, // Brush data ! 1380: // PPOINTL pptlBrush, // Brush offset ! 1381: // ROP4 rop4); // Raster operation ! 1382: // ! 1383: // Provides general Blt capabilities to device managed surfaces. The Blt ! 1384: // might be from an Engine managed bitmap. In that case, the bitmap is ! 1385: // one of the standard format bitmaps. The driver will never be asked ! 1386: // to Blt to an Engine managed surface. ! 1387: // ! 1388: // This function is required if any drawing is done to device managed ! 1389: // surfaces. The basic functionality required is: ! 1390: // ! 1391: // 1 Blt from any standard format bitmap or device surface to a device ! 1392: // surface, ! 1393: // ! 1394: // 2 with any ROP, ! 1395: // ! 1396: // 3 optionally masked, ! 1397: // ! 1398: // 4 with color index translation, ! 1399: // ! 1400: // 5 with arbitrary clipping. ! 1401: // ! 1402: // Engine services allow the clipping to be reduced to a series of clip ! 1403: // rectangles. A translation vector is provided to assist in color index ! 1404: // translation for palettes. ! 1405: // ! 1406: // This is a large and complex function. It represents most of the work ! 1407: // in writing a driver for a raster display device that does not have ! 1408: // a standard format frame buffer. The Microsoft VGA driver provides ! 1409: // example code that supports the basic function completely for a planar ! 1410: // device. ! 1411: // ! 1412: // NOTE: PostScript printers do not support copying from device bitmaps. ! 1413: // Nor can they perform raster operations on bitmaps. Therefore, ! 1414: // it is not possible to support ROPs which interact with the ! 1415: // destination (ie inverting the destination). The driver will ! 1416: // do its best to map these ROPs into ROPs utilizing functions on ! 1417: // the Source or Pattern. ! 1418: // ! 1419: // This driver supports the bitblt cases indicated below: ! 1420: // ! 1421: // Device -> Memory No ! 1422: // Device -> Device No ! 1423: // Memory -> Memory No ! 1424: // Memory -> Device Yes ! 1425: // Brush -> Memory No ! 1426: // Brush -> Device Yes ! 1427: // ! 1428: // Parameters: ! 1429: // <psoDest> ! 1430: // This is a pointer to a device managed SURFOBJ. It identifies the ! 1431: // surface on which to draw. ! 1432: // ! 1433: // <psoSrc> ! 1434: // If the rop requires it, this SURFOBJ defines the source for the ! 1435: // Blt operation. The driver must call the Engine Services to find out ! 1436: // if this is a device managed surface or a bitmap managed by the ! 1437: // Engine. ! 1438: // ! 1439: // <psoMask> ! 1440: // This optional surface provides another input for the rop4. It is ! 1441: // defined by a logic map, i.e. a bitmap with one bit per pel. ! 1442: // ! 1443: // The mask is typically used to limit the area of the destination that ! 1444: // should be modified. This masking is accomplished by a rop4 whose ! 1445: // lower byte is AA, leaving the destination unaffected when the mask ! 1446: // is 0. ! 1447: // ! 1448: // This mask, like a brush, may be of any size and is assumed to tile ! 1449: // to cover the destination of the Blt. ! 1450: // ! 1451: // If this argument is NULL and a mask is required by the rop4, the ! 1452: // implicit mask in the brush will be used. ! 1453: // ! 1454: // <pco> ! 1455: // This is a pointer to a CLIPOBJ. Engine Services are provided to ! 1456: // enumerate the clipping region as a set of rectangles or trapezoids. ! 1457: // This limits the area of the destination that will be modified. ! 1458: // ! 1459: // Whenever possible, the Graphics Engine will simplify the clipping ! 1460: // involved. For example, vBitBlt will never be called with exactly ! 1461: // one clipping rectangle. The Engine will have clipped the destination ! 1462: // rectangle before calling, so that no clipping needs to be considered. ! 1463: // ! 1464: // <pxlo> ! 1465: // This is a pointer to an XLATEOBJ. It tells how color indices should ! 1466: // be translated between the source and target surfaces. ! 1467: // ! 1468: // If the source surface is palette managed, then its colors are ! 1469: // represented by indices into a list of RGB colors. In this case, the ! 1470: // XLATEOBJ can be queried to get a translate vector that will allow ! 1471: // the device driver to quickly translate any source index into a color ! 1472: // index for the destination. ! 1473: // ! 1474: // The situation is more complicated when the source is, for example, ! 1475: // RGB but the destination is palette managed. In this case a closest ! 1476: // match to each source RGB must be found in the destination palette. ! 1477: // The XLATEOBJ provides a service routine to do this matching. (The ! 1478: // device driver is allowed to do the matching itself when the target ! 1479: // palette is the default device palette.) ! 1480: // ! 1481: // <prclDest> ! 1482: // This RECTL defines the area in the coordinate system of the ! 1483: // destination surface that will be modified. The rectangle is defined ! 1484: // as two points, upper left and lower right. The lower and right edges ! 1485: // of this rectangle are not part of the Blt, i.e. the rectangle is ! 1486: // lower right exclusive. vBitBlt will never be called with an empty ! 1487: // destination rectangle, and the two points of the rectangle will ! 1488: // always be well ordered. ! 1489: // ! 1490: // <pptlSrc> ! 1491: // This POINTL defines the upper left corner of the source rectangle, if ! 1492: // there is a source. Ignore this argument if there is no source. ! 1493: // ! 1494: // <pptlMask> ! 1495: // This POINTL defines which pel in the mask corresponds to the upper ! 1496: // left corner of the destination rectangle. Ignore this argument if ! 1497: // no mask is provided with psoMask. ! 1498: // ! 1499: // <pdbrush> ! 1500: // This is a pointer to the device's realization of the brush to be ! 1501: // used in the Blt. The pattern for the Blt is defined by this brush. ! 1502: // Ignore this argument if the rop4 does not require a pattern. ! 1503: // ! 1504: // <pptlBrushOrigin> ! 1505: // This is a pointer to a POINTL which defines the origin of the brush. ! 1506: // The upper left pel of the brush is aligned here and the brush repeats ! 1507: // according to its dimensions. Ignore this argument if the rop4 does ! 1508: // not require a pattern. ! 1509: // ! 1510: // <rop4> ! 1511: // This raster operation defines how the mask, pattern, source, and ! 1512: // destination pels should be combined to determine an output pel to be ! 1513: // written on the destination surface. ! 1514: // ! 1515: // This is a quaternary raster operation, which is a natural extension ! 1516: // of the usual ternary rop3. There are 16 relevant bits in the rop4, ! 1517: // these are like the 8 defining bits of a rop3. (We ignore the other ! 1518: // bits of the rop3, which are redundant.) The simplest way to ! 1519: // implement a rop4 is to consider its two bytes separately. The lower ! 1520: // byte specifies a rop3 that should be computed wherever the mask ! 1521: // is 0. The high byte specifies a rop3 that should then be computed ! 1522: // and applied wherever the mask is 1. ! 1523: // ! 1524: // NOTE: The PostScript driver cannot do anything with any raster ops ! 1525: // which utilize the destination. This means we only support the following ! 1526: // 17 raster ops: ! 1527: // ! 1528: // BLACKNESS_ROP 0x00 ! 1529: // SRCORPATNOT_ROP 0x03 ! 1530: // PATNOTSRCAND_ROP 0x0C ! 1531: // PATNOT_ROP 0x0F ! 1532: // SRCNOTPATAND_ROP 0x30 ! 1533: // SRCNOT_ROP 0x33 ! 1534: // SRCXORPAT_ROP 0x3C ! 1535: // SRCANDPATNOT_ROP 0x3F ! 1536: // DST_ROP 0xAA ! 1537: // SRCANDPAT_ROP 0xC0 ! 1538: // SRCXORPATNOT_ROP 0xC3 ! 1539: // SRC_ROP 0xCC ! 1540: // PATNOTSRCOR_ROP 0xCF ! 1541: // PAT_ROP 0xF0 ! 1542: // SRCNOTPATOR_ROP 0xF3 ! 1543: // SRCORPAT_ROP 0xFC ! 1544: // WHITENESS_ROP 0xFF ! 1545: // ! 1546: // NOTE: PostScript printers cannot handle bitmap masking. What this ! 1547: // translates to is that if the background rop3 is AA (Destination) ! 1548: // there is no way for the printer to not overwrite the background. ! 1549: // ! 1550: // Returns: ! 1551: // This function does not return a value. ! 1552: // ! 1553: // History: ! 1554: // 17-Mar-1993 Thu 21:29:15 updated -by- Rob Kiesler ! 1555: // Added a code path to allow the PS Interpreter to do halftoning when ! 1556: // the option is selected by the user. ! 1557: // ! 1558: // 11-Feb-1993 Thu 21:29:15 updated -by- Daniel Chou (danielc) ! 1559: // Modified so that it call DrvStretchBlt(HALFTONE) when it can. ! 1560: // ! 1561: // 27-Mar-1992 Fri 00:08:43 updated -by- Daniel Chou (danielc) ! 1562: // 1) Remove 'pco' parameter and replaced it with prclClipBound parameter, ! 1563: // since pco is never referenced, prclClipBound is used for the ! 1564: // halftone. ! 1565: // 2) Add another parameter to do NOTSRCCOPY ! 1566: // 04-Dec-1990 -by- Kent Settle (kentse) ! 1567: // Wrote it. ! 1568: //-------------------------------------------------------------------------- ! 1569: ! 1570: BOOL DrvBitBlt( ! 1571: SURFOBJ *psoTrg, // Target surface ! 1572: SURFOBJ *psoSrc, // Source surface ! 1573: SURFOBJ *psoMask, // Mask ! 1574: CLIPOBJ *pco, // Clip through this ! 1575: XLATEOBJ *pxlo, // Color translation ! 1576: PRECTL prclTrg, // Target offset and extent ! 1577: PPOINTL pptlSrc, // Source offset ! 1578: PPOINTL pptlMask, // Mask offset ! 1579: BRUSHOBJ *pbo, // Brush data ! 1580: PPOINTL pptlBrush, // Brush offset ! 1581: ROP4 rop4) // Raster operation ! 1582: { ! 1583: PDEVDATA pdev; ! 1584: PDRVHTINFO pDrvHTInfo; ! 1585: RECTL rclSrc; ! 1586: ULONG ulColor; ! 1587: BOOL bInvertPat; ! 1588: BOOL bClipping; ! 1589: BOOL NotSrcCopy; ! 1590: PRECTL prclClip; ! 1591: RECTL rclClip; ! 1592: RECTL rclTmp; ! 1593: BOOL bMoreClipping; ! 1594: BOOL bFirstClipPass; ! 1595: ! 1596: // make sure none of the high bits are set. ! 1597: ! 1598: ASSERTPS((rop4 & 0xffff0000) == 0, "DrvBitBlt: invalid ROP.\n"); ! 1599: ! 1600: // ! 1601: // get the pointer to our DEVDATA structure and make sure it is ours. ! 1602: // ! 1603: ! 1604: pdev = (PDEVDATA)psoTrg->dhpdev; ! 1605: ! 1606: if (!bValidatePDEV(pdev)) { ! 1607: ! 1608: RIP("PSCRIPT!DrvBitBlt: invalid pdev.\n"); ! 1609: SetLastError(ERROR_INVALID_PARAMETER); ! 1610: return(FALSE); ! 1611: } ! 1612: ! 1613: // ! 1614: // Do DrvStretchBlt(HALFTONE) first if we can, notices that we do not ! 1615: // handle source masking case, because we cannot read back whatever on ! 1616: // the printer surface, also we can just output it to the printer ! 1617: // if the source bitmap/color is same or compatible with halftoned palette ! 1618: // ! 1619: ! 1620: if (!(pDrvHTInfo = (PDRVHTINFO)(pdev->pvDrvHTData))) { ! 1621: ! 1622: DbgPrint("\nPSCRIPT!DrvBitBlt: pDrvHTInfo = NULL ???\n"); ! 1623: return(FALSE); ! 1624: } ! 1625: ! 1626: NotSrcCopy = FALSE; ! 1627: ! 1628: // ! 1629: // Following are the one involve with source and destination. each rop4 ! 1630: // will have two version, one for rop3/rop3 other for rop3/mask ! 1631: // ! 1632: ! 1633: ! 1634: // clear the source OR hack bit. ! 1635: ! 1636: pdev->dwFlags &= ~PDEV_SOURCEORHACK; ! 1637: ! 1638: switch (rop4) { ! 1639: ! 1640: ! 1641: //---------------------------------------------------------------------- ! 1642: // Rop4 Request Op. SrcMASK Pscript Result Op. ! 1643: //---------------------------------------------------------------------- ! 1644: ! 1645: case 0xB8B8: // ugly raster op that apps seem to use to blt text ! 1646: case 0xB8AA: // to our surface, when they treat us as a raster device. ! 1647: ! 1648: if (psoSrc->iBitmapFormat == BMF_1BPP) ! 1649: pdev->dwFlags |= PDEV_SOURCEORHACK; ! 1650: ! 1651: case 0x1111: // ~( S | D) ~S ! 1652: case 0x11AA: // ~( S | D) + SrcMask ~S ! 1653: ! 1654: case 0x3333: // (~S ) ~S ! 1655: case 0x33AA: // (~S ) + SrcMask ~S ! 1656: ! 1657: case 0x9999: // ~( S ^ D) ~S ! 1658: case 0x99AA: // ~( S ^ D) + SrcMask ~S ! 1659: ! 1660: case 0xBBBB: // (~S | D) ~S ! 1661: case 0xBBAA: // (~S | D) + SrcMask ~S ! 1662: ! 1663: case 0x7777: // ~( S & D) ~S ! 1664: case 0x77AA: // ~( S & D) + SrcMask ~S ! 1665: ! 1666: NotSrcCopy = TRUE; ! 1667: ! 1668: case 0x4444: // ( S & ~D) S ! 1669: case 0x44AA: // ( S & ~D) + SrcMask S ! 1670: ! 1671: case 0x6666: // ( S ^ D) S ! 1672: case 0x66AA: // ( S ^ D) + SrcMask S ! 1673: ! 1674: case 0x8888: // ( S & D) S ! 1675: case 0x88AA: // ( S & D) + SrcMask S ! 1676: ! 1677: case 0xCCCC: // ( S ) S ! 1678: case 0xCCAA: // ( S ) + SrcMask S ! 1679: ! 1680: case 0xDDDD: // ( S | ~D) S ! 1681: case 0xDDAA: // ( S | ~D) + SrcMask S ! 1682: ! 1683: case 0xEEEE: // ( S | D) S ! 1684: case 0xEEAA: // ( S | D) + SrcMask S ! 1685: ! 1686: if (pdev->dwFlags & PDEV_PSHALFTONE) ! 1687: { ! 1688: // ! 1689: // Let the Postscript interpreter do the halftoning. ! 1690: // ! 1691: rclSrc.left = pptlSrc->x; ! 1692: rclSrc.top = pptlSrc->y; ! 1693: rclSrc.right = pptlSrc->x + psoSrc->sizlBitmap.cx; ! 1694: rclSrc.bottom = pptlSrc->y + psoSrc->sizlBitmap.cy; ! 1695: ! 1696: prclClip = &rclClip; ! 1697: ! 1698: bMoreClipping = TRUE; ! 1699: bFirstClipPass = TRUE; ! 1700: ! 1701: while (bMoreClipping) ! 1702: { ! 1703: if (!(bClipping = bDoClipObj(pdev, pco, &rclClip, prclTrg, ! 1704: &bMoreClipping, &bFirstClipPass, ! 1705: MAX_CLIP_RECTS))) ! 1706: prclClip = NULL; ! 1707: else ! 1708: ps_clip(pdev, TRUE); ! 1709: ! 1710: // DoSourceCopy does not know how to use prclClip, so don't give it one. ! 1711: // if (!DoSourceCopy(pdev, psoSrc, &rclSrc, prclTrg, pxlo, prclClip, ! 1712: if (!DoSourceCopy(pdev, psoSrc, &rclSrc, prclTrg, pxlo, NULL, ! 1713: NotSrcCopy)) ! 1714: return(FALSE); ! 1715: ! 1716: if (bClipping) ! 1717: ps_restore(pdev, TRUE); ! 1718: } ! 1719: ! 1720: break; ! 1721: } ! 1722: else ! 1723: { ! 1724: // ! 1725: // We will output the bitmap directly to the surface if following ! 1726: // conditions are all met ! 1727: // ! 1728: // 1. SRC = STYPE_BITMAP ! 1729: // 2. No source mask ! 1730: // 3. Source left/top = { 0, 0 } ! 1731: // 4. Destination RECTL is visible on the destination surface ! 1732: // 5. Destination RECTL size same as source bitmap size ! 1733: // ! 1734: ! 1735: if ((psoSrc->iType == STYPE_BITMAP) && ! 1736: ((rop4 & 0xff) != 0xAA) && ! 1737: (pptlSrc->x == 0) && ! 1738: (pptlSrc->y == 0) && ! 1739: (prclTrg->left >= 0) && ! 1740: (prclTrg->top >= 0) && ! 1741: (prclTrg->right <= psoTrg->sizlBitmap.cx) && ! 1742: (prclTrg->bottom <= psoTrg->sizlBitmap.cy) && ! 1743: ((prclTrg->right - prclTrg->left) == psoSrc->sizlBitmap.cx) && ! 1744: ((prclTrg->bottom - prclTrg->top) == psoSrc->sizlBitmap.cy) && ! 1745: (IsHTCompatibleSurfObj(pdev, psoSrc, pxlo))) { ! 1746: ! 1747: return(OutputHTCompatibleBits(pdev, ! 1748: psoSrc, ! 1749: pco, ! 1750: prclTrg->left, ! 1751: prclTrg->top)); ! 1752: } ! 1753: ! 1754: // ! 1755: // If we did not met above conditions then passed it to the ! 1756: // HalftoneBlt(HALFTONE) and eventually it will come back to BitBlt() ! 1757: // with (0xCCCC) or DrvCopyBits() ! 1758: // ! 1759: // The reason we pass the source mask to the HalftoneBlt() function is ! 1760: // that when GDI engine create a shadow bitmap it will ask driver to ! 1761: // provide the current destination surface bits but since we cannot ! 1762: // read back from destination surface we will return FAILED in ! 1763: // DrvCopyBits(FROM DEST) and engine will just WHITE OUT shadow bitmap ! 1764: // (by DrvBitBlt(WHITENESS) before it doing SRC MASK COPY. ! 1765: // ! 1766: ! 1767: if ((rop4 & 0xFF) != 0xAA) { ! 1768: ! 1769: psoMask = NULL; ! 1770: pptlMask = NULL; ! 1771: } ! 1772: ! 1773: rclSrc.left = pptlSrc->x; ! 1774: rclSrc.top = pptlSrc->y; ! 1775: rclSrc.right = rclSrc.left + (prclTrg->right - prclTrg->left); ! 1776: rclSrc.bottom = rclSrc.top + (prclTrg->bottom - prclTrg->top); ! 1777: ! 1778: return(HalftoneBlt(pdev, ! 1779: psoTrg, ! 1780: psoSrc, ! 1781: psoMask, // no mask ! 1782: pco, ! 1783: pxlo, ! 1784: &(pDrvHTInfo->ca), // default clradj ! 1785: NULL, // Brush Origin = (0,0) ! 1786: prclTrg, ! 1787: &rclSrc, ! 1788: pptlMask, ! 1789: NotSrcCopy)); ! 1790: } ! 1791: } ! 1792: // ! 1793: // Now following are not HalftoneBlt() cases ! 1794: // update the SURFOBJ pointer in our PDEV. ! 1795: // ! 1796: ! 1797: // ! 1798: // set some flags concerning the bitmap. ! 1799: // rop4 is a quaternary raster operation, which is a natural extension ! 1800: // of the usual ternary rop3. There are 16 relevant bits in the rop4, ! 1801: // these are like the 8 defining bits of a rop3. (We ignore the other ! 1802: // bits of the rop3, which are redundant.) The simplest way to ! 1803: // implement a rop4 is to consider its two bytes separately. The lower ! 1804: // byte specifies a rop3 that should be computed wherever the mask ! 1805: // is 0. The high byte specifies a rop3 that should then be computed ! 1806: // and applied wherever the mask is 1. if both of the rop3s are the ! 1807: // same, then a mask is not needed. otherwise a mask is necessary. ! 1808: ! 1809: #if 0 ! 1810: if ((rop4 >> 8) != (rop4 & 0xff)) ! 1811: { ! 1812: RIP("PSCRIPT: vBitBlt - mask needed.\n"); ! 1813: return(FALSE); ! 1814: } ! 1815: #endif ! 1816: ! 1817: // assume patterns will not be inverted. ! 1818: ! 1819: bInvertPat = FALSE; ! 1820: ! 1821: switch(rop4) { ! 1822: ! 1823: case 0xFFFF: // WHITENESS. ! 1824: case 0xFFAA: // WHITENESS. ! 1825: case 0x0000: // BLACKNESS. ! 1826: case 0x00AA: // BLACKNESS. ! 1827: ! 1828: if ((rop4 == 0xFFFF) || (rop4 == 0xFFAA)) ! 1829: ulColor = RGB_WHITE; ! 1830: else ! 1831: ulColor = RGB_BLACK; ! 1832: ! 1833: // handle the clip object passed in. ! 1834: ! 1835: bMoreClipping = TRUE; ! 1836: bFirstClipPass = TRUE; ! 1837: ! 1838: while (bMoreClipping) ! 1839: { ! 1840: bClipping = bDoClipObj(pdev, pco, NULL, prclTrg, &bMoreClipping, ! 1841: &bFirstClipPass, MAX_CLIP_RECTS); ! 1842: ! 1843: if (bClipping) { ! 1844: ! 1845: ps_clip(pdev, TRUE); ! 1846: } ! 1847: ! 1848: #ifdef INDEX_PAL ! 1849: ps_setrgbcolor(pdev, (PALETTEENTRY *)&ulColor); ! 1850: #else ! 1851: ps_setrgbcolor(pdev, (BGR_PAL_ENTRY *)&ulColor); ! 1852: #endif ! 1853: ! 1854: // position the image on the page, remembering to flip the image ! 1855: // from top to bottom. ! 1856: ! 1857: // remember, with bitblt, the target rectangle is bottom/right ! 1858: // exclusive. ! 1859: ! 1860: rclTmp.left = prclTrg->left; ! 1861: rclTmp.top = prclTrg->top; ! 1862: rclTmp.right = prclTrg->right; ! 1863: rclTmp.bottom = prclTrg->bottom; ! 1864: ! 1865: if ((prclTrg->right - prclTrg->left) > 1) ! 1866: rclTmp.right -= 1; ! 1867: ! 1868: if ((prclTrg->bottom - prclTrg->top) > 1) ! 1869: rclTmp.bottom -= 1; ! 1870: ! 1871: ps_box(pdev, &rclTmp); ! 1872: PrintString(pdev, "f\n"); ! 1873: ! 1874: if (bClipping) { ! 1875: ! 1876: ps_restore(pdev, TRUE); ! 1877: } ! 1878: } ! 1879: ! 1880: break; ! 1881: ! 1882: case 0x5A5A: ! 1883: case 0x5AAA: ! 1884: // we can't do the right thing, so we are done. ! 1885: ! 1886: break; ! 1887: ! 1888: case 0xF0F0: // PATCOPY opaque. ! 1889: case 0xF0AA: // PATCOPY transparent. ! 1890: ! 1891: // handle the clip object passed in. ! 1892: ! 1893: bMoreClipping = TRUE; ! 1894: bFirstClipPass = TRUE; ! 1895: ! 1896: while (bMoreClipping) ! 1897: { ! 1898: bClipping = bDoClipObj(pdev, pco, NULL, prclTrg, &bMoreClipping, ! 1899: &bFirstClipPass, MAX_CLIP_RECTS); ! 1900: ! 1901: if (bClipping) { ! 1902: ! 1903: ps_clip(pdev, TRUE); ! 1904: } ! 1905: ! 1906: if (!DoPatCopy(pdev, psoTrg, prclTrg, pbo, pptlBrush, rop4, bInvertPat)) { ! 1907: ! 1908: return(FALSE); ! 1909: } ! 1910: ! 1911: if (bClipping) { ! 1912: ! 1913: ps_restore(pdev, TRUE); ! 1914: } ! 1915: } ! 1916: ! 1917: break; ! 1918: ! 1919: default: ! 1920: ! 1921: return (EngBitBlt( ! 1922: psoTrg, ! 1923: psoSrc, ! 1924: psoMask, ! 1925: pco, ! 1926: pxlo, ! 1927: prclTrg, ! 1928: pptlSrc, ! 1929: pptlMask, ! 1930: pbo, ! 1931: pptlBrush, ! 1932: rop4)); ! 1933: } ! 1934: ! 1935: // ! 1936: // bDoClipObj does a save around the clip region. ! 1937: // ! 1938: ! 1939: return(TRUE); ! 1940: ! 1941: } ! 1942: ! 1943: ! 1944: ! 1945: ! 1946: VOID ! 1947: BeginImage( ! 1948: PDEVDATA pdev, ! 1949: BOOL Mono, ! 1950: int x, ! 1951: int y, ! 1952: int cx, ! 1953: int cy, ! 1954: int cxBytes ! 1955: ) ! 1956: ! 1957: /*++ ! 1958: ! 1959: Routine Description: ! 1960: ! 1961: This routine copy sorce image using PostScript code for the image command ! 1962: appropriate for the bitmap format. ! 1963: ! 1964: Arguments: ! 1965: ! 1966: pdev - pointer to PDEVDATA ! 1967: ! 1968: Mono - true if output is B/W monochrome ! 1969: ! 1970: x - starting destination location in x ! 1971: ! 1972: y - starting destination location in y ! 1973: ! 1974: cx - bitmap width ! 1975: ! 1976: cy - bitmap height ! 1977: ! 1978: cxBytes - bytes count per single color scan line ! 1979: ! 1980: Return Value: ! 1981: ! 1982: void ! 1983: ! 1984: Author: ! 1985: ! 1986: 16-Feb-1993 Tue 12:43:03 created -by- Daniel Chou (danielc) ! 1987: ! 1988: ! 1989: Revision History: ! 1990: ! 1991: ! 1992: --*/ ! 1993: ! 1994: { ! 1995: POINTPSFX ptpsfx; ! 1996: ! 1997: // ! 1998: // create the necessary string(s) on the printer's stack to read ! 1999: // in the bitmap data. ! 2000: // ! 2001: ! 2002: if (Mono) { ! 2003: ! 2004: PrintString(pdev, "/mstr "); ! 2005: PrintDecimal(pdev, 1, cxBytes); ! 2006: PrintString(pdev, " string def\n"); ! 2007: ! 2008: } else { ! 2009: ! 2010: PrintString(pdev, "/rstr "); ! 2011: PrintDecimal(pdev, 1, cxBytes); ! 2012: PrintString(pdev, " string def\n"); ! 2013: PrintString(pdev, "/gstr "); ! 2014: PrintDecimal(pdev, 1, cxBytes); ! 2015: PrintString(pdev, " string def\n"); ! 2016: PrintString(pdev, "/bstr "); ! 2017: PrintDecimal(pdev, 1, cxBytes); ! 2018: PrintString(pdev, " string def\n"); ! 2019: } ! 2020: ! 2021: // ! 2022: // position the image on the page, remembering to flip the image ! 2023: // from top to bottom. output PostScript user coordinates to the printer. ! 2024: // ! 2025: // ! 2026: // 22-Feb-1993 Mon 21:44:22 updated -by- Daniel Chou (danielc) ! 2027: // If application do their own banding then this computation could ! 2028: // run into problems by missing 1 device pel because 1/64 accuracy ! 2029: // is not good enough for full size banding ! 2030: // ! 2031: ! 2032: ptpsfx.x = X72DPI(x); ! 2033: ptpsfx.y = Y72DPI(y); ! 2034: ! 2035: PrintPSFIX(pdev, 2, ptpsfx.x, ptpsfx.y); ! 2036: PrintString(pdev, " _snap translate\n"); ! 2037: ! 2038: // ! 2039: // scale the image. ! 2040: // ! 2041: ! 2042: ptpsfx.x = ((cx * PS_FIX_RESOLUTION) + (pdev->psdm.dm.dmPrintQuality / 2)) / ! 2043: pdev->psdm.dm.dmPrintQuality; ! 2044: ptpsfx.y = ((cy * PS_FIX_RESOLUTION) + (pdev->psdm.dm.dmPrintQuality / 2)) / ! 2045: pdev->psdm.dm.dmPrintQuality; ! 2046: ! 2047: PrintPSFIX(pdev, 2, ptpsfx.x, ptpsfx.y); ! 2048: PrintString(pdev, " scale\n"); ! 2049: ! 2050: // ! 2051: // Output the image operator and the scan data. ! 2052: // ! 2053: ! 2054: PrintDecimal(pdev, 2, cx, cy); ! 2055: PrintString(pdev, " "); ! 2056: ! 2057: if (pdev->dwFlags & PDEV_SOURCEORHACK) ! 2058: PrintString(pdev, "true ["); ! 2059: else ! 2060: PrintString(pdev, "1 ["); ! 2061: ! 2062: PrintDecimal(pdev, 1, cx); ! 2063: PrintString(pdev, " 0 0 "); ! 2064: ! 2065: // ! 2066: // We will always send in as TOPDOWN when we calling this function ! 2067: // ! 2068: ! 2069: PrintDecimal(pdev, 1, -cy); ! 2070: PrintString(pdev, " 0 0] "); ! 2071: ! 2072: if (Mono) { ! 2073: ! 2074: PrintString(pdev, "{currentfile mstr readhexstring pop}"); ! 2075: ! 2076: if (pdev->dwFlags & PDEV_SOURCEORHACK) ! 2077: PrintString(pdev, " im\n"); ! 2078: else ! 2079: PrintString(pdev, " image\n"); ! 2080: ! 2081: } else { ! 2082: ! 2083: PrintString(pdev, "\n{currentfile rstr readhexstring pop}\n"); ! 2084: PrintString(pdev, "{currentfile gstr readhexstring pop}\n"); ! 2085: PrintString(pdev, "{currentfile bstr readhexstring pop}\n"); ! 2086: PrintString(pdev, "true 3 colorimage\n"); ! 2087: } ! 2088: } ! 2089: ! 2090: ! 2091: //-------------------------------------------------------------------- ! 2092: // BOOL DoPatCopy(pdev, pso, prclTrg, pbo, pptlBrush, rop4, bInvertPat) ! 2093: // PDEVDATA pdev; ! 2094: // SURFOBJ *pso; ! 2095: // PRECTL prclTrg; ! 2096: // BRUSHOBJ *pbo; ! 2097: // PPOINTL pptlBrush; ! 2098: // ROP4 rop4; ! 2099: // BOOL bInvertPat; ! 2100: // ! 2101: // This routine determines which pattern we are to print from the ! 2102: // BRUSHOBJ passed in, and will output the PostScript commands to ! 2103: // do the pattern fill. It is assumed the clipping will have been ! 2104: // set up at this point. ! 2105: // ! 2106: // History: ! 2107: // Thu May 23, 1991 -by- Kent Settle [kentse] ! 2108: // Wrote it. ! 2109: //-------------------------------------------------------------------- ! 2110: ! 2111: BOOL DoPatCopy(pdev, pso, prclTrg, pbo, pptlBrush, rop4, bInvertPat) ! 2112: PDEVDATA pdev; ! 2113: SURFOBJ *pso; ! 2114: PRECTL prclTrg; ! 2115: BRUSHOBJ *pbo; ! 2116: PPOINTL pptlBrush; ! 2117: ROP4 rop4; ! 2118: BOOL bInvertPat; ! 2119: { ! 2120: RECTL rclTmp; ! 2121: BOOL bUserPat; ! 2122: DEVBRUSH *pBrush; ! 2123: ! 2124: // remember, with bitblt, the target rectangle is bottom/right ! 2125: // exclusive. ! 2126: ! 2127: rclTmp.left = prclTrg->left; ! 2128: rclTmp.top = prclTrg->top; ! 2129: rclTmp.right = prclTrg->right; ! 2130: rclTmp.bottom = prclTrg->bottom; ! 2131: ! 2132: if ((prclTrg->right - prclTrg->left) > 1) ! 2133: rclTmp.right -= 1; ! 2134: ! 2135: if ((prclTrg->bottom - prclTrg->top) > 1) ! 2136: rclTmp.bottom -= 1; ! 2137: ! 2138: // if we have a user defined pattern, don't output the bounding box since ! 2139: // it will not be used. ! 2140: ! 2141: bUserPat = FALSE; ! 2142: ! 2143: if (pbo->iSolidColor != NOT_SOLID_COLOR) ! 2144: bUserPat = FALSE; ! 2145: else ! 2146: { ! 2147: pBrush = (DEVBRUSH *)BRUSHOBJ_pvGetRbrush(pbo); ! 2148: ! 2149: if (!pBrush) ! 2150: bUserPat = FALSE; ! 2151: else ! 2152: { ! 2153: if ((pBrush->iPatIndex < HS_HORIZONTAL) || ! 2154: (pBrush->iPatIndex >= HS_API_MAX)) ! 2155: bUserPat = TRUE; ! 2156: } ! 2157: } ! 2158: ! 2159: if (!bUserPat) ! 2160: ps_box(pdev, & rclTmp); ! 2161: ! 2162: // now fill the target rectangle with the given pattern. ! 2163: ! 2164: return(ps_patfill(pdev, pso, (FLONG)FP_WINDINGMODE, pbo, pptlBrush, (MIX)rop4, ! 2165: &rclTmp, bInvertPat, FALSE)); ! 2166: } ! 2167: ! 2168: //-------------------------------------------------------------------- ! 2169: // BOOL DoSourceCopy(pdev, psoSrc, prclSrc, prclDest, pxlo, prclClipBound, ! 2170: // bNotSrcCopy) ! 2171: // PDEVDATA pdev; ! 2172: // SURFOBJ *psoSrc; ! 2173: // PRECTL prclSrc; ! 2174: // PRECTL prclDest; ! 2175: // XLATEOBJ *pxlo; ! 2176: // RECTL *prclClipBound; ! 2177: // BOOL bNotSrcCopy; ! 2178: // ! 2179: // This routine projects an image of a rectangle on ! 2180: // the source DC's bitmap onto the printer. ! 2181: // ! 2182: // 06-Jun-1991 -by- Kent Settle (kentse) ! 2183: // Wrote it. ! 2184: // 17-Mar-1993 -by- Rob Kiesler ! 2185: // Resurrected and rewritten to allow the PS Interpreter to do Halftoning. ! 2186: //-------------------------------------------------------------------- ! 2187: ! 2188: BOOL DoSourceCopy(pdev, psoSrc, prclSrc, prclDest, pxlo, prclClipBound, ! 2189: bNotSrcCopy) ! 2190: PDEVDATA pdev; ! 2191: SURFOBJ *psoSrc; ! 2192: PRECTL prclSrc; ! 2193: PRECTL prclDest; ! 2194: XLATEOBJ *pxlo; ! 2195: RECTL *prclClipBound; ! 2196: BOOL bNotSrcCopy; ! 2197: { ! 2198: RECTL rclBand, rclDest, rclClip; ! 2199: LONG Temp; ! 2200: DWORD cbSrcScanLine; ! 2201: DWORD cbDstScanLine; ! 2202: POINTL ZeroPointl={0,0}; ! 2203: PBYTE pbSrc; ! 2204: ULONG ulbpp; ! 2205: DWORD cScanlines; ! 2206: // ! 2207: // If we know the destination clipping region bounding rectangle then we ! 2208: // can allocate smaller bitmap and use that bounding rectangle as our ! 2209: // banding rectangle for halftone, if prclClipBound is NULL then the whole ! 2210: // destinaiton rectangle is our bounding (banding) rectangle area ! 2211: // ! 2212: ! 2213: // make sure the destination rectangle is well ordered. ! 2214: ! 2215: rclDest = *prclDest; ! 2216: ! 2217: if (rclDest.left > rclDest.right) ! 2218: { ! 2219: Temp = rclDest.left; ! 2220: rclDest.left = rclDest.right; ! 2221: rclDest.right = Temp; ! 2222: } ! 2223: ! 2224: if (rclDest.top > rclDest.bottom) ! 2225: { ! 2226: Temp = rclDest.top; ! 2227: rclDest.top = rclDest.bottom; ! 2228: rclDest.bottom = Temp; ! 2229: } ! 2230: ! 2231: // if there is a clipping rectangle, intersect it with the destination ! 2232: // rectangle to come up with a banding rectangle. ! 2233: ! 2234: if (prclClipBound) ! 2235: { ! 2236: rclClip = *prclClipBound; ! 2237: ! 2238: // Make sure the clip rectangle is well ordered ! 2239: ! 2240: if (rclClip.left > rclClip.right) ! 2241: { ! 2242: Temp = rclClip.left; ! 2243: rclClip.left = rclClip.right; ! 2244: rclClip.right = Temp; ! 2245: } ! 2246: ! 2247: if (rclClip.top > rclClip.bottom) ! 2248: { ! 2249: Temp = rclClip.top; ! 2250: rclClip.top = rclClip.bottom; ! 2251: rclClip.bottom = Temp; ! 2252: } ! 2253: ! 2254: // now intersect the destination and clip rectangles. ! 2255: ! 2256: if ((rclDest.left >= rclClip.right) || ! 2257: (rclClip.left >= rclDest.right) || ! 2258: (rclDest.top >= rclClip.bottom) || ! 2259: (rclClip.top >= rclDest.bottom)) ! 2260: { ! 2261: #if DBG ! 2262: DbgPrint("PSCRIPT!DoSourceCopy: NULL rectangle, returning FALSE.\n"); ! 2263: #endif ! 2264: return(FALSE); ! 2265: } ! 2266: ! 2267: // we know we have a non-NULL intersection. ! 2268: ! 2269: rclBand.left = max(rclClip.left, rclDest.left); ! 2270: rclBand.right = min(rclClip.right, rclDest.right); ! 2271: rclBand.bottom = min(rclClip.bottom, rclDest.bottom); ! 2272: rclBand.top = max(rclClip.top, rclDest.top); ! 2273: } ! 2274: else ! 2275: rclBand = rclDest; ! 2276: ! 2277: // ! 2278: // Now check if the banding area is bigger than our page size, if so clip ! 2279: // to the page limit ! 2280: // ! 2281: ! 2282: if (rclBand.left < 0) ! 2283: rclBand.left = 0; ! 2284: ! 2285: if (rclBand.top < 0) ! 2286: rclBand.top = 0; ! 2287: ! 2288: // ! 2289: // send out the bitmap data one scanline at a time. ! 2290: // and compute DWORD aligned scanline width in bytes ! 2291: // ! 2292: ! 2293: // ! 2294: // Number of pels/scanline. ! 2295: // ! 2296: cbSrcScanLine = psoSrc->sizlBitmap.cx; ! 2297: ! 2298: // ! 2299: // times how many bits per pel. ! 2300: // ! 2301: switch (psoSrc->iBitmapFormat) ! 2302: { ! 2303: case BMF_1BPP: ! 2304: ulbpp = 1; ! 2305: break; ! 2306: ! 2307: case BMF_4BPP: ! 2308: ulbpp = 4; ! 2309: break; ! 2310: ! 2311: case BMF_8BPP: ! 2312: ulbpp = 8; ! 2313: break; ! 2314: ! 2315: case BMF_16BPP: ! 2316: ulbpp = 16; ! 2317: break; ! 2318: ! 2319: case BMF_24BPP: ! 2320: ulbpp = 24; ! 2321: break; ! 2322: ! 2323: case BMF_32BPP: ! 2324: ulbpp = 32; ! 2325: break; ! 2326: } ! 2327: ! 2328: cbSrcScanLine *= ulbpp; ! 2329: // ! 2330: // cbSrcScanLine now equals the number of bits per scanline. ! 2331: // calculate the destination width in bytes from the width in bits. ! 2332: // Note that the PS image routines only require scans to be padded to ! 2333: // byte boundaries. ! 2334: // ! 2335: cbDstScanLine = (cbSrcScanLine + 7) >> 3; ! 2336: ! 2337: // ! 2338: // Now convert cbSrcScanLine to the number of bytes per scanline, ! 2339: // taking into account that scanlines are padded out to 32 bit ! 2340: // boundaries. ! 2341: // ! 2342: cbSrcScanLine = ((cbDstScanLine + 3) >> 2) * 4; ! 2343: ! 2344: // ! 2345: // Output the PostScript beginimage operator. ! 2346: // ! 2347: BeginImageEx(pdev, ! 2348: psoSrc->sizlBitmap, ! 2349: ulbpp, ! 2350: cbDstScanLine, ! 2351: &rclBand, ! 2352: FALSE, ! 2353: pxlo); ! 2354: ! 2355: // ! 2356: // Set up pbSrc -> start of the source bitmap. ! 2357: // ! 2358: pbSrc = psoSrc->pvBits; ! 2359: ! 2360: cScanlines = (DWORD)psoSrc->sizlBitmap.cy; ! 2361: ! 2362: while (cScanlines--) ! 2363: { ! 2364: if (pdev->dwFlags & PDEV_CANCELDOC) ! 2365: break; ! 2366: ! 2367: // ! 2368: // Output each scanline to the printer ! 2369: // ! 2370: vHexOut(pdev, pbSrc, cbDstScanLine); ! 2371: PrintString(pdev, "\n"); ! 2372: ! 2373: pbSrc += cbSrcScanLine; ! 2374: } ! 2375: PrintString(pdev, "\nendimage\n"); ! 2376: ! 2377: return(TRUE); ! 2378: } ! 2379: ! 2380: ! 2381: //-------------------------------------------------------------------- ! 2382: // BOOL BeginImageEx(pdev, sizlSrc, ulSrcFormat, cbSrcWidth, prclDest, ! 2383: // bNotSrcCopy, pxlo) ! 2384: // PDEVDATA pdev; ! 2385: // SIZEL sizlSrc; ! 2386: // ULONG ulSrcFormat; ! 2387: // DWORD cbSrcWidth; ! 2388: // PRECTL prclDest; ! 2389: // BOOL bNotSrcCopy; ! 2390: // XLATEOBJ *pxlo;VOID ! 2391: // ! 2392: // Routine Description: ! 2393: // ! 2394: // This routine will output the appropriate operators to set up the PS ! 2395: // interprter to receive a source image from the host. This routine is ! 2396: // called only when the PS Interpreter is being asked to perform ! 2397: // halftoning. ! 2398: // ! 2399: // Return Value: ! 2400: // ! 2401: // FALSE if an error occurred. ! 2402: // ! 2403: // Author: ! 2404: // ! 2405: // 17-Mar-1993 created -by- Rob Kiesler ! 2406: // ! 2407: // ! 2408: // Revision History: ! 2409: //-------------------------------------------------------------------- ! 2410: ! 2411: ! 2412: BOOL BeginImageEx(pdev, sizlSrc, ulSrcFormat, cbSrcWidth, prclDest, ! 2413: bNotSrcCopy, pxlo) ! 2414: PDEVDATA pdev; ! 2415: SIZEL sizlSrc; ! 2416: ULONG ulSrcFormat; ! 2417: DWORD cbSrcWidth; ! 2418: PRECTL prclDest; ! 2419: BOOL bNotSrcCopy; ! 2420: XLATEOBJ *pxlo; ! 2421: { ! 2422: #ifdef INDEX_PAL ! 2423: PALETTEENTRY *prgb; ! 2424: DWORD i; ! 2425: POINTPSFX ptpsfx; ! 2426: CHAR bmpTypeStr[2]; ! 2427: BYTE intensity; ! 2428: PALETTEENTRY *prgbFore; ! 2429: PALETTEENTRY *prgbBack; ! 2430: PALETTEENTRY *ppalette; ! 2431: PALETTEENTRY *ppalSave; ! 2432: ULONG *pulColors; ! 2433: DWORD cColors; ! 2434: ! 2435: // ! 2436: // Check to see if any of the PS image handling code ! 2437: // has been downloaded. ! 2438: // ! 2439: if(!(pdev->dwFlags & PDEV_UTILSSENT)) ! 2440: { ! 2441: // ! 2442: // Download the Adobe PS Utilities Procset. ! 2443: // ! 2444: PrintString(pdev, "/Adobe_WinNT_Driver_Gfx 175 dict dup begin\n"); ! 2445: if (!bSendPSProcSet(pdev, UTILS)) ! 2446: { ! 2447: RIP("PSCRIPT!BeginImageEx: Couldn't download Utils Procset.\n"); ! 2448: return(FALSE); ! 2449: } ! 2450: PrintString(pdev, "end def\n[ 1.000 0 0 1.000 0 0 ] Adobe_WinNT_Driver_Gfx dup /initialize get exec\n"); ! 2451: pdev->dwFlags |= PDEV_UTILSSENT; ! 2452: } ! 2453: ! 2454: if(!(pdev->dwFlags & PDEV_IMAGESENT)) ! 2455: { ! 2456: // ! 2457: // Download the Adobe PS Image Procset. ! 2458: // ! 2459: PrintString(pdev, "Adobe_WinNT_Driver_Gfx begin\n"); ! 2460: if (!bSendPSProcSet(pdev, IMAGE)) ! 2461: { ! 2462: RIP("PSCRIPT!BeginImageEx: Couldn't download Image Procset.\n"); ! 2463: return(FALSE); ! 2464: } ! 2465: PrintString(pdev, "end reinitialize\n"); ! 2466: pdev->dwFlags |= PDEV_IMAGESENT; ! 2467: } ! 2468: ! 2469: // ! 2470: // Send the source bmp origin, source bmp format, and scanline width. ! 2471: // ! 2472: ! 2473: PrintDecimal(pdev, 4, sizlSrc.cx, sizlSrc.cy, ulSrcFormat, cbSrcWidth); ! 2474: // PrintDecimal(pdev, 4, sizlSrc.cx, (prclDest->bottom - prclDest->top), ! 2475: // ulSrcFormat, cbSrcWidth); ! 2476: PrintString(pdev, " "); ! 2477: ! 2478: // ! 2479: // Compute the destination rectangle extents, and convert to fixed point. ! 2480: // ! 2481: ! 2482: #if 0 ! 2483: ptpsfx.x = ((prclDest->right - prclDest->left) * PS_FIX_RESOLUTION) / ! 2484: pdev->psdm.dm.dmPrintQuality; ! 2485: ptpsfx.y = ((prclDest->bottom - prclDest->top) * PS_FIX_RESOLUTION) / ! 2486: pdev->psdm.dm.dmPrintQuality; ! 2487: ! 2488: PrintPSFIX(pdev, 2, ptpsfx.x, ptpsfx.y); ! 2489: ! 2490: PrintString(pdev, " "); // PrintPSFIX doesn't generate a " " after ! 2491: // the last # printed! ! 2492: #endif ! 2493: ! 2494: ptpsfx.x = ((prclDest->right - prclDest->left) * PS_FIX_RESOLUTION) / ! 2495: pdev->psdm.dm.dmPrintQuality; ! 2496: ptpsfx.y = ((prclDest->bottom - prclDest->top) * PS_FIX_RESOLUTION) / ! 2497: pdev->psdm.dm.dmPrintQuality; ! 2498: ! 2499: PrintDecimal(pdev, 1, (prclDest->right - prclDest->left)); ! 2500: PrintString(pdev, " 72 mul DPI div "); ! 2501: PrintDecimal(pdev, 1, (prclDest->bottom - prclDest->top)); ! 2502: PrintString(pdev, " 72 mul DPI div "); ! 2503: ! 2504: // ! 2505: // Convert Destination Rect Origin to fixed point. ! 2506: // ! 2507: #if 0 ! 2508: ptpsfx.x = X72DPI(prclDest->left); ! 2509: ptpsfx.y = Y72DPI(prclDest->top); ! 2510: ! 2511: PrintPSFIX(pdev, 2, ptpsfx.x, ptpsfx.y); ! 2512: #endif ! 2513: ! 2514: PrintDecimal(pdev, 1, prclDest->left); ! 2515: PrintString(pdev, " 72 mul DPI div "); ! 2516: PrintDecimal(pdev, 1, pdev->CurForm.imagearea.left); ! 2517: PrintString(pdev, " add\n"); ! 2518: PrintDecimal(pdev, 1, pdev->CurForm.imagearea.top); ! 2519: PrintString(pdev, " "); ! 2520: PrintDecimal(pdev, 1, prclDest->top); ! 2521: PrintString(pdev, " 72 mul DPI div sub\n"); ! 2522: ! 2523: PrintString(pdev, " false "); // Smoothflag = FALSE for now. ! 2524: PrintString(pdev, bNotSrcCopy && (ulSrcFormat == 1) ? "false " : "true "); ! 2525: ! 2526: // ! 2527: // Determine the type of data (binary RLE, ASCII85 RLE, etc) which ! 2528: // the output channel supports, and pass it to the "beginimage" ! 2529: // operator. ! 2530: // ! 2531: itoa(PSBitMapType(pdev, FALSE), bmpTypeStr, 10); ! 2532: PrintString(pdev, bmpTypeStr); ! 2533: PrintString(pdev, " "); ! 2534: ! 2535: PrintString(pdev, "beginimage\n"); ! 2536: ! 2537: if (pxlo) ! 2538: { ! 2539: // get pointer to our device palettes. ! 2540: ! 2541: if (ulSrcFormat == 1) ! 2542: pulColors = PSMonoPalette; ! 2543: else ! 2544: pulColors = PSColorPalette; ! 2545: ! 2546: if (pxlo->flXlate & XO_TRIVIAL) ! 2547: { ! 2548: // if the TRIVIAL color translation flag is set, then fill in ! 2549: // halftoning palette from our hardcoded palettes. ! 2550: ! 2551: if (ulSrcFormat == 1) ! 2552: ppalette = (PALETTEENTRY *)PSMonoPalette; ! 2553: else ! 2554: ppalette = (PALETTEENTRY *)PSColorPalette; ! 2555: } ! 2556: else if (pxlo->flXlate & XO_TABLE) ! 2557: { ! 2558: ppalette = (PALETTEENTRY *)pxlo->pulXlate; ! 2559: } ! 2560: else ! 2561: ppalette = (PALETTEENTRY *)NULL; ! 2562: } ! 2563: else ! 2564: ppalette = (PALETTEENTRY *)NULL; ! 2565: ! 2566: // ppalette now points to our palette. the format of this palette can ! 2567: // vary depending on pxlo->flXlate. ! 2568: ! 2569: switch (ulSrcFormat) ! 2570: { ! 2571: case 1: ! 2572: #if 0 ! 2573: if (ppalette == NULL) ! 2574: { ! 2575: // ! 2576: // No palette, so assume fgcolor = black, bgcolor = white. ! 2577: // ! 2578: PrintString(pdev, "1bitbwcopyimage\n"); ! 2579: } ! 2580: else ! 2581: { ! 2582: // ! 2583: // There is a palette, check the fg and bg colors. ! 2584: // ! 2585: ! 2586: if (pxlo->flXlate & XO_TRIVIAL) ! 2587: { ! 2588: prgbBack = ppalette; ! 2589: prgbFore = ppalette + 1; ! 2590: } ! 2591: else ! 2592: { ! 2593: prgbBack = (PALETTEENTRY *)(pulColors + ! 2594: XLATEOBJ_iXlate(pxlo, *(ULONG *)ppalette)); ! 2595: prgbFore = (PALETTEENTRY *)(pulColors + ! 2596: XLATEOBJ_iXlate(pxlo, *(ULONG *)(ppalette + 1))); ! 2597: } ! 2598: ! 2599: if ((prgbBack->peRed == 0xFF) && ! 2600: (prgbBack->peGreen == 0xFF) && ! 2601: (prgbBack->peBlue == 0xFF) && ! 2602: (prgbFore->peRed == 0x00) && ! 2603: (prgbFore->peGreen == 0x00) && ! 2604: (prgbFore->peBlue == 0x00)) ! 2605: { ! 2606: // ! 2607: // fgcolor = black, bgcolor = white. The default case. ! 2608: // ! 2609: PrintString(pdev, "1bitbwcopyimage\n"); ! 2610: } ! 2611: else ! 2612: { ! 2613: // ! 2614: // Either fg != black, or bg != white, must send ! 2615: // fg and bg colors. ! 2616: // ! 2617: PrintPSFIX(pdev, 3, LTOPSFX((ULONG)prgbFore->peRed) / 255, ! 2618: LTOPSFX((ULONG)prgbFore->peGreen) / 255, ! 2619: LTOPSFX((ULONG)prgbFore->peBlue) / 255); ! 2620: PrintString(pdev, " false "); ! 2621: PrintPSFIX(pdev, 3, LTOPSFX((ULONG)prgbBack->peRed) / 255, ! 2622: LTOPSFX((ULONG)prgbBack->peGreen) / 255, ! 2623: LTOPSFX((ULONG)prgbBack->peBlue) / 255); ! 2624: PrintString(pdev, " false "); ! 2625: PrintString(pdev, "1bitcopyimage\n"); ! 2626: } ! 2627: } ! 2628: #endif ! 2629: PrintString(pdev, " doNimage\n"); ! 2630: break; ! 2631: ! 2632: case 4 : ! 2633: case 8 : ! 2634: if (ppalette == NULL) ! 2635: { ! 2636: // ! 2637: // No palette, use the current PS colors. ! 2638: // ! 2639: PrintString(pdev, "doNimage\n"); ! 2640: } ! 2641: else ! 2642: { ! 2643: // ! 2644: // There is a palette, send it to the PS interpreter. ! 2645: // First, compute and send the mono (intensity) palette. ! 2646: // ! 2647: PrintString(pdev, "<\n"); ! 2648: ! 2649: if (pxlo->flXlate & XO_TRIVIAL) ! 2650: { ! 2651: if (ulSrcFormat == 4) ! 2652: cColors = 16; ! 2653: ! 2654: #if DBG ! 2655: else ! 2656: RIP("PSCRIPT!BeginImageEx: invalid pxlo format.\n"); ! 2657: #endif ! 2658: } ! 2659: else ! 2660: cColors = pxlo->cEntries; ! 2661: ! 2662: ppalSave = ppalette; ! 2663: ! 2664: for (i = 0; i < cColors; ppalette++) ! 2665: { ! 2666: if (pxlo->flXlate & XO_TRIVIAL) ! 2667: prgb = ppalette; ! 2668: else ! 2669: prgb = (PALETTEENTRY *)(pulColors + ! 2670: XLATEOBJ_iXlate(pxlo, *(ULONG *)ppalette)); ! 2671: ! 2672: intensity = INTENSITY(prgb->peRed, ! 2673: prgb->peGreen, ! 2674: prgb->peBlue); ! 2675: ! 2676: vHexOut(pdev, &intensity, 1); ! 2677: ! 2678: if (++i % 16) ! 2679: PrintString(pdev," "); ! 2680: else ! 2681: PrintString(pdev,"\n"); ! 2682: } ! 2683: ! 2684: // ! 2685: // If the number of palette entries is less than the ! 2686: // number of possible colors for ulSrcFormat, pad the ! 2687: // palette with 0's. ! 2688: // ! 2689: for ( ; i < (DWORD)(1 << ulSrcFormat) ; ) ! 2690: { ! 2691: PrintString(pdev,"00"); ! 2692: if (++i % 16) ! 2693: PrintString(pdev," "); ! 2694: else ! 2695: PrintString(pdev, "\n"); ! 2696: } ! 2697: PrintString(pdev, ">\n"); ! 2698: ! 2699: // ! 2700: // Send the RGB palette. ! 2701: // ! 2702: PrintString(pdev, "<\n"); ! 2703: ! 2704: ppalette = ppalSave; ! 2705: ! 2706: for (i = 0; i < cColors; ppalette++) ! 2707: { ! 2708: if (pdev->dwFlags & PDEV_CANCELDOC) ! 2709: break; ! 2710: ! 2711: if (pxlo->flXlate & XO_TRIVIAL) ! 2712: prgb = ppalette; ! 2713: else ! 2714: prgb = (PALETTEENTRY *)(pulColors + ! 2715: XLATEOBJ_iXlate(pxlo, *(ULONG *)ppalette)); ! 2716: ! 2717: if (pxlo->iSrcType & PAL_BGR) ! 2718: { ! 2719: vHexOut(pdev, &(prgb->peBlue), 1); ! 2720: vHexOut(pdev, &(prgb->peGreen), 1); ! 2721: vHexOut(pdev, &(prgb->peRed), 1); ! 2722: } ! 2723: else ! 2724: { ! 2725: vHexOut(pdev, (PBYTE)prgb, 3); ! 2726: } ! 2727: ! 2728: if (++i % 8) ! 2729: PrintString(pdev," "); ! 2730: else ! 2731: PrintString(pdev,"\n"); ! 2732: } ! 2733: ! 2734: // ! 2735: // If the number of palette entries is less than the ! 2736: // number of possible colors for ulSrcFormat, pad the ! 2737: // palette with 0's. ! 2738: // ! 2739: ! 2740: for ( ; i < (DWORD)(1 << ulSrcFormat) ; ) ! 2741: { ! 2742: PrintString(pdev,"000000"); ! 2743: if (++i % 8) ! 2744: PrintString(pdev," "); ! 2745: else ! 2746: PrintString(pdev, "\n"); ! 2747: } ! 2748: PrintString(pdev, "\n>\n"); ! 2749: PrintString(pdev, "doclutimage\n"); ! 2750: } ! 2751: ! 2752: break; ! 2753: ! 2754: #else // 24BPP case. ! 2755: BGR_PAL_ENTRY *pbgr; ! 2756: DWORD i; ! 2757: POINTPSFX ptpsfx; ! 2758: CHAR bmpTypeStr[2]; ! 2759: BYTE intensity; ! 2760: BGR_PAL_ENTRY *pbgrFore; ! 2761: BGR_PAL_ENTRY *pbgrBack; ! 2762: ! 2763: // ! 2764: // Check to see if any of the PS image handling code ! 2765: // has been downloaded. ! 2766: // ! 2767: if(!(pdev->dwFlags & PDEV_UTILSSENT)) ! 2768: { ! 2769: // ! 2770: // Download the Adobe PS Utilities Procset. ! 2771: // ! 2772: PrintString(pdev, "/Adobe_WinNT_Driver_Gfx 175 dict dup begin\n"); ! 2773: if (!bSendPSProcSet(pdev, UTILS)) ! 2774: { ! 2775: RIP("PSCRIPT!BeginImageEx: Couldn't download Utils Procset.\n"); ! 2776: return(FALSE); ! 2777: } ! 2778: PrintString(pdev, "end def\n[ 1.000 0 0 1.000 0 0 ] Adobe_WinNT_Driver_Gfx dup /initialize get exec\n"); ! 2779: pdev->dwFlags |= PDEV_UTILSSENT; ! 2780: } ! 2781: ! 2782: if(!(pdev->dwFlags & PDEV_IMAGESENT)) ! 2783: { ! 2784: // ! 2785: // Download the Adobe PS Image Procset. ! 2786: // ! 2787: PrintString(pdev, "Adobe_WinNT_Driver_Gfx begin\n"); ! 2788: if (!bSendPSProcSet(pdev, IMAGE)) ! 2789: { ! 2790: RIP("PSCRIPT!BeginImageEx: Couldn't download Image Procset.\n"); ! 2791: return(FALSE); ! 2792: } ! 2793: PrintString(pdev, "end reinitialize\n"); ! 2794: pdev->dwFlags |= PDEV_IMAGESENT; ! 2795: } ! 2796: ! 2797: // ! 2798: // Send the source bmp origin, source bmp format, and scanline width. ! 2799: // ! 2800: ! 2801: PrintDecimal(pdev, 4, sizlSrc.cx, sizlSrc.cy, ulSrcFormat, cbSrcWidth); ! 2802: PrintString(pdev, " "); ! 2803: ! 2804: // ! 2805: // Compute the destination rectangle extents, and convert to fixed point. ! 2806: // ! 2807: ! 2808: ptpsfx.x = ((prclDest->right - prclDest->left) * PS_FIX_RESOLUTION) / ! 2809: pdev->psdm.dm.dmPrintQuality; ! 2810: ptpsfx.y = ((prclDest->bottom - prclDest->top) * PS_FIX_RESOLUTION) / ! 2811: pdev->psdm.dm.dmPrintQuality; ! 2812: ! 2813: PrintDecimal(pdev, 1, (prclDest->right - prclDest->left)); ! 2814: PrintString(pdev, " 72 mul DPI div "); ! 2815: PrintDecimal(pdev, 1, (prclDest->bottom - prclDest->top)); ! 2816: PrintString(pdev, " 72 mul DPI div "); ! 2817: ! 2818: // ! 2819: // Convert Destination Rect Origin to fixed point. ! 2820: // ! 2821: ! 2822: PrintDecimal(pdev, 1, prclDest->left); ! 2823: PrintString(pdev, " 72 mul DPI div "); ! 2824: PrintDecimal(pdev, 1, pdev->CurForm.imagearea.left); ! 2825: PrintString(pdev, " add\n"); ! 2826: PrintDecimal(pdev, 1, pdev->CurForm.imagearea.top); ! 2827: PrintString(pdev, " "); ! 2828: PrintDecimal(pdev, 1, prclDest->top); ! 2829: PrintString(pdev, " 72 mul DPI div sub"); ! 2830: ! 2831: PrintString(pdev, " false "); // Smoothflag = FALSE for now. ! 2832: PrintString(pdev, bNotSrcCopy && (ulSrcFormat == 1) ? "false " : "true "); ! 2833: ! 2834: // ! 2835: // Determine the type of data (binary RLE, ASCII85 RLE, etc) which ! 2836: // the output channel supports, and pass it to the "beginimage" ! 2837: // operator. ! 2838: // ! 2839: itoa(PSBitMapType(pdev, FALSE), bmpTypeStr, 10); ! 2840: PrintString(pdev, bmpTypeStr); ! 2841: PrintString(pdev, " "); ! 2842: ! 2843: PrintString(pdev, "beginimage\n"); ! 2844: ! 2845: if (pxlo) ! 2846: pbgr = (BGR_PAL_ENTRY *)pxlo->pulXlate; ! 2847: else ! 2848: pbgr = (BGR_PAL_ENTRY *)NULL; ! 2849: ! 2850: switch (ulSrcFormat) ! 2851: { ! 2852: case 1: ! 2853: #if 0 ! 2854: if (pbgr == NULL) ! 2855: { ! 2856: // ! 2857: // No palette, so assume fgcolor = black, bgcolor = white. ! 2858: // ! 2859: PrintString(pdev, "1bitbwcopyimage\n"); ! 2860: } ! 2861: else ! 2862: { ! 2863: pbgrBack = pbgr; ! 2864: pbgrFore = pbgr + 1; ! 2865: ! 2866: if ((pbgrBack->bgrRed == 0xFF) && ! 2867: (pbgrBack->bgrGreen == 0xFF) && ! 2868: (pbgrBack->bgrBlue == 0xFF) && ! 2869: (pbgrFore->bgrRed == 0x00) && ! 2870: (pbgrFore->bgrGreen == 0x00) && ! 2871: (pbgrFore->bgrBlue == 0x00)) ! 2872: { ! 2873: // ! 2874: // fgcolor = black, bgcolor = white. The default case. ! 2875: // ! 2876: PrintString(pdev, "1bitbwcopyimage\n"); ! 2877: } ! 2878: else ! 2879: { ! 2880: // ! 2881: // Either fg != black, or bg != white, must send ! 2882: // fg and bg colors. ! 2883: // ! 2884: PrintPSFIX(pdev, 3, LTOPSFX((ULONG)pbgrFore->bgrRed) / 255, ! 2885: LTOPSFX((ULONG)pbgrFore->bgrGreen) / 255, ! 2886: LTOPSFX((ULONG)pbgrFore->bgrBlue) / 255); ! 2887: PrintString(pdev, " false "); ! 2888: PrintPSFIX(pdev, 3, LTOPSFX((ULONG)pbgrBack->bgrRed) / 255, ! 2889: LTOPSFX((ULONG)pbgrBack->bgrGreen) / 255, ! 2890: LTOPSFX((ULONG)pbgrBack->bgrBlue) / 255); ! 2891: PrintString(pdev, " false "); ! 2892: PrintString(pdev, "1bitcopyimage\n"); ! 2893: } ! 2894: } ! 2895: #endif ! 2896: PrintString(pdev, "doNimage\n"); ! 2897: break; ! 2898: ! 2899: case 4 : ! 2900: case 8 : ! 2901: if (pbgr == NULL) ! 2902: { ! 2903: // ! 2904: // No palette, use the current PS colors. ! 2905: // ! 2906: PrintString(pdev, "doNimage\n"); ! 2907: } ! 2908: else ! 2909: { ! 2910: // ! 2911: // There is a palette, send it to the PS interpreter. ! 2912: // First, compute and send the mono (intensity) palette. ! 2913: // ! 2914: PrintString(pdev, "<\n"); ! 2915: ! 2916: for (i = 0; i < pxlo->cEntries; pbgr++) ! 2917: { ! 2918: intensity = INTENSITY(pbgr->bgrRed, ! 2919: pbgr->bgrGreen, ! 2920: pbgr->bgrBlue); ! 2921: ! 2922: vHexOut(pdev, &intensity, 1); ! 2923: ! 2924: if (++i % 16) ! 2925: PrintString(pdev," "); ! 2926: else ! 2927: PrintString(pdev,"\n"); ! 2928: } ! 2929: ! 2930: // ! 2931: // If the number of palette entries is less than the ! 2932: // number of possible colors for ulSrcFormat, pad the ! 2933: // palette with 0's. ! 2934: // ! 2935: for ( ; i < (DWORD)(1 << ulSrcFormat) ; ) ! 2936: { ! 2937: PrintString(pdev,"00"); ! 2938: if (++i % 16) ! 2939: PrintString(pdev," "); ! 2940: else ! 2941: PrintString(pdev, "\n"); ! 2942: } ! 2943: PrintString(pdev, ">\n"); ! 2944: ! 2945: // ! 2946: // Send the RGB palette. ! 2947: // ! 2948: PrintString(pdev, "<\n"); ! 2949: ! 2950: pbgr = (BGR_PAL_ENTRY *)pxlo->pulXlate; ! 2951: ! 2952: for (i = 0; i < pxlo->cEntries; pbgr++) ! 2953: { ! 2954: if (pdev->dwFlags & PDEV_CANCELDOC) ! 2955: break; ! 2956: ! 2957: if (pxlo->iSrcType & PAL_BGR) ! 2958: { ! 2959: vHexOut(pdev, (PBYTE)pbgr, 3); ! 2960: } ! 2961: else ! 2962: { ! 2963: vHexOut(pdev, &(pbgr->bgrRed), 1); ! 2964: vHexOut(pdev, &(pbgr->bgrGreen), 1); ! 2965: vHexOut(pdev, &(pbgr->bgrBlue), 1); ! 2966: } ! 2967: ! 2968: if (++i % 8) ! 2969: PrintString(pdev," "); ! 2970: else ! 2971: PrintString(pdev,"\n"); ! 2972: } ! 2973: ! 2974: // ! 2975: // If the number of palette entries is less than the ! 2976: // number of possible colors for ulSrcFormat, pad the ! 2977: // palette with 0's. ! 2978: // ! 2979: ! 2980: for ( ; i < (DWORD)(1 << ulSrcFormat) ; ) ! 2981: { ! 2982: PrintString(pdev,"000000"); ! 2983: if (++i % 8) ! 2984: PrintString(pdev," "); ! 2985: else ! 2986: PrintString(pdev, "\n"); ! 2987: } ! 2988: PrintString(pdev, "\n>\n"); ! 2989: PrintString(pdev, "doclutimage\n"); ! 2990: } ! 2991: ! 2992: break; ! 2993: ! 2994: #endif ! 2995: case 24 : ! 2996: // ! 2997: // 24BPP images don't need a palette, use the doNimage operator. ! 2998: // ! 2999: PrintString(pdev, "doNimage\n"); ! 3000: break; ! 3001: ! 3002: default: ! 3003: // ! 3004: // Can't handle bitmaps in formats other than the ones above! ! 3005: // ! 3006: return(FALSE); ! 3007: } ! 3008: return(TRUE); ! 3009: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.