|
|
1.1 root 1: //--------------------------------------------------------------------------
2: //
3: // Module Name: HEADER.C
4: //
5: // Brief Description: This module contains the PSCRIPT driver's header
6: // output functions and related routines.
7: //
8: // Author: Kent Settle (kentse)
9: // Created: 26-Nov-1990
10: //
11: // Copyright (c) 1990-1993 Microsoft Corporation
12: //
13: // This routine contains routines to output the PostScript driver's header.
14: //--------------------------------------------------------------------------
15:
16: #include "pscript.h"
17: #include "header.h"
18: #include "resource.h"
19: #include "enable.h"
20:
21:
22: extern HMODULE ghmodDrv; // GLOBAL MODULE HANDLE.
23: extern int NameComp(CHAR *, CHAR *);
24:
25: BOOL bSendDeviceSetup(PDEVDATA);
26: VOID DownloadNTProcSet(PDEVDATA, BOOL);
27: VOID SetFormAndTray(PDEVDATA);
28:
29: //--------------------------------------------------------------------------
30: // BOOL bOutputHeader(pdev)
31: // PDEVDATA pdev;
32: //
33: // This routine sends the driver's header to the output channel.
34: //
35: // Parameters:
36: // pdev:
37: // pointer to DEVDATA structure.
38: //
39: // Returns:
40: // This function returns TRUE if the header was successfully sent,
41: // FALSE otherwise.
42: //
43: // History:
44: // 26-Nov-1990 -by- Kent Settle (kentse)
45: // Wrote it.
46: //--------------------------------------------------------------------------
47:
48: BOOL bOutputHeader(pdev)
49: PDEVDATA pdev;
50: {
51: CHAR buf[128];
52: CHAR *pstr;
53: WCHAR *pwstr;
54: DWORD cTmp, i;
55: BOOL bDuplex;
56: SYSTEMTIME systime;
57: DWORD pbgr;
58: PSRESOLUTION *pRes;
59: PNTPD pntpd;
60:
61: // don't do anything if the header has already been sent to the printer.
62:
63: if (pdev->dwFlags & PDEV_PROCSET)
64: return TRUE;
65:
66: // set the header sent flag. this needs to be done before a call
67: // to Print is made in order to keep from getting stuck in a loop.
68:
69: pdev->dwFlags |= PDEV_PROCSET;
70:
71: // if RAWDATA has already been sent to the printer, then we only want
72: // to send down our ProcSet, and not the rest of the header, or any
73: // of the device setup commands.
74:
75: if (pdev->dwFlags & PDEV_RAWDATASENT)
76: {
77: // define our procedure set, FALSE means don't even think
78: // about defining the error handler..
79:
80: DownloadNTProcSet(pdev, FALSE);
81:
82: // output a save command for the first page. this is done in the
83: // header as part of the effort to avoid outputting two headers in
84: // the raw data case. FALSE means to perform a save and not a gsave.
85:
86: ps_save(pdev, FALSE);
87: pdev->dwFlags |= PDEV_WITHINPAGE;
88:
89: return(TRUE);
90: }
91:
92: // get a local pointer.
93:
94: pntpd = pdev->pntpd;
95:
96: // output the header comments. NOTE, these comments conform to
97: // Version 2.0 of the Adobe Structuring Conventions.
98:
99: // if the printer supports job switching, put the printer into
100: // postscript mode now.
101:
102: if (pntpd->flFlags & PJL_PROTOCOL)
103: PrintString(pdev, "\033%-12345X@PJL ENTER LANGUAGE=POSTSCRIPT\n");
104: if (pntpd->flFlags & SIC_PROTOCOL)
105: {
106: // call directly to bPSWrite to output the necessary escape commands.
107: // PrintString will NOT output '\000'.
108:
109: bPSWrite(pdev, "\033\133\113\030\000\006\061\010\000\000\000\000\000", 13);
110: bPSWrite(pdev, "\000\000\000\000\000\000\000\000\004\033\133\113\003", 13);
111: bPSWrite(pdev, "\000\006\061\010\004", 5);
112: }
113:
114: //!!! output something different if Encapsulated PS.
115: //!!! PrintString(pdev, "%!PS-Adobe-2.0 EPSF-2.0\n");
116:
117: PrintString(pdev, "%!PS-Adobe-2.0\n");
118:
119: // output the title of the document.
120:
121: if (pdev->pwstrDocName)
122: {
123: //!!! need to output UNICODE document name??? -kentse.
124: //!!! for now just lop off top word.
125: pstr = buf;
126: pwstr = pdev->pwstrDocName;
127:
128: cTmp = min((sizeof(buf) - 1), wcslen(pwstr));
129:
130: while (cTmp--)
131: *pstr++ = (CHAR)*pwstr++;
132:
133: // NULL terminate the document name.
134:
135: *pstr = '\0';
136:
137: PrintString(pdev, "%%Title: ");
138: PrintString(pdev, buf);
139: PrintString(pdev, "\n");
140: }
141: else
142: PrintString(pdev, "%%Title: Untitled Document\n");
143:
144: // let the world know who we are.
145:
146: PrintString(pdev, "%%Creator: Windows NT 3.1\n");
147:
148: // print the date and time of creation.
149:
150: GetLocalTime(&systime);
151:
152: PrintString(pdev, "%%CreationDate: ");
153: PrintDecimal(pdev, 1, systime.wHour);
154: PrintString(pdev, ":");
155: PrintDecimal(pdev, 1, systime.wMinute);
156: PrintString(pdev, " ");
157: PrintDecimal(pdev, 1, systime.wMonth);
158: PrintString(pdev, "/");
159: PrintDecimal(pdev, 1, systime.wDay);
160: PrintString(pdev, "/");
161: PrintDecimal(pdev, 1, systime.wYear);
162:
163: // mark the bounding box of the document.
164:
165: PrintString(pdev, "\n%%BoundingBox: ");
166: PrintDecimal(pdev, 4, pdev->CurForm.imagearea.left,
167: pdev->CurForm.imagearea.bottom,
168: pdev->CurForm.imagearea.right,
169: pdev->CurForm.imagearea.top);
170:
171: PrintString(pdev, "\n%%DocumentProcSets: Windows_NT_3.1\n");
172: PrintString(pdev, "%%DocumentSuppliedProcSets: Windows_NT_3.1\n");
173:
174: if (pdev->cCopies > 1)
175: {
176: PrintString(pdev, "%%Requirements: numcopies(");
177: PrintDecimal(pdev, 1, pdev->cCopies);
178: PrintString(pdev, ") collate\n");
179: }
180:
181: // we are done with the comments portion of the document.
182:
183: PrintString(pdev, "%%EndComments\n");
184:
185: // define our procedure set.
186:
187: DownloadNTProcSet(pdev, TRUE);
188:
189: PrintString(pdev, "%%EndProlog\n");
190:
191: // do the device setup.
192:
193: PrintString(pdev, "%%BeginSetup\n");
194:
195: // send the resolution selection command, if necessary.
196:
197: if (pntpd->cResolutions > 0)
198: {
199: pRes = (PSRESOLUTION *)((CHAR *)pntpd + pntpd->loResolution);
200:
201: // search each possible resolution until the specified one is
202: // found.
203:
204: for (i = 0; i < (DWORD)pntpd->cResolutions; i++)
205: {
206: if (pRes[i].iValue == (DWORD)pdev->psdm.dm.dmPrintQuality)
207: {
208: PrintString(pdev, "%%BeginFeature: *Resolution ");
209: PrintDecimal(pdev, 1, pdev->psdm.dm.dmPrintQuality);
210: PrintString(pdev, "\n");
211: PrintString(pdev, (CHAR *)pntpd + pRes[i].loInvocation);
212: PrintString(pdev, "\n%%EndFeature\n");
213: }
214: }
215: }
216:
217: // send form and tray selection commands.
218:
219: SetFormAndTray(pdev);
220:
221: // handle duplex if necessary.
222:
223: if ((pntpd->loszDuplexNone) ||
224: (pntpd->loszDuplexNoTumble) ||
225: (pntpd->loszDuplexTumble))
226: bDuplex = TRUE;
227: else
228: bDuplex = FALSE;
229:
230: if (bDuplex)
231: {
232: if (pdev->psdm.dm.dmDuplex == DMDUP_HORIZONTAL)
233: {
234: if (pdev->psdm.dm.dmOrientation == DMORIENT_LANDSCAPE)
235: {
236: PrintString(pdev, "%%BeginFeature: *Duplex DuplexNoTumble\n");
237: if (pntpd->loszDuplexNoTumble)
238: pstr = (char *)pntpd + pntpd->loszDuplexNoTumble;
239: }
240: else
241: {
242: PrintString(pdev, "%%BeginFeature: *Duplex DuplexTumble\n");
243: if (pntpd->loszDuplexTumble)
244: pstr = (char *)pntpd + pntpd->loszDuplexTumble;
245: }
246: }
247: else if (pdev->psdm.dm.dmDuplex == DMDUP_VERTICAL)
248: {
249: if (pdev->psdm.dm.dmOrientation == DMORIENT_LANDSCAPE)
250: {
251: PrintString(pdev, "%%BeginFeature: *Duplex DuplexTumble\n");
252: if (pntpd->loszDuplexTumble)
253: pstr = (char *)pntpd + pntpd->loszDuplexTumble;
254: }
255: else
256: {
257: PrintString(pdev, "%%BeginFeature: *Duplex DuplexNoTumble\n");
258: if (pntpd->loszDuplexNoTumble)
259: pstr = (char *)pntpd + pntpd->loszDuplexNoTumble;
260: }
261: }
262: else // turn duplex off.
263: {
264: PrintString(pdev, "%%BeginFeature: *Duplex None\n");
265: if (pntpd->loszDuplexNone)
266: pstr = (char *)pntpd + pntpd->loszDuplexNone;
267: }
268:
269: PrintString(pdev, pstr);
270: PrintString(pdev, "\n%%EndFeature\n");
271: }
272:
273: // handle collation if the device supports it.
274:
275: if (pntpd->loszCollateOn && pntpd->loszCollateOff)
276: {
277: if (pdev->psdm.dm.dmCollate = DMCOLLATE_TRUE)
278: {
279: PrintString(pdev, "%%BeginFeature: *Collate True\n");
280: pstr = (char *)pntpd + pntpd->loszCollateOn;
281: }
282: else
283: {
284: PrintString(pdev, "%%BeginFeature: *Collate False\n");
285: pstr = (char *)pntpd + pntpd->loszCollateOff;
286: }
287:
288: PrintString(pdev, pstr);
289: PrintString(pdev, "\n%%EndFeature\n");
290: }
291:
292: if (pdev->cCopies > 1)
293: {
294: PrintString(pdev, "/#copies ");
295: PrintDecimal(pdev, 1, pdev->cCopies);
296: PrintString(pdev, " def\n");
297: }
298:
299: PrintString(pdev, "%%EndSetup\n%%Page: 1 1\n%%BeginPageSetup\n");
300:
301: // the form / tray information has already been sent for the first page.
302:
303: pdev->dwFlags &= ~PDEV_CHANGEFORM;
304:
305: bSendDeviceSetup(pdev);
306:
307: PrintString(pdev, "%%EndPageSetup\n");
308:
309: // output a save command for the first page. this is done in the
310: // header as part of the effort to avoid outputting two headers in
311: // the raw data case. FALSE means to perform a save and not a gsave.
312:
313: ps_save(pdev, FALSE);
314: pdev->dwFlags |= PDEV_WITHINPAGE;
315:
316: if (pdev->psdm.dwFlags & PSDEVMODE_NEG)
317: {
318: // fill the entire imageable area with white, which will get
319: // transformed to black. then restore the color to black.
320:
321: pbgr = RGB_WHITE;
322: ps_setrgbcolor(pdev, (BGR_PAL_ENTRY *)&pbgr);
323:
324: PrintDecimal(pdev, 4, 0,
325: (pdev->CurForm.imagearea.left * pdev->psdm.dm.dmScale) / 100,
326: (pdev->CurForm.sizlPaper.cy -
327: ((pdev->CurForm.imagearea.top * pdev->psdm.dm.dmScale) / 100)),
328: (pdev->CurForm.imagearea.right * pdev->psdm.dm.dmScale) / 100,
329: (pdev->CurForm.sizlPaper.cy -
330: ((pdev->CurForm.imagearea.bottom * pdev->psdm.dm.dmScale) / 100)));
331:
332: PrintString(pdev, " box\n");
333: pdev->cgs.dwFlags |= CGS_PATHEXISTS;
334:
335: ps_fill(pdev, (FLONG)FP_WINDINGMODE);
336: pbgr = RGB_BLACK;
337: ps_setrgbcolor(pdev, (BGR_PAL_ENTRY *)&pbgr);
338: }
339:
340: pdev->dwFlags |= PDEV_COMPLETEHEADER;
341:
342: return(TRUE);
343: }
344:
345:
346: //--------------------------------------------------------------------------
347: // BOOL bSendDeviceSetup(pdev)
348: // PDEVDATA pdev;
349: //
350: // This routine sends the driver's device setup section of the header
351: // to the output channel.
352: //
353: // Parameters:
354: // pdev:
355: // pointer to DEVDATA structure.
356: //
357: // Returns:
358: // This function returns TRUE if the header was successfully sent,
359: // FALSE otherwise.
360: //
361: // History:
362: // 26-Nov-1990 -by- Kent Settle (kentse)
363: // Wrote it.
364: //--------------------------------------------------------------------------
365:
366: BOOL bSendDeviceSetup(pdev)
367: PDEVDATA pdev;
368: {
369: PSTR pstr;
370: PNTPD pntpd;
371:
372: // set up for new form if necessary.
373:
374: if (pdev->dwFlags & PDEV_CHANGEFORM)
375: {
376: SetFormAndTray(pdev);
377: pdev->dwFlags &= ~PDEV_CHANGEFORM;
378: }
379:
380: pntpd = pdev->pntpd;
381:
382: // rotate and translate if we are in landscape mode.
383:
384: if (pdev->psdm.dm.dmOrientation == DMORIENT_LANDSCAPE)
385: {
386: #ifdef LANDSCAPE_270_ROTATE
387: PrintString(pdev, "270 rotate ");
388: PrintDecimal(pdev, 2, -pdev->CurForm.sizlPaper.cx, 0);
389: PrintString(pdev, " translate\n");
390: #else // 90 degree rotation case.
391: PrintString(pdev, "90 rotate ");
392: PrintDecimal(pdev, 2, 0, -pdev->CurForm.sizlPaper.cy);
393: PrintString(pdev, " translate\n");
394: #endif
395: }
396:
397: // this implementation of mirror imaging is to simply flip over the
398: // x axis. ie, the image is reversed in the horizontal direction.
399: //!!! perhaps at some point we will want to allow flipping in the
400: //!!! vertical direction as well. -kentse.
401:
402: if (pdev->psdm.dwFlags & PSDEVMODE_MIRROR)
403: {
404: PrintDecimal(pdev, 1, pdev->CurForm.sizlPaper.cx);
405: PrintString(pdev, " 0 translate -1 1 scale\n");
406: }
407:
408: // send the proper normalized transfer function, if one exists.
409: // send the inverted transfer function if the PSDEVMODE_NEG
410: // flag is set.
411:
412: if (pdev->psdm.dwFlags & PSDEVMODE_NEG)
413: {
414: // if an inverse normalized transfer function is defined for
415: // this device, send it to the printer, else send the default
416: // inverse transfer function.
417:
418: if (pntpd->loszInvTransferNorm)
419: {
420: pstr = (char *)pntpd + pntpd->loszInvTransferNorm;
421: PrintString(pdev, pstr);
422: }
423: else // default inverse transfer function.
424: PrintString(pdev, "{1 exch sub}");
425:
426: PrintString(pdev, " settransfer\n");
427: }
428: else
429: {
430: // send the normalized transfer function to the printer if
431: // one exists for this printer.
432:
433: if (pntpd->loszTransferNorm)
434: {
435: pstr = (char *)pntpd + pntpd->loszTransferNorm;
436: PrintString(pdev, pstr);
437: PrintString(pdev, " settransfer\n");
438: }
439: }
440:
441: // set the default line width (8 / 1000th inch).
442:
443: pdev->cgs.psfxLineWidth = 0; // force the linewidth to be set.
444: ps_setlinewidth(pdev, PSFX_DEFAULT_LINEWIDTH);
445:
446: return(TRUE);
447: }
448:
449: //--------------------------------------------------------------------
450: // BOOL bSendPSProcSet(pdev, ulPSid)
451: // PDEVDATA pdev;
452: // ULONG ulPSid;
453: //
454: // Routine Description:
455: //
456: // This routine will output the PS Procset Resource referenced by ulPSid
457: // to the PS Interpreter. See PSPROC.H for valid ids.
458: //
459: // Return Value:
460: //
461: // FALSE if an error occurred.
462: //
463: // Author:
464: //
465: // 15-Feb-1993 created -by- Rob Kiesler
466: //
467: //
468: // Revision History:
469: //--------------------------------------------------------------------
470:
471: BOOL bSendPSProcSet(pdev, ulPSid)
472: PDEVDATA pdev;
473: ULONG ulPSid;
474: {
475: HANDLE hRes;
476: USHORT usSize;
477: HANDLE hProcRes;
478: PSZ pntps;
479:
480: if (pdev->dwFlags & PDEV_CANCELDOC)
481: return(TRUE);
482:
483: if (!(hRes = FindResource(ghmodDrv, MAKEINTRESOURCE(ulPSid),
484: MAKEINTRESOURCE(PSPROC))))
485: {
486: RIP("PSCRIPT!bSendPSProcSet: Couldn't find proc set resource\n");
487: return(FALSE);
488: }
489:
490: usSize = (USHORT)SizeofResource(ghmodDrv, hRes);
491:
492: //
493: // Get the handle to the resource.
494: //
495: if (!(hProcRes = LoadResource(ghmodDrv, hRes)))
496: {
497: RIP("PSCRIPT!bSendPSProcSet: LoadResource failed.\n");
498: return(FALSE);
499: }
500:
501: //
502: // Get a pointer to the resource data.
503: //
504: if (!(pntps = (PSZ) LockResource(hProcRes)))
505: {
506: RIP("PSCRIPT!bSendPSProcSet: LockResource failed.\n");
507: FreeResource(hProcRes);
508: return(FALSE);
509: }
510: if (!bPSWrite(pdev, pntps, usSize))
511: {
512: RIP("PSCRIPT!bSendPSProcSet: Output of Header failed.\n");
513: FreeResource(hProcRes);
514: return(FALSE);
515: }
516:
517: FreeResource(hProcRes);
518: bPSFlush(pdev);
519: return(TRUE);
520: }
521:
522:
523: //--------------------------------------------------------------------------
524: // VOID DownloadNTProcSet(pdev, bEhandler)
525: // PDEVDATA pdev;
526: // BOOL bEhandler;
527: //
528: // This routine sends the driver's ProcSet to the output channel.
529: //
530: // Parameters:
531: // pdev:
532: // pointer to DEVDATA structure.
533: //
534: // bEhandler:
535: // TRUE if we should even consider sending the error handler,
536: // otherwise FALSE.
537: //
538: // Returns:
539: // This function returns no value.
540: //
541: // History:
542: // 11-May-1993 -by- Kent Settle (kentse)
543: // Broke into a separate routine.
544: //--------------------------------------------------------------------------
545:
546: VOID DownloadNTProcSet(pdev, bEhandler)
547: PDEVDATA pdev;
548: BOOL bEhandler;
549: {
550: PSZ *ppsz;
551:
552: // define our procedure set.
553:
554: PrintString(pdev, "%%BeginProcSet: Windows_NT_3.1\n");
555: PrintString(pdev, "% Copyright (c) 1991 - 1993 Microsoft Corporation\n");
556:
557: // we need to define the true resolution of the printer.
558:
559: PrintString(pdev, "100 dict begin ");
560: PrintString(pdev, "/DPI ");
561: PrintDecimal(pdev, 1, pdev->psdm.dm.dmPrintQuality);
562: PrintString(pdev, " def\n");
563:
564: PrintString(pdev, "/_snap {transform 36 DPI div sub round 36 DPI div add\n");
565: PrintString(pdev, "exch 36 DPI div sub round 36 DPI div add exch itransform}bind def\n");
566:
567: // download our error handler if we are told to.
568:
569: if (bEhandler)
570: {
571: if (pdev->psdm.dwFlags & PSDEVMODE_EHANDLER)
572: {
573: ppsz = apszEHandler;
574: while (*ppsz)
575: {
576: PrintString(pdev, (PSZ)*ppsz++);
577: PrintString(pdev, "\n");
578: }
579: }
580: }
581: // download our procedure definitions code.
582:
583: ppsz = apszHeader;
584: while (*ppsz)
585: {
586: PrintString(pdev, (PSZ)*ppsz++);
587: PrintString(pdev, "\n");
588: }
589:
590: PrintString(pdev, "%%EndProcSet\n");
591:
592: pdev->dwFlags |= PDEV_PROCSET;
593: }
594:
595:
596: VOID SetFormAndTray(pdev)
597: PDEVDATA pdev;
598: {
599: WCHAR FormName[CCHFORMNAME];
600: WCHAR *pFormName;
601: WCHAR *pSlotName;
602: WCHAR *pPrinterForm;
603: WCHAR ManualName[MAX_SLOT_NAME];
604: WCHAR SearchName[MAX_SLOT_NAME];
605: BOOL bManual, bForm, bFound, bRegion;
606: WCHAR *pwstr;
607: PSINPUTSLOT *pSlot;
608: DWORD i;
609: PSFORM *pPSForm;
610: PNTPD pntpd;
611:
612: pntpd = pdev->pntpd;
613:
614: // select the paper tray. do this by selecting the first tray
615: // which contains the form in question.
616:
617: // get a unicode version of the form name.
618:
619: strcpy2WChar(FormName, pdev->CurForm.PrinterForm);
620:
621: // get the manual tray name.
622:
623: LoadString(ghmodDrv, (SLOT_MANUAL + SLOTS_BASE),
624: ManualName, (sizeof(ManualName) / sizeof(ManualName[0])));
625:
626: // assume the form is not in manual feed.
627:
628: if (pdev->dwFlags & PDEV_MANUALFEED)
629: {
630: PrintString(pdev, "%%BeginFeature: *ManualFeed False\n");
631: PrintString(pdev, (CHAR *)pntpd + pntpd->loszManualFeedFALSE);
632: PrintString(pdev, "\n%%EndFeature\n");
633: pdev->dwFlags &= ~PDEV_MANUALFEED;
634: }
635:
636: bManual = FALSE;
637:
638: // we have the form name, now check the registry to see if this form
639: // is in any of the paper trays.
640:
641: if (pdev->pTrayFormTable)
642: {
643: pwstr = pdev->pTrayFormTable;
644: bForm = FALSE;
645:
646: while (*pwstr)
647: {
648: pSlotName = pwstr;
649: pFormName = pSlotName + (wcslen(pSlotName) + 1);
650: pPrinterForm = pFormName + (wcslen(pFormName) + 1);
651:
652: if (!(wcscmp(pPrinterForm, FormName)))
653: {
654: // we found the form question. get the tray name.
655:
656: if (!(wcscmp(pSlotName, ManualName)))
657: {
658: // the form is in the manual tray, but see if it is
659: // one of the other trays first.
660:
661: bManual = TRUE;
662:
663: pwstr = pPrinterForm + (wcslen(pPrinterForm) + 1);
664: }
665: else
666: {
667: bForm = TRUE;
668: break;
669: }
670: }
671: else
672: {
673: // this was not the form in question. skip over the
674: // tray-form triplet.
675:
676: pwstr = pPrinterForm + (wcslen(pPrinterForm) + 1);
677: }
678: }
679:
680: // if the tray-form pair was found, output the proper commands
681: // to select the tray in question.
682:
683: bFound = FALSE;
684:
685: if (bForm)
686: {
687: // select the tray if there are multiple trays to select from.
688:
689: if (pntpd->cInputSlots > 0)
690: {
691: pSlot = (PSINPUTSLOT *)((CHAR *)pntpd + pntpd->loPSInputSlots);
692:
693: // get each slot name from the NTPD, and do a look up in the
694: // registry to find the associated form name.
695:
696: for (i = 0; i < pntpd->cInputSlots; i++)
697: {
698: strcpy2WChar(SearchName, (CHAR *)pntpd + pSlot->loSlotName);
699:
700: if (!(wcscmp(pSlotName, SearchName)))
701: {
702: bFound = TRUE;
703: break;
704: }
705:
706: pSlot++;
707: }
708:
709: if (bFound)
710: {
711: PrintString(pdev, "%%BeginFeature: *InputSlot ");
712: PrintString(pdev, (CHAR *)pntpd + pSlot->loSlotName);
713: PrintString(pdev, "\n");
714:
715: PrintString(pdev, (CHAR *)pntpd + pSlot->loSlotInvo);
716: PrintString(pdev, "\n%%EndFeature\n");
717: }
718: }
719:
720: }
721:
722: // if the form was not found in one of the paper trays, and the printer
723: // supports manual feed, see if the form is is the manual feed slot.
724:
725: if ((!bFound) && (pntpd->loszManualFeedTRUE != 0) && (bManual))
726: {
727: // the requested form is in the manual feed slot,
728: // so select manual feed.
729:
730: PrintString(pdev, "%%BeginFeature: *ManualFeed True\n");
731: PrintString(pdev, (CHAR *)pntpd + pntpd->loszManualFeedTRUE);
732: PrintString(pdev, "\n%%EndFeature\n");
733: pdev->dwFlags |= PDEV_MANUALFEED;
734: }
735: }
736:
737: // select the page region if we are also selecting from multiple
738: // paper trays or manual feed, otherwise select page size.
739:
740: bRegion = FALSE;
741:
742: if ((pdev->dwFlags & PDEV_MANUALFEED) || (bFound))
743: bRegion = TRUE;
744:
745: // check for the odd occurence where there are no PageRegions (WANG15FP.PPD).
746:
747: // find the PSFORM structure in the NTPD for the current form.
748:
749: pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray);
750:
751: if (!pntpd->cPageRegions)
752: bRegion = FALSE;
753:
754: if (bRegion)
755: PrintString(pdev, "%%BeginFeature: *PageRegion ");
756: else
757: PrintString(pdev, "%%BeginFeature: *PageSize ");
758:
759: PrintString(pdev, pdev->CurForm.PrinterForm);
760: PrintString(pdev, "\n");
761:
762: pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray);
763:
764: for (i = 0; i < pntpd->cPSForms; i++)
765: {
766: if (!(NameComp((CHAR *)pdev->CurForm.PrinterForm,
767: (CHAR *)pntpd + pPSForm->loFormName)))
768: {
769: if (bRegion)
770: PrintString(pdev, (CHAR *)pntpd + pPSForm->loRegionInvo);
771: else
772: PrintString(pdev, (CHAR *)pntpd + pPSForm->loSizeInvo);
773:
774: PrintString(pdev, "\n");
775: break;
776: }
777:
778: // point to the next PSFORM.
779:
780: pPSForm++;
781: }
782:
783: PrintString(pdev, "%%EndFeature\n");
784: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.