|
|
1.1 root 1: //--------------------------------------------------------------------------
2: //
3: // Module Name: PAGE.C
4: //
5: // Brief Description: DrvStartPage and DrvSendPage routines. Also,
6: // DrvStartDoc, DrvEndDoc and DrvAbortDoc.
7: //
8: // Author: Kent Settle (kentse)
9: // Created: 01-May-1991
10: //
11: // Copyright (C) 1991 - 1992 Microsoft Corporation.
12: //
13: // A little history on how DrvStartDoc and DrvEndDoc bracket a document
14: // in different cases.
15: //
16: // Case 1 - Not raw data. In this case, the application will issue
17: // an ESCAPE(STARTDOC) command. It will get to the driver as
18: // DrvStartDoc. At this point the driver will set a flag, saying
19: // DrvStartDoc has been called. As soon as any drawing command
20: // comes in, and we are about to output something to the printer
21: // the driver checks to see if DrvStartDoc has been called. If
22: // it has, it then checks to see if the header has been sent.
23: // if the header has been sent, the driver just continues normal
24: // output. If the header has not yet been output, the driver
25: // outputs it, then continues with normal output. If DrvStartDoc
26: // has not been called when any drawing begins, no output is
27: // sent to the printer. This is done to force applications to
28: // call start doc and end doc.
29: //
30: // Case 2 - Raw data. In this case, the application will issue an
31: // ESCAPE(STARTDOC) command. It will get to the driver as
32: // DrvStartDoc. At this point the driver will set a flag, saying
33: // DrvStartDoc has been called. The difference here is that
34: // the application will now issue ESCAPE(PASSTHROUGH) commands.
35: // which, in the driver, will not call the normal printing
36: // routine. Therefore, it will not check to see if DrvStartDoc
37: // has been called, and will not output the header. This will
38: // prevent the driver from outputting two headers in the raw
39: // data case. At EndDoc time, the driver checks to see if
40: // we have sent the header to the printer. If we have not, ie
41: // we are sending raw data, then DrvEndDoc will simply send
42: // the end of job command, and not close down dictionaries and
43: // anything else dependent on the header.
44: //
45: // History:
46: // 01-May-1991 -by- Kent Settle (kentse)
47: // Created.
48: //--------------------------------------------------------------------------
49:
50: #include "pscript.h"
51: #include "enable.h"
52: #include <string.h>
53:
54: extern BOOL bSendDeviceSetup(PDEVDATA);
55:
56: //--------------------------------------------------------------------------
57: // VOID DrvStartDoc(pso, pwszDocName, dwJobId)
58: // SURFOBJ *pso;
59: // PWSTR pwszDocName;
60: // DWORD dwJobId;
61: //
62: // This function is called to begin a print job. The title of the
63: // document is pointed to by pvIn.
64: //
65: // History:
66: // 13-Sep-1991 -by- Kent Settle [kentse]
67: // Wrote it.
68: //--------------------------------------------------------------------------
69:
70: BOOL DrvStartDoc(pso, pwszDocName, dwJobId)
71: SURFOBJ *pso;
72: PWSTR pwszDocName;
73: DWORD dwJobId;
74: {
75: PDEVDATA pdev;
76:
77: // get the pointer to our DEVDATA structure and make sure it is ours.
78:
79: pdev = (PDEVDATA) pso->dhpdev;
80:
81: if (!bValidatePDEV(pdev))
82: {
83: RIP("PSCRIPT!DrvStartDoc: invalid pdev.\n");
84: SetLastError(ERROR_INVALID_PARAMETER);
85: return(FALSE);
86: }
87:
88: // set a flag saying that startdoc has been called.
89:
90: pdev->dwFlags |= PDEV_STARTDOC;
91: pdev->iPageNumber = 1;
92:
93: // copy document name into pdev, if we have been passed one.
94:
95: if (pdev->pwstrDocName)
96: HeapFree(pdev->hheap, 0, (LPSTR)pdev->pwstrDocName);
97:
98: if (pwszDocName)
99: {
100: if (!(pdev->pwstrDocName = (PWSTR)HeapAlloc(pdev->hheap, 0,
101: (wcslen(pwszDocName)+1)*sizeof(WCHAR))))
102: {
103: RIP("PSCRIPT!DrvStartDoc: HeapAlloc failed.\n");
104: return(FALSE);
105: }
106:
107: wcscpy(pdev->pwstrDocName, pwszDocName);
108: }
109:
110: return(TRUE);
111: }
112:
113:
114:
115: //--------------------------------------------------------------------------
116: // VOID DrvStartPage(pso)
117: // SURFOBJ *pso;
118: //
119: // Asks the driver to send any control information needed at the start of
120: // a page. The control codes should be sent via WritePrinter.
121: //
122: // History:
123: // 02-May-1991 -by- Kent Settle [kentse]
124: // Wrote it.
125: //--------------------------------------------------------------------------
126:
127: BOOL DrvStartPage(pso)
128: SURFOBJ *pso;
129: {
130: PDEVDATA pdev;
131: DWORD pbgr;
132:
133: // get the pointer to our DEVDATA structure and make sure it is ours.
134:
135: pdev = (PDEVDATA) pso->dhpdev;
136:
137: if (!bValidatePDEV(pdev))
138: {
139: RIP("PSCRIPT!DrvStartPage: invalid pdev.\n");
140: SetLastError(ERROR_INVALID_PARAMETER);
141: return(FALSE);
142: }
143:
144: // bracket each page with a save/restore. however, to get around
145: // sending out two headers when dealing with raw data, do not
146: // send out the save if the header has not been sent. the header
147: // will do the save for the first page.
148:
149: //!!! there must be a cleaner way of doing all this!!! - kentse.
150:
151: if (pdev->dwFlags & PDEV_COMPLETEHEADER)
152: {
153: // output the page number to the printer and update the page count.
154:
155: pdev->iPageNumber++;
156:
157: PrintString(pdev, "%%Page: ");
158: PrintDecimal(pdev, 2, pdev->iPageNumber, pdev->iPageNumber);
159: PrintString(pdev, "\n%%BeginPageSetup\n");
160:
161: // showpage wipes out graphics state and transforms, etc.
162: // so we need to reset some information each page.
163:
164: bSendDeviceSetup(pdev);
165: PrintString(pdev, "%%EndPageSetup\n");
166:
167: // FALSE means to perform a save command, not a gsave.
168:
169: ps_save(pdev, FALSE);
170: pdev->dwFlags |= PDEV_WITHINPAGE;
171:
172: if (pdev->psdm.dwFlags & PSDEVMODE_NEG)
173: {
174: // fill the entire imageable area with white, which will get
175: // transformed to black. then restore the color to black.
176:
177: pbgr = RGB_WHITE;
178: ps_setrgbcolor(pdev, (BGR_PAL_ENTRY *)&pbgr);
179:
180: PrintDecimal(pdev, 4, 0,
181: (pdev->CurForm.imagearea.left * pdev->psdm.dm.dmScale) / 100,
182: (pdev->CurForm.sizlPaper.cy -
183: ((pdev->CurForm.imagearea.top * pdev->psdm.dm.dmScale) / 100)),
184: (pdev->CurForm.imagearea.right * pdev->psdm.dm.dmScale) / 100,
185: (pdev->CurForm.sizlPaper.cy -
186: ((pdev->CurForm.imagearea.bottom * pdev->psdm.dm.dmScale) / 100)));
187:
188: PrintString(pdev, " box\n");
189: pdev->cgs.dwFlags |= CGS_PATHEXISTS;
190:
191: ps_fill(pdev, (FLONG)FP_WINDINGMODE);
192: pbgr = RGB_BLACK;
193: ps_setrgbcolor(pdev, (BGR_PAL_ENTRY *)&pbgr);
194: }
195: }
196:
197: return(TRUE);
198: }
199:
200:
201: //--------------------------------------------------------------------------
202: // VOID DrvEndDoc(pso)
203: // SURFOBJ *pso;
204: //
205: // Informs the driver that the document is ending.
206: //
207: // History:
208: // 13-Sep-1991 -by- Kent Settle [kentse]
209: // Wrote it.
210: //--------------------------------------------------------------------------
211:
212: BOOL DrvEndDoc(pso, fl)
213: SURFOBJ *pso;
214: FLONG fl;
215: {
216: PDEVDATA pdev;
217:
218: UNREFERENCED_PARAMETER(fl);
219:
220: // get the pointer to our DEVDATA structure and make sure it is ours.
221:
222: pdev = (PDEVDATA) pso->dhpdev;
223:
224: if (!bValidatePDEV(pdev))
225: {
226: RIP("PSCRIPT!DrvEndDoc: invalid pdev.\n");
227: SetLastError(ERROR_INVALID_PARAMETER);
228: return(FALSE);
229: }
230:
231: // if RAWDATA has been sent, then we want to do nothing here.
232:
233: if (pdev->dwFlags & PDEV_RAWDATASENT)
234: {
235: // reset some flags.
236:
237: pdev->dwFlags &= ~(PDEV_STARTDOC | PDEV_COMPLETEHEADER |
238: PDEV_PROCSET | PDEV_RAWDATASENT);
239: return(TRUE);
240: }
241:
242: // output the PostScript trailer code if our header was sent out.
243:
244: if ((pdev->dwFlags & PDEV_STARTDOC) &&
245: (pdev->dwFlags & PDEV_COMPLETEHEADER))
246: {
247: // turn off manual feed if it was on.
248:
249: if (pdev->dwFlags & PDEV_MANUALFEED)
250: {
251: PrintString(pdev, "%%BeginFeature: *ManualFeed False\n");
252: PrintString(pdev, (CHAR *)pdev->pntpd +
253: pdev->pntpd->loszManualFeedFALSE);
254: PrintString(pdev, "\n%%EndFeature\n");
255: }
256:
257: // output the Adobe Trailer seperator, and end the dictionary
258: // started at the beginning of the print job.
259:
260: PrintString(pdev, "%%Trailer\nend\n");
261: }
262:
263: // terminate the print job if this is not eps output.
264:
265: if (!(pdev->psdm.dwFlags & PSDEVMODE_EPS))
266: {
267: // set the header sent flag. this will prevent the following
268: // from happening: if we have been sending out raw data, we
269: // will not have sent the header at this point. when we make
270: // the next Print call, it will check to see if we have
271: // sent out the header, and send it if we have not. so lie to
272: // it and tell it we have sent the header.
273:
274: pdev->dwFlags |= PDEV_PROCSET;
275:
276: if (pdev->pntpd->flFlags & PJL_PROTOCOL)
277: {
278: // if the printer supports PJL job switching, send out the universal
279: // end of language code.
280:
281: PrintString(pdev, "\033%-12345X");
282: }
283: else if (pdev->pntpd->flFlags & SIC_PROTOCOL)
284: {
285: // if the printer supports the Lexmark SIC protocol, send out the
286: // end PostScript code.
287:
288: bPSWrite(pdev, "\033\133\113\001\000\006", 7);
289: }
290: else
291: {
292: // end the print job. The character '\4' is
293: // the end of job character for PostScript.
294:
295: if (!(pdev->pntpd->flFlags & NO_ENDOFFILE))
296: PrintString(pdev, "\004");
297: }
298:
299: }
300:
301: // flush the buffer.
302:
303: bPSFlush(pdev);
304:
305: // reset some flags.
306:
307: pdev->dwFlags &= ~(PDEV_STARTDOC | PDEV_COMPLETEHEADER | PDEV_PROCSET);
308:
309: return(TRUE);
310: }
311:
312:
313:
314: //--------------------------------------------------------------------------
315: // BOOL DrvSendPage(pso)
316: // SURFOBJ *pso;
317: //
318: // Requests that the printer send the raw bits from the indicated surface
319: // to the printer via WritePrinter. (WritePrinter does not have to be used when
320: // the hardcopy device is accessed via I/O ports.
321: //
322: // If the surface is a bitmap on which the drawing has been accumulated,
323: // the driver should access the bits via SURFOBJ service functions. If
324: // the surface is a journal, the driver should request that the journal
325: // be played back to a bitmap or device surface, and get the bits
326: // accordingly. Some drivers may have used a device managed surface and
327: // sent the bits to the printer as the drawing orders came in. In that
328: // case, this call does not send out the drawing.
329: //
330: // The control code which causes a page to be ejected from the printer
331: // should be sent as a result of this call.
332: //
333: // If this function is slow, we have to worry about the user wanting to
334: // abort the print job while in this call. Therefore, the driver should
335: // call EngCheckAbort at least once every ten seconds to see if printing
336: // should be terminated. If EngCheckAbort returns TRUE, then processing
337: // of the page should be stopped and this function should return. Note
338: // that EngPlayJournal will take care of querying for the abort itself.
339: // The driver need only be concerned if its own code will run continuously
340: // for more than ten seconds.
341: //
342: // Parameters:
343: // pso:
344: // The surface object on which the drawing has been accumulated. The
345: // object can be queried to find its type and what PDEV it is
346: // associated with.
347: //
348: // Returns:
349: // This function returns no value.
350: //
351: // History:
352: // 01-May-1991 -by- Kent Settle [kentse]
353: // Wrote it.
354: //--------------------------------------------------------------------------
355:
356: BOOL DrvSendPage(pso)
357: SURFOBJ *pso;
358: {
359: PDEVDATA pdev;
360:
361: // get the pointer to our DEVDATA structure and make sure it is ours.
362:
363: pdev = (PDEVDATA) pso->dhpdev;
364:
365: if (!bValidatePDEV(pdev))
366: {
367: RIP("PSCRIPT!DrvSendPage: invalid pdev.\n");
368: SetLastError(ERROR_INVALID_PARAMETER);
369: return(FALSE);
370: }
371:
372: if (pdev->psdm.dwFlags & PSDEVMODE_EPS)
373: {
374: // EPS files consist of one page only, so terminate the
375: // document.
376:
377: if (pdev->dwFlags & PDEV_COMPLETEHEADER)
378: {
379: // output the Adobe Trailer seperator, then end the dictionary
380: // started at the beginning of the print job.
381:
382: PrintString(pdev, "%%Trailer\nend\n");
383:
384: pdev->dwFlags &= ~PDEV_COMPLETEHEADER;
385: }
386:
387: // close the page with a restore. FALSE means restore, not grestore.
388:
389: ps_restore(pdev, FALSE);
390: pdev->dwFlags &= ~PDEV_WITHINPAGE;
391: }
392: else
393: {
394: // if the header has not been sent, nothing will have been sent, so
395: // we have no page to end.
396:
397: if (pdev->dwFlags & PDEV_PROCSET)
398: {
399: // reset PDEV flags concerned with per page information.
400:
401: pdev->dwFlags &= ~(PDEV_FONTREDEFINED | PDEV_LATINENCODED |
402: PDEV_SYMENCODED | PDEV_DINGENCODED);
403:
404: // close the page with a restore. FALSE means restore, not grestore.
405:
406: ps_restore(pdev, FALSE);
407: pdev->dwFlags &= ~PDEV_WITHINPAGE;
408:
409: // generate a PostScript page eject command.
410:
411: ps_showpage(pdev);
412:
413: // flush the output buffer.
414:
415: bPSFlush(pdev);
416: }
417: }
418:
419: return(TRUE);
420: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.