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