From fc773ab80748c0a7fa57594944d67663e4231f9a Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Mon, 10 Feb 2020 21:13:02 +0000 Subject: [PATCH] Bug 1614330 - Update pdf.js to version 2.4.349. r=bdahl Differential Revision: https://phabricator.services.mozilla.com/D62255 --HG-- extra : moz-landing-system : lando --- browser/extensions/pdfjs/README.mozilla | 4 +- browser/extensions/pdfjs/content/build/pdf.js | 26 +++--- .../pdfjs/content/build/pdf.worker.js | 91 ++++++++++++++----- .../extensions/pdfjs/content/web/debugger.js | 6 +- .../extensions/pdfjs/content/web/viewer.css | 29 +++--- .../extensions/pdfjs/content/web/viewer.js | 72 +++++++++------ browser/extensions/pdfjs/moz.yaml | 2 +- 7 files changed, 146 insertions(+), 84 deletions(-) diff --git a/browser/extensions/pdfjs/README.mozilla b/browser/extensions/pdfjs/README.mozilla index 34500b42aaf4..ba993dbbb4be 100644 --- a/browser/extensions/pdfjs/README.mozilla +++ b/browser/extensions/pdfjs/README.mozilla @@ -1,5 +1,5 @@ This is the PDF.js project output, https://github.com/mozilla/pdf.js -Current extension version is: 2.4.326 +Current extension version is: 2.4.349 -Taken from upstream commit: d6754d1e +Taken from upstream commit: dced0a38 diff --git a/browser/extensions/pdfjs/content/build/pdf.js b/browser/extensions/pdfjs/content/build/pdf.js index 01e3b760811d..2737c6d4a22a 100644 --- a/browser/extensions/pdfjs/content/build/pdf.js +++ b/browser/extensions/pdfjs/content/build/pdf.js @@ -123,8 +123,8 @@ return /******/ (function(modules) { // webpackBootstrap "use strict"; -var pdfjsVersion = '2.4.326'; -var pdfjsBuild = 'd6754d1e'; +var pdfjsVersion = '2.4.349'; +var pdfjsBuild = 'dced0a38'; var pdfjsSharedUtil = __w_pdfjs_require__(1); @@ -1205,7 +1205,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) { return worker.messageHandler.sendWithPromise("GetDocRequest", { docId, - apiVersion: '2.4.326', + apiVersion: '2.4.349', source: { data: source.data, url: source.url, @@ -1428,7 +1428,7 @@ class PDFDocumentProxy { } cleanup() { - this._transport.startCleanup(); + return this._transport.startCleanup(); } destroy() { @@ -1759,8 +1759,7 @@ class PDFPageProxy { cleanup(resetStats = false) { this.pendingCleanup = true; - - this._tryCleanup(resetStats); + return this._tryCleanup(resetStats); } _tryCleanup(resetStats = false) { @@ -1768,7 +1767,7 @@ class PDFPageProxy { const intentState = this.intentStates[intent]; return intentState.renderTasks.length !== 0 || !intentState.operatorList.lastChunk; })) { - return; + return false; } Object.keys(this.intentStates).forEach(intent => { @@ -1782,6 +1781,7 @@ class PDFPageProxy { } this.pendingCleanup = false; + return true; } _startRenderPage(transparency, intent) { @@ -2874,12 +2874,16 @@ class WorkerTransport { } startCleanup() { - this.messageHandler.sendWithPromise("Cleanup", null).then(() => { + return this.messageHandler.sendWithPromise("Cleanup", null).then(() => { for (let i = 0, ii = this.pageCache.length; i < ii; i++) { const page = this.pageCache[i]; if (page) { - page.cleanup(); + const cleanupSuccessful = page.cleanup(); + + if (!cleanupSuccessful) { + throw new Error(`startCleanup: Page ${i + 1} is currently rendering.`); + } } } @@ -3148,9 +3152,9 @@ const InternalRenderTask = function InternalRenderTaskClosure() { return InternalRenderTask; }(); -const version = '2.4.326'; +const version = '2.4.349'; exports.version = version; -const build = 'd6754d1e'; +const build = 'dced0a38'; exports.build = build; /***/ }), diff --git a/browser/extensions/pdfjs/content/build/pdf.worker.js b/browser/extensions/pdfjs/content/build/pdf.worker.js index 7e84f61febb9..5d3cc9dadc34 100644 --- a/browser/extensions/pdfjs/content/build/pdf.worker.js +++ b/browser/extensions/pdfjs/content/build/pdf.worker.js @@ -123,8 +123,8 @@ return /******/ (function(modules) { // webpackBootstrap "use strict"; -const pdfjsVersion = '2.4.326'; -const pdfjsBuild = 'd6754d1e'; +const pdfjsVersion = '2.4.349'; +const pdfjsBuild = 'dced0a38'; const pdfjsCoreWorker = __w_pdfjs_require__(1); @@ -223,7 +223,7 @@ var WorkerMessageHandler = { var WorkerTasks = []; const verbosity = (0, _util.getVerbosityLevel)(); const apiVersion = docParams.apiVersion; - const workerVersion = '2.4.326'; + const workerVersion = '2.4.349'; if (apiVersion !== workerVersion) { throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`); @@ -3097,6 +3097,7 @@ const STARTXREF_SIGNATURE = new Uint8Array([0x73, 0x74, 0x61, 0x72, 0x74, 0x78, const ENDOBJ_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64, 0x6f, 0x62, 0x6a]); const FINGERPRINT_FIRST_BYTES = 1024; const EMPTY_FINGERPRINT = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; +const PDF_HEADER_VERSION_REGEXP = /^[1-9]\.[0-9]$/; function find(stream, signature, limit = 1024, backwards = false) { const signatureLength = signature.length; @@ -3338,8 +3339,15 @@ class PDFDocument { ModDate: _util.isString, Trapped: _primitives.isName }; + let version = this.pdfFormatVersion; + + if (typeof version !== "string" || !PDF_HEADER_VERSION_REGEXP.test(version)) { + (0, _util.warn)(`Invalid PDF header version number: ${version}`); + version = null; + } + const docInfo = { - PDFFormatVersion: this.pdfFormatVersion, + PDFFormatVersion: version, IsLinearized: !!this.linearization, IsAcroFormPresent: !!this.acroForm, IsXFAPresent: !!this.xfa, @@ -12903,6 +12911,7 @@ var JpegImage = function JpegImageClosure() { var data = new Uint8ClampedArray(dataLength); var xScaleBlockOffset = new Uint32Array(width); var mask3LSB = 0xfffffff8; + let lastComponentScaleX; for (i = 0; i < numComponents; i++) { component = this.components[i]; @@ -12912,9 +12921,13 @@ var JpegImage = function JpegImageClosure() { output = component.output; blocksPerScanline = component.blocksPerLine + 1 << 3; - for (x = 0; x < width; x++) { - j = 0 | x * componentScaleX; - xScaleBlockOffset[x] = (j & mask3LSB) << 3 | j & 7; + if (componentScaleX !== lastComponentScaleX) { + for (x = 0; x < width; x++) { + j = 0 | x * componentScaleX; + xScaleBlockOffset[x] = (j & mask3LSB) << 3 | j & 7; + } + + lastComponentScaleX = componentScaleX; } for (y = 0; y < height; y++) { @@ -13012,16 +13025,15 @@ var JpegImage = function JpegImageClosure() { _convertCmykToRgb: function convertCmykToRgb(data) { var c, m, y, k; var offset = 0; - var scale = 1 / 255; for (var i = 0, length = data.length; i < length; i += 4) { - c = data[i] * scale; - m = data[i + 1] * scale; - y = data[i + 2] * scale; - k = data[i + 3] * scale; - data[offset++] = 255 + c * (-4.387332384609988 * c + 54.48615194189176 * m + 18.82290502165302 * y + 212.25662451639585 * k - 285.2331026137004) + m * (1.7149763477362134 * m - 5.6096736904047315 * y - 17.873870861415444 * k - 5.497006427196366) + y * (-2.5217340131683033 * y - 21.248923337353073 * k + 17.5119270841813) - k * (21.86122147463605 * k + 189.48180835922747); - data[offset++] = 255 + c * (8.841041422036149 * c + 60.118027045597366 * m + 6.871425592049007 * y + 31.159100130055922 * k - 79.2970844816548) + m * (-15.310361306967817 * m + 17.575251261109482 * y + 131.35250912493976 * k - 190.9453302588951) + y * (4.444339102852739 * y + 9.8632861493405 * k - 24.86741582555878) - k * (20.737325471181034 * k + 187.80453709719578); - data[offset++] = 255 + c * (0.8842522430003296 * c + 8.078677503112928 * m + 30.89978309703729 * y - 0.23883238689178934 * k - 14.183576799673286) + m * (10.49593273432072 * m + 63.02378494754052 * y + 50.606957656360734 * k - 112.23884253719248) + y * (0.03296041114873217 * y + 115.60384449646641 * k - 193.58209356861505) - k * (22.33816807309886 * k + 180.12613974708367); + c = data[i]; + m = data[i + 1]; + y = data[i + 2]; + k = data[i + 3]; + data[offset++] = 255 + c * (-0.00006747147073602441 * c + 0.0008379262121013727 * m + 0.0002894718188643294 * y + 0.003264231057537806 * k - 1.1185611867203937) + m * (0.000026374107616089405 * m - 0.00008626949158638572 * y - 0.0002748769067499491 * k - 0.02155688794978967) + y * (-0.00003878099212869363 * y - 0.0003267808279485286 * k + 0.0686742238595345) - k * (0.0003361971776183937 * k + 0.7430659151342254); + data[offset++] = 255 + c * (0.00013596372813588848 * c + 0.000924537132573585 * m + 0.00010567359618683593 * y + 0.0004791864687436512 * k - 0.3109689587515875) + m * (-0.00023545346108370344 * m + 0.0002702845253534714 * y + 0.0020200308977307156 * k - 0.7488052167015494) + y * (0.00006834815998235662 * y + 0.00015168452363460973 * k - 0.09751927774728933) - k * (0.00031891311758832814 * k + 0.7364883807733168); + data[offset++] = 255 + c * (0.000013598650411385307 * c + 0.00012423956175490851 * m + 0.0004751985097583589 * y - 0.0000036729317476630422 * k - 0.05562186980264034) + m * (0.00016141380598724676 * m + 0.0009692239130725186 * y + 0.0007782692450036253 * k - 0.44015232367526463) + y * (5.068882914068769e-7 * y + 0.0017778369011375071 * k - 0.7591454649749609) - k * (0.0003435319965105553 * k + 0.7063770186160144); } return data.subarray(0, offset); @@ -22119,6 +22131,20 @@ var PartialEvaluator = function PartialEvaluatorClosure() { map[charCode] = String.fromCodePoint.apply(String, str); }); return new _fonts.ToUnicodeMap(map); + }, reason => { + if (reason instanceof _util.AbortException) { + return null; + } + + if (this.options.ignoreErrors) { + this.handler.send("UnsupportedFeature", { + featureId: _util.UNSUPPORTED_FEATURES.font + }); + (0, _util.warn)(`readToUnicode - ignoring ToUnicode data: "${reason}".`); + return null; + } + + throw reason; }); } @@ -22409,6 +22435,8 @@ var PartialEvaluator = function PartialEvaluatorClosure() { var type = preEvaluatedFont.type; var maxCharIndex = composite ? 0xffff : 0xff; var properties; + const firstChar = dict.get("FirstChar") || 0; + const lastChar = dict.get("LastChar") || maxCharIndex; if (!descriptor) { if (type === "Type3") { @@ -22432,18 +22460,29 @@ var PartialEvaluator = function PartialEvaluatorClosure() { widths: metrics.widths, defaultWidth: metrics.defaultWidth, flags, - firstChar: 0, - lastChar: maxCharIndex + firstChar, + lastChar }; + const widths = dict.get("Widths"); return this.extractDataStructures(dict, dict, properties).then(properties => { - properties.widths = this.buildCharCodeToWidth(metrics.widths, properties); + if (widths) { + const glyphWidths = []; + let j = firstChar; + + for (let i = 0, ii = widths.length; i < ii; i++) { + glyphWidths[j++] = this.xref.fetchIfRef(widths[i]); + } + + properties.widths = glyphWidths; + } else { + properties.widths = this.buildCharCodeToWidth(metrics.widths, properties); + } + return new _fonts.Font(baseFontName, null, properties); }); } } - var firstChar = dict.get("FirstChar") || 0; - var lastChar = dict.get("LastChar") || maxCharIndex; var fontName = descriptor.get("FontName"); var baseFont = dict.get("BaseFont"); @@ -24180,7 +24219,7 @@ var CMapFactory = function CMapFactoryClosure() { } return { - create(params) { + async create(params) { var encoding = params.encoding; var fetchBuiltInCMap = params.fetchBuiltInCMap; var useCMap = params.useCMap; @@ -24199,7 +24238,7 @@ var CMapFactory = function CMapFactoryClosure() { }); } - return Promise.reject(new Error("Encoding required.")); + throw new Error("Encoding required."); } }; @@ -25223,7 +25262,7 @@ var Font = function FontClosure() { var name = this.name; var type = this.type; var subtype = this.subtype; - var fontName = name.replace(/[,_]/g, "-"); + let fontName = name.replace(/[,_]/g, "-").replace(/\s/g, ""); var stdFontMap = (0, _standard_fonts.getStdFontMap)(), nonStdFontMap = (0, _standard_fonts.getNonStdFontMap)(); var isStandardFont = !!stdFontMap[fontName] || !!(nonStdFontMap[fontName] && stdFontMap[nonStdFontMap[fontName]]); @@ -26861,6 +26900,12 @@ var Font = function FontClosure() { fontCharCode = this.toFontChar[charcode] || charcode; if (this.missingFile) { + const glyphName = this.differences[charcode] || this.defaultEncoding[charcode]; + + if ((glyphName === ".notdef" || glyphName === "") && this.type === "Type1") { + fontCharCode = 0x20; + } + fontCharCode = (0, _unicode.mapSpecialUnicodeValues)(fontCharCode); } diff --git a/browser/extensions/pdfjs/content/web/debugger.js b/browser/extensions/pdfjs/content/web/debugger.js index 3208f7bd4bef..12ebce779b27 100644 --- a/browser/extensions/pdfjs/content/web/debugger.js +++ b/browser/extensions/pdfjs/content/web/debugger.js @@ -67,7 +67,6 @@ var FontInspector = (function FontInspectorClosure() { manager: null, init: function init(pdfjsLib) { var panel = this.panel; - panel.setAttribute("style", "padding: 5px;"); var tmp = document.createElement("button"); tmp.addEventListener("click", resetSelection); tmp.textContent = "Refresh"; @@ -178,7 +177,6 @@ var StepperManager = (function StepperManagerClosure() { manager: null, init: function init(pdfjsLib) { var self = this; - this.panel.setAttribute("style", "padding: 5px;"); stepperControls = document.createElement("div"); stepperChooser = document.createElement("select"); stepperChooser.addEventListener("change", function(event) { @@ -468,9 +466,7 @@ var Stats = (function Stats() { name: "Stats", panel: null, manager: null, - init(pdfjsLib) { - this.panel.setAttribute("style", "padding: 5px;"); - }, + init(pdfjsLib) {}, enabled: false, active: false, // Stats specific functions. diff --git a/browser/extensions/pdfjs/content/web/viewer.css b/browser/extensions/pdfjs/content/web/viewer.css index 130a15a0cb4f..069419eaa6c8 100644 --- a/browser/extensions/pdfjs/content/web/viewer.css +++ b/browser/extensions/pdfjs/content/web/viewer.css @@ -381,6 +381,8 @@ :root { --sidebar-width: 200px; + --sidebar-transition-duration: 200ms; + --sidebar-transition-timing-function: ease; } * { @@ -451,24 +453,20 @@ select { position: absolute; top: 32px; bottom: 0; - width: 200px; /* Here, and elsewhere below, keep the constant value for compatibility - with older browsers that lack support for CSS variables. */ width: var(--sidebar-width); visibility: hidden; z-index: 100; border-top: 1px solid rgba(51, 51, 51, 1); - transition-duration: 200ms; - transition-timing-function: ease; + transition-duration: var(--sidebar-transition-duration); + transition-timing-function: var(--sidebar-transition-timing-function); } html[dir='ltr'] #sidebarContainer { transition-property: left; - left: -200px; - left: calc(-1 * var(--sidebar-width)); + left: calc(0px - var(--sidebar-width)); } html[dir='rtl'] #sidebarContainer { transition-property: right; - right: -200px; - right: calc(-1 * var(--sidebar-width)); + right: calc(0px - var(--sidebar-width)); } .loadingInProgress #sidebarContainer { @@ -529,8 +527,8 @@ html[dir='rtl'] #sidebarContent { outline: none; } #viewerContainer:not(.pdfPresentationMode) { - transition-duration: 200ms; - transition-timing-function: ease; + transition-duration: var(--sidebar-transition-duration); + transition-timing-function: var(--sidebar-transition-timing-function); } html[dir='ltr'] #viewerContainer { box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.05); @@ -546,12 +544,10 @@ html[dir='rtl'] #viewerContainer { html[dir='ltr'] #outerContainer.sidebarOpen #viewerContainer:not(.pdfPresentationMode) { transition-property: left; - left: 200px; left: var(--sidebar-width); } html[dir='rtl'] #outerContainer.sidebarOpen #viewerContainer:not(.pdfPresentationMode) { transition-property: right; - right: 200px; right: var(--sidebar-width); } @@ -1049,8 +1045,7 @@ html[dir='rtl'] .dropdownToolbarButton { } .dropdownToolbarButton { - width: 120px; - max-width: 120px; + width: 140px; padding: 0; overflow: hidden; background: url(images/toolbarButton-menuArrows.png) no-repeat; @@ -1063,7 +1058,8 @@ html[dir='rtl'] .dropdownToolbarButton { } .dropdownToolbarButton > select { - min-width: 140px; + width: 162px; + height: 23px; font-size: 12px; color: rgba(242, 242, 242, 1); margin: 0; @@ -1822,6 +1818,9 @@ html[dir='rtl'] #documentPropertiesOverlay .row > * { right: 0; top: 27px; } +#PDFBug .panels > div { + padding: 5px; +} #PDFBug button.active { font-weight: bold; } diff --git a/browser/extensions/pdfjs/content/web/viewer.js b/browser/extensions/pdfjs/content/web/viewer.js index c19226ed5bbf..592d4d62dddf 100644 --- a/browser/extensions/pdfjs/content/web/viewer.js +++ b/browser/extensions/pdfjs/content/web/viewer.js @@ -3128,7 +3128,7 @@ class ProgressBar { const scrollbarWidth = container.offsetWidth - viewer.offsetWidth; if (scrollbarWidth > 0) { - this.bar.setAttribute("style", "width: calc(100% - " + scrollbarWidth + "px);"); + this.bar.style.width = `calc(100% - ${scrollbarWidth}px)`; } } @@ -6959,18 +6959,12 @@ class PDFOutlineViewer { bold, italic }) { - let styleStr = ""; - if (bold) { - styleStr += "font-weight: bold;"; + element.style.fontWeight = "bold"; } if (italic) { - styleStr += "font-style: italic;"; - } - - if (styleStr) { - element.setAttribute("style", styleStr); + element.style.fontStyle = "italic"; } } @@ -10809,7 +10803,7 @@ class SecondaryToolbar { return; } - this.toolbarButtonContainer.setAttribute("style", "max-height: " + (this.containerHeight - _ui_utils.SCROLLBAR_PADDING) + "px;"); + this.toolbarButtonContainer.style.maxHeight = `${this.containerHeight - _ui_utils.SCROLLBAR_PADDING}px`; this.previousContainerHeight = this.containerHeight; } @@ -10953,8 +10947,8 @@ exports.Toolbar = void 0; var _ui_utils = __webpack_require__(2); const PAGE_NUMBER_LOADING_INDICATOR = "visiblePageIsLoading"; -const SCALE_SELECT_CONTAINER_PADDING = 8; -const SCALE_SELECT_PADDING = 22; +const SCALE_SELECT_CONTAINER_WIDTH = 140; +const SCALE_SELECT_WIDTH = 162; class Toolbar { constructor(options, eventBus, l10n = _ui_utils.NullL10n) { @@ -11161,22 +11155,46 @@ class Toolbar { pageNumberInput.classList.toggle(PAGE_NUMBER_LOADING_INDICATOR, loading); } - _adjustScaleWidth() { - const container = this.items.scaleSelectContainer; - const select = this.items.scaleSelect; - - _ui_utils.animationStarted.then(function () { - if (container.clientWidth === 0) { - container.setAttribute("style", "display: inherit;"); - } - - if (container.clientWidth > 0) { - select.setAttribute("style", "min-width: inherit;"); - const width = select.clientWidth + SCALE_SELECT_CONTAINER_PADDING; - select.setAttribute("style", `min-width: ${width + SCALE_SELECT_PADDING}px;`); - container.setAttribute("style", `min-width: ${width}px; max-width: ${width}px;`); - } + async _adjustScaleWidth() { + const { + items, + l10n + } = this; + const predefinedValuesPromise = Promise.all([l10n.get("page_scale_auto", null, "Automatic Zoom"), l10n.get("page_scale_actual", null, "Actual Size"), l10n.get("page_scale_fit", null, "Page Fit"), l10n.get("page_scale_width", null, "Page Width")]); + let canvas = document.createElement("canvas"); + canvas.mozOpaque = true; + let ctx = canvas.getContext("2d", { + alpha: false }); + await _ui_utils.animationStarted; + const { + fontSize, + fontFamily + } = getComputedStyle(items.scaleSelect); + ctx.font = `${fontSize} ${fontFamily}`; + let maxWidth = 0; + + for (const predefinedValue of await predefinedValuesPromise) { + const { + width + } = ctx.measureText(predefinedValue); + + if (width > maxWidth) { + maxWidth = width; + } + } + + const overflow = SCALE_SELECT_WIDTH - SCALE_SELECT_CONTAINER_WIDTH; + maxWidth += 1.5 * overflow; + + if (maxWidth > SCALE_SELECT_CONTAINER_WIDTH) { + items.scaleSelect.style.width = `${maxWidth + overflow}px`; + items.scaleSelectContainer.style.width = `${maxWidth}px`; + } + + canvas.width = 0; + canvas.height = 0; + canvas = ctx = null; } } diff --git a/browser/extensions/pdfjs/moz.yaml b/browser/extensions/pdfjs/moz.yaml index 70d438fc46ca..91310f21ded1 100644 --- a/browser/extensions/pdfjs/moz.yaml +++ b/browser/extensions/pdfjs/moz.yaml @@ -20,7 +20,7 @@ origin: # Human-readable identifier for this version/release # Generally "version NNN", "tag SSS", "bookmark SSS" - release: version 2.4.326 + release: version 2.4.349 # The package's license, where possible using the mnemonic from # https://spdx.org/licenses/