When printing to a windows printer using the -sOutputDevice="%printer%PrinterName" command to gswin32c, the number of pages of the job that shows up in windows is the wrong about of pages. A 17 page document shows up as 63,417 pages.
I have checked the code for this device (gp_msprn.c). It starts one page for each buffer of no more than 4k bytes in the output stream. So the number of pages here does not really reflect the actual number in the output, which should be device dependent and as part of the raw data itself, I think. It is not clear to me why the buffer size is currently set as only 4k. If this is increased, maybe the number of pages from the Windows print queue will not seem so large. Another thing that seems worth changing is to move the end page call (EndPagePrinter()) into the while loop, to pair with the start page call. (Currently there can be multiple StartPagePrinter(), but EndPagePrinter() is called only once).
I think that bug #687250 "%printer% OutputFile truncated output" is also relevant, especially bug #687250 comment #8.
After reading comment #8 of bug #687250, I agree that a better way to solve the disparity of start/end page is to move the start page call to right after the start doc call, leaving only one pair of them. This is in case these calls insert unwanted data into the middle of the raw data. (But need to add special handling when the data size exceeds 320MB, to send it in multiple passes).
Making bountiable in case this produces a patch from someone.
Feomn discussion on IRC, we probably should set the page counter after each page is produced, but I don't know Windoze well enough (yet) for the details. If I learn more about how to do this, I will add comments here. Still hoping that someone will collect the bounty.
The code is wrong, in that StartPagePrinter is called too many times. What the code should have done is made the job look like it contains one page only, although it may contain more. The %printer% device has no ability to accurately count pages. It is reading a stream of bytes from a pipe, without understanding the meaning of the bytes. It passes them through unmodified to the printer. To count pages would involve changes to the ghostscript gx_io_device to indicate page boundaries in the stream. Probably not worth doing. My proposal is to change the code so it looks like the print job is a single page.
From discussions with Russell Lang on IRC last night, I understand the problem better now. When the OutputFile specifies a %printer%___ printer queue, the %printer% IODevice code starts a 'reader' thread to get the output that is written (using oridnary 'fwrite' or 'fprintf' from devices to a (FILE *) pointer. The reader then gets a stream of data -- no "out of band" (OOB) data. I propose that the %printer% device adds 'iodev_put_param' for the needed OOB information. The 'gdev_prn_output_page' could do a 'put_param' of the page number and a 'in page' boolean set to 'true', then after the fflush on the file, set the 'in page' boolean parameter to 'false'. The actual parameter names are left to the implementor. Note that in case it is useful, the 'num_copies' could also be transmitted this way and if the put_param returns successfully from writing the number of copies > 1 then the num_copies for the call to the device's "print_page_copies" would be set to 1, leaving the generation of multiple copies to the %printer% device. In theory, on Windows, the spooling system could then produce collated copies from the spool file. The gdev_prn_output_page could always do the 'put_params' (when the OutputFile starts with '%') or could check (observing string length) for "%printer%". I tend to prefer the former so that other IODevice (output file access methods) could take advantage of the information.
No results from Vasu, so reassigning to Robin since he has been hacking on some Windows specific improvements (just my best guess). This is not an urgent customer issue, in fact I can't find an email from them mentioning the problem. It would be nice if it worked correctly, but ...
I found the 'new' command line syntax that doesn't error out that you can use to test with (substitute your printer NAME): bin/gswin64c -sDEVICE=mswinpr2 -sOutputFile="%printer%NAME" examples/annots.pdf I see the correct page count (6 in this case). I found that trying to use -sOutputDevice="%printer%NAME" throws an error from param_check_bytes: if (is_defined && new_value.size == size && !memcmp((const char *)str, (const char *)new_value.data, size) ) break; code = gs_note_error(gs_error_rangecheck); which seems to mean that if 'is_defined' is true, the size and contents have to be the same (OutputDevice cannot be used to change the device). Even though OutputDevice is mentioned in Language.htm, it isn't pointed out that it is a readonly parameter (there is a comment that says: /* Now check nominally read-only parameters. */) Closing the bug as WORKSFORME (if OutputFile is used, not OutputDevice) Investigation done by Eric Johnston.
hmm... actually I was showing Eric how to close the bug, and we forgot to log in as him, so previous comment should have said "Sent from Eric Johnston". So he is the "I" in the previous comment.