GNOME Bugzilla – Bug 339714
Set printer dpi on cairo ps/pdf surfaces when printing
Last modified: 2008-10-30 16:31:46 UTC
When you print to a printer with prints to a specific dpi (or one of many supported dpis was selected by the user) cairo_ps_surface_set_dpi() to make sure that we generate fallback images in the correct resolution.
I'm not sure using the exact dpi from the printer is right btw. For a 300 dpi printer using a 300 pixels per inch photographic image is overkill. On the other hand, for b/w lineart 300 pixels per inch is probably right.
fyi, the cairo set_dpi api is now called cairo_surface_set_fallback_resolution
Created attachment 121126 [details] [review] this patch set fallback resolution of cairo surface This patch set fallback resolution of cairo surface according to settings. It also add distinction between the horizontal and the vertical resolution. It preserves compatibility with the single-valued resolution. Marek
+ + if (gtk_print_settings_get_resolution (settings) == 0) + { + ppd_attr_res = ppdFindAttr (ppd_file, "DefaultResolution", NULL); The printer dpi resolution is unlikely to useful as the fallback resolution. The problem with using the dpi resolution is that due to the halftoning it will be much higher than the effective resolution of the printed color image. This will result in excessive memory usage and significantly slow down the printer. As described at [1], the resolution of color images sent to the printer should be based on the lpi of the printer. This value can be obtained from the "ScreenFreq" attribute. Even better would be to use the "ResScreenFreq" attribute for the specific resolution selected by the user in the Image Quality tab. The Linux Gazette article at [1] recommends using an image resolution of twice the lpi. The GIMP User's Manual [2] recommends 1.6 x lpi. I don't know which would be better but certainly using the printer resolution is the worst option simply due to the huge amount of memory used and the long time it will take the printer to process the image. For example a full-page fallback on an 8" x 11" page at 1200dpi is going to cause cairo to use 1 GB of memory (*) and the printer will likely choke on the 0.5 GB image it receives. (*) 8 x 1200 x 11 x 1200 x 4 (bytes per pixel) x 2 (second copy in memory while blending the transparent image into a white background). [1] http://linuxgazette.net/issue19/more-musings.html [2] http://www.vislab.uq.edu.au/users/manuals/gimp/GimpUsersManual_1.01.pdf page 202
Marek, can you update your patch with this information ?
Created attachment 121434 [details] [review] updated patch Hi Adrian, thank you for the comment. I updated the patch accordingly. Marek
Looks fine to me. Have you give this some testing ?
Hi Matthias, I tested this with virtual printers. I checked the output file and it was always rasterized well (gradient patterns in cairo - I counted number of pixels per inch in rasterized output). Real printers has too high resolution to test it directly on a printer. I had to set LanguageLevel to 2, because cairo doesn't rasterize gradients for Level 3 (they are sent to printer directly). I tested it for different cases ({ResScreenFreq present/not present, ScreenFreq present/not present, selectable resolution / default resolution only}) and also for different values accessible thorough selection of different resolutions. Marek
Thanks for doing that work. Please commit.
What's the "2.0 *" about in: + cairo_surface_set_fallback_resolution (surface, + 2.0 * gtk_print_settings_get_printer_lpi (settings), + 2.0 * gtk_print_settings_get_printer_lpi (settings));
From Adrians recommendations: > The Linux Gazette article at [1] recommends using an image resolution > of twice the lpi. The GIMP User's Manual [2] recommends 1.6 x lpi. I > don't know which would be better
I see. thanks.
It looks like you are using a default lpi of 100 when the lpi can not be determined from the ppd. I assume this applies to creating PDF files as well. I don't think there is any single default lpi value that is going to please everyone. But I would suggest that using a default of 150lpi (or 300dpi cairo fallback when scaled by the 2x scale you are using) would be the best compromise between size and quality for the following reasons: - In the case of PDF files there is no device resolution. The PDF could be printed on many different types of devices or zoomed in on the screen. So we don't want to set a fallback resolution too low for PDF files. - At 300dpi the worst case for a 8"x11" full page full back is 60MB of memory usage and a 30MB image in the PDF (which will be reduced by the compression). This should not cause problems for most modern machines but I wouldn't want to make the default any higher that this. Also a full page fallback in PDF with recent versions of cairo is very rare. You would need to be doing some fancy stuff with the Porter-Duff operators on a full page for this to happen. - My 1200dpi laser has an lpi of 180lpi. According to [1] the lpi of modern inkjet printers is around 300lpi. So a fallback resolution of 300dpi would avoid degrading the image too far below the printer's capability. While 2x the inkjet lpi is actually 600dpi, the memory usage and image size are starting to become excessive and the increase in printing quality would be marginal. - cairo has always had a default fallback of 300dpi and we have not had any complaints. On the subject of the scaling factor, the Wikipedia article on lpi [2] suggests the image resolution should be 1.5 to 2 times the lpi while [1] suggests that the image resolution should be the same as lpi. I have no idea which one is better. [1] http://www.rags-int-inc.com/PhotoTechStuff/Epson2200/ [2] http://en.wikipedia.org/wiki/Lines_per_inch
Created attachment 121575 [details] [review] modified patch Hi, this version of the patch changes the default lpi. I set 100 lpi before because of lowering memory usage (see the comment #1). But the default value will be used at rare cases now, so I changed it to the value corresponding to the Cairo default value. Marek
Please commit, thanks.