This is a long-standiung bug, but probably no one has perceived it because I have worked around it with Foomatic. The problem is that if one sets the resolution by means of the following option in the PPD file --------------------------------------------------------------------------------- *OpenUI *Resolution/Output Resolution: PickOne *OrderDependency: 20 AnySetup *Resolution *DefaultResolution: 600dpi *Resolution 150dpi/150 DPI: "<</HWResolution[150 150]>>setpagedevice" *Resolution 300dpi/300 DPI: "<</HWResolution[300 300]>>setpagedevice" *Resolution 600dpi/600 DPI: "<</HWResolution[600 600]>>setpagedevice" *Resolution 1200dpi/1200 DPI: "<</HWResolution[1200 1200]>>setpagedevice" *CloseUI: *Resolution --------------------------------------------------------------------------------- which means that CUPS, foomatic-rip, or a PPD-aware applicatiuon inserts a command like "<</HWResolution[1200 1200]>>setpagedevice" into the PostScript data stream the resolution is not correctly set. The bitmap size gets set to be double with 1200 dpi and half with 300 dpi, but the printer does not get set to requested resolution. It always prints with 600 dpi and so with 300 dpi selected one gets a shrinked page in the upper left corner of the sheet and with 1200 dpi one gets the upper left quarter of the page magnified to fill the whole sheet. To get the resolution being set correctly one has to do two things - Supply the resolution with the "-r..." option on the Ghostscript command line - Insert a "@PJL SET RESOLUTION=..." line into the PJL header of the output and the reolution setting must be the same for both. Foomatic automates this with the "pxlmono" PPDs, but this is a hack. It would be nice if the driver would do it by itself. I have tried with a small patch (attached) to let the driver insert the "@PJL SET RESOLUTION=..." line via the px_write_file_header() function in src/gdevpxut.c. The problem is that if the above-mentioned PPD option is used, the dev->HWResolution[] seems not to be set when px_write_file_header() is called, but only later when the output pages are generated. So the printer gets a header with 600 dpi being set as resolution and pages for the user-requested resolution (300 dpi or 1200 dpi). To reproduce, download the Ghostscript SVN branch of the ESP/GPL Ghostscript merger via svn co http://svn.ghostscript.com/ghostscript/branches/gs-esp-gpl-merger with the pstopxl CUPS filter and one of the PPDs from the cups/ directory. Try to print with 300, 600, and 1200 dpi. Problem occurs with all Ghostscript versions. and set up a CUPS print
Created attachment 2955 [details] Patch to let pxlmono/pxlcolor drivers insert PJL code for the resolution
Some additional note: The merger with ESP Ghostscript is in the trunk now and the branch is removed. So take the trunk and the cups/ files from there for further investigations now.
Patch looks ok to me. The pxl drivers are high level vector devices, not raster devices. I don't believe it appropriate to mix setpagedevice parameters in the stream for a single job. For example, pxl sets the resolution at the beginning of a job and maintains that setting for all pages. If changing resolutions is necessary a new job must be created. Unfortunately that could result in losing state (downloaded fonts, color settings). These devices could be written like the raster devices, they would require one job (Session in XL terminology) per page but then you would lose a lot performance-wise. In short you have to use the -r option. Or you can experiment using startjob or exitserver to set options in advance. Ray can help you with that if you go that route. Reassign it back to me if you want me to study it more.
So then I think the way to solve it is to apply my patch and to update the documentation telling that the PostScript command insertion <</HWResolution[XRES YRES]>>setpagedevice is not valid for this driver and "-rXRESxYRES" is required to print with resolutions other than 600 dpi. To make it even better, the driver should ignore <</HWResolution[XRES YRES]>>setpagedevice commands. If there are other high-level vector drivers with a similar problem, their documentation should get fixed appropriately.
I have applied the patch to the SVN repositories now. So only the documentation needs to get fixed now.
One thing I do not understand about this patch, is that HWResolution _was_ being used in the PXL output to set the UnitsPerMeasure values. The output from ghostpdl tools/pxl/pxldis.py shows: ` HP-PCL XL;1;1 uint16_xy 600 600 UnitsPerMeasure ubyte 0 Measure // eInch=0 ubyte 3 ErrorReport // eBackChAndErrPage=3 // Op Pos: 1 Op fOff: 140 Op Hex: 41 Level: 0 BeginSession Specifying resolution in PJL doesn't hurt, but I don't quite follow why the UnitsPerMeasure attribute for 'BeginSession' wasn't adequate.
Ray, tests with actual printers show that the PJL command is required. Without the command the printer stays on 600 dpi. I have found a small bug in my patch, which I have fixed in the SVN now: Modified: trunk/gs/base/gdevpxut.c =================================================================== --- trunk/gs/base/gdevpxut.c 2008-09-02 09:06:41 UTC (rev 9060) +++ trunk/gs/base/gdevpxut.c 2008-09-02 18:37:07 UTC (rev 9061) @@ -81,7 +81,7 @@ else px_put_bytes(s, (const byte *)resolution_600, strlen(resolution_600)); - if ((uint) (dev->HWResolution[0] + 0.5) != + if ((uint) (dev->HWResolution[1] + 0.5) != (uint) (dev->HWResolution[0] + 0.5)) { px_put_bytes(s, (const byte *)"x", strlen("x")); if ((uint) (dev->HWResolution[1] + 0.5) == 150)