|
|
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.