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