From d54793682705276cfa07ee262454f4d9107a3be6 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Mon, 19 Mar 2018 17:27:04 +0100 Subject: [PATCH] Ensure that `PDFPageProxy.pageSizeInches` handles non-default /Rotate entries correctly Without this patch, the pageSize will be incorrectly reported for some PDF files. --- Move pageSizeInches to ui_utils --- src/display/api.js | 13 ------------- test/unit/api_spec.js | 8 -------- test/unit/ui_utils_spec.js | 32 ++++++++++++++++++++++++++++++-- web/pdf_document_properties.js | 6 ++++-- web/ui_utils.js | 22 ++++++++++++++++++++++ 5 files changed, 56 insertions(+), 25 deletions(-) diff --git a/src/display/api.js b/src/display/api.js index 203dbe10f..550e968f2 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -874,19 +874,6 @@ var PDFPageProxy = (function PDFPageProxyClosure() { return this.pageInfo.view; }, - /** - * The size of the current page, converted from PDF units to inches. - * @return {Object} An Object containing the properties: {number} `width` - * and {number} `height`, given in inches. - */ - get pageSizeInches() { - const [x1, y1, x2, y2] = this.view, userUnit = this.userUnit; - return { - width: (x2 - x1) / 72 * userUnit, - height: (y2 - y1) / 72 * userUnit, - }; - }, - /** * @param {number} scale The desired scale of the viewport. * @param {number} rotate Degrees to rotate the viewport. If omitted this diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index ed4a809ea..35e729283 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -964,14 +964,6 @@ describe('api', function() { it('gets view', function () { expect(page.view).toEqual([0, 0, 595.28, 841.89]); }); - - it('gets page size (in inches)', function() { - const { width, height, } = page.pageSizeInches; - - expect(+width.toPrecision(3)).toEqual(8.27); - expect(+height.toPrecision(4)).toEqual(11.69); - }); - it('gets viewport', function () { var viewport = page.getViewport(1.5, 90); expect(viewport.viewBox).toEqual(page.view); diff --git a/test/unit/ui_utils_spec.js b/test/unit/ui_utils_spec.js index 4765dcaf4..180b7a036 100644 --- a/test/unit/ui_utils_spec.js +++ b/test/unit/ui_utils_spec.js @@ -14,8 +14,8 @@ */ import { - binarySearchFirstItem, EventBus, getPDFFileNameFromURL, isValidRotation, - waitOnEventOrTimeout, WaitOnType + binarySearchFirstItem, EventBus, getPageSizeInches, getPDFFileNameFromURL, + isValidRotation, waitOnEventOrTimeout, WaitOnType } from '../../web/ui_utils'; import { createObjectURL } from '../../src/shared/util'; import isNodeJS from '../../src/shared/is_node'; @@ -398,4 +398,32 @@ describe('ui_utils', function() { }, done.fail); }); }); + + describe('getPageSizeInches', function () { + it('gets page size (in inches)', function() { + const page = { + view: [0, 0, 595.28, 841.89], + userUnit: 1.0, + rotate: 0, + }; + const { width, height, } = getPageSizeInches(page); + + expect(+width.toPrecision(3)).toEqual(8.27); + expect(+height.toPrecision(4)).toEqual(11.69); + }); + + it('gets page size (in inches), for non-default /Rotate entry', function() { + const pdfPage1 = { view: [0, 0, 612, 792], userUnit: 1, rotate: 0, }; + const { width: width1, height: height1, } = getPageSizeInches(pdfPage1); + + expect(width1).toEqual(8.5); + expect(height1).toEqual(11); + + const pdfPage2 = { view: [0, 0, 612, 792], userUnit: 1, rotate: 90, }; + const { width: width2, height: height2, } = getPageSizeInches(pdfPage2); + + expect(width2).toEqual(11); + expect(height2).toEqual(8.5); + }); + }); }); diff --git a/web/pdf_document_properties.js b/web/pdf_document_properties.js index 880c0a1b8..cb5d81e8f 100644 --- a/web/pdf_document_properties.js +++ b/web/pdf_document_properties.js @@ -13,7 +13,9 @@ * limitations under the License. */ -import { cloneObj, getPDFFileNameFromURL, NullL10n } from './ui_utils'; +import { + cloneObj, getPageSizeInches, getPDFFileNameFromURL, NullL10n +} from './ui_utils'; import { createPromiseCapability } from 'pdfjs-lib'; const DEFAULT_FIELD_CONTENT = '-'; @@ -92,7 +94,7 @@ class PDFDocumentProperties { this._parseDate(info.CreationDate), this._parseDate(info.ModDate), this.pdfDocument.getPage(currentPageNumber).then((pdfPage) => { - return this._parsePageSize(pdfPage.pageSizeInches); + return this._parsePageSize(getPageSizeInches(pdfPage)); }), ]); }).then(([info, metadata, fileName, fileSize, creationDate, modDate, diff --git a/web/ui_utils.js b/web/ui_utils.js index b289ecd01..62a06789b 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -269,6 +269,27 @@ function roundToDivide(x, div) { return r === 0 ? x : Math.round(x - r + div); } +/** + * Gets the size of the specified page, converted from PDF units to inches. + * @param {Object} An Object containing the properties: {Array} `view`, + * {number} `userUnit`, and {number} `rotate`. + * @return {Object} An Object containing the properties: {number} `width` + * and {number} `height`, given in inches. + */ +function getPageSizeInches({ view, userUnit, rotate, }) { + const [x1, y1, x2, y2] = view; + // We need to take the page rotation into account as well. + const changeOrientation = rotate % 180 !== 0; + + const width = (x2 - x1) / 72 * userUnit; + const height = (y2 - y1) / 72 * userUnit; + + return { + width: (changeOrientation ? height : width), + height: (changeOrientation ? width : height), + }; +} + /** * Generic helper to find out what elements are visible within a scroll pane. */ @@ -645,6 +666,7 @@ export { parseQueryString, getVisibleElements, roundToDivide, + getPageSizeInches, approximateFraction, getOutputScale, scrollIntoView,