Disable Subpixel Snapping When Rendering to PDFs
Categories
(Core :: Printing: Output, defect)
Tracking
()
People
(Reporter: ossman, Unassigned)
Details
Attachments
(5 files)
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:105.0) Gecko/20100101 Firefox/105.0
Steps to reproduce:
- Create a page with borders
- Print to PDF
Actual results:
Borders in PDF are thinner than specified by CSS.
Expected results:
Borders should match width specified in CSS.
Reporter | ||
Comment 1•2 years ago
|
||
Test case that demonstrates the bug. It seems to be some explicit nudging of border widths as only widths that are integer pixel sizes are tweaked, and always by a fixed amount (rather than a linear scale).
Also embedded a SVG image for reference, where dimensions are left alone.
Reporter | ||
Comment 2•2 years ago
|
||
Output as generated on my copy of Firefox, in case you get some other result.
Reporter | ||
Comment 3•2 years ago
|
||
We are trying to use Firefox as a way to generate vector-based screenshots, and this bug screws up the layout as the CSS isn't properly respected.
Comment 4•2 years ago
|
||
The Bugbug bot thinks this bug should belong to the 'Firefox::PDF Viewer' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.
Updated•2 years ago
|
Comment 5•2 years ago
•
|
||
Quoting comment 0 here:
Expected results:
Borders should match width specified in CSS.
So: we don't precisely match the width specified in CSS, since (as you inferred in comment 1) we in fact round borders (specifically borders, as distinguished from other CSS sizes) to whole display-pixel values -- which may or may not be the same as whole CSS pixels, depending on the resolution of the display/output device.
WebKit does this rounding as well, and Chrome is changing to match -- see https://bugs.chromium.org/p/chromium/issues/detail?id=1201762 and https://github.com/w3c/csswg-drafts/issues/5210
emilio blogged about this in https://crisal.io/words/2020/06/13/rounding-borders.html as well if you want more nitty-gritty details and background about the reasons/tradeoffs.
If you're setting up content that depends on border-width:1.5px
reliably occupying 1.5 css pixels of layout space (being visually distinct from a 1px border, and offsetting the content that follows by an extra half-pixel), then that's likely to not reliably work in any browser pretty soon (though it may work in some cases if your display device's pixel ratio is such that 1.5 css pixels is a whole number of device pixels).
Does that make sense? Am I missing something about the description/testcase here?
Comment 6•2 years ago
|
||
Also: to the extent that you're seeing different border-thickness-behavior in print-to-PDF output vs. regular browser rendering of your testcase, that's likely because of DPI differences between the PDF-printing backend vs. your screen. The PDF virtual-printer probably has a higher display-pixel density than your screen, so it ends up with different pixel-rounding behavior as a result.
Reporter | ||
Comment 7•2 years ago
|
||
Hmm... So if I understand you correctly only borders get this nudging, nothing else? This is problematic when you want to match it with other things...
I would have expected the PDF output to have massive DPI? Or just plainly disable the nudging since it isn't relevant. Right now I seem to be seeing that a PDF pixel is 0.6667 CSS pixels, which is a very annoying number as fairly sane on-screen widths such as 1px get distorted in print.
Is there some way we can influence this grid? I tried changing the print scale, but it did not fix it. It seems the pixel grid scales as well, keeping that odd ratio to CSS pixels.
Comment 8•2 years ago
•
|
||
(In reply to Pierre Ossman from comment #7)
Hmm... So if I understand you correctly only borders get this nudging, nothing else? This is problematic when you want to match it with other things...
Correct. See bug 477157 which I filed 14 years back, for one case where it's problematic (borders not exactly covering a red background area that's nominally the same size).
It's a tradeoff, and Emilio's above-linked blog post goes into the reasons for this.
It at least should be standardized and reasonably-interoperable soon, per the above-linked Chrome bug.
I would have expected the PDF output to have massive DPI? Or just plainly disable the nudging since it isn't relevant.
That seems like a reasonable intuition, if you think of a PDF as having an infinite resolution. On the other hand, PDFs obviously aren't viewed on devices with infinite resolution, so we might be picking some assumed resolution based on assumptions about the eventual display device; I'm not sure.
Anyway -- I don't recall what resolution we use for generating PDFs, but I or someone can check... [I'll try to circle back with an answer on that, please nag me if I forget]
Is there some way we can influence this grid? I tried changing the print scale, but it did not fix it. It seems the pixel grid scales as well, keeping that odd ratio to CSS pixels.
I'm not sure offhand; I think really you would need to control the device-pixel-to-css-pixel ratio. I don't think that's configurable for our built-in save-to-PDF backend. It might be possible to do using a custom print driver, though I'm not entirely sure.
Reporter | ||
Comment 9•2 years ago
|
||
Yay! I found a setting amongst the dragons that fixes this! Specifically printer.default_dpi
. It's set to 144
by default, i.e. 1.5×96
, which fully explains why a PDF “device pixel” is .667 CSS pixels. If I change that value to 96
, then I get much saner output.
Why is that value not 96
by default, though? Historical reasons? I tried to compare both PDFs and real prints with different settings, and I could not find any difference except border width rounding. Images and vector graphics are all rendered using the same size and density no matter the setting.
Side note: Background position seems to be rounded to device pixels for screen output, but not for print output. Perhaps something that also should be harmonised?
Comment 10•2 years ago
|
||
Higher DPI is very useful for images / rasterized web content, see bug 1664258. It was historically 144 already on Windows.
Reporter | ||
Comment 11•2 years ago
|
||
Do you have a more clear example? I could not see any rasterisation differences when changing that value.
If it truly needs to be higher than the standard 96, then I think it should at the very least be an integer multiple of 96 to avoid issues like the one described in the bug here.
Comment 12•2 years ago
|
||
There were a variety of reports like bug 1658333 where images were wrongly scaled. IIRC the "regular" DPI before that bug was 72.0. Jonathans, do you have context on why the default dpi for printing used to be 72 rather than 96?
Comment 13•2 years ago
|
||
I don't know the specific history of our printing code, but 72dpi was the typical resolution of old dot-matrix printers, and of the original Mac's "WYSIWYG" bitmapped display. (It also relates to PostScript and PDF's native "point" unit.)
Comment 14•2 years ago
•
|
||
I do wonder if we should disable the pixel-snapping of borders altogether when rendering to PDF, at least, and maybe for all printing unless we know it's a raster printer with a specific DPI. We have absolutely no way of knowing what resolution will be used when the PDF eventually gets viewed or printed, so the chances that our snapping will be "right" for that context, and improve the final quality, must be quite low.
Comment 15•2 years ago
|
||
For convenience, here's a testcase with each of the 0.1px values between 0.1px and 3px, to help visualize what the threshold is where the snapping behavior changes.
Comment 16•2 years ago
|
||
Comment 17•2 years ago
|
||
Comment 18•2 years ago
|
||
Changing title as per discussion - I wonder if bug 1803373 relates?
Updated•2 years ago
|
Comment 19•2 years ago
|
||
(In reply to Emilio Cobos Álvarez (:emilio) from comment #12)
Jonathans, do you have context on why the default dpi for printing used to be 72 rather than 96?
I'd just add to jfkthame's comment that subsequent dot matrix printers were 144 DPI, I think, so it probably still made some sense to use 72 DPI in the Netscape era.
Description
•