From 77d025dc14f0a3eabb1ade8c9a46af9a8776ddfa Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 20 Mar 2018 13:25:13 +0100 Subject: [PATCH 1/8] Move the `isPortraitOrientation` helper function from `web/base_viewer.js` to `web/ui_utils.js` A couple of basic unit-tests are added, and a manual `isLandscape` check (in `web/base_viewer.js`) is also converted to use the helper function instead. --- test/unit/ui_utils_spec.js | 23 ++++++++++++++++++++++- web/base_viewer.js | 16 ++++++---------- web/ui_utils.js | 5 +++++ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/test/unit/ui_utils_spec.js b/test/unit/ui_utils_spec.js index 180b7a036..64426c966 100644 --- a/test/unit/ui_utils_spec.js +++ b/test/unit/ui_utils_spec.js @@ -15,7 +15,7 @@ import { binarySearchFirstItem, EventBus, getPageSizeInches, getPDFFileNameFromURL, - isValidRotation, waitOnEventOrTimeout, WaitOnType + isPortraitOrientation, isValidRotation, waitOnEventOrTimeout, WaitOnType } from '../../web/ui_utils'; import { createObjectURL } from '../../src/shared/util'; import isNodeJS from '../../src/shared/is_node'; @@ -285,6 +285,27 @@ describe('ui_utils', function() { }); }); + describe('isPortraitOrientation', function() { + it('should be portrait orientation', function() { + expect(isPortraitOrientation({ + width: 200, + height: 400, + })).toEqual(true); + + expect(isPortraitOrientation({ + width: 500, + height: 500, + })).toEqual(true); + }); + + it('should be landscape orientation', function() { + expect(isPortraitOrientation({ + width: 600, + height: 300, + })).toEqual(false); + }); + }); + describe('waitOnEventOrTimeout', function() { let eventBus; diff --git a/web/base_viewer.js b/web/base_viewer.js index bc7955750..daefce3cc 100644 --- a/web/base_viewer.js +++ b/web/base_viewer.js @@ -14,9 +14,10 @@ */ import { - CSS_UNITS, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, isValidRotation, - MAX_AUTO_SCALE, NullL10n, PresentationModeState, RendererType, - SCROLLBAR_PADDING, TextLayerMode, UNKNOWN_SCALE, VERTICAL_PADDING, watchScroll + CSS_UNITS, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, isPortraitOrientation, + isValidRotation, MAX_AUTO_SCALE, NullL10n, PresentationModeState, + RendererType, SCROLLBAR_PADDING, TextLayerMode, UNKNOWN_SCALE, + VERTICAL_PADDING, watchScroll } from './ui_utils'; import { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue'; import { AnnotationLayerBuilder } from './annotation_layer_builder'; @@ -94,10 +95,6 @@ function isSameScale(oldScale, newScale) { return false; } -function isPortraitOrientation(size) { - return size.width <= size.height; -} - /** * Simple viewer control to display PDF content/pages. * @implements {IRenderableView} @@ -578,11 +575,10 @@ class BaseViewer { scale = Math.min(pageWidthScale, pageHeightScale); break; case 'auto': - let isLandscape = (currentPage.width > currentPage.height); // For pages in landscape mode, fit the page height to the viewer // *unless* the page would thus become too wide to fit horizontally. - let horizontalScale = isLandscape ? - Math.min(pageHeightScale, pageWidthScale) : pageWidthScale; + let horizontalScale = isPortraitOrientation(currentPage) ? + pageWidthScale : Math.min(pageHeightScale, pageWidthScale); scale = Math.min(MAX_AUTO_SCALE, horizontalScale); break; default: diff --git a/web/ui_utils.js b/web/ui_utils.js index 67fd93d4a..471ca8202 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -439,6 +439,10 @@ function isValidRotation(angle) { return Number.isInteger(angle) && angle % 90 === 0; } +function isPortraitOrientation(size) { + return size.width <= size.height; +} + function cloneObj(obj) { let result = Object.create(null); for (let i in obj) { @@ -642,6 +646,7 @@ export { SCROLLBAR_PADDING, VERTICAL_PADDING, isValidRotation, + isPortraitOrientation, isFileSchema, cloneObj, PresentationModeState, From b7b5d93231d13f04c24035d445c30bffe3131bb3 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 20 Mar 2018 13:30:55 +0100 Subject: [PATCH 2/8] Reduce the duplication for the `document_properties_page_size_*` strings, by defining the units separately --- l10n/en-US/viewer.properties | 12 ++++++------ l10n/sv-SE/viewer.properties | 12 ++++++------ web/pdf_document_properties.js | 33 +++++++++++++++++++-------------- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/l10n/en-US/viewer.properties b/l10n/en-US/viewer.properties index 4533de643..a20f72219 100644 --- a/l10n/en-US/viewer.properties +++ b/l10n/en-US/viewer.properties @@ -90,12 +90,12 @@ document_properties_producer=PDF Producer: document_properties_version=PDF Version: document_properties_page_count=Page Count: document_properties_page_size=Page Size: -# LOCALIZATION NOTE (document_properties_page_size_in_2): "{{width}}" and "{{height}}" -# will be replaced by the size of the (current) page, in inches. -document_properties_page_size_in_2={{width}} × {{height}} in -# LOCALIZATION NOTE (document_properties_page_size_mm_2): "{{width}}" and "{{height}}" -# will be replaced by the size of the (current) page, in millimeters. -document_properties_page_size_mm_2={{width}} × {{height}} mm +document_properties_page_size_unit_inches=in +document_properties_page_size_unit_millimeters=mm +# LOCALIZATION NOTE (document_properties_page_size_dimension_string): +# "{{width}}", "{{height}}", and {{unit}} will be replaced by the size, +# respectively their unit of measurement, of the (current) page. +document_properties_page_size_dimension_string={{width}} × {{height}} {{unit}} document_properties_close=Close print_progress_message=Preparing document for printing… diff --git a/l10n/sv-SE/viewer.properties b/l10n/sv-SE/viewer.properties index 8b015fa50..59f4a99d3 100644 --- a/l10n/sv-SE/viewer.properties +++ b/l10n/sv-SE/viewer.properties @@ -90,12 +90,12 @@ document_properties_producer=PDF-producent: document_properties_version=PDF-version: document_properties_page_count=Sidantal: document_properties_page_size=Sidstorlek: -# LOCALIZATION NOTE (document_properties_page_size_in_2): "{{width}}" and "{{height}}" -# will be replaced by the size of the (current) page, in inches. -document_properties_page_size_in_2={{width}} × {{height}} tum -# LOCALIZATION NOTE (document_properties_page_size_mm_2): "{{width}}" and "{{height}}" -# will be replaced by the size of the (current) page, in millimeters. -document_properties_page_size_mm_2={{width}} × {{height}} mm +document_properties_page_size_unit_inches=tum +document_properties_page_size_unit_millimeters=mm +# LOCALIZATION NOTE (document_properties_page_size_dimension_string): +# "{{width}}", "{{height}}", and {{unit}} will be replaced by the size, +# respectively their unit of measurement, of the (current) page. +document_properties_page_size_dimension_string={{width}} × {{height}} {{unit}} document_properties_close=Stäng print_progress_message=Förbereder sidor för utskrift… diff --git a/web/pdf_document_properties.js b/web/pdf_document_properties.js index cb5d81e8f..31033a61c 100644 --- a/web/pdf_document_properties.js +++ b/web/pdf_document_properties.js @@ -247,20 +247,25 @@ class PDFDocumentProperties { const { width, height, } = pageSizeInches; return Promise.all([ - this.l10n.get('document_properties_page_size_in_2', { - width: (Math.round(width * 100) / 100).toLocaleString(), - height: (Math.round(height * 100) / 100).toLocaleString(), - }, '{{width}} × {{height}} in'), - // 1in = 25.4mm; no need to round to 2 decimals for millimeters. - this.l10n.get('document_properties_page_size_mm_2', { - width: (Math.round(width * 25.4 * 10) / 10).toLocaleString(), - height: (Math.round(height * 25.4 * 10) / 10).toLocaleString(), - }, '{{width}} × {{height}} mm'), - ]).then((sizes) => { - return { - inch: sizes[0], - mm: sizes[1], - }; + this.l10n.get('document_properties_page_size_unit_inches', null, 'in'), + this.l10n.get('document_properties_page_size_unit_millimeters', null, + 'mm'), + ]).then(([unitInches, unitMillimeters]) => { + return Promise.all([ + this.l10n.get('document_properties_page_size_dimension_string', { + width: (Math.round(width * 100) / 100).toLocaleString(), + height: (Math.round(height * 100) / 100).toLocaleString(), + unit: unitInches, + }, '{{width}} × {{height}} {{unit}}'), + // 1in == 25.4mm; no need to round to 2 decimals for millimeters. + this.l10n.get('document_properties_page_size_dimension_string', { + width: (Math.round(width * 25.4 * 10) / 10).toLocaleString(), + height: (Math.round(height * 25.4 * 10) / 10).toLocaleString(), + unit: unitMillimeters, + }, '{{width}} × {{height}} {{unit}}'), + ]); + }).then((sizes) => { + return { inch: sizes[0], mm: sizes[1], }; }); } From ab74b320543da2529b3beba9cb241d139b8aacce Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 20 Mar 2018 13:37:19 +0100 Subject: [PATCH 3/8] Adjust the displayed pageSize, in the document properties dialog, depending on the current *viewer* rotation (PR 9586 follow-up) Please note that the behaviour implemented here mirrors the one used in Adobe Reader. --- web/pdf_document_properties.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/web/pdf_document_properties.js b/web/pdf_document_properties.js index 31033a61c..731dd5c9e 100644 --- a/web/pdf_document_properties.js +++ b/web/pdf_document_properties.js @@ -55,6 +55,9 @@ class PDFDocumentProperties { eventBus.on('pagechanging', (evt) => { this._currentPageNumber = evt.pageNumber; }); + eventBus.on('rotationchanging', (evt) => { + this._pagesRotation = evt.pagesRotation; + }); } } @@ -74,11 +77,13 @@ class PDFDocumentProperties { Promise.all([this.overlayManager.open(this.overlayName), this._dataAvailableCapability.promise]).then(() => { const currentPageNumber = this._currentPageNumber; + const pagesRotation = this._pagesRotation; // If the document properties were previously fetched (for this PDF file), // just update the dialog immediately to avoid redundant lookups. if (this.fieldData && - currentPageNumber === this.fieldData['_currentPageNumber']) { + currentPageNumber === this.fieldData['_currentPageNumber'] && + pagesRotation === this.fieldData['_pagesRotation']) { this._updateUI(); return; } @@ -94,7 +99,8 @@ class PDFDocumentProperties { this._parseDate(info.CreationDate), this._parseDate(info.ModDate), this.pdfDocument.getPage(currentPageNumber).then((pdfPage) => { - return this._parsePageSize(getPageSizeInches(pdfPage)); + return this._parsePageSize(getPageSizeInches(pdfPage), + pagesRotation); }), ]); }).then(([info, metadata, fileName, fileSize, creationDate, modDate, @@ -115,6 +121,7 @@ class PDFDocumentProperties { 'pageSizeInch': pageSizes.inch, 'pageSizeMM': pageSizes.mm, '_currentPageNumber': currentPageNumber, + '_pagesRotation': pagesRotation, }); this._updateUI(); @@ -191,6 +198,7 @@ class PDFDocumentProperties { delete this.fieldData; this._dataAvailableCapability = createPromiseCapability(); this._currentPageNumber = 1; + this._pagesRotation = 0; } /** @@ -240,10 +248,17 @@ class PDFDocumentProperties { /** * @private */ - _parsePageSize(pageSizeInches) { + _parsePageSize(pageSizeInches, pagesRotation) { if (!pageSizeInches) { return Promise.resolve({ inch: undefined, mm: undefined, }); } + // Take the viewer rotation into account as well; compare with Adobe Reader. + if (pagesRotation % 180 !== 0) { + pageSizeInches = { + width: pageSizeInches.height, + height: pageSizeInches.width, + }; + } const { width, height, } = pageSizeInches; return Promise.all([ From 513412c92ed5219846df8fc50511360aa74f8cb0 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 20 Mar 2018 13:42:45 +0100 Subject: [PATCH 4/8] Add a new `getLanguage` method to the various `IL10n` implementations --- web/firefoxcom.js | 4 ++++ web/genericl10n.js | 6 ++++++ web/interfaces.js | 5 +++++ web/ui_utils.js | 4 ++++ 4 files changed, 19 insertions(+) diff --git a/web/firefoxcom.js b/web/firefoxcom.js index 5d7bc5997..9435bc562 100644 --- a/web/firefoxcom.js +++ b/web/firefoxcom.js @@ -145,6 +145,10 @@ class MozL10n { this.mozL10n = mozL10n; } + getLanguage() { + return Promise.resolve(this.mozL10n.getLanguage()); + } + getDirection() { return Promise.resolve(this.mozL10n.getDirection()); } diff --git a/web/genericl10n.js b/web/genericl10n.js index 6c0dcfb67..e2da69a60 100644 --- a/web/genericl10n.js +++ b/web/genericl10n.js @@ -27,6 +27,12 @@ class GenericL10n { }); } + getLanguage() { + return this._ready.then((l10n) => { + return l10n.getLanguage(); + }); + } + getDirection() { return this._ready.then((l10n) => { return l10n.getDirection(); diff --git a/web/interfaces.js b/web/interfaces.js index 455185b9b..2e8b52d1d 100644 --- a/web/interfaces.js +++ b/web/interfaces.js @@ -160,6 +160,11 @@ class IPDFAnnotationLayerFactory { * @interface */ class IL10n { + /** + * @returns {Promise} - Resolves to the current locale. + */ + getLanguage() {} + /** * @returns {Promise} - Resolves to 'rtl' or 'ltr'. */ diff --git a/web/ui_utils.js b/web/ui_utils.js index 471ca8202..3b3c1febe 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -58,6 +58,10 @@ function formatL10nValue(text, args) { * @implements {IL10n} */ let NullL10n = { + getLanguage() { + return Promise.resolve('en-us'); + }, + getDirection() { return Promise.resolve('ltr'); }, From f3b74c5028a9ee24fa5fbe3db2595390af959347 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 20 Mar 2018 13:51:56 +0100 Subject: [PATCH 5/8] Display the pageSize, in the document properties dialog, with locale dependent units This uses a whitelist, based on the locale, to determine where non-metric units should be used. Note that the behaviour implemented here seem consistent with desktop PDF viewers (e.g. Adobe Reader), where the pageSizes are *always* displayed with locale dependent units rather than pageSize dependent ones (since the latter would probably be quite confusing). --- web/pdf_document_properties.js | 55 +++++++++++++++++++--------------- web/viewer.html | 6 +--- web/viewer.js | 3 +- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/web/pdf_document_properties.js b/web/pdf_document_properties.js index 731dd5c9e..f65a10656 100644 --- a/web/pdf_document_properties.js +++ b/web/pdf_document_properties.js @@ -20,6 +20,9 @@ import { createPromiseCapability } from 'pdfjs-lib'; const DEFAULT_FIELD_CONTENT = '-'; +// See https://en.wikibooks.org/wiki/Lentis/Conversion_to_the_Metric_Standard_in_the_United_States +const NON_METRIC_LOCALES = ['en-us', 'en-lr', 'my']; + /** * @typedef {Object} PDFDocumentPropertiesOptions * @property {string} overlayName - Name/identifier for the overlay. @@ -59,6 +62,11 @@ class PDFDocumentProperties { this._pagesRotation = evt.pagesRotation; }); } + + this._isNonMetricLocale = true; // The default viewer locale is 'en-us'. + l10n.getLanguage().then((locale) => { + this._isNonMetricLocale = NON_METRIC_LOCALES.includes(locale); + }); } /** @@ -104,7 +112,7 @@ class PDFDocumentProperties { }), ]); }).then(([info, metadata, fileName, fileSize, creationDate, modDate, - pageSizes]) => { + pageSize]) => { freezeFieldData({ 'fileName': fileName, 'fileSize': fileSize, @@ -118,8 +126,7 @@ class PDFDocumentProperties { 'producer': info.Producer, 'version': info.PDFFormatVersion, 'pageCount': this.pdfDocument.numPages, - 'pageSizeInch': pageSizes.inch, - 'pageSizeMM': pageSizes.mm, + 'pageSize': pageSize, '_currentPageNumber': currentPageNumber, '_pagesRotation': pagesRotation, }); @@ -250,7 +257,7 @@ class PDFDocumentProperties { */ _parsePageSize(pageSizeInches, pagesRotation) { if (!pageSizeInches) { - return Promise.resolve({ inch: undefined, mm: undefined, }); + return Promise.resolve(undefined); } // Take the viewer rotation into account as well; compare with Adobe Reader. if (pagesRotation % 180 !== 0) { @@ -259,28 +266,28 @@ class PDFDocumentProperties { height: pageSizeInches.width, }; } - const { width, height, } = pageSizeInches; + + const sizeInches = { + width: Math.round(pageSizeInches.width * 100) / 100, + height: Math.round(pageSizeInches.height * 100) / 100, + }; + // 1in == 25.4mm; no need to round to 2 decimals for millimeters. + const sizeMillimeters = { + width: Math.round(pageSizeInches.width * 25.4 * 10) / 10, + height: Math.round(pageSizeInches.height * 25.4 * 10) / 10, + }; return Promise.all([ - this.l10n.get('document_properties_page_size_unit_inches', null, 'in'), - this.l10n.get('document_properties_page_size_unit_millimeters', null, - 'mm'), - ]).then(([unitInches, unitMillimeters]) => { - return Promise.all([ - this.l10n.get('document_properties_page_size_dimension_string', { - width: (Math.round(width * 100) / 100).toLocaleString(), - height: (Math.round(height * 100) / 100).toLocaleString(), - unit: unitInches, - }, '{{width}} × {{height}} {{unit}}'), - // 1in == 25.4mm; no need to round to 2 decimals for millimeters. - this.l10n.get('document_properties_page_size_dimension_string', { - width: (Math.round(width * 25.4 * 10) / 10).toLocaleString(), - height: (Math.round(height * 25.4 * 10) / 10).toLocaleString(), - unit: unitMillimeters, - }, '{{width}} × {{height}} {{unit}}'), - ]); - }).then((sizes) => { - return { inch: sizes[0], mm: sizes[1], }; + (this._isNonMetricLocale ? sizeInches : sizeMillimeters), + this.l10n.get('document_properties_page_size_unit_' + + (this._isNonMetricLocale ? 'inches' : 'millimeters'), null, + this._isNonMetricLocale ? 'in' : 'mm'), + ]).then(([{ width, height, }, unit]) => { + return this.l10n.get('document_properties_page_size_dimension_string', { + width: width.toLocaleString(), + height: height.toLocaleString(), + unit, + }, '{{width}} × {{height}} {{unit}}'); }); } diff --git a/web/viewer.html b/web/viewer.html index 7baec33e2..2d460456c 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -352,11 +352,7 @@ See https://github.com/adobe-type-tools/cmap-resources Page Count:

-

- Page Size: -

- -
- - -

+ Page Size:

-

diff --git a/web/viewer.js b/web/viewer.js index 242bf1df6..632a217f7 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -159,8 +159,7 @@ function getViewerConfiguration() { 'producer': document.getElementById('producerField'), 'version': document.getElementById('versionField'), 'pageCount': document.getElementById('pageCountField'), - 'pageSizeInch': document.getElementById('pageSizeFieldInch'), - 'pageSizeMM': document.getElementById('pageSizeFieldMM'), + 'pageSize': document.getElementById('pageSizeField'), }, }, errorWrapper: { From fc0038d609a1bff225f8f4f01525a7d1f781624d Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 20 Mar 2018 13:58:55 +0100 Subject: [PATCH 6/8] Add orientation description to the pageSize information, displayed in the properties dialog Since the l10n strings were added in a previous commit, modifying them here shouldn't be a problem since they haven't landed in mozilla-central yet. --- l10n/en-US/viewer.properties | 8 +++++--- l10n/sv-SE/viewer.properties | 8 +++++--- web/pdf_document_properties.js | 12 +++++++++--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/l10n/en-US/viewer.properties b/l10n/en-US/viewer.properties index a20f72219..324e843ba 100644 --- a/l10n/en-US/viewer.properties +++ b/l10n/en-US/viewer.properties @@ -92,10 +92,12 @@ document_properties_page_count=Page Count: document_properties_page_size=Page Size: document_properties_page_size_unit_inches=in document_properties_page_size_unit_millimeters=mm +document_properties_page_size_orientation_portrait=portrait +document_properties_page_size_orientation_landscape=landscape # LOCALIZATION NOTE (document_properties_page_size_dimension_string): -# "{{width}}", "{{height}}", and {{unit}} will be replaced by the size, -# respectively their unit of measurement, of the (current) page. -document_properties_page_size_dimension_string={{width}} × {{height}} {{unit}} +# "{{width}}", "{{height}}", {{unit}}, and {{orientation}} will be replaced by +# the size, respectively their unit of measurement and orientation, of the (current) page. +document_properties_page_size_dimension_string={{width}} × {{height}} {{unit}} ({{orientation}}) document_properties_close=Close print_progress_message=Preparing document for printing… diff --git a/l10n/sv-SE/viewer.properties b/l10n/sv-SE/viewer.properties index 59f4a99d3..b31720635 100644 --- a/l10n/sv-SE/viewer.properties +++ b/l10n/sv-SE/viewer.properties @@ -92,10 +92,12 @@ document_properties_page_count=Sidantal: document_properties_page_size=Sidstorlek: document_properties_page_size_unit_inches=tum document_properties_page_size_unit_millimeters=mm +document_properties_page_size_orientation_portrait=stående +document_properties_page_size_orientation_landscape=liggande # LOCALIZATION NOTE (document_properties_page_size_dimension_string): -# "{{width}}", "{{height}}", and {{unit}} will be replaced by the size, -# respectively their unit of measurement, of the (current) page. -document_properties_page_size_dimension_string={{width}} × {{height}} {{unit}} +# "{{width}}", "{{height}}", {{unit}}, and {{orientation}} will be replaced by +# the size, respectively their unit of measurement and orientation, of the (current) page. +document_properties_page_size_dimension_string={{width}} × {{height}} {{unit}} ({{orientation}}) document_properties_close=Stäng print_progress_message=Förbereder sidor för utskrift… diff --git a/web/pdf_document_properties.js b/web/pdf_document_properties.js index f65a10656..9513014f3 100644 --- a/web/pdf_document_properties.js +++ b/web/pdf_document_properties.js @@ -14,7 +14,8 @@ */ import { - cloneObj, getPageSizeInches, getPDFFileNameFromURL, NullL10n + cloneObj, getPageSizeInches, getPDFFileNameFromURL, isPortraitOrientation, + NullL10n } from './ui_utils'; import { createPromiseCapability } from 'pdfjs-lib'; @@ -266,6 +267,7 @@ class PDFDocumentProperties { height: pageSizeInches.width, }; } + const isPortrait = isPortraitOrientation(pageSizeInches); const sizeInches = { width: Math.round(pageSizeInches.width * 100) / 100, @@ -282,12 +284,16 @@ class PDFDocumentProperties { this.l10n.get('document_properties_page_size_unit_' + (this._isNonMetricLocale ? 'inches' : 'millimeters'), null, this._isNonMetricLocale ? 'in' : 'mm'), - ]).then(([{ width, height, }, unit]) => { + this.l10n.get('document_properties_page_size_orientation_' + + (isPortrait ? 'portrait' : 'landscape'), null, + isPortrait ? 'portrait' : 'landscape'), + ]).then(([{ width, height, }, unit, orientation]) => { return this.l10n.get('document_properties_page_size_dimension_string', { width: width.toLocaleString(), height: height.toLocaleString(), unit, - }, '{{width}} × {{height}} {{unit}}'); + orientation, + }, '{{width}} × {{height}} {{unit}} ({{orientation}})'); }); } From d86b816c2b9d4146b2aea80dc86461ad55e3555c Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 20 Mar 2018 14:26:49 +0100 Subject: [PATCH 7/8] Display the names, for a couple of standard page sizes, in the document properties dialog Please note that this patch *purposely* doesn't add every standard (or semi-standard) page name in existence, but rather only a few common ones. This is done to lessen the burden on localizers, since it's quite possible that all of the page names could need translation (depending on locale). It's easy to add more standard page sizes in the future, but we should take care to *only* add those that are very commonly used in actual PDF files. --- l10n/en-US/viewer.properties | 8 ++++++++ l10n/sv-SE/viewer.properties | 8 ++++++++ web/pdf_document_properties.js | 36 +++++++++++++++++++++++++++++++--- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/l10n/en-US/viewer.properties b/l10n/en-US/viewer.properties index 324e843ba..3f4723eb2 100644 --- a/l10n/en-US/viewer.properties +++ b/l10n/en-US/viewer.properties @@ -94,10 +94,18 @@ document_properties_page_size_unit_inches=in document_properties_page_size_unit_millimeters=mm document_properties_page_size_orientation_portrait=portrait document_properties_page_size_orientation_landscape=landscape +document_properties_page_size_name_a3=A3 +document_properties_page_size_name_a4=A4 +document_properties_page_size_name_letter=Letter +document_properties_page_size_name_legal=Legal # LOCALIZATION NOTE (document_properties_page_size_dimension_string): # "{{width}}", "{{height}}", {{unit}}, and {{orientation}} will be replaced by # the size, respectively their unit of measurement and orientation, of the (current) page. document_properties_page_size_dimension_string={{width}} × {{height}} {{unit}} ({{orientation}}) +# LOCALIZATION NOTE (document_properties_page_size_dimension_name_string): +# "{{width}}", "{{height}}", {{unit}}, {{name}}, and {{orientation}} will be replaced by +# the size, respectively their unit of measurement, name, and orientation, of the (current) page. +document_properties_page_size_dimension_name_string={{width}} × {{height}} {{unit}} ({{name}}, {{orientation}}) document_properties_close=Close print_progress_message=Preparing document for printing… diff --git a/l10n/sv-SE/viewer.properties b/l10n/sv-SE/viewer.properties index b31720635..29ac19836 100644 --- a/l10n/sv-SE/viewer.properties +++ b/l10n/sv-SE/viewer.properties @@ -94,10 +94,18 @@ document_properties_page_size_unit_inches=tum document_properties_page_size_unit_millimeters=mm document_properties_page_size_orientation_portrait=stående document_properties_page_size_orientation_landscape=liggande +document_properties_page_size_name_a3=A3 +document_properties_page_size_name_a4=A4 +document_properties_page_size_name_letter=Letter +document_properties_page_size_name_legal=Legal # LOCALIZATION NOTE (document_properties_page_size_dimension_string): # "{{width}}", "{{height}}", {{unit}}, and {{orientation}} will be replaced by # the size, respectively their unit of measurement and orientation, of the (current) page. document_properties_page_size_dimension_string={{width}} × {{height}} {{unit}} ({{orientation}}) +# LOCALIZATION NOTE (document_properties_page_size_dimension_name_string): +# "{{width}}", "{{height}}", {{unit}}, {{name}}, and {{orientation}} will be replaced by +# the size, respectively their unit of measurement, name, and orientation, of the (current) page. +document_properties_page_size_dimension_name_string={{width}} × {{height}} {{unit}} ({{name}}, {{orientation}}) document_properties_close=Stäng print_progress_message=Förbereder sidor för utskrift… diff --git a/web/pdf_document_properties.js b/web/pdf_document_properties.js index 9513014f3..b030705a8 100644 --- a/web/pdf_document_properties.js +++ b/web/pdf_document_properties.js @@ -24,6 +24,24 @@ const DEFAULT_FIELD_CONTENT = '-'; // See https://en.wikibooks.org/wiki/Lentis/Conversion_to_the_Metric_Standard_in_the_United_States const NON_METRIC_LOCALES = ['en-us', 'en-lr', 'my']; +// Should use the format: `width x height`, in portrait orientation. +// See https://en.wikipedia.org/wiki/Paper_size +const US_PAGE_NAMES = { + '8.5x11': 'Letter', + '8.5x14': 'Legal', +}; +const METRIC_PAGE_NAMES = { + '297x420': 'A3', + '210x297': 'A4', +}; + +function getPageName(size, isPortrait, pageNames) { + const width = (isPortrait ? size.width : size.height); + const height = (isPortrait ? size.height : size.width); + + return pageNames[`${width}x${height}`]; +} + /** * @typedef {Object} PDFDocumentPropertiesOptions * @property {string} overlayName - Name/identifier for the overlay. @@ -279,21 +297,33 @@ class PDFDocumentProperties { height: Math.round(pageSizeInches.height * 25.4 * 10) / 10, }; + let pageName = null; + const name = getPageName(sizeInches, isPortrait, US_PAGE_NAMES) || + getPageName(sizeMillimeters, isPortrait, METRIC_PAGE_NAMES); + if (name) { + pageName = this.l10n.get('document_properties_page_size_name_' + + name.toLowerCase(), null, name); + } + return Promise.all([ (this._isNonMetricLocale ? sizeInches : sizeMillimeters), this.l10n.get('document_properties_page_size_unit_' + (this._isNonMetricLocale ? 'inches' : 'millimeters'), null, this._isNonMetricLocale ? 'in' : 'mm'), + pageName, this.l10n.get('document_properties_page_size_orientation_' + (isPortrait ? 'portrait' : 'landscape'), null, isPortrait ? 'portrait' : 'landscape'), - ]).then(([{ width, height, }, unit, orientation]) => { - return this.l10n.get('document_properties_page_size_dimension_string', { + ]).then(([{ width, height, }, unit, name, orientation]) => { + return this.l10n.get('document_properties_page_size_dimension_' + + (name ? 'name_' : '') + 'string', { width: width.toLocaleString(), height: height.toLocaleString(), unit, + name, orientation, - }, '{{width}} × {{height}} {{unit}} ({{orientation}})'); + }, '{{width}} × {{height}} {{unit}} (' + + (name ? '{{name}}, ' : '') + '{{orientation}})'); }); } From b004308f884c8698e7793b3df19a80f60f088824 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Wed, 21 Mar 2018 13:39:07 +0100 Subject: [PATCH 8/8] Attempt to improve the detection of (metric) page names, by fuzzy matching the dimensions The following is an example of a PDF file (the specification to be exact) where the page size (compare the size displayed in Adobe Reader), and the page name, isn't correctly displayed without the patch: https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf --- web/pdf_document_properties.js | 39 ++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/web/pdf_document_properties.js b/web/pdf_document_properties.js index b030705a8..ce57e9474 100644 --- a/web/pdf_document_properties.js +++ b/web/pdf_document_properties.js @@ -287,19 +287,50 @@ class PDFDocumentProperties { } const isPortrait = isPortraitOrientation(pageSizeInches); - const sizeInches = { + let sizeInches = { width: Math.round(pageSizeInches.width * 100) / 100, height: Math.round(pageSizeInches.height * 100) / 100, }; // 1in == 25.4mm; no need to round to 2 decimals for millimeters. - const sizeMillimeters = { + let sizeMillimeters = { width: Math.round(pageSizeInches.width * 25.4 * 10) / 10, height: Math.round(pageSizeInches.height * 25.4 * 10) / 10, }; let pageName = null; - const name = getPageName(sizeInches, isPortrait, US_PAGE_NAMES) || - getPageName(sizeMillimeters, isPortrait, METRIC_PAGE_NAMES); + let name = getPageName(sizeInches, isPortrait, US_PAGE_NAMES) || + getPageName(sizeMillimeters, isPortrait, METRIC_PAGE_NAMES); + + if (!name && !(Number.isInteger(sizeMillimeters.width) && + Number.isInteger(sizeMillimeters.height))) { + // Attempt to improve the page name detection by falling back to fuzzy + // matching of the metric dimensions, to account for e.g. rounding errors + // and/or PDF files that define the page sizes in an imprecise manner. + const exactMillimeters = { + width: pageSizeInches.width * 25.4, + height: pageSizeInches.height * 25.4, + }; + const intMillimeters = { + width: Math.round(sizeMillimeters.width), + height: Math.round(sizeMillimeters.height), + }; + + // Try to avoid false positives, by only considering "small" differences. + if (Math.abs(exactMillimeters.width - intMillimeters.width) < 0.1 && + Math.abs(exactMillimeters.height - intMillimeters.height) < 0.1) { + + name = getPageName(intMillimeters, isPortrait, METRIC_PAGE_NAMES); + if (name) { + // Update *both* sizes, computed above, to ensure that the displayed + // dimensions always correspond to the detected page name. + sizeInches = { + width: Math.round(intMillimeters.width / 25.4 * 100) / 100, + height: Math.round(intMillimeters.height / 25.4 * 100) / 100, + }; + sizeMillimeters = intMillimeters; + } + } + } if (name) { pageName = this.l10n.get('document_properties_page_size_name_' + name.toLowerCase(), null, name);