PDFs viewed using the Firefox built-in PDF viewer render blurry on Mac. It appears that the PDF viewer is not rendering at Retina-level resolution.
Configuration:
Steps to reproduce the problem:
What is the expected behavior? Crisp rendering
What went wrong? Blurry rendering
Another example here. Just view in Firefox on a Retina display Mac.
Currently on Macbook Air 13-inch 2018 running OS X 10.14.2 with Firefox Nightly 67.0a1.
pdf.js uses a canvas for rendering, which renders at "device-independent" resolution. On high dpi screens, this is lower than the actual "native device-pixel resolution", so the canvas bitmap is upscaled to the display.
I found some links on how to draw a canvas at "device-pixel resolution". I cannot confirm these work, or that they're pixel-perfect with no rounding errors or linear-interpolation blurring.
https://gist.github.com/callumlocke/cc258a193839691f60dd
https://stackoverflow.com/questions/19142993/how-draw-in-high-resolution-to-canvas-on-chrome-and-why-if-devicepixelratio
Do we need to update examples for resolving this or change a part of the code so that we don't need to update examples?
I really don't understand this question, since it's clearly already supported in PDF.js courtesy of https://github.com/mozilla/pdf.js/blob/06b253d6092e14a118f9d5b23fa0652498c68a96/web/ui_utils.js#L95
Besides, this issue is (most likely) a duplicate of https://bugzilla.mozilla.org/show_bug.cgi?id=1537955, in which case it cannot really be fixed here anyway. Closing as duplicate of the upstream issue?
Of course it is, but not if one tries the examples here on High DPI displays. For that to work, we'd have add something like
canvas.style.width = viewport.width
canvas.style.height = viewport.height
canvas.width = viewport.width * window.devicePixelRatio;
canvas.height = viewport.height * window.devicePixelRatio;
Right?
The image linked in https://github.com/mozilla/pdf.js/issues/10509#issue-404449549 clearly shows the default viewer, hence my remarks in https://github.com/mozilla/pdf.js/issues/10509#issuecomment-500881064 still stands.
https://mozilla.github.io/pdf.js/examples/ is purposely a very basic example, and when using something like the "viewer components" examples there's already support for HiDPI built-in (again see https://github.com/mozilla/pdf.js/issues/10509#issuecomment-500881064).
I was able to improve image quality by increasing scale and then reducing the canvas style size by the scale. I believe this is effectively increasing the DPI per canvas dimensions? Also kinda a hack, is there a better way to do this?
var scales = { 1: 3.2, 2: 4 },
defaultScale = 3,
scale = scales[window.devicePixelRatio] || defaultScale;
var viewport = page.getViewport({ scale: scale });
canvas.height = viewport.height;
canvas.width = viewport.width;
var displayWidth = 1.5;
canvas.style.width = `${(viewport.width * displayWidth) / scale}px`;
canvas.style.height = `${(viewport.height * displayWidth) / scale}px`;
increasing the scale alone as @apoorv-mishra suggested. I would end up with the pdf taking up just the top left quarter of the page.
|X |
| |
+--+
Assuming that the problem described in https://github.com/mozilla/pdf.js/issues/10509#issue-404449549 was related to "resistFingerprinting", then this issue should now have been fixed (in the latest Nightly) courtesy of https://bugzilla.mozilla.org/show_bug.cgi?id=1537955.
Assuming that the problem described in #10509 (comment) was related to "resistFingerprinting", then this issue _should_ now have been fixed (in the latest Nightly) courtesy of https://bugzilla.mozilla.org/show_bug.cgi?id=1537955.
Unfortunately, it is _not_ fixed in the latest Nightly
Unfortunately, it is _not_ fixed in the latest Nightly
Just to make absolutely sure, can you please enter about:buildconfig
in the address bar and copy-and-paste the line that reads "Built from ..." near the top.
This is now fixed on the latest Nightly!
Build config: https://hg.mozilla.org/mozilla-central/rev/36c3240e5cafd7b57146bab3b177bfa47f42bcfa
Hi, I'm still experiencing this issue on latest Firefox with this user.js:
user_pref("privacy.firstparty.isolate", true);
user_pref("privacy.resistFingerprinting", true);
Version: Firefox Developer Edition 71.0b10, build rev 992520c31cde6750358c5d5c3a610f77ebadd404
OS: Debian 10
The problem appears only when the two above settings are set. With the default config rendering is crisp.
@ChrisCPO I had the exact same problem with the PDF filling only the upper left quarter. I think I found the "clean" solution here
It's an extension of @apoorv-mishra solution:
const devicePixelRatio = window.devicePixelRatio || 1;
canvas.style.width = viewport.width;
canvas.style.height = viewport.height;
canvas.width = viewport.width * devicePixelRatio;
canvas.height = viewport.height * devicePixelRatio;
// [sx, 0, 0, sy, 0, 0]
const transform = [ devicePixelRatio, 0 , 0, devicePixelRatio, 0, 0];
const renderContext = {
canvasContext: canvas.getContext("2d");
viewport: viewport,
transform: transform
}
@Franziskus1988 I can confirm that this solution does indeed work (well) for initial rendering. Subsequent zooming in also works well. However, when zooming out to say 50% and then back to 400% on a hi-dpi PDF the blurriness remains. Just a note for anyone else following this thread. Thanks for the code though, it has saved me a lot of headaches so far.
@Jon-Murray I didn't come across this problem, because we are limiting the zooming in our application. It suprises me a little bit that it fails on zoom.
In the original implementation here they are setting a maxScale. Maybe you could try to use this more sophisticated code from the original pdf.js viewer.
The result from code by @ChrisCPO looks much better than that by @Franziskus1988
It is better to set the scale
based on the display resolution
andzoom level
.
Here is a link on How to detect page zoom level in all modern browsers?
https://stackoverflow.com/questions/1713771/how-to-detect-page-zoom-level-in-all-modern-browsers
Most helpful comment
I was able to improve image quality by increasing scale and then reducing the canvas style size by the scale. I believe this is effectively increasing the DPI per canvas dimensions? Also kinda a hack, is there a better way to do this?
increasing the scale alone as @apoorv-mishra suggested. I would end up with the pdf taking up just the top left quarter of the page.