Annotation of ntddk/src/print/pscript/bitblt.c, revision 1.1.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.