-
-
Notifications
You must be signed in to change notification settings - Fork 977
Description
First of all, really appreciate everyone who contributes to this project 🙇 .
Our team recently encountered an issue with getting the pages' width and height. To be more specific, we have a custom callback function that's passed as the onRenderSuccess prop to the <Page /> component. In that callback, we access the parameter that passed to the callback to get the dimensional information of the page such as height, width, etc.
Something like this:
handleRenderSuccess = pageData => {
const height = pageData.height;
const width = pageData.width;
// Do something else
}
render() {
<Page
onRenderSuccess={handleRenderSuccess}
// Other props
/>
}However we found out for very little pdfs, the pageData.height gives us 0 and so is pageData.originalHeight. Even if the page renders correctly without any error in the console.
After some digging, we found the parameter passes to onRenderSuccess prop is generated by makePageCallback() in utils:
react-pdf/src/Page/PageCanvas.jsx
Line 59 in 2df1e24
| if (onRenderSuccess) onRenderSuccess(makePageCallback(page, scale)); |
Inside
makePageCallback(), it gets the page's original width by this.view[2] and original height by this.view[3], then times the scale to get the width and height respectively.Lines 120 to 126 in 2c0e179
| export const makePageCallback = (page, scale) => { | |
| Object.defineProperty(page, 'width', { get() { return this.view[2] * scale; }, configurable: true }); | |
| Object.defineProperty(page, 'height', { get() { return this.view[3] * scale; }, configurable: true }); | |
| Object.defineProperty(page, 'originalWidth', { get() { return this.view[2]; }, configurable: true }); | |
| Object.defineProperty(page, 'originalHeight', { get() { return this.view[3]; }, configurable: true }); | |
| return page; | |
| }; |
The
view is an array with four entries representing the "mediaBox" of the current page (https://github.com/mozilla/pdf.js/blob/e389ed6201df7955147dafda3a6813fff8ca5934/src/core/document.js#L173-L191).Conventionally, the first two numbers are the lower left x and y coordinates, and the last two numbers are the upper right x and y coordinates.
However, according to this pdf spec by Adobe (section 7.9.5), it's also acceptable to specify the upper left x and y, and lower right x and y. It also recommends applications to take this into consideration.
We verify that's the reason for some pages' originalHeight to be zero by checking the view property. It gives us something like [0, 824.400024, 578.159973, 0]. Which we believe the first two numbers are the upper left x and y coordinates, and the last two numbers are lower left x and y coordinates.
I wonder has anybody else also encountered this issue? My suggestion for the fix will probably be updating makePageCallback() to:
export const makePageCallback = (page, scale) => {
const originalWidth = Math.max(this.view[0], this.view[2]);
const originalHeight = Math.max(this.view[1], this.view[3]);
Object.defineProperty(page, 'width', { get() { return originalWidth * scale; }, configurable: true });
Object.defineProperty(page, 'height', { get() { return originalHeight * scale; }, configurable: true });
Object.defineProperty(page, 'originalWidth', { get() { return originalWidth; }, configurable: true });
Object.defineProperty(page, 'originalHeight', { get() { return originalHeight; }, configurable: true });
return page;
}; Does this sound like the right approach? I'm by no means an expert of pdf. Any feedback or suggestion are definitely welcome. Thank you for your time!
Due to some privacy issue, I'm not able to provide an example pdf. Apologize in advance.