Annotation of ntddk/src/print/pscript/bitblt.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.