Problem with PDF background image in Macbook pro retina screen (Chrome)
See original GitHub issueLink to PDF file (or attach file here): Dropbox ‘Getting Started.pdf’ PDF -> https://www.dropbox.com/s/zwfzuaampxim8bi/Getting Started.pdf?dl=0
Configuration:
- Web browser and its version: Chrome 60.0.3112.101.
- Operating system and its version: macOS Sierra 10.12.6
- PDF.js version: 1.8.571
- Is an extension: Is the pdfjs-dist npm. The project is using Angular 1.x JS Framework.
Steps to reproduce the problem:
- Upload a pdf with a background image, like the default Dropbox PDF, using pdfjs library in an angular 1.x project, in Chrome on a macOS.
- Render it in the Mac screen.
What is the expected behavior? (add screenshot)
A well perfectly scaled blue Dropbox box in background image. Like in the real life.
What went wrong? (add screenshot)
Bad scaled background Dropbox box image. Background is rendered as if CSS styles or canvas width, height are not applying, is my first idea. But I don’t know exactly. It fails only in this configuration. Works in FF in all OS. Works in Chrome both in ubuntu and windows. Works in Mac in another screen. I can only reproduce the bug in the Macbook pro default retina display. Which is important because the target of people using Macbook pro screen and chrome is huge.
Canvas dimensions I’m applying:
/**
* @desc
* Sets canvas dimensions
* @param {Object} canvas - The canvas object.
* @param {number} w - Canvas width.
* @param {number} h - Canvas height.
*/
let setCanvasDimensions = function(canvas, w, h) {
let ratio = backingScale(canvas);
canvas.width = Math.floor(w * ratio);
canvas.height = Math.floor(h * ratio);
canvas.style.width = Math.floor(w) + 'px';
canvas.style.height = Math.floor(h) + 'px';
canvas.getContext('2d').setTransform(ratio, 0, 0, ratio, 0, 0);
return canvas;
};
/**
* @desc
* Backing on scale.
* @param {Object} canvas - The canvas object.
* @returns {number}
*/
let backingScale = function(canvas) {
let ctx = canvas.getContext('2d');
let dpr = window.devicePixelRatio || 1;
let bsr = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1;
return dpr / bsr;
};
The best part: It just happens every first time PDF is rendered in page load. Page 1 is first rendered, and fails. If I go to the next PDF page, 2, page renders ok. Going going back to the page 1, now is ok. Same exact function is called for every page:
function renderPDF() {
[...]
// canvas and ctx are set globally. I put here to better understand code.
let canvas = document.getElementById('pdf-canvas');
let ctx = canvas.getContext('2d');
pdfDoc.getPage(num).then(function(page) {
let viewport, pageWidthScale, renderContext;
viewport = page.getViewport(scale); // scale = 0.8.
setCanvasDimensions(canvas, viewport.width, viewport.height);
renderContext = {
canvasContext: ctx,
viewport: viewport
};
renderTask = page.render(renderContext);
renderTask.promise.then(function() {
if (typeof scope.onPageRender === 'function') {
scope.onPageRender();
}
}).catch( (reason) => console.log(reason));
});
[...]
}
Thanks
Issue Analytics
- State:
- Created 6 years ago
- Comments:14 (7 by maintainers)
Top GitHub Comments
mmm he is asking about current angular (>2.x), different from this issue’s angular (1.x). But I can try it this weekend.
Thank you. Having a minimal Angular example in https://github.com/mozilla/pdf.js/tree/master/examples would probably help out quite a bit of people. I think we should aim for Angular > 2.x since that’s simply more modern, but having an AngularJS example (1.x) would already be better than nothing. People could probably alter it for usage in Angular > 2.x anyway.