This is an automated email from the git hooks/post-receive script.
richard pushed a commit to branch geckoview-102.3.0esr-12.0-1 in repository tor-browser.
commit 4fbde0237d239b970f408fd5e707ef8f2e4bee3d Author: Calixte cdenizet@mozilla.com AuthorDate: Mon Sep 5 10:56:18 2022 +0000
Bug 1780839 - Update pdf.js to bf000687313b08924186f9f35a604f8cce27bd1d in ESR102. r=marco, a=RyanVM
- bug 1778692: cherry-pick 8f26ba54875ac0730fe72328301085fbb456898a - bug 1777693: cherry-pick 6c9e538f5621a554c867123c57b34a9493ec646a - fix test toolkit/components/pdfjs/test/browser_pdfjs_js.js
Differential Revision: https://phabricator.services.mozilla.com/D156417 --- .../pdfjs/content/PdfJsDefaultPreferences.jsm | 2 + toolkit/components/pdfjs/content/build/pdf.js | 16103 +++++++++++-------- .../pdfjs/content/build/pdf.scripting.js | 58 +- .../components/pdfjs/content/build/pdf.worker.js | 11227 +++++++------ toolkit/components/pdfjs/content/web/debugger.js | 99 +- .../web/images/toolbarButton-editorFreeText.svg | 24 + .../content/web/images/toolbarButton-editorInk.svg | 9 + .../web/images/toolbarButton-editorNone.svg | 4 + toolkit/components/pdfjs/content/web/viewer.css | 358 +- toolkit/components/pdfjs/content/web/viewer.html | 48 +- toolkit/components/pdfjs/content/web/viewer.js | 1633 +- toolkit/components/pdfjs/moz.yaml | 4 +- toolkit/components/pdfjs/test/browser_pdfjs_js.js | 2 +- 13 files changed, 17324 insertions(+), 12247 deletions(-)
diff --git a/toolkit/components/pdfjs/content/PdfJsDefaultPreferences.jsm b/toolkit/components/pdfjs/content/PdfJsDefaultPreferences.jsm index 91a36d0b00540..495893cea8186 100644 --- a/toolkit/components/pdfjs/content/PdfJsDefaultPreferences.jsm +++ b/toolkit/components/pdfjs/content/PdfJsDefaultPreferences.jsm @@ -22,6 +22,7 @@ "use strict"; var EXPORTED_SYMBOLS = ["PdfJsDefaultPreferences"]; var PdfJsDefaultPreferences = Object.freeze({ + "annotationEditorMode": -1, "annotationMode": 2, "cursorToolOnLoad": 0, "defaultZoomValue": "", @@ -32,6 +33,7 @@ var PdfJsDefaultPreferences = Object.freeze({ "externalLinkTarget": 0, "historyUpdateUrl": false, "ignoreDestinationZoom": false, + "forcePageColors": false, "pageColorsBackground": "Canvas", "pageColorsForeground": "CanvasText", "pdfBugEnabled": false, diff --git a/toolkit/components/pdfjs/content/build/pdf.js b/toolkit/components/pdfjs/content/build/pdf.js index 84575a1968044..535bf8ffa57ce 100644 --- a/toolkit/components/pdfjs/content/build/pdf.js +++ b/toolkit/components/pdfjs/content/build/pdf.js @@ -29,7 +29,7 @@ exports["pdfjs-dist/build/pdf"] = factory(); else root["pdfjs-dist/build/pdf"] = root.pdfjsLib = factory(); -})(this, () => { +})(globalThis, () => { return /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -42,7 +42,7 @@ return /******/ (() => { // webpackBootstrap Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.UNSUPPORTED_FEATURES = exports.TextRenderingMode = exports.StreamType = exports.RenderingIntentFlag = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FontType = [...] +exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.UNSUPPORTED_FEATURES = exports.TextRenderingMode = exports.StreamType = exports.RenderingIntentFlag = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.LINE_FACTOR = exports.LINE_DESCENT_FACTOR = exports.InvalidPDFException = exports.ImageKind = exports.IDENTIT [...] exports.arrayByteLength = arrayByteLength; exports.arraysToBytes = arraysToBytes; exports.assert = assert; @@ -75,6 +75,10 @@ const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; exports.IDENTITY_MATRIX = IDENTITY_MATRIX; const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0]; exports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX; +const LINE_FACTOR = 1.35; +exports.LINE_FACTOR = LINE_FACTOR; +const LINE_DESCENT_FACTOR = 0.35; +exports.LINE_DESCENT_FACTOR = LINE_DESCENT_FACTOR; const RenderingIntentFlag = { ANY: 0x01, DISPLAY: 0x02, @@ -92,6 +96,22 @@ const AnnotationMode = { ENABLE_STORAGE: 3 }; exports.AnnotationMode = AnnotationMode; +const AnnotationEditorPrefix = "pdfjs_internal_editor_"; +exports.AnnotationEditorPrefix = AnnotationEditorPrefix; +const AnnotationEditorType = { + DISABLE: -1, + NONE: 0, + FREETEXT: 3, + INK: 15 +}; +exports.AnnotationEditorType = AnnotationEditorType; +const AnnotationEditorParamsType = { + FREETEXT_SIZE: 0, + FREETEXT_COLOR: 1, + INK_COLOR: 2, + INK_THICKNESS: 3 +}; +exports.AnnotationEditorParamsType = AnnotationEditorParamsType; const PermissionFlag = { PRINT: 0x04, MODIFY_CONTENTS: 0x08, @@ -1087,3164 +1107,2965 @@ exports.isNodeJS = isNodeJS; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.build = exports.RenderTask = exports.PDFWorkerUtil = exports.PDFWorker = exports.PDFPageProxy = exports.PDFDocumentProxy = exports.PDFDocumentLoadingTask = exports.PDFDataRangeTransport = exports.LoopbackPort = exports.DefaultStandardFontDataFactory = exports.DefaultCanvasFactory = exports.DefaultCMapReaderFactory = void 0; -exports.getDocument = getDocument; -exports.setPDFNetworkStreamFactory = setPDFNetworkStreamFactory; -exports.version = void 0; +exports.StatTimer = exports.RenderingCancelledException = exports.PixelsPerInch = exports.PageViewport = exports.PDFDateString = exports.DOMStandardFontDataFactory = exports.DOMSVGFactory = exports.DOMCanvasFactory = exports.DOMCMapReaderFactory = void 0; +exports.binarySearchFirstItem = binarySearchFirstItem; +exports.deprecated = deprecated; +exports.getColorValues = getColorValues; +exports.getFilenameFromUrl = getFilenameFromUrl; +exports.getPdfFilenameFromUrl = getPdfFilenameFromUrl; +exports.getRGB = getRGB; +exports.getXfaPageViewport = getXfaPageViewport; +exports.isDataScheme = isDataScheme; +exports.isPdfFile = isPdfFile; +exports.isValidFetchUrl = isValidFetchUrl; +exports.loadScript = loadScript; + +var _base_factory = __w_pdfjs_require__(5);
var _util = __w_pdfjs_require__(1);
-var _display_utils = __w_pdfjs_require__(5); +const SVG_NS = "http://www.w3.org/2000/svg";
-var _font_loader = __w_pdfjs_require__(7); +class PixelsPerInch { + static CSS = 96.0; + static PDF = 72.0; + static PDF_TO_CSS_UNITS = this.CSS / this.PDF; +}
-var _annotation_storage = __w_pdfjs_require__(8); +exports.PixelsPerInch = PixelsPerInch;
-var _canvas = __w_pdfjs_require__(10); +class DOMCanvasFactory extends _base_factory.BaseCanvasFactory { + constructor({ + ownerDocument = globalThis.document + } = {}) { + super(); + this._document = ownerDocument; + }
-var _worker_options = __w_pdfjs_require__(13); + _createCanvas(width, height) { + const canvas = this._document.createElement("canvas");
-var _is_node = __w_pdfjs_require__(3); + canvas.width = width; + canvas.height = height; + return canvas; + }
-var _message_handler = __w_pdfjs_require__(14); +}
-var _metadata = __w_pdfjs_require__(15); +exports.DOMCanvasFactory = DOMCanvasFactory;
-var _optional_content_config = __w_pdfjs_require__(16); +async function fetchData(url, asTypedArray = false) { + const response = await fetch(url);
-var _transport_stream = __w_pdfjs_require__(17); + if (!response.ok) { + throw new Error(response.statusText); + }
-var _xfa_text = __w_pdfjs_require__(18); + return asTypedArray ? new Uint8Array(await response.arrayBuffer()) : (0, _util.stringToBytes)(await response.text()); +}
-const DEFAULT_RANGE_CHUNK_SIZE = 65536; -const RENDERING_CANCELLED_TIMEOUT = 100; -let DefaultCanvasFactory = _display_utils.DOMCanvasFactory; -exports.DefaultCanvasFactory = DefaultCanvasFactory; -let DefaultCMapReaderFactory = _display_utils.DOMCMapReaderFactory; -exports.DefaultCMapReaderFactory = DefaultCMapReaderFactory; -let DefaultStandardFontDataFactory = _display_utils.DOMStandardFontDataFactory; -exports.DefaultStandardFontDataFactory = DefaultStandardFontDataFactory; -; -let createPDFNetworkStream; +class DOMCMapReaderFactory extends _base_factory.BaseCMapReaderFactory { + _fetchData(url, compressionType) { + return fetchData(url, this.isCompressed).then(data => { + return { + cMapData: data, + compressionType + }; + }); + }
-function setPDFNetworkStreamFactory(pdfNetworkStreamFactory) { - createPDFNetworkStream = pdfNetworkStreamFactory; }
-function getDocument(src) { - const task = new PDFDocumentLoadingTask(); - let source; +exports.DOMCMapReaderFactory = DOMCMapReaderFactory;
- if (typeof src === "string" || src instanceof URL) { - source = { - url: src - }; - } else if ((0, _util.isArrayBuffer)(src)) { - source = { - data: src - }; - } else if (src instanceof PDFDataRangeTransport) { - source = { - range: src - }; - } else { - if (typeof src !== "object") { - throw new Error("Invalid parameter in getDocument, " + "need either string, URL, Uint8Array, or parameter object."); - } +class DOMStandardFontDataFactory extends _base_factory.BaseStandardFontDataFactory { + _fetchData(url) { + return fetchData(url, true); + }
- if (!src.url && !src.data && !src.range) { - throw new Error("Invalid parameter object: need either .data, .range or .url"); - } +}
- source = src; +exports.DOMStandardFontDataFactory = DOMStandardFontDataFactory; + +class DOMSVGFactory extends _base_factory.BaseSVGFactory { + _createSVG(type) { + return document.createElementNS(SVG_NS, type); }
- const params = Object.create(null); - let rangeTransport = null, - worker = null; +}
- for (const key in source) { - const value = source[key]; +exports.DOMSVGFactory = DOMSVGFactory;
- switch (key) { - case "url": - if (typeof window !== "undefined") { - try { - params[key] = new URL(value, window.location).href; - continue; - } catch (ex) { - (0, _util.warn)(`Cannot create valid URL: "${ex}".`); - } - } else if (typeof value === "string" || value instanceof URL) { - params[key] = value.toString(); - continue; - } +class PageViewport { + constructor({ + viewBox, + scale, + rotation, + offsetX = 0, + offsetY = 0, + dontFlip = false + }) { + this.viewBox = viewBox; + this.scale = scale; + this.rotation = rotation; + this.offsetX = offsetX; + this.offsetY = offsetY; + const centerX = (viewBox[2] + viewBox[0]) / 2; + const centerY = (viewBox[3] + viewBox[1]) / 2; + let rotateA, rotateB, rotateC, rotateD; + rotation %= 360;
- throw new Error("Invalid PDF url data: " + "either string or URL-object is expected in the url property."); + if (rotation < 0) { + rotation += 360; + }
- case "range": - rangeTransport = value; - continue; + switch (rotation) { + case 180: + rotateA = -1; + rotateB = 0; + rotateC = 0; + rotateD = 1; + break;
- case "worker": - worker = value; - continue; + case 90: + rotateA = 0; + rotateB = 1; + rotateC = 1; + rotateD = 0; + break;
- case "data": - if (value instanceof Uint8Array) { - break; - } else if (typeof value === "string") { - params[key] = (0, _util.stringToBytes)(value); - } else if (typeof value === "object" && value !== null && !isNaN(value.length)) { - params[key] = new Uint8Array(value); - } else if ((0, _util.isArrayBuffer)(value)) { - params[key] = new Uint8Array(value); - } else { - throw new Error("Invalid PDF binary data: either typed array, " + "string, or array-like object is expected in the data property."); - } + case 270: + rotateA = 0; + rotateB = -1; + rotateC = -1; + rotateD = 0; + break;
- continue; + case 0: + rotateA = 1; + rotateB = 0; + rotateC = 0; + rotateD = -1; + break; + + default: + throw new Error("PageViewport: Invalid rotation, must be a multiple of 90 degrees."); }
- params[key] = value; - } + if (dontFlip) { + rotateC = -rotateC; + rotateD = -rotateD; + }
- params.CMapReaderFactory = params.CMapReaderFactory || DefaultCMapReaderFactory; - params.StandardFontDataFactory = params.StandardFontDataFactory || DefaultStandardFontDataFactory; - params.ignoreErrors = params.stopAtErrors !== true; - params.fontExtraProperties = params.fontExtraProperties === true; - params.pdfBug = params.pdfBug === true; - params.enableXfa = params.enableXfa === true; + let offsetCanvasX, offsetCanvasY; + let width, height;
- if (!Number.isInteger(params.rangeChunkSize) || params.rangeChunkSize < 1) { - params.rangeChunkSize = DEFAULT_RANGE_CHUNK_SIZE; - } + if (rotateA === 0) { + offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX; + offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY; + width = Math.abs(viewBox[3] - viewBox[1]) * scale; + height = Math.abs(viewBox[2] - viewBox[0]) * scale; + } else { + offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX; + offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY; + width = Math.abs(viewBox[2] - viewBox[0]) * scale; + height = Math.abs(viewBox[3] - viewBox[1]) * scale; + }
- if (typeof params.docBaseUrl !== "string" || (0, _display_utils.isDataScheme)(params.docBaseUrl)) { - params.docBaseUrl = null; + this.transform = [rotateA * scale, rotateB * scale, rotateC * scale, rotateD * scale, offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY]; + this.width = width; + this.height = height; }
- if (!Number.isInteger(params.maxImageSize) || params.maxImageSize < -1) { - params.maxImageSize = -1; + clone({ + scale = this.scale, + rotation = this.rotation, + offsetX = this.offsetX, + offsetY = this.offsetY, + dontFlip = false + } = {}) { + return new PageViewport({ + viewBox: this.viewBox.slice(), + scale, + rotation, + offsetX, + offsetY, + dontFlip + }); }
- if (typeof params.cMapUrl !== "string") { - params.cMapUrl = null; + convertToViewportPoint(x, y) { + return _util.Util.applyTransform([x, y], this.transform); }
- if (typeof params.standardFontDataUrl !== "string") { - params.standardFontDataUrl = null; - } + convertToViewportRectangle(rect) { + const topLeft = _util.Util.applyTransform([rect[0], rect[1]], this.transform);
- if (typeof params.useWorkerFetch !== "boolean") { - params.useWorkerFetch = params.CMapReaderFactory === _display_utils.DOMCMapReaderFactory && params.StandardFontDataFactory === _display_utils.DOMStandardFontDataFactory; + const bottomRight = _util.Util.applyTransform([rect[2], rect[3]], this.transform); + + return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]]; }
- if (typeof params.isEvalSupported !== "boolean") { - params.isEvalSupported = true; - } - - if (typeof params.disableFontFace !== "boolean") { - params.disableFontFace = _is_node.isNodeJS; + convertToPdfPoint(x, y) { + return _util.Util.applyInverseTransform([x, y], this.transform); }
- if (typeof params.useSystemFonts !== "boolean") { - params.useSystemFonts = !_is_node.isNodeJS && !params.disableFontFace; - } +}
- if (typeof params.ownerDocument !== "object" || params.ownerDocument === null) { - params.ownerDocument = globalThis.document; - } +exports.PageViewport = PageViewport;
- if (typeof params.disableRange !== "boolean") { - params.disableRange = false; +class RenderingCancelledException extends _util.BaseException { + constructor(msg, type) { + super(msg, "RenderingCancelledException"); + this.type = type; }
- if (typeof params.disableStream !== "boolean") { - params.disableStream = false; - } +}
- if (typeof params.disableAutoFetch !== "boolean") { - params.disableAutoFetch = false; - } +exports.RenderingCancelledException = RenderingCancelledException;
- (0, _util.setVerbosityLevel)(params.verbosity); +function isDataScheme(url) { + const ii = url.length; + let i = 0;
- if (!worker) { - const workerParams = { - verbosity: params.verbosity, - port: _worker_options.GlobalWorkerOptions.workerPort - }; - worker = workerParams.port ? PDFWorker.fromPort(workerParams) : new PDFWorker(workerParams); - task._worker = worker; + while (i < ii && url[i].trim() === "") { + i++; }
- const docId = task.docId; - worker.promise.then(function () { - if (task.destroyed) { - throw new Error("Loading aborted"); - } - - const workerIdPromise = _fetchDocument(worker, params, rangeTransport, docId); - - const networkStreamPromise = new Promise(function (resolve) { - let networkStream; - - if (rangeTransport) { - networkStream = new _transport_stream.PDFDataTransportStream({ - length: params.length, - initialData: params.initialData, - progressiveDone: params.progressiveDone, - contentDispositionFilename: params.contentDispositionFilename, - disableRange: params.disableRange, - disableStream: params.disableStream - }, rangeTransport); - } else if (!params.data) { - networkStream = createPDFNetworkStream({ - url: params.url, - length: params.length, - httpHeaders: params.httpHeaders, - withCredentials: params.withCredentials, - rangeChunkSize: params.rangeChunkSize, - disableRange: params.disableRange, - disableStream: params.disableStream - }); - } + return url.substring(i, i + 5).toLowerCase() === "data:"; +}
- resolve(networkStream); - }); - return Promise.all([workerIdPromise, networkStreamPromise]).then(function ([workerId, networkStream]) { - if (task.destroyed) { - throw new Error("Loading aborted"); - } +function isPdfFile(filename) { + return typeof filename === "string" && /.pdf$/i.test(filename); +}
- const messageHandler = new _message_handler.MessageHandler(docId, workerId, worker.port); - const transport = new WorkerTransport(messageHandler, task, networkStream, params); - task._transport = transport; - messageHandler.send("Ready", null); - }); - }).catch(task._capability.reject); - return task; +function getFilenameFromUrl(url) { + const anchor = url.indexOf("#"); + const query = url.indexOf("?"); + const end = Math.min(anchor > 0 ? anchor : url.length, query > 0 ? query : url.length); + return url.substring(url.lastIndexOf("/", end) + 1, end); }
-async function _fetchDocument(worker, source, pdfDataRangeTransport, docId) { - if (worker.destroyed) { - throw new Error("Worker was destroyed"); +function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") { + if (typeof url !== "string") { + return defaultFilename; }
- if (pdfDataRangeTransport) { - source.length = pdfDataRangeTransport.length; - source.initialData = pdfDataRangeTransport.initialData; - source.progressiveDone = pdfDataRangeTransport.progressiveDone; - source.contentDispositionFilename = pdfDataRangeTransport.contentDispositionFilename; + if (isDataScheme(url)) { + (0, _util.warn)('getPdfFilenameFromUrl: ignore "data:"-URL for performance reasons.'); + return defaultFilename; }
- const workerId = await worker.messageHandler.sendWithPromise("GetDocRequest", { - docId, - apiVersion: '2.14.290', - source: { - data: source.data, - url: source.url, - password: source.password, - disableAutoFetch: source.disableAutoFetch, - rangeChunkSize: source.rangeChunkSize, - length: source.length - }, - maxImageSize: source.maxImageSize, - disableFontFace: source.disableFontFace, - docBaseUrl: source.docBaseUrl, - ignoreErrors: source.ignoreErrors, - isEvalSupported: source.isEvalSupported, - fontExtraProperties: source.fontExtraProperties, - enableXfa: source.enableXfa, - useSystemFonts: source.useSystemFonts, - cMapUrl: source.useWorkerFetch ? source.cMapUrl : null, - standardFontDataUrl: source.useWorkerFetch ? source.standardFontDataUrl : null - }); + const reURI = /^(?:(?:[^:]+:)?//[^/]+)?([^?#]*)(?[^#]*)?(#.*)?$/; + const reFilename = /[^/?#=]+.pdf\b(?!.*.pdf\b)/i; + const splitURI = reURI.exec(url); + let suggestedFilename = reFilename.exec(splitURI[1]) || reFilename.exec(splitURI[2]) || reFilename.exec(splitURI[3]);
- if (worker.destroyed) { - throw new Error("Worker was destroyed"); + if (suggestedFilename) { + suggestedFilename = suggestedFilename[0]; + + if (suggestedFilename.includes("%")) { + try { + suggestedFilename = reFilename.exec(decodeURIComponent(suggestedFilename))[0]; + } catch (ex) {} + } }
- return workerId; + return suggestedFilename || defaultFilename; }
-class PDFDocumentLoadingTask { - static #docId = 0; - +class StatTimer { constructor() { - this._capability = (0, _util.createPromiseCapability)(); - this._transport = null; - this._worker = null; - this.docId = `d${PDFDocumentLoadingTask.#docId++}`; - this.destroyed = false; - this.onPassword = null; - this.onProgress = null; - this.onUnsupportedFeature = null; - } - - get promise() { - return this._capability.promise; + this.started = Object.create(null); + this.times = []; }
- async destroy() { - this.destroyed = true; - await this._transport?.destroy(); - this._transport = null; + time(name) { + if (name in this.started) { + (0, _util.warn)(`Timer is already running for ${name}`); + }
- if (this._worker) { - this._worker.destroy(); + this.started[name] = Date.now(); + }
- this._worker = null; + timeEnd(name) { + if (!(name in this.started)) { + (0, _util.warn)(`Timer has not been started for ${name}`); } + + this.times.push({ + name, + start: this.started[name], + end: Date.now() + }); + delete this.started[name]; }
-} + toString() { + const outBuf = []; + let longest = 0;
-exports.PDFDocumentLoadingTask = PDFDocumentLoadingTask; + for (const time of this.times) { + const name = time.name;
-class PDFDataRangeTransport { - constructor(length, initialData, progressiveDone = false, contentDispositionFilename = null) { - this.length = length; - this.initialData = initialData; - this.progressiveDone = progressiveDone; - this.contentDispositionFilename = contentDispositionFilename; - this._rangeListeners = []; - this._progressListeners = []; - this._progressiveReadListeners = []; - this._progressiveDoneListeners = []; - this._readyCapability = (0, _util.createPromiseCapability)(); - } + if (name.length > longest) { + longest = name.length; + } + }
- addRangeListener(listener) { - this._rangeListeners.push(listener); - } + for (const time of this.times) { + const duration = time.end - time.start; + outBuf.push(`${time.name.padEnd(longest)} ${duration}ms\n`); + }
- addProgressListener(listener) { - this._progressListeners.push(listener); + return outBuf.join(""); }
- addProgressiveReadListener(listener) { - this._progressiveReadListeners.push(listener); - } +}
- addProgressiveDoneListener(listener) { - this._progressiveDoneListeners.push(listener); - } +exports.StatTimer = StatTimer;
- onDataRange(begin, chunk) { - for (const listener of this._rangeListeners) { - listener(begin, chunk); - } +function isValidFetchUrl(url, baseUrl) { + try { + const { + protocol + } = baseUrl ? new URL(url, baseUrl) : new URL(url); + return protocol === "http:" || protocol === "https:"; + } catch (ex) { + return false; } +}
- onDataProgress(loaded, total) { - this._readyCapability.promise.then(() => { - for (const listener of this._progressListeners) { - listener(loaded, total); - } - }); - } +function loadScript(src, removeScriptElement = false) { + return new Promise((resolve, reject) => { + const script = document.createElement("script"); + script.src = src;
- onDataProgressiveRead(chunk) { - this._readyCapability.promise.then(() => { - for (const listener of this._progressiveReadListeners) { - listener(chunk); - } - }); - } - - onDataProgressiveDone() { - this._readyCapability.promise.then(() => { - for (const listener of this._progressiveDoneListeners) { - listener(); + script.onload = function (evt) { + if (removeScriptElement) { + script.remove(); } - }); - }
- transportReady() { - this._readyCapability.resolve(); - } + resolve(evt); + };
- requestDataRange(begin, end) { - (0, _util.unreachable)("Abstract method PDFDataRangeTransport.requestDataRange"); - } + script.onerror = function () { + reject(new Error(`Cannot load script at: ${script.src}`)); + };
- abort() {} + (document.head || document.documentElement).append(script); + }); +}
+function deprecated(details) { + console.log("Deprecated API usage: " + details); }
-exports.PDFDataRangeTransport = PDFDataRangeTransport; +let pdfDateStringRegex;
-class PDFDocumentProxy { - constructor(pdfInfo, transport) { - this._pdfInfo = pdfInfo; - this._transport = transport; - } +class PDFDateString { + static toDateObject(input) { + if (!input || typeof input !== "string") { + return null; + }
- get annotationStorage() { - return this._transport.annotationStorage; - } + if (!pdfDateStringRegex) { + pdfDateStringRegex = new RegExp("^D:" + "(\d{4})" + "(\d{2})?" + "(\d{2})?" + "(\d{2})?" + "(\d{2})?" + "(\d{2})?" + "([Z|+|-])?" + "(\d{2})?" + "'?" + "(\d{2})?" + "'?"); + }
- get numPages() { - return this._pdfInfo.numPages; - } + const matches = pdfDateStringRegex.exec(input);
- get fingerprints() { - return this._pdfInfo.fingerprints; - } + if (!matches) { + return null; + }
- get stats() { - return this._transport.stats; - } + const year = parseInt(matches[1], 10); + let month = parseInt(matches[2], 10); + month = month >= 1 && month <= 12 ? month - 1 : 0; + let day = parseInt(matches[3], 10); + day = day >= 1 && day <= 31 ? day : 1; + let hour = parseInt(matches[4], 10); + hour = hour >= 0 && hour <= 23 ? hour : 0; + let minute = parseInt(matches[5], 10); + minute = minute >= 0 && minute <= 59 ? minute : 0; + let second = parseInt(matches[6], 10); + second = second >= 0 && second <= 59 ? second : 0; + const universalTimeRelation = matches[7] || "Z"; + let offsetHour = parseInt(matches[8], 10); + offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0; + let offsetMinute = parseInt(matches[9], 10) || 0; + offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0;
- get isPureXfa() { - return !!this._transport._htmlForXfa; - } + if (universalTimeRelation === "-") { + hour += offsetHour; + minute += offsetMinute; + } else if (universalTimeRelation === "+") { + hour -= offsetHour; + minute -= offsetMinute; + }
- get allXfaHtml() { - return this._transport._htmlForXfa; + return new Date(Date.UTC(year, month, day, hour, minute, second)); }
- getPage(pageNumber) { - return this._transport.getPage(pageNumber); - } +}
- getPageIndex(ref) { - return this._transport.getPageIndex(ref); - } +exports.PDFDateString = PDFDateString;
- getDestinations() { - return this._transport.getDestinations(); - } +function getXfaPageViewport(xfaPage, { + scale = 1, + rotation = 0 +}) { + const { + width, + height + } = xfaPage.attributes.style; + const viewBox = [0, 0, parseInt(width), parseInt(height)]; + return new PageViewport({ + viewBox, + scale, + rotation + }); +}
- getDestination(id) { - return this._transport.getDestination(id); +function getRGB(color) { + if (color.startsWith("#")) { + const colorRGB = parseInt(color.slice(1), 16); + return [(colorRGB & 0xff0000) >> 16, (colorRGB & 0x00ff00) >> 8, colorRGB & 0x0000ff]; }
- getPageLabels() { - return this._transport.getPageLabels(); + if (color.startsWith("rgb(")) { + return color.slice(4, -1).split(",").map(x => parseInt(x)); }
- getPageLayout() { - return this._transport.getPageLayout(); - } + (0, _util.warn)(`Not a valid color format: "${color}"`); + return [0, 0, 0]; +}
- getPageMode() { - return this._transport.getPageMode(); - } +function getColorValues(colors) { + const span = document.createElement("span"); + span.style.visibility = "hidden"; + document.body.append(span);
- getViewerPreferences() { - return this._transport.getViewerPreferences(); + for (const name of colors.keys()) { + span.style.color = name; + const computedColor = window.getComputedStyle(span).color; + colors.set(name, getRGB(computedColor)); }
- getOpenAction() { - return this._transport.getOpenAction(); - } + span.remove(); +}
- getAttachments() { - return this._transport.getAttachments(); - } +function binarySearchFirstItem(items, condition, start = 0) { + let minIndex = start; + let maxIndex = items.length - 1;
- getJavaScript() { - return this._transport.getJavaScript(); + if (maxIndex < 0 || !condition(items[maxIndex])) { + return items.length; }
- getJSActions() { - return this._transport.getDocJSActions(); + if (condition(items[minIndex])) { + return minIndex; }
- getOutline() { - return this._transport.getOutline(); - } + while (minIndex < maxIndex) { + const currentIndex = minIndex + maxIndex >> 1; + const currentItem = items[currentIndex];
- getOptionalContentConfig() { - return this._transport.getOptionalContentConfig(); + if (condition(currentItem)) { + maxIndex = currentIndex; + } else { + minIndex = currentIndex + 1; + } }
- getPermissions() { - return this._transport.getPermissions(); - } + return minIndex; +}
- getMetadata() { - return this._transport.getMetadata(); - } +/***/ }), +/* 5 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- getMarkInfo() { - return this._transport.getMarkInfo(); - }
- getData() { - return this._transport.getData(); - }
- getDownloadInfo() { - return this._transport.downloadInfoCapability.promise; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.BaseStandardFontDataFactory = exports.BaseSVGFactory = exports.BaseCanvasFactory = exports.BaseCMapReaderFactory = void 0;
- cleanup(keepLoadedFonts = false) { - return this._transport.startCleanup(keepLoadedFonts || this.isPureXfa); - } +var _util = __w_pdfjs_require__(1);
- destroy() { - return this.loadingTask.destroy(); +class BaseCanvasFactory { + constructor() { + if (this.constructor === BaseCanvasFactory) { + (0, _util.unreachable)("Cannot initialize BaseCanvasFactory."); + } }
- get loadingParams() { - return this._transport.loadingParams; - } + create(width, height) { + if (width <= 0 || height <= 0) { + throw new Error("Invalid canvas size"); + }
- get loadingTask() { - return this._transport.loadingTask; - } + const canvas = this._createCanvas(width, height);
- saveDocument() { - return this._transport.saveDocument(); + return { + canvas, + context: canvas.getContext("2d") + }; }
- getFieldObjects() { - return this._transport.getFieldObjects(); - } + reset(canvasAndContext, width, height) { + if (!canvasAndContext.canvas) { + throw new Error("Canvas is not specified"); + }
- hasJSActions() { - return this._transport.hasJSActions(); - } + if (width <= 0 || height <= 0) { + throw new Error("Invalid canvas size"); + }
- getCalculationOrderIds() { - return this._transport.getCalculationOrderIds(); + canvasAndContext.canvas.width = width; + canvasAndContext.canvas.height = height; }
-} - -exports.PDFDocumentProxy = PDFDocumentProxy; + destroy(canvasAndContext) { + if (!canvasAndContext.canvas) { + throw new Error("Canvas is not specified"); + }
-class PDFPageProxy { - constructor(pageIndex, pageInfo, transport, ownerDocument, pdfBug = false) { - this._pageIndex = pageIndex; - this._pageInfo = pageInfo; - this._ownerDocument = ownerDocument; - this._transport = transport; - this._stats = pdfBug ? new _display_utils.StatTimer() : null; - this._pdfBug = pdfBug; - this.commonObjs = transport.commonObjs; - this.objs = new PDFObjects(); - this._bitmaps = new Set(); - this.cleanupAfterRender = false; - this.pendingCleanup = false; - this._intentStates = new Map(); - this._annotationPromises = new Map(); - this.destroyed = false; + canvasAndContext.canvas.width = 0; + canvasAndContext.canvas.height = 0; + canvasAndContext.canvas = null; + canvasAndContext.context = null; }
- get pageNumber() { - return this._pageIndex + 1; + _createCanvas(width, height) { + (0, _util.unreachable)("Abstract method `_createCanvas` called."); }
- get rotate() { - return this._pageInfo.rotate; - } +}
- get ref() { - return this._pageInfo.ref; - } +exports.BaseCanvasFactory = BaseCanvasFactory;
- get userUnit() { - return this._pageInfo.userUnit; - } +class BaseCMapReaderFactory { + constructor({ + baseUrl = null, + isCompressed = false + }) { + if (this.constructor === BaseCMapReaderFactory) { + (0, _util.unreachable)("Cannot initialize BaseCMapReaderFactory."); + }
- get view() { - return this._pageInfo.view; + this.baseUrl = baseUrl; + this.isCompressed = isCompressed; }
- getViewport({ - scale, - rotation = this.rotate, - offsetX = 0, - offsetY = 0, - dontFlip = false - } = {}) { - return new _display_utils.PageViewport({ - viewBox: this.view, - scale, - rotation, - offsetX, - offsetY, - dontFlip + async fetch({ + name + }) { + if (!this.baseUrl) { + throw new Error('The CMap "baseUrl" parameter must be specified, ensure that ' + 'the "cMapUrl" and "cMapPacked" API parameters are provided.'); + } + + if (!name) { + throw new Error("CMap name must be specified."); + } + + const url = this.baseUrl + name + (this.isCompressed ? ".bcmap" : ""); + const compressionType = this.isCompressed ? _util.CMapCompressionType.BINARY : _util.CMapCompressionType.NONE; + return this._fetchData(url, compressionType).catch(reason => { + throw new Error(`Unable to load ${this.isCompressed ? "binary " : ""}CMap at: ${url}`); }); }
- getAnnotations({ - intent = "display" - } = {}) { - const intentArgs = this._transport.getRenderingIntent(intent); + _fetchData(url, compressionType) { + (0, _util.unreachable)("Abstract method `_fetchData` called."); + }
- let promise = this._annotationPromises.get(intentArgs.cacheKey); +}
- if (!promise) { - promise = this._transport.getAnnotations(this._pageIndex, intentArgs.renderingIntent); +exports.BaseCMapReaderFactory = BaseCMapReaderFactory;
- this._annotationPromises.set(intentArgs.cacheKey, promise); +class BaseStandardFontDataFactory { + constructor({ + baseUrl = null + }) { + if (this.constructor === BaseStandardFontDataFactory) { + (0, _util.unreachable)("Cannot initialize BaseStandardFontDataFactory."); }
- return promise; - } - - getJSActions() { - return this._jsActionsPromise ||= this._transport.getPageJSActions(this._pageIndex); - } - - async getXfa() { - return this._transport._htmlForXfa?.children[this._pageIndex] || null; + this.baseUrl = baseUrl; }
- render({ - canvasContext, - viewport, - intent = "display", - annotationMode = _util.AnnotationMode.ENABLE, - transform = null, - imageLayer = null, - canvasFactory = null, - background = null, - optionalContentConfigPromise = null, - annotationCanvasMap = null, - pageColors = null + async fetch({ + filename }) { - if (this._stats) { - this._stats.time("Overall"); + if (!this.baseUrl) { + throw new Error('The standard font "baseUrl" parameter must be specified, ensure that ' + 'the "standardFontDataUrl" API parameter is provided.'); }
- const intentArgs = this._transport.getRenderingIntent(intent, annotationMode); + if (!filename) { + throw new Error("Font filename must be specified."); + }
- this.pendingCleanup = false; + const url = `${this.baseUrl}${filename}`; + return this._fetchData(url).catch(reason => { + throw new Error(`Unable to load font data at: ${url}`); + }); + }
- if (!optionalContentConfigPromise) { - optionalContentConfigPromise = this._transport.getOptionalContentConfig(); - } + _fetchData(url) { + (0, _util.unreachable)("Abstract method `_fetchData` called."); + }
- let intentState = this._intentStates.get(intentArgs.cacheKey); +}
- if (!intentState) { - intentState = Object.create(null); +exports.BaseStandardFontDataFactory = BaseStandardFontDataFactory;
- this._intentStates.set(intentArgs.cacheKey, intentState); +class BaseSVGFactory { + constructor() { + if (this.constructor === BaseSVGFactory) { + (0, _util.unreachable)("Cannot initialize BaseSVGFactory."); } + }
- if (intentState.streamReaderCancelTimeout) { - clearTimeout(intentState.streamReaderCancelTimeout); - intentState.streamReaderCancelTimeout = null; + create(width, height, skipDimensions = false) { + if (width <= 0 || height <= 0) { + throw new Error("Invalid SVG dimensions"); }
- const canvasFactoryInstance = canvasFactory || new DefaultCanvasFactory({ - ownerDocument: this._ownerDocument - }); - const intentPrint = !!(intentArgs.renderingIntent & _util.RenderingIntentFlag.PRINT); + const svg = this._createSVG("svg:svg");
- if (!intentState.displayReadyCapability) { - intentState.displayReadyCapability = (0, _util.createPromiseCapability)(); - intentState.operatorList = { - fnArray: [], - argsArray: [], - lastChunk: false - }; + svg.setAttribute("version", "1.1");
- if (this._stats) { - this._stats.time("Page Request"); - } + if (!skipDimensions) { + svg.setAttribute("width", `${width}px`); + svg.setAttribute("height", `${height}px`); + }
- this._pumpOperatorList(intentArgs); + svg.setAttribute("preserveAspectRatio", "none"); + svg.setAttribute("viewBox", `0 0 ${width} ${height}`); + return svg; + } + + createElement(type) { + if (typeof type !== "string") { + throw new Error("Invalid SVG element type"); }
- const complete = error => { - intentState.renderTasks.delete(internalRenderTask); + return this._createSVG(type); + }
- if (this.cleanupAfterRender || intentPrint) { - this.pendingCleanup = true; - } + _createSVG(type) { + (0, _util.unreachable)("Abstract method `_createSVG` called."); + }
- this._tryCleanup(); +}
- if (error) { - internalRenderTask.capability.reject(error); +exports.BaseSVGFactory = BaseSVGFactory;
- this._abortOperatorList({ - intentState, - reason: error instanceof Error ? error : new Error(error) - }); - } else { - internalRenderTask.capability.resolve(); - } +/***/ }), +/* 6 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- if (this._stats) { - this._stats.timeEnd("Rendering");
- this._stats.timeEnd("Overall"); - } - };
- const internalRenderTask = new InternalRenderTask({ - callback: complete, - params: { - canvasContext, - viewport, - transform, - imageLayer, - background - }, - objs: this.objs, - commonObjs: this.commonObjs, - annotationCanvasMap, - operatorList: intentState.operatorList, - pageIndex: this._pageIndex, - canvasFactory: canvasFactoryInstance, - useRequestAnimationFrame: !intentPrint, - pdfBug: this._pdfBug, - pageColors - }); - (intentState.renderTasks ||= new Set()).add(internalRenderTask); - const renderTask = internalRenderTask.task; - Promise.all([intentState.displayReadyCapability.promise, optionalContentConfigPromise]).then(([transparency, optionalContentConfig]) => { - if (this.pendingCleanup) { - complete(); - return; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.build = exports.RenderTask = exports.PDFWorkerUtil = exports.PDFWorker = exports.PDFPageProxy = exports.PDFDocumentProxy = exports.PDFDocumentLoadingTask = exports.PDFDataRangeTransport = exports.LoopbackPort = exports.DefaultStandardFontDataFactory = exports.DefaultCanvasFactory = exports.DefaultCMapReaderFactory = void 0; +exports.getDocument = getDocument; +exports.setPDFNetworkStreamFactory = setPDFNetworkStreamFactory; +exports.version = void 0;
- if (this._stats) { - this._stats.time("Rendering"); - } +var _util = __w_pdfjs_require__(1);
- internalRenderTask.initializeGraphics({ - transparency, - optionalContentConfig - }); - internalRenderTask.operatorListChanged(); - }).catch(complete); - return renderTask; - } +var _annotation_storage = __w_pdfjs_require__(7);
- getOperatorList({ - intent = "display", - annotationMode = _util.AnnotationMode.ENABLE - } = {}) { - function operatorListChanged() { - if (intentState.operatorList.lastChunk) { - intentState.opListReadCapability.resolve(intentState.operatorList); - intentState.renderTasks.delete(opListTask); - } - } +var _display_utils = __w_pdfjs_require__(4);
- const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, true); +var _font_loader = __w_pdfjs_require__(11);
- let intentState = this._intentStates.get(intentArgs.cacheKey); +var _canvas = __w_pdfjs_require__(12);
- if (!intentState) { - intentState = Object.create(null); +var _worker_options = __w_pdfjs_require__(15);
- this._intentStates.set(intentArgs.cacheKey, intentState); - } +var _is_node = __w_pdfjs_require__(3);
- let opListTask; +var _message_handler = __w_pdfjs_require__(16);
- if (!intentState.opListReadCapability) { - opListTask = Object.create(null); - opListTask.operatorListChanged = operatorListChanged; - intentState.opListReadCapability = (0, _util.createPromiseCapability)(); - (intentState.renderTasks ||= new Set()).add(opListTask); - intentState.operatorList = { - fnArray: [], - argsArray: [], - lastChunk: false - }; +var _metadata = __w_pdfjs_require__(17);
- if (this._stats) { - this._stats.time("Page Request"); - } +var _optional_content_config = __w_pdfjs_require__(18);
- this._pumpOperatorList(intentArgs); - } +var _transport_stream = __w_pdfjs_require__(19);
- return intentState.opListReadCapability.promise; - } +var _xfa_text = __w_pdfjs_require__(20);
- streamTextContent({ - disableCombineTextItems = false, - includeMarkedContent = false - } = {}) { - const TEXT_CONTENT_CHUNK_SIZE = 100; - return this._transport.messageHandler.sendWithStream("GetTextContent", { - pageIndex: this._pageIndex, - combineTextItems: disableCombineTextItems !== true, - includeMarkedContent: includeMarkedContent === true - }, { - highWaterMark: TEXT_CONTENT_CHUNK_SIZE, +const DEFAULT_RANGE_CHUNK_SIZE = 65536; +const RENDERING_CANCELLED_TIMEOUT = 100; +let DefaultCanvasFactory = _display_utils.DOMCanvasFactory; +exports.DefaultCanvasFactory = DefaultCanvasFactory; +let DefaultCMapReaderFactory = _display_utils.DOMCMapReaderFactory; +exports.DefaultCMapReaderFactory = DefaultCMapReaderFactory; +let DefaultStandardFontDataFactory = _display_utils.DOMStandardFontDataFactory; +exports.DefaultStandardFontDataFactory = DefaultStandardFontDataFactory; +; +let createPDFNetworkStream;
- size(textContent) { - return textContent.items.length; - } +function setPDFNetworkStreamFactory(pdfNetworkStreamFactory) { + createPDFNetworkStream = pdfNetworkStreamFactory; +}
- }); - } +function getDocument(src) { + const task = new PDFDocumentLoadingTask(); + let source;
- getTextContent(params = {}) { - if (this._transport._htmlForXfa) { - return this.getXfa().then(xfa => { - return _xfa_text.XfaText.textContent(xfa); - }); + if (typeof src === "string" || src instanceof URL) { + source = { + url: src + }; + } else if ((0, _util.isArrayBuffer)(src)) { + source = { + data: src + }; + } else if (src instanceof PDFDataRangeTransport) { + source = { + range: src + }; + } else { + if (typeof src !== "object") { + throw new Error("Invalid parameter in getDocument, " + "need either string, URL, Uint8Array, or parameter object."); }
- const readableStream = this.streamTextContent(params); - return new Promise(function (resolve, reject) { - function pump() { - reader.read().then(function ({ - value, - done - }) { - if (done) { - resolve(textContent); - return; - } - - Object.assign(textContent.styles, value.styles); - textContent.items.push(...value.items); - pump(); - }, reject); - } + if (!src.url && !src.data && !src.range) { + throw new Error("Invalid parameter object: need either .data, .range or .url"); + }
- const reader = readableStream.getReader(); - const textContent = { - items: [], - styles: Object.create(null) - }; - pump(); - }); + source = src; }
- getStructTree() { - return this._structTreePromise ||= this._transport.getStructTree(this._pageIndex); - } + const params = Object.create(null); + let rangeTransport = null, + worker = null;
- _destroy() { - this.destroyed = true; - const waitOn = []; + for (const key in source) { + const value = source[key];
- for (const intentState of this._intentStates.values()) { - this._abortOperatorList({ - intentState, - reason: new Error("Page was destroyed."), - force: true - }); + switch (key) { + case "url": + if (typeof window !== "undefined") { + try { + params[key] = new URL(value, window.location).href; + continue; + } catch (ex) { + (0, _util.warn)(`Cannot create valid URL: "${ex}".`); + } + } else if (typeof value === "string" || value instanceof URL) { + params[key] = value.toString(); + continue; + }
- if (intentState.opListReadCapability) { + throw new Error("Invalid PDF url data: " + "either string or URL-object is expected in the url property."); + + case "range": + rangeTransport = value; continue; - }
- for (const internalRenderTask of intentState.renderTasks) { - waitOn.push(internalRenderTask.completed); - internalRenderTask.cancel(); - } - } + case "worker": + worker = value; + continue;
- this.objs.clear(); + case "data": + if (value instanceof Uint8Array) { + break; + } else if (typeof value === "string") { + params[key] = (0, _util.stringToBytes)(value); + } else if (typeof value === "object" && value !== null && !isNaN(value.length)) { + params[key] = new Uint8Array(value); + } else if ((0, _util.isArrayBuffer)(value)) { + params[key] = new Uint8Array(value); + } else { + throw new Error("Invalid PDF binary data: either typed array, " + "string, or array-like object is expected in the data property."); + }
- for (const bitmap of this._bitmaps) { - bitmap.close(); + continue; }
- this._bitmaps.clear(); + params[key] = value; + }
- this._annotationPromises.clear(); + params.CMapReaderFactory = params.CMapReaderFactory || DefaultCMapReaderFactory; + params.StandardFontDataFactory = params.StandardFontDataFactory || DefaultStandardFontDataFactory; + params.ignoreErrors = params.stopAtErrors !== true; + params.fontExtraProperties = params.fontExtraProperties === true; + params.pdfBug = params.pdfBug === true; + params.enableXfa = params.enableXfa === true;
- this._jsActionsPromise = null; - this._structTreePromise = null; - this.pendingCleanup = false; - return Promise.all(waitOn); + if (!Number.isInteger(params.rangeChunkSize) || params.rangeChunkSize < 1) { + params.rangeChunkSize = DEFAULT_RANGE_CHUNK_SIZE; }
- cleanup(resetStats = false) { - this.pendingCleanup = true; - return this._tryCleanup(resetStats); + if (typeof params.docBaseUrl !== "string" || (0, _display_utils.isDataScheme)(params.docBaseUrl)) { + params.docBaseUrl = null; }
- _tryCleanup(resetStats = false) { - if (!this.pendingCleanup) { - return false; - } - - for (const { - renderTasks, - operatorList - } of this._intentStates.values()) { - if (renderTasks.size > 0 || !operatorList.lastChunk) { - return false; - } - } + if (!Number.isInteger(params.maxImageSize) || params.maxImageSize < -1) { + params.maxImageSize = -1; + }
- this._intentStates.clear(); + if (typeof params.cMapUrl !== "string") { + params.cMapUrl = null; + }
- this.objs.clear(); + if (typeof params.standardFontDataUrl !== "string") { + params.standardFontDataUrl = null; + }
- this._annotationPromises.clear(); + if (typeof params.useWorkerFetch !== "boolean") { + params.useWorkerFetch = params.CMapReaderFactory === _display_utils.DOMCMapReaderFactory && params.StandardFontDataFactory === _display_utils.DOMStandardFontDataFactory; + }
- this._jsActionsPromise = null; - this._structTreePromise = null; + if (typeof params.isEvalSupported !== "boolean") { + params.isEvalSupported = true; + }
- if (resetStats && this._stats) { - this._stats = new _display_utils.StatTimer(); - } + if (typeof params.disableFontFace !== "boolean") { + params.disableFontFace = _is_node.isNodeJS; + }
- for (const bitmap of this._bitmaps) { - bitmap.close(); - } + if (typeof params.useSystemFonts !== "boolean") { + params.useSystemFonts = !_is_node.isNodeJS && !params.disableFontFace; + }
- this._bitmaps.clear(); + if (typeof params.ownerDocument !== "object" || params.ownerDocument === null) { + params.ownerDocument = globalThis.document; + }
- this.pendingCleanup = false; - return true; + if (typeof params.disableRange !== "boolean") { + params.disableRange = false; }
- _startRenderPage(transparency, cacheKey) { - const intentState = this._intentStates.get(cacheKey); + if (typeof params.disableStream !== "boolean") { + params.disableStream = false; + }
- if (!intentState) { - return; - } + if (typeof params.disableAutoFetch !== "boolean") { + params.disableAutoFetch = false; + }
- if (this._stats) { - this._stats.timeEnd("Page Request"); - } + (0, _util.setVerbosityLevel)(params.verbosity);
- if (intentState.displayReadyCapability) { - intentState.displayReadyCapability.resolve(transparency); - } + if (!worker) { + const workerParams = { + verbosity: params.verbosity, + port: _worker_options.GlobalWorkerOptions.workerPort + }; + worker = workerParams.port ? PDFWorker.fromPort(workerParams) : new PDFWorker(workerParams); + task._worker = worker; }
- _renderPageChunk(operatorListChunk, intentState) { - for (let i = 0, ii = operatorListChunk.length; i < ii; i++) { - intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]); - intentState.operatorList.argsArray.push(operatorListChunk.argsArray[i]); + const docId = task.docId; + worker.promise.then(function () { + if (task.destroyed) { + throw new Error("Loading aborted"); }
- intentState.operatorList.lastChunk = operatorListChunk.lastChunk; + const workerIdPromise = _fetchDocument(worker, params, rangeTransport, docId);
- for (const internalRenderTask of intentState.renderTasks) { - internalRenderTask.operatorListChanged(); - } + const networkStreamPromise = new Promise(function (resolve) { + let networkStream;
- if (operatorListChunk.lastChunk) { - this._tryCleanup(); - } - } + if (rangeTransport) { + networkStream = new _transport_stream.PDFDataTransportStream({ + length: params.length, + initialData: params.initialData, + progressiveDone: params.progressiveDone, + contentDispositionFilename: params.contentDispositionFilename, + disableRange: params.disableRange, + disableStream: params.disableStream + }, rangeTransport); + } else if (!params.data) { + networkStream = createPDFNetworkStream({ + url: params.url, + length: params.length, + httpHeaders: params.httpHeaders, + withCredentials: params.withCredentials, + rangeChunkSize: params.rangeChunkSize, + disableRange: params.disableRange, + disableStream: params.disableStream + }); + }
- _pumpOperatorList({ - renderingIntent, - cacheKey - }) { - const readableStream = this._transport.messageHandler.sendWithStream("GetOperatorList", { - pageIndex: this._pageIndex, - intent: renderingIntent, - cacheKey, - annotationStorage: renderingIntent & _util.RenderingIntentFlag.ANNOTATIONS_STORAGE ? this._transport.annotationStorage.serializable : null + resolve(networkStream); }); + return Promise.all([workerIdPromise, networkStreamPromise]).then(function ([workerId, networkStream]) { + if (task.destroyed) { + throw new Error("Loading aborted"); + }
- const reader = readableStream.getReader(); - - const intentState = this._intentStates.get(cacheKey); - - intentState.streamReader = reader; - - const pump = () => { - reader.read().then(({ - value, - done - }) => { - if (done) { - intentState.streamReader = null; - return; - } - - if (this._transport.destroyed) { - return; - } + const messageHandler = new _message_handler.MessageHandler(docId, workerId, worker.port); + const transport = new WorkerTransport(messageHandler, task, networkStream, params); + task._transport = transport; + messageHandler.send("Ready", null); + }); + }).catch(task._capability.reject); + return task; +}
- this._renderPageChunk(value, intentState); +async function _fetchDocument(worker, source, pdfDataRangeTransport, docId) { + if (worker.destroyed) { + throw new Error("Worker was destroyed"); + }
- pump(); - }, reason => { - intentState.streamReader = null; + if (pdfDataRangeTransport) { + source.length = pdfDataRangeTransport.length; + source.initialData = pdfDataRangeTransport.initialData; + source.progressiveDone = pdfDataRangeTransport.progressiveDone; + source.contentDispositionFilename = pdfDataRangeTransport.contentDispositionFilename; + }
- if (this._transport.destroyed) { - return; - } + const workerId = await worker.messageHandler.sendWithPromise("GetDocRequest", { + docId, + apiVersion: '2.15.305', + source: { + data: source.data, + url: source.url, + password: source.password, + disableAutoFetch: source.disableAutoFetch, + rangeChunkSize: source.rangeChunkSize, + length: source.length + }, + maxImageSize: source.maxImageSize, + disableFontFace: source.disableFontFace, + docBaseUrl: source.docBaseUrl, + ignoreErrors: source.ignoreErrors, + isEvalSupported: source.isEvalSupported, + fontExtraProperties: source.fontExtraProperties, + enableXfa: source.enableXfa, + useSystemFonts: source.useSystemFonts, + cMapUrl: source.useWorkerFetch ? source.cMapUrl : null, + standardFontDataUrl: source.useWorkerFetch ? source.standardFontDataUrl : null + });
- if (intentState.operatorList) { - intentState.operatorList.lastChunk = true; + if (source.data) { + source.data = null; + }
- for (const internalRenderTask of intentState.renderTasks) { - internalRenderTask.operatorListChanged(); - } + if (worker.destroyed) { + throw new Error("Worker was destroyed"); + }
- this._tryCleanup(); - } + return workerId; +}
- if (intentState.displayReadyCapability) { - intentState.displayReadyCapability.reject(reason); - } else if (intentState.opListReadCapability) { - intentState.opListReadCapability.reject(reason); - } else { - throw reason; - } - }); - }; +class PDFDocumentLoadingTask { + static #docId = 0;
- pump(); + constructor() { + this._capability = (0, _util.createPromiseCapability)(); + this._transport = null; + this._worker = null; + this.docId = `d${PDFDocumentLoadingTask.#docId++}`; + this.destroyed = false; + this.onPassword = null; + this.onProgress = null; + this.onUnsupportedFeature = null; }
- _abortOperatorList({ - intentState, - reason, - force = false - }) { - if (!intentState.streamReader) { - return; - } - - if (!force) { - if (intentState.renderTasks.size > 0) { - return; - } - - if (reason instanceof _display_utils.RenderingCancelledException) { - intentState.streamReaderCancelTimeout = setTimeout(() => { - this._abortOperatorList({ - intentState, - reason, - force: true - }); + get promise() { + return this._capability.promise; + }
- intentState.streamReaderCancelTimeout = null; - }, RENDERING_CANCELLED_TIMEOUT); - return; - } - } + async destroy() { + this.destroyed = true; + await this._transport?.destroy(); + this._transport = null;
- intentState.streamReader.cancel(new _util.AbortException(reason.message)).catch(() => {}); - intentState.streamReader = null; + if (this._worker) { + this._worker.destroy();
- if (this._transport.destroyed) { - return; + this._worker = null; } + }
- for (const [curCacheKey, curIntentState] of this._intentStates) { - if (curIntentState === intentState) { - this._intentStates.delete(curCacheKey); +}
- break; - } - } +exports.PDFDocumentLoadingTask = PDFDocumentLoadingTask;
- this.cleanup(); +class PDFDataRangeTransport { + constructor(length, initialData, progressiveDone = false, contentDispositionFilename = null) { + this.length = length; + this.initialData = initialData; + this.progressiveDone = progressiveDone; + this.contentDispositionFilename = contentDispositionFilename; + this._rangeListeners = []; + this._progressListeners = []; + this._progressiveReadListeners = []; + this._progressiveDoneListeners = []; + this._readyCapability = (0, _util.createPromiseCapability)(); }
- get stats() { - return this._stats; + addRangeListener(listener) { + this._rangeListeners.push(listener); }
-} + addProgressListener(listener) { + this._progressListeners.push(listener); + }
-exports.PDFPageProxy = PDFPageProxy; + addProgressiveReadListener(listener) { + this._progressiveReadListeners.push(listener); + }
-class LoopbackPort { - constructor() { - this._listeners = []; - this._deferred = Promise.resolve(); + addProgressiveDoneListener(listener) { + this._progressiveDoneListeners.push(listener); }
- postMessage(obj, transfers) { - const event = { - data: structuredClone(obj, transfers) - }; + onDataRange(begin, chunk) { + for (const listener of this._rangeListeners) { + listener(begin, chunk); + } + }
- this._deferred.then(() => { - for (const listener of this._listeners) { - listener.call(this, event); + onDataProgress(loaded, total) { + this._readyCapability.promise.then(() => { + for (const listener of this._progressListeners) { + listener(loaded, total); } }); }
- addEventListener(name, listener) { - this._listeners.push(listener); + onDataProgressiveRead(chunk) { + this._readyCapability.promise.then(() => { + for (const listener of this._progressiveReadListeners) { + listener(chunk); + } + }); }
- removeEventListener(name, listener) { - const i = this._listeners.indexOf(listener); + onDataProgressiveDone() { + this._readyCapability.promise.then(() => { + for (const listener of this._progressiveDoneListeners) { + listener(); + } + }); + }
- this._listeners.splice(i, 1); + transportReady() { + this._readyCapability.resolve(); }
- terminate() { - this._listeners.length = 0; + requestDataRange(begin, end) { + (0, _util.unreachable)("Abstract method PDFDataRangeTransport.requestDataRange"); }
+ abort() {} + }
-exports.LoopbackPort = LoopbackPort; -const PDFWorkerUtil = { - isWorkerDisabled: false, - fallbackWorkerSrc: null, - fakeWorkerId: 0 -}; -exports.PDFWorkerUtil = PDFWorkerUtil; -; - -class PDFWorker { - static #workerPorts = new WeakMap(); - - constructor({ - name = null, - port = null, - verbosity = (0, _util.getVerbosityLevel)() - } = {}) { - if (port && PDFWorker.#workerPorts.has(port)) { - throw new Error("Cannot use more than one PDFWorker per port."); - } - - this.name = name; - this.destroyed = false; - this.verbosity = verbosity; - this._readyCapability = (0, _util.createPromiseCapability)(); - this._port = null; - this._webWorker = null; - this._messageHandler = null; - - if (port) { - PDFWorker.#workerPorts.set(port, this); - - this._initializeFromPort(port); - - return; - } +exports.PDFDataRangeTransport = PDFDataRangeTransport;
- this._initialize(); +class PDFDocumentProxy { + constructor(pdfInfo, transport) { + this._pdfInfo = pdfInfo; + this._transport = transport; }
- get promise() { - return this._readyCapability.promise; + get annotationStorage() { + return this._transport.annotationStorage; }
- get port() { - return this._port; + get numPages() { + return this._pdfInfo.numPages; }
- get messageHandler() { - return this._messageHandler; + get fingerprints() { + return this._pdfInfo.fingerprints; }
- _initializeFromPort(port) { - this._port = port; - this._messageHandler = new _message_handler.MessageHandler("main", "worker", port); - - this._messageHandler.on("ready", function () {}); - - this._readyCapability.resolve(); + get stats() { + return this._transport.stats; }
- _initialize() { - if (typeof Worker !== "undefined" && !PDFWorkerUtil.isWorkerDisabled && !PDFWorker._mainThreadWorkerMessageHandler) { - let workerSrc = PDFWorker.workerSrc; + get isPureXfa() { + return !!this._transport._htmlForXfa; + }
- try { - const worker = new Worker(workerSrc); - const messageHandler = new _message_handler.MessageHandler("main", "worker", worker); + get allXfaHtml() { + return this._transport._htmlForXfa; + }
- const terminateEarly = () => { - worker.removeEventListener("error", onWorkerError); - messageHandler.destroy(); - worker.terminate(); + getPage(pageNumber) { + return this._transport.getPage(pageNumber); + }
- if (this.destroyed) { - this._readyCapability.reject(new Error("Worker was destroyed")); - } else { - this._setupFakeWorker(); - } - }; + getPageIndex(ref) { + return this._transport.getPageIndex(ref); + }
- const onWorkerError = () => { - if (!this._webWorker) { - terminateEarly(); - } - }; + getDestinations() { + return this._transport.getDestinations(); + }
- worker.addEventListener("error", onWorkerError); - messageHandler.on("test", data => { - worker.removeEventListener("error", onWorkerError); + getDestination(id) { + return this._transport.getDestination(id); + }
- if (this.destroyed) { - terminateEarly(); - return; - } + getPageLabels() { + return this._transport.getPageLabels(); + }
- if (data) { - this._messageHandler = messageHandler; - this._port = worker; - this._webWorker = worker; + getPageLayout() { + return this._transport.getPageLayout(); + }
- this._readyCapability.resolve(); + getPageMode() { + return this._transport.getPageMode(); + }
- messageHandler.send("configure", { - verbosity: this.verbosity - }); - } else { - this._setupFakeWorker(); + getViewerPreferences() { + return this._transport.getViewerPreferences(); + }
- messageHandler.destroy(); - worker.terminate(); - } - }); - messageHandler.on("ready", data => { - worker.removeEventListener("error", onWorkerError); + getOpenAction() { + return this._transport.getOpenAction(); + }
- if (this.destroyed) { - terminateEarly(); - return; - } + getAttachments() { + return this._transport.getAttachments(); + }
- try { - sendTest(); - } catch (e) { - this._setupFakeWorker(); - } - }); + getJavaScript() { + return this._transport.getJavaScript(); + }
- const sendTest = () => { - const testObj = new Uint8Array(); - messageHandler.send("test", testObj, [testObj.buffer]); - }; + getJSActions() { + return this._transport.getDocJSActions(); + }
- sendTest(); - return; - } catch (e) { - (0, _util.info)("The worker has been disabled."); - } - } + getOutline() { + return this._transport.getOutline(); + }
- this._setupFakeWorker(); + getOptionalContentConfig() { + return this._transport.getOptionalContentConfig(); }
- _setupFakeWorker() { - if (!PDFWorkerUtil.isWorkerDisabled) { - (0, _util.warn)("Setting up fake worker."); - PDFWorkerUtil.isWorkerDisabled = true; - } + getPermissions() { + return this._transport.getPermissions(); + }
- PDFWorker._setupFakeWorkerGlobal.then(WorkerMessageHandler => { - if (this.destroyed) { - this._readyCapability.reject(new Error("Worker was destroyed")); + getMetadata() { + return this._transport.getMetadata(); + }
- return; - } + getMarkInfo() { + return this._transport.getMarkInfo(); + }
- const port = new LoopbackPort(); - this._port = port; - const id = `fake${PDFWorkerUtil.fakeWorkerId++}`; - const workerHandler = new _message_handler.MessageHandler(id + "_worker", id, port); - WorkerMessageHandler.setup(workerHandler, port); - const messageHandler = new _message_handler.MessageHandler(id, id + "_worker", port); - this._messageHandler = messageHandler; + getData() { + return this._transport.getData(); + }
- this._readyCapability.resolve(); + getDownloadInfo() { + return this._transport.downloadInfoCapability.promise; + }
- messageHandler.send("configure", { - verbosity: this.verbosity - }); - }).catch(reason => { - this._readyCapability.reject(new Error(`Setting up fake worker failed: "${reason.message}".`)); - }); + cleanup(keepLoadedFonts = false) { + return this._transport.startCleanup(keepLoadedFonts || this.isPureXfa); }
destroy() { - this.destroyed = true; + return this.loadingTask.destroy(); + }
- if (this._webWorker) { - this._webWorker.terminate(); + get loadingParams() { + return this._transport.loadingParams; + }
- this._webWorker = null; - } + get loadingTask() { + return this._transport.loadingTask; + }
- PDFWorker.#workerPorts.delete(this._port); - this._port = null; + saveDocument() { + return this._transport.saveDocument(); + }
- if (this._messageHandler) { - this._messageHandler.destroy(); + getFieldObjects() { + return this._transport.getFieldObjects(); + }
- this._messageHandler = null; - } + hasJSActions() { + return this._transport.hasJSActions(); }
- static fromPort(params) { - if (!params?.port) { - throw new Error("PDFWorker.fromPort - invalid method signature."); - } + getCalculationOrderIds() { + return this._transport.getCalculationOrderIds(); + }
- if (this.#workerPorts.has(params.port)) { - return this.#workerPorts.get(params.port); - } +}
- return new PDFWorker(params); - } +exports.PDFDocumentProxy = PDFDocumentProxy;
- static get workerSrc() { - if (_worker_options.GlobalWorkerOptions.workerSrc) { - return _worker_options.GlobalWorkerOptions.workerSrc; - } - - if (PDFWorkerUtil.fallbackWorkerSrc !== null) { - if (!_is_node.isNodeJS) { - (0, _display_utils.deprecated)('No "GlobalWorkerOptions.workerSrc" specified.'); - } - - return PDFWorkerUtil.fallbackWorkerSrc; - } - - throw new Error('No "GlobalWorkerOptions.workerSrc" specified.'); +class PDFPageProxy { + constructor(pageIndex, pageInfo, transport, ownerDocument, pdfBug = false) { + this._pageIndex = pageIndex; + this._pageInfo = pageInfo; + this._ownerDocument = ownerDocument; + this._transport = transport; + this._stats = pdfBug ? new _display_utils.StatTimer() : null; + this._pdfBug = pdfBug; + this.commonObjs = transport.commonObjs; + this.objs = new PDFObjects(); + this._bitmaps = new Set(); + this.cleanupAfterRender = false; + this.pendingCleanup = false; + this._intentStates = new Map(); + this._annotationPromises = new Map(); + this.destroyed = false; }
- static get _mainThreadWorkerMessageHandler() { - try { - return globalThis.pdfjsWorker?.WorkerMessageHandler || null; - } catch (ex) { - return null; - } + get pageNumber() { + return this._pageIndex + 1; }
- static get _setupFakeWorkerGlobal() { - const loader = async () => { - const mainWorkerMessageHandler = this._mainThreadWorkerMessageHandler; + get rotate() { + return this._pageInfo.rotate; + }
- if (mainWorkerMessageHandler) { - return mainWorkerMessageHandler; - } + get ref() { + return this._pageInfo.ref; + }
- await (0, _display_utils.loadScript)(this.workerSrc); - return window.pdfjsWorker.WorkerMessageHandler; - }; + get userUnit() { + return this._pageInfo.userUnit; + }
- return (0, _util.shadow)(this, "_setupFakeWorkerGlobal", loader()); + get view() { + return this._pageInfo.view; }
-} + getViewport({ + scale, + rotation = this.rotate, + offsetX = 0, + offsetY = 0, + dontFlip = false + } = {}) { + return new _display_utils.PageViewport({ + viewBox: this.view, + scale, + rotation, + offsetX, + offsetY, + dontFlip + }); + }
-exports.PDFWorker = PDFWorker; -; + getAnnotations({ + intent = "display" + } = {}) { + const intentArgs = this._transport.getRenderingIntent(intent);
-class WorkerTransport { - #docStats = null; - #pageCache = new Map(); - #pagePromises = new Map(); - #metadataPromise = null; + let promise = this._annotationPromises.get(intentArgs.cacheKey);
- constructor(messageHandler, loadingTask, networkStream, params) { - this.messageHandler = messageHandler; - this.loadingTask = loadingTask; - this.commonObjs = new PDFObjects(); - this.fontLoader = new _font_loader.FontLoader({ - docId: loadingTask.docId, - onUnsupportedFeature: this._onUnsupportedFeature.bind(this), - ownerDocument: params.ownerDocument, - styleElement: params.styleElement - }); - this._params = params; + if (!promise) { + promise = this._transport.getAnnotations(this._pageIndex, intentArgs.renderingIntent);
- if (!params.useWorkerFetch) { - this.CMapReaderFactory = new params.CMapReaderFactory({ - baseUrl: params.cMapUrl, - isCompressed: params.cMapPacked - }); - this.StandardFontDataFactory = new params.StandardFontDataFactory({ - baseUrl: params.standardFontDataUrl - }); + this._annotationPromises.set(intentArgs.cacheKey, promise); }
- this.destroyed = false; - this.destroyCapability = null; - this._passwordCapability = null; - this._networkStream = networkStream; - this._fullReader = null; - this._lastProgress = null; - this.downloadInfoCapability = (0, _util.createPromiseCapability)(); - this.setupMessageHandler(); + return promise; }
- get annotationStorage() { - return (0, _util.shadow)(this, "annotationStorage", new _annotation_storage.AnnotationStorage()); + getJSActions() { + return this._jsActionsPromise ||= this._transport.getPageJSActions(this._pageIndex); }
- get stats() { - return this.#docStats; + async getXfa() { + return this._transport._htmlForXfa?.children[this._pageIndex] || null; }
- getRenderingIntent(intent, annotationMode = _util.AnnotationMode.ENABLE, isOpList = false) { - let renderingIntent = _util.RenderingIntentFlag.DISPLAY; - let annotationHash = ""; - - switch (intent) { - case "any": - renderingIntent = _util.RenderingIntentFlag.ANY; - break; + render({ + canvasContext, + viewport, + intent = "display", + annotationMode = _util.AnnotationMode.ENABLE, + transform = null, + imageLayer = null, + canvasFactory = null, + background = null, + optionalContentConfigPromise = null, + annotationCanvasMap = null, + pageColors = null, + printAnnotationStorage = null + }) { + if (this._stats) { + this._stats.time("Overall"); + }
- case "display": - break; + const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage);
- case "print": - renderingIntent = _util.RenderingIntentFlag.PRINT; - break; + this.pendingCleanup = false;
- default: - (0, _util.warn)(`getRenderingIntent - invalid intent: ${intent}`); + if (!optionalContentConfigPromise) { + optionalContentConfigPromise = this._transport.getOptionalContentConfig(); }
- switch (annotationMode) { - case _util.AnnotationMode.DISABLE: - renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_DISABLE; - break; - - case _util.AnnotationMode.ENABLE: - break; - - case _util.AnnotationMode.ENABLE_FORMS: - renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_FORMS; - break; + let intentState = this._intentStates.get(intentArgs.cacheKey);
- case _util.AnnotationMode.ENABLE_STORAGE: - renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_STORAGE; - annotationHash = this.annotationStorage.hash; - break; + if (!intentState) { + intentState = Object.create(null);
- default: - (0, _util.warn)(`getRenderingIntent - invalid annotationMode: ${annotationMode}`); + this._intentStates.set(intentArgs.cacheKey, intentState); }
- if (isOpList) { - renderingIntent += _util.RenderingIntentFlag.OPLIST; + if (intentState.streamReaderCancelTimeout) { + clearTimeout(intentState.streamReaderCancelTimeout); + intentState.streamReaderCancelTimeout = null; }
- return { - renderingIntent, - cacheKey: `${renderingIntent}_${annotationHash}` - }; - } + const canvasFactoryInstance = canvasFactory || new DefaultCanvasFactory({ + ownerDocument: this._ownerDocument + }); + const intentPrint = !!(intentArgs.renderingIntent & _util.RenderingIntentFlag.PRINT);
- destroy() { - if (this.destroyCapability) { - return this.destroyCapability.promise; - } + if (!intentState.displayReadyCapability) { + intentState.displayReadyCapability = (0, _util.createPromiseCapability)(); + intentState.operatorList = { + fnArray: [], + argsArray: [], + lastChunk: false + };
- this.destroyed = true; - this.destroyCapability = (0, _util.createPromiseCapability)(); + if (this._stats) { + this._stats.time("Page Request"); + }
- if (this._passwordCapability) { - this._passwordCapability.reject(new Error("Worker was destroyed during onPassword callback")); + this._pumpOperatorList(intentArgs); }
- const waitOn = []; - - for (const page of this.#pageCache.values()) { - waitOn.push(page._destroy()); - } + const complete = error => { + intentState.renderTasks.delete(internalRenderTask);
- this.#pageCache.clear(); - this.#pagePromises.clear(); + if (this.cleanupAfterRender || intentPrint) { + this.pendingCleanup = true; + }
- if (this.hasOwnProperty("annotationStorage")) { - this.annotationStorage.resetModified(); - } + this._tryCleanup();
- const terminated = this.messageHandler.sendWithPromise("Terminate", null); - waitOn.push(terminated); - Promise.all(waitOn).then(() => { - this.commonObjs.clear(); - this.fontLoader.clear(); - this.#metadataPromise = null; - this._getFieldObjectsPromise = null; - this._hasJSActionsPromise = null; + if (error) { + internalRenderTask.capability.reject(error);
- if (this._networkStream) { - this._networkStream.cancelAllRequests(new _util.AbortException("Worker was terminated.")); + this._abortOperatorList({ + intentState, + reason: error instanceof Error ? error : new Error(error) + }); + } else { + internalRenderTask.capability.resolve(); }
- if (this.messageHandler) { - this.messageHandler.destroy(); - this.messageHandler = null; - } + if (this._stats) { + this._stats.timeEnd("Rendering");
- this.destroyCapability.resolve(); - }, this.destroyCapability.reject); - return this.destroyCapability.promise; - } + this._stats.timeEnd("Overall"); + } + };
- setupMessageHandler() { - const { - messageHandler, - loadingTask - } = this; - messageHandler.on("GetReader", (data, sink) => { - (0, _util.assert)(this._networkStream, "GetReader - no `IPDFStream` instance available."); - this._fullReader = this._networkStream.getFullReader(); + const internalRenderTask = new InternalRenderTask({ + callback: complete, + params: { + canvasContext, + viewport, + transform, + imageLayer, + background + }, + objs: this.objs, + commonObjs: this.commonObjs, + annotationCanvasMap, + operatorList: intentState.operatorList, + pageIndex: this._pageIndex, + canvasFactory: canvasFactoryInstance, + useRequestAnimationFrame: !intentPrint, + pdfBug: this._pdfBug, + pageColors + }); + (intentState.renderTasks ||= new Set()).add(internalRenderTask); + const renderTask = internalRenderTask.task; + Promise.all([intentState.displayReadyCapability.promise, optionalContentConfigPromise]).then(([transparency, optionalContentConfig]) => { + if (this.pendingCleanup) { + complete(); + return; + }
- this._fullReader.onProgress = evt => { - this._lastProgress = { - loaded: evt.loaded, - total: evt.total - }; - }; + if (this._stats) { + this._stats.time("Rendering"); + }
- sink.onPull = () => { - this._fullReader.read().then(function ({ - value, - done - }) { - if (done) { - sink.close(); - return; - } + internalRenderTask.initializeGraphics({ + transparency, + optionalContentConfig + }); + internalRenderTask.operatorListChanged(); + }).catch(complete); + return renderTask; + }
- (0, _util.assert)((0, _util.isArrayBuffer)(value), "GetReader - expected an ArrayBuffer."); - sink.enqueue(new Uint8Array(value), 1, [value]); - }).catch(reason => { - sink.error(reason); - }); - }; + getOperatorList({ + intent = "display", + annotationMode = _util.AnnotationMode.ENABLE, + printAnnotationStorage = null + } = {}) { + function operatorListChanged() { + if (intentState.operatorList.lastChunk) { + intentState.opListReadCapability.resolve(intentState.operatorList); + intentState.renderTasks.delete(opListTask); + } + }
- sink.onCancel = reason => { - this._fullReader.cancel(reason); + const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage, true);
- sink.ready.catch(readyReason => { - if (this.destroyed) { - return; - } + let intentState = this._intentStates.get(intentArgs.cacheKey);
- throw readyReason; - }); + if (!intentState) { + intentState = Object.create(null); + + this._intentStates.set(intentArgs.cacheKey, intentState); + } + + let opListTask; + + if (!intentState.opListReadCapability) { + opListTask = Object.create(null); + opListTask.operatorListChanged = operatorListChanged; + intentState.opListReadCapability = (0, _util.createPromiseCapability)(); + (intentState.renderTasks ||= new Set()).add(opListTask); + intentState.operatorList = { + fnArray: [], + argsArray: [], + lastChunk: false }; - }); - messageHandler.on("ReaderHeadersReady", data => { - const headersCapability = (0, _util.createPromiseCapability)(); - const fullReader = this._fullReader; - fullReader.headersReady.then(() => { - if (!fullReader.isStreamingSupported || !fullReader.isRangeSupported) { - if (this._lastProgress) { - loadingTask.onProgress?.(this._lastProgress); - }
- fullReader.onProgress = evt => { - loadingTask.onProgress?.({ - loaded: evt.loaded, - total: evt.total - }); - }; - } + if (this._stats) { + this._stats.time("Page Request"); + }
- headersCapability.resolve({ - isStreamingSupported: fullReader.isStreamingSupported, - isRangeSupported: fullReader.isRangeSupported, - contentLength: fullReader.contentLength - }); - }, headersCapability.reject); - return headersCapability.promise; - }); - messageHandler.on("GetRangeReader", (data, sink) => { - (0, _util.assert)(this._networkStream, "GetRangeReader - no `IPDFStream` instance available."); + this._pumpOperatorList(intentArgs); + }
- const rangeReader = this._networkStream.getRangeReader(data.begin, data.end); + return intentState.opListReadCapability.promise; + }
- if (!rangeReader) { - sink.close(); - return; + streamTextContent({ + disableCombineTextItems = false, + includeMarkedContent = false + } = {}) { + const TEXT_CONTENT_CHUNK_SIZE = 100; + return this._transport.messageHandler.sendWithStream("GetTextContent", { + pageIndex: this._pageIndex, + combineTextItems: disableCombineTextItems !== true, + includeMarkedContent: includeMarkedContent === true + }, { + highWaterMark: TEXT_CONTENT_CHUNK_SIZE, + + size(textContent) { + return textContent.items.length; }
- sink.onPull = () => { - rangeReader.read().then(function ({ + }); + } + + getTextContent(params = {}) { + if (this._transport._htmlForXfa) { + return this.getXfa().then(xfa => { + return _xfa_text.XfaText.textContent(xfa); + }); + } + + const readableStream = this.streamTextContent(params); + return new Promise(function (resolve, reject) { + function pump() { + reader.read().then(function ({ value, done }) { if (done) { - sink.close(); + resolve(textContent); return; }
- (0, _util.assert)((0, _util.isArrayBuffer)(value), "GetRangeReader - expected an ArrayBuffer."); - sink.enqueue(new Uint8Array(value), 1, [value]); - }).catch(reason => { - sink.error(reason); - }); - }; - - sink.onCancel = reason => { - rangeReader.cancel(reason); - sink.ready.catch(readyReason => { - if (this.destroyed) { - return; - } + Object.assign(textContent.styles, value.styles); + textContent.items.push(...value.items); + pump(); + }, reject); + }
- throw readyReason; - }); + const reader = readableStream.getReader(); + const textContent = { + items: [], + styles: Object.create(null) }; + pump(); }); - messageHandler.on("GetDoc", ({ - pdfInfo - }) => { - this._numPages = pdfInfo.numPages; - this._htmlForXfa = pdfInfo.htmlForXfa; - delete pdfInfo.htmlForXfa; + }
- loadingTask._capability.resolve(new PDFDocumentProxy(pdfInfo, this)); - }); - messageHandler.on("DocException", function (ex) { - let reason; + getStructTree() { + return this._structTreePromise ||= this._transport.getStructTree(this._pageIndex); + }
- switch (ex.name) { - case "PasswordException": - reason = new _util.PasswordException(ex.message, ex.code); - break; + _destroy() { + this.destroyed = true; + const waitOn = [];
- case "InvalidPDFException": - reason = new _util.InvalidPDFException(ex.message); - break; + for (const intentState of this._intentStates.values()) { + this._abortOperatorList({ + intentState, + reason: new Error("Page was destroyed."), + force: true + });
- case "MissingPDFException": - reason = new _util.MissingPDFException(ex.message); - break; + if (intentState.opListReadCapability) { + continue; + }
- case "UnexpectedResponseException": - reason = new _util.UnexpectedResponseException(ex.message, ex.status); - break; + for (const internalRenderTask of intentState.renderTasks) { + waitOn.push(internalRenderTask.completed); + internalRenderTask.cancel(); + } + }
- case "UnknownErrorException": - reason = new _util.UnknownErrorException(ex.message, ex.details); - break; + this.objs.clear();
- default: - (0, _util.unreachable)("DocException - expected a valid Error."); - } + for (const bitmap of this._bitmaps) { + bitmap.close(); + }
- loadingTask._capability.reject(reason); - }); - messageHandler.on("PasswordRequest", exception => { - this._passwordCapability = (0, _util.createPromiseCapability)(); + this._bitmaps.clear();
- if (loadingTask.onPassword) { - const updatePassword = password => { - if (password instanceof Error) { - this._passwordCapability.reject(password); - } else { - this._passwordCapability.resolve({ - password - }); - } - }; - - try { - loadingTask.onPassword(updatePassword, exception.code); - } catch (ex) { - this._passwordCapability.reject(ex); - } - } else { - this._passwordCapability.reject(new _util.PasswordException(exception.message, exception.code)); - } + this._annotationPromises.clear();
- return this._passwordCapability.promise; - }); - messageHandler.on("DataLoaded", data => { - loadingTask.onProgress?.({ - loaded: data.length, - total: data.length - }); - this.downloadInfoCapability.resolve(data); - }); - messageHandler.on("StartRenderPage", data => { - if (this.destroyed) { - return; - } + this._jsActionsPromise = null; + this._structTreePromise = null; + this.pendingCleanup = false; + return Promise.all(waitOn); + }
- const page = this.#pageCache.get(data.pageIndex); + cleanup(resetStats = false) { + this.pendingCleanup = true; + return this._tryCleanup(resetStats); + }
- page._startRenderPage(data.transparency, data.cacheKey); - }); - messageHandler.on("commonobj", ([id, type, exportedData]) => { - if (this.destroyed) { - return; - } + _tryCleanup(resetStats = false) { + if (!this.pendingCleanup) { + return false; + }
- if (this.commonObjs.has(id)) { - return; + for (const { + renderTasks, + operatorList + } of this._intentStates.values()) { + if (renderTasks.size > 0 || !operatorList.lastChunk) { + return false; } + }
- switch (type) { - case "Font": - const params = this._params; - - if ("error" in exportedData) { - const exportedError = exportedData.error; - (0, _util.warn)(`Error during font loading: ${exportedError}`); - this.commonObjs.resolve(id, exportedError); - break; - } - - let fontRegistry = null; + this._intentStates.clear();
- if (params.pdfBug && globalThis.FontInspector?.enabled) { - fontRegistry = { - registerFont(font, url) { - globalThis.FontInspector.fontAdded(font, url); - } + this.objs.clear();
- }; - } + this._annotationPromises.clear();
- const font = new _font_loader.FontFaceObject(exportedData, { - isEvalSupported: params.isEvalSupported, - disableFontFace: params.disableFontFace, - ignoreErrors: params.ignoreErrors, - onUnsupportedFeature: this._onUnsupportedFeature.bind(this), - fontRegistry - }); - this.fontLoader.bind(font).catch(reason => { - return messageHandler.sendWithPromise("FontFallback", { - id - }); - }).finally(() => { - if (!params.fontExtraProperties && font.data) { - font.data = null; - } + this._jsActionsPromise = null; + this._structTreePromise = null;
- this.commonObjs.resolve(id, font); - }); - break; + if (resetStats && this._stats) { + this._stats = new _display_utils.StatTimer(); + }
- case "FontPath": - case "Image": - this.commonObjs.resolve(id, exportedData); - break; + for (const bitmap of this._bitmaps) { + bitmap.close(); + }
- default: - throw new Error(`Got unknown common object type ${type}`); - } - }); - messageHandler.on("obj", ([id, pageIndex, type, imageData]) => { - if (this.destroyed) { - return; - } + this._bitmaps.clear();
- const pageProxy = this.#pageCache.get(pageIndex); + this.pendingCleanup = false; + return true; + }
- if (pageProxy.objs.has(id)) { - return; - } + _startRenderPage(transparency, cacheKey) { + const intentState = this._intentStates.get(cacheKey);
- switch (type) { - case "Image": - pageProxy.objs.resolve(id, imageData); - const MAX_IMAGE_SIZE_TO_STORE = 8000000; + if (!intentState) { + return; + }
- if (imageData) { - let length; + if (this._stats) { + this._stats.timeEnd("Page Request"); + }
- if (imageData.bitmap) { - const { - bitmap, - width, - height - } = imageData; - length = width * height * 4; + if (intentState.displayReadyCapability) { + intentState.displayReadyCapability.resolve(transparency); + } + }
- pageProxy._bitmaps.add(bitmap); - } else { - length = imageData.data?.length || 0; - } + _renderPageChunk(operatorListChunk, intentState) { + for (let i = 0, ii = operatorListChunk.length; i < ii; i++) { + intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]); + intentState.operatorList.argsArray.push(operatorListChunk.argsArray[i]); + }
- if (length > MAX_IMAGE_SIZE_TO_STORE) { - pageProxy.cleanupAfterRender = true; - } - } + intentState.operatorList.lastChunk = operatorListChunk.lastChunk;
- break; + for (const internalRenderTask of intentState.renderTasks) { + internalRenderTask.operatorListChanged(); + }
- case "Pattern": - pageProxy.objs.resolve(id, imageData); - break; + if (operatorListChunk.lastChunk) { + this._tryCleanup(); + } + }
- default: - throw new Error(`Got unknown object type ${type}`); - } + _pumpOperatorList({ + renderingIntent, + cacheKey, + annotationStorageMap + }) { + const readableStream = this._transport.messageHandler.sendWithStream("GetOperatorList", { + pageIndex: this._pageIndex, + intent: renderingIntent, + cacheKey, + annotationStorage: annotationStorageMap }); - messageHandler.on("DocProgress", data => { - if (this.destroyed) { - return; - }
- loadingTask.onProgress?.({ - loaded: data.loaded, - total: data.total - }); - }); - messageHandler.on("DocStats", data => { - if (this.destroyed) { - return; - } + const reader = readableStream.getReader();
- this.#docStats = Object.freeze({ - streamTypes: Object.freeze(data.streamTypes), - fontTypes: Object.freeze(data.fontTypes) - }); - }); - messageHandler.on("UnsupportedFeature", this._onUnsupportedFeature.bind(this)); - messageHandler.on("FetchBuiltInCMap", data => { - if (this.destroyed) { - return Promise.reject(new Error("Worker was destroyed.")); - } + const intentState = this._intentStates.get(cacheKey);
- if (!this.CMapReaderFactory) { - return Promise.reject(new Error("CMapReaderFactory not initialized, see the `useWorkerFetch` parameter.")); - } + intentState.streamReader = reader;
- return this.CMapReaderFactory.fetch(data); - }); - messageHandler.on("FetchStandardFontData", data => { - if (this.destroyed) { - return Promise.reject(new Error("Worker was destroyed.")); - } + const pump = () => { + reader.read().then(({ + value, + done + }) => { + if (done) { + intentState.streamReader = null; + return; + }
- if (!this.StandardFontDataFactory) { - return Promise.reject(new Error("StandardFontDataFactory not initialized, see the `useWorkerFetch` parameter.")); - } + if (this._transport.destroyed) { + return; + }
- return this.StandardFontDataFactory.fetch(data); - }); - } + this._renderPageChunk(value, intentState);
- _onUnsupportedFeature({ - featureId - }) { - if (this.destroyed) { - return; - } + pump(); + }, reason => { + intentState.streamReader = null;
- this.loadingTask.onUnsupportedFeature?.(featureId); - } + if (this._transport.destroyed) { + return; + }
- getData() { - return this.messageHandler.sendWithPromise("GetData", null); + if (intentState.operatorList) { + intentState.operatorList.lastChunk = true; + + for (const internalRenderTask of intentState.renderTasks) { + internalRenderTask.operatorListChanged(); + } + + this._tryCleanup(); + } + + if (intentState.displayReadyCapability) { + intentState.displayReadyCapability.reject(reason); + } else if (intentState.opListReadCapability) { + intentState.opListReadCapability.reject(reason); + } else { + throw reason; + } + }); + }; + + pump(); }
- getPage(pageNumber) { - if (!Number.isInteger(pageNumber) || pageNumber <= 0 || pageNumber > this._numPages) { - return Promise.reject(new Error("Invalid page request.")); + _abortOperatorList({ + intentState, + reason, + force = false + }) { + if (!intentState.streamReader) { + return; }
- const pageIndex = pageNumber - 1, - cachedPromise = this.#pagePromises.get(pageIndex); + if (!force) { + if (intentState.renderTasks.size > 0) { + return; + }
- if (cachedPromise) { - return cachedPromise; - } + if (reason instanceof _display_utils.RenderingCancelledException) { + intentState.streamReaderCancelTimeout = setTimeout(() => { + this._abortOperatorList({ + intentState, + reason, + force: true + });
- const promise = this.messageHandler.sendWithPromise("GetPage", { - pageIndex - }).then(pageInfo => { - if (this.destroyed) { - throw new Error("Transport destroyed"); + intentState.streamReaderCancelTimeout = null; + }, RENDERING_CANCELLED_TIMEOUT); + return; } + }
- const page = new PDFPageProxy(pageIndex, pageInfo, this, this._params.ownerDocument, this._params.pdfBug); - this.#pageCache.set(pageIndex, page); - return page; - }); - this.#pagePromises.set(pageIndex, promise); - return promise; - } + intentState.streamReader.cancel(new _util.AbortException(reason.message)).catch(() => {}); + intentState.streamReader = null;
- getPageIndex(ref) { - if (typeof ref !== "object" || ref === null || !Number.isInteger(ref.num) || ref.num < 0 || !Number.isInteger(ref.gen) || ref.gen < 0) { - return Promise.reject(new Error("Invalid pageIndex request.")); + if (this._transport.destroyed) { + return; }
- return this.messageHandler.sendWithPromise("GetPageIndex", { - num: ref.num, - gen: ref.gen - }); - } + for (const [curCacheKey, curIntentState] of this._intentStates) { + if (curIntentState === intentState) { + this._intentStates.delete(curCacheKey);
- getAnnotations(pageIndex, intent) { - return this.messageHandler.sendWithPromise("GetAnnotations", { - pageIndex, - intent - }); - } + break; + } + }
- saveDocument() { - return this.messageHandler.sendWithPromise("SaveDocument", { - isPureXfa: !!this._htmlForXfa, - numPages: this._numPages, - annotationStorage: this.annotationStorage.serializable, - filename: this._fullReader?.filename ?? null - }).finally(() => { - this.annotationStorage.resetModified(); - }); + this.cleanup(); }
- getFieldObjects() { - return this._getFieldObjectsPromise ||= this.messageHandler.sendWithPromise("GetFieldObjects", null); + get stats() { + return this._stats; }
- hasJSActions() { - return this._hasJSActionsPromise ||= this.messageHandler.sendWithPromise("HasJSActions", null); - } +}
- getCalculationOrderIds() { - return this.messageHandler.sendWithPromise("GetCalculationOrderIds", null); - } +exports.PDFPageProxy = PDFPageProxy;
- getDestinations() { - return this.messageHandler.sendWithPromise("GetDestinations", null); +class LoopbackPort { + constructor() { + this._listeners = []; + this._deferred = Promise.resolve(); }
- getDestination(id) { - if (typeof id !== "string") { - return Promise.reject(new Error("Invalid destination request.")); - } + postMessage(obj, transfers) { + const event = { + data: structuredClone(obj, transfers) + };
- return this.messageHandler.sendWithPromise("GetDestination", { - id + this._deferred.then(() => { + for (const listener of this._listeners) { + listener.call(this, event); + } }); }
- getPageLabels() { - return this.messageHandler.sendWithPromise("GetPageLabels", null); + addEventListener(name, listener) { + this._listeners.push(listener); }
- getPageLayout() { - return this.messageHandler.sendWithPromise("GetPageLayout", null); - } + removeEventListener(name, listener) { + const i = this._listeners.indexOf(listener);
- getPageMode() { - return this.messageHandler.sendWithPromise("GetPageMode", null); + this._listeners.splice(i, 1); }
- getViewerPreferences() { - return this.messageHandler.sendWithPromise("GetViewerPreferences", null); + terminate() { + this._listeners.length = 0; }
- getOpenAction() { - return this.messageHandler.sendWithPromise("GetOpenAction", null); - } +}
- getAttachments() { - return this.messageHandler.sendWithPromise("GetAttachments", null); - } +exports.LoopbackPort = LoopbackPort; +const PDFWorkerUtil = { + isWorkerDisabled: false, + fallbackWorkerSrc: null, + fakeWorkerId: 0 +}; +exports.PDFWorkerUtil = PDFWorkerUtil; +;
- getJavaScript() { - return this.messageHandler.sendWithPromise("GetJavaScript", null); - } +class PDFWorker { + static #workerPorts = new WeakMap();
- getDocJSActions() { - return this.messageHandler.sendWithPromise("GetDocJSActions", null); - } + constructor({ + name = null, + port = null, + verbosity = (0, _util.getVerbosityLevel)() + } = {}) { + if (port && PDFWorker.#workerPorts.has(port)) { + throw new Error("Cannot use more than one PDFWorker per port."); + }
- getPageJSActions(pageIndex) { - return this.messageHandler.sendWithPromise("GetPageJSActions", { - pageIndex - }); - } + this.name = name; + this.destroyed = false; + this.verbosity = verbosity; + this._readyCapability = (0, _util.createPromiseCapability)(); + this._port = null; + this._webWorker = null; + this._messageHandler = null;
- getStructTree(pageIndex) { - return this.messageHandler.sendWithPromise("GetStructTree", { - pageIndex - }); - } + if (port) { + PDFWorker.#workerPorts.set(port, this);
- getOutline() { - return this.messageHandler.sendWithPromise("GetOutline", null); - } + this._initializeFromPort(port);
- getOptionalContentConfig() { - return this.messageHandler.sendWithPromise("GetOptionalContentConfig", null).then(results => { - return new _optional_content_config.OptionalContentConfig(results); - }); - } + return; + }
- getPermissions() { - return this.messageHandler.sendWithPromise("GetPermissions", null); + this._initialize(); }
- getMetadata() { - return this.#metadataPromise ||= this.messageHandler.sendWithPromise("GetMetadata", null).then(results => { - return { - info: results[0], - metadata: results[1] ? new _metadata.Metadata(results[1]) : null, - contentDispositionFilename: this._fullReader?.filename ?? null, - contentLength: this._fullReader?.contentLength ?? null - }; - }); + get promise() { + return this._readyCapability.promise; }
- getMarkInfo() { - return this.messageHandler.sendWithPromise("GetMarkInfo", null); + get port() { + return this._port; }
- async startCleanup(keepLoadedFonts = false) { - await this.messageHandler.sendWithPromise("Cleanup", null); + get messageHandler() { + return this._messageHandler; + }
- if (this.destroyed) { - return; - } + _initializeFromPort(port) { + this._port = port; + this._messageHandler = new _message_handler.MessageHandler("main", "worker", port);
- for (const page of this.#pageCache.values()) { - const cleanupSuccessful = page.cleanup(); + this._messageHandler.on("ready", function () {});
- if (!cleanupSuccessful) { - throw new Error(`startCleanup: Page ${page.pageNumber} is currently rendering.`); - } - } + this._readyCapability.resolve(); + }
- this.commonObjs.clear(); + _initialize() { + if (typeof Worker !== "undefined" && !PDFWorkerUtil.isWorkerDisabled && !PDFWorker._mainThreadWorkerMessageHandler) { + let workerSrc = PDFWorker.workerSrc;
- if (!keepLoadedFonts) { - this.fontLoader.clear(); - } + try { + const worker = new Worker(workerSrc); + const messageHandler = new _message_handler.MessageHandler("main", "worker", worker);
- this.#metadataPromise = null; - this._getFieldObjectsPromise = null; - this._hasJSActionsPromise = null; - } + const terminateEarly = () => { + worker.removeEventListener("error", onWorkerError); + messageHandler.destroy(); + worker.terminate();
- get loadingParams() { - const params = this._params; - return (0, _util.shadow)(this, "loadingParams", { - disableAutoFetch: params.disableAutoFetch, - enableXfa: params.enableXfa - }); - } + if (this.destroyed) { + this._readyCapability.reject(new Error("Worker was destroyed")); + } else { + this._setupFakeWorker(); + } + };
-} + const onWorkerError = () => { + if (!this._webWorker) { + terminateEarly(); + } + };
-class PDFObjects { - #objs = Object.create(null); + worker.addEventListener("error", onWorkerError); + messageHandler.on("test", data => { + worker.removeEventListener("error", onWorkerError);
- #ensureObj(objId) { - const obj = this.#objs[objId]; + if (this.destroyed) { + terminateEarly(); + return; + }
- if (obj) { - return obj; - } + if (data) { + this._messageHandler = messageHandler; + this._port = worker; + this._webWorker = worker;
- return this.#objs[objId] = { - capability: (0, _util.createPromiseCapability)(), - data: null - }; - } + this._readyCapability.resolve();
- get(objId, callback = null) { - if (callback) { - const obj = this.#ensureObj(objId); - obj.capability.promise.then(() => callback(obj.data)); - return null; - } + messageHandler.send("configure", { + verbosity: this.verbosity + }); + } else { + this._setupFakeWorker();
- const obj = this.#objs[objId]; + messageHandler.destroy(); + worker.terminate(); + } + }); + messageHandler.on("ready", data => { + worker.removeEventListener("error", onWorkerError);
- if (!obj?.capability.settled) { - throw new Error(`Requesting object that isn't resolved yet ${objId}.`); + if (this.destroyed) { + terminateEarly(); + return; + } + + try { + sendTest(); + } catch (e) { + this._setupFakeWorker(); + } + }); + + const sendTest = () => { + const testObj = new Uint8Array(); + messageHandler.send("test", testObj, [testObj.buffer]); + }; + + sendTest(); + return; + } catch (e) { + (0, _util.info)("The worker has been disabled."); + } }
- return obj.data; + this._setupFakeWorker(); }
- has(objId) { - const obj = this.#objs[objId]; - return obj?.capability.settled || false; - } + _setupFakeWorker() { + if (!PDFWorkerUtil.isWorkerDisabled) { + (0, _util.warn)("Setting up fake worker."); + PDFWorkerUtil.isWorkerDisabled = true; + }
- resolve(objId, data = null) { - const obj = this.#ensureObj(objId); - obj.data = data; - obj.capability.resolve(); - } + PDFWorker._setupFakeWorkerGlobal.then(WorkerMessageHandler => { + if (this.destroyed) { + this._readyCapability.reject(new Error("Worker was destroyed"));
- clear() { - this.#objs = Object.create(null); - } + return; + }
-} + const port = new LoopbackPort(); + this._port = port; + const id = `fake${PDFWorkerUtil.fakeWorkerId++}`; + const workerHandler = new _message_handler.MessageHandler(id + "_worker", id, port); + WorkerMessageHandler.setup(workerHandler, port); + const messageHandler = new _message_handler.MessageHandler(id, id + "_worker", port); + this._messageHandler = messageHandler;
-class RenderTask { - constructor(internalRenderTask) { - this._internalRenderTask = internalRenderTask; - this.onContinue = null; - } + this._readyCapability.resolve();
- get promise() { - return this._internalRenderTask.capability.promise; + messageHandler.send("configure", { + verbosity: this.verbosity + }); + }).catch(reason => { + this._readyCapability.reject(new Error(`Setting up fake worker failed: "${reason.message}".`)); + }); }
- cancel() { - this._internalRenderTask.cancel(); - } + destroy() { + this.destroyed = true;
-} + if (this._webWorker) { + this._webWorker.terminate();
-exports.RenderTask = RenderTask; + this._webWorker = null; + }
-class InternalRenderTask { - static #canvasInUse = new WeakSet(); + PDFWorker.#workerPorts.delete(this._port); + this._port = null;
- constructor({ - callback, - params, - objs, - commonObjs, - annotationCanvasMap, - operatorList, - pageIndex, - canvasFactory, - useRequestAnimationFrame = false, - pdfBug = false, - pageColors = null - }) { - this.callback = callback; - this.params = params; - this.objs = objs; - this.commonObjs = commonObjs; - this.annotationCanvasMap = annotationCanvasMap; - this.operatorListIdx = null; - this.operatorList = operatorList; - this._pageIndex = pageIndex; - this.canvasFactory = canvasFactory; - this._pdfBug = pdfBug; - this.pageColors = pageColors; - this.running = false; - this.graphicsReadyCallback = null; - this.graphicsReady = false; - this._useRequestAnimationFrame = useRequestAnimationFrame === true && typeof window !== "undefined"; - this.cancelled = false; - this.capability = (0, _util.createPromiseCapability)(); - this.task = new RenderTask(this); - this._cancelBound = this.cancel.bind(this); - this._continueBound = this._continue.bind(this); - this._scheduleNextBound = this._scheduleNext.bind(this); - this._nextBound = this._next.bind(this); - this._canvas = params.canvasContext.canvas; - } + if (this._messageHandler) { + this._messageHandler.destroy();
- get completed() { - return this.capability.promise.catch(function () {}); + this._messageHandler = null; + } }
- initializeGraphics({ - transparency = false, - optionalContentConfig - }) { - if (this.cancelled) { - return; + static fromPort(params) { + if (!params?.port) { + throw new Error("PDFWorker.fromPort - invalid method signature."); }
- if (this._canvas) { - if (InternalRenderTask.#canvasInUse.has(this._canvas)) { - throw new Error("Cannot use the same canvas during multiple render() operations. " + "Use different canvas or ensure previous operations were " + "cancelled or completed."); - } + if (this.#workerPorts.has(params.port)) { + return this.#workerPorts.get(params.port); + }
- InternalRenderTask.#canvasInUse.add(this._canvas); + return new PDFWorker(params); + } + + static get workerSrc() { + if (_worker_options.GlobalWorkerOptions.workerSrc) { + return _worker_options.GlobalWorkerOptions.workerSrc; }
- if (this._pdfBug && globalThis.StepperManager?.enabled) { - this.stepper = globalThis.StepperManager.create(this._pageIndex); - this.stepper.init(this.operatorList); - this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint(); + if (PDFWorkerUtil.fallbackWorkerSrc !== null) { + if (!_is_node.isNodeJS) { + (0, _display_utils.deprecated)('No "GlobalWorkerOptions.workerSrc" specified.'); + } + + return PDFWorkerUtil.fallbackWorkerSrc; }
- const { - canvasContext, - viewport, - transform, - imageLayer, - background - } = this.params; - this.gfx = new _canvas.CanvasGraphics(canvasContext, this.commonObjs, this.objs, this.canvasFactory, imageLayer, optionalContentConfig, this.annotationCanvasMap, this.pageColors); - this.gfx.beginDrawing({ - transform, - viewport, - transparency, - background - }); - this.operatorListIdx = 0; - this.graphicsReady = true; + throw new Error('No "GlobalWorkerOptions.workerSrc" specified.'); + }
- if (this.graphicsReadyCallback) { - this.graphicsReadyCallback(); + static get _mainThreadWorkerMessageHandler() { + try { + return globalThis.pdfjsWorker?.WorkerMessageHandler || null; + } catch (ex) { + return null; } }
- cancel(error = null) { - this.running = false; - this.cancelled = true; + static get _setupFakeWorkerGlobal() { + const loader = async () => { + const mainWorkerMessageHandler = this._mainThreadWorkerMessageHandler;
- if (this.gfx) { - this.gfx.endDrawing(); - } + if (mainWorkerMessageHandler) { + return mainWorkerMessageHandler; + }
- if (this._canvas) { - InternalRenderTask.#canvasInUse.delete(this._canvas); - } + await (0, _display_utils.loadScript)(this.workerSrc); + return window.pdfjsWorker.WorkerMessageHandler; + };
- this.callback(error || new _display_utils.RenderingCancelledException(`Rendering cancelled, page ${this._pageIndex + 1}`, "canvas")); + return (0, _util.shadow)(this, "_setupFakeWorkerGlobal", loader()); }
- operatorListChanged() { - if (!this.graphicsReady) { - if (!this.graphicsReadyCallback) { - this.graphicsReadyCallback = this._continueBound; - } - - return; - } - - if (this.stepper) { - this.stepper.updateOperatorList(this.operatorList); - } +}
- if (this.running) { - return; - } +exports.PDFWorker = PDFWorker; +;
- this._continue(); - } +class WorkerTransport { + #docStats = null; + #pageCache = new Map(); + #pagePromises = new Map(); + #metadataPromise = null;
- _continue() { - this.running = true; + constructor(messageHandler, loadingTask, networkStream, params) { + this.messageHandler = messageHandler; + this.loadingTask = loadingTask; + this.commonObjs = new PDFObjects(); + this.fontLoader = new _font_loader.FontLoader({ + docId: loadingTask.docId, + onUnsupportedFeature: this._onUnsupportedFeature.bind(this), + ownerDocument: params.ownerDocument, + styleElement: params.styleElement + }); + this._params = params;
- if (this.cancelled) { - return; + if (!params.useWorkerFetch) { + this.CMapReaderFactory = new params.CMapReaderFactory({ + baseUrl: params.cMapUrl, + isCompressed: params.cMapPacked + }); + this.StandardFontDataFactory = new params.StandardFontDataFactory({ + baseUrl: params.standardFontDataUrl + }); }
- if (this.task.onContinue) { - this.task.onContinue(this._scheduleNextBound); - } else { - this._scheduleNext(); - } + this.destroyed = false; + this.destroyCapability = null; + this._passwordCapability = null; + this._networkStream = networkStream; + this._fullReader = null; + this._lastProgress = null; + this.downloadInfoCapability = (0, _util.createPromiseCapability)(); + this.setupMessageHandler(); }
- _scheduleNext() { - if (this._useRequestAnimationFrame) { - window.requestAnimationFrame(() => { - this._nextBound().catch(this._cancelBound); - }); - } else { - Promise.resolve().then(this._nextBound).catch(this._cancelBound); - } + get annotationStorage() { + return (0, _util.shadow)(this, "annotationStorage", new _annotation_storage.AnnotationStorage()); }
- async _next() { - if (this.cancelled) { - return; - } + get stats() { + return this.#docStats; + }
- this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList, this.operatorListIdx, this._continueBound, this.stepper); + getRenderingIntent(intent, annotationMode = _util.AnnotationMode.ENABLE, printAnnotationStorage = null, isOpList = false) { + let renderingIntent = _util.RenderingIntentFlag.DISPLAY; + let annotationMap = null;
- if (this.operatorListIdx === this.operatorList.argsArray.length) { - this.running = false; + switch (intent) { + case "any": + renderingIntent = _util.RenderingIntentFlag.ANY; + break;
- if (this.operatorList.lastChunk) { - this.gfx.endDrawing(); + case "display": + break;
- if (this._canvas) { - InternalRenderTask.#canvasInUse.delete(this._canvas); - } + case "print": + renderingIntent = _util.RenderingIntentFlag.PRINT; + break;
- this.callback(); - } + default: + (0, _util.warn)(`getRenderingIntent - invalid intent: ${intent}`); } - }
-} + switch (annotationMode) { + case _util.AnnotationMode.DISABLE: + renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_DISABLE; + break;
-const version = '2.14.290'; -exports.version = version; -const build = '38c82357b'; -exports.build = build; + case _util.AnnotationMode.ENABLE: + break;
-/***/ }), -/* 5 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + case _util.AnnotationMode.ENABLE_FORMS: + renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_FORMS; + break;
+ case _util.AnnotationMode.ENABLE_STORAGE: + renderingIntent += _util.RenderingIntentFlag.ANNOTATIONS_STORAGE; + const annotationStorage = renderingIntent & _util.RenderingIntentFlag.PRINT && printAnnotationStorage instanceof _annotation_storage.PrintAnnotationStorage ? printAnnotationStorage : this.annotationStorage; + annotationMap = annotationStorage.serializable; + break;
+ default: + (0, _util.warn)(`getRenderingIntent - invalid annotationMode: ${annotationMode}`); + }
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.StatTimer = exports.RenderingCancelledException = exports.PixelsPerInch = exports.PageViewport = exports.PDFDateString = exports.DOMStandardFontDataFactory = exports.DOMSVGFactory = exports.DOMCanvasFactory = exports.DOMCMapReaderFactory = void 0; -exports.deprecated = deprecated; -exports.getFilenameFromUrl = getFilenameFromUrl; -exports.getPdfFilenameFromUrl = getPdfFilenameFromUrl; -exports.getXfaPageViewport = getXfaPageViewport; -exports.isDataScheme = isDataScheme; -exports.isPdfFile = isPdfFile; -exports.isValidFetchUrl = isValidFetchUrl; -exports.loadScript = loadScript; + if (isOpList) { + renderingIntent += _util.RenderingIntentFlag.OPLIST; + }
-var _base_factory = __w_pdfjs_require__(6); + return { + renderingIntent, + cacheKey: `${renderingIntent}_${_annotation_storage.AnnotationStorage.getHash(annotationMap)}`, + annotationStorageMap: annotationMap + }; + }
-var _util = __w_pdfjs_require__(1); + destroy() { + if (this.destroyCapability) { + return this.destroyCapability.promise; + }
-const SVG_NS = "http://www.w3.org/2000/svg"; + this.destroyed = true; + this.destroyCapability = (0, _util.createPromiseCapability)();
-class PixelsPerInch { - static CSS = 96.0; - static PDF = 72.0; - static PDF_TO_CSS_UNITS = this.CSS / this.PDF; -} + if (this._passwordCapability) { + this._passwordCapability.reject(new Error("Worker was destroyed during onPassword callback")); + }
-exports.PixelsPerInch = PixelsPerInch; + const waitOn = [];
-class DOMCanvasFactory extends _base_factory.BaseCanvasFactory { - constructor({ - ownerDocument = globalThis.document - } = {}) { - super(); - this._document = ownerDocument; - } + for (const page of this.#pageCache.values()) { + waitOn.push(page._destroy()); + }
- _createCanvas(width, height) { - const canvas = this._document.createElement("canvas"); + this.#pageCache.clear(); + this.#pagePromises.clear();
- canvas.width = width; - canvas.height = height; - return canvas; - } + if (this.hasOwnProperty("annotationStorage")) { + this.annotationStorage.resetModified(); + }
-} + const terminated = this.messageHandler.sendWithPromise("Terminate", null); + waitOn.push(terminated); + Promise.all(waitOn).then(() => { + this.commonObjs.clear(); + this.fontLoader.clear(); + this.#metadataPromise = null; + this._getFieldObjectsPromise = null; + this._hasJSActionsPromise = null;
-exports.DOMCanvasFactory = DOMCanvasFactory; + if (this._networkStream) { + this._networkStream.cancelAllRequests(new _util.AbortException("Worker was terminated.")); + }
-async function fetchData(url, asTypedArray = false) { - const response = await fetch(url); + if (this.messageHandler) { + this.messageHandler.destroy(); + this.messageHandler = null; + }
- if (!response.ok) { - throw new Error(response.statusText); + this.destroyCapability.resolve(); + }, this.destroyCapability.reject); + return this.destroyCapability.promise; }
- return asTypedArray ? new Uint8Array(await response.arrayBuffer()) : (0, _util.stringToBytes)(await response.text()); -} + setupMessageHandler() { + const { + messageHandler, + loadingTask + } = this; + messageHandler.on("GetReader", (data, sink) => { + (0, _util.assert)(this._networkStream, "GetReader - no `IPDFStream` instance available."); + this._fullReader = this._networkStream.getFullReader();
-class DOMCMapReaderFactory extends _base_factory.BaseCMapReaderFactory { - _fetchData(url, compressionType) { - return fetchData(url, this.isCompressed).then(data => { - return { - cMapData: data, - compressionType + this._fullReader.onProgress = evt => { + this._lastProgress = { + loaded: evt.loaded, + total: evt.total + }; }; - }); - }
-} + sink.onPull = () => { + this._fullReader.read().then(function ({ + value, + done + }) { + if (done) { + sink.close(); + return; + }
-exports.DOMCMapReaderFactory = DOMCMapReaderFactory; + (0, _util.assert)((0, _util.isArrayBuffer)(value), "GetReader - expected an ArrayBuffer."); + sink.enqueue(new Uint8Array(value), 1, [value]); + }).catch(reason => { + sink.error(reason); + }); + };
-class DOMStandardFontDataFactory extends _base_factory.BaseStandardFontDataFactory { - _fetchData(url) { - return fetchData(url, true); - } + sink.onCancel = reason => { + this._fullReader.cancel(reason);
-} + sink.ready.catch(readyReason => { + if (this.destroyed) { + return; + }
-exports.DOMStandardFontDataFactory = DOMStandardFontDataFactory; + throw readyReason; + }); + }; + }); + messageHandler.on("ReaderHeadersReady", data => { + const headersCapability = (0, _util.createPromiseCapability)(); + const fullReader = this._fullReader; + fullReader.headersReady.then(() => { + if (!fullReader.isStreamingSupported || !fullReader.isRangeSupported) { + if (this._lastProgress) { + loadingTask.onProgress?.(this._lastProgress); + }
-class DOMSVGFactory extends _base_factory.BaseSVGFactory { - _createSVG(type) { - return document.createElementNS(SVG_NS, type); - } + fullReader.onProgress = evt => { + loadingTask.onProgress?.({ + loaded: evt.loaded, + total: evt.total + }); + }; + }
-} + headersCapability.resolve({ + isStreamingSupported: fullReader.isStreamingSupported, + isRangeSupported: fullReader.isRangeSupported, + contentLength: fullReader.contentLength + }); + }, headersCapability.reject); + return headersCapability.promise; + }); + messageHandler.on("GetRangeReader", (data, sink) => { + (0, _util.assert)(this._networkStream, "GetRangeReader - no `IPDFStream` instance available.");
-exports.DOMSVGFactory = DOMSVGFactory; + const rangeReader = this._networkStream.getRangeReader(data.begin, data.end);
-class PageViewport { - constructor({ - viewBox, - scale, - rotation, - offsetX = 0, - offsetY = 0, - dontFlip = false - }) { - this.viewBox = viewBox; - this.scale = scale; - this.rotation = rotation; - this.offsetX = offsetX; - this.offsetY = offsetY; - const centerX = (viewBox[2] + viewBox[0]) / 2; - const centerY = (viewBox[3] + viewBox[1]) / 2; - let rotateA, rotateB, rotateC, rotateD; - rotation %= 360; + if (!rangeReader) { + sink.close(); + return; + }
- if (rotation < 0) { - rotation += 360; - } + sink.onPull = () => { + rangeReader.read().then(function ({ + value, + done + }) { + if (done) { + sink.close(); + return; + }
- switch (rotation) { - case 180: - rotateA = -1; - rotateB = 0; - rotateC = 0; - rotateD = 1; - break; + (0, _util.assert)((0, _util.isArrayBuffer)(value), "GetRangeReader - expected an ArrayBuffer."); + sink.enqueue(new Uint8Array(value), 1, [value]); + }).catch(reason => { + sink.error(reason); + }); + };
- case 90: - rotateA = 0; - rotateB = 1; - rotateC = 1; - rotateD = 0; - break; + sink.onCancel = reason => { + rangeReader.cancel(reason); + sink.ready.catch(readyReason => { + if (this.destroyed) { + return; + }
- case 270: - rotateA = 0; - rotateB = -1; - rotateC = -1; - rotateD = 0; - break; + throw readyReason; + }); + }; + }); + messageHandler.on("GetDoc", ({ + pdfInfo + }) => { + this._numPages = pdfInfo.numPages; + this._htmlForXfa = pdfInfo.htmlForXfa; + delete pdfInfo.htmlForXfa;
- case 0: - rotateA = 1; - rotateB = 0; - rotateC = 0; - rotateD = -1; - break; + loadingTask._capability.resolve(new PDFDocumentProxy(pdfInfo, this)); + }); + messageHandler.on("DocException", function (ex) { + let reason;
- default: - throw new Error("PageViewport: Invalid rotation, must be a multiple of 90 degrees."); - } + switch (ex.name) { + case "PasswordException": + reason = new _util.PasswordException(ex.message, ex.code); + break;
- if (dontFlip) { - rotateC = -rotateC; - rotateD = -rotateD; - } + case "InvalidPDFException": + reason = new _util.InvalidPDFException(ex.message); + break;
- let offsetCanvasX, offsetCanvasY; - let width, height; + case "MissingPDFException": + reason = new _util.MissingPDFException(ex.message); + break;
- if (rotateA === 0) { - offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX; - offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY; - width = Math.abs(viewBox[3] - viewBox[1]) * scale; - height = Math.abs(viewBox[2] - viewBox[0]) * scale; - } else { - offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX; - offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY; - width = Math.abs(viewBox[2] - viewBox[0]) * scale; - height = Math.abs(viewBox[3] - viewBox[1]) * scale; - } + case "UnexpectedResponseException": + reason = new _util.UnexpectedResponseException(ex.message, ex.status); + break;
- this.transform = [rotateA * scale, rotateB * scale, rotateC * scale, rotateD * scale, offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY]; - this.width = width; - this.height = height; - } + case "UnknownErrorException": + reason = new _util.UnknownErrorException(ex.message, ex.details); + break;
- clone({ - scale = this.scale, - rotation = this.rotation, - offsetX = this.offsetX, - offsetY = this.offsetY, - dontFlip = false - } = {}) { - return new PageViewport({ - viewBox: this.viewBox.slice(), - scale, - rotation, - offsetX, - offsetY, - dontFlip + default: + (0, _util.unreachable)("DocException - expected a valid Error."); + } + + loadingTask._capability.reject(reason); }); - } + messageHandler.on("PasswordRequest", exception => { + this._passwordCapability = (0, _util.createPromiseCapability)();
- convertToViewportPoint(x, y) { - return _util.Util.applyTransform([x, y], this.transform); - } + if (loadingTask.onPassword) { + const updatePassword = password => { + if (password instanceof Error) { + this._passwordCapability.reject(password); + } else { + this._passwordCapability.resolve({ + password + }); + } + };
- convertToViewportRectangle(rect) { - const topLeft = _util.Util.applyTransform([rect[0], rect[1]], this.transform); + try { + loadingTask.onPassword(updatePassword, exception.code); + } catch (ex) { + this._passwordCapability.reject(ex); + } + } else { + this._passwordCapability.reject(new _util.PasswordException(exception.message, exception.code)); + }
- const bottomRight = _util.Util.applyTransform([rect[2], rect[3]], this.transform); + return this._passwordCapability.promise; + }); + messageHandler.on("DataLoaded", data => { + loadingTask.onProgress?.({ + loaded: data.length, + total: data.length + }); + this.downloadInfoCapability.resolve(data); + }); + messageHandler.on("StartRenderPage", data => { + if (this.destroyed) { + return; + }
- return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]]; - } + const page = this.#pageCache.get(data.pageIndex);
- convertToPdfPoint(x, y) { - return _util.Util.applyInverseTransform([x, y], this.transform); - } + page._startRenderPage(data.transparency, data.cacheKey); + }); + messageHandler.on("commonobj", ([id, type, exportedData]) => { + if (this.destroyed) { + return; + }
-} + if (this.commonObjs.has(id)) { + return; + }
-exports.PageViewport = PageViewport; + switch (type) { + case "Font": + const params = this._params;
-class RenderingCancelledException extends _util.BaseException { - constructor(msg, type) { - super(msg, "RenderingCancelledException"); - this.type = type; - } + if ("error" in exportedData) { + const exportedError = exportedData.error; + (0, _util.warn)(`Error during font loading: ${exportedError}`); + this.commonObjs.resolve(id, exportedError); + break; + }
-} + let fontRegistry = null;
-exports.RenderingCancelledException = RenderingCancelledException; + if (params.pdfBug && globalThis.FontInspector?.enabled) { + fontRegistry = { + registerFont(font, url) { + globalThis.FontInspector.fontAdded(font, url); + }
-function isDataScheme(url) { - const ii = url.length; - let i = 0; + }; + }
- while (i < ii && url[i].trim() === "") { - i++; - } + const font = new _font_loader.FontFaceObject(exportedData, { + isEvalSupported: params.isEvalSupported, + disableFontFace: params.disableFontFace, + ignoreErrors: params.ignoreErrors, + onUnsupportedFeature: this._onUnsupportedFeature.bind(this), + fontRegistry + }); + this.fontLoader.bind(font).catch(reason => { + return messageHandler.sendWithPromise("FontFallback", { + id + }); + }).finally(() => { + if (!params.fontExtraProperties && font.data) { + font.data = null; + }
- return url.substring(i, i + 5).toLowerCase() === "data:"; -} + this.commonObjs.resolve(id, font); + }); + break;
-function isPdfFile(filename) { - return typeof filename === "string" && /.pdf$/i.test(filename); -} + case "FontPath": + case "Image": + this.commonObjs.resolve(id, exportedData); + break;
-function getFilenameFromUrl(url) { - const anchor = url.indexOf("#"); - const query = url.indexOf("?"); - const end = Math.min(anchor > 0 ? anchor : url.length, query > 0 ? query : url.length); - return url.substring(url.lastIndexOf("/", end) + 1, end); -} + default: + throw new Error(`Got unknown common object type ${type}`); + } + }); + messageHandler.on("obj", ([id, pageIndex, type, imageData]) => { + if (this.destroyed) { + return; + }
-function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") { - if (typeof url !== "string") { - return defaultFilename; - } + const pageProxy = this.#pageCache.get(pageIndex);
- if (isDataScheme(url)) { - (0, _util.warn)('getPdfFilenameFromUrl: ignore "data:"-URL for performance reasons.'); - return defaultFilename; - } + if (pageProxy.objs.has(id)) { + return; + }
- const reURI = /^(?:(?:[^:]+:)?//[^/]+)?([^?#]*)(?[^#]*)?(#.*)?$/; - const reFilename = /[^/?#=]+.pdf\b(?!.*.pdf\b)/i; - const splitURI = reURI.exec(url); - let suggestedFilename = reFilename.exec(splitURI[1]) || reFilename.exec(splitURI[2]) || reFilename.exec(splitURI[3]); + switch (type) { + case "Image": + pageProxy.objs.resolve(id, imageData); + const MAX_IMAGE_SIZE_TO_STORE = 8000000;
- if (suggestedFilename) { - suggestedFilename = suggestedFilename[0]; + if (imageData) { + let length;
- if (suggestedFilename.includes("%")) { - try { - suggestedFilename = reFilename.exec(decodeURIComponent(suggestedFilename))[0]; - } catch (ex) {} - } - } + if (imageData.bitmap) { + const { + bitmap, + width, + height + } = imageData; + length = width * height * 4;
- return suggestedFilename || defaultFilename; -} + pageProxy._bitmaps.add(bitmap); + } else { + length = imageData.data?.length || 0; + }
-class StatTimer { - constructor() { - this.started = Object.create(null); - this.times = []; - } + if (length > MAX_IMAGE_SIZE_TO_STORE) { + pageProxy.cleanupAfterRender = true; + } + }
- time(name) { - if (name in this.started) { - (0, _util.warn)(`Timer is already running for ${name}`); - } + break;
- this.started[name] = Date.now(); - } + case "Pattern": + pageProxy.objs.resolve(id, imageData); + break;
- timeEnd(name) { - if (!(name in this.started)) { - (0, _util.warn)(`Timer has not been started for ${name}`); - } + default: + throw new Error(`Got unknown object type ${type}`); + } + }); + messageHandler.on("DocProgress", data => { + if (this.destroyed) { + return; + }
- this.times.push({ - name, - start: this.started[name], - end: Date.now() + loadingTask.onProgress?.({ + loaded: data.loaded, + total: data.total + }); }); - delete this.started[name]; - } + messageHandler.on("DocStats", data => { + if (this.destroyed) { + return; + }
- toString() { - const outBuf = []; - let longest = 0; + this.#docStats = Object.freeze({ + streamTypes: Object.freeze(data.streamTypes), + fontTypes: Object.freeze(data.fontTypes) + }); + }); + messageHandler.on("UnsupportedFeature", this._onUnsupportedFeature.bind(this)); + messageHandler.on("FetchBuiltInCMap", data => { + if (this.destroyed) { + return Promise.reject(new Error("Worker was destroyed.")); + }
- for (const time of this.times) { - const name = time.name; + if (!this.CMapReaderFactory) { + return Promise.reject(new Error("CMapReaderFactory not initialized, see the `useWorkerFetch` parameter.")); + }
- if (name.length > longest) { - longest = name.length; + return this.CMapReaderFactory.fetch(data); + }); + messageHandler.on("FetchStandardFontData", data => { + if (this.destroyed) { + return Promise.reject(new Error("Worker was destroyed.")); } - }
- for (const time of this.times) { - const duration = time.end - time.start; - outBuf.push(`${time.name.padEnd(longest)} ${duration}ms\n`); - } + if (!this.StandardFontDataFactory) { + return Promise.reject(new Error("StandardFontDataFactory not initialized, see the `useWorkerFetch` parameter.")); + }
- return outBuf.join(""); + return this.StandardFontDataFactory.fetch(data); + }); }
-} + _onUnsupportedFeature({ + featureId + }) { + if (this.destroyed) { + return; + }
-exports.StatTimer = StatTimer; + this.loadingTask.onUnsupportedFeature?.(featureId); + }
-function isValidFetchUrl(url, baseUrl) { - try { - const { - protocol - } = baseUrl ? new URL(url, baseUrl) : new URL(url); - return protocol === "http:" || protocol === "https:"; - } catch (ex) { - return false; + getData() { + return this.messageHandler.sendWithPromise("GetData", null); } -}
-function loadScript(src, removeScriptElement = false) { - return new Promise((resolve, reject) => { - const script = document.createElement("script"); - script.src = src; + getPage(pageNumber) { + if (!Number.isInteger(pageNumber) || pageNumber <= 0 || pageNumber > this._numPages) { + return Promise.reject(new Error("Invalid page request.")); + }
- script.onload = function (evt) { - if (removeScriptElement) { - script.remove(); - } + const pageIndex = pageNumber - 1, + cachedPromise = this.#pagePromises.get(pageIndex);
- resolve(evt); - }; + if (cachedPromise) { + return cachedPromise; + }
- script.onerror = function () { - reject(new Error(`Cannot load script at: ${script.src}`)); - }; + const promise = this.messageHandler.sendWithPromise("GetPage", { + pageIndex + }).then(pageInfo => { + if (this.destroyed) { + throw new Error("Transport destroyed"); + }
- (document.head || document.documentElement).appendChild(script); - }); -} + const page = new PDFPageProxy(pageIndex, pageInfo, this, this._params.ownerDocument, this._params.pdfBug); + this.#pageCache.set(pageIndex, page); + return page; + }); + this.#pagePromises.set(pageIndex, promise); + return promise; + }
-function deprecated(details) { - console.log("Deprecated API usage: " + details); -} - -let pdfDateStringRegex; - -class PDFDateString { - static toDateObject(input) { - if (!input || typeof input !== "string") { - return null; - } - - if (!pdfDateStringRegex) { - pdfDateStringRegex = new RegExp("^D:" + "(\d{4})" + "(\d{2})?" + "(\d{2})?" + "(\d{2})?" + "(\d{2})?" + "(\d{2})?" + "([Z|+|-])?" + "(\d{2})?" + "'?" + "(\d{2})?" + "'?"); + getPageIndex(ref) { + if (typeof ref !== "object" || ref === null || !Number.isInteger(ref.num) || ref.num < 0 || !Number.isInteger(ref.gen) || ref.gen < 0) { + return Promise.reject(new Error("Invalid pageIndex request.")); }
- const matches = pdfDateStringRegex.exec(input); + return this.messageHandler.sendWithPromise("GetPageIndex", { + num: ref.num, + gen: ref.gen + }); + }
- if (!matches) { - return null; - } + getAnnotations(pageIndex, intent) { + return this.messageHandler.sendWithPromise("GetAnnotations", { + pageIndex, + intent + }); + }
- const year = parseInt(matches[1], 10); - let month = parseInt(matches[2], 10); - month = month >= 1 && month <= 12 ? month - 1 : 0; - let day = parseInt(matches[3], 10); - day = day >= 1 && day <= 31 ? day : 1; - let hour = parseInt(matches[4], 10); - hour = hour >= 0 && hour <= 23 ? hour : 0; - let minute = parseInt(matches[5], 10); - minute = minute >= 0 && minute <= 59 ? minute : 0; - let second = parseInt(matches[6], 10); - second = second >= 0 && second <= 59 ? second : 0; - const universalTimeRelation = matches[7] || "Z"; - let offsetHour = parseInt(matches[8], 10); - offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0; - let offsetMinute = parseInt(matches[9], 10) || 0; - offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0; + saveDocument() { + return this.messageHandler.sendWithPromise("SaveDocument", { + isPureXfa: !!this._htmlForXfa, + numPages: this._numPages, + annotationStorage: this.annotationStorage.serializable, + filename: this._fullReader?.filename ?? null + }).finally(() => { + this.annotationStorage.resetModified(); + }); + }
- if (universalTimeRelation === "-") { - hour += offsetHour; - minute += offsetMinute; - } else if (universalTimeRelation === "+") { - hour -= offsetHour; - minute -= offsetMinute; - } + getFieldObjects() { + return this._getFieldObjectsPromise ||= this.messageHandler.sendWithPromise("GetFieldObjects", null); + }
- return new Date(Date.UTC(year, month, day, hour, minute, second)); + hasJSActions() { + return this._hasJSActionsPromise ||= this.messageHandler.sendWithPromise("HasJSActions", null); }
-} + getCalculationOrderIds() { + return this.messageHandler.sendWithPromise("GetCalculationOrderIds", null); + }
-exports.PDFDateString = PDFDateString; + getDestinations() { + return this.messageHandler.sendWithPromise("GetDestinations", null); + }
-function getXfaPageViewport(xfaPage, { - scale = 1, - rotation = 0 -}) { - const { - width, - height - } = xfaPage.attributes.style; - const viewBox = [0, 0, parseInt(width), parseInt(height)]; - return new PageViewport({ - viewBox, - scale, - rotation - }); -} + getDestination(id) { + if (typeof id !== "string") { + return Promise.reject(new Error("Invalid destination request.")); + }
-/***/ }), -/* 6 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + return this.messageHandler.sendWithPromise("GetDestination", { + id + }); + }
+ getPageLabels() { + return this.messageHandler.sendWithPromise("GetPageLabels", null); + }
+ getPageLayout() { + return this.messageHandler.sendWithPromise("GetPageLayout", null); + }
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.BaseStandardFontDataFactory = exports.BaseSVGFactory = exports.BaseCanvasFactory = exports.BaseCMapReaderFactory = void 0; + getPageMode() { + return this.messageHandler.sendWithPromise("GetPageMode", null); + }
-var _util = __w_pdfjs_require__(1); + getViewerPreferences() { + return this.messageHandler.sendWithPromise("GetViewerPreferences", null); + }
-class BaseCanvasFactory { - constructor() { - if (this.constructor === BaseCanvasFactory) { - (0, _util.unreachable)("Cannot initialize BaseCanvasFactory."); - } + getOpenAction() { + return this.messageHandler.sendWithPromise("GetOpenAction", null); }
- create(width, height) { - if (width <= 0 || height <= 0) { - throw new Error("Invalid canvas size"); - } + getAttachments() { + return this.messageHandler.sendWithPromise("GetAttachments", null); + }
- const canvas = this._createCanvas(width, height); + getJavaScript() { + return this.messageHandler.sendWithPromise("GetJavaScript", null); + }
- return { - canvas, - context: canvas.getContext("2d") - }; + getDocJSActions() { + return this.messageHandler.sendWithPromise("GetDocJSActions", null); }
- reset(canvasAndContext, width, height) { - if (!canvasAndContext.canvas) { - throw new Error("Canvas is not specified"); - } + getPageJSActions(pageIndex) { + return this.messageHandler.sendWithPromise("GetPageJSActions", { + pageIndex + }); + }
- if (width <= 0 || height <= 0) { - throw new Error("Invalid canvas size"); - } + getStructTree(pageIndex) { + return this.messageHandler.sendWithPromise("GetStructTree", { + pageIndex + }); + }
- canvasAndContext.canvas.width = width; - canvasAndContext.canvas.height = height; + getOutline() { + return this.messageHandler.sendWithPromise("GetOutline", null); }
- destroy(canvasAndContext) { - if (!canvasAndContext.canvas) { - throw new Error("Canvas is not specified"); - } + getOptionalContentConfig() { + return this.messageHandler.sendWithPromise("GetOptionalContentConfig", null).then(results => { + return new _optional_content_config.OptionalContentConfig(results); + }); + }
- canvasAndContext.canvas.width = 0; - canvasAndContext.canvas.height = 0; - canvasAndContext.canvas = null; - canvasAndContext.context = null; + getPermissions() { + return this.messageHandler.sendWithPromise("GetPermissions", null); }
- _createCanvas(width, height) { - (0, _util.unreachable)("Abstract method `_createCanvas` called."); + getMetadata() { + return this.#metadataPromise ||= this.messageHandler.sendWithPromise("GetMetadata", null).then(results => { + return { + info: results[0], + metadata: results[1] ? new _metadata.Metadata(results[1]) : null, + contentDispositionFilename: this._fullReader?.filename ?? null, + contentLength: this._fullReader?.contentLength ?? null + }; + }); }
-} + getMarkInfo() { + return this.messageHandler.sendWithPromise("GetMarkInfo", null); + }
-exports.BaseCanvasFactory = BaseCanvasFactory; + async startCleanup(keepLoadedFonts = false) { + await this.messageHandler.sendWithPromise("Cleanup", null);
-class BaseCMapReaderFactory { - constructor({ - baseUrl = null, - isCompressed = false - }) { - if (this.constructor === BaseCMapReaderFactory) { - (0, _util.unreachable)("Cannot initialize BaseCMapReaderFactory."); + if (this.destroyed) { + return; }
- this.baseUrl = baseUrl; - this.isCompressed = isCompressed; - } + for (const page of this.#pageCache.values()) { + const cleanupSuccessful = page.cleanup();
- async fetch({ - name - }) { - if (!this.baseUrl) { - throw new Error('The CMap "baseUrl" parameter must be specified, ensure that ' + 'the "cMapUrl" and "cMapPacked" API parameters are provided.'); + if (!cleanupSuccessful) { + throw new Error(`startCleanup: Page ${page.pageNumber} is currently rendering.`); + } }
- if (!name) { - throw new Error("CMap name must be specified."); + this.commonObjs.clear(); + + if (!keepLoadedFonts) { + this.fontLoader.clear(); }
- const url = this.baseUrl + name + (this.isCompressed ? ".bcmap" : ""); - const compressionType = this.isCompressed ? _util.CMapCompressionType.BINARY : _util.CMapCompressionType.NONE; - return this._fetchData(url, compressionType).catch(reason => { - throw new Error(`Unable to load ${this.isCompressed ? "binary " : ""}CMap at: ${url}`); - }); + this.#metadataPromise = null; + this._getFieldObjectsPromise = null; + this._hasJSActionsPromise = null; }
- _fetchData(url, compressionType) { - (0, _util.unreachable)("Abstract method `_fetchData` called."); + get loadingParams() { + const params = this._params; + return (0, _util.shadow)(this, "loadingParams", { + disableAutoFetch: params.disableAutoFetch, + enableXfa: params.enableXfa + }); }
}
-exports.BaseCMapReaderFactory = BaseCMapReaderFactory; +class PDFObjects { + #objs = Object.create(null);
-class BaseStandardFontDataFactory { - constructor({ - baseUrl = null - }) { - if (this.constructor === BaseStandardFontDataFactory) { - (0, _util.unreachable)("Cannot initialize BaseStandardFontDataFactory."); + #ensureObj(objId) { + const obj = this.#objs[objId]; + + if (obj) { + return obj; }
- this.baseUrl = baseUrl; + return this.#objs[objId] = { + capability: (0, _util.createPromiseCapability)(), + data: null + }; }
- async fetch({ - filename - }) { - if (!this.baseUrl) { - throw new Error('The standard font "baseUrl" parameter must be specified, ensure that ' + 'the "standardFontDataUrl" API parameter is provided.'); + get(objId, callback = null) { + if (callback) { + const obj = this.#ensureObj(objId); + obj.capability.promise.then(() => callback(obj.data)); + return null; }
- if (!filename) { - throw new Error("Font filename must be specified."); + const obj = this.#objs[objId]; + + if (!obj?.capability.settled) { + throw new Error(`Requesting object that isn't resolved yet ${objId}.`); }
- const url = `${this.baseUrl}${filename}`; - return this._fetchData(url).catch(reason => { - throw new Error(`Unable to load font data at: ${url}`); - }); + return obj.data; }
- _fetchData(url) { - (0, _util.unreachable)("Abstract method `_fetchData` called."); + has(objId) { + const obj = this.#objs[objId]; + return obj?.capability.settled || false; }
-} - -exports.BaseStandardFontDataFactory = BaseStandardFontDataFactory; - -class BaseSVGFactory { - constructor() { - if (this.constructor === BaseSVGFactory) { - (0, _util.unreachable)("Cannot initialize BaseSVGFactory."); - } + resolve(objId, data = null) { + const obj = this.#ensureObj(objId); + obj.data = data; + obj.capability.resolve(); }
- create(width, height) { - if (width <= 0 || height <= 0) { - throw new Error("Invalid SVG dimensions"); - } + clear() { + this.#objs = Object.create(null); + }
- const svg = this._createSVG("svg:svg"); +}
- svg.setAttribute("version", "1.1"); - svg.setAttribute("width", `${width}px`); - svg.setAttribute("height", `${height}px`); - svg.setAttribute("preserveAspectRatio", "none"); - svg.setAttribute("viewBox", `0 0 ${width} ${height}`); - return svg; +class RenderTask { + constructor(internalRenderTask) { + this._internalRenderTask = internalRenderTask; + this.onContinue = null; }
- createElement(type) { - if (typeof type !== "string") { - throw new Error("Invalid SVG element type"); - } - - return this._createSVG(type); + get promise() { + return this._internalRenderTask.capability.promise; }
- _createSVG(type) { - (0, _util.unreachable)("Abstract method `_createSVG` called."); + cancel() { + this._internalRenderTask.cancel(); }
}
-exports.BaseSVGFactory = BaseSVGFactory; - -/***/ }), -/* 7 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.FontLoader = exports.FontFaceObject = void 0; +exports.RenderTask = RenderTask;
-var _util = __w_pdfjs_require__(1); +class InternalRenderTask { + static #canvasInUse = new WeakSet();
-class BaseFontLoader { constructor({ - docId, - onUnsupportedFeature, - ownerDocument = globalThis.document, - styleElement = null + callback, + params, + objs, + commonObjs, + annotationCanvasMap, + operatorList, + pageIndex, + canvasFactory, + useRequestAnimationFrame = false, + pdfBug = false, + pageColors = null }) { - if (this.constructor === BaseFontLoader) { - (0, _util.unreachable)("Cannot initialize BaseFontLoader."); - } - - this.docId = docId; - this._onUnsupportedFeature = onUnsupportedFeature; - this._document = ownerDocument; - this.nativeFontFaces = []; - this.styleElement = null; + this.callback = callback; + this.params = params; + this.objs = objs; + this.commonObjs = commonObjs; + this.annotationCanvasMap = annotationCanvasMap; + this.operatorListIdx = null; + this.operatorList = operatorList; + this._pageIndex = pageIndex; + this.canvasFactory = canvasFactory; + this._pdfBug = pdfBug; + this.pageColors = pageColors; + this.running = false; + this.graphicsReadyCallback = null; + this.graphicsReady = false; + this._useRequestAnimationFrame = useRequestAnimationFrame === true && typeof window !== "undefined"; + this.cancelled = false; + this.capability = (0, _util.createPromiseCapability)(); + this.task = new RenderTask(this); + this._cancelBound = this.cancel.bind(this); + this._continueBound = this._continue.bind(this); + this._scheduleNextBound = this._scheduleNext.bind(this); + this._nextBound = this._next.bind(this); + this._canvas = params.canvasContext.canvas; }
- addNativeFontFace(nativeFontFace) { - this.nativeFontFaces.push(nativeFontFace); - - this._document.fonts.add(nativeFontFace); + get completed() { + return this.capability.promise.catch(function () {}); }
- insertRule(rule) { - let styleElement = this.styleElement; + initializeGraphics({ + transparency = false, + optionalContentConfig + }) { + if (this.cancelled) { + return; + }
- if (!styleElement) { - styleElement = this.styleElement = this._document.createElement("style"); - styleElement.id = `PDFJS_FONT_STYLE_TAG_${this.docId}`; + if (this._canvas) { + if (InternalRenderTask.#canvasInUse.has(this._canvas)) { + throw new Error("Cannot use the same canvas during multiple render() operations. " + "Use different canvas or ensure previous operations were " + "cancelled or completed."); + }
- this._document.documentElement.getElementsByTagName("head")[0].appendChild(styleElement); + InternalRenderTask.#canvasInUse.add(this._canvas); }
- const styleSheet = styleElement.sheet; - styleSheet.insertRule(rule, styleSheet.cssRules.length); - } - - clear() { - for (const nativeFontFace of this.nativeFontFaces) { - this._document.fonts.delete(nativeFontFace); + if (this._pdfBug && globalThis.StepperManager?.enabled) { + this.stepper = globalThis.StepperManager.create(this._pageIndex); + this.stepper.init(this.operatorList); + this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint(); }
- this.nativeFontFaces.length = 0; + const { + canvasContext, + viewport, + transform, + imageLayer, + background + } = this.params; + this.gfx = new _canvas.CanvasGraphics(canvasContext, this.commonObjs, this.objs, this.canvasFactory, imageLayer, optionalContentConfig, this.annotationCanvasMap, this.pageColors); + this.gfx.beginDrawing({ + transform, + viewport, + transparency, + background + }); + this.operatorListIdx = 0; + this.graphicsReady = true;
- if (this.styleElement) { - this.styleElement.remove(); - this.styleElement = null; + if (this.graphicsReadyCallback) { + this.graphicsReadyCallback(); } }
- async bind(font) { - if (font.attached || font.missingFile) { - return; - } - - font.attached = true; + cancel(error = null) { + this.running = false; + this.cancelled = true;
- if (this.isFontLoadingAPISupported) { - const nativeFontFace = font.createNativeFontFace(); + if (this.gfx) { + this.gfx.endDrawing(); + }
- if (nativeFontFace) { - this.addNativeFontFace(nativeFontFace); + if (this._canvas) { + InternalRenderTask.#canvasInUse.delete(this._canvas); + }
- try { - await nativeFontFace.loaded; - } catch (ex) { - this._onUnsupportedFeature({ - featureId: _util.UNSUPPORTED_FEATURES.errorFontLoadNative - }); + this.callback(error || new _display_utils.RenderingCancelledException(`Rendering cancelled, page ${this._pageIndex + 1}`, "canvas")); + }
- (0, _util.warn)(`Failed to load font '${nativeFontFace.family}': '${ex}'.`); - font.disableFontFace = true; - throw ex; - } + operatorListChanged() { + if (!this.graphicsReady) { + if (!this.graphicsReadyCallback) { + this.graphicsReadyCallback = this._continueBound; }
return; }
- const rule = font.createFontFaceRule(); + if (this.stepper) { + this.stepper.updateOperatorList(this.operatorList); + }
- if (rule) { - this.insertRule(rule); + if (this.running) { + return; + }
- if (this.isSyncFontLoadingSupported) { - return; - } + this._continue(); + }
- await new Promise(resolve => { - const request = this._queueLoadingCallback(resolve); + _continue() { + this.running = true;
- this._prepareFontLoadEvent([rule], [font], request); - }); + if (this.cancelled) { + return; + } + + if (this.task.onContinue) { + this.task.onContinue(this._scheduleNextBound); + } else { + this._scheduleNext(); } }
- _queueLoadingCallback(callback) { - (0, _util.unreachable)("Abstract method `_queueLoadingCallback`."); - } - - get isFontLoadingAPISupported() { - const hasFonts = !!this._document?.fonts; - return (0, _util.shadow)(this, "isFontLoadingAPISupported", hasFonts); - } - - get isSyncFontLoadingSupported() { - (0, _util.unreachable)("Abstract method `isSyncFontLoadingSupported`."); - } - - get _loadTestFont() { - (0, _util.unreachable)("Abstract method `_loadTestFont`."); - } - - _prepareFontLoadEvent(rules, fontsToLoad, request) { - (0, _util.unreachable)("Abstract method `_prepareFontLoadEvent`."); - } - -} - -let FontLoader; -exports.FontLoader = FontLoader; -{ - exports.FontLoader = FontLoader = class MozcentralFontLoader extends BaseFontLoader { - get isSyncFontLoadingSupported() { - return (0, _util.shadow)(this, "isSyncFontLoadingSupported", true); - } - - }; -} - -class FontFaceObject { - constructor(translatedData, { - isEvalSupported = true, - disableFontFace = false, - ignoreErrors = false, - onUnsupportedFeature, - fontRegistry = null - }) { - this.compiledGlyphs = Object.create(null); - - for (const i in translatedData) { - this[i] = translatedData[i]; - } - - this.isEvalSupported = isEvalSupported !== false; - this.disableFontFace = disableFontFace === true; - this.ignoreErrors = ignoreErrors === true; - this._onUnsupportedFeature = onUnsupportedFeature; - this.fontRegistry = fontRegistry; - } - - createNativeFontFace() { - if (!this.data || this.disableFontFace) { - return null; - } - - let nativeFontFace; - - if (!this.cssFontInfo) { - nativeFontFace = new FontFace(this.loadedName, this.data, {}); - } else { - const css = { - weight: this.cssFontInfo.fontWeight - }; - - if (this.cssFontInfo.italicAngle) { - css.style = `oblique ${this.cssFontInfo.italicAngle}deg`; - } - - nativeFontFace = new FontFace(this.cssFontInfo.fontFamily, this.data, css); - } - - if (this.fontRegistry) { - this.fontRegistry.registerFont(this); - } - - return nativeFontFace; - } - - createFontFaceRule() { - if (!this.data || this.disableFontFace) { - return null; - } - - const data = (0, _util.bytesToString)(this.data); - const url = `url(data:${this.mimetype};base64,${btoa(data)});`; - let rule; - - if (!this.cssFontInfo) { - rule = `@font-face {font-family:"${this.loadedName}";src:${url}}`; + _scheduleNext() { + if (this._useRequestAnimationFrame) { + window.requestAnimationFrame(() => { + this._nextBound().catch(this._cancelBound); + }); } else { - let css = `font-weight: ${this.cssFontInfo.fontWeight};`; - - if (this.cssFontInfo.italicAngle) { - css += `font-style: oblique ${this.cssFontInfo.italicAngle}deg;`; - } - - rule = `@font-face {font-family:"${this.cssFontInfo.fontFamily}";${css}src:${url}}`; - } - - if (this.fontRegistry) { - this.fontRegistry.registerFont(this, url); + Promise.resolve().then(this._nextBound).catch(this._cancelBound); } - - return rule; }
- getPathGenerator(objs, character) { - if (this.compiledGlyphs[character] !== undefined) { - return this.compiledGlyphs[character]; - } - - let cmds; - - try { - cmds = objs.get(this.loadedName + "_path_" + character); - } catch (ex) { - if (!this.ignoreErrors) { - throw ex; - } - - this._onUnsupportedFeature({ - featureId: _util.UNSUPPORTED_FEATURES.errorFontGetPath - }); - - (0, _util.warn)(`getPathGenerator - ignoring character: "${ex}".`); - return this.compiledGlyphs[character] = function (c, size) {}; + async _next() { + if (this.cancelled) { + return; }
- if (this.isEvalSupported && _util.FeatureTest.isEvalSupported) { - const jsBuf = []; + this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList, this.operatorListIdx, this._continueBound, this.stepper);
- for (const current of cmds) { - const args = current.args !== undefined ? current.args.join(",") : ""; - jsBuf.push("c.", current.cmd, "(", args, ");\n"); - } + if (this.operatorListIdx === this.operatorList.argsArray.length) { + this.running = false;
- return this.compiledGlyphs[character] = new Function("c", "size", jsBuf.join("")); - } + if (this.operatorList.lastChunk) { + this.gfx.endDrawing();
- return this.compiledGlyphs[character] = function (c, size) { - for (const current of cmds) { - if (current.cmd === "scale") { - current.args = [size, -size]; + if (this._canvas) { + InternalRenderTask.#canvasInUse.delete(this._canvas); }
- c[current.cmd].apply(c, current.args); + this.callback(); } - }; + } }
}
-exports.FontFaceObject = FontFaceObject; +const version = '2.15.305'; +exports.version = version; +const build = '2a386eff9'; +exports.build = build;
/***/ }), -/* 8 */ +/* 7 */ /***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
@@ -4252,12 +4073,14 @@ exports.FontFaceObject = FontFaceObject; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.AnnotationStorage = void 0; - -var _murmurhash = __w_pdfjs_require__(9); +exports.PrintAnnotationStorage = exports.AnnotationStorage = void 0;
var _util = __w_pdfjs_require__(1);
+var _editor = __w_pdfjs_require__(8); + +var _murmurhash = __w_pdfjs_require__(10); + class AnnotationStorage { constructor() { this._storage = new Map(); @@ -4280,6 +4103,14 @@ class AnnotationStorage { return this._storage.get(key); }
+ removeKey(key) { + this._storage.delete(key); + + if (this._storage.size === 0) { + this.resetModified(); + } + } + setValue(key, value) { const obj = this._storage.get(key);
@@ -4299,7 +4130,7 @@ class AnnotationStorage { }
if (modified) { - this._setModified(); + this.#setModified(); } }
@@ -4311,7 +4142,7 @@ class AnnotationStorage { return this._storage.size; }
- _setModified() { + #setModified() { if (!this._modified) { this._modified = true;
@@ -4331,15 +4162,37 @@ class AnnotationStorage { } }
+ get print() { + return new PrintAnnotationStorage(this); + } + get serializable() { - return this._storage.size > 0 ? this._storage : null; + if (this._storage.size === 0) { + return null; + } + + const clone = new Map(); + + for (const [key, val] of this._storage) { + const serialized = val instanceof _editor.AnnotationEditor ? val.serialize() : val; + + if (serialized) { + clone.set(key, serialized); + } + } + + return clone; }
- get hash() { + static getHash(map) { + if (!map) { + return ""; + } + const hash = new _murmurhash.MurmurHash3_64();
- for (const [key, value] of this._storage) { - hash.update(`${key}:${JSON.stringify(value)}`); + for (const [key, val] of map) { + hash.update(`${key}:${JSON.stringify(val)}`); }
return hash.hexdigest(); @@ -4349,8 +4202,28 @@ class AnnotationStorage {
exports.AnnotationStorage = AnnotationStorage;
+class PrintAnnotationStorage extends AnnotationStorage { + #serializable = null; + + constructor(parent) { + super(); + this.#serializable = structuredClone(parent.serializable); + } + + get print() { + (0, _util.unreachable)("Should not call PrintAnnotationStorage.print"); + } + + get serializable() { + return this.#serializable; + } + +} + +exports.PrintAnnotationStorage = PrintAnnotationStorage; + /***/ }), -/* 9 */ +/* 8 */ /***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
@@ -4358,4213 +4231,7193 @@ exports.AnnotationStorage = AnnotationStorage; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.MurmurHash3_64 = void 0; +exports.AnnotationEditor = void 0; + +var _tools = __w_pdfjs_require__(9);
var _util = __w_pdfjs_require__(1);
-const SEED = 0xc3d2e1f0; -const MASK_HIGH = 0xffff0000; -const MASK_LOW = 0xffff; +class AnnotationEditor { + #boundFocusin = this.focusin.bind(this); + #boundFocusout = this.focusout.bind(this); + #hasBeenSelected = false; + #isEditing = false; + #isInEditMode = false; + #zIndex = AnnotationEditor._zIndex++; + static _colorManager = new _tools.ColorManager(); + static _zIndex = 1;
-class MurmurHash3_64 { - constructor(seed) { - this.h1 = seed ? seed & 0xffffffff : SEED; - this.h2 = seed ? seed & 0xffffffff : SEED; + constructor(parameters) { + if (this.constructor === AnnotationEditor) { + (0, _util.unreachable)("Cannot initialize AnnotationEditor."); + } + + this.parent = parameters.parent; + this.id = parameters.id; + this.width = this.height = null; + this.pageIndex = parameters.parent.pageIndex; + this.name = parameters.name; + this.div = null; + const [width, height] = this.parent.viewportBaseDimensions; + this.x = parameters.x / width; + this.y = parameters.y / height; + this.rotation = this.parent.viewport.rotation; + this.isAttachedToDOM = false; }
- update(input) { - let data, length; + static get _defaultLineColor() { + return (0, _util.shadow)(this, "_defaultLineColor", this._colorManager.getHexCode("CanvasText")); + }
- if (typeof input === "string") { - data = new Uint8Array(input.length * 2); - length = 0; + setInBackground() { + this.div.style.zIndex = 0; + }
- for (let i = 0, ii = input.length; i < ii; i++) { - const code = input.charCodeAt(i); + setInForeground() { + this.div.style.zIndex = this.#zIndex; + }
- if (code <= 0xff) { - data[length++] = code; - } else { - data[length++] = code >>> 8; - data[length++] = code & 0xff; - } - } - } else if ((0, _util.isArrayBuffer)(input)) { - data = input.slice(); - length = data.byteLength; + focusin(event) { + if (!this.#hasBeenSelected) { + this.parent.setSelected(this); } else { - throw new Error("Wrong data format in MurmurHash3_64_update. " + "Input must be a string or array."); + this.#hasBeenSelected = false; } + }
- const blockCounts = length >> 2; - const tailLength = length - blockCounts * 4; - const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts); - let k1 = 0, - k2 = 0; - let h1 = this.h1, - h2 = this.h2; - const C1 = 0xcc9e2d51, - C2 = 0x1b873593; - const C1_LOW = C1 & MASK_LOW, - C2_LOW = C2 & MASK_LOW; + focusout(event) { + if (!this.isAttachedToDOM) { + return; + }
- for (let i = 0; i < blockCounts; i++) { - if (i & 1) { - k1 = dataUint32[i]; - k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; - k1 = k1 << 15 | k1 >>> 17; - k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; - h1 ^= k1; - h1 = h1 << 13 | h1 >>> 19; - h1 = h1 * 5 + 0xe6546b64; - } else { - k2 = dataUint32[i]; - k2 = k2 * C1 & MASK_HIGH | k2 * C1_LOW & MASK_LOW; - k2 = k2 << 15 | k2 >>> 17; - k2 = k2 * C2 & MASK_HIGH | k2 * C2_LOW & MASK_LOW; - h2 ^= k2; - h2 = h2 << 13 | h2 >>> 19; - h2 = h2 * 5 + 0xe6546b64; - } + const target = event.relatedTarget; + + if (target?.closest(`#${this.id}`)) { + return; }
- k1 = 0; + event.preventDefault();
- switch (tailLength) { - case 3: - k1 ^= data[blockCounts * 4 + 2] << 16; + if (!this.parent.isMultipleSelection) { + this.commitOrRemove(); + } + }
- case 2: - k1 ^= data[blockCounts * 4 + 1] << 8; + commitOrRemove() { + if (this.isEmpty()) { + this.remove(); + } else { + this.commit(); + } + }
- case 1: - k1 ^= data[blockCounts * 4]; - k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; - k1 = k1 << 15 | k1 >>> 17; - k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; + dragstart(event) { + const rect = this.parent.div.getBoundingClientRect(); + this.startX = event.clientX - rect.x; + this.startY = event.clientY - rect.y; + event.dataTransfer.setData("text/plain", this.id); + event.dataTransfer.effectAllowed = "move"; + }
- if (blockCounts & 1) { - h1 ^= k1; - } else { - h2 ^= k1; - } + setAt(x, y, tx, ty) { + const [width, height] = this.parent.viewportBaseDimensions; + [tx, ty] = this.screenToPageTranslation(tx, ty); + this.x = (x + tx) / width; + this.y = (y + ty) / height; + this.div.style.left = `${100 * this.x}%`; + this.div.style.top = `${100 * this.y}%`; + } + + translate(x, y) { + const [width, height] = this.parent.viewportBaseDimensions; + [x, y] = this.screenToPageTranslation(x, y); + this.x += x / width; + this.y += y / height; + this.div.style.left = `${100 * this.x}%`; + this.div.style.top = `${100 * this.y}%`; + } + + screenToPageTranslation(x, y) { + const { + rotation + } = this.parent.viewport; + + switch (rotation) { + case 90: + return [y, -x]; + + case 180: + return [-x, -y];
+ case 270: + return [-y, x]; + + default: + return [x, y]; } + }
- this.h1 = h1; - this.h2 = h2; + setDims(width, height) { + const [parentWidth, parentHeight] = this.parent.viewportBaseDimensions; + this.div.style.width = `${100 * width / parentWidth}%`; + this.div.style.height = `${100 * height / parentHeight}%`; }
- hexdigest() { - let h1 = this.h1, - h2 = this.h2; - h1 ^= h2 >>> 1; - h1 = h1 * 0xed558ccd & MASK_HIGH | h1 * 0x8ccd & MASK_LOW; - h2 = h2 * 0xff51afd7 & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16; - h1 ^= h2 >>> 1; - h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW; - h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16; - h1 ^= h2 >>> 1; - const hex1 = (h1 >>> 0).toString(16), - hex2 = (h2 >>> 0).toString(16); - return hex1.padStart(8, "0") + hex2.padStart(8, "0"); + getInitialTranslation() { + return [0, 0]; }
-} + render() { + this.div = document.createElement("div"); + this.div.setAttribute("data-editor-rotation", (360 - this.rotation) % 360); + this.div.className = this.name; + this.div.setAttribute("id", this.id); + this.div.setAttribute("tabIndex", 0); + this.setInForeground(); + this.div.addEventListener("focusin", this.#boundFocusin); + this.div.addEventListener("focusout", this.#boundFocusout); + const [tx, ty] = this.getInitialTranslation(); + this.translate(tx, ty); + (0, _tools.bindEvents)(this, this.div, ["dragstart", "pointerdown"]); + return this.div; + } + + pointerdown(event) { + if (event.button !== 0) { + event.preventDefault(); + } + + if (event.ctrlKey || event.shiftKey) { + this.parent.toggleSelected(this); + } else { + this.parent.setSelected(this); + }
-exports.MurmurHash3_64 = MurmurHash3_64; + this.#hasBeenSelected = true; + }
-/***/ }), -/* 10 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + getRect(tx, ty) { + const [parentWidth, parentHeight] = this.parent.viewportBaseDimensions; + const [pageWidth, pageHeight] = this.parent.pageDimensions; + const shiftX = pageWidth * tx / parentWidth; + const shiftY = pageHeight * ty / parentHeight; + const x = this.x * pageWidth; + const y = this.y * pageHeight; + const width = this.width * pageWidth; + const height = this.height * pageHeight;
+ switch (this.rotation) { + case 0: + return [x + shiftX, pageHeight - y - shiftY - height, x + shiftX + width, pageHeight - y - shiftY];
+ case 90: + return [x + shiftY, pageHeight - y + shiftX, x + shiftY + height, pageHeight - y + shiftX + width];
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.CanvasGraphics = void 0; + case 180: + return [x - shiftX - width, pageHeight - y + shiftY, x - shiftX, pageHeight - y + shiftY + height];
-var _util = __w_pdfjs_require__(1); + case 270: + return [x - shiftY - height, pageHeight - y - shiftX - width, x - shiftY, pageHeight - y - shiftX];
-var _pattern_helper = __w_pdfjs_require__(11); + default: + throw new Error("Invalid rotation"); + } + }
-var _image_utils = __w_pdfjs_require__(12); + getRectInCurrentCoords(rect, pageHeight) { + const [x1, y1, x2, y2] = rect; + const width = x2 - x1; + const height = y2 - y1;
-var _is_node = __w_pdfjs_require__(3); + switch (this.rotation) { + case 0: + return [x1, pageHeight - y2, width, height];
-var _display_utils = __w_pdfjs_require__(5); + case 90: + return [x1, pageHeight - y1, height, width];
-const MIN_FONT_SIZE = 16; -const MAX_FONT_SIZE = 100; -const MAX_GROUP_SIZE = 4096; -const EXECUTION_TIME = 15; -const EXECUTION_STEPS = 10; -const COMPILE_TYPE3_GLYPHS = true; -const MAX_SIZE_TO_COMPILE = 1000; -const FULL_CHUNK_HEIGHT = 16; -const LINEWIDTH_SCALE_FACTOR = 1.000001; + case 180: + return [x2, pageHeight - y1, width, height];
-function mirrorContextOperations(ctx, destCtx) { - if (ctx._removeMirroring) { - throw new Error("Context is already forwarding operations."); + case 270: + return [x2, pageHeight - y2, height, width]; + + default: + throw new Error("Invalid rotation"); + } }
- ctx.__originalSave = ctx.save; - ctx.__originalRestore = ctx.restore; - ctx.__originalRotate = ctx.rotate; - ctx.__originalScale = ctx.scale; - ctx.__originalTranslate = ctx.translate; - ctx.__originalTransform = ctx.transform; - ctx.__originalSetTransform = ctx.setTransform; - ctx.__originalResetTransform = ctx.resetTransform; - ctx.__originalClip = ctx.clip; - ctx.__originalMoveTo = ctx.moveTo; - ctx.__originalLineTo = ctx.lineTo; - ctx.__originalBezierCurveTo = ctx.bezierCurveTo; - ctx.__originalRect = ctx.rect; - ctx.__originalClosePath = ctx.closePath; - ctx.__originalBeginPath = ctx.beginPath; + onceAdded() {}
- ctx._removeMirroring = () => { - ctx.save = ctx.__originalSave; - ctx.restore = ctx.__originalRestore; - ctx.rotate = ctx.__originalRotate; - ctx.scale = ctx.__originalScale; - ctx.translate = ctx.__originalTranslate; - ctx.transform = ctx.__originalTransform; - ctx.setTransform = ctx.__originalSetTransform; - ctx.resetTransform = ctx.__originalResetTransform; - ctx.clip = ctx.__originalClip; - ctx.moveTo = ctx.__originalMoveTo; - ctx.lineTo = ctx.__originalLineTo; - ctx.bezierCurveTo = ctx.__originalBezierCurveTo; - ctx.rect = ctx.__originalRect; - ctx.closePath = ctx.__originalClosePath; - ctx.beginPath = ctx.__originalBeginPath; - delete ctx._removeMirroring; - }; + isEmpty() { + return false; + }
- ctx.save = function ctxSave() { - destCtx.save(); + enableEditMode() { + this.#isInEditMode = true; + }
- this.__originalSave(); - }; + disableEditMode() { + this.#isInEditMode = false; + }
- ctx.restore = function ctxRestore() { - destCtx.restore(); + isInEditMode() { + return this.#isInEditMode; + }
- this.__originalRestore(); - }; + shouldGetKeyboardEvents() { + return false; + }
- ctx.translate = function ctxTranslate(x, y) { - destCtx.translate(x, y); + needsToBeRebuilt() { + return this.div && !this.isAttachedToDOM; + }
- this.__originalTranslate(x, y); - }; + rebuild() { + this.div?.addEventListener("focusin", this.#boundFocusin); + }
- ctx.scale = function ctxScale(x, y) { - destCtx.scale(x, y); + serialize() { + (0, _util.unreachable)("An editor must be serializable"); + }
- this.__originalScale(x, y); - }; + static deserialize(data, parent) { + const editor = new this.prototype.constructor({ + parent, + id: parent.getNextId() + }); + editor.rotation = data.rotation; + const [pageWidth, pageHeight] = parent.pageDimensions; + const [x, y, width, height] = editor.getRectInCurrentCoords(data.rect, pageHeight); + editor.x = x / pageWidth; + editor.y = y / pageHeight; + editor.width = width / pageWidth; + editor.height = height / pageHeight; + return editor; + }
- ctx.transform = function ctxTransform(a, b, c, d, e, f) { - destCtx.transform(a, b, c, d, e, f); + remove() { + this.div.removeEventListener("focusin", this.#boundFocusin); + this.div.removeEventListener("focusout", this.#boundFocusout);
- this.__originalTransform(a, b, c, d, e, f); - }; + if (!this.isEmpty()) { + this.commit(); + }
- ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) { - destCtx.setTransform(a, b, c, d, e, f); + this.parent.remove(this); + }
- this.__originalSetTransform(a, b, c, d, e, f); - }; + select() { + this.div?.classList.add("selectedEditor"); + }
- ctx.resetTransform = function ctxResetTransform() { - destCtx.resetTransform(); + unselect() { + this.div?.classList.remove("selectedEditor"); + }
- this.__originalResetTransform(); - }; + updateParams(type, value) {}
- ctx.rotate = function ctxRotate(angle) { - destCtx.rotate(angle); + disableEditing() {}
- this.__originalRotate(angle); - }; + enableEditing() {}
- ctx.clip = function ctxRotate(rule) { - destCtx.clip(rule); + getIdForTextLayer() { + return this.id; + }
- this.__originalClip(rule); - }; + get propertiesToUpdate() { + return {}; + }
- ctx.moveTo = function (x, y) { - destCtx.moveTo(x, y); + get contentDiv() { + return this.div; + }
- this.__originalMoveTo(x, y); - }; + get isEditing() { + return this.#isEditing; + }
- ctx.lineTo = function (x, y) { - destCtx.lineTo(x, y); + set isEditing(value) { + this.#isEditing = value;
- this.__originalLineTo(x, y); - }; + if (value) { + this.parent.setSelected(this); + this.parent.setActiveEditor(this); + } else { + this.parent.setActiveEditor(null); + } + }
- ctx.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) { - destCtx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); +}
- this.__originalBezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); - }; +exports.AnnotationEditor = AnnotationEditor;
- ctx.rect = function (x, y, width, height) { - destCtx.rect(x, y, width, height); +/***/ }), +/* 9 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- this.__originalRect(x, y, width, height); - };
- ctx.closePath = function () { - destCtx.closePath();
- this.__originalClosePath(); - }; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.KeyboardManager = exports.CommandManager = exports.ColorManager = exports.AnnotationEditorUIManager = void 0; +exports.bindEvents = bindEvents;
- ctx.beginPath = function () { - destCtx.beginPath(); +var _util = __w_pdfjs_require__(1);
- this.__originalBeginPath(); - }; +var _display_utils = __w_pdfjs_require__(4); + +function bindEvents(obj, element, names) { + for (const name of names) { + element.addEventListener(name, obj[name].bind(obj)); + } }
-function addContextCurrentTransform(ctx) { - if (ctx._transformStack) { - ctx._transformStack = []; +class IdManager { + #id = 0; + + getId() { + return `${_util.AnnotationEditorPrefix}${this.#id++}`; }
- if (ctx.mozCurrentTransform) { - return; +} + +class CommandManager { + #commands = []; + #maxSize; + #position = -1; + + constructor(maxSize = 128) { + this.#maxSize = maxSize; }
- ctx._originalSave = ctx.save; - ctx._originalRestore = ctx.restore; - ctx._originalRotate = ctx.rotate; - ctx._originalScale = ctx.scale; - ctx._originalTranslate = ctx.translate; - ctx._originalTransform = ctx.transform; - ctx._originalSetTransform = ctx.setTransform; - ctx._originalResetTransform = ctx.resetTransform; - ctx._transformMatrix = ctx._transformMatrix || [1, 0, 0, 1, 0, 0]; - ctx._transformStack = []; + add({ + cmd, + undo, + mustExec, + type = NaN, + overwriteIfSameType = false, + keepUndo = false + }) { + if (mustExec) { + cmd(); + }
- try { - const desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(ctx), "lineWidth"); - ctx._setLineWidth = desc.set; - ctx._getLineWidth = desc.get; - Object.defineProperty(ctx, "lineWidth", { - set: function setLineWidth(width) { - this._setLineWidth(width * LINEWIDTH_SCALE_FACTOR); - }, - get: function getLineWidth() { - return this._getLineWidth(); - } - }); - } catch (_) {} + const save = { + cmd, + undo, + type + };
- Object.defineProperty(ctx, "mozCurrentTransform", { - get: function getCurrentTransform() { - return this._transformMatrix; - } - }); - Object.defineProperty(ctx, "mozCurrentTransformInverse", { - get: function getCurrentTransformInverse() { - const [a, b, c, d, e, f] = this._transformMatrix; - const ad_bc = a * d - b * c; - const bc_ad = b * c - a * d; - return [d / ad_bc, b / bc_ad, c / bc_ad, a / ad_bc, (d * e - c * f) / bc_ad, (b * e - a * f) / ad_bc]; + if (this.#position === -1) { + this.#position = 0; + this.#commands.push(save); + return; } - }); - - ctx.save = function ctxSave() { - const old = this._transformMatrix; - - this._transformStack.push(old);
- this._transformMatrix = old.slice(0, 6); - - this._originalSave(); - }; + if (overwriteIfSameType && this.#commands[this.#position].type === type) { + if (keepUndo) { + save.undo = this.#commands[this.#position].undo; + }
- ctx.restore = function ctxRestore() { - if (this._transformStack.length === 0) { - (0, _util.warn)("Tried to restore a ctx when the stack was already empty."); + this.#commands[this.#position] = save; + return; }
- const prev = this._transformStack.pop(); + const next = this.#position + 1;
- if (prev) { - this._transformMatrix = prev; + if (next === this.#maxSize) { + this.#commands.splice(0, 1); + } else { + this.#position = next;
- this._originalRestore(); + if (next < this.#commands.length) { + this.#commands.splice(next); + } } - };
- ctx.translate = function ctxTranslate(x, y) { - const m = this._transformMatrix; - m[4] = m[0] * x + m[2] * y + m[4]; - m[5] = m[1] * x + m[3] * y + m[5]; + this.#commands.push(save); + }
- this._originalTranslate(x, y); - }; + undo() { + if (this.#position === -1) { + return; + }
- ctx.scale = function ctxScale(x, y) { - const m = this._transformMatrix; - m[0] *= x; - m[1] *= x; - m[2] *= y; - m[3] *= y; + this.#commands[this.#position].undo(); + this.#position -= 1; + }
- this._originalScale(x, y); - }; + redo() { + if (this.#position < this.#commands.length - 1) { + this.#position += 1; + this.#commands[this.#position].cmd(); + } + }
- ctx.transform = function ctxTransform(a, b, c, d, e, f) { - const m = this._transformMatrix; - this._transformMatrix = [m[0] * a + m[2] * b, m[1] * a + m[3] * b, m[0] * c + m[2] * d, m[1] * c + m[3] * d, m[0] * e + m[2] * f + m[4], m[1] * e + m[3] * f + m[5]]; + hasSomethingToUndo() { + return this.#position !== -1; + }
- ctx._originalTransform(a, b, c, d, e, f); - }; + hasSomethingToRedo() { + return this.#position < this.#commands.length - 1; + }
- ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) { - this._transformMatrix = [a, b, c, d, e, f]; + destroy() { + this.#commands = null; + }
- ctx._originalSetTransform(a, b, c, d, e, f); - }; +}
- ctx.resetTransform = function ctxResetTransform() { - this._transformMatrix = [1, 0, 0, 1, 0, 0]; +exports.CommandManager = CommandManager;
- ctx._originalResetTransform(); - }; +class KeyboardManager { + constructor(callbacks) { + this.buffer = []; + this.callbacks = new Map(); + this.allKeys = new Set(); + const isMac = KeyboardManager.platform.isMac;
- ctx.rotate = function ctxRotate(angle) { - const cosValue = Math.cos(angle); - const sinValue = Math.sin(angle); - const m = this._transformMatrix; - this._transformMatrix = [m[0] * cosValue + m[2] * sinValue, m[1] * cosValue + m[3] * sinValue, m[0] * -sinValue + m[2] * cosValue, m[1] * -sinValue + m[3] * cosValue, m[4], m[5]]; + for (const [keys, callback] of callbacks) { + for (const key of keys) { + const isMacKey = key.startsWith("mac+");
- this._originalRotate(angle); - }; -} + if (isMac && isMacKey) { + this.callbacks.set(key.slice(4), callback); + this.allKeys.add(key.split("+").at(-1)); + } else if (!isMac && !isMacKey) { + this.callbacks.set(key, callback); + this.allKeys.add(key.split("+").at(-1)); + } + } + } + }
-class CachedCanvases { - constructor(canvasFactory) { - this.canvasFactory = canvasFactory; - this.cache = Object.create(null); + static get platform() { + const platform = typeof navigator !== "undefined" ? navigator.platform : ""; + return (0, _util.shadow)(this, "platform", { + isWin: platform.includes("Win"), + isMac: platform.includes("Mac") + }); }
- getCanvas(id, width, height, trackTransform) { - let canvasEntry; + #serialize(event) { + if (event.altKey) { + this.buffer.push("alt"); + }
- if (this.cache[id] !== undefined) { - canvasEntry = this.cache[id]; - this.canvasFactory.reset(canvasEntry, width, height); - canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0); - } else { - canvasEntry = this.canvasFactory.create(width, height); - this.cache[id] = canvasEntry; + if (event.ctrlKey) { + this.buffer.push("ctrl"); }
- if (trackTransform) { - addContextCurrentTransform(canvasEntry.context); + if (event.metaKey) { + this.buffer.push("meta"); }
- return canvasEntry; - } + if (event.shiftKey) { + this.buffer.push("shift"); + }
- delete(id) { - delete this.cache[id]; + this.buffer.push(event.key); + const str = this.buffer.join("+"); + this.buffer.length = 0; + return str; }
- clear() { - for (const id in this.cache) { - const canvasEntry = this.cache[id]; - this.canvasFactory.destroy(canvasEntry); - delete this.cache[id]; + exec(self, event) { + if (!this.allKeys.has(event.key)) { + return; + } + + const callback = this.callbacks.get(this.#serialize(event)); + + if (!callback) { + return; } + + callback.bind(self)(); + event.preventDefault(); }
}
-function drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH) { - const [a, b, c, d, tx, ty] = ctx.mozCurrentTransform; +exports.KeyboardManager = KeyboardManager;
- if (b === 0 && c === 0) { - const tlX = destX * a + tx; - const rTlX = Math.round(tlX); - const tlY = destY * d + ty; - const rTlY = Math.round(tlY); - const brX = (destX + destW) * a + tx; - const rWidth = Math.abs(Math.round(brX) - rTlX) || 1; - const brY = (destY + destH) * d + ty; - const rHeight = Math.abs(Math.round(brY) - rTlY) || 1; - ctx.setTransform(Math.sign(a), 0, 0, Math.sign(d), rTlX, rTlY); - ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rWidth, rHeight); - ctx.setTransform(a, b, c, d, tx, ty); - return [rWidth, rHeight]; - } +class ClipboardManager { + #elements = null;
- if (a === 0 && d === 0) { - const tlX = destY * c + tx; - const rTlX = Math.round(tlX); - const tlY = destX * b + ty; - const rTlY = Math.round(tlY); - const brX = (destY + destH) * c + tx; - const rWidth = Math.abs(Math.round(brX) - rTlX) || 1; - const brY = (destX + destW) * b + ty; - const rHeight = Math.abs(Math.round(brY) - rTlY) || 1; - ctx.setTransform(0, Math.sign(b), Math.sign(c), 0, rTlX, rTlY); - ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rHeight, rWidth); - ctx.setTransform(a, b, c, d, tx, ty); - return [rHeight, rWidth]; - } + copy(element) { + if (!element) { + return; + }
- ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH); - const scaleX = Math.hypot(a, b); - const scaleY = Math.hypot(c, d); - return [scaleX * destW, scaleY * destH]; -} + if (Array.isArray(element)) { + this.#elements = element.map(el => el.serialize()); + } else { + this.#elements = [element.serialize()]; + }
-function compileType3Glyph(imgData) { - const { - width, - height - } = imgData; + this.#elements = this.#elements.filter(el => !!el);
- if (!COMPILE_TYPE3_GLYPHS || width > MAX_SIZE_TO_COMPILE || height > MAX_SIZE_TO_COMPILE) { - return null; + if (this.#elements.length === 0) { + this.#elements = null; + } }
- const POINT_TO_PROCESS_LIMIT = 1000; - const POINT_TYPES = new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]); - const width1 = width + 1; - let points = new Uint8Array(width1 * (height + 1)); - let i, j, j0; - const lineSize = width + 7 & ~7; - let data = new Uint8Array(lineSize * height), - pos = 0; + paste() { + return this.#elements; + }
- for (const elem of imgData.data) { - let mask = 128; + isEmpty() { + return this.#elements === null; + }
- while (mask > 0) { - data[pos++] = elem & mask ? 0 : 255; - mask >>= 1; - } + destroy() { + this.#elements = null; }
- let count = 0; - pos = 0; +}
- if (data[pos] !== 0) { - points[0] = 1; - ++count; +class ColorManager { + static _colorsMapping = new Map([["CanvasText", [0, 0, 0]], ["Canvas", [255, 255, 255]]]); + + get _colors() { + const colors = new Map([["CanvasText", null], ["Canvas", null]]); + (0, _display_utils.getColorValues)(colors); + return (0, _util.shadow)(this, "_colors", colors); }
- for (j = 1; j < width; j++) { - if (data[pos] !== data[pos + 1]) { - points[j] = data[pos] ? 2 : 1; - ++count; + convert(color) { + const rgb = (0, _display_utils.getRGB)(color); + + if (!window.matchMedia("(forced-colors: active)").matches) { + return rgb; }
- pos++; - } + for (const [name, RGB] of this._colors) { + if (RGB.every((x, i) => x === rgb[i])) { + return ColorManager._colorsMapping.get(name); + } + }
- if (data[pos] !== 0) { - points[j] = 2; - ++count; + return rgb; }
- for (i = 1; i < height; i++) { - pos = i * lineSize; - j0 = i * width1; + getHexCode(name) { + const rgb = this._colors.get(name);
- if (data[pos - lineSize] !== data[pos]) { - points[j0] = data[pos] ? 1 : 8; - ++count; + if (!rgb) { + return name; }
- let sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0); + return _util.Util.makeHexColor(...rgb); + }
- for (j = 1; j < width; j++) { - sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + (data[pos - lineSize + 1] ? 8 : 0); +}
- if (POINT_TYPES[sum]) { - points[j0 + j] = POINT_TYPES[sum]; - ++count; - } +exports.ColorManager = ColorManager;
- pos++; - } +class AnnotationEditorUIManager { + #activeEditor = null; + #allEditors = new Map(); + #allLayers = new Map(); + #clipboardManager = new ClipboardManager(); + #commandManager = new CommandManager(); + #currentPageIndex = 0; + #editorTypes = null; + #eventBus = null; + #idManager = new IdManager(); + #isEnabled = false; + #mode = _util.AnnotationEditorType.NONE; + #selectedEditors = new Set(); + #boundKeydown = this.keydown.bind(this); + #boundOnEditingAction = this.onEditingAction.bind(this); + #boundOnPageChanging = this.onPageChanging.bind(this); + #boundOnTextLayerRendered = this.onTextLayerRendered.bind(this); + #previousStates = { + isEditing: false, + isEmpty: true, + hasEmptyClipboard: true, + hasSomethingToUndo: false, + hasSomethingToRedo: false, + hasSelectedEditor: false + }; + #container = null; + static _keyboardManager = new KeyboardManager([[["ctrl+a", "mac+meta+a"], AnnotationEditorUIManager.prototype.selectAll], [["ctrl+c", "mac+meta+c"], AnnotationEditorUIManager.prototype.copy], [["ctrl+v", "mac+meta+v"], AnnotationEditorUIManager.prototype.paste], [["ctrl+x", "mac+meta+x"], AnnotationEditorUIManager.prototype.cut], [["ctrl+z", "mac+meta+z"], AnnotationEditorUIManager.prototype.undo], [["ctrl+y", "ctrl+shift+Z", "mac+meta+shift+Z"], AnnotationEditorUIManager.prototype.red [...]
- if (data[pos - lineSize] !== data[pos]) { - points[j0 + j] = data[pos] ? 2 : 4; - ++count; - } + constructor(container, eventBus) { + this.#container = container; + this.#eventBus = eventBus;
- if (count > POINT_TO_PROCESS_LIMIT) { - return null; - } - } + this.#eventBus._on("editingaction", this.#boundOnEditingAction);
- pos = lineSize * (height - 1); - j0 = i * width1; + this.#eventBus._on("pagechanging", this.#boundOnPageChanging);
- if (data[pos] !== 0) { - points[j0] = 8; - ++count; + this.#eventBus._on("textlayerrendered", this.#boundOnTextLayerRendered); }
- for (j = 1; j < width; j++) { - if (data[pos] !== data[pos + 1]) { - points[j0 + j] = data[pos] ? 4 : 8; - ++count; + destroy() { + this.#removeKeyboardManager(); + + this.#eventBus._off("editingaction", this.#boundOnEditingAction); + + this.#eventBus._off("pagechanging", this.#boundOnPageChanging); + + this.#eventBus._off("textlayerrendered", this.#boundOnTextLayerRendered); + + for (const layer of this.#allLayers.values()) { + layer.destroy(); }
- pos++; + this.#allLayers.clear(); + this.#allEditors.clear(); + this.#activeEditor = null; + this.#selectedEditors.clear(); + this.#clipboardManager.destroy(); + this.#commandManager.destroy(); }
- if (data[pos] !== 0) { - points[j0 + j] = 4; - ++count; + onPageChanging({ + pageNumber + }) { + this.#currentPageIndex = pageNumber - 1; }
- if (count > POINT_TO_PROCESS_LIMIT) { - return null; + onTextLayerRendered({ + pageNumber + }) { + const pageIndex = pageNumber - 1; + const layer = this.#allLayers.get(pageIndex); + layer?.onTextLayerRendered(); }
- const steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]); - let path, outlines, coords; + focusMainContainer() { + this.#container.focus(); + }
- if (!_is_node.isNodeJS) { - path = new Path2D(); - } else { - outlines = []; + #addKeyboardManager() { + this.#container.addEventListener("keydown", this.#boundKeydown); }
- for (i = 0; count && i <= height; i++) { - let p = i * width1; - const end = p + width; + #removeKeyboardManager() { + this.#container.removeEventListener("keydown", this.#boundKeydown); + }
- while (p < end && !points[p]) { - p++; + keydown(event) { + if (!this.getActive()?.shouldGetKeyboardEvents()) { + AnnotationEditorUIManager._keyboardManager.exec(this, event); } + }
- if (p === end) { - continue; + onEditingAction(details) { + if (["undo", "redo", "cut", "copy", "paste", "delete", "selectAll"].includes(details.name)) { + this[details.name](); } + }
- if (path) { - path.moveTo(p % width1, i); - } else { - coords = [p % width1, i]; - } + #dispatchUpdateStates(details) { + const hasChanged = Object.entries(details).some(([key, value]) => this.#previousStates[key] !== value);
- const p0 = p; - let type = points[p]; + if (hasChanged) { + this.#eventBus.dispatch("annotationeditorstateschanged", { + source: this, + details: Object.assign(this.#previousStates, details) + }); + } + }
- do { - const step = steps[type]; + #dispatchUpdateUI(details) { + this.#eventBus.dispatch("annotationeditorparamschanged", { + source: this, + details + }); + }
- do { - p += step; - } while (!points[p]); + setEditingState(isEditing) { + if (isEditing) { + this.#addKeyboardManager(); + this.#dispatchUpdateStates({ + isEditing: this.#mode !== _util.AnnotationEditorType.NONE, + isEmpty: this.#isEmpty(), + hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(), + hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(), + hasSelectedEditor: false, + hasEmptyClipboard: this.#clipboardManager.isEmpty() + }); + } else { + this.#removeKeyboardManager(); + this.#dispatchUpdateStates({ + isEditing: false + }); + } + }
- const pp = points[p]; + registerEditorTypes(types) { + this.#editorTypes = types;
- if (pp !== 5 && pp !== 10) { - type = pp; - points[p] = 0; - } else { - type = pp & 0x33 * type >> 4; - points[p] &= type >> 2 | type << 2; - } + for (const editorType of this.#editorTypes) { + this.#dispatchUpdateUI(editorType.defaultPropertiesToUpdate); + } + }
- if (path) { - path.lineTo(p % width1, p / width1 | 0); - } else { - coords.push(p % width1, p / width1 | 0); - } + getId() { + return this.#idManager.getId(); + }
- if (!points[p]) { - --count; - } - } while (p0 !== p); + addLayer(layer) { + this.#allLayers.set(layer.pageIndex, layer);
- if (!path) { - outlines.push(coords); + if (this.#isEnabled) { + layer.enable(); + } else { + layer.disable(); } - - --i; }
- data = null; - points = null; + removeLayer(layer) { + this.#allLayers.delete(layer.pageIndex); + }
- const drawOutline = function (c) { - c.save(); - c.scale(1 / width, -1 / height); - c.translate(0, -height); + updateMode(mode) { + this.#mode = mode;
- if (path) { - c.fill(path); + if (mode === _util.AnnotationEditorType.NONE) { + this.setEditingState(false); + this.#disableAll(); } else { - c.beginPath(); - - for (const o of outlines) { - c.moveTo(o[0], o[1]); + this.setEditingState(true); + this.#enableAll();
- for (let l = 2, ll = o.length; l < ll; l += 2) { - c.lineTo(o[l], o[l + 1]); - } + for (const layer of this.#allLayers.values()) { + layer.updateMode(mode); } + } + }
- c.fill(); + updateToolbar(mode) { + if (mode === this.#mode) { + return; }
- c.beginPath(); - c.restore(); - }; + this.#eventBus.dispatch("switchannotationeditormode", { + source: this, + mode + }); + }
- return drawOutline; -} + updateParams(type, value) { + for (const editor of this.#selectedEditors) { + editor.updateParams(type, value); + }
-class CanvasExtraState { - constructor(width, height) { - this.alphaIsShape = false; - this.fontSize = 0; - this.fontSizeScale = 1; - this.textMatrix = _util.IDENTITY_MATRIX; - this.textMatrixScale = 1; - this.fontMatrix = _util.FONT_IDENTITY_MATRIX; - this.leading = 0; - this.x = 0; - this.y = 0; - this.lineX = 0; - this.lineY = 0; - this.charSpacing = 0; - this.wordSpacing = 0; - this.textHScale = 1; - this.textRenderingMode = _util.TextRenderingMode.FILL; - this.textRise = 0; - this.fillColor = "#000000"; - this.strokeColor = "#000000"; - this.patternFill = false; - this.fillAlpha = 1; - this.strokeAlpha = 1; - this.lineWidth = 1; - this.activeSMask = null; - this.transferMaps = null; - this.startNewPathAndClipBox([0, 0, width, height]); + for (const editorType of this.#editorTypes) { + editorType.updateDefaultParams(type, value); + } }
- clone() { - const clone = Object.create(this); - clone.clipBox = this.clipBox.slice(); - return clone; - } + #enableAll() { + if (!this.#isEnabled) { + this.#isEnabled = true;
- setCurrentPoint(x, y) { - this.x = x; - this.y = y; + for (const layer of this.#allLayers.values()) { + layer.enable(); + } + } }
- updatePathMinMax(transform, x, y) { - [x, y] = _util.Util.applyTransform([x, y], transform); - this.minX = Math.min(this.minX, x); - this.minY = Math.min(this.minY, y); - this.maxX = Math.max(this.maxX, x); - this.maxY = Math.max(this.maxY, y); + #disableAll() { + this.unselectAll(); + + if (this.#isEnabled) { + this.#isEnabled = false; + + for (const layer of this.#allLayers.values()) { + layer.disable(); + } + } }
- updateRectMinMax(transform, rect) { - const p1 = _util.Util.applyTransform(rect, transform); + getEditors(pageIndex) { + const editors = [];
- const p2 = _util.Util.applyTransform(rect.slice(2), transform); + for (const editor of this.#allEditors.values()) { + if (editor.pageIndex === pageIndex) { + editors.push(editor); + } + }
- this.minX = Math.min(this.minX, p1[0], p2[0]); - this.minY = Math.min(this.minY, p1[1], p2[1]); - this.maxX = Math.max(this.maxX, p1[0], p2[0]); - this.maxY = Math.max(this.maxY, p1[1], p2[1]); + return editors; }
- updateScalingPathMinMax(transform, minMax) { - _util.Util.scaleMinMax(transform, minMax); + getEditor(id) { + return this.#allEditors.get(id); + }
- this.minX = Math.min(this.minX, minMax[0]); - this.maxX = Math.max(this.maxX, minMax[1]); - this.minY = Math.min(this.minY, minMax[2]); - this.maxY = Math.max(this.maxY, minMax[3]); + addEditor(editor) { + this.#allEditors.set(editor.id, editor); }
- updateCurvePathMinMax(transform, x0, y0, x1, y1, x2, y2, x3, y3, minMax) { - const box = _util.Util.bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3); + removeEditor(editor) { + this.#allEditors.delete(editor.id); + this.unselect(editor); + }
- if (minMax) { - minMax[0] = Math.min(minMax[0], box[0], box[2]); - minMax[1] = Math.max(minMax[1], box[0], box[2]); - minMax[2] = Math.min(minMax[2], box[1], box[3]); - minMax[3] = Math.max(minMax[3], box[1], box[3]); - return; - } + #addEditorToLayer(editor) { + const layer = this.#allLayers.get(editor.pageIndex);
- this.updateRectMinMax(transform, box); + if (layer) { + layer.addOrRebuild(editor); + } else { + this.addEditor(editor); + } }
- getPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) { - const box = [this.minX, this.minY, this.maxX, this.maxY]; + setActiveEditor(editor) { + if (this.#activeEditor === editor) { + return; + }
- if (pathType === _pattern_helper.PathType.STROKE) { - if (!transform) { - (0, _util.unreachable)("Stroke bounding box must include transform."); - } + this.#activeEditor = editor;
- const scale = _util.Util.singularValueDecompose2dScale(transform); + if (editor) { + this.#dispatchUpdateUI(editor.propertiesToUpdate); + } + }
- const xStrokePad = scale[0] * this.lineWidth / 2; - const yStrokePad = scale[1] * this.lineWidth / 2; - box[0] -= xStrokePad; - box[1] -= yStrokePad; - box[2] += xStrokePad; - box[3] += yStrokePad; + toggleSelected(editor) { + if (this.#selectedEditors.has(editor)) { + this.#selectedEditors.delete(editor); + editor.unselect(); + this.#dispatchUpdateStates({ + hasSelectedEditor: this.hasSelection + }); + return; }
- return box; + this.#selectedEditors.add(editor); + editor.select(); + this.#dispatchUpdateUI(editor.propertiesToUpdate); + this.#dispatchUpdateStates({ + hasSelectedEditor: true + }); }
- updateClipFromPath() { - const intersect = _util.Util.intersect(this.clipBox, this.getPathBoundingBox()); + setSelected(editor) { + for (const ed of this.#selectedEditors) { + if (ed !== editor) { + ed.unselect(); + } + }
- this.startNewPathAndClipBox(intersect || [0, 0, 0, 0]); + this.#selectedEditors.clear(); + this.#selectedEditors.add(editor); + editor.select(); + this.#dispatchUpdateUI(editor.propertiesToUpdate); + this.#dispatchUpdateStates({ + hasSelectedEditor: true + }); }
- isEmptyClip() { - return this.minX === Infinity; + isSelected(editor) { + return this.#selectedEditors.has(editor); }
- startNewPathAndClipBox(box) { - this.clipBox = box; - this.minX = Infinity; - this.minY = Infinity; - this.maxX = 0; - this.maxY = 0; + unselect(editor) { + editor.unselect(); + this.#selectedEditors.delete(editor); + this.#dispatchUpdateStates({ + hasSelectedEditor: this.hasSelection + }); }
- getClippedPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) { - return _util.Util.intersect(this.clipBox, this.getPathBoundingBox(pathType, transform)); + get hasSelection() { + return this.#selectedEditors.size !== 0; }
-} + undo() { + this.#commandManager.undo(); + this.#dispatchUpdateStates({ + hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(), + hasSomethingToRedo: true, + isEmpty: this.#isEmpty() + }); + }
-function putBinaryImageData(ctx, imgData, transferMaps = null) { - if (typeof ImageData !== "undefined" && imgData instanceof ImageData) { - ctx.putImageData(imgData, 0, 0); - return; + redo() { + this.#commandManager.redo(); + this.#dispatchUpdateStates({ + hasSomethingToUndo: true, + hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(), + isEmpty: this.#isEmpty() + }); }
- const height = imgData.height, - width = imgData.width; - const partialChunkHeight = height % FULL_CHUNK_HEIGHT; - const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; - const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; - const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); - let srcPos = 0, - destPos; - const src = imgData.data; - const dest = chunkImgData.data; - let i, j, thisChunkHeight, elemsInThisChunk; - let transferMapRed, transferMapGreen, transferMapBlue, transferMapGray; + addCommands(params) { + this.#commandManager.add(params); + this.#dispatchUpdateStates({ + hasSomethingToUndo: true, + hasSomethingToRedo: false, + isEmpty: this.#isEmpty() + }); + }
- if (transferMaps) { - switch (transferMaps.length) { - case 1: - transferMapRed = transferMaps[0]; - transferMapGreen = transferMaps[0]; - transferMapBlue = transferMaps[0]; - transferMapGray = transferMaps[0]; - break; + #isEmpty() { + if (this.#allEditors.size === 0) { + return true; + }
- case 4: - transferMapRed = transferMaps[0]; - transferMapGreen = transferMaps[1]; - transferMapBlue = transferMaps[2]; - transferMapGray = transferMaps[3]; - break; + if (this.#allEditors.size === 1) { + for (const editor of this.#allEditors.values()) { + return editor.isEmpty(); + } } + + return false; }
- if (imgData.kind === _util.ImageKind.GRAYSCALE_1BPP) { - const srcLength = src.byteLength; - const dest32 = new Uint32Array(dest.buffer, 0, dest.byteLength >> 2); - const dest32DataLength = dest32.length; - const fullSrcDiff = width + 7 >> 3; - let white = 0xffffffff; - let black = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; - - if (transferMapGray) { - if (transferMapGray[0] === 0xff && transferMapGray[0xff] === 0) { - [white, black] = [black, white]; - } + delete() { + if (this.#activeEditor) { + this.#activeEditor.commitOrRemove(); }
- for (i = 0; i < totalChunks; i++) { - thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight; - destPos = 0; - - for (j = 0; j < thisChunkHeight; j++) { - const srcDiff = srcLength - srcPos; - let k = 0; - const kEnd = srcDiff > fullSrcDiff ? width : srcDiff * 8 - 7; - const kEndUnrolled = kEnd & ~7; - let mask = 0; - let srcByte = 0; - - for (; k < kEndUnrolled; k += 8) { - srcByte = src[srcPos++]; - dest32[destPos++] = srcByte & 128 ? white : black; - dest32[destPos++] = srcByte & 64 ? white : black; - dest32[destPos++] = srcByte & 32 ? white : black; - dest32[destPos++] = srcByte & 16 ? white : black; - dest32[destPos++] = srcByte & 8 ? white : black; - dest32[destPos++] = srcByte & 4 ? white : black; - dest32[destPos++] = srcByte & 2 ? white : black; - dest32[destPos++] = srcByte & 1 ? white : black; - } + if (!this.hasSelection) { + return; + }
- for (; k < kEnd; k++) { - if (mask === 0) { - srcByte = src[srcPos++]; - mask = 128; - } + const editors = [...this.#selectedEditors];
- dest32[destPos++] = srcByte & mask ? white : black; - mask >>= 1; - } + const cmd = () => { + for (const editor of editors) { + editor.remove(); } + };
- while (destPos < dest32DataLength) { - dest32[destPos++] = 0; + const undo = () => { + for (const editor of editors) { + this.#addEditorToLayer(editor); } + };
- ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); - } - } else if (imgData.kind === _util.ImageKind.RGBA_32BPP) { - const hasTransferMaps = !!(transferMapRed || transferMapGreen || transferMapBlue); - j = 0; - elemsInThisChunk = width * FULL_CHUNK_HEIGHT * 4; - - for (i = 0; i < fullChunks; i++) { - dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); - srcPos += elemsInThisChunk; + this.addCommands({ + cmd, + undo, + mustExec: true + }); + }
- if (hasTransferMaps) { - for (let k = 0; k < elemsInThisChunk; k += 4) { - if (transferMapRed) { - dest[k + 0] = transferMapRed[dest[k + 0]]; - } + copy() { + if (this.#activeEditor) { + this.#activeEditor.commitOrRemove(); + }
- if (transferMapGreen) { - dest[k + 1] = transferMapGreen[dest[k + 1]]; - } + if (this.hasSelection) { + const editors = [];
- if (transferMapBlue) { - dest[k + 2] = transferMapBlue[dest[k + 2]]; - } + for (const editor of this.#selectedEditors) { + if (!editor.isEmpty()) { + editors.push(editor); } }
- ctx.putImageData(chunkImgData, 0, j); - j += FULL_CHUNK_HEIGHT; - } - - if (i < totalChunks) { - elemsInThisChunk = width * partialChunkHeight * 4; - dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); - - if (hasTransferMaps) { - for (let k = 0; k < elemsInThisChunk; k += 4) { - if (transferMapRed) { - dest[k + 0] = transferMapRed[dest[k + 0]]; - } + if (editors.length === 0) { + return; + }
- if (transferMapGreen) { - dest[k + 1] = transferMapGreen[dest[k + 1]]; - } + this.#clipboardManager.copy(editors); + this.#dispatchUpdateStates({ + hasEmptyClipboard: false + }); + } + }
- if (transferMapBlue) { - dest[k + 2] = transferMapBlue[dest[k + 2]]; - } - } - } + cut() { + this.copy(); + this.delete(); + }
- ctx.putImageData(chunkImgData, 0, j); + paste() { + if (this.#clipboardManager.isEmpty()) { + return; } - } else if (imgData.kind === _util.ImageKind.RGB_24BPP) { - const hasTransferMaps = !!(transferMapRed || transferMapGreen || transferMapBlue); - thisChunkHeight = FULL_CHUNK_HEIGHT; - elemsInThisChunk = width * thisChunkHeight;
- for (i = 0; i < totalChunks; i++) { - if (i >= fullChunks) { - thisChunkHeight = partialChunkHeight; - elemsInThisChunk = width * thisChunkHeight; + this.unselectAll(); + const layer = this.#allLayers.get(this.#currentPageIndex); + const newEditors = this.#clipboardManager.paste().map(data => layer.deserialize(data)); + + const cmd = () => { + for (const editor of newEditors) { + this.#addEditorToLayer(editor); }
- destPos = 0; + this.#selectEditors(newEditors); + };
- for (j = elemsInThisChunk; j--;) { - dest[destPos++] = src[srcPos++]; - dest[destPos++] = src[srcPos++]; - dest[destPos++] = src[srcPos++]; - dest[destPos++] = 255; + const undo = () => { + for (const editor of newEditors) { + editor.remove(); } + };
- if (hasTransferMaps) { - for (let k = 0; k < destPos; k += 4) { - if (transferMapRed) { - dest[k + 0] = transferMapRed[dest[k + 0]]; - } + this.addCommands({ + cmd, + undo, + mustExec: true + }); + }
- if (transferMapGreen) { - dest[k + 1] = transferMapGreen[dest[k + 1]]; - } + #selectEditors(editors) { + this.#selectedEditors.clear();
- if (transferMapBlue) { - dest[k + 2] = transferMapBlue[dest[k + 2]]; - } - } + for (const editor of editors) { + if (editor.isEmpty()) { + continue; }
- ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); + this.#selectedEditors.add(editor); + editor.select(); } - } else { - throw new Error(`bad image kind: ${imgData.kind}`); - } -}
-function putBinaryImageMask(ctx, imgData) { - if (imgData.bitmap) { - ctx.drawImage(imgData.bitmap, 0, 0); - return; + this.#dispatchUpdateStates({ + hasSelectedEditor: true + }); }
- const height = imgData.height, - width = imgData.width; - const partialChunkHeight = height % FULL_CHUNK_HEIGHT; - const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; - const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; - const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); - let srcPos = 0; - const src = imgData.data; - const dest = chunkImgData.data; + selectAll() { + for (const editor of this.#selectedEditors) { + editor.commit(); + }
- for (let i = 0; i < totalChunks; i++) { - const thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight; - ({ - srcPos - } = (0, _image_utils.applyMaskImageData)({ - src, - srcPos, - dest, - width, - height: thisChunkHeight - })); - ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); + this.#selectEditors(this.#allEditors.values()); } -}
-function copyCtxState(sourceCtx, destCtx) { - const properties = ["strokeStyle", "fillStyle", "fillRule", "globalAlpha", "lineWidth", "lineCap", "lineJoin", "miterLimit", "globalCompositeOperation", "font"]; + unselectAll() { + if (this.#activeEditor) { + this.#activeEditor.commitOrRemove(); + return; + }
- for (let i = 0, ii = properties.length; i < ii; i++) { - const property = properties[i]; + if (this.#selectEditors.size === 0) { + return; + }
- if (sourceCtx[property] !== undefined) { - destCtx[property] = sourceCtx[property]; + for (const editor of this.#selectedEditors) { + editor.unselect(); } + + this.#selectedEditors.clear(); + this.#dispatchUpdateStates({ + hasSelectedEditor: false + }); }
- if (sourceCtx.setLineDash !== undefined) { - destCtx.setLineDash(sourceCtx.getLineDash()); - destCtx.lineDashOffset = sourceCtx.lineDashOffset; + isActive(editor) { + return this.#activeEditor === editor; } -}
-function resetCtxToDefault(ctx, foregroundColor) { - ctx.strokeStyle = ctx.fillStyle = foregroundColor || "#000000"; - ctx.fillRule = "nonzero"; - ctx.globalAlpha = 1; - ctx.lineWidth = 1; - ctx.lineCap = "butt"; - ctx.lineJoin = "miter"; - ctx.miterLimit = 10; - ctx.globalCompositeOperation = "source-over"; - ctx.font = "10px sans-serif"; + getActive() { + return this.#activeEditor; + }
- if (ctx.setLineDash !== undefined) { - ctx.setLineDash([]); - ctx.lineDashOffset = 0; + getMode() { + return this.#mode; } -}
-function composeSMaskBackdrop(bytes, r0, g0, b0) { - const length = bytes.length; +}
- for (let i = 3; i < length; i += 4) { - const alpha = bytes[i]; +exports.AnnotationEditorUIManager = AnnotationEditorUIManager;
- if (alpha === 0) { - bytes[i - 3] = r0; - bytes[i - 2] = g0; - bytes[i - 1] = b0; - } else if (alpha < 255) { - const alpha_ = 255 - alpha; - bytes[i - 3] = bytes[i - 3] * alpha + r0 * alpha_ >> 8; - bytes[i - 2] = bytes[i - 2] * alpha + g0 * alpha_ >> 8; - bytes[i - 1] = bytes[i - 1] * alpha + b0 * alpha_ >> 8; - } - } -} +/***/ }), +/* 10 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
-function composeSMaskAlpha(maskData, layerData, transferMap) { - const length = maskData.length; - const scale = 1 / 255;
- for (let i = 3; i < length; i += 4) { - const alpha = transferMap ? transferMap[maskData[i]] : maskData[i]; - layerData[i] = layerData[i] * alpha * scale | 0; - } -}
-function composeSMaskLuminosity(maskData, layerData, transferMap) { - const length = maskData.length; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.MurmurHash3_64 = void 0;
- for (let i = 3; i < length; i += 4) { - const y = maskData[i - 3] * 77 + maskData[i - 2] * 152 + maskData[i - 1] * 28; - layerData[i] = transferMap ? layerData[i] * transferMap[y >> 8] >> 8 : layerData[i] * y >> 16; - } -} +var _util = __w_pdfjs_require__(1);
-function genericComposeSMask(maskCtx, layerCtx, width, height, subtype, backdrop, transferMap, layerOffsetX, layerOffsetY, maskOffsetX, maskOffsetY) { - const hasBackdrop = !!backdrop; - const r0 = hasBackdrop ? backdrop[0] : 0; - const g0 = hasBackdrop ? backdrop[1] : 0; - const b0 = hasBackdrop ? backdrop[2] : 0; - let composeFn; +const SEED = 0xc3d2e1f0; +const MASK_HIGH = 0xffff0000; +const MASK_LOW = 0xffff;
- if (subtype === "Luminosity") { - composeFn = composeSMaskLuminosity; - } else { - composeFn = composeSMaskAlpha; +class MurmurHash3_64 { + constructor(seed) { + this.h1 = seed ? seed & 0xffffffff : SEED; + this.h2 = seed ? seed & 0xffffffff : SEED; }
- const PIXELS_TO_PROCESS = 1048576; - const chunkSize = Math.min(height, Math.ceil(PIXELS_TO_PROCESS / width)); + update(input) { + let data, length;
- for (let row = 0; row < height; row += chunkSize) { - const chunkHeight = Math.min(chunkSize, height - row); - const maskData = maskCtx.getImageData(layerOffsetX - maskOffsetX, row + (layerOffsetY - maskOffsetY), width, chunkHeight); - const layerData = layerCtx.getImageData(layerOffsetX, row + layerOffsetY, width, chunkHeight); + if (typeof input === "string") { + data = new Uint8Array(input.length * 2); + length = 0;
- if (hasBackdrop) { - composeSMaskBackdrop(maskData.data, r0, g0, b0); + for (let i = 0, ii = input.length; i < ii; i++) { + const code = input.charCodeAt(i); + + if (code <= 0xff) { + data[length++] = code; + } else { + data[length++] = code >>> 8; + data[length++] = code & 0xff; + } + } + } else if ((0, _util.isArrayBuffer)(input)) { + data = input.slice(); + length = data.byteLength; + } else { + throw new Error("Wrong data format in MurmurHash3_64_update. " + "Input must be a string or array."); }
- composeFn(maskData.data, layerData.data, transferMap); - layerCtx.putImageData(layerData, layerOffsetX, row + layerOffsetY); - } -} + const blockCounts = length >> 2; + const tailLength = length - blockCounts * 4; + const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts); + let k1 = 0, + k2 = 0; + let h1 = this.h1, + h2 = this.h2; + const C1 = 0xcc9e2d51, + C2 = 0x1b873593; + const C1_LOW = C1 & MASK_LOW, + C2_LOW = C2 & MASK_LOW;
-function composeSMask(ctx, smask, layerCtx, layerBox) { - const layerOffsetX = layerBox[0]; - const layerOffsetY = layerBox[1]; - const layerWidth = layerBox[2] - layerOffsetX; - const layerHeight = layerBox[3] - layerOffsetY; + for (let i = 0; i < blockCounts; i++) { + if (i & 1) { + k1 = dataUint32[i]; + k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; + k1 = k1 << 15 | k1 >>> 17; + k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; + h1 ^= k1; + h1 = h1 << 13 | h1 >>> 19; + h1 = h1 * 5 + 0xe6546b64; + } else { + k2 = dataUint32[i]; + k2 = k2 * C1 & MASK_HIGH | k2 * C1_LOW & MASK_LOW; + k2 = k2 << 15 | k2 >>> 17; + k2 = k2 * C2 & MASK_HIGH | k2 * C2_LOW & MASK_LOW; + h2 ^= k2; + h2 = h2 << 13 | h2 >>> 19; + h2 = h2 * 5 + 0xe6546b64; + } + }
- if (layerWidth === 0 || layerHeight === 0) { - return; - } + k1 = 0;
- genericComposeSMask(smask.context, layerCtx, layerWidth, layerHeight, smask.subtype, smask.backdrop, smask.transferMap, layerOffsetX, layerOffsetY, smask.offsetX, smask.offsetY); - ctx.save(); - ctx.globalAlpha = 1; - ctx.globalCompositeOperation = "source-over"; - ctx.setTransform(1, 0, 0, 1, 0, 0); - ctx.drawImage(layerCtx.canvas, 0, 0); - ctx.restore(); -} + switch (tailLength) { + case 3: + k1 ^= data[blockCounts * 4 + 2] << 16;
-function getImageSmoothingEnabled(transform, interpolate) { - const scale = _util.Util.singularValueDecompose2dScale(transform); + case 2: + k1 ^= data[blockCounts * 4 + 1] << 8;
- scale[0] = Math.fround(scale[0]); - scale[1] = Math.fround(scale[1]); - const actualScale = Math.fround((globalThis.devicePixelRatio || 1) * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS); + case 1: + k1 ^= data[blockCounts * 4]; + k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; + k1 = k1 << 15 | k1 >>> 17; + k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW;
- if (interpolate !== undefined) { - return interpolate; - } else if (scale[0] <= actualScale || scale[1] <= actualScale) { - return true; + if (blockCounts & 1) { + h1 ^= k1; + } else { + h2 ^= k1; + } + + } + + this.h1 = h1; + this.h2 = h2; + } + + hexdigest() { + let h1 = this.h1, + h2 = this.h2; + h1 ^= h2 >>> 1; + h1 = h1 * 0xed558ccd & MASK_HIGH | h1 * 0x8ccd & MASK_LOW; + h2 = h2 * 0xff51afd7 & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16; + h1 ^= h2 >>> 1; + h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW; + h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16; + h1 ^= h2 >>> 1; + const hex1 = (h1 >>> 0).toString(16), + hex2 = (h2 >>> 0).toString(16); + return hex1.padStart(8, "0") + hex2.padStart(8, "0"); }
- return false; }
-const LINE_CAP_STYLES = ["butt", "round", "square"]; -const LINE_JOIN_STYLES = ["miter", "round", "bevel"]; -const NORMAL_CLIP = {}; -const EO_CLIP = {}; +exports.MurmurHash3_64 = MurmurHash3_64;
-class CanvasGraphics { - constructor(canvasCtx, commonObjs, objs, canvasFactory, imageLayer, optionalContentConfig, annotationCanvasMap, pageColors) { - this.ctx = canvasCtx; - this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height); - this.stateStack = []; - this.pendingClip = null; - this.pendingEOFill = false; - this.res = null; - this.xobjs = null; - this.commonObjs = commonObjs; - this.objs = objs; - this.canvasFactory = canvasFactory; - this.imageLayer = imageLayer; - this.groupStack = []; - this.processingType3 = null; - this.baseTransform = null; - this.baseTransformStack = []; - this.groupLevel = 0; - this.smaskStack = []; - this.smaskCounter = 0; - this.tempSMask = null; - this.suspendedCtx = null; - this.contentVisible = true; - this.markedContentStack = []; - this.optionalContentConfig = optionalContentConfig; - this.cachedCanvases = new CachedCanvases(this.canvasFactory); - this.cachedPatterns = new Map(); - this.annotationCanvasMap = annotationCanvasMap; - this.viewportScale = 1; - this.outputScaleX = 1; - this.outputScaleY = 1; - this.backgroundColor = pageColors?.background || null; - this.foregroundColor = pageColors?.foreground || null; +/***/ }), +/* 11 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- if (canvasCtx) { - addContextCurrentTransform(canvasCtx); - }
- this._cachedScaleForStroking = null; - this._cachedGetSinglePixelWidth = null; - this._cachedBitmapsMap = new Map(); - }
- getObject(data, fallback = null) { - if (typeof data === "string") { - return data.startsWith("g_") ? this.commonObjs.get(data) : this.objs.get(data); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.FontLoader = exports.FontFaceObject = void 0;
- return fallback; - } +var _util = __w_pdfjs_require__(1);
- beginDrawing({ - transform, - viewport, - transparency = false, - background = null +class BaseFontLoader { + constructor({ + docId, + onUnsupportedFeature, + ownerDocument = globalThis.document, + styleElement = null }) { - const width = this.ctx.canvas.width; - const height = this.ctx.canvas.height; - const defaultBackgroundColor = background || "#ffffff"; - this.ctx.save(); - - if (this.foregroundColor && this.backgroundColor) { - this.ctx.fillStyle = this.foregroundColor; - const fg = this.foregroundColor = this.ctx.fillStyle; - this.ctx.fillStyle = this.backgroundColor; - const bg = this.backgroundColor = this.ctx.fillStyle; - let isValidDefaultBg = true; - let defaultBg = defaultBackgroundColor; + if (this.constructor === BaseFontLoader) { + (0, _util.unreachable)("Cannot initialize BaseFontLoader."); + }
- if (fg === "#000000" && bg === "#ffffff" || fg === bg || !isValidDefaultBg) { - this.foregroundColor = this.backgroundColor = null; - } else { - const cB = parseInt(defaultBg.slice(1), 16); - const rB = (cB && 0xff0000) >> 16; - const gB = (cB && 0x00ff00) >> 8; - const bB = cB && 0x0000ff; + this.docId = docId; + this._onUnsupportedFeature = onUnsupportedFeature; + this._document = ownerDocument; + this.nativeFontFaces = []; + this.styleElement = null; + }
- const newComp = x => { - x /= 255; - return x <= 0.03928 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4; - }; + addNativeFontFace(nativeFontFace) { + this.nativeFontFaces.push(nativeFontFace);
- const lumB = Math.round(0.2126 * newComp(rB) + 0.7152 * newComp(gB) + 0.0722 * newComp(bB)); + this._document.fonts.add(nativeFontFace); + }
- this.selectColor = (r, g, b) => { - const lumC = 0.2126 * newComp(r) + 0.7152 * newComp(g) + 0.0722 * newComp(b); - return Math.round(lumC) === lumB ? bg : fg; - }; - } - } + insertRule(rule) { + let styleElement = this.styleElement;
- this.ctx.fillStyle = this.backgroundColor || defaultBackgroundColor; - this.ctx.fillRect(0, 0, width, height); - this.ctx.restore(); + if (!styleElement) { + styleElement = this.styleElement = this._document.createElement("style"); + styleElement.id = `PDFJS_FONT_STYLE_TAG_${this.docId}`;
- if (transparency) { - const transparentCanvas = this.cachedCanvases.getCanvas("transparent", width, height, true); - this.compositeCtx = this.ctx; - this.transparentCanvas = transparentCanvas.canvas; - this.ctx = transparentCanvas.context; - this.ctx.save(); - this.ctx.transform.apply(this.ctx, this.compositeCtx.mozCurrentTransform); + this._document.documentElement.getElementsByTagName("head")[0].append(styleElement); }
- this.ctx.save(); - resetCtxToDefault(this.ctx, this.foregroundColor); + const styleSheet = styleElement.sheet; + styleSheet.insertRule(rule, styleSheet.cssRules.length); + }
- if (transform) { - this.ctx.transform.apply(this.ctx, transform); - this.outputScaleX = transform[0]; - this.outputScaleY = transform[0]; + clear() { + for (const nativeFontFace of this.nativeFontFaces) { + this._document.fonts.delete(nativeFontFace); }
- this.ctx.transform.apply(this.ctx, viewport.transform); - this.viewportScale = viewport.scale; - this.baseTransform = this.ctx.mozCurrentTransform.slice(); + this.nativeFontFaces.length = 0;
- if (this.imageLayer) { - this.imageLayer.beginLayout(); + if (this.styleElement) { + this.styleElement.remove(); + this.styleElement = null; } }
- executeOperatorList(operatorList, executionStartIdx, continueCallback, stepper) { - const argsArray = operatorList.argsArray; - const fnArray = operatorList.fnArray; - let i = executionStartIdx || 0; - const argsArrayLen = argsArray.length; - - if (argsArrayLen === i) { - return i; + async bind(font) { + if (font.attached || font.missingFile) { + return; }
- const chunkOperations = argsArrayLen - i > EXECUTION_STEPS && typeof continueCallback === "function"; - const endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0; - let steps = 0; - const commonObjs = this.commonObjs; - const objs = this.objs; - let fnId; + font.attached = true;
- while (true) { - if (stepper !== undefined && i === stepper.nextBreakPoint) { - stepper.breakIt(i, continueCallback); - return i; - } + if (this.isFontLoadingAPISupported) { + const nativeFontFace = font.createNativeFontFace();
- fnId = fnArray[i]; + if (nativeFontFace) { + this.addNativeFontFace(nativeFontFace);
- if (fnId !== _util.OPS.dependency) { - this[fnId].apply(this, argsArray[i]); - } else { - for (const depObjId of argsArray[i]) { - const objsPool = depObjId.startsWith("g_") ? commonObjs : objs; + try { + await nativeFontFace.loaded; + } catch (ex) { + this._onUnsupportedFeature({ + featureId: _util.UNSUPPORTED_FEATURES.errorFontLoadNative + });
- if (!objsPool.has(depObjId)) { - objsPool.get(depObjId, continueCallback); - return i; - } + (0, _util.warn)(`Failed to load font '${nativeFontFace.family}': '${ex}'.`); + font.disableFontFace = true; + throw ex; } }
- i++; + return; + }
- if (i === argsArrayLen) { - return i; - } + const rule = font.createFontFaceRule();
- if (chunkOperations && ++steps > EXECUTION_STEPS) { - if (Date.now() > endTime) { - continueCallback(); - return i; - } + if (rule) { + this.insertRule(rule);
- steps = 0; + if (this.isSyncFontLoadingSupported) { + return; } + + await new Promise(resolve => { + const request = this._queueLoadingCallback(resolve); + + this._prepareFontLoadEvent([rule], [font], request); + }); } }
- endDrawing() { - while (this.stateStack.length || this.inSMaskMode) { - this.restore(); - } + _queueLoadingCallback(callback) { + (0, _util.unreachable)("Abstract method `_queueLoadingCallback`."); + }
- this.ctx.restore(); + get isFontLoadingAPISupported() { + const hasFonts = !!this._document?.fonts; + return (0, _util.shadow)(this, "isFontLoadingAPISupported", hasFonts); + }
- if (this.transparentCanvas) { - this.ctx = this.compositeCtx; - this.ctx.save(); - this.ctx.setTransform(1, 0, 0, 1, 0, 0); - this.ctx.drawImage(this.transparentCanvas, 0, 0); - this.ctx.restore(); - this.transparentCanvas = null; - } + get isSyncFontLoadingSupported() { + (0, _util.unreachable)("Abstract method `isSyncFontLoadingSupported`."); + }
- this.cachedCanvases.clear(); - this.cachedPatterns.clear(); + get _loadTestFont() { + (0, _util.unreachable)("Abstract method `_loadTestFont`."); + }
- for (const cache of this._cachedBitmapsMap.values()) { - for (const canvas of cache.values()) { - if (typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) { - canvas.width = canvas.height = 0; - } - } + _prepareFontLoadEvent(rules, fontsToLoad, request) { + (0, _util.unreachable)("Abstract method `_prepareFontLoadEvent`."); + }
- cache.clear(); +} + +let FontLoader; +exports.FontLoader = FontLoader; +{ + exports.FontLoader = FontLoader = class MozcentralFontLoader extends BaseFontLoader { + get isSyncFontLoadingSupported() { + return (0, _util.shadow)(this, "isSyncFontLoadingSupported", true); }
- this._cachedBitmapsMap.clear(); + }; +}
- if (this.imageLayer) { - this.imageLayer.endLayout(); +class FontFaceObject { + constructor(translatedData, { + isEvalSupported = true, + disableFontFace = false, + ignoreErrors = false, + onUnsupportedFeature, + fontRegistry = null + }) { + this.compiledGlyphs = Object.create(null); + + for (const i in translatedData) { + this[i] = translatedData[i]; } + + this.isEvalSupported = isEvalSupported !== false; + this.disableFontFace = disableFontFace === true; + this.ignoreErrors = ignoreErrors === true; + this._onUnsupportedFeature = onUnsupportedFeature; + this.fontRegistry = fontRegistry; }
- _scaleImage(img, inverseTransform) { - const width = img.width; - const height = img.height; - let widthScale = Math.max(Math.hypot(inverseTransform[0], inverseTransform[1]), 1); - let heightScale = Math.max(Math.hypot(inverseTransform[2], inverseTransform[3]), 1); - let paintWidth = width, - paintHeight = height; - let tmpCanvasId = "prescale1"; - let tmpCanvas, tmpCtx; + createNativeFontFace() { + if (!this.data || this.disableFontFace) { + return null; + }
- while (widthScale > 2 && paintWidth > 1 || heightScale > 2 && paintHeight > 1) { - let newWidth = paintWidth, - newHeight = paintHeight; + let nativeFontFace;
- if (widthScale > 2 && paintWidth > 1) { - newWidth = Math.ceil(paintWidth / 2); - widthScale /= paintWidth / newWidth; - } + if (!this.cssFontInfo) { + nativeFontFace = new FontFace(this.loadedName, this.data, {}); + } else { + const css = { + weight: this.cssFontInfo.fontWeight + };
- if (heightScale > 2 && paintHeight > 1) { - newHeight = Math.ceil(paintHeight / 2); - heightScale /= paintHeight / newHeight; + if (this.cssFontInfo.italicAngle) { + css.style = `oblique ${this.cssFontInfo.italicAngle}deg`; }
- tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight, false); - tmpCtx = tmpCanvas.context; - tmpCtx.clearRect(0, 0, newWidth, newHeight); - tmpCtx.drawImage(img, 0, 0, paintWidth, paintHeight, 0, 0, newWidth, newHeight); - img = tmpCanvas.canvas; - paintWidth = newWidth; - paintHeight = newHeight; - tmpCanvasId = tmpCanvasId === "prescale1" ? "prescale2" : "prescale1"; + nativeFontFace = new FontFace(this.cssFontInfo.fontFamily, this.data, css); }
- return { - img, - paintWidth, - paintHeight - }; - } - - _createMaskCanvas(img) { - const ctx = this.ctx; - const { - width, - height - } = img; - const fillColor = this.current.fillColor; - const isPatternFill = this.current.patternFill; - const currentTransform = ctx.mozCurrentTransform; - let cache, cacheKey, scaled, maskCanvas; + if (this.fontRegistry) { + this.fontRegistry.registerFont(this); + }
- if ((img.bitmap || img.data) && img.count > 1) { - const mainKey = img.bitmap || img.data.buffer; - const withoutTranslation = currentTransform.slice(0, 4); - cacheKey = JSON.stringify(isPatternFill ? withoutTranslation : [withoutTranslation, fillColor]); - cache = this._cachedBitmapsMap.get(mainKey); + return nativeFontFace; + }
- if (!cache) { - cache = new Map(); + createFontFaceRule() { + if (!this.data || this.disableFontFace) { + return null; + }
- this._cachedBitmapsMap.set(mainKey, cache); - } + const data = (0, _util.bytesToString)(this.data); + const url = `url(data:${this.mimetype};base64,${btoa(data)});`; + let rule;
- const cachedImage = cache.get(cacheKey); + if (!this.cssFontInfo) { + rule = `@font-face {font-family:"${this.loadedName}";src:${url}}`; + } else { + let css = `font-weight: ${this.cssFontInfo.fontWeight};`;
- if (cachedImage && !isPatternFill) { - const offsetX = Math.round(Math.min(currentTransform[0], currentTransform[2]) + currentTransform[4]); - const offsetY = Math.round(Math.min(currentTransform[1], currentTransform[3]) + currentTransform[5]); - return { - canvas: cachedImage, - offsetX, - offsetY - }; + if (this.cssFontInfo.italicAngle) { + css += `font-style: oblique ${this.cssFontInfo.italicAngle}deg;`; }
- scaled = cachedImage; + rule = `@font-face {font-family:"${this.cssFontInfo.fontFamily}";${css}src:${url}}`; }
- if (!scaled) { - maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height, false); - putBinaryImageMask(maskCanvas.context, img); + if (this.fontRegistry) { + this.fontRegistry.registerFont(this, url); }
- let maskToCanvas = _util.Util.transform(currentTransform, [1 / width, 0, 0, -1 / height, 0, 0]); + return rule; + }
- maskToCanvas = _util.Util.transform(maskToCanvas, [1, 0, 0, 1, 0, -height]); + getPathGenerator(objs, character) { + if (this.compiledGlyphs[character] !== undefined) { + return this.compiledGlyphs[character]; + }
- const cord1 = _util.Util.applyTransform([0, 0], maskToCanvas); - - const cord2 = _util.Util.applyTransform([width, height], maskToCanvas); - - const rect = _util.Util.normalizeRect([cord1[0], cord1[1], cord2[0], cord2[1]]); + let cmds;
- const drawnWidth = Math.round(rect[2] - rect[0]) || 1; - const drawnHeight = Math.round(rect[3] - rect[1]) || 1; - const fillCanvas = this.cachedCanvases.getCanvas("fillCanvas", drawnWidth, drawnHeight, true); - const fillCtx = fillCanvas.context; - const offsetX = Math.min(cord1[0], cord2[0]); - const offsetY = Math.min(cord1[1], cord2[1]); - fillCtx.translate(-offsetX, -offsetY); - fillCtx.transform.apply(fillCtx, maskToCanvas); + try { + cmds = objs.get(this.loadedName + "_path_" + character); + } catch (ex) { + if (!this.ignoreErrors) { + throw ex; + }
- if (!scaled) { - scaled = this._scaleImage(maskCanvas.canvas, fillCtx.mozCurrentTransformInverse); - scaled = scaled.img; + this._onUnsupportedFeature({ + featureId: _util.UNSUPPORTED_FEATURES.errorFontGetPath + });
- if (cache && isPatternFill) { - cache.set(cacheKey, scaled); - } + (0, _util.warn)(`getPathGenerator - ignoring character: "${ex}".`); + return this.compiledGlyphs[character] = function (c, size) {}; }
- fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled(fillCtx.mozCurrentTransform, img.interpolate); - drawImageAtIntegerCoords(fillCtx, scaled, 0, 0, scaled.width, scaled.height, 0, 0, width, height); - fillCtx.globalCompositeOperation = "source-in"; - - const inverse = _util.Util.transform(fillCtx.mozCurrentTransformInverse, [1, 0, 0, 1, -offsetX, -offsetY]); + if (this.isEvalSupported && _util.FeatureTest.isEvalSupported) { + const jsBuf = [];
- fillCtx.fillStyle = isPatternFill ? fillColor.getPattern(ctx, this, inverse, _pattern_helper.PathType.FILL) : fillColor; - fillCtx.fillRect(0, 0, width, height); + for (const current of cmds) { + const args = current.args !== undefined ? current.args.join(",") : ""; + jsBuf.push("c.", current.cmd, "(", args, ");\n"); + }
- if (cache && !isPatternFill) { - this.cachedCanvases.delete("fillCanvas"); - cache.set(cacheKey, fillCanvas.canvas); + return this.compiledGlyphs[character] = new Function("c", "size", jsBuf.join("")); }
- return { - canvas: fillCanvas.canvas, - offsetX: Math.round(offsetX), - offsetY: Math.round(offsetY) + return this.compiledGlyphs[character] = function (c, size) { + for (const current of cmds) { + if (current.cmd === "scale") { + current.args = [size, -size]; + } + + c[current.cmd].apply(c, current.args); + } }; }
- setLineWidth(width) { - if (width !== this.current.lineWidth) { - this._cachedScaleForStroking = null; - } +}
- this.current.lineWidth = width; - this.ctx.lineWidth = width; - } +exports.FontFaceObject = FontFaceObject;
- setLineCap(style) { - this.ctx.lineCap = LINE_CAP_STYLES[style]; - } +/***/ }), +/* 12 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- setLineJoin(style) { - this.ctx.lineJoin = LINE_JOIN_STYLES[style]; - }
- setMiterLimit(limit) { - this.ctx.miterLimit = limit; - }
- setDash(dashArray, dashPhase) { - const ctx = this.ctx; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.CanvasGraphics = void 0;
- if (ctx.setLineDash !== undefined) { - ctx.setLineDash(dashArray); - ctx.lineDashOffset = dashPhase; - } - } +var _util = __w_pdfjs_require__(1);
- setRenderingIntent(intent) {} +var _display_utils = __w_pdfjs_require__(4);
- setFlatness(flatness) {} +var _pattern_helper = __w_pdfjs_require__(13);
- setGState(states) { - for (let i = 0, ii = states.length; i < ii; i++) { - const state = states[i]; - const key = state[0]; - const value = state[1]; +var _image_utils = __w_pdfjs_require__(14);
- switch (key) { - case "LW": - this.setLineWidth(value); - break; +var _is_node = __w_pdfjs_require__(3);
- case "LC": - this.setLineCap(value); - break; +const MIN_FONT_SIZE = 16; +const MAX_FONT_SIZE = 100; +const MAX_GROUP_SIZE = 4096; +const EXECUTION_TIME = 15; +const EXECUTION_STEPS = 10; +const COMPILE_TYPE3_GLYPHS = true; +const MAX_SIZE_TO_COMPILE = 1000; +const FULL_CHUNK_HEIGHT = 16; +const LINEWIDTH_SCALE_FACTOR = 1.000001;
- case "LJ": - this.setLineJoin(value); - break; +function mirrorContextOperations(ctx, destCtx) { + if (ctx._removeMirroring) { + throw new Error("Context is already forwarding operations."); + }
- case "ML": - this.setMiterLimit(value); - break; + ctx.__originalSave = ctx.save; + ctx.__originalRestore = ctx.restore; + ctx.__originalRotate = ctx.rotate; + ctx.__originalScale = ctx.scale; + ctx.__originalTranslate = ctx.translate; + ctx.__originalTransform = ctx.transform; + ctx.__originalSetTransform = ctx.setTransform; + ctx.__originalResetTransform = ctx.resetTransform; + ctx.__originalClip = ctx.clip; + ctx.__originalMoveTo = ctx.moveTo; + ctx.__originalLineTo = ctx.lineTo; + ctx.__originalBezierCurveTo = ctx.bezierCurveTo; + ctx.__originalRect = ctx.rect; + ctx.__originalClosePath = ctx.closePath; + ctx.__originalBeginPath = ctx.beginPath;
- case "D": - this.setDash(value[0], value[1]); - break; + ctx._removeMirroring = () => { + ctx.save = ctx.__originalSave; + ctx.restore = ctx.__originalRestore; + ctx.rotate = ctx.__originalRotate; + ctx.scale = ctx.__originalScale; + ctx.translate = ctx.__originalTranslate; + ctx.transform = ctx.__originalTransform; + ctx.setTransform = ctx.__originalSetTransform; + ctx.resetTransform = ctx.__originalResetTransform; + ctx.clip = ctx.__originalClip; + ctx.moveTo = ctx.__originalMoveTo; + ctx.lineTo = ctx.__originalLineTo; + ctx.bezierCurveTo = ctx.__originalBezierCurveTo; + ctx.rect = ctx.__originalRect; + ctx.closePath = ctx.__originalClosePath; + ctx.beginPath = ctx.__originalBeginPath; + delete ctx._removeMirroring; + };
- case "RI": - this.setRenderingIntent(value); - break; + ctx.save = function ctxSave() { + destCtx.save();
- case "FL": - this.setFlatness(value); - break; + this.__originalSave(); + };
- case "Font": - this.setFont(value[0], value[1]); - break; + ctx.restore = function ctxRestore() { + destCtx.restore();
- case "CA": - this.current.strokeAlpha = state[1]; - break; + this.__originalRestore(); + };
- case "ca": - this.current.fillAlpha = state[1]; - this.ctx.globalAlpha = state[1]; - break; + ctx.translate = function ctxTranslate(x, y) { + destCtx.translate(x, y);
- case "BM": - this.ctx.globalCompositeOperation = value; - break; + this.__originalTranslate(x, y); + };
- case "SMask": - this.current.activeSMask = value ? this.tempSMask : null; - this.tempSMask = null; - this.checkSMaskState(); - break; + ctx.scale = function ctxScale(x, y) { + destCtx.scale(x, y);
- case "TR": - this.current.transferMaps = value; - } - } - } + this.__originalScale(x, y); + };
- get inSMaskMode() { - return !!this.suspendedCtx; - } + ctx.transform = function ctxTransform(a, b, c, d, e, f) { + destCtx.transform(a, b, c, d, e, f);
- checkSMaskState() { - const inSMaskMode = this.inSMaskMode; + this.__originalTransform(a, b, c, d, e, f); + };
- if (this.current.activeSMask && !inSMaskMode) { - this.beginSMaskMode(); - } else if (!this.current.activeSMask && inSMaskMode) { - this.endSMaskMode(); - } - } + ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) { + destCtx.setTransform(a, b, c, d, e, f);
- beginSMaskMode() { - if (this.inSMaskMode) { - throw new Error("beginSMaskMode called while already in smask mode"); - } + this.__originalSetTransform(a, b, c, d, e, f); + };
- const drawnWidth = this.ctx.canvas.width; - const drawnHeight = this.ctx.canvas.height; - const cacheId = "smaskGroupAt" + this.groupLevel; - const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight, true); - this.suspendedCtx = this.ctx; - this.ctx = scratchCanvas.context; - const ctx = this.ctx; - ctx.setTransform.apply(ctx, this.suspendedCtx.mozCurrentTransform); - copyCtxState(this.suspendedCtx, ctx); - mirrorContextOperations(ctx, this.suspendedCtx); - this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]); - } + ctx.resetTransform = function ctxResetTransform() { + destCtx.resetTransform();
- endSMaskMode() { - if (!this.inSMaskMode) { - throw new Error("endSMaskMode called while not in smask mode"); - } + this.__originalResetTransform(); + };
- this.ctx._removeMirroring(); + ctx.rotate = function ctxRotate(angle) { + destCtx.rotate(angle);
- copyCtxState(this.ctx, this.suspendedCtx); - this.ctx = this.suspendedCtx; - this.suspendedCtx = null; - } - - compose(dirtyBox) { - if (!this.current.activeSMask) { - return; - } - - if (!dirtyBox) { - dirtyBox = [0, 0, this.ctx.canvas.width, this.ctx.canvas.height]; - } else { - dirtyBox[0] = Math.floor(dirtyBox[0]); - dirtyBox[1] = Math.floor(dirtyBox[1]); - dirtyBox[2] = Math.ceil(dirtyBox[2]); - dirtyBox[3] = Math.ceil(dirtyBox[3]); - } + this.__originalRotate(angle); + };
- const smask = this.current.activeSMask; - const suspendedCtx = this.suspendedCtx; - composeSMask(suspendedCtx, smask, this.ctx, dirtyBox); - this.ctx.save(); - this.ctx.setTransform(1, 0, 0, 1, 0, 0); - this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height); - this.ctx.restore(); - } + ctx.clip = function ctxRotate(rule) { + destCtx.clip(rule);
- save() { - if (this.inSMaskMode) { - copyCtxState(this.ctx, this.suspendedCtx); - this.suspendedCtx.save(); - } else { - this.ctx.save(); - } + this.__originalClip(rule); + };
- const old = this.current; - this.stateStack.push(old); - this.current = old.clone(); - } + ctx.moveTo = function (x, y) { + destCtx.moveTo(x, y);
- restore() { - if (this.stateStack.length === 0 && this.inSMaskMode) { - this.endSMaskMode(); - } + this.__originalMoveTo(x, y); + };
- if (this.stateStack.length !== 0) { - this.current = this.stateStack.pop(); + ctx.lineTo = function (x, y) { + destCtx.lineTo(x, y);
- if (this.inSMaskMode) { - this.suspendedCtx.restore(); - copyCtxState(this.suspendedCtx, this.ctx); - } else { - this.ctx.restore(); - } + this.__originalLineTo(x, y); + };
- this.checkSMaskState(); - this.pendingClip = null; - this._cachedScaleForStroking = null; - this._cachedGetSinglePixelWidth = null; - } - } + ctx.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) { + destCtx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
- transform(a, b, c, d, e, f) { - this.ctx.transform(a, b, c, d, e, f); - this._cachedScaleForStroking = null; - this._cachedGetSinglePixelWidth = null; - } + this.__originalBezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); + };
- constructPath(ops, args, minMax) { - const ctx = this.ctx; - const current = this.current; - let x = current.x, - y = current.y; - let startX, startY; - const currentTransform = ctx.mozCurrentTransform; - const isScalingMatrix = currentTransform[0] === 0 && currentTransform[3] === 0 || currentTransform[1] === 0 && currentTransform[2] === 0; - const minMaxForBezier = isScalingMatrix ? minMax.slice(0) : null; + ctx.rect = function (x, y, width, height) { + destCtx.rect(x, y, width, height);
- for (let i = 0, j = 0, ii = ops.length; i < ii; i++) { - switch (ops[i] | 0) { - case _util.OPS.rectangle: - x = args[j++]; - y = args[j++]; - const width = args[j++]; - const height = args[j++]; - const xw = x + width; - const yh = y + height; - ctx.moveTo(x, y); + this.__originalRect(x, y, width, height); + };
- if (width === 0 || height === 0) { - ctx.lineTo(xw, yh); - } else { - ctx.lineTo(xw, y); - ctx.lineTo(xw, yh); - ctx.lineTo(x, yh); - } + ctx.closePath = function () { + destCtx.closePath();
- if (!isScalingMatrix) { - current.updateRectMinMax(currentTransform, [x, y, xw, yh]); - } + this.__originalClosePath(); + };
- ctx.closePath(); - break; + ctx.beginPath = function () { + destCtx.beginPath();
- case _util.OPS.moveTo: - x = args[j++]; - y = args[j++]; - ctx.moveTo(x, y); + this.__originalBeginPath(); + }; +}
- if (!isScalingMatrix) { - current.updatePathMinMax(currentTransform, x, y); - } +function addContextCurrentTransform(ctx) { + if (ctx._transformStack) { + ctx._transformStack = []; + }
- break; + if (ctx.mozCurrentTransform) { + return; + }
- case _util.OPS.lineTo: - x = args[j++]; - y = args[j++]; - ctx.lineTo(x, y); + ctx._originalSave = ctx.save; + ctx._originalRestore = ctx.restore; + ctx._originalRotate = ctx.rotate; + ctx._originalScale = ctx.scale; + ctx._originalTranslate = ctx.translate; + ctx._originalTransform = ctx.transform; + ctx._originalSetTransform = ctx.setTransform; + ctx._originalResetTransform = ctx.resetTransform; + ctx._transformMatrix = ctx._transformMatrix || [1, 0, 0, 1, 0, 0]; + ctx._transformStack = [];
- if (!isScalingMatrix) { - current.updatePathMinMax(currentTransform, x, y); - } + try { + const desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(ctx), "lineWidth"); + ctx._setLineWidth = desc.set; + ctx._getLineWidth = desc.get; + Object.defineProperty(ctx, "lineWidth", { + set: function setLineWidth(width) { + this._setLineWidth(width * LINEWIDTH_SCALE_FACTOR); + }, + get: function getLineWidth() { + return this._getLineWidth(); + } + }); + } catch (_) {}
- break; + Object.defineProperty(ctx, "mozCurrentTransform", { + get: function getCurrentTransform() { + return this._transformMatrix; + } + }); + Object.defineProperty(ctx, "mozCurrentTransformInverse", { + get: function getCurrentTransformInverse() { + const [a, b, c, d, e, f] = this._transformMatrix; + const ad_bc = a * d - b * c; + const bc_ad = b * c - a * d; + return [d / ad_bc, b / bc_ad, c / bc_ad, a / ad_bc, (d * e - c * f) / bc_ad, (b * e - a * f) / ad_bc]; + } + });
- case _util.OPS.curveTo: - startX = x; - startY = y; - x = args[j + 4]; - y = args[j + 5]; - ctx.bezierCurveTo(args[j], args[j + 1], args[j + 2], args[j + 3], x, y); - current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], args[j + 2], args[j + 3], x, y, minMaxForBezier); - j += 6; - break; + ctx.save = function ctxSave() { + const old = this._transformMatrix;
- case _util.OPS.curveTo2: - startX = x; - startY = y; - ctx.bezierCurveTo(x, y, args[j], args[j + 1], args[j + 2], args[j + 3]); - current.updateCurvePathMinMax(currentTransform, startX, startY, x, y, args[j], args[j + 1], args[j + 2], args[j + 3], minMaxForBezier); - x = args[j + 2]; - y = args[j + 3]; - j += 4; - break; + this._transformStack.push(old);
- case _util.OPS.curveTo3: - startX = x; - startY = y; - x = args[j + 2]; - y = args[j + 3]; - ctx.bezierCurveTo(args[j], args[j + 1], x, y, x, y); - current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], x, y, x, y, minMaxForBezier); - j += 4; - break; + this._transformMatrix = old.slice(0, 6);
- case _util.OPS.closePath: - ctx.closePath(); - break; - } - } + this._originalSave(); + };
- if (isScalingMatrix) { - current.updateScalingPathMinMax(currentTransform, minMaxForBezier); + ctx.restore = function ctxRestore() { + if (this._transformStack.length === 0) { + (0, _util.warn)("Tried to restore a ctx when the stack was already empty."); }
- current.setCurrentPoint(x, y); - } - - closePath() { - this.ctx.closePath(); - } + const prev = this._transformStack.pop();
- stroke(consumePath) { - consumePath = typeof consumePath !== "undefined" ? consumePath : true; - const ctx = this.ctx; - const strokeColor = this.current.strokeColor; - ctx.globalAlpha = this.current.strokeAlpha; + if (prev) { + this._transformMatrix = prev;
- if (this.contentVisible) { - if (typeof strokeColor === "object" && strokeColor?.getPattern) { - ctx.save(); - ctx.strokeStyle = strokeColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.STROKE); - this.rescaleAndStroke(false); - ctx.restore(); - } else { - this.rescaleAndStroke(true); - } + this._originalRestore(); } + };
- if (consumePath) { - this.consumePath(this.current.getClippedPathBoundingBox()); - } + ctx.translate = function ctxTranslate(x, y) { + const m = this._transformMatrix; + m[4] = m[0] * x + m[2] * y + m[4]; + m[5] = m[1] * x + m[3] * y + m[5];
- ctx.globalAlpha = this.current.fillAlpha; - } + this._originalTranslate(x, y); + };
- closeStroke() { - this.closePath(); - this.stroke(); - } + ctx.scale = function ctxScale(x, y) { + const m = this._transformMatrix; + m[0] *= x; + m[1] *= x; + m[2] *= y; + m[3] *= y;
- fill(consumePath) { - consumePath = typeof consumePath !== "undefined" ? consumePath : true; - const ctx = this.ctx; - const fillColor = this.current.fillColor; - const isPatternFill = this.current.patternFill; - let needRestore = false; + this._originalScale(x, y); + };
- if (isPatternFill) { - ctx.save(); - ctx.fillStyle = fillColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL); - needRestore = true; - } + ctx.transform = function ctxTransform(a, b, c, d, e, f) { + const m = this._transformMatrix; + this._transformMatrix = [m[0] * a + m[2] * b, m[1] * a + m[3] * b, m[0] * c + m[2] * d, m[1] * c + m[3] * d, m[0] * e + m[2] * f + m[4], m[1] * e + m[3] * f + m[5]];
- const intersect = this.current.getClippedPathBoundingBox(); + ctx._originalTransform(a, b, c, d, e, f); + };
- if (this.contentVisible && intersect !== null) { - if (this.pendingEOFill) { - ctx.fill("evenodd"); - this.pendingEOFill = false; - } else { - ctx.fill(); - } - } + ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) { + this._transformMatrix = [a, b, c, d, e, f];
- if (needRestore) { - ctx.restore(); - } + ctx._originalSetTransform(a, b, c, d, e, f); + };
- if (consumePath) { - this.consumePath(intersect); - } - } + ctx.resetTransform = function ctxResetTransform() { + this._transformMatrix = [1, 0, 0, 1, 0, 0];
- eoFill() { - this.pendingEOFill = true; - this.fill(); - } + ctx._originalResetTransform(); + };
- fillStroke() { - this.fill(false); - this.stroke(false); - this.consumePath(); - } + ctx.rotate = function ctxRotate(angle) { + const cosValue = Math.cos(angle); + const sinValue = Math.sin(angle); + const m = this._transformMatrix; + this._transformMatrix = [m[0] * cosValue + m[2] * sinValue, m[1] * cosValue + m[3] * sinValue, m[0] * -sinValue + m[2] * cosValue, m[1] * -sinValue + m[3] * cosValue, m[4], m[5]];
- eoFillStroke() { - this.pendingEOFill = true; - this.fillStroke(); - } + this._originalRotate(angle); + }; +}
- closeFillStroke() { - this.closePath(); - this.fillStroke(); +class CachedCanvases { + constructor(canvasFactory) { + this.canvasFactory = canvasFactory; + this.cache = Object.create(null); }
- closeEOFillStroke() { - this.pendingEOFill = true; - this.closePath(); - this.fillStroke(); - } + getCanvas(id, width, height, trackTransform) { + let canvasEntry;
- endPath() { - this.consumePath(); - } + if (this.cache[id] !== undefined) { + canvasEntry = this.cache[id]; + this.canvasFactory.reset(canvasEntry, width, height); + canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0); + } else { + canvasEntry = this.canvasFactory.create(width, height); + this.cache[id] = canvasEntry; + }
- clip() { - this.pendingClip = NORMAL_CLIP; - } + if (trackTransform) { + addContextCurrentTransform(canvasEntry.context); + }
- eoClip() { - this.pendingClip = EO_CLIP; + return canvasEntry; }
- beginText() { - this.current.textMatrix = _util.IDENTITY_MATRIX; - this.current.textMatrixScale = 1; - this.current.x = this.current.lineX = 0; - this.current.y = this.current.lineY = 0; + delete(id) { + delete this.cache[id]; }
- endText() { - const paths = this.pendingTextPaths; - const ctx = this.ctx; - - if (paths === undefined) { - ctx.beginPath(); - return; + clear() { + for (const id in this.cache) { + const canvasEntry = this.cache[id]; + this.canvasFactory.destroy(canvasEntry); + delete this.cache[id]; } + }
- ctx.save(); - ctx.beginPath(); +}
- for (let i = 0; i < paths.length; i++) { - const path = paths[i]; - ctx.setTransform.apply(ctx, path.transform); - ctx.translate(path.x, path.y); - path.addToPath(ctx, path.fontSize); - } +function drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH) { + const [a, b, c, d, tx, ty] = ctx.mozCurrentTransform;
- ctx.restore(); - ctx.clip(); - ctx.beginPath(); - delete this.pendingTextPaths; + if (b === 0 && c === 0) { + const tlX = destX * a + tx; + const rTlX = Math.round(tlX); + const tlY = destY * d + ty; + const rTlY = Math.round(tlY); + const brX = (destX + destW) * a + tx; + const rWidth = Math.abs(Math.round(brX) - rTlX) || 1; + const brY = (destY + destH) * d + ty; + const rHeight = Math.abs(Math.round(brY) - rTlY) || 1; + ctx.setTransform(Math.sign(a), 0, 0, Math.sign(d), rTlX, rTlY); + ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rWidth, rHeight); + ctx.setTransform(a, b, c, d, tx, ty); + return [rWidth, rHeight]; }
- setCharSpacing(spacing) { - this.current.charSpacing = spacing; + if (a === 0 && d === 0) { + const tlX = destY * c + tx; + const rTlX = Math.round(tlX); + const tlY = destX * b + ty; + const rTlY = Math.round(tlY); + const brX = (destY + destH) * c + tx; + const rWidth = Math.abs(Math.round(brX) - rTlX) || 1; + const brY = (destX + destW) * b + ty; + const rHeight = Math.abs(Math.round(brY) - rTlY) || 1; + ctx.setTransform(0, Math.sign(b), Math.sign(c), 0, rTlX, rTlY); + ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rHeight, rWidth); + ctx.setTransform(a, b, c, d, tx, ty); + return [rHeight, rWidth]; }
- setWordSpacing(spacing) { - this.current.wordSpacing = spacing; - } + ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH); + const scaleX = Math.hypot(a, b); + const scaleY = Math.hypot(c, d); + return [scaleX * destW, scaleY * destH]; +}
- setHScale(scale) { - this.current.textHScale = scale / 100; - } +function compileType3Glyph(imgData) { + const { + width, + height + } = imgData;
- setLeading(leading) { - this.current.leading = -leading; + if (!COMPILE_TYPE3_GLYPHS || width > MAX_SIZE_TO_COMPILE || height > MAX_SIZE_TO_COMPILE) { + return null; }
- setFont(fontRefName, size) { - const fontObj = this.commonObjs.get(fontRefName); - const current = this.current; + const POINT_TO_PROCESS_LIMIT = 1000; + const POINT_TYPES = new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]); + const width1 = width + 1; + let points = new Uint8Array(width1 * (height + 1)); + let i, j, j0; + const lineSize = width + 7 & ~7; + let data = new Uint8Array(lineSize * height), + pos = 0;
- if (!fontObj) { - throw new Error(`Can't find font for ${fontRefName}`); + for (const elem of imgData.data) { + let mask = 128; + + while (mask > 0) { + data[pos++] = elem & mask ? 0 : 255; + mask >>= 1; } + }
- current.fontMatrix = fontObj.fontMatrix || _util.FONT_IDENTITY_MATRIX; + let count = 0; + pos = 0;
- if (current.fontMatrix[0] === 0 || current.fontMatrix[3] === 0) { - (0, _util.warn)("Invalid font matrix for font " + fontRefName); - } + if (data[pos] !== 0) { + points[0] = 1; + ++count; + }
- if (size < 0) { - size = -size; - current.fontDirection = -1; - } else { - current.fontDirection = 1; + for (j = 1; j < width; j++) { + if (data[pos] !== data[pos + 1]) { + points[j] = data[pos] ? 2 : 1; + ++count; }
- this.current.font = fontObj; - this.current.fontSize = size; + pos++; + }
- if (fontObj.isType3Font) { - return; - } + if (data[pos] !== 0) { + points[j] = 2; + ++count; + }
- const name = fontObj.loadedName || "sans-serif"; - let bold = "normal"; + for (i = 1; i < height; i++) { + pos = i * lineSize; + j0 = i * width1;
- if (fontObj.black) { - bold = "900"; - } else if (fontObj.bold) { - bold = "bold"; + if (data[pos - lineSize] !== data[pos]) { + points[j0] = data[pos] ? 1 : 8; + ++count; }
- const italic = fontObj.italic ? "italic" : "normal"; - const typeface = `"${name}", ${fontObj.fallbackName}`; - let browserFontSize = size; + let sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0);
- if (size < MIN_FONT_SIZE) { - browserFontSize = MIN_FONT_SIZE; - } else if (size > MAX_FONT_SIZE) { - browserFontSize = MAX_FONT_SIZE; + for (j = 1; j < width; j++) { + sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + (data[pos - lineSize + 1] ? 8 : 0); + + if (POINT_TYPES[sum]) { + points[j0 + j] = POINT_TYPES[sum]; + ++count; + } + + pos++; }
- this.current.fontSizeScale = size / browserFontSize; - this.ctx.font = `${italic} ${bold} ${browserFontSize}px ${typeface}`; - } + if (data[pos - lineSize] !== data[pos]) { + points[j0 + j] = data[pos] ? 2 : 4; + ++count; + }
- setTextRenderingMode(mode) { - this.current.textRenderingMode = mode; + if (count > POINT_TO_PROCESS_LIMIT) { + return null; + } }
- setTextRise(rise) { - this.current.textRise = rise; - } + pos = lineSize * (height - 1); + j0 = i * width1;
- moveText(x, y) { - this.current.x = this.current.lineX += x; - this.current.y = this.current.lineY += y; + if (data[pos] !== 0) { + points[j0] = 8; + ++count; }
- setLeadingMoveText(x, y) { - this.setLeading(-y); - this.moveText(x, y); - } + for (j = 1; j < width; j++) { + if (data[pos] !== data[pos + 1]) { + points[j0 + j] = data[pos] ? 4 : 8; + ++count; + }
- setTextMatrix(a, b, c, d, e, f) { - this.current.textMatrix = [a, b, c, d, e, f]; - this.current.textMatrixScale = Math.hypot(a, b); - this.current.x = this.current.lineX = 0; - this.current.y = this.current.lineY = 0; + pos++; }
- nextLine() { - this.moveText(0, this.current.leading); + if (data[pos] !== 0) { + points[j0 + j] = 4; + ++count; }
- paintChar(character, x, y, patternTransform) { - const ctx = this.ctx; - const current = this.current; - const font = current.font; - const textRenderingMode = current.textRenderingMode; - const fontSize = current.fontSize / current.fontSizeScale; - const fillStrokeMode = textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; - const isAddToPathSet = !!(textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG); - const patternFill = current.patternFill && !font.missingFile; - let addToPath; + if (count > POINT_TO_PROCESS_LIMIT) { + return null; + }
- if (font.disableFontFace || isAddToPathSet || patternFill) { - addToPath = font.getPathGenerator(this.commonObjs, character); - } + const steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]); + let path, outlines, coords;
- if (font.disableFontFace || patternFill) { - ctx.save(); - ctx.translate(x, y); - ctx.beginPath(); - addToPath(ctx, fontSize); + if (!_is_node.isNodeJS) { + path = new Path2D(); + } else { + outlines = []; + }
- if (patternTransform) { - ctx.setTransform.apply(ctx, patternTransform); - } + for (i = 0; count && i <= height; i++) { + let p = i * width1; + const end = p + width;
- if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { - ctx.fill(); - } + while (p < end && !points[p]) { + p++; + }
- if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { - ctx.stroke(); - } + if (p === end) { + continue; + }
- ctx.restore(); + if (path) { + path.moveTo(p % width1, i); } else { - if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { - ctx.fillText(character, x, y); - } - - if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { - ctx.strokeText(character, x, y); - } + coords = [p % width1, i]; }
- if (isAddToPathSet) { - const paths = this.pendingTextPaths || (this.pendingTextPaths = []); - paths.push({ - transform: ctx.mozCurrentTransform, - x, - y, - fontSize, - addToPath - }); - } - } + const p0 = p; + let type = points[p];
- get isFontSubpixelAAEnabled() { - const { - context: ctx - } = this.cachedCanvases.getCanvas("isFontSubpixelAAEnabled", 10, 10, false); - ctx.scale(1.5, 1); - ctx.fillText("I", 0, 10); - const data = ctx.getImageData(0, 0, 10, 10).data; - let enabled = false; + do { + const step = steps[type];
- for (let i = 3; i < data.length; i += 4) { - if (data[i] > 0 && data[i] < 255) { - enabled = true; - break; - } - } + do { + p += step; + } while (!points[p]);
- return (0, _util.shadow)(this, "isFontSubpixelAAEnabled", enabled); - } + const pp = points[p];
- showText(glyphs) { - const current = this.current; - const font = current.font; + if (pp !== 5 && pp !== 10) { + type = pp; + points[p] = 0; + } else { + type = pp & 0x33 * type >> 4; + points[p] &= type >> 2 | type << 2; + }
- if (font.isType3Font) { - return this.showType3Text(glyphs); - } + if (path) { + path.lineTo(p % width1, p / width1 | 0); + } else { + coords.push(p % width1, p / width1 | 0); + }
- const fontSize = current.fontSize; + if (!points[p]) { + --count; + } + } while (p0 !== p);
- if (fontSize === 0) { - return undefined; + if (!path) { + outlines.push(coords); }
- const ctx = this.ctx; - const fontSizeScale = current.fontSizeScale; - const charSpacing = current.charSpacing; - const wordSpacing = current.wordSpacing; - const fontDirection = current.fontDirection; - const textHScale = current.textHScale * fontDirection; - const glyphsLength = glyphs.length; - const vertical = font.vertical; - const spacingDir = vertical ? 1 : -1; - const defaultVMetrics = font.defaultVMetrics; - const widthAdvanceScale = fontSize * current.fontMatrix[0]; - const simpleFillText = current.textRenderingMode === _util.TextRenderingMode.FILL && !font.disableFontFace && !current.patternFill; - ctx.save(); - ctx.transform.apply(ctx, current.textMatrix); - ctx.translate(current.x, current.y + current.textRise); - - if (fontDirection > 0) { - ctx.scale(textHScale, -1); - } else { - ctx.scale(textHScale, 1); - } + --i; + }
- let patternTransform; + data = null; + points = null;
- if (current.patternFill) { - ctx.save(); - const pattern = current.fillColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL); - patternTransform = ctx.mozCurrentTransform; - ctx.restore(); - ctx.fillStyle = pattern; - } + const drawOutline = function (c) { + c.save(); + c.scale(1 / width, -1 / height); + c.translate(0, -height);
- let lineWidth = current.lineWidth; - const scale = current.textMatrixScale; + if (path) { + c.fill(path); + } else { + c.beginPath();
- if (scale === 0 || lineWidth === 0) { - const fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; + for (const o of outlines) { + c.moveTo(o[0], o[1]);
- if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { - lineWidth = this.getSinglePixelWidth(); + for (let l = 2, ll = o.length; l < ll; l += 2) { + c.lineTo(o[l], o[l + 1]); + } } - } else { - lineWidth /= scale; - }
- if (fontSizeScale !== 1.0) { - ctx.scale(fontSizeScale, fontSizeScale); - lineWidth /= fontSizeScale; + c.fill(); }
- ctx.lineWidth = lineWidth; - let x = 0, - i; - - for (i = 0; i < glyphsLength; ++i) { - const glyph = glyphs[i]; - - if (typeof glyph === "number") { - x += spacingDir * glyph * fontSize / 1000; - continue; - } + c.beginPath(); + c.restore(); + };
- let restoreNeeded = false; - const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; - const character = glyph.fontChar; - const accent = glyph.accent; - let scaledX, scaledY; - let width = glyph.width; + return drawOutline; +}
- if (vertical) { - const vmetric = glyph.vmetric || defaultVMetrics; - const vx = -(glyph.vmetric ? vmetric[1] : width * 0.5) * widthAdvanceScale; - const vy = vmetric[2] * widthAdvanceScale; - width = vmetric ? -vmetric[0] : width; - scaledX = vx / fontSizeScale; - scaledY = (x + vy) / fontSizeScale; - } else { - scaledX = x / fontSizeScale; - scaledY = 0; - } - - if (font.remeasure && width > 0) { - const measuredWidth = ctx.measureText(character).width * 1000 / fontSize * fontSizeScale; - - if (width < measuredWidth && this.isFontSubpixelAAEnabled) { - const characterScaleX = width / measuredWidth; - restoreNeeded = true; - ctx.save(); - ctx.scale(characterScaleX, 1); - scaledX /= characterScaleX; - } else if (width !== measuredWidth) { - scaledX += (width - measuredWidth) / 2000 * fontSize / fontSizeScale; - } - } +class CanvasExtraState { + constructor(width, height) { + this.alphaIsShape = false; + this.fontSize = 0; + this.fontSizeScale = 1; + this.textMatrix = _util.IDENTITY_MATRIX; + this.textMatrixScale = 1; + this.fontMatrix = _util.FONT_IDENTITY_MATRIX; + this.leading = 0; + this.x = 0; + this.y = 0; + this.lineX = 0; + this.lineY = 0; + this.charSpacing = 0; + this.wordSpacing = 0; + this.textHScale = 1; + this.textRenderingMode = _util.TextRenderingMode.FILL; + this.textRise = 0; + this.fillColor = "#000000"; + this.strokeColor = "#000000"; + this.patternFill = false; + this.fillAlpha = 1; + this.strokeAlpha = 1; + this.lineWidth = 1; + this.activeSMask = null; + this.transferMaps = null; + this.startNewPathAndClipBox([0, 0, width, height]); + }
- if (this.contentVisible && (glyph.isInFont || font.missingFile)) { - if (simpleFillText && !accent) { - ctx.fillText(character, scaledX, scaledY); - } else { - this.paintChar(character, scaledX, scaledY, patternTransform); + clone() { + const clone = Object.create(this); + clone.clipBox = this.clipBox.slice(); + return clone; + }
- if (accent) { - const scaledAccentX = scaledX + fontSize * accent.offset.x / fontSizeScale; - const scaledAccentY = scaledY - fontSize * accent.offset.y / fontSizeScale; - this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY, patternTransform); - } - } - } + setCurrentPoint(x, y) { + this.x = x; + this.y = y; + }
- let charWidth; + updatePathMinMax(transform, x, y) { + [x, y] = _util.Util.applyTransform([x, y], transform); + this.minX = Math.min(this.minX, x); + this.minY = Math.min(this.minY, y); + this.maxX = Math.max(this.maxX, x); + this.maxY = Math.max(this.maxY, y); + }
- if (vertical) { - charWidth = width * widthAdvanceScale - spacing * fontDirection; - } else { - charWidth = width * widthAdvanceScale + spacing * fontDirection; - } + updateRectMinMax(transform, rect) { + const p1 = _util.Util.applyTransform(rect, transform);
- x += charWidth; + const p2 = _util.Util.applyTransform(rect.slice(2), transform);
- if (restoreNeeded) { - ctx.restore(); - } - } + this.minX = Math.min(this.minX, p1[0], p2[0]); + this.minY = Math.min(this.minY, p1[1], p2[1]); + this.maxX = Math.max(this.maxX, p1[0], p2[0]); + this.maxY = Math.max(this.maxY, p1[1], p2[1]); + }
- if (vertical) { - current.y -= x; - } else { - current.x += x * textHScale; - } + updateScalingPathMinMax(transform, minMax) { + _util.Util.scaleMinMax(transform, minMax);
- ctx.restore(); - this.compose(); - return undefined; + this.minX = Math.min(this.minX, minMax[0]); + this.maxX = Math.max(this.maxX, minMax[1]); + this.minY = Math.min(this.minY, minMax[2]); + this.maxY = Math.max(this.maxY, minMax[3]); }
- showType3Text(glyphs) { - const ctx = this.ctx; - const current = this.current; - const font = current.font; - const fontSize = current.fontSize; - const fontDirection = current.fontDirection; - const spacingDir = font.vertical ? 1 : -1; - const charSpacing = current.charSpacing; - const wordSpacing = current.wordSpacing; - const textHScale = current.textHScale * fontDirection; - const fontMatrix = current.fontMatrix || _util.FONT_IDENTITY_MATRIX; - const glyphsLength = glyphs.length; - const isTextInvisible = current.textRenderingMode === _util.TextRenderingMode.INVISIBLE; - let i, glyph, width, spacingLength; + updateCurvePathMinMax(transform, x0, y0, x1, y1, x2, y2, x3, y3, minMax) { + const box = _util.Util.bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3);
- if (isTextInvisible || fontSize === 0) { + if (minMax) { + minMax[0] = Math.min(minMax[0], box[0], box[2]); + minMax[1] = Math.max(minMax[1], box[0], box[2]); + minMax[2] = Math.min(minMax[2], box[1], box[3]); + minMax[3] = Math.max(minMax[3], box[1], box[3]); return; }
- this._cachedScaleForStroking = null; - this._cachedGetSinglePixelWidth = null; - ctx.save(); - ctx.transform.apply(ctx, current.textMatrix); - ctx.translate(current.x, current.y); - ctx.scale(textHScale, fontDirection); - - for (i = 0; i < glyphsLength; ++i) { - glyph = glyphs[i]; - - if (typeof glyph === "number") { - spacingLength = spacingDir * glyph * fontSize / 1000; - this.ctx.translate(spacingLength, 0); - current.x += spacingLength * textHScale; - continue; - } - - const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; - const operatorList = font.charProcOperatorList[glyph.operatorListId]; + this.updateRectMinMax(transform, box); + }
- if (!operatorList) { - (0, _util.warn)(`Type3 character "${glyph.operatorListId}" is not available.`); - continue; - } + getPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) { + const box = [this.minX, this.minY, this.maxX, this.maxY];
- if (this.contentVisible) { - this.processingType3 = glyph; - this.save(); - ctx.scale(fontSize, fontSize); - ctx.transform.apply(ctx, fontMatrix); - this.executeOperatorList(operatorList); - this.restore(); + if (pathType === _pattern_helper.PathType.STROKE) { + if (!transform) { + (0, _util.unreachable)("Stroke bounding box must include transform."); }
- const transformed = _util.Util.applyTransform([glyph.width, 0], fontMatrix); + const scale = _util.Util.singularValueDecompose2dScale(transform);
- width = transformed[0] * fontSize + spacing; - ctx.translate(width, 0); - current.x += width * textHScale; + const xStrokePad = scale[0] * this.lineWidth / 2; + const yStrokePad = scale[1] * this.lineWidth / 2; + box[0] -= xStrokePad; + box[1] -= yStrokePad; + box[2] += xStrokePad; + box[3] += yStrokePad; }
- ctx.restore(); - this.processingType3 = null; + return box; }
- setCharWidth(xWidth, yWidth) {} + updateClipFromPath() { + const intersect = _util.Util.intersect(this.clipBox, this.getPathBoundingBox());
- setCharWidthAndBounds(xWidth, yWidth, llx, lly, urx, ury) { - this.ctx.rect(llx, lly, urx - llx, ury - lly); - this.ctx.clip(); - this.endPath(); + this.startNewPathAndClipBox(intersect || [0, 0, 0, 0]); }
- getColorN_Pattern(IR) { - let pattern; - - if (IR[0] === "TilingPattern") { - const color = IR[1]; - const baseTransform = this.baseTransform || this.ctx.mozCurrentTransform.slice(); - const canvasGraphicsFactory = { - createCanvasGraphics: ctx => { - return new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory); - } - }; - pattern = new _pattern_helper.TilingPattern(IR, color, this.ctx, canvasGraphicsFactory, baseTransform); - } else { - pattern = this._getPattern(IR[1], IR[2]); - } - - return pattern; + isEmptyClip() { + return this.minX === Infinity; }
- setStrokeColorN() { - this.current.strokeColor = this.getColorN_Pattern(arguments); + startNewPathAndClipBox(box) { + this.clipBox = box; + this.minX = Infinity; + this.minY = Infinity; + this.maxX = 0; + this.maxY = 0; }
- setFillColorN() { - this.current.fillColor = this.getColorN_Pattern(arguments); - this.current.patternFill = true; + getClippedPathBoundingBox(pathType = _pattern_helper.PathType.FILL, transform = null) { + return _util.Util.intersect(this.clipBox, this.getPathBoundingBox(pathType, transform)); }
- setStrokeRGBColor(r, g, b) { - const color = this.selectColor?.(r, g, b) || _util.Util.makeHexColor(r, g, b); +}
- this.ctx.strokeStyle = color; - this.current.strokeColor = color; +function putBinaryImageData(ctx, imgData, transferMaps = null) { + if (typeof ImageData !== "undefined" && imgData instanceof ImageData) { + ctx.putImageData(imgData, 0, 0); + return; }
- setFillRGBColor(r, g, b) { - const color = this.selectColor?.(r, g, b) || _util.Util.makeHexColor(r, g, b); + const height = imgData.height, + width = imgData.width; + const partialChunkHeight = height % FULL_CHUNK_HEIGHT; + const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; + const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; + const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); + let srcPos = 0, + destPos; + const src = imgData.data; + const dest = chunkImgData.data; + let i, j, thisChunkHeight, elemsInThisChunk; + let transferMapRed, transferMapGreen, transferMapBlue, transferMapGray; + + if (transferMaps) { + switch (transferMaps.length) { + case 1: + transferMapRed = transferMaps[0]; + transferMapGreen = transferMaps[0]; + transferMapBlue = transferMaps[0]; + transferMapGray = transferMaps[0]; + break; + + case 4: + transferMapRed = transferMaps[0]; + transferMapGreen = transferMaps[1]; + transferMapBlue = transferMaps[2]; + transferMapGray = transferMaps[3]; + break; + } + } + + if (imgData.kind === _util.ImageKind.GRAYSCALE_1BPP) { + const srcLength = src.byteLength; + const dest32 = new Uint32Array(dest.buffer, 0, dest.byteLength >> 2); + const dest32DataLength = dest32.length; + const fullSrcDiff = width + 7 >> 3; + let white = 0xffffffff; + let black = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; + + if (transferMapGray) { + if (transferMapGray[0] === 0xff && transferMapGray[0xff] === 0) { + [white, black] = [black, white]; + } + } + + for (i = 0; i < totalChunks; i++) { + thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight; + destPos = 0; + + for (j = 0; j < thisChunkHeight; j++) { + const srcDiff = srcLength - srcPos; + let k = 0; + const kEnd = srcDiff > fullSrcDiff ? width : srcDiff * 8 - 7; + const kEndUnrolled = kEnd & ~7; + let mask = 0; + let srcByte = 0; + + for (; k < kEndUnrolled; k += 8) { + srcByte = src[srcPos++]; + dest32[destPos++] = srcByte & 128 ? white : black; + dest32[destPos++] = srcByte & 64 ? white : black; + dest32[destPos++] = srcByte & 32 ? white : black; + dest32[destPos++] = srcByte & 16 ? white : black; + dest32[destPos++] = srcByte & 8 ? white : black; + dest32[destPos++] = srcByte & 4 ? white : black; + dest32[destPos++] = srcByte & 2 ? white : black; + dest32[destPos++] = srcByte & 1 ? white : black; + } + + for (; k < kEnd; k++) { + if (mask === 0) { + srcByte = src[srcPos++]; + mask = 128; + } + + dest32[destPos++] = srcByte & mask ? white : black; + mask >>= 1; + } + } + + while (destPos < dest32DataLength) { + dest32[destPos++] = 0; + } + + ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); + } + } else if (imgData.kind === _util.ImageKind.RGBA_32BPP) { + const hasTransferMaps = !!(transferMapRed || transferMapGreen || transferMapBlue); + j = 0; + elemsInThisChunk = width * FULL_CHUNK_HEIGHT * 4; + + for (i = 0; i < fullChunks; i++) { + dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); + srcPos += elemsInThisChunk; + + if (hasTransferMaps) { + for (let k = 0; k < elemsInThisChunk; k += 4) { + if (transferMapRed) { + dest[k + 0] = transferMapRed[dest[k + 0]]; + } + + if (transferMapGreen) { + dest[k + 1] = transferMapGreen[dest[k + 1]]; + } + + if (transferMapBlue) { + dest[k + 2] = transferMapBlue[dest[k + 2]]; + } + } + } + + ctx.putImageData(chunkImgData, 0, j); + j += FULL_CHUNK_HEIGHT; + } + + if (i < totalChunks) { + elemsInThisChunk = width * partialChunkHeight * 4; + dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); + + if (hasTransferMaps) { + for (let k = 0; k < elemsInThisChunk; k += 4) { + if (transferMapRed) { + dest[k + 0] = transferMapRed[dest[k + 0]]; + } + + if (transferMapGreen) { + dest[k + 1] = transferMapGreen[dest[k + 1]]; + } + + if (transferMapBlue) { + dest[k + 2] = transferMapBlue[dest[k + 2]]; + } + } + } + + ctx.putImageData(chunkImgData, 0, j); + } + } else if (imgData.kind === _util.ImageKind.RGB_24BPP) { + const hasTransferMaps = !!(transferMapRed || transferMapGreen || transferMapBlue); + thisChunkHeight = FULL_CHUNK_HEIGHT; + elemsInThisChunk = width * thisChunkHeight; + + for (i = 0; i < totalChunks; i++) { + if (i >= fullChunks) { + thisChunkHeight = partialChunkHeight; + elemsInThisChunk = width * thisChunkHeight; + } + + destPos = 0; + + for (j = elemsInThisChunk; j--;) { + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; + dest[destPos++] = 255; + } + + if (hasTransferMaps) { + for (let k = 0; k < destPos; k += 4) { + if (transferMapRed) { + dest[k + 0] = transferMapRed[dest[k + 0]]; + } + + if (transferMapGreen) { + dest[k + 1] = transferMapGreen[dest[k + 1]]; + } + + if (transferMapBlue) { + dest[k + 2] = transferMapBlue[dest[k + 2]]; + } + } + } + + ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); + } + } else { + throw new Error(`bad image kind: ${imgData.kind}`); + } +} + +function putBinaryImageMask(ctx, imgData) { + if (imgData.bitmap) { + ctx.drawImage(imgData.bitmap, 0, 0); + return; + } + + const height = imgData.height, + width = imgData.width; + const partialChunkHeight = height % FULL_CHUNK_HEIGHT; + const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; + const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; + const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); + let srcPos = 0; + const src = imgData.data; + const dest = chunkImgData.data; + + for (let i = 0; i < totalChunks; i++) { + const thisChunkHeight = i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight; + ({ + srcPos + } = (0, _image_utils.applyMaskImageData)({ + src, + srcPos, + dest, + width, + height: thisChunkHeight + })); + ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); + } +} + +function copyCtxState(sourceCtx, destCtx) { + const properties = ["strokeStyle", "fillStyle", "fillRule", "globalAlpha", "lineWidth", "lineCap", "lineJoin", "miterLimit", "globalCompositeOperation", "font"]; + + for (let i = 0, ii = properties.length; i < ii; i++) { + const property = properties[i]; + + if (sourceCtx[property] !== undefined) { + destCtx[property] = sourceCtx[property]; + } + } + + if (sourceCtx.setLineDash !== undefined) { + destCtx.setLineDash(sourceCtx.getLineDash()); + destCtx.lineDashOffset = sourceCtx.lineDashOffset; + } +} + +function resetCtxToDefault(ctx, foregroundColor) { + ctx.strokeStyle = ctx.fillStyle = foregroundColor || "#000000"; + ctx.fillRule = "nonzero"; + ctx.globalAlpha = 1; + ctx.lineWidth = 1; + ctx.lineCap = "butt"; + ctx.lineJoin = "miter"; + ctx.miterLimit = 10; + ctx.globalCompositeOperation = "source-over"; + ctx.font = "10px sans-serif"; + + if (ctx.setLineDash !== undefined) { + ctx.setLineDash([]); + ctx.lineDashOffset = 0; + } +} + +function composeSMaskBackdrop(bytes, r0, g0, b0) { + const length = bytes.length; + + for (let i = 3; i < length; i += 4) { + const alpha = bytes[i]; + + if (alpha === 0) { + bytes[i - 3] = r0; + bytes[i - 2] = g0; + bytes[i - 1] = b0; + } else if (alpha < 255) { + const alpha_ = 255 - alpha; + bytes[i - 3] = bytes[i - 3] * alpha + r0 * alpha_ >> 8; + bytes[i - 2] = bytes[i - 2] * alpha + g0 * alpha_ >> 8; + bytes[i - 1] = bytes[i - 1] * alpha + b0 * alpha_ >> 8; + } + } +} + +function composeSMaskAlpha(maskData, layerData, transferMap) { + const length = maskData.length; + const scale = 1 / 255; + + for (let i = 3; i < length; i += 4) { + const alpha = transferMap ? transferMap[maskData[i]] : maskData[i]; + layerData[i] = layerData[i] * alpha * scale | 0; + } +} + +function composeSMaskLuminosity(maskData, layerData, transferMap) { + const length = maskData.length; + + for (let i = 3; i < length; i += 4) { + const y = maskData[i - 3] * 77 + maskData[i - 2] * 152 + maskData[i - 1] * 28; + layerData[i] = transferMap ? layerData[i] * transferMap[y >> 8] >> 8 : layerData[i] * y >> 16; + } +} + +function genericComposeSMask(maskCtx, layerCtx, width, height, subtype, backdrop, transferMap, layerOffsetX, layerOffsetY, maskOffsetX, maskOffsetY) { + const hasBackdrop = !!backdrop; + const r0 = hasBackdrop ? backdrop[0] : 0; + const g0 = hasBackdrop ? backdrop[1] : 0; + const b0 = hasBackdrop ? backdrop[2] : 0; + let composeFn; + + if (subtype === "Luminosity") { + composeFn = composeSMaskLuminosity; + } else { + composeFn = composeSMaskAlpha; + } + + const PIXELS_TO_PROCESS = 1048576; + const chunkSize = Math.min(height, Math.ceil(PIXELS_TO_PROCESS / width)); + + for (let row = 0; row < height; row += chunkSize) { + const chunkHeight = Math.min(chunkSize, height - row); + const maskData = maskCtx.getImageData(layerOffsetX - maskOffsetX, row + (layerOffsetY - maskOffsetY), width, chunkHeight); + const layerData = layerCtx.getImageData(layerOffsetX, row + layerOffsetY, width, chunkHeight); + + if (hasBackdrop) { + composeSMaskBackdrop(maskData.data, r0, g0, b0); + } + + composeFn(maskData.data, layerData.data, transferMap); + layerCtx.putImageData(layerData, layerOffsetX, row + layerOffsetY); + } +} + +function composeSMask(ctx, smask, layerCtx, layerBox) { + const layerOffsetX = layerBox[0]; + const layerOffsetY = layerBox[1]; + const layerWidth = layerBox[2] - layerOffsetX; + const layerHeight = layerBox[3] - layerOffsetY; + + if (layerWidth === 0 || layerHeight === 0) { + return; + } + + genericComposeSMask(smask.context, layerCtx, layerWidth, layerHeight, smask.subtype, smask.backdrop, smask.transferMap, layerOffsetX, layerOffsetY, smask.offsetX, smask.offsetY); + ctx.save(); + ctx.globalAlpha = 1; + ctx.globalCompositeOperation = "source-over"; + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.drawImage(layerCtx.canvas, 0, 0); + ctx.restore(); +} + +function getImageSmoothingEnabled(transform, interpolate) { + const scale = _util.Util.singularValueDecompose2dScale(transform); + + scale[0] = Math.fround(scale[0]); + scale[1] = Math.fround(scale[1]); + const actualScale = Math.fround((globalThis.devicePixelRatio || 1) * _display_utils.PixelsPerInch.PDF_TO_CSS_UNITS); + + if (interpolate !== undefined) { + return interpolate; + } else if (scale[0] <= actualScale || scale[1] <= actualScale) { + return true; + } + + return false; +} + +const LINE_CAP_STYLES = ["butt", "round", "square"]; +const LINE_JOIN_STYLES = ["miter", "round", "bevel"]; +const NORMAL_CLIP = {}; +const EO_CLIP = {}; + +class CanvasGraphics { + constructor(canvasCtx, commonObjs, objs, canvasFactory, imageLayer, optionalContentConfig, annotationCanvasMap, pageColors) { + this.ctx = canvasCtx; + this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height); + this.stateStack = []; + this.pendingClip = null; + this.pendingEOFill = false; + this.res = null; + this.xobjs = null; + this.commonObjs = commonObjs; + this.objs = objs; + this.canvasFactory = canvasFactory; + this.imageLayer = imageLayer; + this.groupStack = []; + this.processingType3 = null; + this.baseTransform = null; + this.baseTransformStack = []; + this.groupLevel = 0; + this.smaskStack = []; + this.smaskCounter = 0; + this.tempSMask = null; + this.suspendedCtx = null; + this.contentVisible = true; + this.markedContentStack = []; + this.optionalContentConfig = optionalContentConfig; + this.cachedCanvases = new CachedCanvases(this.canvasFactory); + this.cachedPatterns = new Map(); + this.annotationCanvasMap = annotationCanvasMap; + this.viewportScale = 1; + this.outputScaleX = 1; + this.outputScaleY = 1; + this.backgroundColor = pageColors?.background || null; + this.foregroundColor = pageColors?.foreground || null; + + if (canvasCtx) { + addContextCurrentTransform(canvasCtx); + } + + this._cachedScaleForStroking = null; + this._cachedGetSinglePixelWidth = null; + this._cachedBitmapsMap = new Map(); + } + + getObject(data, fallback = null) { + if (typeof data === "string") { + return data.startsWith("g_") ? this.commonObjs.get(data) : this.objs.get(data); + } + + return fallback; + } + + beginDrawing({ + transform, + viewport, + transparency = false, + background = null + }) { + const width = this.ctx.canvas.width; + const height = this.ctx.canvas.height; + const defaultBackgroundColor = background || "#ffffff"; + this.ctx.save(); + + if (this.foregroundColor && this.backgroundColor) { + this.ctx.fillStyle = this.foregroundColor; + const fg = this.foregroundColor = this.ctx.fillStyle; + this.ctx.fillStyle = this.backgroundColor; + const bg = this.backgroundColor = this.ctx.fillStyle; + let isValidDefaultBg = true; + let defaultBg = defaultBackgroundColor; + + if (fg === "#000000" && bg === "#ffffff" || fg === bg || !isValidDefaultBg) { + this.foregroundColor = this.backgroundColor = null; + } else { + const [rB, gB, bB] = (0, _display_utils.getRGB)(defaultBg); + + const newComp = x => { + x /= 255; + return x <= 0.03928 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4; + }; + + const lumB = Math.round(0.2126 * newComp(rB) + 0.7152 * newComp(gB) + 0.0722 * newComp(bB)); + + this.selectColor = (r, g, b) => { + const lumC = 0.2126 * newComp(r) + 0.7152 * newComp(g) + 0.0722 * newComp(b); + return Math.round(lumC) === lumB ? bg : fg; + }; + } + } + + this.ctx.fillStyle = this.backgroundColor || defaultBackgroundColor; + this.ctx.fillRect(0, 0, width, height); + this.ctx.restore(); + + if (transparency) { + const transparentCanvas = this.cachedCanvases.getCanvas("transparent", width, height, true); + this.compositeCtx = this.ctx; + this.transparentCanvas = transparentCanvas.canvas; + this.ctx = transparentCanvas.context; + this.ctx.save(); + this.ctx.transform.apply(this.ctx, this.compositeCtx.mozCurrentTransform); + } + + this.ctx.save(); + resetCtxToDefault(this.ctx, this.foregroundColor); + + if (transform) { + this.ctx.transform.apply(this.ctx, transform); + this.outputScaleX = transform[0]; + this.outputScaleY = transform[0]; + } + + this.ctx.transform.apply(this.ctx, viewport.transform); + this.viewportScale = viewport.scale; + this.baseTransform = this.ctx.mozCurrentTransform.slice(); + + if (this.imageLayer) { + this.imageLayer.beginLayout(); + } + } + + executeOperatorList(operatorList, executionStartIdx, continueCallback, stepper) { + const argsArray = operatorList.argsArray; + const fnArray = operatorList.fnArray; + let i = executionStartIdx || 0; + const argsArrayLen = argsArray.length; + + if (argsArrayLen === i) { + return i; + } + + const chunkOperations = argsArrayLen - i > EXECUTION_STEPS && typeof continueCallback === "function"; + const endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0; + let steps = 0; + const commonObjs = this.commonObjs; + const objs = this.objs; + let fnId; + + while (true) { + if (stepper !== undefined && i === stepper.nextBreakPoint) { + stepper.breakIt(i, continueCallback); + return i; + } + + fnId = fnArray[i]; + + if (fnId !== _util.OPS.dependency) { + this[fnId].apply(this, argsArray[i]); + } else { + for (const depObjId of argsArray[i]) { + const objsPool = depObjId.startsWith("g_") ? commonObjs : objs; + + if (!objsPool.has(depObjId)) { + objsPool.get(depObjId, continueCallback); + return i; + } + } + } + + i++; + + if (i === argsArrayLen) { + return i; + } + + if (chunkOperations && ++steps > EXECUTION_STEPS) { + if (Date.now() > endTime) { + continueCallback(); + return i; + } + + steps = 0; + } + } + } + + #restoreInitialState() { + while (this.stateStack.length || this.inSMaskMode) { + this.restore(); + } + + this.ctx.restore(); + + if (this.transparentCanvas) { + this.ctx = this.compositeCtx; + this.ctx.save(); + this.ctx.setTransform(1, 0, 0, 1, 0, 0); + this.ctx.drawImage(this.transparentCanvas, 0, 0); + this.ctx.restore(); + this.transparentCanvas = null; + } + } + + endDrawing() { + this.#restoreInitialState(); + this.cachedCanvases.clear(); + this.cachedPatterns.clear(); + + for (const cache of this._cachedBitmapsMap.values()) { + for (const canvas of cache.values()) { + if (typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) { + canvas.width = canvas.height = 0; + } + } + + cache.clear(); + } + + this._cachedBitmapsMap.clear(); + + if (this.imageLayer) { + this.imageLayer.endLayout(); + } + } + + _scaleImage(img, inverseTransform) { + const width = img.width; + const height = img.height; + let widthScale = Math.max(Math.hypot(inverseTransform[0], inverseTransform[1]), 1); + let heightScale = Math.max(Math.hypot(inverseTransform[2], inverseTransform[3]), 1); + let paintWidth = width, + paintHeight = height; + let tmpCanvasId = "prescale1"; + let tmpCanvas, tmpCtx; + + while (widthScale > 2 && paintWidth > 1 || heightScale > 2 && paintHeight > 1) { + let newWidth = paintWidth, + newHeight = paintHeight; + + if (widthScale > 2 && paintWidth > 1) { + newWidth = Math.ceil(paintWidth / 2); + widthScale /= paintWidth / newWidth; + } + + if (heightScale > 2 && paintHeight > 1) { + newHeight = Math.ceil(paintHeight / 2); + heightScale /= paintHeight / newHeight; + } + + tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight, false); + tmpCtx = tmpCanvas.context; + tmpCtx.clearRect(0, 0, newWidth, newHeight); + tmpCtx.drawImage(img, 0, 0, paintWidth, paintHeight, 0, 0, newWidth, newHeight); + img = tmpCanvas.canvas; + paintWidth = newWidth; + paintHeight = newHeight; + tmpCanvasId = tmpCanvasId === "prescale1" ? "prescale2" : "prescale1"; + } + + return { + img, + paintWidth, + paintHeight + }; + } + + _createMaskCanvas(img) { + const ctx = this.ctx; + const { + width, + height + } = img; + const fillColor = this.current.fillColor; + const isPatternFill = this.current.patternFill; + const currentTransform = ctx.mozCurrentTransform; + let cache, cacheKey, scaled, maskCanvas; + + if ((img.bitmap || img.data) && img.count > 1) { + const mainKey = img.bitmap || img.data.buffer; + const withoutTranslation = currentTransform.slice(0, 4); + cacheKey = JSON.stringify(isPatternFill ? withoutTranslation : [withoutTranslation, fillColor]); + cache = this._cachedBitmapsMap.get(mainKey); + + if (!cache) { + cache = new Map(); + + this._cachedBitmapsMap.set(mainKey, cache); + } + + const cachedImage = cache.get(cacheKey); + + if (cachedImage && !isPatternFill) { + const offsetX = Math.round(Math.min(currentTransform[0], currentTransform[2]) + currentTransform[4]); + const offsetY = Math.round(Math.min(currentTransform[1], currentTransform[3]) + currentTransform[5]); + return { + canvas: cachedImage, + offsetX, + offsetY + }; + } + + scaled = cachedImage; + } + + if (!scaled) { + maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height, false); + putBinaryImageMask(maskCanvas.context, img); + } + + let maskToCanvas = _util.Util.transform(currentTransform, [1 / width, 0, 0, -1 / height, 0, 0]); + + maskToCanvas = _util.Util.transform(maskToCanvas, [1, 0, 0, 1, 0, -height]); + + const cord1 = _util.Util.applyTransform([0, 0], maskToCanvas); + + const cord2 = _util.Util.applyTransform([width, height], maskToCanvas); + + const rect = _util.Util.normalizeRect([cord1[0], cord1[1], cord2[0], cord2[1]]); + + const drawnWidth = Math.round(rect[2] - rect[0]) || 1; + const drawnHeight = Math.round(rect[3] - rect[1]) || 1; + const fillCanvas = this.cachedCanvases.getCanvas("fillCanvas", drawnWidth, drawnHeight, true); + const fillCtx = fillCanvas.context; + const offsetX = Math.min(cord1[0], cord2[0]); + const offsetY = Math.min(cord1[1], cord2[1]); + fillCtx.translate(-offsetX, -offsetY); + fillCtx.transform.apply(fillCtx, maskToCanvas); + + if (!scaled) { + scaled = this._scaleImage(maskCanvas.canvas, fillCtx.mozCurrentTransformInverse); + scaled = scaled.img; + + if (cache && isPatternFill) { + cache.set(cacheKey, scaled); + } + } + + fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled(fillCtx.mozCurrentTransform, img.interpolate); + drawImageAtIntegerCoords(fillCtx, scaled, 0, 0, scaled.width, scaled.height, 0, 0, width, height); + fillCtx.globalCompositeOperation = "source-in"; + + const inverse = _util.Util.transform(fillCtx.mozCurrentTransformInverse, [1, 0, 0, 1, -offsetX, -offsetY]); + + fillCtx.fillStyle = isPatternFill ? fillColor.getPattern(ctx, this, inverse, _pattern_helper.PathType.FILL) : fillColor; + fillCtx.fillRect(0, 0, width, height); + + if (cache && !isPatternFill) { + this.cachedCanvases.delete("fillCanvas"); + cache.set(cacheKey, fillCanvas.canvas); + } + + return { + canvas: fillCanvas.canvas, + offsetX: Math.round(offsetX), + offsetY: Math.round(offsetY) + }; + } + + setLineWidth(width) { + if (width !== this.current.lineWidth) { + this._cachedScaleForStroking = null; + } + + this.current.lineWidth = width; + this.ctx.lineWidth = width; + } + + setLineCap(style) { + this.ctx.lineCap = LINE_CAP_STYLES[style]; + } + + setLineJoin(style) { + this.ctx.lineJoin = LINE_JOIN_STYLES[style]; + } + + setMiterLimit(limit) { + this.ctx.miterLimit = limit; + } + + setDash(dashArray, dashPhase) { + const ctx = this.ctx; + + if (ctx.setLineDash !== undefined) { + ctx.setLineDash(dashArray); + ctx.lineDashOffset = dashPhase; + } + } + + setRenderingIntent(intent) {} + + setFlatness(flatness) {} + + setGState(states) { + for (let i = 0, ii = states.length; i < ii; i++) { + const state = states[i]; + const key = state[0]; + const value = state[1]; + + switch (key) { + case "LW": + this.setLineWidth(value); + break; + + case "LC": + this.setLineCap(value); + break; + + case "LJ": + this.setLineJoin(value); + break; + + case "ML": + this.setMiterLimit(value); + break; + + case "D": + this.setDash(value[0], value[1]); + break; + + case "RI": + this.setRenderingIntent(value); + break; + + case "FL": + this.setFlatness(value); + break; + + case "Font": + this.setFont(value[0], value[1]); + break; + + case "CA": + this.current.strokeAlpha = state[1]; + break; + + case "ca": + this.current.fillAlpha = state[1]; + this.ctx.globalAlpha = state[1]; + break; + + case "BM": + this.ctx.globalCompositeOperation = value; + break; + + case "SMask": + this.current.activeSMask = value ? this.tempSMask : null; + this.tempSMask = null; + this.checkSMaskState(); + break; + + case "TR": + this.current.transferMaps = value; + } + } + } + + get inSMaskMode() { + return !!this.suspendedCtx; + } + + checkSMaskState() { + const inSMaskMode = this.inSMaskMode; + + if (this.current.activeSMask && !inSMaskMode) { + this.beginSMaskMode(); + } else if (!this.current.activeSMask && inSMaskMode) { + this.endSMaskMode(); + } + } + + beginSMaskMode() { + if (this.inSMaskMode) { + throw new Error("beginSMaskMode called while already in smask mode"); + } + + const drawnWidth = this.ctx.canvas.width; + const drawnHeight = this.ctx.canvas.height; + const cacheId = "smaskGroupAt" + this.groupLevel; + const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight, true); + this.suspendedCtx = this.ctx; + this.ctx = scratchCanvas.context; + const ctx = this.ctx; + ctx.setTransform.apply(ctx, this.suspendedCtx.mozCurrentTransform); + copyCtxState(this.suspendedCtx, ctx); + mirrorContextOperations(ctx, this.suspendedCtx); + this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]); + } + + endSMaskMode() { + if (!this.inSMaskMode) { + throw new Error("endSMaskMode called while not in smask mode"); + } + + this.ctx._removeMirroring(); + + copyCtxState(this.ctx, this.suspendedCtx); + this.ctx = this.suspendedCtx; + this.suspendedCtx = null; + } + + compose(dirtyBox) { + if (!this.current.activeSMask) { + return; + } + + if (!dirtyBox) { + dirtyBox = [0, 0, this.ctx.canvas.width, this.ctx.canvas.height]; + } else { + dirtyBox[0] = Math.floor(dirtyBox[0]); + dirtyBox[1] = Math.floor(dirtyBox[1]); + dirtyBox[2] = Math.ceil(dirtyBox[2]); + dirtyBox[3] = Math.ceil(dirtyBox[3]); + } + + const smask = this.current.activeSMask; + const suspendedCtx = this.suspendedCtx; + composeSMask(suspendedCtx, smask, this.ctx, dirtyBox); + this.ctx.save(); + this.ctx.setTransform(1, 0, 0, 1, 0, 0); + this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height); + this.ctx.restore(); + } + + save() { + if (this.inSMaskMode) { + copyCtxState(this.ctx, this.suspendedCtx); + this.suspendedCtx.save(); + } else { + this.ctx.save(); + } + + const old = this.current; + this.stateStack.push(old); + this.current = old.clone(); + } + + restore() { + if (this.stateStack.length === 0 && this.inSMaskMode) { + this.endSMaskMode(); + } + + if (this.stateStack.length !== 0) { + this.current = this.stateStack.pop(); + + if (this.inSMaskMode) { + this.suspendedCtx.restore(); + copyCtxState(this.suspendedCtx, this.ctx); + } else { + this.ctx.restore(); + } + + this.checkSMaskState(); + this.pendingClip = null; + this._cachedScaleForStroking = null; + this._cachedGetSinglePixelWidth = null; + } + } + + transform(a, b, c, d, e, f) { + this.ctx.transform(a, b, c, d, e, f); + this._cachedScaleForStroking = null; + this._cachedGetSinglePixelWidth = null; + } + + constructPath(ops, args, minMax) { + const ctx = this.ctx; + const current = this.current; + let x = current.x, + y = current.y; + let startX, startY; + const currentTransform = ctx.mozCurrentTransform; + const isScalingMatrix = currentTransform[0] === 0 && currentTransform[3] === 0 || currentTransform[1] === 0 && currentTransform[2] === 0; + const minMaxForBezier = isScalingMatrix ? minMax.slice(0) : null; + + for (let i = 0, j = 0, ii = ops.length; i < ii; i++) { + switch (ops[i] | 0) { + case _util.OPS.rectangle: + x = args[j++]; + y = args[j++]; + const width = args[j++]; + const height = args[j++]; + const xw = x + width; + const yh = y + height; + ctx.moveTo(x, y); + + if (width === 0 || height === 0) { + ctx.lineTo(xw, yh); + } else { + ctx.lineTo(xw, y); + ctx.lineTo(xw, yh); + ctx.lineTo(x, yh); + } + + if (!isScalingMatrix) { + current.updateRectMinMax(currentTransform, [x, y, xw, yh]); + } + + ctx.closePath(); + break; + + case _util.OPS.moveTo: + x = args[j++]; + y = args[j++]; + ctx.moveTo(x, y); + + if (!isScalingMatrix) { + current.updatePathMinMax(currentTransform, x, y); + } + + break; + + case _util.OPS.lineTo: + x = args[j++]; + y = args[j++]; + ctx.lineTo(x, y); + + if (!isScalingMatrix) { + current.updatePathMinMax(currentTransform, x, y); + } + + break; + + case _util.OPS.curveTo: + startX = x; + startY = y; + x = args[j + 4]; + y = args[j + 5]; + ctx.bezierCurveTo(args[j], args[j + 1], args[j + 2], args[j + 3], x, y); + current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], args[j + 2], args[j + 3], x, y, minMaxForBezier); + j += 6; + break; + + case _util.OPS.curveTo2: + startX = x; + startY = y; + ctx.bezierCurveTo(x, y, args[j], args[j + 1], args[j + 2], args[j + 3]); + current.updateCurvePathMinMax(currentTransform, startX, startY, x, y, args[j], args[j + 1], args[j + 2], args[j + 3], minMaxForBezier); + x = args[j + 2]; + y = args[j + 3]; + j += 4; + break; + + case _util.OPS.curveTo3: + startX = x; + startY = y; + x = args[j + 2]; + y = args[j + 3]; + ctx.bezierCurveTo(args[j], args[j + 1], x, y, x, y); + current.updateCurvePathMinMax(currentTransform, startX, startY, args[j], args[j + 1], x, y, x, y, minMaxForBezier); + j += 4; + break; + + case _util.OPS.closePath: + ctx.closePath(); + break; + } + } + + if (isScalingMatrix) { + current.updateScalingPathMinMax(currentTransform, minMaxForBezier); + } + + current.setCurrentPoint(x, y); + } + + closePath() { + this.ctx.closePath(); + } + + stroke(consumePath) { + consumePath = typeof consumePath !== "undefined" ? consumePath : true; + const ctx = this.ctx; + const strokeColor = this.current.strokeColor; + ctx.globalAlpha = this.current.strokeAlpha; + + if (this.contentVisible) { + if (typeof strokeColor === "object" && strokeColor?.getPattern) { + ctx.save(); + ctx.strokeStyle = strokeColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.STROKE); + this.rescaleAndStroke(false); + ctx.restore(); + } else { + this.rescaleAndStroke(true); + } + } + + if (consumePath) { + this.consumePath(this.current.getClippedPathBoundingBox()); + } + + ctx.globalAlpha = this.current.fillAlpha; + } + + closeStroke() { + this.closePath(); + this.stroke(); + } + + fill(consumePath) { + consumePath = typeof consumePath !== "undefined" ? consumePath : true; + const ctx = this.ctx; + const fillColor = this.current.fillColor; + const isPatternFill = this.current.patternFill; + let needRestore = false; + + if (isPatternFill) { + ctx.save(); + ctx.fillStyle = fillColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL); + needRestore = true; + } + + const intersect = this.current.getClippedPathBoundingBox(); + + if (this.contentVisible && intersect !== null) { + if (this.pendingEOFill) { + ctx.fill("evenodd"); + this.pendingEOFill = false; + } else { + ctx.fill(); + } + } + + if (needRestore) { + ctx.restore(); + } + + if (consumePath) { + this.consumePath(intersect); + } + } + + eoFill() { + this.pendingEOFill = true; + this.fill(); + } + + fillStroke() { + this.fill(false); + this.stroke(false); + this.consumePath(); + } + + eoFillStroke() { + this.pendingEOFill = true; + this.fillStroke(); + } + + closeFillStroke() { + this.closePath(); + this.fillStroke(); + } + + closeEOFillStroke() { + this.pendingEOFill = true; + this.closePath(); + this.fillStroke(); + } + + endPath() { + this.consumePath(); + } + + clip() { + this.pendingClip = NORMAL_CLIP; + } + + eoClip() { + this.pendingClip = EO_CLIP; + } + + beginText() { + this.current.textMatrix = _util.IDENTITY_MATRIX; + this.current.textMatrixScale = 1; + this.current.x = this.current.lineX = 0; + this.current.y = this.current.lineY = 0; + } + + endText() { + const paths = this.pendingTextPaths; + const ctx = this.ctx; + + if (paths === undefined) { + ctx.beginPath(); + return; + } + + ctx.save(); + ctx.beginPath(); + + for (const path of paths) { + ctx.setTransform.apply(ctx, path.transform); + ctx.translate(path.x, path.y); + path.addToPath(ctx, path.fontSize); + } + + ctx.restore(); + ctx.clip(); + ctx.beginPath(); + delete this.pendingTextPaths; + } + + setCharSpacing(spacing) { + this.current.charSpacing = spacing; + } + + setWordSpacing(spacing) { + this.current.wordSpacing = spacing; + } + + setHScale(scale) { + this.current.textHScale = scale / 100; + } + + setLeading(leading) { + this.current.leading = -leading; + } + + setFont(fontRefName, size) { + const fontObj = this.commonObjs.get(fontRefName); + const current = this.current; + + if (!fontObj) { + throw new Error(`Can't find font for ${fontRefName}`); + } + + current.fontMatrix = fontObj.fontMatrix || _util.FONT_IDENTITY_MATRIX; + + if (current.fontMatrix[0] === 0 || current.fontMatrix[3] === 0) { + (0, _util.warn)("Invalid font matrix for font " + fontRefName); + } + + if (size < 0) { + size = -size; + current.fontDirection = -1; + } else { + current.fontDirection = 1; + } + + this.current.font = fontObj; + this.current.fontSize = size; + + if (fontObj.isType3Font) { + return; + } + + const name = fontObj.loadedName || "sans-serif"; + let bold = "normal"; + + if (fontObj.black) { + bold = "900"; + } else if (fontObj.bold) { + bold = "bold"; + } + + const italic = fontObj.italic ? "italic" : "normal"; + const typeface = `"${name}", ${fontObj.fallbackName}`; + let browserFontSize = size; + + if (size < MIN_FONT_SIZE) { + browserFontSize = MIN_FONT_SIZE; + } else if (size > MAX_FONT_SIZE) { + browserFontSize = MAX_FONT_SIZE; + } + + this.current.fontSizeScale = size / browserFontSize; + this.ctx.font = `${italic} ${bold} ${browserFontSize}px ${typeface}`; + } + + setTextRenderingMode(mode) { + this.current.textRenderingMode = mode; + } + + setTextRise(rise) { + this.current.textRise = rise; + } + + moveText(x, y) { + this.current.x = this.current.lineX += x; + this.current.y = this.current.lineY += y; + } + + setLeadingMoveText(x, y) { + this.setLeading(-y); + this.moveText(x, y); + } + + setTextMatrix(a, b, c, d, e, f) { + this.current.textMatrix = [a, b, c, d, e, f]; + this.current.textMatrixScale = Math.hypot(a, b); + this.current.x = this.current.lineX = 0; + this.current.y = this.current.lineY = 0; + } + + nextLine() { + this.moveText(0, this.current.leading); + } + + paintChar(character, x, y, patternTransform) { + const ctx = this.ctx; + const current = this.current; + const font = current.font; + const textRenderingMode = current.textRenderingMode; + const fontSize = current.fontSize / current.fontSizeScale; + const fillStrokeMode = textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; + const isAddToPathSet = !!(textRenderingMode & _util.TextRenderingMode.ADD_TO_PATH_FLAG); + const patternFill = current.patternFill && !font.missingFile; + let addToPath; + + if (font.disableFontFace || isAddToPathSet || patternFill) { + addToPath = font.getPathGenerator(this.commonObjs, character); + } + + if (font.disableFontFace || patternFill) { + ctx.save(); + ctx.translate(x, y); + ctx.beginPath(); + addToPath(ctx, fontSize); + + if (patternTransform) { + ctx.setTransform.apply(ctx, patternTransform); + } + + if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { + ctx.fill(); + } + + if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { + ctx.stroke(); + } + + ctx.restore(); + } else { + if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { + ctx.fillText(character, x, y); + } + + if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { + ctx.strokeText(character, x, y); + } + } + + if (isAddToPathSet) { + const paths = this.pendingTextPaths || (this.pendingTextPaths = []); + paths.push({ + transform: ctx.mozCurrentTransform, + x, + y, + fontSize, + addToPath + }); + } + } + + get isFontSubpixelAAEnabled() { + const { + context: ctx + } = this.cachedCanvases.getCanvas("isFontSubpixelAAEnabled", 10, 10, false); + ctx.scale(1.5, 1); + ctx.fillText("I", 0, 10); + const data = ctx.getImageData(0, 0, 10, 10).data; + let enabled = false; + + for (let i = 3; i < data.length; i += 4) { + if (data[i] > 0 && data[i] < 255) { + enabled = true; + break; + } + } + + return (0, _util.shadow)(this, "isFontSubpixelAAEnabled", enabled); + } + + showText(glyphs) { + const current = this.current; + const font = current.font; + + if (font.isType3Font) { + return this.showType3Text(glyphs); + } + + const fontSize = current.fontSize; + + if (fontSize === 0) { + return undefined; + } + + const ctx = this.ctx; + const fontSizeScale = current.fontSizeScale; + const charSpacing = current.charSpacing; + const wordSpacing = current.wordSpacing; + const fontDirection = current.fontDirection; + const textHScale = current.textHScale * fontDirection; + const glyphsLength = glyphs.length; + const vertical = font.vertical; + const spacingDir = vertical ? 1 : -1; + const defaultVMetrics = font.defaultVMetrics; + const widthAdvanceScale = fontSize * current.fontMatrix[0]; + const simpleFillText = current.textRenderingMode === _util.TextRenderingMode.FILL && !font.disableFontFace && !current.patternFill; + ctx.save(); + ctx.transform.apply(ctx, current.textMatrix); + ctx.translate(current.x, current.y + current.textRise); + + if (fontDirection > 0) { + ctx.scale(textHScale, -1); + } else { + ctx.scale(textHScale, 1); + } + + let patternTransform; + + if (current.patternFill) { + ctx.save(); + const pattern = current.fillColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL); + patternTransform = ctx.mozCurrentTransform; + ctx.restore(); + ctx.fillStyle = pattern; + } + + let lineWidth = current.lineWidth; + const scale = current.textMatrixScale; + + if (scale === 0 || lineWidth === 0) { + const fillStrokeMode = current.textRenderingMode & _util.TextRenderingMode.FILL_STROKE_MASK; + + if (fillStrokeMode === _util.TextRenderingMode.STROKE || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) { + lineWidth = this.getSinglePixelWidth(); + } + } else { + lineWidth /= scale; + } + + if (fontSizeScale !== 1.0) { + ctx.scale(fontSizeScale, fontSizeScale); + lineWidth /= fontSizeScale; + } + + ctx.lineWidth = lineWidth; + let x = 0, + i; + + for (i = 0; i < glyphsLength; ++i) { + const glyph = glyphs[i]; + + if (typeof glyph === "number") { + x += spacingDir * glyph * fontSize / 1000; + continue; + } + + let restoreNeeded = false; + const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; + const character = glyph.fontChar; + const accent = glyph.accent; + let scaledX, scaledY; + let width = glyph.width; + + if (vertical) { + const vmetric = glyph.vmetric || defaultVMetrics; + const vx = -(glyph.vmetric ? vmetric[1] : width * 0.5) * widthAdvanceScale; + const vy = vmetric[2] * widthAdvanceScale; + width = vmetric ? -vmetric[0] : width; + scaledX = vx / fontSizeScale; + scaledY = (x + vy) / fontSizeScale; + } else { + scaledX = x / fontSizeScale; + scaledY = 0; + } + + if (font.remeasure && width > 0) { + const measuredWidth = ctx.measureText(character).width * 1000 / fontSize * fontSizeScale; + + if (width < measuredWidth && this.isFontSubpixelAAEnabled) { + const characterScaleX = width / measuredWidth; + restoreNeeded = true; + ctx.save(); + ctx.scale(characterScaleX, 1); + scaledX /= characterScaleX; + } else if (width !== measuredWidth) { + scaledX += (width - measuredWidth) / 2000 * fontSize / fontSizeScale; + } + } + + if (this.contentVisible && (glyph.isInFont || font.missingFile)) { + if (simpleFillText && !accent) { + ctx.fillText(character, scaledX, scaledY); + } else { + this.paintChar(character, scaledX, scaledY, patternTransform); + + if (accent) { + const scaledAccentX = scaledX + fontSize * accent.offset.x / fontSizeScale; + const scaledAccentY = scaledY - fontSize * accent.offset.y / fontSizeScale; + this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY, patternTransform); + } + } + } + + let charWidth; + + if (vertical) { + charWidth = width * widthAdvanceScale - spacing * fontDirection; + } else { + charWidth = width * widthAdvanceScale + spacing * fontDirection; + } + + x += charWidth; + + if (restoreNeeded) { + ctx.restore(); + } + } + + if (vertical) { + current.y -= x; + } else { + current.x += x * textHScale; + } + + ctx.restore(); + this.compose(); + return undefined; + } + + showType3Text(glyphs) { + const ctx = this.ctx; + const current = this.current; + const font = current.font; + const fontSize = current.fontSize; + const fontDirection = current.fontDirection; + const spacingDir = font.vertical ? 1 : -1; + const charSpacing = current.charSpacing; + const wordSpacing = current.wordSpacing; + const textHScale = current.textHScale * fontDirection; + const fontMatrix = current.fontMatrix || _util.FONT_IDENTITY_MATRIX; + const glyphsLength = glyphs.length; + const isTextInvisible = current.textRenderingMode === _util.TextRenderingMode.INVISIBLE; + let i, glyph, width, spacingLength; + + if (isTextInvisible || fontSize === 0) { + return; + } + + this._cachedScaleForStroking = null; + this._cachedGetSinglePixelWidth = null; + ctx.save(); + ctx.transform.apply(ctx, current.textMatrix); + ctx.translate(current.x, current.y); + ctx.scale(textHScale, fontDirection); + + for (i = 0; i < glyphsLength; ++i) { + glyph = glyphs[i]; + + if (typeof glyph === "number") { + spacingLength = spacingDir * glyph * fontSize / 1000; + this.ctx.translate(spacingLength, 0); + current.x += spacingLength * textHScale; + continue; + } + + const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; + const operatorList = font.charProcOperatorList[glyph.operatorListId]; + + if (!operatorList) { + (0, _util.warn)(`Type3 character "${glyph.operatorListId}" is not available.`); + continue; + } + + if (this.contentVisible) { + this.processingType3 = glyph; + this.save(); + ctx.scale(fontSize, fontSize); + ctx.transform.apply(ctx, fontMatrix); + this.executeOperatorList(operatorList); + this.restore(); + } + + const transformed = _util.Util.applyTransform([glyph.width, 0], fontMatrix); + + width = transformed[0] * fontSize + spacing; + ctx.translate(width, 0); + current.x += width * textHScale; + } + + ctx.restore(); + this.processingType3 = null; + } + + setCharWidth(xWidth, yWidth) {} + + setCharWidthAndBounds(xWidth, yWidth, llx, lly, urx, ury) { + this.ctx.rect(llx, lly, urx - llx, ury - lly); + this.ctx.clip(); + this.endPath(); + } + + getColorN_Pattern(IR) { + let pattern; + + if (IR[0] === "TilingPattern") { + const color = IR[1]; + const baseTransform = this.baseTransform || this.ctx.mozCurrentTransform.slice(); + const canvasGraphicsFactory = { + createCanvasGraphics: ctx => { + return new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory); + } + }; + pattern = new _pattern_helper.TilingPattern(IR, color, this.ctx, canvasGraphicsFactory, baseTransform); + } else { + pattern = this._getPattern(IR[1], IR[2]); + } + + return pattern; + } + + setStrokeColorN() { + this.current.strokeColor = this.getColorN_Pattern(arguments); + } + + setFillColorN() { + this.current.fillColor = this.getColorN_Pattern(arguments); + this.current.patternFill = true; + } + + setStrokeRGBColor(r, g, b) { + const color = this.selectColor?.(r, g, b) || _util.Util.makeHexColor(r, g, b); + + this.ctx.strokeStyle = color; + this.current.strokeColor = color; + } + + setFillRGBColor(r, g, b) { + const color = this.selectColor?.(r, g, b) || _util.Util.makeHexColor(r, g, b); + + this.ctx.fillStyle = color; + this.current.fillColor = color; + this.current.patternFill = false; + } + + _getPattern(objId, matrix = null) { + let pattern; + + if (this.cachedPatterns.has(objId)) { + pattern = this.cachedPatterns.get(objId); + } else { + pattern = (0, _pattern_helper.getShadingPattern)(this.objs.get(objId)); + this.cachedPatterns.set(objId, pattern); + } + + if (matrix) { + pattern.matrix = matrix; + } + + return pattern; + } + + shadingFill(objId) { + if (!this.contentVisible) { + return; + } + + const ctx = this.ctx; + this.save(); + + const pattern = this._getPattern(objId); + + ctx.fillStyle = pattern.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.SHADING); + const inv = ctx.mozCurrentTransformInverse; + + if (inv) { + const canvas = ctx.canvas; + const width = canvas.width; + const height = canvas.height; + + const bl = _util.Util.applyTransform([0, 0], inv); + + const br = _util.Util.applyTransform([0, height], inv); + + const ul = _util.Util.applyTransform([width, 0], inv); + + const ur = _util.Util.applyTransform([width, height], inv); + + const x0 = Math.min(bl[0], br[0], ul[0], ur[0]); + const y0 = Math.min(bl[1], br[1], ul[1], ur[1]); + const x1 = Math.max(bl[0], br[0], ul[0], ur[0]); + const y1 = Math.max(bl[1], br[1], ul[1], ur[1]); + this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0); + } else { + this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10); + } + + this.compose(this.current.getClippedPathBoundingBox()); + this.restore(); + } + + beginInlineImage() { + (0, _util.unreachable)("Should not call beginInlineImage"); + } + + beginImageData() { + (0, _util.unreachable)("Should not call beginImageData"); + } + + paintFormXObjectBegin(matrix, bbox) { + if (!this.contentVisible) { + return; + } + + this.save(); + this.baseTransformStack.push(this.baseTransform); + + if (Array.isArray(matrix) && matrix.length === 6) { + this.transform.apply(this, matrix); + } + + this.baseTransform = this.ctx.mozCurrentTransform; + + if (bbox) { + const width = bbox[2] - bbox[0]; + const height = bbox[3] - bbox[1]; + this.ctx.rect(bbox[0], bbox[1], width, height); + this.current.updateRectMinMax(this.ctx.mozCurrentTransform, bbox); + this.clip(); + this.endPath(); + } + } + + paintFormXObjectEnd() { + if (!this.contentVisible) { + return; + } + + this.restore(); + this.baseTransform = this.baseTransformStack.pop(); + } + + beginGroup(group) { + if (!this.contentVisible) { + return; + } + + this.save(); + + if (this.inSMaskMode) { + this.endSMaskMode(); + this.current.activeSMask = null; + } + + const currentCtx = this.ctx; + + if (!group.isolated) { + (0, _util.info)("TODO: Support non-isolated groups."); + } + + if (group.knockout) { + (0, _util.warn)("Knockout groups not supported."); + } + + const currentTransform = currentCtx.mozCurrentTransform; + + if (group.matrix) { + currentCtx.transform.apply(currentCtx, group.matrix); + } + + if (!group.bbox) { + throw new Error("Bounding box is required."); + } + + let bounds = _util.Util.getAxialAlignedBoundingBox(group.bbox, currentCtx.mozCurrentTransform); + + const canvasBounds = [0, 0, currentCtx.canvas.width, currentCtx.canvas.height]; + bounds = _util.Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0]; + const offsetX = Math.floor(bounds[0]); + const offsetY = Math.floor(bounds[1]); + let drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1); + let drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1); + let scaleX = 1, + scaleY = 1; + + if (drawnWidth > MAX_GROUP_SIZE) { + scaleX = drawnWidth / MAX_GROUP_SIZE; + drawnWidth = MAX_GROUP_SIZE; + } + + if (drawnHeight > MAX_GROUP_SIZE) { + scaleY = drawnHeight / MAX_GROUP_SIZE; + drawnHeight = MAX_GROUP_SIZE; + } + + this.current.startNewPathAndClipBox([0, 0, drawnWidth, drawnHeight]); + let cacheId = "groupAt" + this.groupLevel; + + if (group.smask) { + cacheId += "_smask_" + this.smaskCounter++ % 2; + } + + const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight, true); + const groupCtx = scratchCanvas.context; + groupCtx.scale(1 / scaleX, 1 / scaleY); + groupCtx.translate(-offsetX, -offsetY); + groupCtx.transform.apply(groupCtx, currentTransform); + + if (group.smask) { + this.smaskStack.push({ + canvas: scratchCanvas.canvas, + context: groupCtx, + offsetX, + offsetY, + scaleX, + scaleY, + subtype: group.smask.subtype, + backdrop: group.smask.backdrop, + transferMap: group.smask.transferMap || null, + startTransformInverse: null + }); + } else { + currentCtx.setTransform(1, 0, 0, 1, 0, 0); + currentCtx.translate(offsetX, offsetY); + currentCtx.scale(scaleX, scaleY); + currentCtx.save(); + } + + copyCtxState(currentCtx, groupCtx); + this.ctx = groupCtx; + this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]); + this.groupStack.push(currentCtx); + this.groupLevel++; + } + + endGroup(group) { + if (!this.contentVisible) { + return; + } + + this.groupLevel--; + const groupCtx = this.ctx; + const ctx = this.groupStack.pop(); + this.ctx = ctx; + this.ctx.imageSmoothingEnabled = false; + + if (group.smask) { + this.tempSMask = this.smaskStack.pop(); + this.restore(); + } else { + this.ctx.restore(); + const currentMtx = this.ctx.mozCurrentTransform; + this.restore(); + this.ctx.save(); + this.ctx.setTransform.apply(this.ctx, currentMtx); + + const dirtyBox = _util.Util.getAxialAlignedBoundingBox([0, 0, groupCtx.canvas.width, groupCtx.canvas.height], currentMtx); + + this.ctx.drawImage(groupCtx.canvas, 0, 0); + this.ctx.restore(); + this.compose(dirtyBox); + } + } + + beginAnnotation(id, rect, transform, matrix, hasOwnCanvas) { + this.#restoreInitialState(); + resetCtxToDefault(this.ctx, this.foregroundColor); + this.ctx.save(); + this.save(); + + if (this.baseTransform) { + this.ctx.setTransform.apply(this.ctx, this.baseTransform); + } + + if (Array.isArray(rect) && rect.length === 4) { + const width = rect[2] - rect[0]; + const height = rect[3] - rect[1]; + + if (hasOwnCanvas && this.annotationCanvasMap) { + transform = transform.slice(); + transform[4] -= rect[0]; + transform[5] -= rect[1]; + rect = rect.slice(); + rect[0] = rect[1] = 0; + rect[2] = width; + rect[3] = height; + + const [scaleX, scaleY] = _util.Util.singularValueDecompose2dScale(this.ctx.mozCurrentTransform); + + const { + viewportScale + } = this; + const canvasWidth = Math.ceil(width * this.outputScaleX * viewportScale); + const canvasHeight = Math.ceil(height * this.outputScaleY * viewportScale); + this.annotationCanvas = this.canvasFactory.create(canvasWidth, canvasHeight); + const { + canvas, + context + } = this.annotationCanvas; + this.annotationCanvasMap.set(id, canvas); + this.annotationCanvas.savedCtx = this.ctx; + this.ctx = context; + addContextCurrentTransform(this.ctx); + this.ctx.setTransform(scaleX, 0, 0, -scaleY, 0, height * scaleY); + resetCtxToDefault(this.ctx, this.foregroundColor); + } else { + resetCtxToDefault(this.ctx, this.foregroundColor); + this.ctx.rect(rect[0], rect[1], width, height); + this.ctx.clip(); + this.endPath(); + } + } + + this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height); + this.transform.apply(this, transform); + this.transform.apply(this, matrix); + } + + endAnnotation() { + if (this.annotationCanvas) { + this.ctx = this.annotationCanvas.savedCtx; + delete this.annotationCanvas.savedCtx; + delete this.annotationCanvas; + } + } + + paintImageMaskXObject(img) { + if (!this.contentVisible) { + return; + } + + const count = img.count; + img = this.getObject(img.data, img); + img.count = count; + const ctx = this.ctx; + const glyph = this.processingType3; + + if (glyph) { + if (glyph.compiled === undefined) { + glyph.compiled = compileType3Glyph(img); + } + + if (glyph.compiled) { + glyph.compiled(ctx); + return; + } + } + + const mask = this._createMaskCanvas(img); + + const maskCanvas = mask.canvas; + ctx.save(); + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.drawImage(maskCanvas, mask.offsetX, mask.offsetY); + ctx.restore(); + this.compose(); + } + + paintImageMaskXObjectRepeat(img, scaleX, skewX = 0, skewY = 0, scaleY, positions) { + if (!this.contentVisible) { + return; + } + + img = this.getObject(img.data, img); + const ctx = this.ctx; + ctx.save(); + const currentTransform = ctx.mozCurrentTransform; + ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0); + + const mask = this._createMaskCanvas(img); + + ctx.setTransform(1, 0, 0, 1, 0, 0); + + for (let i = 0, ii = positions.length; i < ii; i += 2) { + const trans = _util.Util.transform(currentTransform, [scaleX, skewX, skewY, scaleY, positions[i], positions[i + 1]]); + + const [x, y] = _util.Util.applyTransform([0, 0], trans); + + ctx.drawImage(mask.canvas, x, y); + } + + ctx.restore(); + this.compose(); + } + + paintImageMaskXObjectGroup(images) { + if (!this.contentVisible) { + return; + } + + const ctx = this.ctx; + const fillColor = this.current.fillColor; + const isPatternFill = this.current.patternFill; + + for (const image of images) { + const { + data, + width, + height, + transform + } = image; + const maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height, false); + const maskCtx = maskCanvas.context; + maskCtx.save(); + const img = this.getObject(data, image); + putBinaryImageMask(maskCtx, img); + maskCtx.globalCompositeOperation = "source-in"; + maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL) : fillColor; + maskCtx.fillRect(0, 0, width, height); + maskCtx.restore(); + ctx.save(); + ctx.transform.apply(ctx, transform); + ctx.scale(1, -1); + drawImageAtIntegerCoords(ctx, maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1); + ctx.restore(); + } + + this.compose(); + } + + paintImageXObject(objId) { + if (!this.contentVisible) { + return; + } + + const imgData = this.getObject(objId); + + if (!imgData) { + (0, _util.warn)("Dependent image isn't ready yet"); + return; + } + + this.paintInlineImageXObject(imgData); + } + + paintImageXObjectRepeat(objId, scaleX, scaleY, positions) { + if (!this.contentVisible) { + return; + } + + const imgData = this.getObject(objId); + + if (!imgData) { + (0, _util.warn)("Dependent image isn't ready yet"); + return; + } + + const width = imgData.width; + const height = imgData.height; + const map = []; + + for (let i = 0, ii = positions.length; i < ii; i += 2) { + map.push({ + transform: [scaleX, 0, 0, scaleY, positions[i], positions[i + 1]], + x: 0, + y: 0, + w: width, + h: height + }); + } + + this.paintInlineImageXObjectGroup(imgData, map); + } + + paintInlineImageXObject(imgData) { + if (!this.contentVisible) { + return; + } + + const width = imgData.width; + const height = imgData.height; + const ctx = this.ctx; + this.save(); + ctx.scale(1 / width, -1 / height); + let imgToPaint; + + if (typeof HTMLElement === "function" && imgData instanceof HTMLElement || !imgData.data) { + imgToPaint = imgData; + } else { + const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", width, height, false); + const tmpCtx = tmpCanvas.context; + putBinaryImageData(tmpCtx, imgData, this.current.transferMaps); + imgToPaint = tmpCanvas.canvas; + } + + const scaled = this._scaleImage(imgToPaint, ctx.mozCurrentTransformInverse); + + ctx.imageSmoothingEnabled = getImageSmoothingEnabled(ctx.mozCurrentTransform, imgData.interpolate); + const [rWidth, rHeight] = drawImageAtIntegerCoords(ctx, scaled.img, 0, 0, scaled.paintWidth, scaled.paintHeight, 0, -height, width, height); + + if (this.imageLayer) { + const position = this.getCanvasPosition(0, -height); + this.imageLayer.appendImage({ + imgData, + left: position[0], + top: position[1], + width: rWidth, + height: rHeight + }); + } + + this.compose(); + this.restore(); + } + + paintInlineImageXObjectGroup(imgData, map) { + if (!this.contentVisible) { + return; + } + + const ctx = this.ctx; + const w = imgData.width; + const h = imgData.height; + const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", w, h, false); + const tmpCtx = tmpCanvas.context; + putBinaryImageData(tmpCtx, imgData, this.current.transferMaps); + + for (let i = 0, ii = map.length; i < ii; i++) { + const entry = map[i]; + ctx.save(); + ctx.transform.apply(ctx, entry.transform); + ctx.scale(1, -1); + drawImageAtIntegerCoords(ctx, tmpCanvas.canvas, entry.x, entry.y, entry.w, entry.h, 0, -1, 1, 1); + + if (this.imageLayer) { + const position = this.getCanvasPosition(entry.x, entry.y); + this.imageLayer.appendImage({ + imgData, + left: position[0], + top: position[1], + width: w, + height: h + }); + } + + ctx.restore(); + } + + this.compose(); + } + + paintSolidColorImageMask() { + if (!this.contentVisible) { + return; + } + + this.ctx.fillRect(0, 0, 1, 1); + this.compose(); + } + + markPoint(tag) {} + + markPointProps(tag, properties) {} + + beginMarkedContent(tag) { + this.markedContentStack.push({ + visible: true + }); + } + + beginMarkedContentProps(tag, properties) { + if (tag === "OC") { + this.markedContentStack.push({ + visible: this.optionalContentConfig.isVisible(properties) + }); + } else { + this.markedContentStack.push({ + visible: true + }); + } + + this.contentVisible = this.isContentVisible(); + } + + endMarkedContent() { + this.markedContentStack.pop(); + this.contentVisible = this.isContentVisible(); + } + + beginCompat() {} + + endCompat() {} + + consumePath(clipBox) { + const isEmpty = this.current.isEmptyClip(); + + if (this.pendingClip) { + this.current.updateClipFromPath(); + } + + if (!this.pendingClip) { + this.compose(clipBox); + } + + const ctx = this.ctx; + + if (this.pendingClip) { + if (!isEmpty) { + if (this.pendingClip === EO_CLIP) { + ctx.clip("evenodd"); + } else { + ctx.clip(); + } + } + + this.pendingClip = null; + } + + this.current.startNewPathAndClipBox(this.current.clipBox); + ctx.beginPath(); + } + + getSinglePixelWidth() { + if (!this._cachedGetSinglePixelWidth) { + const m = this.ctx.mozCurrentTransform; + + if (m[1] === 0 && m[2] === 0) { + this._cachedGetSinglePixelWidth = 1 / Math.min(Math.abs(m[0]), Math.abs(m[3])); + } else { + const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]); + const normX = Math.hypot(m[0], m[2]); + const normY = Math.hypot(m[1], m[3]); + this._cachedGetSinglePixelWidth = Math.max(normX, normY) / absDet; + } + } + + return this._cachedGetSinglePixelWidth; + } + + getScaleForStroking() { + if (!this._cachedScaleForStroking) { + const { + lineWidth + } = this.current; + const m = this.ctx.mozCurrentTransform; + let scaleX, scaleY; + + if (m[1] === 0 && m[2] === 0) { + const normX = Math.abs(m[0]); + const normY = Math.abs(m[3]); + + if (lineWidth === 0) { + scaleX = 1 / normX; + scaleY = 1 / normY; + } else { + const scaledXLineWidth = normX * lineWidth; + const scaledYLineWidth = normY * lineWidth; + scaleX = scaledXLineWidth < 1 ? 1 / scaledXLineWidth : 1; + scaleY = scaledYLineWidth < 1 ? 1 / scaledYLineWidth : 1; + } + } else { + const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]); + const normX = Math.hypot(m[0], m[1]); + const normY = Math.hypot(m[2], m[3]); + + if (lineWidth === 0) { + scaleX = normY / absDet; + scaleY = normX / absDet; + } else { + const baseArea = lineWidth * absDet; + scaleX = normY > baseArea ? normY / baseArea : 1; + scaleY = normX > baseArea ? normX / baseArea : 1; + } + } + + this._cachedScaleForStroking = [scaleX, scaleY]; + } + + return this._cachedScaleForStroking; + } + + rescaleAndStroke(saveRestore) { + const { + ctx + } = this; + const { + lineWidth + } = this.current; + const [scaleX, scaleY] = this.getScaleForStroking(); + ctx.lineWidth = lineWidth || 1; + + if (scaleX === 1 && scaleY === 1) { + ctx.stroke(); + return; + } + + let savedMatrix, savedDashes, savedDashOffset; + + if (saveRestore) { + savedMatrix = ctx.mozCurrentTransform.slice(); + savedDashes = ctx.getLineDash().slice(); + savedDashOffset = ctx.lineDashOffset; + } + + ctx.scale(scaleX, scaleY); + const scale = Math.max(scaleX, scaleY); + ctx.setLineDash(ctx.getLineDash().map(x => x / scale)); + ctx.lineDashOffset /= scale; + ctx.stroke(); + + if (saveRestore) { + ctx.setTransform(...savedMatrix); + ctx.setLineDash(savedDashes); + ctx.lineDashOffset = savedDashOffset; + } + } + + getCanvasPosition(x, y) { + const transform = this.ctx.mozCurrentTransform; + return [transform[0] * x + transform[2] * y + transform[4], transform[1] * x + transform[3] * y + transform[5]]; + } + + isContentVisible() { + for (let i = this.markedContentStack.length - 1; i >= 0; i--) { + if (!this.markedContentStack[i].visible) { + return false; + } + } + + return true; + } + +} + +exports.CanvasGraphics = CanvasGraphics; + +for (const op in _util.OPS) { + if (CanvasGraphics.prototype[op] !== undefined) { + CanvasGraphics.prototype[_util.OPS[op]] = CanvasGraphics.prototype[op]; + } +} + +/***/ }), +/* 13 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.TilingPattern = exports.PathType = void 0; +exports.getShadingPattern = getShadingPattern; + +var _util = __w_pdfjs_require__(1); + +var _is_node = __w_pdfjs_require__(3); + +const PathType = { + FILL: "Fill", + STROKE: "Stroke", + SHADING: "Shading" +}; +exports.PathType = PathType; + +function applyBoundingBox(ctx, bbox) { + if (!bbox || _is_node.isNodeJS) { + return; + } + + const width = bbox[2] - bbox[0]; + const height = bbox[3] - bbox[1]; + const region = new Path2D(); + region.rect(bbox[0], bbox[1], width, height); + ctx.clip(region); +} + +class BaseShadingPattern { + constructor() { + if (this.constructor === BaseShadingPattern) { + (0, _util.unreachable)("Cannot initialize BaseShadingPattern."); + } + } + + getPattern() { + (0, _util.unreachable)("Abstract method `getPattern` called."); + } + +} + +class RadialAxialShadingPattern extends BaseShadingPattern { + constructor(IR) { + super(); + this._type = IR[1]; + this._bbox = IR[2]; + this._colorStops = IR[3]; + this._p0 = IR[4]; + this._p1 = IR[5]; + this._r0 = IR[6]; + this._r1 = IR[7]; + this.matrix = null; + } + + _createGradient(ctx) { + let grad; + + if (this._type === "axial") { + grad = ctx.createLinearGradient(this._p0[0], this._p0[1], this._p1[0], this._p1[1]); + } else if (this._type === "radial") { + grad = ctx.createRadialGradient(this._p0[0], this._p0[1], this._r0, this._p1[0], this._p1[1], this._r1); + } + + for (const colorStop of this._colorStops) { + grad.addColorStop(colorStop[0], colorStop[1]); + } + + return grad; + } + + getPattern(ctx, owner, inverse, pathType) { + let pattern; + + if (pathType === PathType.STROKE || pathType === PathType.FILL) { + const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, ctx.mozCurrentTransform) || [0, 0, 0, 0]; + const width = Math.ceil(ownerBBox[2] - ownerBBox[0]) || 1; + const height = Math.ceil(ownerBBox[3] - ownerBBox[1]) || 1; + const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", width, height, true); + const tmpCtx = tmpCanvas.context; + tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); + tmpCtx.beginPath(); + tmpCtx.rect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); + tmpCtx.translate(-ownerBBox[0], -ownerBBox[1]); + inverse = _util.Util.transform(inverse, [1, 0, 0, 1, ownerBBox[0], ownerBBox[1]]); + tmpCtx.transform.apply(tmpCtx, owner.baseTransform); + + if (this.matrix) { + tmpCtx.transform.apply(tmpCtx, this.matrix); + } + + applyBoundingBox(tmpCtx, this._bbox); + tmpCtx.fillStyle = this._createGradient(tmpCtx); + tmpCtx.fill(); + pattern = ctx.createPattern(tmpCanvas.canvas, "no-repeat"); + const domMatrix = new DOMMatrix(inverse); + + try { + pattern.setTransform(domMatrix); + } catch (ex) { + (0, _util.warn)(`RadialAxialShadingPattern.getPattern: "${ex?.message}".`); + } + } else { + applyBoundingBox(ctx, this._bbox); + pattern = this._createGradient(ctx); + } + + return pattern; + } + +} + +function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) { + const coords = context.coords, + colors = context.colors; + const bytes = data.data, + rowSize = data.width * 4; + let tmp; + + if (coords[p1 + 1] > coords[p2 + 1]) { + tmp = p1; + p1 = p2; + p2 = tmp; + tmp = c1; + c1 = c2; + c2 = tmp; + } + + if (coords[p2 + 1] > coords[p3 + 1]) { + tmp = p2; + p2 = p3; + p3 = tmp; + tmp = c2; + c2 = c3; + c3 = tmp; + } + + if (coords[p1 + 1] > coords[p2 + 1]) { + tmp = p1; + p1 = p2; + p2 = tmp; + tmp = c1; + c1 = c2; + c2 = tmp; + } + + const x1 = (coords[p1] + context.offsetX) * context.scaleX; + const y1 = (coords[p1 + 1] + context.offsetY) * context.scaleY; + const x2 = (coords[p2] + context.offsetX) * context.scaleX; + const y2 = (coords[p2 + 1] + context.offsetY) * context.scaleY; + const x3 = (coords[p3] + context.offsetX) * context.scaleX; + const y3 = (coords[p3 + 1] + context.offsetY) * context.scaleY; + + if (y1 >= y3) { + return; + } + + const c1r = colors[c1], + c1g = colors[c1 + 1], + c1b = colors[c1 + 2]; + const c2r = colors[c2], + c2g = colors[c2 + 1], + c2b = colors[c2 + 2]; + const c3r = colors[c3], + c3g = colors[c3 + 1], + c3b = colors[c3 + 2]; + const minY = Math.round(y1), + maxY = Math.round(y3); + let xa, car, cag, cab; + let xb, cbr, cbg, cbb; + + for (let y = minY; y <= maxY; y++) { + if (y < y2) { + let k; + + if (y < y1) { + k = 0; + } else { + k = (y1 - y) / (y1 - y2); + } + + xa = x1 - (x1 - x2) * k; + car = c1r - (c1r - c2r) * k; + cag = c1g - (c1g - c2g) * k; + cab = c1b - (c1b - c2b) * k; + } else { + let k; + + if (y > y3) { + k = 1; + } else if (y2 === y3) { + k = 0; + } else { + k = (y2 - y) / (y2 - y3); + } + + xa = x2 - (x2 - x3) * k; + car = c2r - (c2r - c3r) * k; + cag = c2g - (c2g - c3g) * k; + cab = c2b - (c2b - c3b) * k; + } + + let k; + + if (y < y1) { + k = 0; + } else if (y > y3) { + k = 1; + } else { + k = (y1 - y) / (y1 - y3); + } + + xb = x1 - (x1 - x3) * k; + cbr = c1r - (c1r - c3r) * k; + cbg = c1g - (c1g - c3g) * k; + cbb = c1b - (c1b - c3b) * k; + const x1_ = Math.round(Math.min(xa, xb)); + const x2_ = Math.round(Math.max(xa, xb)); + let j = rowSize * y + x1_ * 4; + + for (let x = x1_; x <= x2_; x++) { + k = (xa - x) / (xa - xb); + + if (k < 0) { + k = 0; + } else if (k > 1) { + k = 1; + } + + bytes[j++] = car - (car - cbr) * k | 0; + bytes[j++] = cag - (cag - cbg) * k | 0; + bytes[j++] = cab - (cab - cbb) * k | 0; + bytes[j++] = 255; + } + } +} + +function drawFigure(data, figure, context) { + const ps = figure.coords; + const cs = figure.colors; + let i, ii; + + switch (figure.type) { + case "lattice": + const verticesPerRow = figure.verticesPerRow; + const rows = Math.floor(ps.length / verticesPerRow) - 1; + const cols = verticesPerRow - 1; + + for (i = 0; i < rows; i++) { + let q = i * verticesPerRow; + + for (let j = 0; j < cols; j++, q++) { + drawTriangle(data, context, ps[q], ps[q + 1], ps[q + verticesPerRow], cs[q], cs[q + 1], cs[q + verticesPerRow]); + drawTriangle(data, context, ps[q + verticesPerRow + 1], ps[q + 1], ps[q + verticesPerRow], cs[q + verticesPerRow + 1], cs[q + 1], cs[q + verticesPerRow]); + } + } + + break; + + case "triangles": + for (i = 0, ii = ps.length; i < ii; i += 3) { + drawTriangle(data, context, ps[i], ps[i + 1], ps[i + 2], cs[i], cs[i + 1], cs[i + 2]); + } + + break; + + default: + throw new Error("illegal figure"); + } +} + +class MeshShadingPattern extends BaseShadingPattern { + constructor(IR) { + super(); + this._coords = IR[2]; + this._colors = IR[3]; + this._figures = IR[4]; + this._bounds = IR[5]; + this._bbox = IR[7]; + this._background = IR[8]; + this.matrix = null; + } + + _createMeshCanvas(combinedScale, backgroundColor, cachedCanvases) { + const EXPECTED_SCALE = 1.1; + const MAX_PATTERN_SIZE = 3000; + const BORDER_SIZE = 2; + const offsetX = Math.floor(this._bounds[0]); + const offsetY = Math.floor(this._bounds[1]); + const boundsWidth = Math.ceil(this._bounds[2]) - offsetX; + const boundsHeight = Math.ceil(this._bounds[3]) - offsetY; + const width = Math.min(Math.ceil(Math.abs(boundsWidth * combinedScale[0] * EXPECTED_SCALE)), MAX_PATTERN_SIZE); + const height = Math.min(Math.ceil(Math.abs(boundsHeight * combinedScale[1] * EXPECTED_SCALE)), MAX_PATTERN_SIZE); + const scaleX = boundsWidth / width; + const scaleY = boundsHeight / height; + const context = { + coords: this._coords, + colors: this._colors, + offsetX: -offsetX, + offsetY: -offsetY, + scaleX: 1 / scaleX, + scaleY: 1 / scaleY + }; + const paddedWidth = width + BORDER_SIZE * 2; + const paddedHeight = height + BORDER_SIZE * 2; + const tmpCanvas = cachedCanvases.getCanvas("mesh", paddedWidth, paddedHeight, false); + const tmpCtx = tmpCanvas.context; + const data = tmpCtx.createImageData(width, height); + + if (backgroundColor) { + const bytes = data.data; + + for (let i = 0, ii = bytes.length; i < ii; i += 4) { + bytes[i] = backgroundColor[0]; + bytes[i + 1] = backgroundColor[1]; + bytes[i + 2] = backgroundColor[2]; + bytes[i + 3] = 255; + } + } + + for (const figure of this._figures) { + drawFigure(data, figure, context); + } + + tmpCtx.putImageData(data, BORDER_SIZE, BORDER_SIZE); + const canvas = tmpCanvas.canvas; + return { + canvas, + offsetX: offsetX - BORDER_SIZE * scaleX, + offsetY: offsetY - BORDER_SIZE * scaleY, + scaleX, + scaleY + }; + } + + getPattern(ctx, owner, inverse, pathType) { + applyBoundingBox(ctx, this._bbox); + let scale; + + if (pathType === PathType.SHADING) { + scale = _util.Util.singularValueDecompose2dScale(ctx.mozCurrentTransform); + } else { + scale = _util.Util.singularValueDecompose2dScale(owner.baseTransform); + + if (this.matrix) { + const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix); + + scale = [scale[0] * matrixScale[0], scale[1] * matrixScale[1]]; + } + } + + const temporaryPatternCanvas = this._createMeshCanvas(scale, pathType === PathType.SHADING ? null : this._background, owner.cachedCanvases); + + if (pathType !== PathType.SHADING) { + ctx.setTransform.apply(ctx, owner.baseTransform); + + if (this.matrix) { + ctx.transform.apply(ctx, this.matrix); + } + } + + ctx.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY); + ctx.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY); + return ctx.createPattern(temporaryPatternCanvas.canvas, "no-repeat"); + } + +} + +class DummyShadingPattern extends BaseShadingPattern { + getPattern() { + return "hotpink"; + } + +} + +function getShadingPattern(IR) { + switch (IR[0]) { + case "RadialAxial": + return new RadialAxialShadingPattern(IR); + + case "Mesh": + return new MeshShadingPattern(IR); + + case "Dummy": + return new DummyShadingPattern(); + } + + throw new Error(`Unknown IR type: ${IR[0]}`); +} + +const PaintType = { + COLORED: 1, + UNCOLORED: 2 +}; + +class TilingPattern { + static get MAX_PATTERN_SIZE() { + return (0, _util.shadow)(this, "MAX_PATTERN_SIZE", 3000); + } + + constructor(IR, color, ctx, canvasGraphicsFactory, baseTransform) { + this.operatorList = IR[2]; + this.matrix = IR[3] || [1, 0, 0, 1, 0, 0]; + this.bbox = IR[4]; + this.xstep = IR[5]; + this.ystep = IR[6]; + this.paintType = IR[7]; + this.tilingType = IR[8]; + this.color = color; + this.ctx = ctx; + this.canvasGraphicsFactory = canvasGraphicsFactory; + this.baseTransform = baseTransform; + } + + createPatternCanvas(owner) { + const operatorList = this.operatorList; + const bbox = this.bbox; + const xstep = this.xstep; + const ystep = this.ystep; + const paintType = this.paintType; + const tilingType = this.tilingType; + const color = this.color; + const canvasGraphicsFactory = this.canvasGraphicsFactory; + (0, _util.info)("TilingType: " + tilingType); + const x0 = bbox[0], + y0 = bbox[1], + x1 = bbox[2], + y1 = bbox[3]; + + const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix); + + const curMatrixScale = _util.Util.singularValueDecompose2dScale(this.baseTransform); + + const combinedScale = [matrixScale[0] * curMatrixScale[0], matrixScale[1] * curMatrixScale[1]]; + const dimx = this.getSizeAndScale(xstep, this.ctx.canvas.width, combinedScale[0]); + const dimy = this.getSizeAndScale(ystep, this.ctx.canvas.height, combinedScale[1]); + const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", dimx.size, dimy.size, true); + const tmpCtx = tmpCanvas.context; + const graphics = canvasGraphicsFactory.createCanvasGraphics(tmpCtx); + graphics.groupLevel = owner.groupLevel; + this.setFillAndStrokeStyleToContext(graphics, paintType, color); + let adjustedX0 = x0; + let adjustedY0 = y0; + let adjustedX1 = x1; + let adjustedY1 = y1; + + if (x0 < 0) { + adjustedX0 = 0; + adjustedX1 += Math.abs(x0); + } + + if (y0 < 0) { + adjustedY0 = 0; + adjustedY1 += Math.abs(y0); + } + + tmpCtx.translate(-(dimx.scale * adjustedX0), -(dimy.scale * adjustedY0)); + graphics.transform(dimx.scale, 0, 0, dimy.scale, 0, 0); + tmpCtx.save(); + this.clipBbox(graphics, adjustedX0, adjustedY0, adjustedX1, adjustedY1); + graphics.baseTransform = graphics.ctx.mozCurrentTransform.slice(); + graphics.executeOperatorList(operatorList); + graphics.endDrawing(); + return { + canvas: tmpCanvas.canvas, + scaleX: dimx.scale, + scaleY: dimy.scale, + offsetX: adjustedX0, + offsetY: adjustedY0 + }; + } + + getSizeAndScale(step, realOutputSize, scale) { + step = Math.abs(step); + const maxSize = Math.max(TilingPattern.MAX_PATTERN_SIZE, realOutputSize); + let size = Math.ceil(step * scale); + + if (size >= maxSize) { + size = maxSize; + } else { + scale = size / step; + } + + return { + scale, + size + }; + } + + clipBbox(graphics, x0, y0, x1, y1) { + const bboxWidth = x1 - x0; + const bboxHeight = y1 - y0; + graphics.ctx.rect(x0, y0, bboxWidth, bboxHeight); + graphics.current.updateRectMinMax(graphics.ctx.mozCurrentTransform, [x0, y0, x1, y1]); + graphics.clip(); + graphics.endPath(); + } + + setFillAndStrokeStyleToContext(graphics, paintType, color) { + const context = graphics.ctx, + current = graphics.current; + + switch (paintType) { + case PaintType.COLORED: + const ctx = this.ctx; + context.fillStyle = ctx.fillStyle; + context.strokeStyle = ctx.strokeStyle; + current.fillColor = ctx.fillStyle; + current.strokeColor = ctx.strokeStyle; + break; + + case PaintType.UNCOLORED: + const cssColor = _util.Util.makeHexColor(color[0], color[1], color[2]); + + context.fillStyle = cssColor; + context.strokeStyle = cssColor; + current.fillColor = cssColor; + current.strokeColor = cssColor; + break; + + default: + throw new _util.FormatError(`Unsupported paint type: ${paintType}`); + } + } + + getPattern(ctx, owner, inverse, pathType) { + let matrix = inverse; + + if (pathType !== PathType.SHADING) { + matrix = _util.Util.transform(matrix, owner.baseTransform); + + if (this.matrix) { + matrix = _util.Util.transform(matrix, this.matrix); + } + } + + const temporaryPatternCanvas = this.createPatternCanvas(owner); + let domMatrix = new DOMMatrix(matrix); + domMatrix = domMatrix.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY); + domMatrix = domMatrix.scale(1 / temporaryPatternCanvas.scaleX, 1 / temporaryPatternCanvas.scaleY); + const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "repeat"); + + try { + pattern.setTransform(domMatrix); + } catch (ex) { + (0, _util.warn)(`TilingPattern.getPattern: "${ex?.message}".`); + } + + return pattern; + } + +} + +exports.TilingPattern = TilingPattern; + +/***/ }), +/* 14 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.applyMaskImageData = applyMaskImageData; + +var _util = __w_pdfjs_require__(1); + +function applyMaskImageData({ + src, + srcPos = 0, + dest, + destPos = 0, + width, + height, + inverseDecode = false +}) { + const opaque = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; + const [zeroMapping, oneMapping] = !inverseDecode ? [opaque, 0] : [0, opaque]; + const widthInSource = width >> 3; + const widthRemainder = width & 7; + const srcLength = src.length; + dest = new Uint32Array(dest.buffer); + + for (let i = 0; i < height; i++) { + for (const max = srcPos + widthInSource; srcPos < max; srcPos++) { + const elem = srcPos < srcLength ? src[srcPos] : 255; + dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping; + dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping; + } + + if (widthRemainder === 0) { + continue; + } + + const elem = srcPos < srcLength ? src[srcPos++] : 255; + + for (let j = 0; j < widthRemainder; j++) { + dest[destPos++] = elem & 1 << 7 - j ? oneMapping : zeroMapping; + } + } + + return { + srcPos, + destPos + }; +} + +/***/ }), +/* 15 */ +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.GlobalWorkerOptions = void 0; +const GlobalWorkerOptions = Object.create(null); +exports.GlobalWorkerOptions = GlobalWorkerOptions; +GlobalWorkerOptions.workerPort = GlobalWorkerOptions.workerPort === undefined ? null : GlobalWorkerOptions.workerPort; +GlobalWorkerOptions.workerSrc = GlobalWorkerOptions.workerSrc === undefined ? "" : GlobalWorkerOptions.workerSrc; + +/***/ }), +/* 16 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.MessageHandler = void 0; + +var _util = __w_pdfjs_require__(1); + +const CallbackKind = { + UNKNOWN: 0, + DATA: 1, + ERROR: 2 +}; +const StreamKind = { + UNKNOWN: 0, + CANCEL: 1, + CANCEL_COMPLETE: 2, + CLOSE: 3, + ENQUEUE: 4, + ERROR: 5, + PULL: 6, + PULL_COMPLETE: 7, + START_COMPLETE: 8 +}; + +function wrapReason(reason) { + if (!(reason instanceof Error || typeof reason === "object" && reason !== null)) { + (0, _util.unreachable)('wrapReason: Expected "reason" to be a (possibly cloned) Error.'); + } + + switch (reason.name) { + case "AbortException": + return new _util.AbortException(reason.message); + + case "MissingPDFException": + return new _util.MissingPDFException(reason.message); + + case "PasswordException": + return new _util.PasswordException(reason.message, reason.code); + + case "UnexpectedResponseException": + return new _util.UnexpectedResponseException(reason.message, reason.status); + + case "UnknownErrorException": + return new _util.UnknownErrorException(reason.message, reason.details); + + default: + return new _util.UnknownErrorException(reason.message, reason.toString()); + } +} + +class MessageHandler { + constructor(sourceName, targetName, comObj) { + this.sourceName = sourceName; + this.targetName = targetName; + this.comObj = comObj; + this.callbackId = 1; + this.streamId = 1; + this.streamSinks = Object.create(null); + this.streamControllers = Object.create(null); + this.callbackCapabilities = Object.create(null); + this.actionHandler = Object.create(null); + + this._onComObjOnMessage = event => { + const data = event.data; + + if (data.targetName !== this.sourceName) { + return; + } + + if (data.stream) { + this._processStreamMessage(data); + + return; + } + + if (data.callback) { + const callbackId = data.callbackId; + const capability = this.callbackCapabilities[callbackId]; + + if (!capability) { + throw new Error(`Cannot resolve callback ${callbackId}`); + } + + delete this.callbackCapabilities[callbackId]; + + if (data.callback === CallbackKind.DATA) { + capability.resolve(data.data); + } else if (data.callback === CallbackKind.ERROR) { + capability.reject(wrapReason(data.reason)); + } else { + throw new Error("Unexpected callback case"); + } + + return; + } + + const action = this.actionHandler[data.action]; + + if (!action) { + throw new Error(`Unknown action from worker: ${data.action}`); + } + + if (data.callbackId) { + const cbSourceName = this.sourceName; + const cbTargetName = data.sourceName; + new Promise(function (resolve) { + resolve(action(data.data)); + }).then(function (result) { + comObj.postMessage({ + sourceName: cbSourceName, + targetName: cbTargetName, + callback: CallbackKind.DATA, + callbackId: data.callbackId, + data: result + }); + }, function (reason) { + comObj.postMessage({ + sourceName: cbSourceName, + targetName: cbTargetName, + callback: CallbackKind.ERROR, + callbackId: data.callbackId, + reason: wrapReason(reason) + }); + }); + return; + } + + if (data.streamId) { + this._createStreamSink(data); + + return; + } + + action(data.data); + }; + + comObj.addEventListener("message", this._onComObjOnMessage); + } + + on(actionName, handler) { + const ah = this.actionHandler; + + if (ah[actionName]) { + throw new Error(`There is already an actionName called "${actionName}"`); + } + + ah[actionName] = handler; + } + + send(actionName, data, transfers) { + this.comObj.postMessage({ + sourceName: this.sourceName, + targetName: this.targetName, + action: actionName, + data + }, transfers); + } + + sendWithPromise(actionName, data, transfers) { + const callbackId = this.callbackId++; + const capability = (0, _util.createPromiseCapability)(); + this.callbackCapabilities[callbackId] = capability; + + try { + this.comObj.postMessage({ + sourceName: this.sourceName, + targetName: this.targetName, + action: actionName, + callbackId, + data + }, transfers); + } catch (ex) { + capability.reject(ex); + } + + return capability.promise; + } + + sendWithStream(actionName, data, queueingStrategy, transfers) { + const streamId = this.streamId++, + sourceName = this.sourceName, + targetName = this.targetName, + comObj = this.comObj; + return new ReadableStream({ + start: controller => { + const startCapability = (0, _util.createPromiseCapability)(); + this.streamControllers[streamId] = { + controller, + startCall: startCapability, + pullCall: null, + cancelCall: null, + isClosed: false + }; + comObj.postMessage({ + sourceName, + targetName, + action: actionName, + streamId, + data, + desiredSize: controller.desiredSize + }, transfers); + return startCapability.promise; + }, + pull: controller => { + const pullCapability = (0, _util.createPromiseCapability)(); + this.streamControllers[streamId].pullCall = pullCapability; + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.PULL, + streamId, + desiredSize: controller.desiredSize + }); + return pullCapability.promise; + }, + cancel: reason => { + (0, _util.assert)(reason instanceof Error, "cancel must have a valid reason"); + const cancelCapability = (0, _util.createPromiseCapability)(); + this.streamControllers[streamId].cancelCall = cancelCapability; + this.streamControllers[streamId].isClosed = true; + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.CANCEL, + streamId, + reason: wrapReason(reason) + }); + return cancelCapability.promise; + } + }, queueingStrategy); + } + + _createStreamSink(data) { + const streamId = data.streamId, + sourceName = this.sourceName, + targetName = data.sourceName, + comObj = this.comObj; + const self = this, + action = this.actionHandler[data.action]; + const streamSink = { + enqueue(chunk, size = 1, transfers) { + if (this.isCancelled) { + return; + } + + const lastDesiredSize = this.desiredSize; + this.desiredSize -= size; + + if (lastDesiredSize > 0 && this.desiredSize <= 0) { + this.sinkCapability = (0, _util.createPromiseCapability)(); + this.ready = this.sinkCapability.promise; + } + + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.ENQUEUE, + streamId, + chunk + }, transfers); + }, + + close() { + if (this.isCancelled) { + return; + } + + this.isCancelled = true; + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.CLOSE, + streamId + }); + delete self.streamSinks[streamId]; + }, + + error(reason) { + (0, _util.assert)(reason instanceof Error, "error must have a valid reason"); + + if (this.isCancelled) { + return; + } + + this.isCancelled = true; + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.ERROR, + streamId, + reason: wrapReason(reason) + }); + }, + + sinkCapability: (0, _util.createPromiseCapability)(), + onPull: null, + onCancel: null, + isCancelled: false, + desiredSize: data.desiredSize, + ready: null + }; + streamSink.sinkCapability.resolve(); + streamSink.ready = streamSink.sinkCapability.promise; + this.streamSinks[streamId] = streamSink; + new Promise(function (resolve) { + resolve(action(data.data, streamSink)); + }).then(function () { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.START_COMPLETE, + streamId, + success: true + }); + }, function (reason) { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.START_COMPLETE, + streamId, + reason: wrapReason(reason) + }); + }); + } + + _processStreamMessage(data) { + const streamId = data.streamId, + sourceName = this.sourceName, + targetName = data.sourceName, + comObj = this.comObj; + const streamController = this.streamControllers[streamId], + streamSink = this.streamSinks[streamId]; + + switch (data.stream) { + case StreamKind.START_COMPLETE: + if (data.success) { + streamController.startCall.resolve(); + } else { + streamController.startCall.reject(wrapReason(data.reason)); + }
- this.ctx.fillStyle = color; - this.current.fillColor = color; - this.current.patternFill = false; - } + break;
- _getPattern(objId, matrix = null) { - let pattern; + case StreamKind.PULL_COMPLETE: + if (data.success) { + streamController.pullCall.resolve(); + } else { + streamController.pullCall.reject(wrapReason(data.reason)); + }
- if (this.cachedPatterns.has(objId)) { - pattern = this.cachedPatterns.get(objId); - } else { - pattern = (0, _pattern_helper.getShadingPattern)(this.objs.get(objId)); - this.cachedPatterns.set(objId, pattern); - } + break;
- if (matrix) { - pattern.matrix = matrix; - } + case StreamKind.PULL: + if (!streamSink) { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.PULL_COMPLETE, + streamId, + success: true + }); + break; + }
- return pattern; - } + if (streamSink.desiredSize <= 0 && data.desiredSize > 0) { + streamSink.sinkCapability.resolve(); + }
- shadingFill(objId) { - if (!this.contentVisible) { - return; - } + streamSink.desiredSize = data.desiredSize; + new Promise(function (resolve) { + resolve(streamSink.onPull && streamSink.onPull()); + }).then(function () { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.PULL_COMPLETE, + streamId, + success: true + }); + }, function (reason) { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.PULL_COMPLETE, + streamId, + reason: wrapReason(reason) + }); + }); + break;
- const ctx = this.ctx; - this.save(); + case StreamKind.ENQUEUE: + (0, _util.assert)(streamController, "enqueue should have stream controller");
- const pattern = this._getPattern(objId); + if (streamController.isClosed) { + break; + }
- ctx.fillStyle = pattern.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.SHADING); - const inv = ctx.mozCurrentTransformInverse; + streamController.controller.enqueue(data.chunk); + break;
- if (inv) { - const canvas = ctx.canvas; - const width = canvas.width; - const height = canvas.height; + case StreamKind.CLOSE: + (0, _util.assert)(streamController, "close should have stream controller");
- const bl = _util.Util.applyTransform([0, 0], inv); + if (streamController.isClosed) { + break; + }
- const br = _util.Util.applyTransform([0, height], inv); + streamController.isClosed = true; + streamController.controller.close();
- const ul = _util.Util.applyTransform([width, 0], inv); + this._deleteStreamController(streamController, streamId);
- const ur = _util.Util.applyTransform([width, height], inv); + break;
- const x0 = Math.min(bl[0], br[0], ul[0], ur[0]); - const y0 = Math.min(bl[1], br[1], ul[1], ur[1]); - const x1 = Math.max(bl[0], br[0], ul[0], ur[0]); - const y1 = Math.max(bl[1], br[1], ul[1], ur[1]); - this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0); - } else { - this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10); - } + case StreamKind.ERROR: + (0, _util.assert)(streamController, "error should have stream controller"); + streamController.controller.error(wrapReason(data.reason));
- this.compose(this.current.getClippedPathBoundingBox()); - this.restore(); - } + this._deleteStreamController(streamController, streamId);
- beginInlineImage() { - (0, _util.unreachable)("Should not call beginInlineImage"); - } + break;
- beginImageData() { - (0, _util.unreachable)("Should not call beginImageData"); - } + case StreamKind.CANCEL_COMPLETE: + if (data.success) { + streamController.cancelCall.resolve(); + } else { + streamController.cancelCall.reject(wrapReason(data.reason)); + }
- paintFormXObjectBegin(matrix, bbox) { - if (!this.contentVisible) { - return; - } + this._deleteStreamController(streamController, streamId);
- this.save(); - this.baseTransformStack.push(this.baseTransform); + break;
- if (Array.isArray(matrix) && matrix.length === 6) { - this.transform.apply(this, matrix); - } + case StreamKind.CANCEL: + if (!streamSink) { + break; + }
- this.baseTransform = this.ctx.mozCurrentTransform; + new Promise(function (resolve) { + resolve(streamSink.onCancel && streamSink.onCancel(wrapReason(data.reason))); + }).then(function () { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.CANCEL_COMPLETE, + streamId, + success: true + }); + }, function (reason) { + comObj.postMessage({ + sourceName, + targetName, + stream: StreamKind.CANCEL_COMPLETE, + streamId, + reason: wrapReason(reason) + }); + }); + streamSink.sinkCapability.reject(wrapReason(data.reason)); + streamSink.isCancelled = true; + delete this.streamSinks[streamId]; + break;
- if (bbox) { - const width = bbox[2] - bbox[0]; - const height = bbox[3] - bbox[1]; - this.ctx.rect(bbox[0], bbox[1], width, height); - this.current.updateRectMinMax(this.ctx.mozCurrentTransform, bbox); - this.clip(); - this.endPath(); + default: + throw new Error("Unexpected stream case"); } }
- paintFormXObjectEnd() { - if (!this.contentVisible) { - return; - } + async _deleteStreamController(streamController, streamId) { + await Promise.allSettled([streamController.startCall && streamController.startCall.promise, streamController.pullCall && streamController.pullCall.promise, streamController.cancelCall && streamController.cancelCall.promise]); + delete this.streamControllers[streamId]; + }
- this.restore(); - this.baseTransform = this.baseTransformStack.pop(); + destroy() { + this.comObj.removeEventListener("message", this._onComObjOnMessage); }
- beginGroup(group) { - if (!this.contentVisible) { - return; - } +}
- this.save(); +exports.MessageHandler = MessageHandler;
- if (this.inSMaskMode) { - this.endSMaskMode(); - this.current.activeSMask = null; - } +/***/ }), +/* 17 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- const currentCtx = this.ctx;
- if (!group.isolated) { - (0, _util.info)("TODO: Support non-isolated groups."); - }
- if (group.knockout) { - (0, _util.warn)("Knockout groups not supported."); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.Metadata = void 0;
- const currentTransform = currentCtx.mozCurrentTransform; +var _util = __w_pdfjs_require__(1);
- if (group.matrix) { - currentCtx.transform.apply(currentCtx, group.matrix); - } +class Metadata { + #metadataMap; + #data;
- if (!group.bbox) { - throw new Error("Bounding box is required."); - } + constructor({ + parsedData, + rawData + }) { + this.#metadataMap = parsedData; + this.#data = rawData; + }
- let bounds = _util.Util.getAxialAlignedBoundingBox(group.bbox, currentCtx.mozCurrentTransform); + getRaw() { + return this.#data; + }
- const canvasBounds = [0, 0, currentCtx.canvas.width, currentCtx.canvas.height]; - bounds = _util.Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0]; - const offsetX = Math.floor(bounds[0]); - const offsetY = Math.floor(bounds[1]); - let drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1); - let drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1); - let scaleX = 1, - scaleY = 1; + get(name) { + return this.#metadataMap.get(name) ?? null; + } + + getAll() { + return (0, _util.objectFromMap)(this.#metadataMap); + } + + has(name) { + return this.#metadataMap.has(name); + }
- if (drawnWidth > MAX_GROUP_SIZE) { - scaleX = drawnWidth / MAX_GROUP_SIZE; - drawnWidth = MAX_GROUP_SIZE; - } +}
- if (drawnHeight > MAX_GROUP_SIZE) { - scaleY = drawnHeight / MAX_GROUP_SIZE; - drawnHeight = MAX_GROUP_SIZE; - } +exports.Metadata = Metadata;
- this.current.startNewPathAndClipBox([0, 0, drawnWidth, drawnHeight]); - let cacheId = "groupAt" + this.groupLevel; +/***/ }), +/* 18 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- if (group.smask) { - cacheId += "_smask_" + this.smaskCounter++ % 2; - }
- const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight, true); - const groupCtx = scratchCanvas.context; - groupCtx.scale(1 / scaleX, 1 / scaleY); - groupCtx.translate(-offsetX, -offsetY); - groupCtx.transform.apply(groupCtx, currentTransform);
- if (group.smask) { - this.smaskStack.push({ - canvas: scratchCanvas.canvas, - context: groupCtx, - offsetX, - offsetY, - scaleX, - scaleY, - subtype: group.smask.subtype, - backdrop: group.smask.backdrop, - transferMap: group.smask.transferMap || null, - startTransformInverse: null - }); - } else { - currentCtx.setTransform(1, 0, 0, 1, 0, 0); - currentCtx.translate(offsetX, offsetY); - currentCtx.scale(scaleX, scaleY); - currentCtx.save(); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.OptionalContentConfig = void 0;
- copyCtxState(currentCtx, groupCtx); - this.ctx = groupCtx; - this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]); - this.groupStack.push(currentCtx); - this.groupLevel++; +var _util = __w_pdfjs_require__(1); + +class OptionalContentGroup { + constructor(name, intent) { + this.visible = true; + this.name = name; + this.intent = intent; }
- endGroup(group) { - if (!this.contentVisible) { - return; - } +}
- this.groupLevel--; - const groupCtx = this.ctx; - const ctx = this.groupStack.pop(); - this.ctx = ctx; - this.ctx.imageSmoothingEnabled = false; +class OptionalContentConfig { + constructor(data) { + this.name = null; + this.creator = null; + this._order = null; + this._groups = new Map();
- if (group.smask) { - this.tempSMask = this.smaskStack.pop(); - this.restore(); - } else { - this.ctx.restore(); - const currentMtx = this.ctx.mozCurrentTransform; - this.restore(); - this.ctx.save(); - this.ctx.setTransform.apply(this.ctx, currentMtx); + if (data === null) { + return; + }
- const dirtyBox = _util.Util.getAxialAlignedBoundingBox([0, 0, groupCtx.canvas.width, groupCtx.canvas.height], currentMtx); + this.name = data.name; + this.creator = data.creator; + this._order = data.order;
- this.ctx.drawImage(groupCtx.canvas, 0, 0); - this.ctx.restore(); - this.compose(dirtyBox); + for (const group of data.groups) { + this._groups.set(group.id, new OptionalContentGroup(group.name, group.intent)); } - }
- beginAnnotations() { - this.save(); + if (data.baseState === "OFF") { + for (const group of this._groups) { + group.visible = false; + } + }
- if (this.baseTransform) { - this.ctx.setTransform.apply(this.ctx, this.baseTransform); + for (const on of data.on) { + this._groups.get(on).visible = true; } - }
- endAnnotations() { - this.restore(); + for (const off of data.off) { + this._groups.get(off).visible = false; + } }
- beginAnnotation(id, rect, transform, matrix, hasOwnCanvas) { - this.save(); + _evaluateVisibilityExpression(array) { + const length = array.length;
- if (Array.isArray(rect) && rect.length === 4) { - const width = rect[2] - rect[0]; - const height = rect[3] - rect[1]; + if (length < 2) { + return true; + }
- if (hasOwnCanvas && this.annotationCanvasMap) { - transform = transform.slice(); - transform[4] -= rect[0]; - transform[5] -= rect[1]; - rect = rect.slice(); - rect[0] = rect[1] = 0; - rect[2] = width; - rect[3] = height; + const operator = array[0];
- const [scaleX, scaleY] = _util.Util.singularValueDecompose2dScale(this.ctx.mozCurrentTransform); + for (let i = 1; i < length; i++) { + const element = array[i]; + let state;
- const { - viewportScale - } = this; - const canvasWidth = Math.ceil(width * this.outputScaleX * viewportScale); - const canvasHeight = Math.ceil(height * this.outputScaleY * viewportScale); - this.annotationCanvas = this.canvasFactory.create(canvasWidth, canvasHeight); - const { - canvas, - context - } = this.annotationCanvas; - const viewportScaleFactorStr = `var(--zoom-factor) * ${_display_utils.PixelsPerInch.PDF_TO_CSS_UNITS}`; - canvas.style.width = `calc(${width}px * ${viewportScaleFactorStr})`; - canvas.style.height = `calc(${height}px * ${viewportScaleFactorStr})`; - this.annotationCanvasMap.set(id, canvas); - this.annotationCanvas.savedCtx = this.ctx; - this.ctx = context; - this.ctx.setTransform(scaleX, 0, 0, -scaleY, 0, height * scaleY); - addContextCurrentTransform(this.ctx); - resetCtxToDefault(this.ctx, this.foregroundColor); + if (Array.isArray(element)) { + state = this._evaluateVisibilityExpression(element); + } else if (this._groups.has(element)) { + state = this._groups.get(element).visible; } else { - resetCtxToDefault(this.ctx, this.foregroundColor); - this.ctx.rect(rect[0], rect[1], width, height); - this.ctx.clip(); - this.endPath(); + (0, _util.warn)(`Optional content group not found: ${element}`); + return true; } - } - - this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height); - this.transform.apply(this, transform); - this.transform.apply(this, matrix); - }
- endAnnotation() { - if (this.annotationCanvas) { - this.ctx = this.annotationCanvas.savedCtx; - delete this.annotationCanvas.savedCtx; - delete this.annotationCanvas; - } + switch (operator) { + case "And": + if (!state) { + return false; + }
- this.restore(); - } + break;
- paintImageMaskXObject(img) { - if (!this.contentVisible) { - return; - } + case "Or": + if (state) { + return true; + }
- const count = img.count; - img = this.getObject(img.data, img); - img.count = count; - const ctx = this.ctx; - const glyph = this.processingType3; + break;
- if (glyph) { - if (glyph.compiled === undefined) { - glyph.compiled = compileType3Glyph(img); - } + case "Not": + return !state;
- if (glyph.compiled) { - glyph.compiled(ctx); - return; + default: + return true; } }
- const mask = this._createMaskCanvas(img); - - const maskCanvas = mask.canvas; - ctx.save(); - ctx.setTransform(1, 0, 0, 1, 0, 0); - ctx.drawImage(maskCanvas, mask.offsetX, mask.offsetY); - ctx.restore(); - this.compose(); + return operator === "And"; }
- paintImageMaskXObjectRepeat(img, scaleX, skewX = 0, skewY = 0, scaleY, positions) { - if (!this.contentVisible) { - return; + isVisible(group) { + if (this._groups.size === 0) { + return true; }
- img = this.getObject(img.data, img); - const ctx = this.ctx; - ctx.save(); - const currentTransform = ctx.mozCurrentTransform; - ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0); + if (!group) { + (0, _util.warn)("Optional content group not defined."); + return true; + }
- const mask = this._createMaskCanvas(img); + if (group.type === "OCG") { + if (!this._groups.has(group.id)) { + (0, _util.warn)(`Optional content group not found: ${group.id}`); + return true; + }
- ctx.setTransform(1, 0, 0, 1, 0, 0); + return this._groups.get(group.id).visible; + } else if (group.type === "OCMD") { + if (group.expression) { + return this._evaluateVisibilityExpression(group.expression); + }
- for (let i = 0, ii = positions.length; i < ii; i += 2) { - const trans = _util.Util.transform(currentTransform, [scaleX, skewX, skewY, scaleY, positions[i], positions[i + 1]]); + if (!group.policy || group.policy === "AnyOn") { + for (const id of group.ids) { + if (!this._groups.has(id)) { + (0, _util.warn)(`Optional content group not found: ${id}`); + return true; + } + + if (this._groups.get(id).visible) { + return true; + } + }
- const [x, y] = _util.Util.applyTransform([0, 0], trans); + return false; + } else if (group.policy === "AllOn") { + for (const id of group.ids) { + if (!this._groups.has(id)) { + (0, _util.warn)(`Optional content group not found: ${id}`); + return true; + }
- ctx.drawImage(mask.canvas, x, y); - } + if (!this._groups.get(id).visible) { + return false; + } + }
- ctx.restore(); - this.compose(); - } + return true; + } else if (group.policy === "AnyOff") { + for (const id of group.ids) { + if (!this._groups.has(id)) { + (0, _util.warn)(`Optional content group not found: ${id}`); + return true; + }
- paintImageMaskXObjectGroup(images) { - if (!this.contentVisible) { - return; - } + if (!this._groups.get(id).visible) { + return true; + } + }
- const ctx = this.ctx; - const fillColor = this.current.fillColor; - const isPatternFill = this.current.patternFill; + return false; + } else if (group.policy === "AllOff") { + for (const id of group.ids) { + if (!this._groups.has(id)) { + (0, _util.warn)(`Optional content group not found: ${id}`); + return true; + }
- for (let i = 0, ii = images.length; i < ii; i++) { - const image = images[i]; - const width = image.width, - height = image.height; - const maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height, false); - const maskCtx = maskCanvas.context; - maskCtx.save(); - putBinaryImageMask(maskCtx, image); - maskCtx.globalCompositeOperation = "source-in"; - maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL) : fillColor; - maskCtx.fillRect(0, 0, width, height); - maskCtx.restore(); - ctx.save(); - ctx.transform.apply(ctx, image.transform); - ctx.scale(1, -1); - drawImageAtIntegerCoords(ctx, maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1); - ctx.restore(); - } + if (this._groups.get(id).visible) { + return false; + } + }
- this.compose(); - } + return true; + }
- paintImageXObject(objId) { - if (!this.contentVisible) { - return; + (0, _util.warn)(`Unknown optional content policy ${group.policy}.`); + return true; }
- const imgData = this.getObject(objId); + (0, _util.warn)(`Unknown group type ${group.type}.`); + return true; + }
- if (!imgData) { - (0, _util.warn)("Dependent image isn't ready yet"); + setVisibility(id, visible = true) { + if (!this._groups.has(id)) { + (0, _util.warn)(`Optional content group not found: ${id}`); return; }
- this.paintInlineImageXObject(imgData); + this._groups.get(id).visible = !!visible; }
- paintImageXObjectRepeat(objId, scaleX, scaleY, positions) { - if (!this.contentVisible) { - return; + getOrder() { + if (!this._groups.size) { + return null; }
- const imgData = this.getObject(objId); - - if (!imgData) { - (0, _util.warn)("Dependent image isn't ready yet"); - return; + if (this._order) { + return this._order.slice(); }
- const width = imgData.width; - const height = imgData.height; - const map = []; - - for (let i = 0, ii = positions.length; i < ii; i += 2) { - map.push({ - transform: [scaleX, 0, 0, scaleY, positions[i], positions[i + 1]], - x: 0, - y: 0, - w: width, - h: height - }); - } + return Array.from(this._groups.keys()); + }
- this.paintInlineImageXObjectGroup(imgData, map); + getGroups() { + return this._groups.size > 0 ? (0, _util.objectFromMap)(this._groups) : null; }
- paintInlineImageXObject(imgData) { - if (!this.contentVisible) { - return; - } + getGroup(id) { + return this._groups.get(id) || null; + }
- const width = imgData.width; - const height = imgData.height; - const ctx = this.ctx; - this.save(); - ctx.scale(1 / width, -1 / height); - let imgToPaint; +}
- if (typeof HTMLElement === "function" && imgData instanceof HTMLElement || !imgData.data) { - imgToPaint = imgData; - } else { - const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", width, height, false); - const tmpCtx = tmpCanvas.context; - putBinaryImageData(tmpCtx, imgData, this.current.transferMaps); - imgToPaint = tmpCanvas.canvas; - } +exports.OptionalContentConfig = OptionalContentConfig;
- const scaled = this._scaleImage(imgToPaint, ctx.mozCurrentTransformInverse); +/***/ }), +/* 19 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- ctx.imageSmoothingEnabled = getImageSmoothingEnabled(ctx.mozCurrentTransform, imgData.interpolate); - const [rWidth, rHeight] = drawImageAtIntegerCoords(ctx, scaled.img, 0, 0, scaled.paintWidth, scaled.paintHeight, 0, -height, width, height);
- if (this.imageLayer) { - const position = this.getCanvasPosition(0, -height); - this.imageLayer.appendImage({ - imgData, - left: position[0], - top: position[1], - width: rWidth, - height: rHeight - }); - }
- this.compose(); - this.restore(); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.PDFDataTransportStream = void 0;
- paintInlineImageXObjectGroup(imgData, map) { - if (!this.contentVisible) { - return; - } +var _util = __w_pdfjs_require__(1);
- const ctx = this.ctx; - const w = imgData.width; - const h = imgData.height; - const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", w, h, false); - const tmpCtx = tmpCanvas.context; - putBinaryImageData(tmpCtx, imgData, this.current.transferMaps); +var _display_utils = __w_pdfjs_require__(4);
- for (let i = 0, ii = map.length; i < ii; i++) { - const entry = map[i]; - ctx.save(); - ctx.transform.apply(ctx, entry.transform); - ctx.scale(1, -1); - drawImageAtIntegerCoords(ctx, tmpCanvas.canvas, entry.x, entry.y, entry.w, entry.h, 0, -1, 1, 1); +class PDFDataTransportStream { + constructor(params, pdfDataRangeTransport) { + (0, _util.assert)(pdfDataRangeTransport, 'PDFDataTransportStream - missing required "pdfDataRangeTransport" argument.'); + this._queuedChunks = []; + this._progressiveDone = params.progressiveDone || false; + this._contentDispositionFilename = params.contentDispositionFilename || null; + const initialData = params.initialData;
- if (this.imageLayer) { - const position = this.getCanvasPosition(entry.x, entry.y); - this.imageLayer.appendImage({ - imgData, - left: position[0], - top: position[1], - width: w, - height: h - }); - } + if (initialData?.length > 0) { + const buffer = new Uint8Array(initialData).buffer;
- ctx.restore(); + this._queuedChunks.push(buffer); }
- this.compose(); - } - - paintSolidColorImageMask() { - if (!this.contentVisible) { - return; - } + this._pdfDataRangeTransport = pdfDataRangeTransport; + this._isStreamingSupported = !params.disableStream; + this._isRangeSupported = !params.disableRange; + this._contentLength = params.length; + this._fullRequestReader = null; + this._rangeReaders = [];
- this.ctx.fillRect(0, 0, 1, 1); - this.compose(); - } + this._pdfDataRangeTransport.addRangeListener((begin, chunk) => { + this._onReceiveData({ + begin, + chunk + }); + });
- markPoint(tag) {} + this._pdfDataRangeTransport.addProgressListener((loaded, total) => { + this._onProgress({ + loaded, + total + }); + });
- markPointProps(tag, properties) {} + this._pdfDataRangeTransport.addProgressiveReadListener(chunk => { + this._onReceiveData({ + chunk + }); + });
- beginMarkedContent(tag) { - this.markedContentStack.push({ - visible: true + this._pdfDataRangeTransport.addProgressiveDoneListener(() => { + this._onProgressiveDone(); }); + + this._pdfDataRangeTransport.transportReady(); }
- beginMarkedContentProps(tag, properties) { - if (tag === "OC") { - this.markedContentStack.push({ - visible: this.optionalContentConfig.isVisible(properties) - }); + _onReceiveData(args) { + const buffer = new Uint8Array(args.chunk).buffer; + + if (args.begin === undefined) { + if (this._fullRequestReader) { + this._fullRequestReader._enqueue(buffer); + } else { + this._queuedChunks.push(buffer); + } } else { - this.markedContentStack.push({ - visible: true + const found = this._rangeReaders.some(function (rangeReader) { + if (rangeReader._begin !== args.begin) { + return false; + } + + rangeReader._enqueue(buffer); + + return true; }); - }
- this.contentVisible = this.isContentVisible(); + (0, _util.assert)(found, "_onReceiveData - no `PDFDataTransportStreamRangeReader` instance found."); + } }
- endMarkedContent() { - this.markedContentStack.pop(); - this.contentVisible = this.isContentVisible(); + get _progressiveDataLength() { + return this._fullRequestReader?._loaded ?? 0; }
- beginCompat() {} - - endCompat() {} + _onProgress(evt) { + if (evt.total === undefined) { + const firstReader = this._rangeReaders[0];
- consumePath(clipBox) { - const isEmpty = this.current.isEmptyClip(); + if (firstReader?.onProgress) { + firstReader.onProgress({ + loaded: evt.loaded + }); + } + } else { + const fullReader = this._fullRequestReader;
- if (this.pendingClip) { - this.current.updateClipFromPath(); + if (fullReader?.onProgress) { + fullReader.onProgress({ + loaded: evt.loaded, + total: evt.total + }); + } } + }
- if (!this.pendingClip) { - this.compose(clipBox); + _onProgressiveDone() { + if (this._fullRequestReader) { + this._fullRequestReader.progressiveDone(); }
- const ctx = this.ctx; + this._progressiveDone = true; + }
- if (this.pendingClip) { - if (!isEmpty) { - if (this.pendingClip === EO_CLIP) { - ctx.clip("evenodd"); - } else { - ctx.clip(); - } - } + _removeRangeReader(reader) { + const i = this._rangeReaders.indexOf(reader);
- this.pendingClip = null; + if (i >= 0) { + this._rangeReaders.splice(i, 1); } - - this.current.startNewPathAndClipBox(this.current.clipBox); - ctx.beginPath(); }
- getSinglePixelWidth() { - if (!this._cachedGetSinglePixelWidth) { - const m = this.ctx.mozCurrentTransform; + getFullReader() { + (0, _util.assert)(!this._fullRequestReader, "PDFDataTransportStream.getFullReader can only be called once."); + const queuedChunks = this._queuedChunks; + this._queuedChunks = null; + return new PDFDataTransportStreamReader(this, queuedChunks, this._progressiveDone, this._contentDispositionFilename); + }
- if (m[1] === 0 && m[2] === 0) { - this._cachedGetSinglePixelWidth = 1 / Math.min(Math.abs(m[0]), Math.abs(m[3])); - } else { - const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]); - const normX = Math.hypot(m[0], m[2]); - const normY = Math.hypot(m[1], m[3]); - this._cachedGetSinglePixelWidth = Math.max(normX, normY) / absDet; - } + getRangeReader(begin, end) { + if (end <= this._progressiveDataLength) { + return null; }
- return this._cachedGetSinglePixelWidth; - } + const reader = new PDFDataTransportStreamRangeReader(this, begin, end);
- getScaleForStroking() { - if (!this._cachedScaleForStroking) { - const { - lineWidth - } = this.current; - const m = this.ctx.mozCurrentTransform; - let scaleX, scaleY; + this._pdfDataRangeTransport.requestDataRange(begin, end);
- if (m[1] === 0 && m[2] === 0) { - const normX = Math.abs(m[0]); - const normY = Math.abs(m[3]); + this._rangeReaders.push(reader);
- if (lineWidth === 0) { - scaleX = 1 / normX; - scaleY = 1 / normY; - } else { - const scaledXLineWidth = normX * lineWidth; - const scaledYLineWidth = normY * lineWidth; - scaleX = scaledXLineWidth < 1 ? 1 / scaledXLineWidth : 1; - scaleY = scaledYLineWidth < 1 ? 1 / scaledYLineWidth : 1; - } - } else { - const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]); - const normX = Math.hypot(m[0], m[1]); - const normY = Math.hypot(m[2], m[3]); + return reader; + }
- if (lineWidth === 0) { - scaleX = normY / absDet; - scaleY = normX / absDet; - } else { - const baseArea = lineWidth * absDet; - scaleX = normY > baseArea ? normY / baseArea : 1; - scaleY = normX > baseArea ? normX / baseArea : 1; - } - } + cancelAllRequests(reason) { + if (this._fullRequestReader) { + this._fullRequestReader.cancel(reason); + }
- this._cachedScaleForStroking = [scaleX, scaleY]; + for (const reader of this._rangeReaders.slice(0)) { + reader.cancel(reason); }
- return this._cachedScaleForStroking; + this._pdfDataRangeTransport.abort(); }
- rescaleAndStroke(saveRestore) { - const { - ctx - } = this; - const { - lineWidth - } = this.current; - const [scaleX, scaleY] = this.getScaleForStroking(); - ctx.lineWidth = lineWidth || 1; +}
- if (scaleX === 1 && scaleY === 1) { - ctx.stroke(); - return; - } +exports.PDFDataTransportStream = PDFDataTransportStream;
- let savedMatrix, savedDashes, savedDashOffset; +class PDFDataTransportStreamReader { + constructor(stream, queuedChunks, progressiveDone = false, contentDispositionFilename = null) { + this._stream = stream; + this._done = progressiveDone || false; + this._filename = (0, _display_utils.isPdfFile)(contentDispositionFilename) ? contentDispositionFilename : null; + this._queuedChunks = queuedChunks || []; + this._loaded = 0;
- if (saveRestore) { - savedMatrix = ctx.mozCurrentTransform.slice(); - savedDashes = ctx.getLineDash().slice(); - savedDashOffset = ctx.lineDashOffset; + for (const chunk of this._queuedChunks) { + this._loaded += chunk.byteLength; }
- ctx.scale(scaleX, scaleY); - const scale = Math.max(scaleX, scaleY); - ctx.setLineDash(ctx.getLineDash().map(x => x / scale)); - ctx.lineDashOffset /= scale; - ctx.stroke(); + this._requests = []; + this._headersReady = Promise.resolve(); + stream._fullRequestReader = this; + this.onProgress = null; + }
- if (saveRestore) { - ctx.setTransform(...savedMatrix); - ctx.setLineDash(savedDashes); - ctx.lineDashOffset = savedDashOffset; + _enqueue(chunk) { + if (this._done) { + return; } - }
- getCanvasPosition(x, y) { - const transform = this.ctx.mozCurrentTransform; - return [transform[0] * x + transform[2] * y + transform[4], transform[1] * x + transform[3] * y + transform[5]]; - } + if (this._requests.length > 0) { + const requestCapability = this._requests.shift();
- isContentVisible() { - for (let i = this.markedContentStack.length - 1; i >= 0; i--) { - if (!this.markedContentStack[i].visible) { - return false; - } + requestCapability.resolve({ + value: chunk, + done: false + }); + } else { + this._queuedChunks.push(chunk); }
- return true; + this._loaded += chunk.byteLength; }
-} + get headersReady() { + return this._headersReady; + }
-exports.CanvasGraphics = CanvasGraphics; + get filename() { + return this._filename; + }
-for (const op in _util.OPS) { - if (CanvasGraphics.prototype[op] !== undefined) { - CanvasGraphics.prototype[_util.OPS[op]] = CanvasGraphics.prototype[op]; + get isRangeSupported() { + return this._stream._isRangeSupported; } -}
-/***/ }), -/* 11 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + get isStreamingSupported() { + return this._stream._isStreamingSupported; + }
+ get contentLength() { + return this._stream._contentLength; + }
+ async read() { + if (this._queuedChunks.length > 0) { + const chunk = this._queuedChunks.shift();
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.TilingPattern = exports.PathType = void 0; -exports.getShadingPattern = getShadingPattern; + return { + value: chunk, + done: false + }; + }
-var _util = __w_pdfjs_require__(1); + if (this._done) { + return { + value: undefined, + done: true + }; + }
-var _is_node = __w_pdfjs_require__(3); + const requestCapability = (0, _util.createPromiseCapability)();
-const PathType = { - FILL: "Fill", - STROKE: "Stroke", - SHADING: "Shading" -}; -exports.PathType = PathType; + this._requests.push(requestCapability);
-function applyBoundingBox(ctx, bbox) { - if (!bbox || _is_node.isNodeJS) { - return; + return requestCapability.promise; }
- const width = bbox[2] - bbox[0]; - const height = bbox[3] - bbox[1]; - const region = new Path2D(); - region.rect(bbox[0], bbox[1], width, height); - ctx.clip(region); -} + cancel(reason) { + this._done = true;
-class BaseShadingPattern { - constructor() { - if (this.constructor === BaseShadingPattern) { - (0, _util.unreachable)("Cannot initialize BaseShadingPattern."); + for (const requestCapability of this._requests) { + requestCapability.resolve({ + value: undefined, + done: true + }); } + + this._requests.length = 0; }
- getPattern() { - (0, _util.unreachable)("Abstract method `getPattern` called."); + progressiveDone() { + if (this._done) { + return; + } + + this._done = true; }
}
-class RadialAxialShadingPattern extends BaseShadingPattern { - constructor(IR) { - super(); - this._type = IR[1]; - this._bbox = IR[2]; - this._colorStops = IR[3]; - this._p0 = IR[4]; - this._p1 = IR[5]; - this._r0 = IR[6]; - this._r1 = IR[7]; - this.matrix = null; +class PDFDataTransportStreamRangeReader { + constructor(stream, begin, end) { + this._stream = stream; + this._begin = begin; + this._end = end; + this._queuedChunk = null; + this._requests = []; + this._done = false; + this.onProgress = null; }
- _createGradient(ctx) { - let grad; - - if (this._type === "axial") { - grad = ctx.createLinearGradient(this._p0[0], this._p0[1], this._p1[0], this._p1[1]); - } else if (this._type === "radial") { - grad = ctx.createRadialGradient(this._p0[0], this._p0[1], this._r0, this._p1[0], this._p1[1], this._r1); + _enqueue(chunk) { + if (this._done) { + return; }
- for (const colorStop of this._colorStops) { - grad.addColorStop(colorStop[0], colorStop[1]); - } + if (this._requests.length === 0) { + this._queuedChunk = chunk; + } else { + const requestsCapability = this._requests.shift();
- return grad; - } + requestsCapability.resolve({ + value: chunk, + done: false + });
- getPattern(ctx, owner, inverse, pathType) { - let pattern; + for (const requestCapability of this._requests) { + requestCapability.resolve({ + value: undefined, + done: true + }); + }
- if (pathType === PathType.STROKE || pathType === PathType.FILL) { - const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, ctx.mozCurrentTransform) || [0, 0, 0, 0]; - const width = Math.ceil(ownerBBox[2] - ownerBBox[0]) || 1; - const height = Math.ceil(ownerBBox[3] - ownerBBox[1]) || 1; - const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", width, height, true); - const tmpCtx = tmpCanvas.context; - tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); - tmpCtx.beginPath(); - tmpCtx.rect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); - tmpCtx.translate(-ownerBBox[0], -ownerBBox[1]); - inverse = _util.Util.transform(inverse, [1, 0, 0, 1, ownerBBox[0], ownerBBox[1]]); - tmpCtx.transform.apply(tmpCtx, owner.baseTransform); + this._requests.length = 0; + }
- if (this.matrix) { - tmpCtx.transform.apply(tmpCtx, this.matrix); - } + this._done = true;
- applyBoundingBox(tmpCtx, this._bbox); - tmpCtx.fillStyle = this._createGradient(tmpCtx); - tmpCtx.fill(); - pattern = ctx.createPattern(tmpCanvas.canvas, "no-repeat"); - const domMatrix = new DOMMatrix(inverse); + this._stream._removeRangeReader(this); + }
- try { - pattern.setTransform(domMatrix); - } catch (ex) { - (0, _util.warn)(`RadialAxialShadingPattern.getPattern: "${ex?.message}".`); - } - } else { - applyBoundingBox(ctx, this._bbox); - pattern = this._createGradient(ctx); + get isStreamingSupported() { + return false; + } + + async read() { + if (this._queuedChunk) { + const chunk = this._queuedChunk; + this._queuedChunk = null; + return { + value: chunk, + done: false + }; }
- return pattern; - } + if (this._done) { + return { + value: undefined, + done: true + }; + }
-} + const requestCapability = (0, _util.createPromiseCapability)();
-function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) { - const coords = context.coords, - colors = context.colors; - const bytes = data.data, - rowSize = data.width * 4; - let tmp; + this._requests.push(requestCapability);
- if (coords[p1 + 1] > coords[p2 + 1]) { - tmp = p1; - p1 = p2; - p2 = tmp; - tmp = c1; - c1 = c2; - c2 = tmp; + return requestCapability.promise; }
- if (coords[p2 + 1] > coords[p3 + 1]) { - tmp = p2; - p2 = p3; - p3 = tmp; - tmp = c2; - c2 = c3; - c3 = tmp; - } + cancel(reason) { + this._done = true;
- if (coords[p1 + 1] > coords[p2 + 1]) { - tmp = p1; - p1 = p2; - p2 = tmp; - tmp = c1; - c1 = c2; - c2 = tmp; - } + for (const requestCapability of this._requests) { + requestCapability.resolve({ + value: undefined, + done: true + }); + }
- const x1 = (coords[p1] + context.offsetX) * context.scaleX; - const y1 = (coords[p1 + 1] + context.offsetY) * context.scaleY; - const x2 = (coords[p2] + context.offsetX) * context.scaleX; - const y2 = (coords[p2 + 1] + context.offsetY) * context.scaleY; - const x3 = (coords[p3] + context.offsetX) * context.scaleX; - const y3 = (coords[p3 + 1] + context.offsetY) * context.scaleY; + this._requests.length = 0;
- if (y1 >= y3) { - return; + this._stream._removeRangeReader(this); }
- const c1r = colors[c1], - c1g = colors[c1 + 1], - c1b = colors[c1 + 2]; - const c2r = colors[c2], - c2g = colors[c2 + 1], - c2b = colors[c2 + 2]; - const c3r = colors[c3], - c3g = colors[c3 + 1], - c3b = colors[c3 + 2]; - const minY = Math.round(y1), - maxY = Math.round(y3); - let xa, car, cag, cab; - let xb, cbr, cbg, cbb; +}
- for (let y = minY; y <= maxY; y++) { - if (y < y2) { - let k; +/***/ }), +/* 20 */ +/***/ ((__unused_webpack_module, exports) => {
- if (y < y1) { - k = 0; - } else { - k = (y1 - y) / (y1 - y2); - }
- xa = x1 - (x1 - x2) * k; - car = c1r - (c1r - c2r) * k; - cag = c1g - (c1g - c2g) * k; - cab = c1b - (c1b - c2b) * k; - } else { - let k;
- if (y > y3) { - k = 1; - } else if (y2 === y3) { - k = 0; - } else { - k = (y2 - y) / (y2 - y3); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.XfaText = void 0;
- xa = x2 - (x2 - x3) * k; - car = c2r - (c2r - c3r) * k; - cag = c2g - (c2g - c3g) * k; - cab = c2b - (c2b - c3b) * k; - } +class XfaText { + static textContent(xfa) { + const items = []; + const output = { + items, + styles: Object.create(null) + };
- let k; + function walk(node) { + if (!node) { + return; + }
- if (y < y1) { - k = 0; - } else if (y > y3) { - k = 1; - } else { - k = (y1 - y) / (y1 - y3); - } + let str = null; + const name = node.name;
- xb = x1 - (x1 - x3) * k; - cbr = c1r - (c1r - c3r) * k; - cbg = c1g - (c1g - c3g) * k; - cbb = c1b - (c1b - c3b) * k; - const x1_ = Math.round(Math.min(xa, xb)); - const x2_ = Math.round(Math.max(xa, xb)); - let j = rowSize * y + x1_ * 4; + if (name === "#text") { + str = node.value; + } else if (!XfaText.shouldBuildText(name)) { + return; + } else if (node?.attributes?.textContent) { + str = node.attributes.textContent; + } else if (node.value) { + str = node.value; + }
- for (let x = x1_; x <= x2_; x++) { - k = (xa - x) / (xa - xb); + if (str !== null) { + items.push({ + str + }); + }
- if (k < 0) { - k = 0; - } else if (k > 1) { - k = 1; + if (!node.children) { + return; }
- bytes[j++] = car - (car - cbr) * k | 0; - bytes[j++] = cag - (cag - cbg) * k | 0; - bytes[j++] = cab - (cab - cbb) * k | 0; - bytes[j++] = 255; + for (const child of node.children) { + walk(child); + } } + + walk(xfa); + return output; + } + + static shouldBuildText(name) { + return !(name === "textarea" || name === "input" || name === "option" || name === "select"); } + }
-function drawFigure(data, figure, context) { - const ps = figure.coords; - const cs = figure.colors; - let i, ii; +exports.XfaText = XfaText;
- switch (figure.type) { - case "lattice": - const verticesPerRow = figure.verticesPerRow; - const rows = Math.floor(ps.length / verticesPerRow) - 1; - const cols = verticesPerRow - 1; +/***/ }), +/* 21 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- for (i = 0; i < rows; i++) { - let q = i * verticesPerRow;
- for (let j = 0; j < cols; j++, q++) { - drawTriangle(data, context, ps[q], ps[q + 1], ps[q + verticesPerRow], cs[q], cs[q + 1], cs[q + verticesPerRow]); - drawTriangle(data, context, ps[q + verticesPerRow + 1], ps[q + 1], ps[q + verticesPerRow], cs[q + verticesPerRow + 1], cs[q + 1], cs[q + verticesPerRow]); - } - }
- break; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.AnnotationEditorLayer = void 0;
- case "triangles": - for (i = 0, ii = ps.length; i < ii; i += 3) { - drawTriangle(data, context, ps[i], ps[i + 1], ps[i + 2], cs[i], cs[i + 1], cs[i + 2]); - } +var _util = __w_pdfjs_require__(1);
- break; +var _display_utils = __w_pdfjs_require__(4);
- default: - throw new Error("illegal figure"); - } -} +var _tools = __w_pdfjs_require__(9);
-class MeshShadingPattern extends BaseShadingPattern { - constructor(IR) { - super(); - this._coords = IR[2]; - this._colors = IR[3]; - this._figures = IR[4]; - this._bounds = IR[5]; - this._bbox = IR[7]; - this._background = IR[8]; - this.matrix = null; +var _freetext = __w_pdfjs_require__(22); + +var _ink = __w_pdfjs_require__(23); + +class AnnotationEditorLayer { + #allowClick = false; + #boundPointerup = this.pointerup.bind(this); + #boundPointerdown = this.pointerdown.bind(this); + #editors = new Map(); + #isCleaningUp = false; + #textLayerMap = new WeakMap(); + #textNodes = new Map(); + #uiManager; + #waitingEditors = new Set(); + static _initialized = false; + + constructor(options) { + if (!AnnotationEditorLayer._initialized) { + AnnotationEditorLayer._initialized = true; + + _freetext.FreeTextEditor.initialize(options.l10n); + + _ink.InkEditor.initialize(options.l10n); + + options.uiManager.registerEditorTypes([_freetext.FreeTextEditor, _ink.InkEditor]); + } + + this.#uiManager = options.uiManager; + this.annotationStorage = options.annotationStorage; + this.pageIndex = options.pageIndex; + this.div = options.div; + this.#uiManager.addLayer(this); }
- _createMeshCanvas(combinedScale, backgroundColor, cachedCanvases) { - const EXPECTED_SCALE = 1.1; - const MAX_PATTERN_SIZE = 3000; - const BORDER_SIZE = 2; - const offsetX = Math.floor(this._bounds[0]); - const offsetY = Math.floor(this._bounds[1]); - const boundsWidth = Math.ceil(this._bounds[2]) - offsetX; - const boundsHeight = Math.ceil(this._bounds[3]) - offsetY; - const width = Math.min(Math.ceil(Math.abs(boundsWidth * combinedScale[0] * EXPECTED_SCALE)), MAX_PATTERN_SIZE); - const height = Math.min(Math.ceil(Math.abs(boundsHeight * combinedScale[1] * EXPECTED_SCALE)), MAX_PATTERN_SIZE); - const scaleX = boundsWidth / width; - const scaleY = boundsHeight / height; - const context = { - coords: this._coords, - colors: this._colors, - offsetX: -offsetX, - offsetY: -offsetY, - scaleX: 1 / scaleX, - scaleY: 1 / scaleY - }; - const paddedWidth = width + BORDER_SIZE * 2; - const paddedHeight = height + BORDER_SIZE * 2; - const tmpCanvas = cachedCanvases.getCanvas("mesh", paddedWidth, paddedHeight, false); - const tmpCtx = tmpCanvas.context; - const data = tmpCtx.createImageData(width, height); + get textLayerElements() { + const textLayer = this.div.parentNode.getElementsByClassName("textLayer").item(0);
- if (backgroundColor) { - const bytes = data.data; + if (!textLayer) { + return (0, _util.shadow)(this, "textLayerElements", null); + }
- for (let i = 0, ii = bytes.length; i < ii; i += 4) { - bytes[i] = backgroundColor[0]; - bytes[i + 1] = backgroundColor[1]; - bytes[i + 2] = backgroundColor[2]; - bytes[i + 3] = 255; - } + let textChildren = this.#textLayerMap.get(textLayer); + + if (textChildren) { + return textChildren; }
- for (const figure of this._figures) { - drawFigure(data, figure, context); + textChildren = textLayer.querySelectorAll(`span[role="presentation"]`); + + if (textChildren.length === 0) { + return (0, _util.shadow)(this, "textLayerElements", null); }
- tmpCtx.putImageData(data, BORDER_SIZE, BORDER_SIZE); - const canvas = tmpCanvas.canvas; - return { - canvas, - offsetX: offsetX - BORDER_SIZE * scaleX, - offsetY: offsetY - BORDER_SIZE * scaleY, - scaleX, - scaleY - }; + textChildren = Array.from(textChildren); + textChildren.sort(AnnotationEditorLayer.#compareElementPositions); + this.#textLayerMap.set(textLayer, textChildren); + return textChildren; }
- getPattern(ctx, owner, inverse, pathType) { - applyBoundingBox(ctx, this._bbox); - let scale; + get #hasTextLayer() { + return !!this.div.parentNode.querySelector(".textLayer .endOfContent"); + }
- if (pathType === PathType.SHADING) { - scale = _util.Util.singularValueDecompose2dScale(ctx.mozCurrentTransform); - } else { - scale = _util.Util.singularValueDecompose2dScale(owner.baseTransform); + updateToolbar(mode) { + this.#uiManager.updateToolbar(mode); + }
- if (this.matrix) { - const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix); + updateMode(mode = this.#uiManager.getMode()) { + this.#cleanup();
- scale = [scale[0] * matrixScale[0], scale[1] * matrixScale[1]]; - } + if (mode === _util.AnnotationEditorType.INK) { + this.addInkEditorIfNeeded(false); + this.disableClick(); + } else { + this.enableClick(); }
- const temporaryPatternCanvas = this._createMeshCanvas(scale, pathType === PathType.SHADING ? null : this._background, owner.cachedCanvases); + this.#uiManager.unselectAll(); + }
- if (pathType !== PathType.SHADING) { - ctx.setTransform.apply(ctx, owner.baseTransform); + addInkEditorIfNeeded(isCommitting) { + if (!isCommitting && this.#uiManager.getMode() !== _util.AnnotationEditorType.INK) { + return; + }
- if (this.matrix) { - ctx.transform.apply(ctx, this.matrix); + if (!isCommitting) { + for (const editor of this.#editors.values()) { + if (editor.isEmpty()) { + editor.setInBackground(); + return; + } } }
- ctx.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY); - ctx.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY); - return ctx.createPattern(temporaryPatternCanvas.canvas, "no-repeat"); + const editor = this.#createAndAddNewEditor({ + offsetX: 0, + offsetY: 0 + }); + editor.setInBackground(); }
-} + setEditingState(isEditing) { + this.#uiManager.setEditingState(isEditing); + }
-class DummyShadingPattern extends BaseShadingPattern { - getPattern() { - return "hotpink"; + addCommands(params) { + this.#uiManager.addCommands(params); }
-} + enable() { + this.div.style.pointerEvents = "auto";
-function getShadingPattern(IR) { - switch (IR[0]) { - case "RadialAxial": - return new RadialAxialShadingPattern(IR); + for (const editor of this.#editors.values()) { + editor.enableEditing(); + } + }
- case "Mesh": - return new MeshShadingPattern(IR); + disable() { + this.div.style.pointerEvents = "none";
- case "Dummy": - return new DummyShadingPattern(); + for (const editor of this.#editors.values()) { + editor.disableEditing(); + } }
- throw new Error(`Unknown IR type: ${IR[0]}`); -} + setActiveEditor(editor) { + const currentActive = this.#uiManager.getActive();
-const PaintType = { - COLORED: 1, - UNCOLORED: 2 -}; + if (currentActive === editor) { + return; + }
-class TilingPattern { - static get MAX_PATTERN_SIZE() { - return (0, _util.shadow)(this, "MAX_PATTERN_SIZE", 3000); + this.#uiManager.setActiveEditor(editor); }
- constructor(IR, color, ctx, canvasGraphicsFactory, baseTransform) { - this.operatorList = IR[2]; - this.matrix = IR[3] || [1, 0, 0, 1, 0, 0]; - this.bbox = IR[4]; - this.xstep = IR[5]; - this.ystep = IR[6]; - this.paintType = IR[7]; - this.tilingType = IR[8]; - this.color = color; - this.ctx = ctx; - this.canvasGraphicsFactory = canvasGraphicsFactory; - this.baseTransform = baseTransform; + enableClick() { + this.div.addEventListener("pointerdown", this.#boundPointerdown); + this.div.addEventListener("pointerup", this.#boundPointerup); }
- createPatternCanvas(owner) { - const operatorList = this.operatorList; - const bbox = this.bbox; - const xstep = this.xstep; - const ystep = this.ystep; - const paintType = this.paintType; - const tilingType = this.tilingType; - const color = this.color; - const canvasGraphicsFactory = this.canvasGraphicsFactory; - (0, _util.info)("TilingType: " + tilingType); - const x0 = bbox[0], - y0 = bbox[1], - x1 = bbox[2], - y1 = bbox[3]; + disableClick() { + this.div.removeEventListener("pointerdown", this.#boundPointerdown); + this.div.removeEventListener("pointerup", this.#boundPointerup); + }
- const matrixScale = _util.Util.singularValueDecompose2dScale(this.matrix); + attach(editor) { + this.#editors.set(editor.id, editor); + }
- const curMatrixScale = _util.Util.singularValueDecompose2dScale(this.baseTransform); + detach(editor) { + this.#editors.delete(editor.id); + this.removePointerInTextLayer(editor); + }
- const combinedScale = [matrixScale[0] * curMatrixScale[0], matrixScale[1] * curMatrixScale[1]]; - const dimx = this.getSizeAndScale(xstep, this.ctx.canvas.width, combinedScale[0]); - const dimy = this.getSizeAndScale(ystep, this.ctx.canvas.height, combinedScale[1]); - const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", dimx.size, dimy.size, true); - const tmpCtx = tmpCanvas.context; - const graphics = canvasGraphicsFactory.createCanvasGraphics(tmpCtx); - graphics.groupLevel = owner.groupLevel; - this.setFillAndStrokeStyleToContext(graphics, paintType, color); - let adjustedX0 = x0; - let adjustedY0 = y0; - let adjustedX1 = x1; - let adjustedY1 = y1; + remove(editor) { + this.#uiManager.removeEditor(editor); + this.detach(editor); + this.annotationStorage.removeKey(editor.id); + editor.div.style.display = "none"; + setTimeout(() => { + editor.div.style.display = ""; + editor.div.remove(); + editor.isAttachedToDOM = false;
- if (x0 < 0) { - adjustedX0 = 0; - adjustedX1 += Math.abs(x0); + if (document.activeElement === document.body) { + this.#uiManager.focusMainContainer(); + } + }, 0); + + if (!this.#isCleaningUp) { + this.addInkEditorIfNeeded(false); } + }
- if (y0 < 0) { - adjustedY0 = 0; - adjustedY1 += Math.abs(y0); + #changeParent(editor) { + if (editor.parent === this) { + return; }
- tmpCtx.translate(-(dimx.scale * adjustedX0), -(dimy.scale * adjustedY0)); - graphics.transform(dimx.scale, 0, 0, dimy.scale, 0, 0); - tmpCtx.save(); - this.clipBbox(graphics, adjustedX0, adjustedY0, adjustedX1, adjustedY1); - graphics.baseTransform = graphics.ctx.mozCurrentTransform.slice(); - graphics.executeOperatorList(operatorList); - graphics.endDrawing(); - return { - canvas: tmpCanvas.canvas, - scaleX: dimx.scale, - scaleY: dimy.scale, - offsetX: adjustedX0, - offsetY: adjustedY0 - }; + this.attach(editor); + editor.pageIndex = this.pageIndex; + editor.parent?.detach(editor); + editor.parent = this; + + if (editor.div && editor.isAttachedToDOM) { + editor.div.remove(); + this.div.append(editor.div); + } }
- getSizeAndScale(step, realOutputSize, scale) { - step = Math.abs(step); - const maxSize = Math.max(TilingPattern.MAX_PATTERN_SIZE, realOutputSize); - let size = Math.ceil(step * scale); + static #compareElementPositions(e1, e2) { + const rect1 = e1.getBoundingClientRect(); + const rect2 = e2.getBoundingClientRect();
- if (size >= maxSize) { - size = maxSize; - } else { - scale = size / step; + if (rect1.y + rect1.height <= rect2.y) { + return -1; }
- return { - scale, - size - }; + if (rect2.y + rect2.height <= rect1.y) { + return +1; + } + + const centerX1 = rect1.x + rect1.width / 2; + const centerX2 = rect2.x + rect2.width / 2; + return centerX1 - centerX2; }
- clipBbox(graphics, x0, y0, x1, y1) { - const bboxWidth = x1 - x0; - const bboxHeight = y1 - y0; - graphics.ctx.rect(x0, y0, bboxWidth, bboxHeight); - graphics.current.updateRectMinMax(graphics.ctx.mozCurrentTransform, [x0, y0, x1, y1]); - graphics.clip(); - graphics.endPath(); + onTextLayerRendered() { + this.#textNodes.clear(); + + for (const editor of this.#waitingEditors) { + if (editor.isAttachedToDOM) { + this.addPointerInTextLayer(editor); + } + } + + this.#waitingEditors.clear(); }
- setFillAndStrokeStyleToContext(graphics, paintType, color) { - const context = graphics.ctx, - current = graphics.current; + removePointerInTextLayer(editor) { + if (!this.#hasTextLayer) { + this.#waitingEditors.delete(editor); + return; + }
- switch (paintType) { - case PaintType.COLORED: - const ctx = this.ctx; - context.fillStyle = ctx.fillStyle; - context.strokeStyle = ctx.strokeStyle; - current.fillColor = ctx.fillStyle; - current.strokeColor = ctx.strokeStyle; - break; + const { + id + } = editor; + const node = this.#textNodes.get(id);
- case PaintType.UNCOLORED: - const cssColor = _util.Util.makeHexColor(color[0], color[1], color[2]); + if (!node) { + return; + }
- context.fillStyle = cssColor; - context.strokeStyle = cssColor; - current.fillColor = cssColor; - current.strokeColor = cssColor; - break; + this.#textNodes.delete(id); + let owns = node.getAttribute("aria-owns");
- default: - throw new _util.FormatError(`Unsupported paint type: ${paintType}`); + if (owns?.includes(id)) { + owns = owns.split(" ").filter(x => x !== id).join(" "); + + if (owns) { + node.setAttribute("aria-owns", owns); + } else { + node.removeAttribute("aria-owns"); + node.setAttribute("role", "presentation"); + } } }
- getPattern(ctx, owner, inverse, pathType) { - let matrix = inverse; + addPointerInTextLayer(editor) { + if (!this.#hasTextLayer) { + this.#waitingEditors.add(editor); + return; + }
- if (pathType !== PathType.SHADING) { - matrix = _util.Util.transform(matrix, owner.baseTransform); + this.removePointerInTextLayer(editor); + const children = this.textLayerElements;
- if (this.matrix) { - matrix = _util.Util.transform(matrix, this.matrix); - } + if (!children) { + return; }
- const temporaryPatternCanvas = this.createPatternCanvas(owner); - let domMatrix = new DOMMatrix(matrix); - domMatrix = domMatrix.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY); - domMatrix = domMatrix.scale(1 / temporaryPatternCanvas.scaleX, 1 / temporaryPatternCanvas.scaleY); - const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "repeat"); + const { + contentDiv + } = editor; + const id = editor.getIdForTextLayer(); + const index = (0, _display_utils.binarySearchFirstItem)(children, node => AnnotationEditorLayer.#compareElementPositions(contentDiv, node) < 0); + const node = children[Math.max(0, index - 1)]; + const owns = node.getAttribute("aria-owns");
- try { - pattern.setTransform(domMatrix); - } catch (ex) { - (0, _util.warn)(`TilingPattern.getPattern: "${ex?.message}".`); + if (!owns?.includes(id)) { + node.setAttribute("aria-owns", owns ? `${owns} ${id}` : id); }
- return pattern; + node.removeAttribute("role"); + this.#textNodes.set(id, node); }
-} - -exports.TilingPattern = TilingPattern; + moveDivInDOM(editor) { + this.addPointerInTextLayer(editor); + const { + div, + contentDiv + } = editor;
-/***/ }), -/* 12 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + if (!this.div.hasChildNodes()) { + this.div.append(div); + return; + }
+ const children = Array.from(this.div.childNodes).filter(node => node !== div);
+ if (children.length === 0) { + return; + }
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.applyMaskImageData = applyMaskImageData; + const index = (0, _display_utils.binarySearchFirstItem)(children, node => AnnotationEditorLayer.#compareElementPositions(contentDiv, node) < 0);
-var _util = __w_pdfjs_require__(1); + if (index === 0) { + children[0].before(div); + } else { + children[index - 1].after(div); + } + }
-function applyMaskImageData({ - src, - srcPos = 0, - dest, - destPos = 0, - width, - height, - inverseDecode = false -}) { - const opaque = _util.FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; - const [zeroMapping, oneMapping] = !inverseDecode ? [opaque, 0] : [0, opaque]; - const widthInSource = width >> 3; - const widthRemainder = width & 7; - const srcLength = src.length; - dest = new Uint32Array(dest.buffer); + add(editor) { + this.#changeParent(editor); + this.annotationStorage.setValue(editor.id, editor); + this.#uiManager.addEditor(editor); + this.attach(editor);
- for (let i = 0; i < height; i++) { - for (const max = srcPos + widthInSource; srcPos < max; srcPos++) { - const elem = srcPos < srcLength ? src[srcPos] : 255; - dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping; - dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping; - dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping; - dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping; - dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping; - dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping; - dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping; - dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping; + if (!editor.isAttachedToDOM) { + const div = editor.render(); + this.div.append(div); + editor.isAttachedToDOM = true; }
- if (widthRemainder === 0) { - continue; + this.moveDivInDOM(editor); + editor.onceAdded(); + } + + addOrRebuild(editor) { + if (editor.needsToBeRebuilt()) { + editor.rebuild(); + } else { + this.add(editor); } + }
- const elem = srcPos < srcLength ? src[srcPos++] : 255; + addANewEditor(editor) { + const cmd = () => { + this.addOrRebuild(editor); + };
- for (let j = 0; j < widthRemainder; j++) { - dest[destPos++] = elem & 1 << 7 - j ? oneMapping : zeroMapping; + const undo = () => { + editor.remove(); + }; + + this.addCommands({ + cmd, + undo, + mustExec: true + }); + } + + addUndoableEditor(editor) { + const cmd = () => { + this.addOrRebuild(editor); + }; + + const undo = () => { + editor.remove(); + }; + + this.addCommands({ + cmd, + undo, + mustExec: false + }); + } + + getNextId() { + return this.#uiManager.getId(); + } + + #createNewEditor(params) { + switch (this.#uiManager.getMode()) { + case _util.AnnotationEditorType.FREETEXT: + return new _freetext.FreeTextEditor(params); + + case _util.AnnotationEditorType.INK: + return new _ink.InkEditor(params); } + + return null; }
- return { - srcPos, - destPos - }; -} + deserialize(data) { + switch (data.annotationType) { + case _util.AnnotationEditorType.FREETEXT: + return _freetext.FreeTextEditor.deserialize(data, this);
-/***/ }), -/* 13 */ -/***/ ((__unused_webpack_module, exports) => { + case _util.AnnotationEditorType.INK: + return _ink.InkEditor.deserialize(data, this); + }
+ return null; + }
+ #createAndAddNewEditor(event) { + const id = this.getNextId(); + const editor = this.#createNewEditor({ + parent: this, + id, + x: event.offsetX, + y: event.offsetY + });
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.GlobalWorkerOptions = void 0; -const GlobalWorkerOptions = Object.create(null); -exports.GlobalWorkerOptions = GlobalWorkerOptions; -GlobalWorkerOptions.workerPort = GlobalWorkerOptions.workerPort === undefined ? null : GlobalWorkerOptions.workerPort; -GlobalWorkerOptions.workerSrc = GlobalWorkerOptions.workerSrc === undefined ? "" : GlobalWorkerOptions.workerSrc; + if (editor) { + this.add(editor); + }
-/***/ }), -/* 14 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + return editor; + }
+ setSelected(editor) { + this.#uiManager.setSelected(editor); + }
+ toggleSelected(editor) { + this.#uiManager.toggleSelected(editor); + }
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.MessageHandler = void 0; + isSelected(editor) { + return this.#uiManager.isSelected(editor); + }
-var _util = __w_pdfjs_require__(1); + unselect(editor) { + this.#uiManager.unselect(editor); + }
-const CallbackKind = { - UNKNOWN: 0, - DATA: 1, - ERROR: 2 -}; -const StreamKind = { - UNKNOWN: 0, - CANCEL: 1, - CANCEL_COMPLETE: 2, - CLOSE: 3, - ENQUEUE: 4, - ERROR: 5, - PULL: 6, - PULL_COMPLETE: 7, - START_COMPLETE: 8 -}; + pointerup(event) { + if (event.target !== this.div) { + return; + }
-function wrapReason(reason) { - if (!(reason instanceof Error || typeof reason === "object" && reason !== null)) { - (0, _util.unreachable)('wrapReason: Expected "reason" to be a (possibly cloned) Error.'); + if (!this.#allowClick) { + this.#allowClick = true; + return; + } + + this.#createAndAddNewEditor(event); }
- switch (reason.name) { - case "AbortException": - return new _util.AbortException(reason.message); + pointerdown(event) { + if (event.target !== this.div) { + return; + }
- case "MissingPDFException": - return new _util.MissingPDFException(reason.message); + const editor = this.#uiManager.getActive(); + this.#allowClick = !editor || editor.isEmpty(); + }
- case "PasswordException": - return new _util.PasswordException(reason.message, reason.code); + drop(event) { + const id = event.dataTransfer.getData("text/plain"); + const editor = this.#uiManager.getEditor(id);
- case "UnexpectedResponseException": - return new _util.UnexpectedResponseException(reason.message, reason.status); + if (!editor) { + return; + }
- case "UnknownErrorException": - return new _util.UnknownErrorException(reason.message, reason.details); + event.preventDefault(); + event.dataTransfer.dropEffect = "move"; + this.#changeParent(editor); + const rect = this.div.getBoundingClientRect(); + const endX = event.clientX - rect.x; + const endY = event.clientY - rect.y; + editor.translate(endX - editor.startX, endY - editor.startY); + this.moveDivInDOM(editor); + editor.div.focus(); + }
- default: - return new _util.UnknownErrorException(reason.message, reason.toString()); + dragover(event) { + event.preventDefault(); } -}
-class MessageHandler { - constructor(sourceName, targetName, comObj) { - this.sourceName = sourceName; - this.targetName = targetName; - this.comObj = comObj; - this.callbackId = 1; - this.streamId = 1; - this.streamSinks = Object.create(null); - this.streamControllers = Object.create(null); - this.callbackCapabilities = Object.create(null); - this.actionHandler = Object.create(null); + destroy() { + if (this.#uiManager.getActive()?.parent === this) { + this.#uiManager.setActiveEditor(null); + }
- this._onComObjOnMessage = event => { - const data = event.data; + for (const editor of this.#editors.values()) { + this.removePointerInTextLayer(editor); + editor.isAttachedToDOM = false; + editor.div.remove(); + editor.parent = null; + }
- if (data.targetName !== this.sourceName) { - return; + this.#textNodes.clear(); + this.div = null; + this.#editors.clear(); + this.#waitingEditors.clear(); + this.#uiManager.removeLayer(this); + } + + #cleanup() { + this.#isCleaningUp = true; + + for (const editor of this.#editors.values()) { + if (editor.isEmpty()) { + editor.remove(); } + }
- if (data.stream) { - this._processStreamMessage(data); + this.#isCleaningUp = false; + } + + render(parameters) { + this.viewport = parameters.viewport; + (0, _tools.bindEvents)(this, this.div, ["dragover", "drop"]); + this.setDimensions(); + + for (const editor of this.#uiManager.getEditors(this.pageIndex)) { + this.add(editor); + } + + this.updateMode(); + }
- return; - } + update(parameters) { + this.viewport = parameters.viewport; + this.setDimensions(); + this.updateMode(); + }
- if (data.callback) { - const callbackId = data.callbackId; - const capability = this.callbackCapabilities[callbackId]; + get scaleFactor() { + return this.viewport.scale; + }
- if (!capability) { - throw new Error(`Cannot resolve callback ${callbackId}`); - } + get pageDimensions() { + const [pageLLx, pageLLy, pageURx, pageURy] = this.viewport.viewBox; + const width = pageURx - pageLLx; + const height = pageURy - pageLLy; + return [width, height]; + }
- delete this.callbackCapabilities[callbackId]; + get viewportBaseDimensions() { + const { + width, + height, + rotation + } = this.viewport; + return rotation % 180 === 0 ? [width, height] : [height, width]; + }
- if (data.callback === CallbackKind.DATA) { - capability.resolve(data.data); - } else if (data.callback === CallbackKind.ERROR) { - capability.reject(wrapReason(data.reason)); - } else { - throw new Error("Unexpected callback case"); - } + setDimensions() { + const { + width, + height, + rotation + } = this.viewport; + const flipOrientation = rotation % 180 !== 0, + widthStr = Math.floor(width) + "px", + heightStr = Math.floor(height) + "px"; + this.div.style.width = flipOrientation ? heightStr : widthStr; + this.div.style.height = flipOrientation ? widthStr : heightStr; + this.div.setAttribute("data-main-rotation", rotation); + }
- return; - } +}
- const action = this.actionHandler[data.action]; +exports.AnnotationEditorLayer = AnnotationEditorLayer;
- if (!action) { - throw new Error(`Unknown action from worker: ${data.action}`); - } +/***/ }), +/* 22 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- if (data.callbackId) { - const cbSourceName = this.sourceName; - const cbTargetName = data.sourceName; - new Promise(function (resolve) { - resolve(action(data.data)); - }).then(function (result) { - comObj.postMessage({ - sourceName: cbSourceName, - targetName: cbTargetName, - callback: CallbackKind.DATA, - callbackId: data.callbackId, - data: result - }); - }, function (reason) { - comObj.postMessage({ - sourceName: cbSourceName, - targetName: cbTargetName, - callback: CallbackKind.ERROR, - callbackId: data.callbackId, - reason: wrapReason(reason) - }); - }); - return; - }
- if (data.streamId) { - this._createStreamSink(data);
- return; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.FreeTextEditor = void 0;
- action(data.data); - }; +var _util = __w_pdfjs_require__(1);
- comObj.addEventListener("message", this._onComObjOnMessage); +var _tools = __w_pdfjs_require__(9); + +var _editor = __w_pdfjs_require__(8); + +class FreeTextEditor extends _editor.AnnotationEditor { + #boundEditorDivBlur = this.editorDivBlur.bind(this); + #boundEditorDivFocus = this.editorDivFocus.bind(this); + #boundEditorDivKeydown = this.editorDivKeydown.bind(this); + #color; + #content = ""; + #contentHTML = ""; + #hasAlreadyBeenCommitted = false; + #fontSize; + static _freeTextDefaultContent = ""; + static _l10nPromise; + static _internalPadding = 0; + static _defaultColor = null; + static _defaultFontSize = 10; + static _keyboardManager = new _tools.KeyboardManager([[["ctrl+Enter", "mac+meta+Enter", "Escape", "mac+Escape"], FreeTextEditor.prototype.commitOrRemove]]); + + constructor(params) { + super({ ...params, + name: "freeTextEditor" + }); + this.#color = params.color || FreeTextEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor; + this.#fontSize = params.fontSize || FreeTextEditor._defaultFontSize; }
- on(actionName, handler) { - const ah = this.actionHandler; + static initialize(l10n) { + this._l10nPromise = new Map(["free_text_default_content", "editor_free_text_aria_label"].map(str => [str, l10n.get(str)])); + const style = getComputedStyle(document.documentElement); + this._internalPadding = parseFloat(style.getPropertyValue("--freetext-padding")); + }
- if (ah[actionName]) { - throw new Error(`There is already an actionName called "${actionName}"`); + static updateDefaultParams(type, value) { + switch (type) { + case _util.AnnotationEditorParamsType.FREETEXT_SIZE: + FreeTextEditor._defaultFontSize = value; + break; + + case _util.AnnotationEditorParamsType.FREETEXT_COLOR: + FreeTextEditor._defaultColor = value; + break; } + }
- ah[actionName] = handler; + updateParams(type, value) { + switch (type) { + case _util.AnnotationEditorParamsType.FREETEXT_SIZE: + this.#updateFontSize(value); + break; + + case _util.AnnotationEditorParamsType.FREETEXT_COLOR: + this.#updateColor(value); + break; + } }
- send(actionName, data, transfers) { - this.comObj.postMessage({ - sourceName: this.sourceName, - targetName: this.targetName, - action: actionName, - data - }, transfers); + static get defaultPropertiesToUpdate() { + return [[_util.AnnotationEditorParamsType.FREETEXT_SIZE, FreeTextEditor._defaultFontSize], [_util.AnnotationEditorParamsType.FREETEXT_COLOR, FreeTextEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor]]; }
- sendWithPromise(actionName, data, transfers) { - const callbackId = this.callbackId++; - const capability = (0, _util.createPromiseCapability)(); - this.callbackCapabilities[callbackId] = capability; + get propertiesToUpdate() { + return [[_util.AnnotationEditorParamsType.FREETEXT_SIZE, this.#fontSize], [_util.AnnotationEditorParamsType.FREETEXT_COLOR, this.#color]]; + }
- try { - this.comObj.postMessage({ - sourceName: this.sourceName, - targetName: this.targetName, - action: actionName, - callbackId, - data - }, transfers); - } catch (ex) { - capability.reject(ex); - } + #updateFontSize(fontSize) { + const setFontsize = size => { + this.editorDiv.style.fontSize = `calc(${size}px * var(--scale-factor))`; + this.translate(0, -(size - this.#fontSize) * this.parent.scaleFactor); + this.#fontSize = size; + this.#setEditorDimensions(); + };
- return capability.promise; + const savedFontsize = this.#fontSize; + this.parent.addCommands({ + cmd: () => { + setFontsize(fontSize); + }, + undo: () => { + setFontsize(savedFontsize); + }, + mustExec: true, + type: _util.AnnotationEditorParamsType.FREETEXT_SIZE, + overwriteIfSameType: true, + keepUndo: true + }); }
- sendWithStream(actionName, data, queueingStrategy, transfers) { - const streamId = this.streamId++, - sourceName = this.sourceName, - targetName = this.targetName, - comObj = this.comObj; - return new ReadableStream({ - start: controller => { - const startCapability = (0, _util.createPromiseCapability)(); - this.streamControllers[streamId] = { - controller, - startCall: startCapability, - pullCall: null, - cancelCall: null, - isClosed: false - }; - comObj.postMessage({ - sourceName, - targetName, - action: actionName, - streamId, - data, - desiredSize: controller.desiredSize - }, transfers); - return startCapability.promise; + #updateColor(color) { + const savedColor = this.#color; + this.parent.addCommands({ + cmd: () => { + this.#color = color; + this.editorDiv.style.color = color; }, - pull: controller => { - const pullCapability = (0, _util.createPromiseCapability)(); - this.streamControllers[streamId].pullCall = pullCapability; - comObj.postMessage({ - sourceName, - targetName, - stream: StreamKind.PULL, - streamId, - desiredSize: controller.desiredSize - }); - return pullCapability.promise; + undo: () => { + this.#color = savedColor; + this.editorDiv.style.color = savedColor; }, - cancel: reason => { - (0, _util.assert)(reason instanceof Error, "cancel must have a valid reason"); - const cancelCapability = (0, _util.createPromiseCapability)(); - this.streamControllers[streamId].cancelCall = cancelCapability; - this.streamControllers[streamId].isClosed = true; - comObj.postMessage({ - sourceName, - targetName, - stream: StreamKind.CANCEL, - streamId, - reason: wrapReason(reason) - }); - return cancelCapability.promise; - } - }, queueingStrategy); + mustExec: true, + type: _util.AnnotationEditorParamsType.FREETEXT_COLOR, + overwriteIfSameType: true, + keepUndo: true + }); }
- _createStreamSink(data) { - const streamId = data.streamId, - sourceName = this.sourceName, - targetName = data.sourceName, - comObj = this.comObj; - const self = this, - action = this.actionHandler[data.action]; - const streamSink = { - enqueue(chunk, size = 1, transfers) { - if (this.isCancelled) { - return; - } - - const lastDesiredSize = this.desiredSize; - this.desiredSize -= size; - - if (lastDesiredSize > 0 && this.desiredSize <= 0) { - this.sinkCapability = (0, _util.createPromiseCapability)(); - this.ready = this.sinkCapability.promise; - } + getInitialTranslation() { + return [-FreeTextEditor._internalPadding * this.parent.scaleFactor, -(FreeTextEditor._internalPadding + this.#fontSize) * this.parent.scaleFactor]; + }
- comObj.postMessage({ - sourceName, - targetName, - stream: StreamKind.ENQUEUE, - streamId, - chunk - }, transfers); - }, + rebuild() { + super.rebuild();
- close() { - if (this.isCancelled) { - return; - } + if (this.div === null) { + return; + }
- this.isCancelled = true; - comObj.postMessage({ - sourceName, - targetName, - stream: StreamKind.CLOSE, - streamId - }); - delete self.streamSinks[streamId]; - }, + if (!this.isAttachedToDOM) { + this.parent.add(this); + } + }
- error(reason) { - (0, _util.assert)(reason instanceof Error, "error must have a valid reason"); + enableEditMode() { + this.parent.setEditingState(false); + this.parent.updateToolbar(_util.AnnotationEditorType.FREETEXT); + super.enableEditMode(); + this.overlayDiv.classList.remove("enabled"); + this.editorDiv.contentEditable = true; + this.div.draggable = false; + this.editorDiv.addEventListener("keydown", this.#boundEditorDivKeydown); + this.editorDiv.addEventListener("focus", this.#boundEditorDivFocus); + this.editorDiv.addEventListener("blur", this.#boundEditorDivBlur); + }
- if (this.isCancelled) { - return; - } + disableEditMode() { + this.parent.setEditingState(true); + super.disableEditMode(); + this.overlayDiv.classList.add("enabled"); + this.editorDiv.contentEditable = false; + this.div.draggable = true; + this.editorDiv.removeEventListener("keydown", this.#boundEditorDivKeydown); + this.editorDiv.removeEventListener("focus", this.#boundEditorDivFocus); + this.editorDiv.removeEventListener("blur", this.#boundEditorDivBlur); + this.isEditing = false; + }
- this.isCancelled = true; - comObj.postMessage({ - sourceName, - targetName, - stream: StreamKind.ERROR, - streamId, - reason: wrapReason(reason) - }); - }, + focusin(event) { + super.focusin(event);
- sinkCapability: (0, _util.createPromiseCapability)(), - onPull: null, - onCancel: null, - isCancelled: false, - desiredSize: data.desiredSize, - ready: null - }; - streamSink.sinkCapability.resolve(); - streamSink.ready = streamSink.sinkCapability.promise; - this.streamSinks[streamId] = streamSink; - new Promise(function (resolve) { - resolve(action(data.data, streamSink)); - }).then(function () { - comObj.postMessage({ - sourceName, - targetName, - stream: StreamKind.START_COMPLETE, - streamId, - success: true - }); - }, function (reason) { - comObj.postMessage({ - sourceName, - targetName, - stream: StreamKind.START_COMPLETE, - streamId, - reason: wrapReason(reason) - }); - }); + if (event.target !== this.editorDiv) { + this.editorDiv.focus(); + } }
- _processStreamMessage(data) { - const streamId = data.streamId, - sourceName = this.sourceName, - targetName = data.sourceName, - comObj = this.comObj; - const streamController = this.streamControllers[streamId], - streamSink = this.streamSinks[streamId]; + onceAdded() { + if (this.width) { + this.parent.setActiveEditor(this); + return; + }
- switch (data.stream) { - case StreamKind.START_COMPLETE: - if (data.success) { - streamController.startCall.resolve(); - } else { - streamController.startCall.reject(wrapReason(data.reason)); - } + this.enableEditMode(); + this.editorDiv.focus(); + }
- break; + isEmpty() { + return this.editorDiv.innerText.trim() === ""; + }
- case StreamKind.PULL_COMPLETE: - if (data.success) { - streamController.pullCall.resolve(); - } else { - streamController.pullCall.reject(wrapReason(data.reason)); - } + remove() { + this.isEditing = false; + this.parent.setEditingState(true); + super.remove(); + }
- break; + #extractText() { + const divs = this.editorDiv.getElementsByTagName("div");
- case StreamKind.PULL: - if (!streamSink) { - comObj.postMessage({ - sourceName, - targetName, - stream: StreamKind.PULL_COMPLETE, - streamId, - success: true - }); - break; - } + if (divs.length === 0) { + return this.editorDiv.innerText; + }
- if (streamSink.desiredSize <= 0 && data.desiredSize > 0) { - streamSink.sinkCapability.resolve(); - } + const buffer = [];
- streamSink.desiredSize = data.desiredSize; - new Promise(function (resolve) { - resolve(streamSink.onPull && streamSink.onPull()); - }).then(function () { - comObj.postMessage({ - sourceName, - targetName, - stream: StreamKind.PULL_COMPLETE, - streamId, - success: true - }); - }, function (reason) { - comObj.postMessage({ - sourceName, - targetName, - stream: StreamKind.PULL_COMPLETE, - streamId, - reason: wrapReason(reason) - }); - }); - break; + for (let i = 0, ii = divs.length; i < ii; i++) { + const div = divs[i]; + const first = div.firstChild;
- case StreamKind.ENQUEUE: - (0, _util.assert)(streamController, "enqueue should have stream controller"); + if (first?.nodeName === "#text") { + buffer.push(first.data); + } else { + buffer.push(""); + } + }
- if (streamController.isClosed) { - break; - } + return buffer.join("\n"); + }
- streamController.controller.enqueue(data.chunk); - break; + #setEditorDimensions() { + const [parentWidth, parentHeight] = this.parent.viewportBaseDimensions; + const rect = this.div.getBoundingClientRect(); + this.width = rect.width / parentWidth; + this.height = rect.height / parentHeight; + }
- case StreamKind.CLOSE: - (0, _util.assert)(streamController, "close should have stream controller"); + commit() { + if (!this.#hasAlreadyBeenCommitted) { + this.#hasAlreadyBeenCommitted = true; + this.parent.addUndoableEditor(this); + }
- if (streamController.isClosed) { - break; - } + this.disableEditMode(); + this.#contentHTML = this.editorDiv.innerHTML; + this.#content = this.#extractText().trimEnd(); + this.#setEditorDimensions(); + }
- streamController.isClosed = true; - streamController.controller.close(); + shouldGetKeyboardEvents() { + return this.isInEditMode(); + }
- this._deleteStreamController(streamController, streamId); + dblclick(event) { + this.enableEditMode(); + this.editorDiv.focus(); + }
- break; + keydown(event) { + if (event.target === this.div && event.key === "Enter") { + this.enableEditMode(); + this.editorDiv.focus(); + } + }
- case StreamKind.ERROR: - (0, _util.assert)(streamController, "error should have stream controller"); - streamController.controller.error(wrapReason(data.reason)); + editorDivKeydown(event) { + FreeTextEditor._keyboardManager.exec(this, event); + }
- this._deleteStreamController(streamController, streamId); + editorDivFocus(event) { + this.isEditing = true; + }
- break; + editorDivBlur(event) { + this.isEditing = false; + }
- case StreamKind.CANCEL_COMPLETE: - if (data.success) { - streamController.cancelCall.resolve(); - } else { - streamController.cancelCall.reject(wrapReason(data.reason)); - } + disableEditing() { + this.editorDiv.setAttribute("role", "comment"); + this.editorDiv.removeAttribute("aria-multiline"); + }
- this._deleteStreamController(streamController, streamId); + enableEditing() { + this.editorDiv.setAttribute("role", "textbox"); + this.editorDiv.setAttribute("aria-multiline", true); + }
- break; + getIdForTextLayer() { + return this.editorDiv.id; + }
- case StreamKind.CANCEL: - if (!streamSink) { - break; - } + render() { + if (this.div) { + return this.div; + }
- new Promise(function (resolve) { - resolve(streamSink.onCancel && streamSink.onCancel(wrapReason(data.reason))); - }).then(function () { - comObj.postMessage({ - sourceName, - targetName, - stream: StreamKind.CANCEL_COMPLETE, - streamId, - success: true - }); - }, function (reason) { - comObj.postMessage({ - sourceName, - targetName, - stream: StreamKind.CANCEL_COMPLETE, - streamId, - reason: wrapReason(reason) - }); - }); - streamSink.sinkCapability.reject(wrapReason(data.reason)); - streamSink.isCancelled = true; - delete this.streamSinks[streamId]; - break; + let baseX, baseY;
- default: - throw new Error("Unexpected stream case"); + if (this.width) { + baseX = this.x; + baseY = this.y; + } + + super.render(); + this.editorDiv = document.createElement("div"); + this.editorDiv.className = "internal"; + this.editorDiv.setAttribute("id", `${this.id}-editor`); + this.enableEditing(); + + FreeTextEditor._l10nPromise.get("editor_free_text_aria_label").then(msg => this.editorDiv?.setAttribute("aria-label", msg)); + + FreeTextEditor._l10nPromise.get("free_text_default_content").then(msg => this.editorDiv?.setAttribute("default-content", msg)); + + this.editorDiv.contentEditable = true; + const { + style + } = this.editorDiv; + style.fontSize = `calc(${this.#fontSize}px * var(--scale-factor))`; + style.color = this.#color; + this.div.append(this.editorDiv); + this.overlayDiv = document.createElement("div"); + this.overlayDiv.classList.add("overlay", "enabled"); + this.div.append(this.overlayDiv); + (0, _tools.bindEvents)(this, this.div, ["dblclick", "keydown"]); + + if (this.width) { + const [parentWidth, parentHeight] = this.parent.viewportBaseDimensions; + this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); + this.editorDiv.innerHTML = this.#contentHTML; + this.div.draggable = true; + this.editorDiv.contentEditable = false; + } else { + this.div.draggable = false; + this.editorDiv.contentEditable = true; } + + return this.div; }
- async _deleteStreamController(streamController, streamId) { - await Promise.allSettled([streamController.startCall && streamController.startCall.promise, streamController.pullCall && streamController.pullCall.promise, streamController.cancelCall && streamController.cancelCall.promise]); - delete this.streamControllers[streamId]; + get contentDiv() { + return this.editorDiv; }
- destroy() { - this.comObj.removeEventListener("message", this._onComObjOnMessage); + static deserialize(data, parent) { + const editor = super.deserialize(data, parent); + editor.#fontSize = data.fontSize; + editor.#color = _util.Util.makeHexColor(...data.color); + editor.#content = data.value; + editor.#contentHTML = data.value.split("\n").map(line => `<div>${line}</div>`).join(""); + return editor; + } + + serialize() { + if (this.isEmpty()) { + return null; + } + + const padding = FreeTextEditor._internalPadding * this.parent.scaleFactor; + const rect = this.getRect(padding, padding); + + const color = _editor.AnnotationEditor._colorManager.convert(getComputedStyle(this.editorDiv).color); + + return { + annotationType: _util.AnnotationEditorType.FREETEXT, + color, + fontSize: this.#fontSize, + value: this.#content, + pageIndex: this.parent.pageIndex, + rect, + rotation: this.rotation + }; }
}
-exports.MessageHandler = MessageHandler; +exports.FreeTextEditor = FreeTextEditor;
/***/ }), -/* 15 */ +/* 23 */ /***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
@@ -8572,684 +11425,1107 @@ exports.MessageHandler = MessageHandler; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.Metadata = void 0; +exports.InkEditor = void 0; +Object.defineProperty(exports, "fitCurve", ({ + enumerable: true, + get: function () { + return _pdfjsFitCurve.fitCurve; + } +}));
var _util = __w_pdfjs_require__(1);
-class Metadata { - #metadataMap; - #data; +var _editor = __w_pdfjs_require__(8); + +var _pdfjsFitCurve = __w_pdfjs_require__(24); + +const RESIZER_SIZE = 16; + +class InkEditor extends _editor.AnnotationEditor { + #aspectRatio = 0; + #baseHeight = 0; + #baseWidth = 0; + #boundCanvasPointermove = this.canvasPointermove.bind(this); + #boundCanvasPointerleave = this.canvasPointerleave.bind(this); + #boundCanvasPointerup = this.canvasPointerup.bind(this); + #boundCanvasPointerdown = this.canvasPointerdown.bind(this); + #disableEditing = false; + #isCanvasInitialized = false; + #observer = null; + #realWidth = 0; + #realHeight = 0; + static _defaultColor = null; + static _defaultThickness = 1; + static _l10nPromise; + + constructor(params) { + super({ ...params, + name: "inkEditor" + }); + this.color = params.color || null; + this.thickness = params.thickness || null; + this.paths = []; + this.bezierPath2D = []; + this.currentPath = []; + this.scaleFactor = 1; + this.translationX = this.translationY = 0; + this.x = 0; + this.y = 0; + }
- constructor({ - parsedData, - rawData - }) { - this.#metadataMap = parsedData; - this.#data = rawData; + static initialize(l10n) { + this._l10nPromise = new Map(["editor_ink_canvas_aria_label", "editor_ink_aria_label"].map(str => [str, l10n.get(str)])); }
- getRaw() { - return this.#data; + static updateDefaultParams(type, value) { + switch (type) { + case _util.AnnotationEditorParamsType.INK_THICKNESS: + InkEditor._defaultThickness = value; + break; + + case _util.AnnotationEditorParamsType.INK_COLOR: + InkEditor._defaultColor = value; + break; + } }
- get(name) { - return this.#metadataMap.get(name) ?? null; + updateParams(type, value) { + switch (type) { + case _util.AnnotationEditorParamsType.INK_THICKNESS: + this.#updateThickness(value); + break; + + case _util.AnnotationEditorParamsType.INK_COLOR: + this.#updateColor(value); + break; + } }
- getAll() { - return (0, _util.objectFromMap)(this.#metadataMap); + static get defaultPropertiesToUpdate() { + return [[_util.AnnotationEditorParamsType.INK_THICKNESS, InkEditor._defaultThickness], [_util.AnnotationEditorParamsType.INK_COLOR, InkEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor]]; }
- has(name) { - return this.#metadataMap.has(name); + get propertiesToUpdate() { + return [[_util.AnnotationEditorParamsType.INK_THICKNESS, this.thickness || InkEditor._defaultThickness], [_util.AnnotationEditorParamsType.INK_COLOR, this.color || InkEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor]]; }
-} + #updateThickness(thickness) { + const savedThickness = this.thickness; + this.parent.addCommands({ + cmd: () => { + this.thickness = thickness; + this.#fitToContent(true); + }, + undo: () => { + this.thickness = savedThickness; + this.#fitToContent(true); + }, + mustExec: true, + type: _util.AnnotationEditorParamsType.INK_THICKNESS, + overwriteIfSameType: true, + keepUndo: true + }); + }
-exports.Metadata = Metadata; + #updateColor(color) { + const savedColor = this.color; + this.parent.addCommands({ + cmd: () => { + this.color = color; + this.#redraw(); + }, + undo: () => { + this.color = savedColor; + this.#redraw(); + }, + mustExec: true, + type: _util.AnnotationEditorParamsType.INK_COLOR, + overwriteIfSameType: true, + keepUndo: true + }); + }
-/***/ }), -/* 16 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + rebuild() { + super.rebuild();
+ if (this.div === null) { + return; + }
+ if (!this.canvas) { + this.#createCanvas(); + this.#createObserver(); + }
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.OptionalContentConfig = void 0; + if (!this.isAttachedToDOM) { + this.parent.add(this); + this.#setCanvasDims(); + }
-var _util = __w_pdfjs_require__(1); + this.#fitToContent(); + }
-class OptionalContentGroup { - constructor(name, intent) { - this.visible = true; - this.name = name; - this.intent = intent; + remove() { + if (this.canvas === null) { + return; + } + + if (!this.isEmpty()) { + this.commit(); + } + + this.canvas.width = this.canvas.height = 0; + this.canvas.remove(); + this.canvas = null; + this.#observer.disconnect(); + this.#observer = null; + super.remove(); }
-} + enableEditMode() { + if (this.#disableEditing || this.canvas === null) { + return; + }
-class OptionalContentConfig { - constructor(data) { - this.name = null; - this.creator = null; - this._order = null; - this._groups = new Map(); + super.enableEditMode(); + this.div.draggable = false; + this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown); + this.canvas.addEventListener("pointerup", this.#boundCanvasPointerup); + } + + disableEditMode() { + if (!this.isInEditMode() || this.canvas === null) { + return; + } + + super.disableEditMode(); + this.div.draggable = !this.isEmpty(); + this.div.classList.remove("editing"); + this.canvas.removeEventListener("pointerdown", this.#boundCanvasPointerdown); + this.canvas.removeEventListener("pointerup", this.#boundCanvasPointerup); + } + + onceAdded() { + this.div.draggable = !this.isEmpty(); + } + + isEmpty() { + return this.paths.length === 0 || this.paths.length === 1 && this.paths[0].length === 0; + } + + #getInitialBBox() { + const { + width, + height, + rotation + } = this.parent.viewport; + + switch (rotation) { + case 90: + return [0, width, width, height];
- if (data === null) { - return; - } + case 180: + return [width, height, width, height];
- this.name = data.name; - this.creator = data.creator; - this._order = data.order; + case 270: + return [height, 0, width, height];
- for (const group of data.groups) { - this._groups.set(group.id, new OptionalContentGroup(group.name, group.intent)); + default: + return [0, 0, width, height]; } + }
- if (data.baseState === "OFF") { - for (const group of this._groups) { - group.visible = false; - } - } + #setStroke() { + this.ctx.lineWidth = this.thickness * this.parent.scaleFactor / this.scaleFactor; + this.ctx.lineCap = "round"; + this.ctx.lineJoin = "round"; + this.ctx.miterLimit = 10; + this.ctx.strokeStyle = this.color; + }
- for (const on of data.on) { - this._groups.get(on).visible = true; - } + #startDrawing(x, y) { + this.isEditing = true;
- for (const off of data.off) { - this._groups.get(off).visible = false; + if (!this.#isCanvasInitialized) { + this.#isCanvasInitialized = true; + this.#setCanvasDims(); + this.thickness ||= InkEditor._defaultThickness; + this.color ||= InkEditor._defaultColor || _editor.AnnotationEditor._defaultLineColor; } + + this.currentPath.push([x, y]); + this.#setStroke(); + this.ctx.beginPath(); + this.ctx.moveTo(x, y); }
- _evaluateVisibilityExpression(array) { - const length = array.length; + #draw(x, y) { + this.currentPath.push([x, y]); + this.ctx.lineTo(x, y); + this.ctx.stroke(); + }
- if (length < 2) { - return true; + #stopDrawing(x, y) { + x = Math.min(Math.max(x, 0), this.canvas.width); + y = Math.min(Math.max(y, 0), this.canvas.height); + this.currentPath.push([x, y]); + let bezier; + + if (this.currentPath.length !== 2 || this.currentPath[0][0] !== x || this.currentPath[0][1] !== y) { + bezier = (0, _pdfjsFitCurve.fitCurve)(this.currentPath, 30, null); + } else { + const xy = [x, y]; + bezier = [[xy, xy.slice(), xy.slice(), xy]]; }
- const operator = array[0]; + const path2D = InkEditor.#buildPath2D(bezier); + this.currentPath.length = 0;
- for (let i = 1; i < length; i++) { - const element = array[i]; - let state; + const cmd = () => { + this.paths.push(bezier); + this.bezierPath2D.push(path2D); + this.rebuild(); + };
- if (Array.isArray(element)) { - state = this._evaluateVisibilityExpression(element); - } else if (this._groups.has(element)) { - state = this._groups.get(element).visible; + const undo = () => { + this.paths.pop(); + this.bezierPath2D.pop(); + + if (this.paths.length === 0) { + this.remove(); } else { - (0, _util.warn)(`Optional content group not found: ${element}`); - return true; + if (!this.canvas) { + this.#createCanvas(); + this.#createObserver(); + } + + this.#fitToContent(); } + };
- switch (operator) { - case "And": - if (!state) { - return false; - } + this.parent.addCommands({ + cmd, + undo, + mustExec: true + }); + }
- break; + #redraw() { + this.#setStroke();
- case "Or": - if (state) { - return true; - } + if (this.isEmpty()) { + this.#updateTransform(); + return; + }
- break; + const [parentWidth, parentHeight] = this.parent.viewportBaseDimensions; + const { + ctx, + height, + width + } = this; + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.clearRect(0, 0, width * parentWidth, height * parentHeight); + this.#updateTransform();
- case "Not": - return !state; + for (const path of this.bezierPath2D) { + ctx.stroke(path); + } + }
- default: - return true; - } + commit() { + if (this.#disableEditing) { + return; }
- return operator === "And"; + this.isEditing = false; + this.disableEditMode(); + this.setInForeground(); + this.#disableEditing = true; + this.div.classList.add("disabled"); + this.#fitToContent(); + this.parent.addInkEditorIfNeeded(true); + this.parent.moveDivInDOM(this); + this.div.focus(); }
- isVisible(group) { - if (this._groups.size === 0) { - return true; + focusin(event) { + super.focusin(event); + this.enableEditMode(); + } + + canvasPointerdown(event) { + if (event.button !== 0 || !this.isInEditMode() || this.#disableEditing) { + return; }
- if (!group) { - (0, _util.warn)("Optional content group not defined."); - return true; + this.setInForeground(); + + if (event.type !== "mouse") { + this.div.focus(); }
- if (group.type === "OCG") { - if (!this._groups.has(group.id)) { - (0, _util.warn)(`Optional content group not found: ${group.id}`); - return true; - } + event.stopPropagation(); + this.canvas.addEventListener("pointerleave", this.#boundCanvasPointerleave); + this.canvas.addEventListener("pointermove", this.#boundCanvasPointermove); + this.#startDrawing(event.offsetX, event.offsetY); + }
- return this._groups.get(group.id).visible; - } else if (group.type === "OCMD") { - if (group.expression) { - return this._evaluateVisibilityExpression(group.expression); - } + canvasPointermove(event) { + event.stopPropagation(); + this.#draw(event.offsetX, event.offsetY); + }
- if (!group.policy || group.policy === "AnyOn") { - for (const id of group.ids) { - if (!this._groups.has(id)) { - (0, _util.warn)(`Optional content group not found: ${id}`); - return true; - } + canvasPointerup(event) { + if (event.button !== 0) { + return; + }
- if (this._groups.get(id).visible) { - return true; - } - } + if (this.isInEditMode() && this.currentPath.length !== 0) { + event.stopPropagation(); + this.#endDrawing(event); + this.setInBackground(); + } + }
- return false; - } else if (group.policy === "AllOn") { - for (const id of group.ids) { - if (!this._groups.has(id)) { - (0, _util.warn)(`Optional content group not found: ${id}`); - return true; - } + canvasPointerleave(event) { + this.#endDrawing(event); + this.setInBackground(); + }
- if (!this._groups.get(id).visible) { - return false; - } - } + #endDrawing(event) { + this.#stopDrawing(event.offsetX, event.offsetY); + this.canvas.removeEventListener("pointerleave", this.#boundCanvasPointerleave); + this.canvas.removeEventListener("pointermove", this.#boundCanvasPointermove); + }
- return true; - } else if (group.policy === "AnyOff") { - for (const id of group.ids) { - if (!this._groups.has(id)) { - (0, _util.warn)(`Optional content group not found: ${id}`); - return true; - } + #createCanvas() { + this.canvas = document.createElement("canvas"); + this.canvas.width = this.canvas.height = 0; + this.canvas.className = "inkEditorCanvas";
- if (!this._groups.get(id).visible) { - return true; - } - } + InkEditor._l10nPromise.get("editor_ink_canvas_aria_label").then(msg => this.canvas?.setAttribute("aria-label", msg));
- return false; - } else if (group.policy === "AllOff") { - for (const id of group.ids) { - if (!this._groups.has(id)) { - (0, _util.warn)(`Optional content group not found: ${id}`); - return true; - } + this.div.append(this.canvas); + this.ctx = this.canvas.getContext("2d"); + }
- if (this._groups.get(id).visible) { - return false; - } - } + #createObserver() { + this.#observer = new ResizeObserver(entries => { + const rect = entries[0].contentRect;
- return true; + if (rect.width && rect.height) { + this.setDimensions(rect.width, rect.height); } + }); + this.#observer.observe(this.div); + }
- (0, _util.warn)(`Unknown optional content policy ${group.policy}.`); - return true; + render() { + if (this.div) { + return this.div; }
- (0, _util.warn)(`Unknown group type ${group.type}.`); - return true; - } + let baseX, baseY;
- setVisibility(id, visible = true) { - if (!this._groups.has(id)) { - (0, _util.warn)(`Optional content group not found: ${id}`); - return; + if (this.width) { + baseX = this.x; + baseY = this.y; }
- this._groups.get(id).visible = !!visible; - } + super.render();
- getOrder() { - if (!this._groups.size) { - return null; - } + InkEditor._l10nPromise.get("editor_ink_aria_label").then(msg => this.div?.setAttribute("aria-label", msg));
- if (this._order) { - return this._order.slice(); + const [x, y, w, h] = this.#getInitialBBox(); + this.setAt(x, y, 0, 0); + this.setDims(w, h); + this.#createCanvas(); + + if (this.width) { + const [parentWidth, parentHeight] = this.parent.viewportBaseDimensions; + this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); + this.#isCanvasInitialized = true; + this.#setCanvasDims(); + this.setDims(this.width * parentWidth, this.height * parentHeight); + this.#redraw(); + this.#setMinDims(); + this.div.classList.add("disabled"); + } else { + this.div.classList.add("editing"); + this.enableEditMode(); }
- return Array.from(this._groups.keys()); + this.#createObserver(); + return this.div; }
- getGroups() { - return this._groups.size > 0 ? (0, _util.objectFromMap)(this._groups) : null; - } + #setCanvasDims() { + if (!this.#isCanvasInitialized) { + return; + }
- getGroup(id) { - return this._groups.get(id) || null; + const [parentWidth, parentHeight] = this.parent.viewportBaseDimensions; + this.canvas.width = Math.ceil(this.width * parentWidth); + this.canvas.height = Math.ceil(this.height * parentHeight); + this.#updateTransform(); }
-} + setDimensions(width, height) { + const roundedWidth = Math.round(width); + const roundedHeight = Math.round(height);
-exports.OptionalContentConfig = OptionalContentConfig; + if (this.#realWidth === roundedWidth && this.#realHeight === roundedHeight) { + return; + }
-/***/ }), -/* 17 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + this.#realWidth = roundedWidth; + this.#realHeight = roundedHeight; + this.canvas.style.visibility = "hidden";
+ if (this.#aspectRatio && Math.abs(this.#aspectRatio - width / height) > 1e-2) { + height = Math.ceil(width / this.#aspectRatio); + this.setDims(width, height); + }
+ const [parentWidth, parentHeight] = this.parent.viewportBaseDimensions; + this.width = width / parentWidth; + this.height = height / parentHeight;
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.PDFDataTransportStream = void 0; + if (this.#disableEditing) { + this.#setScaleFactor(width, height); + }
-var _util = __w_pdfjs_require__(1); + this.#setCanvasDims(); + this.#redraw(); + this.canvas.style.visibility = "visible"; + }
-var _display_utils = __w_pdfjs_require__(5); + #setScaleFactor(width, height) { + const padding = this.#getPadding(); + const scaleFactorW = (width - padding) / this.#baseWidth; + const scaleFactorH = (height - padding) / this.#baseHeight; + this.scaleFactor = Math.min(scaleFactorW, scaleFactorH); + }
-class PDFDataTransportStream { - constructor(params, pdfDataRangeTransport) { - (0, _util.assert)(pdfDataRangeTransport, 'PDFDataTransportStream - missing required "pdfDataRangeTransport" argument.'); - this._queuedChunks = []; - this._progressiveDone = params.progressiveDone || false; - this._contentDispositionFilename = params.contentDispositionFilename || null; - const initialData = params.initialData; + #updateTransform() { + const padding = this.#getPadding() / 2; + this.ctx.setTransform(this.scaleFactor, 0, 0, this.scaleFactor, this.translationX * this.scaleFactor + padding, this.translationY * this.scaleFactor + padding); + }
- if (initialData?.length > 0) { - const buffer = new Uint8Array(initialData).buffer; + static #buildPath2D(bezier) { + const path2D = new Path2D();
- this._queuedChunks.push(buffer); - } + for (let i = 0, ii = bezier.length; i < ii; i++) { + const [first, control1, control2, second] = bezier[i];
- this._pdfDataRangeTransport = pdfDataRangeTransport; - this._isStreamingSupported = !params.disableStream; - this._isRangeSupported = !params.disableRange; - this._contentLength = params.length; - this._fullRequestReader = null; - this._rangeReaders = []; + if (i === 0) { + path2D.moveTo(...first); + }
- this._pdfDataRangeTransport.addRangeListener((begin, chunk) => { - this._onReceiveData({ - begin, - chunk - }); - }); + path2D.bezierCurveTo(control1[0], control1[1], control2[0], control2[1], second[0], second[1]); + }
- this._pdfDataRangeTransport.addProgressListener((loaded, total) => { - this._onProgress({ - loaded, - total - }); - }); + return path2D; + }
- this._pdfDataRangeTransport.addProgressiveReadListener(chunk => { - this._onReceiveData({ - chunk - }); - }); + #serializePaths(s, tx, ty, h) { + const NUMBER_OF_POINTS_ON_BEZIER_CURVE = 4; + const paths = []; + const padding = this.thickness / 2; + let buffer, points;
- this._pdfDataRangeTransport.addProgressiveDoneListener(() => { - this._onProgressiveDone(); - }); + for (const bezier of this.paths) { + buffer = []; + points = [];
- this._pdfDataRangeTransport.transportReady(); - } + for (let i = 0, ii = bezier.length; i < ii; i++) { + const [first, control1, control2, second] = bezier[i]; + const p10 = s * (first[0] + tx) + padding; + const p11 = h - s * (first[1] + ty) - padding; + const p20 = s * (control1[0] + tx) + padding; + const p21 = h - s * (control1[1] + ty) - padding; + const p30 = s * (control2[0] + tx) + padding; + const p31 = h - s * (control2[1] + ty) - padding; + const p40 = s * (second[0] + tx) + padding; + const p41 = h - s * (second[1] + ty) - padding;
- _onReceiveData(args) { - const buffer = new Uint8Array(args.chunk).buffer; + if (i === 0) { + buffer.push(p10, p11); + points.push(p10, p11); + }
- if (args.begin === undefined) { - if (this._fullRequestReader) { - this._fullRequestReader._enqueue(buffer); - } else { - this._queuedChunks.push(buffer); + buffer.push(p20, p21, p30, p31, p40, p41); + this.#extractPointsOnBezier(p10, p11, p20, p21, p30, p31, p40, p41, NUMBER_OF_POINTS_ON_BEZIER_CURVE, points); } - } else { - const found = this._rangeReaders.some(function (rangeReader) { - if (rangeReader._begin !== args.begin) { - return false; - }
- rangeReader._enqueue(buffer); + paths.push({ + bezier: buffer, + points + }); + } + + return paths; + }
- return true; - }); + #extractPointsOnBezier(p10, p11, p20, p21, p30, p31, p40, p41, n, points) { + if (this.#isAlmostFlat(p10, p11, p20, p21, p30, p31, p40, p41)) { + points.push(p40, p41); + return; + }
- (0, _util.assert)(found, "_onReceiveData - no `PDFDataTransportStreamRangeReader` instance found."); + for (let i = 1; i < n - 1; i++) { + const t = i / n; + const mt = 1 - t; + let q10 = t * p10 + mt * p20; + let q11 = t * p11 + mt * p21; + let q20 = t * p20 + mt * p30; + let q21 = t * p21 + mt * p31; + const q30 = t * p30 + mt * p40; + const q31 = t * p31 + mt * p41; + q10 = t * q10 + mt * q20; + q11 = t * q11 + mt * q21; + q20 = t * q20 + mt * q30; + q21 = t * q21 + mt * q31; + q10 = t * q10 + mt * q20; + q11 = t * q11 + mt * q21; + points.push(q10, q11); } + + points.push(p40, p41); }
- get _progressiveDataLength() { - return this._fullRequestReader?._loaded ?? 0; + #isAlmostFlat(p10, p11, p20, p21, p30, p31, p40, p41) { + const tol = 10; + const ax = (3 * p20 - 2 * p10 - p40) ** 2; + const ay = (3 * p21 - 2 * p11 - p41) ** 2; + const bx = (3 * p30 - p10 - 2 * p40) ** 2; + const by = (3 * p31 - p11 - 2 * p41) ** 2; + return Math.max(ax, bx) + Math.max(ay, by) <= tol; }
- _onProgress(evt) { - if (evt.total === undefined) { - const firstReader = this._rangeReaders[0]; + #getBbox() { + let xMin = Infinity; + let xMax = -Infinity; + let yMin = Infinity; + let yMax = -Infinity;
- if (firstReader?.onProgress) { - firstReader.onProgress({ - loaded: evt.loaded - }); - } - } else { - const fullReader = this._fullRequestReader; + for (const path of this.paths) { + for (const [first, control1, control2, second] of path) { + const bbox = _util.Util.bezierBoundingBox(...first, ...control1, ...control2, ...second);
- if (fullReader?.onProgress) { - fullReader.onProgress({ - loaded: evt.loaded, - total: evt.total - }); + xMin = Math.min(xMin, bbox[0]); + yMin = Math.min(yMin, bbox[1]); + xMax = Math.max(xMax, bbox[2]); + yMax = Math.max(yMax, bbox[3]); } } + + return [xMin, yMin, xMax, yMax]; }
- _onProgressiveDone() { - if (this._fullRequestReader) { - this._fullRequestReader.progressiveDone(); + #getPadding() { + return this.#disableEditing ? Math.ceil(this.thickness * this.parent.scaleFactor) : 0; + } + + #fitToContent(thicknessChanged = false) { + if (this.isEmpty()) { + return; }
- this._progressiveDone = true; - } + if (!this.#disableEditing) { + this.#redraw(); + return; + }
- _removeRangeReader(reader) { - const i = this._rangeReaders.indexOf(reader); + const bbox = this.#getBbox(); + const padding = this.#getPadding(); + this.#baseWidth = Math.max(RESIZER_SIZE, bbox[2] - bbox[0]); + this.#baseHeight = Math.max(RESIZER_SIZE, bbox[3] - bbox[1]); + const width = Math.ceil(padding + this.#baseWidth * this.scaleFactor); + const height = Math.ceil(padding + this.#baseHeight * this.scaleFactor); + const [parentWidth, parentHeight] = this.parent.viewportBaseDimensions; + this.width = width / parentWidth; + this.height = height / parentHeight; + this.#aspectRatio = width / height; + this.#setMinDims(); + const prevTranslationX = this.translationX; + const prevTranslationY = this.translationY; + this.translationX = -bbox[0]; + this.translationY = -bbox[1]; + this.#setCanvasDims(); + this.#redraw(); + this.#realWidth = width; + this.#realHeight = height; + this.setDims(width, height); + const unscaledPadding = thicknessChanged ? 0 : padding / this.scaleFactor / 2; + this.translate(prevTranslationX - this.translationX - unscaledPadding, prevTranslationY - this.translationY - unscaledPadding); + } + + #setMinDims() { + const { + style + } = this.div;
- if (i >= 0) { - this._rangeReaders.splice(i, 1); + if (this.#aspectRatio >= 1) { + style.minHeight = `${RESIZER_SIZE}px`; + style.minWidth = `${Math.round(this.#aspectRatio * RESIZER_SIZE)}px`; + } else { + style.minWidth = `${RESIZER_SIZE}px`; + style.minHeight = `${Math.round(RESIZER_SIZE / this.#aspectRatio)}px`; } }
- getFullReader() { - (0, _util.assert)(!this._fullRequestReader, "PDFDataTransportStream.getFullReader can only be called once."); - const queuedChunks = this._queuedChunks; - this._queuedChunks = null; - return new PDFDataTransportStreamReader(this, queuedChunks, this._progressiveDone, this._contentDispositionFilename); - } + static deserialize(data, parent) { + const editor = super.deserialize(data, parent); + editor.thickness = data.thickness; + editor.color = _util.Util.makeHexColor(...data.color); + const [pageWidth, pageHeight] = parent.pageDimensions; + const width = editor.width * pageWidth; + const height = editor.height * pageHeight; + const scaleFactor = parent.scaleFactor; + const padding = data.thickness / 2; + editor.#aspectRatio = width / height; + editor.#disableEditing = true; + editor.#realWidth = Math.round(width); + editor.#realHeight = Math.round(height);
- getRangeReader(begin, end) { - if (end <= this._progressiveDataLength) { + for (const { + bezier + } of data.paths) { + const path = []; + editor.paths.push(path); + let p0 = scaleFactor * (bezier[0] - padding); + let p1 = scaleFactor * (height - bezier[1] - padding); + + for (let i = 2, ii = bezier.length; i < ii; i += 6) { + const p10 = scaleFactor * (bezier[i] - padding); + const p11 = scaleFactor * (height - bezier[i + 1] - padding); + const p20 = scaleFactor * (bezier[i + 2] - padding); + const p21 = scaleFactor * (height - bezier[i + 3] - padding); + const p30 = scaleFactor * (bezier[i + 4] - padding); + const p31 = scaleFactor * (height - bezier[i + 5] - padding); + path.push([[p0, p1], [p10, p11], [p20, p21], [p30, p31]]); + p0 = p30; + p1 = p31; + } + + const path2D = this.#buildPath2D(path); + editor.bezierPath2D.push(path2D); + } + + const bbox = editor.#getBbox(); + editor.#baseWidth = bbox[2] - bbox[0]; + editor.#baseHeight = bbox[3] - bbox[1]; + editor.#setScaleFactor(width, height); + return editor; + } + + serialize() { + if (this.isEmpty()) { return null; }
- const reader = new PDFDataTransportStreamRangeReader(this, begin, end); - - this._pdfDataRangeTransport.requestDataRange(begin, end); + const rect = this.getRect(0, 0); + const height = this.rotation % 180 === 0 ? rect[3] - rect[1] : rect[2] - rect[0];
- this._rangeReaders.push(reader); + const color = _editor.AnnotationEditor._colorManager.convert(this.ctx.strokeStyle);
- return reader; + return { + annotationType: _util.AnnotationEditorType.INK, + color, + thickness: this.thickness, + paths: this.#serializePaths(this.scaleFactor / this.parent.scaleFactor, this.translationX, this.translationY, height), + pageIndex: this.parent.pageIndex, + rect, + rotation: this.rotation + }; }
- cancelAllRequests(reason) { - if (this._fullRequestReader) { - this._fullRequestReader.cancel(reason); - } +}
- for (const reader of this._rangeReaders.slice(0)) { - reader.cancel(reason); - } +exports.InkEditor = InkEditor;
- this._pdfDataRangeTransport.abort(); - } +/***/ }), +/* 24 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
-}
-exports.PDFDataTransportStream = PDFDataTransportStream;
-class PDFDataTransportStreamReader { - constructor(stream, queuedChunks, progressiveDone = false, contentDispositionFilename = null) { - this._stream = stream; - this._done = progressiveDone || false; - this._filename = (0, _display_utils.isPdfFile)(contentDispositionFilename) ? contentDispositionFilename : null; - this._queuedChunks = queuedChunks || []; - this._loaded = 0; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.fitCurve = void 0;
- for (const chunk of this._queuedChunks) { - this._loaded += chunk.byteLength; - } +const fitCurve = __w_pdfjs_require__(25);
- this._requests = []; - this._headersReady = Promise.resolve(); - stream._fullRequestReader = this; - this.onProgress = null; - } +exports.fitCurve = fitCurve;
- _enqueue(chunk) { - if (this._done) { - return; - } +/***/ }), +/* 25 */ +/***/ ((module) => {
- if (this._requests.length > 0) { - const requestCapability = this._requests.shift();
- requestCapability.resolve({ - value: chunk, - done: false - }); - } else { - this._queuedChunks.push(chunk); - }
- this._loaded += chunk.byteLength; +function fitCurve(points, maxError, progressCallback) { + if (!Array.isArray(points)) { + throw new TypeError("First argument should be an array"); }
- get headersReady() { - return this._headersReady; - } + points.forEach(point => { + if (!Array.isArray(point) || point.some(item => typeof item !== 'number') || point.length !== points[0].length) { + throw Error("Each point should be an array of numbers. Each point should have the same amount of numbers."); + } + }); + points = points.filter((point, i) => i === 0 || !point.every((val, j) => val === points[i - 1][j]));
- get filename() { - return this._filename; + if (points.length < 2) { + return []; }
- get isRangeSupported() { - return this._stream._isRangeSupported; - } + const len = points.length; + const leftTangent = createTangent(points[1], points[0]); + const rightTangent = createTangent(points[len - 2], points[len - 1]); + return fitCubic(points, leftTangent, rightTangent, maxError, progressCallback); +}
- get isStreamingSupported() { - return this._stream._isStreamingSupported; +function fitCubic(points, leftTangent, rightTangent, error, progressCallback) { + const MaxIterations = 20; + var bezCurve, u, uPrime, maxError, prevErr, splitPoint, prevSplit, centerVector, toCenterTangent, fromCenterTangent, beziers, dist, i; + + if (points.length === 2) { + dist = maths.vectorLen(maths.subtract(points[0], points[1])) / 3.0; + bezCurve = [points[0], maths.addArrays(points[0], maths.mulItems(leftTangent, dist)), maths.addArrays(points[1], maths.mulItems(rightTangent, dist)), points[1]]; + return [bezCurve]; }
- get contentLength() { - return this._stream._contentLength; + u = chordLengthParameterize(points); + [bezCurve, maxError, splitPoint] = generateAndReport(points, u, u, leftTangent, rightTangent, progressCallback); + + if (maxError === 0 || maxError < error) { + return [bezCurve]; }
- async read() { - if (this._queuedChunks.length > 0) { - const chunk = this._queuedChunks.shift(); + if (maxError < error * error) { + uPrime = u; + prevErr = maxError; + prevSplit = splitPoint;
- return { - value: chunk, - done: false - }; - } + for (i = 0; i < MaxIterations; i++) { + uPrime = reparameterize(bezCurve, points, uPrime); + [bezCurve, maxError, splitPoint] = generateAndReport(points, u, uPrime, leftTangent, rightTangent, progressCallback);
- if (this._done) { - return { - value: undefined, - done: true - }; - } + if (maxError < error) { + return [bezCurve]; + } else if (splitPoint === prevSplit) { + let errChange = maxError / prevErr;
- const requestCapability = (0, _util.createPromiseCapability)(); + if (errChange > .9999 && errChange < 1.0001) { + break; + } + }
- this._requests.push(requestCapability); + prevErr = maxError; + prevSplit = splitPoint; + } + }
- return requestCapability.promise; + beziers = []; + centerVector = maths.subtract(points[splitPoint - 1], points[splitPoint + 1]); + + if (centerVector.every(val => val === 0)) { + centerVector = maths.subtract(points[splitPoint - 1], points[splitPoint]); + [centerVector[0], centerVector[1]] = [-centerVector[1], centerVector[0]]; }
- cancel(reason) { - this._done = true; + toCenterTangent = maths.normalize(centerVector); + fromCenterTangent = maths.mulItems(toCenterTangent, -1); + beziers = beziers.concat(fitCubic(points.slice(0, splitPoint + 1), leftTangent, toCenterTangent, error, progressCallback)); + beziers = beziers.concat(fitCubic(points.slice(splitPoint), fromCenterTangent, rightTangent, error, progressCallback)); + return beziers; +}
- for (const requestCapability of this._requests) { - requestCapability.resolve({ - value: undefined, - done: true - }); - } +;
- this._requests.length = 0; +function generateAndReport(points, paramsOrig, paramsPrime, leftTangent, rightTangent, progressCallback) { + var bezCurve, maxError, splitPoint; + bezCurve = generateBezier(points, paramsPrime, leftTangent, rightTangent, progressCallback); + [maxError, splitPoint] = computeMaxError(points, bezCurve, paramsOrig); + + if (progressCallback) { + progressCallback({ + bez: bezCurve, + points: points, + params: paramsOrig, + maxErr: maxError, + maxPoint: splitPoint + }); }
- progressiveDone() { - if (this._done) { - return; - } - - this._done = true; + return [bezCurve, maxError, splitPoint]; +} + +function generateBezier(points, parameters, leftTangent, rightTangent) { + var bezCurve, + A, + a, + C, + X, + det_C0_C1, + det_C0_X, + det_X_C1, + alpha_l, + alpha_r, + epsilon, + segLength, + i, + len, + tmp, + u, + ux, + firstPoint = points[0], + lastPoint = points[points.length - 1]; + bezCurve = [firstPoint, null, null, lastPoint]; + A = maths.zeros_Xx2x2(parameters.length); + + for (i = 0, len = parameters.length; i < len; i++) { + u = parameters[i]; + ux = 1 - u; + a = A[i]; + a[0] = maths.mulItems(leftTangent, 3 * u * (ux * ux)); + a[1] = maths.mulItems(rightTangent, 3 * ux * (u * u)); + } + + C = [[0, 0], [0, 0]]; + X = [0, 0]; + + for (i = 0, len = points.length; i < len; i++) { + u = parameters[i]; + a = A[i]; + C[0][0] += maths.dot(a[0], a[0]); + C[0][1] += maths.dot(a[0], a[1]); + C[1][0] += maths.dot(a[0], a[1]); + C[1][1] += maths.dot(a[1], a[1]); + tmp = maths.subtract(points[i], bezier.q([firstPoint, firstPoint, lastPoint, lastPoint], u)); + X[0] += maths.dot(a[0], tmp); + X[1] += maths.dot(a[1], tmp); + } + + det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1]; + det_C0_X = C[0][0] * X[1] - C[1][0] * X[0]; + det_X_C1 = X[0] * C[1][1] - X[1] * C[0][1]; + alpha_l = det_C0_C1 === 0 ? 0 : det_X_C1 / det_C0_C1; + alpha_r = det_C0_C1 === 0 ? 0 : det_C0_X / det_C0_C1; + segLength = maths.vectorLen(maths.subtract(firstPoint, lastPoint)); + epsilon = 1.0e-6 * segLength; + + if (alpha_l < epsilon || alpha_r < epsilon) { + bezCurve[1] = maths.addArrays(firstPoint, maths.mulItems(leftTangent, segLength / 3.0)); + bezCurve[2] = maths.addArrays(lastPoint, maths.mulItems(rightTangent, segLength / 3.0)); + } else { + bezCurve[1] = maths.addArrays(firstPoint, maths.mulItems(leftTangent, alpha_l)); + bezCurve[2] = maths.addArrays(lastPoint, maths.mulItems(rightTangent, alpha_r)); }
+ return bezCurve; }
-class PDFDataTransportStreamRangeReader { - constructor(stream, begin, end) { - this._stream = stream; - this._begin = begin; - this._end = end; - this._queuedChunk = null; - this._requests = []; - this._done = false; - this.onProgress = null; +; + +function reparameterize(bezier, points, parameters) { + return parameters.map((p, i) => newtonRaphsonRootFind(bezier, points[i], p)); +} + +; + +function newtonRaphsonRootFind(bez, point, u) { + var d = maths.subtract(bezier.q(bez, u), point), + qprime = bezier.qprime(bez, u), + numerator = maths.mulMatrix(d, qprime), + denominator = maths.sum(maths.squareItems(qprime)) + 2 * maths.mulMatrix(d, bezier.qprimeprime(bez, u)); + + if (denominator === 0) { + return u; + } else { + return u - numerator / denominator; } +}
- _enqueue(chunk) { - if (this._done) { - return; - } +;
- if (this._requests.length === 0) { - this._queuedChunk = chunk; - } else { - const requestsCapability = this._requests.shift(); +function chordLengthParameterize(points) { + var u = [], + currU, + prevU, + prevP; + points.forEach((p, i) => { + currU = i ? prevU + maths.vectorLen(maths.subtract(p, prevP)) : 0; + u.push(currU); + prevU = currU; + prevP = p; + }); + u = u.map(x => x / prevU); + return u; +}
- requestsCapability.resolve({ - value: chunk, - done: false - }); +;
- for (const requestCapability of this._requests) { - requestCapability.resolve({ - value: undefined, - done: true - }); - } +function computeMaxError(points, bez, parameters) { + var dist, maxDist, splitPoint, v, i, count, point, t; + maxDist = 0; + splitPoint = Math.floor(points.length / 2); + const t_distMap = mapTtoRelativeDistances(bez, 10);
- this._requests.length = 0; + for (i = 0, count = points.length; i < count; i++) { + point = points[i]; + t = find_t(bez, parameters[i], t_distMap, 10); + v = maths.subtract(bezier.q(bez, t), point); + dist = v[0] * v[0] + v[1] * v[1]; + + if (dist > maxDist) { + maxDist = dist; + splitPoint = i; } + }
- this._done = true; + return [maxDist, splitPoint]; +}
- this._stream._removeRangeReader(this); - } +;
- get isStreamingSupported() { - return false; +var mapTtoRelativeDistances = function (bez, B_parts) { + var B_t_curr; + var B_t_dist = [0]; + var B_t_prev = bez[0]; + var sumLen = 0; + + for (var i = 1; i <= B_parts; i++) { + B_t_curr = bezier.q(bez, i / B_parts); + sumLen += maths.vectorLen(maths.subtract(B_t_curr, B_t_prev)); + B_t_dist.push(sumLen); + B_t_prev = B_t_curr; }
- async read() { - if (this._queuedChunk) { - const chunk = this._queuedChunk; - this._queuedChunk = null; - return { - value: chunk, - done: false - }; - } + B_t_dist = B_t_dist.map(x => x / sumLen); + return B_t_dist; +};
- if (this._done) { - return { - value: undefined, - done: true - }; - } +function find_t(bez, param, t_distMap, B_parts) { + if (param < 0) { + return 0; + }
- const requestCapability = (0, _util.createPromiseCapability)(); + if (param > 1) { + return 1; + }
- this._requests.push(requestCapability); + var lenMax, lenMin, tMax, tMin, t;
- return requestCapability.promise; + for (var i = 1; i <= B_parts; i++) { + if (param <= t_distMap[i]) { + tMin = (i - 1) / B_parts; + tMax = i / B_parts; + lenMin = t_distMap[i - 1]; + lenMax = t_distMap[i]; + t = (param - lenMin) / (lenMax - lenMin) * (tMax - tMin) + tMin; + break; + } }
- cancel(reason) { - this._done = true; + return t; +}
- for (const requestCapability of this._requests) { - requestCapability.resolve({ - value: undefined, - done: true - }); +function createTangent(pointA, pointB) { + return maths.normalize(maths.subtract(pointA, pointB)); +} + +class maths { + static zeros_Xx2x2(x) { + var zs = []; + + while (x--) { + zs.push([0, 0]); }
- this._requests.length = 0; + return zs; + }
- this._stream._removeRangeReader(this); + static mulItems(items, multiplier) { + return items.map(x => x * multiplier); }
-} + static mulMatrix(m1, m2) { + return m1.reduce((sum, x1, i) => sum + x1 * m2[i], 0); + }
-/***/ }), -/* 18 */ -/***/ ((__unused_webpack_module, exports) => { + static subtract(arr1, arr2) { + return arr1.map((x1, i) => x1 - arr2[i]); + }
+ static addArrays(arr1, arr2) { + return arr1.map((x1, i) => x1 + arr2[i]); + }
+ static addItems(items, addition) { + return items.map(x => x + addition); + }
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.XfaText = void 0; + static sum(items) { + return items.reduce((sum, x) => sum + x); + }
-class XfaText { - static textContent(xfa) { - const items = []; - const output = { - items, - styles: Object.create(null) - }; + static dot(m1, m2) { + return maths.mulMatrix(m1, m2); + }
- function walk(node) { - if (!node) { - return; - } + static vectorLen(v) { + return Math.hypot(...v); + }
- let str = null; - const name = node.name; + static divItems(items, divisor) { + return items.map(x => x / divisor); + }
- if (name === "#text") { - str = node.value; - } else if (!XfaText.shouldBuildText(name)) { - return; - } else if (node?.attributes?.textContent) { - str = node.attributes.textContent; - } else if (node.value) { - str = node.value; - } + static squareItems(items) { + return items.map(x => x * x); + }
- if (str !== null) { - items.push({ - str - }); - } + static normalize(v) { + return this.divItems(v, this.vectorLen(v)); + }
- if (!node.children) { - return; - } +}
- for (const child of node.children) { - walk(child); - } - } +class bezier { + static q(ctrlPoly, t) { + var tx = 1.0 - t; + var pA = maths.mulItems(ctrlPoly[0], tx * tx * tx), + pB = maths.mulItems(ctrlPoly[1], 3 * tx * tx * t), + pC = maths.mulItems(ctrlPoly[2], 3 * tx * t * t), + pD = maths.mulItems(ctrlPoly[3], t * t * t); + return maths.addArrays(maths.addArrays(pA, pB), maths.addArrays(pC, pD)); + }
- walk(xfa); - return output; + static qprime(ctrlPoly, t) { + var tx = 1.0 - t; + var pA = maths.mulItems(maths.subtract(ctrlPoly[1], ctrlPoly[0]), 3 * tx * tx), + pB = maths.mulItems(maths.subtract(ctrlPoly[2], ctrlPoly[1]), 6 * tx * t), + pC = maths.mulItems(maths.subtract(ctrlPoly[3], ctrlPoly[2]), 3 * t * t); + return maths.addArrays(maths.addArrays(pA, pB), pC); }
- static shouldBuildText(name) { - return !(name === "textarea" || name === "input" || name === "option" || name === "select"); + static qprimeprime(ctrlPoly, t) { + return maths.addArrays(maths.mulItems(maths.addArrays(maths.subtract(ctrlPoly[2], maths.mulItems(ctrlPoly[1], 2)), ctrlPoly[0]), 6 * (1.0 - t)), maths.mulItems(maths.addArrays(maths.subtract(ctrlPoly[3], maths.mulItems(ctrlPoly[2], 2)), ctrlPoly[1]), 6 * t)); }
}
-exports.XfaText = XfaText; +module.exports = fitCurve; +module.exports.fitCubic = fitCubic; +module.exports.createTangent = createTangent;
/***/ }), -/* 19 */ +/* 26 */ /***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
@@ -9261,15 +12537,16 @@ exports.AnnotationLayer = void 0;
var _util = __w_pdfjs_require__(1);
-var _display_utils = __w_pdfjs_require__(5); +var _display_utils = __w_pdfjs_require__(4);
-var _annotation_storage = __w_pdfjs_require__(8); +var _annotation_storage = __w_pdfjs_require__(7);
-var _scripting_utils = __w_pdfjs_require__(20); +var _scripting_utils = __w_pdfjs_require__(27);
-var _xfa_layer = __w_pdfjs_require__(21); +var _xfa_layer = __w_pdfjs_require__(28);
const DEFAULT_TAB_INDEX = 1000; +const DEFAULT_FONT_SIZE = 9; const GetElementsByNameSet = new WeakSet();
function getRectDims(rect) { @@ -9400,48 +12677,24 @@ class AnnotationElement { page = this.page, viewport = this.viewport; const container = document.createElement("section"); - let { + const { width, height } = getRectDims(data.rect); + const [pageLLx, pageLLy, pageURx, pageURy] = viewport.viewBox; + const pageWidth = pageURx - pageLLx; + const pageHeight = pageURy - pageLLy; container.setAttribute("data-annotation-id", data.id);
const rect = _util.Util.normalizeRect([data.rect[0], page.view[3] - data.rect[1] + page.view[1], data.rect[2], page.view[3] - data.rect[3] + page.view[1]]);
- if (data.hasOwnCanvas) { - const transform = viewport.transform.slice(); - - const [scaleX, scaleY] = _util.Util.singularValueDecompose2dScale(transform); - - width = Math.ceil(width * scaleX); - height = Math.ceil(height * scaleY); - rect[0] *= scaleX; - rect[1] *= scaleY; - - for (let i = 0; i < 4; i++) { - transform[i] = Math.sign(transform[i]); - } - - container.style.transform = `matrix(${transform.join(",")})`; - } else { - container.style.transform = `matrix(${viewport.transform.join(",")})`; - } - - container.style.transformOrigin = `${-rect[0]}px ${-rect[1]}px`; - if (!ignoreBorder && data.borderStyle.width > 0) { container.style.borderWidth = `${data.borderStyle.width}px`; - - if (data.borderStyle.style !== _util.AnnotationBorderStyleType.UNDERLINE) { - width -= 2 * data.borderStyle.width; - height -= 2 * data.borderStyle.width; - } - const horizontalRadius = data.borderStyle.horizontalCornerRadius; const verticalRadius = data.borderStyle.verticalCornerRadius;
if (horizontalRadius > 0 || verticalRadius > 0) { - const radius = `${horizontalRadius}px / ${verticalRadius}px`; + const radius = `calc(${horizontalRadius}px * var(--scale-factor)) / calc(${verticalRadius}px * var(--scale-factor))`; container.style.borderRadius = radius; }
@@ -9470,28 +12723,54 @@ class AnnotationElement { break; }
- const borderColor = data.borderColor || data.color || null; + const borderColor = data.borderColor || null;
if (borderColor) { - container.style.borderColor = _util.Util.makeHexColor(data.color[0] | 0, data.color[1] | 0, data.color[2] | 0); + container.style.borderColor = _util.Util.makeHexColor(borderColor[0] | 0, borderColor[1] | 0, borderColor[2] | 0); } else { container.style.borderWidth = 0; } }
- container.style.left = `${rect[0]}px`; - container.style.top = `${rect[1]}px`; + container.style.left = `${100 * (rect[0] - pageLLx) / pageWidth}%`; + container.style.top = `${100 * (rect[1] - pageLLy) / pageHeight}%`; + const { + rotation + } = data;
- if (data.hasOwnCanvas) { - container.style.width = container.style.height = "auto"; + if (data.hasOwnCanvas || rotation === 0) { + container.style.width = `${100 * width / pageWidth}%`; + container.style.height = `${100 * height / pageHeight}%`; } else { - container.style.width = `${width}px`; - container.style.height = `${height}px`; + this.setRotation(rotation, container); }
return container; }
+ setRotation(angle, container = this.container) { + const [pageLLx, pageLLy, pageURx, pageURy] = this.viewport.viewBox; + const pageWidth = pageURx - pageLLx; + const pageHeight = pageURy - pageLLy; + const { + width, + height + } = getRectDims(this.data.rect); + let elementWidth, elementHeight; + + if (angle % 180 === 0) { + elementWidth = 100 * width / pageWidth; + elementHeight = 100 * height / pageHeight; + } else { + elementWidth = 100 * height / pageWidth; + elementHeight = 100 * width / pageHeight; + } + + container.style.width = `${elementWidth}%`; + container.style.height = `${elementHeight}%`; + container.setAttribute("data-main-rotation", (360 - angle) % 360); + } + get _commonActions() { const setColor = (jsName, styleName, event) => { const color = event.detail[jsName]; @@ -9501,7 +12780,7 @@ class AnnotationElement { return (0, _util.shadow)(this, "_commonActions", { display: event => { const hidden = event.detail.display % 2 === 1; - event.target.style.visibility = hidden ? "hidden" : "visible"; + this.container.style.visibility = hidden ? "hidden" : "visible"; this.annotationStorage.setValue(this.data.id, { hidden, print: event.detail.display === 0 || event.detail.display === 3 @@ -9513,7 +12792,7 @@ class AnnotationElement { }); }, hidden: event => { - event.target.style.visibility = event.detail.hidden ? "hidden" : "visible"; + this.container.style.visibility = event.detail.hidden ? "hidden" : "visible"; this.annotationStorage.setValue(this.data.id, { hidden: event.detail.hidden }); @@ -9534,11 +12813,7 @@ class AnnotationElement { } }, required: event => { - if (event.detail.required) { - event.target.setAttribute("required", ""); - } else { - event.target.removeAttribute("required"); - } + this._setRequired(event.target, event.detail.required); }, bgColor: event => { setColor("bgColor", "backgroundColor", event); @@ -9557,6 +12832,13 @@ class AnnotationElement { }, strokeColor: event => { setColor("strokeColor", "borderColor", event); + }, + rotation: event => { + const angle = event.detail.rotation; + this.setRotation(angle); + this.annotationStorage.setValue(this.data.id, { + rotation: angle + }); } }); } @@ -9626,9 +12908,8 @@ class AnnotationElement {
if (!trigger) { trigger = document.createElement("div"); - trigger.style.height = container.style.height; - trigger.style.width = container.style.width; - container.appendChild(trigger); + trigger.className = "popupTriggerArea"; + container.append(trigger); }
const popupElement = new PopupElement({ @@ -9642,8 +12923,8 @@ class AnnotationElement { hideWrapper: true }); const popup = popupElement.render(); - popup.style.left = container.style.width; - container.appendChild(popup); + popup.style.left = "100%"; + container.append(popup); }
_renderQuadrilaterals(className) { @@ -9679,7 +12960,7 @@ class AnnotationElement { }
const exportValue = typeof exportValues === "string" ? exportValues : null; - const domElement = document.getElementById(id); + const domElement = document.querySelector(`[data-element-id="${id}"]`);
if (domElement && !GetElementsByNameSet.has(domElement)) { (0, _util.warn)(`_getElementsByName - element not allowed: ${id}`); @@ -9733,12 +13014,12 @@ class AnnotationElement {
class LinkAnnotationElement extends AnnotationElement { constructor(parameters, options = null) { - const isRenderable = !!(parameters.data.url || parameters.data.dest || parameters.data.action || parameters.data.isTooltipOnly || parameters.data.resetForm || parameters.data.actions && (parameters.data.actions.Action || parameters.data.actions["Mouse Up"] || parameters.data.actions["Mouse Down"])); super(parameters, { - isRenderable, + isRenderable: true, ignoreBorder: !!options?.ignoreBorder, createQuadrilaterals: true }); + this.isTooltipOnly = parameters.data.isTooltipOnly; }
render() { @@ -9747,39 +13028,52 @@ class LinkAnnotationElement extends AnnotationElement { linkService } = this; const link = document.createElement("a"); + link.setAttribute("data-element-id", data.id); + let isBound = false;
if (data.url) { linkService.addLinkAttributes(link, data.url, data.newWindow); + isBound = true; } else if (data.action) { this._bindNamedAction(link, data.action); + + isBound = true; } else if (data.dest) { this._bindLink(link, data.dest); - } else { - let hasClickAction = false;
+ isBound = true; + } else { if (data.actions && (data.actions.Action || data.actions["Mouse Up"] || data.actions["Mouse Down"]) && this.enableScripting && this.hasJSActions) { - hasClickAction = true; - this._bindJSAction(link, data); + + isBound = true; }
if (data.resetForm) { this._bindResetFormAction(link, data.resetForm); - } else if (!hasClickAction) { + + isBound = true; + } else if (this.isTooltipOnly && !isBound) { this._bindLink(link, ""); + + isBound = true; } }
if (this.quadrilaterals) { return this._renderQuadrilaterals("linkAnnotation").map((quadrilateral, index) => { const linkElement = index === 0 ? link : link.cloneNode(); - quadrilateral.appendChild(linkElement); + quadrilateral.append(linkElement); return quadrilateral; }); }
this.container.className = "linkAnnotation"; - this.container.appendChild(link); + + if (isBound) { + this.container.append(link); + } + return this.container; }
@@ -9940,9 +13234,12 @@ class LinkAnnotationElement extends AnnotationElement { continue; }
- const domElement = document.getElementById(id); + const domElement = document.querySelector(`[data-element-id="${id}"]`);
- if (!domElement || !GetElementsByNameSet.has(domElement)) { + if (!domElement) { + continue; + } else if (!GetElementsByNameSet.has(domElement)) { + (0, _util.warn)(`_bindResetFormAction - element not allowed: ${id}`); continue; }
@@ -9977,8 +13274,6 @@ class TextAnnotationElement extends AnnotationElement { render() { this.container.className = "textAnnotation"; const image = document.createElement("img"); - image.style.height = this.container.style.height; - image.style.width = this.container.style.width; image.src = this.imageResourcesPath + "annotation-" + this.data.name.toLowerCase() + ".svg"; image.alt = "[{{type}} Annotation]"; image.dataset.l10nId = "text_annotation_type"; @@ -9990,7 +13285,7 @@ class TextAnnotationElement extends AnnotationElement { this._createPopup(image, this.data); }
- this.container.appendChild(image); + this.container.append(image); return this.container; }
@@ -10054,6 +13349,43 @@ class WidgetAnnotationElement extends AnnotationElement { element.style.backgroundColor = color === null ? "transparent" : _util.Util.makeHexColor(color[0], color[1], color[2]); }
+ _setTextStyle(element) { + const TEXT_ALIGNMENT = ["left", "center", "right"]; + const { + fontColor + } = this.data.defaultAppearanceData; + const fontSize = this.data.defaultAppearanceData.fontSize || DEFAULT_FONT_SIZE; + const style = element.style; + let computedFontSize; + + if (this.data.multiLine) { + const height = Math.abs(this.data.rect[3] - this.data.rect[1]); + const numberOfLines = Math.round(height / (_util.LINE_FACTOR * fontSize)) || 1; + const lineHeight = height / numberOfLines; + computedFontSize = Math.min(fontSize, Math.round(lineHeight / _util.LINE_FACTOR)); + } else { + const height = Math.abs(this.data.rect[3] - this.data.rect[1]); + computedFontSize = Math.min(fontSize, Math.round(height / _util.LINE_FACTOR)); + } + + style.fontSize = `calc(${computedFontSize}px * var(--scale-factor))`; + style.color = _util.Util.makeHexColor(fontColor[0], fontColor[1], fontColor[2]); + + if (this.data.textAlignment !== null) { + style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment]; + } + } + + _setRequired(element, isRequired) { + if (isRequired) { + element.setAttribute("required", true); + } else { + element.removeAttribute("required"); + } + + element.setAttribute("aria-required", isRequired); + } + }
class TextWidgetAnnotationElement extends WidgetAnnotationElement { @@ -10090,7 +13422,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement { }); const textContent = storedData.formattedValue || storedData.value || ""; const elementData = { - userValue: null, + userValue: textContent, formattedValue: null, valueOnFocus: "" }; @@ -10098,18 +13430,28 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement { if (this.data.multiLine) { element = document.createElement("textarea"); element.textContent = textContent; + + if (this.data.doNotScroll) { + element.style.overflowY = "hidden"; + } } else { element = document.createElement("input"); element.type = "text"; element.setAttribute("value", textContent); + + if (this.data.doNotScroll) { + element.style.overflowX = "hidden"; + } }
GetElementsByNameSet.add(element); + element.setAttribute("data-element-id", id); element.disabled = this.data.readOnly; element.name = this.data.fieldName; element.tabIndex = DEFAULT_TAB_INDEX; - elementData.userValue = textContent; - element.setAttribute("id", id); + + this._setRequired(element, this.data.required); + element.addEventListener("input", event => { storage.setValue(id, { value: event.target.value @@ -10321,7 +13663,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement { const fieldWidth = this.data.rect[2] - this.data.rect[0]; const combWidth = fieldWidth / this.data.maxLen; element.classList.add("comb"); - element.style.letterSpacing = `calc(${combWidth}px - 1ch)`; + element.style.letterSpacing = `calc(${combWidth}px * var(--scale-factor) - 1ch)`; } } else { element = document.createElement("div"); @@ -10336,29 +13678,10 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
this._setDefaultPropertiesFromJS(element);
- this.container.appendChild(element); + this.container.append(element); return this.container; }
- _setTextStyle(element) { - const TEXT_ALIGNMENT = ["left", "center", "right"]; - const { - fontSize, - fontColor - } = this.data.defaultAppearanceData; - const style = element.style; - - if (fontSize) { - style.fontSize = `${fontSize}px`; - } - - style.color = _util.Util.makeHexColor(fontColor[0], fontColor[1], fontColor[2]); - - if (this.data.textAlignment !== null) { - style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment]; - } - } - }
class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement { @@ -10386,7 +13709,11 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement { this.container.className = "buttonWidgetAnnotation checkBox"; const element = document.createElement("input"); GetElementsByNameSet.add(element); + element.setAttribute("data-element-id", id); element.disabled = data.readOnly; + + this._setRequired(element, this.data.required); + element.type = "checkbox"; element.name = data.fieldName;
@@ -10394,7 +13721,6 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement { element.setAttribute("checked", true); }
- element.setAttribute("id", id); element.setAttribute("exportValue", data.exportValue); element.tabIndex = DEFAULT_TAB_INDEX; element.addEventListener("change", event => { @@ -10446,7 +13772,7 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
this._setDefaultPropertiesFromJS(element);
- this.container.appendChild(element); + this.container.append(element); return this.container; }
@@ -10477,7 +13803,11 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
const element = document.createElement("input"); GetElementsByNameSet.add(element); + element.setAttribute("data-element-id", id); element.disabled = data.readOnly; + + this._setRequired(element, this.data.required); + element.type = "radio"; element.name = data.fieldName;
@@ -10485,7 +13815,6 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement { element.setAttribute("checked", true); }
- element.setAttribute("id", id); element.tabIndex = DEFAULT_TAB_INDEX; element.addEventListener("change", event => { const { @@ -10539,7 +13868,7 @@ class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
this._setDefaultPropertiesFromJS(element);
- this.container.appendChild(element); + this.container.append(element); return this.container; }
@@ -10560,7 +13889,15 @@ class PushButtonWidgetAnnotationElement extends LinkAnnotationElement { container.title = this.data.alternativeText; }
- this._setDefaultPropertiesFromJS(container); + const linkElement = container.lastChild; + + if (this.enableScripting && this.hasJSActions && linkElement) { + this._setDefaultPropertiesFromJS(linkElement); + + linkElement.addEventListener("updatefromsandbox", jsEvent => { + this._dispatchEventFromSandbox({}, jsEvent); + }); + }
return container; } @@ -10581,22 +13918,16 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { const storedData = storage.getValue(id, { value: this.data.fieldValue }); - let { - fontSize - } = this.data.defaultAppearanceData; - - if (!fontSize) { - fontSize = 9; - } - - const fontSizeStyle = `calc(${fontSize}px * var(--zoom-factor))`; const selectElement = document.createElement("select"); GetElementsByNameSet.add(selectElement); + selectElement.setAttribute("data-element-id", id); selectElement.disabled = this.data.readOnly; + + this._setRequired(selectElement, this.data.required); + selectElement.name = this.data.fieldName; - selectElement.setAttribute("id", id); selectElement.tabIndex = DEFAULT_TAB_INDEX; - selectElement.style.fontSize = `${fontSize}px`; + let addAnEmptyEntry = this.data.combo && this.data.options.length > 0;
if (!this.data.combo) { selectElement.size = this.data.options.length; @@ -10619,15 +13950,30 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { optionElement.textContent = option.displayValue; optionElement.value = option.exportValue;
- if (this.data.combo) { - optionElement.style.fontSize = fontSizeStyle; - } - if (storedData.value.includes(option.exportValue)) { optionElement.setAttribute("selected", true); + addAnEmptyEntry = false; }
- selectElement.appendChild(optionElement); + selectElement.append(optionElement); + } + + let removeEmptyEntry = null; + + if (addAnEmptyEntry) { + const noneOptionElement = document.createElement("option"); + noneOptionElement.value = " "; + noneOptionElement.setAttribute("hidden", true); + noneOptionElement.setAttribute("selected", true); + selectElement.prepend(noneOptionElement); + + removeEmptyEntry = () => { + noneOptionElement.remove(); + selectElement.removeEventListener("input", removeEmptyEntry); + removeEmptyEntry = null; + }; + + selectElement.addEventListener("input", removeEmptyEntry); }
const getValue = (event, isExport) => { @@ -10655,6 +14001,7 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { selectElement.addEventListener("updatefromsandbox", jsEvent => { const actions = { value(event) { + removeEmptyEntry?.(); const value = event.detail.value; const values = new Set(Array.isArray(value) ? value : [value]);
@@ -10708,10 +14055,17 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { displayValue, exportValue } = event.detail.insert; + const selectChild = selectElement.children[index]; const optionElement = document.createElement("option"); optionElement.textContent = displayValue; optionElement.value = exportValue; - selectElement.insertBefore(optionElement, selectElement.children[index]); + + if (selectChild) { + selectChild.before(optionElement); + } else { + selectElement.append(optionElement); + } + storage.setValue(id, { value: getValue(event, true), items: getItems(event) @@ -10735,7 +14089,7 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { const optionElement = document.createElement("option"); optionElement.textContent = displayValue; optionElement.value = exportValue; - selectElement.appendChild(optionElement); + selectElement.append(optionElement); }
if (selectElement.options.length > 0) { @@ -10797,11 +14151,15 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { }); }
+ if (this.data.combo) { + this._setTextStyle(selectElement); + } else {} + this._setBackgroundColor(selectElement);
this._setDefaultPropertiesFromJS(selectElement);
- this.container.appendChild(selectElement); + this.container.append(selectElement); return this.container; }
@@ -10845,10 +14203,12 @@ class PopupAnnotationElement extends AnnotationElement {
const popupLeft = rect[0] + this.data.parentRect[2] - this.data.parentRect[0]; const popupTop = rect[1]; - this.container.style.transformOrigin = `${-popupLeft}px ${-popupTop}px`; - this.container.style.left = `${popupLeft}px`; - this.container.style.top = `${popupTop}px`; - this.container.appendChild(popup.render()); + const [pageLLx, pageLLy, pageURx, pageURy] = this.viewport.viewBox; + const pageWidth = pageURx - pageLLx; + const pageHeight = pageURy - pageLLy; + this.container.style.left = `${100 * (popupLeft - pageLLx) / pageWidth}%`; + this.container.style.top = `${100 * (popupTop - pageLLy) / pageHeight}%`; + this.container.append(popup.render()); return this.container; }
@@ -10887,7 +14247,7 @@ class PopupElement { const title = document.createElement("h1"); title.dir = this.titleObj.dir; title.textContent = this.titleObj.str; - popup.appendChild(title); + popup.append(title);
const dateObject = _display_utils.PDFDateString.toDateObject(this.modificationDate);
@@ -10900,7 +14260,7 @@ class PopupElement { date: dateObject.toLocaleDateString(), time: dateObject.toLocaleTimeString() }); - popup.appendChild(modificationDate); + popup.append(modificationDate); }
if (this.richText?.str && (!this.contentsObj?.str || this.contentsObj.str === this.richText.str)) { @@ -10914,7 +14274,7 @@ class PopupElement { } else { const contents = this._formatContents(this.contentsObj);
- popup.appendChild(contents); + popup.append(contents); }
if (!Array.isArray(this.trigger)) { @@ -10928,7 +14288,7 @@ class PopupElement { }
popup.addEventListener("click", this._hide.bind(this, true)); - wrapper.appendChild(popup); + wrapper.append(popup); return wrapper; }
@@ -10943,10 +14303,10 @@ class PopupElement {
for (let i = 0, ii = lines.length; i < ii; ++i) { const line = lines[i]; - p.appendChild(document.createTextNode(line)); + p.append(document.createTextNode(line));
if (i < ii - 1) { - p.appendChild(document.createElement("br")); + p.append(document.createElement("br")); } }
@@ -11022,7 +14382,7 @@ class LineAnnotationElement extends AnnotationElement { width, height } = getRectDims(data.rect); - const svg = this.svgFactory.create(width, height); + const svg = this.svgFactory.create(width, height, true); const line = this.svgFactory.createElement("svg:line"); line.setAttribute("x1", data.rect[2] - data.lineCoordinates[0]); line.setAttribute("y1", data.rect[3] - data.lineCoordinates[1]); @@ -11031,7 +14391,7 @@ class LineAnnotationElement extends AnnotationElement { line.setAttribute("stroke-width", data.borderStyle.width || 1); line.setAttribute("stroke", "transparent"); line.setAttribute("fill", "transparent"); - svg.appendChild(line); + svg.append(line); this.container.append(svg);
this._createPopup(line, data); @@ -11057,7 +14417,7 @@ class SquareAnnotationElement extends AnnotationElement { width, height } = getRectDims(data.rect); - const svg = this.svgFactory.create(width, height); + const svg = this.svgFactory.create(width, height, true); const borderWidth = data.borderStyle.width; const square = this.svgFactory.createElement("svg:rect"); square.setAttribute("x", borderWidth / 2); @@ -11067,7 +14427,7 @@ class SquareAnnotationElement extends AnnotationElement { square.setAttribute("stroke-width", borderWidth || 1); square.setAttribute("stroke", "transparent"); square.setAttribute("fill", "transparent"); - svg.appendChild(square); + svg.append(square); this.container.append(svg);
this._createPopup(square, data); @@ -11093,7 +14453,7 @@ class CircleAnnotationElement extends AnnotationElement { width, height } = getRectDims(data.rect); - const svg = this.svgFactory.create(width, height); + const svg = this.svgFactory.create(width, height, true); const borderWidth = data.borderStyle.width; const circle = this.svgFactory.createElement("svg:ellipse"); circle.setAttribute("cx", width / 2); @@ -11103,7 +14463,7 @@ class CircleAnnotationElement extends AnnotationElement { circle.setAttribute("stroke-width", borderWidth || 1); circle.setAttribute("stroke", "transparent"); circle.setAttribute("fill", "transparent"); - svg.appendChild(circle); + svg.append(circle); this.container.append(svg);
this._createPopup(circle, data); @@ -11131,7 +14491,7 @@ class PolylineAnnotationElement extends AnnotationElement { width, height } = getRectDims(data.rect); - const svg = this.svgFactory.create(width, height); + const svg = this.svgFactory.create(width, height, true); let points = [];
for (const coordinate of data.vertices) { @@ -11146,7 +14506,7 @@ class PolylineAnnotationElement extends AnnotationElement { polyline.setAttribute("stroke-width", data.borderStyle.width || 1); polyline.setAttribute("stroke", "transparent"); polyline.setAttribute("fill", "transparent"); - svg.appendChild(polyline); + svg.append(polyline); this.container.append(svg);
this._createPopup(polyline, data); @@ -11204,7 +14564,7 @@ class InkAnnotationElement extends AnnotationElement { width, height } = getRectDims(data.rect); - const svg = this.svgFactory.create(width, height); + const svg = this.svgFactory.create(width, height, true);
for (const inkList of data.inkLists) { let points = []; @@ -11224,7 +14584,7 @@ class InkAnnotationElement extends AnnotationElement {
this._createPopup(polyline, data);
- svg.appendChild(polyline); + svg.append(polyline); }
this.container.append(svg); @@ -11375,15 +14735,14 @@ class FileAttachmentAnnotationElement extends AnnotationElement { render() { this.container.className = "fileAttachmentAnnotation"; const trigger = document.createElement("div"); - trigger.style.height = this.container.style.height; - trigger.style.width = this.container.style.width; + trigger.className = "popupTriggerArea"; trigger.addEventListener("dblclick", this._download.bind(this));
if (!this.data.hasPopup && (this.data.titleObj?.str || this.data.contentsObj?.str || this.data.richText)) { this._createPopup(trigger, this.data); }
- this.container.appendChild(trigger); + this.container.append(trigger); return this.container; }
@@ -11395,14 +14754,25 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
class AnnotationLayer { static render(parameters) { + const { + annotations, + div, + viewport + } = parameters; + this.#setDimensions(div, viewport); const sortedAnnotations = [], popupAnnotations = [];
- for (const data of parameters.annotations) { + for (const data of annotations) { if (!data) { continue; }
+ if (data.annotationType === _util.AnnotationType.POPUP) { + popupAnnotations.push(data); + continue; + } + const { width, height @@ -11412,11 +14782,6 @@ class AnnotationLayer { continue; }
- if (data.annotationType === _util.AnnotationType.POPUP) { - popupAnnotations.push(data); - continue; - } - sortedAnnotations.push(data); }
@@ -11424,14 +14789,12 @@ class AnnotationLayer { sortedAnnotations.push(...popupAnnotations); }
- const div = parameters.div; - for (const data of sortedAnnotations) { const element = AnnotationElementFactory.create({ data, layer: div, page: parameters.page, - viewport: parameters.viewport, + viewport, linkService: parameters.linkService, downloadManager: parameters.downloadManager, imageResourcesPath: parameters.imageResourcesPath || "", @@ -11455,13 +14818,13 @@ class AnnotationLayer {
if (Array.isArray(rendered)) { for (const renderedElement of rendered) { - div.appendChild(renderedElement); + div.append(renderedElement); } } else { if (element instanceof PopupAnnotationElement) { div.prepend(rendered); } else { - div.appendChild(rendered); + div.append(rendered); } } } @@ -11472,52 +14835,31 @@ class AnnotationLayer {
static update(parameters) { const { - page, - viewport, - annotations, annotationCanvasMap, - div + div, + viewport } = parameters; - const transform = viewport.transform; - const matrix = `matrix(${transform.join(",")})`; - let scale, ownMatrix; - - for (const data of annotations) { - const elements = div.querySelectorAll(`[data-annotation-id="${data.id}"]`); - - if (elements) { - for (const element of elements) { - if (data.hasOwnCanvas) { - const rect = _util.Util.normalizeRect([data.rect[0], page.view[3] - data.rect[1] + page.view[1], data.rect[2], page.view[3] - data.rect[3] + page.view[1]]); - - if (!ownMatrix) { - scale = Math.abs(transform[0] || transform[1]); - const ownTransform = transform.slice(); - - for (let i = 0; i < 4; i++) { - ownTransform[i] = Math.sign(ownTransform[i]); - } - - ownMatrix = `matrix(${ownTransform.join(",")})`; - } - - const left = rect[0] * scale; - const top = rect[1] * scale; - element.style.left = `${left}px`; - element.style.top = `${top}px`; - element.style.transformOrigin = `${-left}px ${-top}px`; - element.style.transform = ownMatrix; - } else { - element.style.transform = matrix; - } - } - } - } - + this.#setDimensions(div, viewport); this.#setAnnotationCanvasMap(div, annotationCanvasMap); div.hidden = false; }
+ static #setDimensions(div, { + width, + height, + rotation + }) { + const { + style + } = div; + const flipOrientation = rotation % 180 !== 0, + widthStr = Math.floor(width) + "px", + heightStr = Math.floor(height) + "px"; + style.width = flipOrientation ? heightStr : widthStr; + style.height = flipOrientation ? widthStr : heightStr; + div.setAttribute("data-main-rotation", rotation); + } + static #setAnnotationCanvasMap(div, annotationCanvasMap) { if (!annotationCanvasMap) { return; @@ -11534,10 +14876,12 @@ class AnnotationLayer { firstChild } = element;
- if (firstChild.nodeName === "CANVAS") { - element.replaceChild(canvas, firstChild); + if (!firstChild) { + element.append(canvas); + } else if (firstChild.nodeName === "CANVAS") { + firstChild.replaceWith(canvas); } else { - element.insertBefore(canvas, firstChild); + firstChild.before(canvas); } }
@@ -11549,7 +14893,7 @@ class AnnotationLayer { exports.AnnotationLayer = AnnotationLayer;
/***/ }), -/* 20 */ +/* 27 */ /***/ ((__unused_webpack_module, exports) => {
@@ -11601,7 +14945,8 @@ class ColorConverters { }
static CMYK_HTML(components) { - return this.RGB_HTML(this.CMYK_RGB(components)); + const rgb = this.CMYK_RGB(components).slice(1); + return this.RGB_HTML(rgb); }
static RGB_CMYK([r, g, b]) { @@ -11617,7 +14962,7 @@ class ColorConverters { exports.ColorConverters = ColorConverters;
/***/ }), -/* 21 */ +/* 28 */ /***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
@@ -11627,7 +14972,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.XfaLayer = void 0;
-var _xfa_text = __w_pdfjs_require__(18); +var _xfa_text = __w_pdfjs_require__(20);
class XfaLayer { static setupStorage(html, id, element, storage, intent) { @@ -11724,26 +15069,38 @@ class XfaLayer { }
for (const [key, value] of Object.entries(attributes)) { - if (value === null || value === undefined || key === "dataId") { + if (value === null || value === undefined) { continue; }
- if (key !== "style") { - if (key === "textContent") { - html.textContent = value; - } else if (key === "class") { + switch (key) { + case "class": if (value.length) { html.setAttribute(key, value.join(" ")); } - } else { - if (isHTMLAnchorElement && (key === "href" || key === "newWindow")) { - continue; + + break; + + case "dataId": + break; + + case "id": + html.setAttribute("data-element-id", value); + break; + + case "style": + Object.assign(html.style, value); + break; + + case "textContent": + html.textContent = value; + break; + + default: + if (!isHTMLAnchorElement || key !== "href" && key !== "newWindow") { + html.setAttribute(key, value); }
- html.setAttribute(key, value); - } - } else { - Object.assign(html.style, value); } }
@@ -11774,7 +15131,7 @@ class XfaLayer {
const stack = [[root, -1, rootHtml]]; const rootDiv = parameters.div; - rootDiv.appendChild(rootHtml); + rootDiv.append(rootHtml);
if (parameters.viewport) { const transform = `matrix(${parameters.viewport.transform.join(",")})`; @@ -11788,14 +15145,14 @@ class XfaLayer { const textDivs = [];
while (stack.length > 0) { - const [parent, i, html] = stack[stack.length - 1]; + const [parent, i, html] = stack.at(-1);
if (i + 1 === parent.children.length) { stack.pop(); continue; }
- const child = parent.children[++stack[stack.length - 1][1]]; + const child = parent.children[++stack.at(-1)[1]];
if (child === null) { continue; @@ -11808,7 +15165,7 @@ class XfaLayer { if (name === "#text") { const node = document.createTextNode(child.value); textDivs.push(node); - html.appendChild(node); + html.append(node); continue; }
@@ -11820,7 +15177,7 @@ class XfaLayer { childHtml = document.createElement(name); }
- html.appendChild(childHtml); + html.append(childHtml);
if (child.attributes) { this.setAttributes({ @@ -11841,7 +15198,7 @@ class XfaLayer { textDivs.push(node); }
- childHtml.appendChild(node); + childHtml.append(node); } }
@@ -11865,7 +15222,7 @@ class XfaLayer { exports.XfaLayer = XfaLayer;
/***/ }), -/* 22 */ +/* 29 */ /***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
@@ -11873,10 +15230,13 @@ exports.XfaLayer = XfaLayer; Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.TextLayerRenderTask = void 0; exports.renderTextLayer = renderTextLayer;
var _util = __w_pdfjs_require__(1);
+var _display_utils = __w_pdfjs_require__(4); + const MAX_TEXT_DIVS_TO_RENDER = 100000; const DEFAULT_FONT_SIZE = 30; const DEFAULT_FONT_ASCENT = 0.8; @@ -12287,7 +15647,7 @@ function expandBoundsLTR(width, bounds) { const useBoundary = affectedBoundary.x2 > boundary.x2 ? affectedBoundary : boundary;
if (lastBoundary === useBoundary) { - changedHorizon[changedHorizon.length - 1].end = horizonPart.end; + changedHorizon.at(-1).end = horizonPart.end; } else { changedHorizon.push({ start: horizonPart.start, @@ -12308,7 +15668,7 @@ function expandBoundsLTR(width, bounds) { }
if (boundary.y2 < horizon[j].end) { - changedHorizon[changedHorizon.length - 1].end = boundary.y2; + changedHorizon.at(-1).end = boundary.y2; changedHorizon.push({ start: boundary.y2, end: horizon[j].end, @@ -12343,7 +15703,7 @@ function expandBoundsLTR(width, bounds) { } }
- Array.prototype.splice.apply(horizon, [i, j - i + 1].concat(changedHorizon)); + Array.prototype.splice.apply(horizon, [i, j - i + 1, ...changedHorizon]); }
for (const horizonPart of horizon) { @@ -12365,6 +15725,10 @@ class TextLayerRenderTask { textContentItemsStr, enhanceTextSelection }) { + if (enhanceTextSelection) { + (0, _display_utils.deprecated)("The `enhanceTextSelection` functionality will be removed in the future."); + } + this._textContent = textContent; this._textContentStream = textContentStream; this._container = container; @@ -12432,7 +15796,7 @@ class TextLayerRenderTask { this._container.setAttribute("id", `${items[i].id}`); }
- parent.appendChild(this._container); + parent.append(this._container); } else if (items[i].type === "endMarkedContent") { this._container = this._container.parentNode; } @@ -12491,14 +15855,14 @@ class TextLayerRenderTask { }
if (textDivProperties.hasText) { - this._container.appendChild(textDiv); + this._container.append(textDiv); }
if (textDivProperties.hasEOL) { const br = document.createElement("br"); br.setAttribute("role", "presentation");
- this._container.appendChild(br); + this._container.append(br); } }
@@ -12509,7 +15873,6 @@ class TextLayerRenderTask { const canvas = this._document.createElement("canvas");
canvas.height = canvas.width = DEFAULT_FONT_SIZE; - canvas.mozOpaque = true; this._layoutTextCtx = canvas.getContext("2d", { alpha: false }); @@ -12630,6 +15993,8 @@ class TextLayerRenderTask {
}
+exports.TextLayerRenderTask = TextLayerRenderTask; + function renderTextLayer(renderParameters) { const task = new TextLayerRenderTask({ textContent: renderParameters.textContent, @@ -12647,7 +16012,7 @@ function renderTextLayer(renderParameters) { }
/***/ }), -/* 23 */ +/* 30 */ /***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
@@ -12657,9 +16022,9 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.SVGGraphics = void 0;
-var _util = __w_pdfjs_require__(1); +var _display_utils = __w_pdfjs_require__(4);
-var _display_utils = __w_pdfjs_require__(5); +var _util = __w_pdfjs_require__(1);
var _is_node = __w_pdfjs_require__(3);
@@ -12709,6 +16074,30 @@ var exports = __webpack_exports__; Object.defineProperty(exports, "__esModule", ({ value: true })); +Object.defineProperty(exports, "AnnotationEditorLayer", ({ + enumerable: true, + get: function () { + return _annotation_editor_layer.AnnotationEditorLayer; + } +})); +Object.defineProperty(exports, "AnnotationEditorParamsType", ({ + enumerable: true, + get: function () { + return _util.AnnotationEditorParamsType; + } +})); +Object.defineProperty(exports, "AnnotationEditorType", ({ + enumerable: true, + get: function () { + return _util.AnnotationEditorType; + } +})); +Object.defineProperty(exports, "AnnotationEditorUIManager", ({ + enumerable: true, + get: function () { + return _tools.AnnotationEditorUIManager; + } +})); Object.defineProperty(exports, "AnnotationLayer", ({ enumerable: true, get: function () { @@ -12835,6 +16224,12 @@ Object.defineProperty(exports, "XfaLayer", ({ return _xfa_layer.XfaLayer; } })); +Object.defineProperty(exports, "binarySearchFirstItem", ({ + enumerable: true, + get: function () { + return _display_utils.binarySearchFirstItem; + } +})); Object.defineProperty(exports, "build", ({ enumerable: true, get: function () { @@ -12910,24 +16305,28 @@ Object.defineProperty(exports, "version", ({
var _util = __w_pdfjs_require__(1);
-var _api = __w_pdfjs_require__(4); +var _display_utils = __w_pdfjs_require__(4); + +var _api = __w_pdfjs_require__(6); + +var _annotation_editor_layer = __w_pdfjs_require__(21);
-var _display_utils = __w_pdfjs_require__(5); +var _tools = __w_pdfjs_require__(9);
-var _annotation_layer = __w_pdfjs_require__(19); +var _annotation_layer = __w_pdfjs_require__(26);
-var _worker_options = __w_pdfjs_require__(13); +var _worker_options = __w_pdfjs_require__(15);
var _is_node = __w_pdfjs_require__(3);
-var _text_layer = __w_pdfjs_require__(22); +var _text_layer = __w_pdfjs_require__(29);
-var _svg = __w_pdfjs_require__(23); +var _svg = __w_pdfjs_require__(30);
-var _xfa_layer = __w_pdfjs_require__(21); +var _xfa_layer = __w_pdfjs_require__(28);
-const pdfjsVersion = '2.14.290'; -const pdfjsBuild = '38c82357b'; +const pdfjsVersion = '2.15.305'; +const pdfjsBuild = '2a386eff9'; ; })();
diff --git a/toolkit/components/pdfjs/content/build/pdf.scripting.js b/toolkit/components/pdfjs/content/build/pdf.scripting.js index 4e3d79197ef54..3c2162209ab74 100644 --- a/toolkit/components/pdfjs/content/build/pdf.scripting.js +++ b/toolkit/components/pdfjs/content/build/pdf.scripting.js @@ -29,7 +29,7 @@ exports["pdfjs-dist/build/pdf.scripting"] = factory(); else root.pdfjsScripting = factory(); -})(this, () => { +})(globalThis, () => { return /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -464,7 +464,6 @@ class Field extends _pdf_object.PDFObject { this.required = data.required; this.richText = data.richText; this.richValue = data.richValue; - this.rotation = data.rotation; this.style = data.style; this.submitName = data.submitName; this.textFont = data.textFont; @@ -489,6 +488,7 @@ class Field extends _pdf_object.PDFObject { this._kidIds = data.kidIds || null; this._fieldType = (0, _common.getFieldType)(this._actions); this._siblings = data.siblings || null; + this._rotation = data.rotation || 0; this._globalEval = data.globalEval; this._appObjects = data.appObjects; } @@ -592,6 +592,26 @@ class Field extends _pdf_object.PDFObject { throw new Error("field.page is read-only"); }
+ get rotation() { + return this._rotation; + } + + set rotation(angle) { + angle = Math.floor(angle); + + if (angle % 90 !== 0) { + throw new Error("Invalid rotation: must be a multiple of 90"); + } + + angle %= 360; + + if (angle < 0) { + angle += 360; + } + + this._rotation = angle; + } + get textColor() { return this._textColor; } @@ -1331,7 +1351,8 @@ class ColorConverters { }
static CMYK_HTML(components) { - return this.RGB_HTML(this.CMYK_RGB(components)); + const rgb = this.CMYK_RGB(components).slice(1); + return this.RGB_HTML(rgb); }
static RGB_CMYK([r, g, b]) { @@ -2638,6 +2659,10 @@ class EventDispatcher { }
if (id === "doc") { + if (event.name === "Open") { + this.formatAll(); + } + this._document.obj._dispatchDocEvent(event.name); } else if (id === "page") { this._document.obj._dispatchPageEvent(event.name, baseEvent.actions, baseEvent.pageNumber); @@ -2720,6 +2745,7 @@ class EventDispatcher {
source.obj._send({ id: source.obj._id, + siblings: source.obj._siblings, value, selRange: [selStart, selEnd] }); @@ -2727,12 +2753,14 @@ class EventDispatcher { } else if (!event.willCommit) { source.obj._send({ id: source.obj._id, + siblings: source.obj._siblings, value: savedChange.value, selRange: [savedChange.selStart, savedChange.selEnd] }); } else { source.obj._send({ id: source.obj._id, + siblings: source.obj._siblings, value: "", formattedValue: null, selRange: [0, 0] @@ -2740,6 +2768,22 @@ class EventDispatcher { } }
+ formatAll() { + const event = globalThis.event = new Event({}); + + for (const source of Object.values(this._objects)) { + event.value = source.obj.value; + + if (this.runActions(source, source, event, "Format")) { + source.obj._send({ + id: source.obj._id, + siblings: source.obj._siblings, + formattedValue: event.value?.toString?.() + }); + } + } + } + runValidation(source, event) { const didValidateRun = this.runActions(source, source, event, "Validate");
@@ -2755,6 +2799,7 @@ class EventDispatcher {
source.obj._send({ id: source.obj._id, + siblings: source.obj._siblings, value: savedValue, formattedValue }); @@ -2763,6 +2808,7 @@ class EventDispatcher { } else if (didValidateRun) { source.obj._send({ id: source.obj._id, + siblings: source.obj._siblings, value: "", formattedValue: null, selRange: [0, 0] @@ -2846,6 +2892,7 @@ class EventDispatcher {
target.obj._send({ id: target.obj._id, + siblings: target.obj._siblings, value: savedValue, formattedValue }); @@ -4089,6 +4136,7 @@ class Doc extends _pdf_object.PDFObject {
this._send({ id: field.obj._id, + siblings: field.obj._siblings, value: field.obj.defaultValue, formattedValue: null, selRange: [0, 0] @@ -5020,8 +5068,8 @@ Object.defineProperty(exports, "initSandbox", ({
var _initialization = __w_pdfjs_require__(1);
-const pdfjsVersion = '2.14.290'; -const pdfjsBuild = '38c82357b'; +const pdfjsVersion = '2.15.305'; +const pdfjsBuild = '2a386eff9'; })();
/******/ return __webpack_exports__; diff --git a/toolkit/components/pdfjs/content/build/pdf.worker.js b/toolkit/components/pdfjs/content/build/pdf.worker.js index cec7840a7c1af..da44b8783f29c 100644 --- a/toolkit/components/pdfjs/content/build/pdf.worker.js +++ b/toolkit/components/pdfjs/content/build/pdf.worker.js @@ -29,7 +29,7 @@ exports["pdfjs-dist/build/pdf.worker"] = factory(); else root["pdfjs-dist/build/pdf.worker"] = root.pdfjsWorker = factory(); -})(this, () => { +})(globalThis, () => { return /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -48,11 +48,13 @@ var _util = __w_pdfjs_require__(2);
var _primitives = __w_pdfjs_require__(5);
-var _pdf_manager = __w_pdfjs_require__(6); +var _core_utils = __w_pdfjs_require__(6);
-var _cleanup_helper = __w_pdfjs_require__(67); +var _pdf_manager = __w_pdfjs_require__(8);
-var _writer = __w_pdfjs_require__(73); +var _cleanup_helper = __w_pdfjs_require__(71); + +var _writer = __w_pdfjs_require__(65);
var _is_node = __w_pdfjs_require__(4);
@@ -60,8 +62,6 @@ var _message_handler = __w_pdfjs_require__(102);
var _worker_stream = __w_pdfjs_require__(103);
-var _core_utils = __w_pdfjs_require__(8); - class WorkerTask { constructor(name) { this.name = name; @@ -117,7 +117,7 @@ class WorkerMessageHandler { const WorkerTasks = []; const verbosity = (0, _util.getVerbosityLevel)(); const apiVersion = docParams.apiVersion; - const workerVersion = '2.14.290'; + const workerVersion = '2.15.305';
if (apiVersion !== workerVersion) { throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`); @@ -208,8 +208,8 @@ class WorkerMessageHandler { rangeChunkSize: source.rangeChunkSize }, evaluatorOptions, enableXfa, docBaseUrl);
- for (let i = 0; i < cachedChunks.length; i++) { - newPdfManager.sendProgressiveData(cachedChunks[i]); + for (const chunk of cachedChunks) { + newPdfManager.sendProgressiveData(chunk); }
cachedChunks = []; @@ -464,8 +464,20 @@ class WorkerMessageHandler { filename }) { pdfManager.requestLoadedStream(); + const newAnnotationsByPage = !isPureXfa ? (0, _core_utils.getNewAnnotationsMap)(annotationStorage) : null; const promises = [pdfManager.onLoadedStream(), pdfManager.ensureCatalog("acroForm"), pdfManager.ensureCatalog("acroFormRef"), pdfManager.ensureDoc("xref"), pdfManager.ensureDoc("startXRef")];
+ if (newAnnotationsByPage) { + for (const [pageIndex, annotations] of newAnnotationsByPage) { + promises.push(pdfManager.getPage(pageIndex).then(page => { + const task = new WorkerTask(`Save (editor): page ${pageIndex}`); + return page.saveNewAnnotations(handler, task, annotations).finally(function () { + finishWorkerTask(task); + }); + })); + } + } + if (isPureXfa) { promises.push(pdfManager.serializeXfaData(annotationStorage)); } else { @@ -490,9 +502,7 @@ class WorkerMessageHandler { return stream.bytes; } } else { - for (const ref of refs) { - newRefs = ref.filter(x => x !== null).reduce((a, b) => a.concat(b), newRefs); - } + newRefs = refs.flat(2);
if (newRefs.length === 0) { return stream.bytes; @@ -699,7 +709,7 @@ if (typeof window === "undefined" && !_is_node.isNodeJS && typeof self !== "unde Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.UNSUPPORTED_FEATURES = exports.TextRenderingMode = exports.StreamType = exports.RenderingIntentFlag = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FontType = [...] +exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.UNSUPPORTED_FEATURES = exports.TextRenderingMode = exports.StreamType = exports.RenderingIntentFlag = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.LINE_FACTOR = exports.LINE_DESCENT_FACTOR = exports.InvalidPDFException = exports.ImageKind = exports.IDENTIT [...] exports.arrayByteLength = arrayByteLength; exports.arraysToBytes = arraysToBytes; exports.assert = assert; @@ -732,6 +742,10 @@ const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0]; exports.IDENTITY_MATRIX = IDENTITY_MATRIX; const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0]; exports.FONT_IDENTITY_MATRIX = FONT_IDENTITY_MATRIX; +const LINE_FACTOR = 1.35; +exports.LINE_FACTOR = LINE_FACTOR; +const LINE_DESCENT_FACTOR = 0.35; +exports.LINE_DESCENT_FACTOR = LINE_DESCENT_FACTOR; const RenderingIntentFlag = { ANY: 0x01, DISPLAY: 0x02, @@ -749,6 +763,22 @@ const AnnotationMode = { ENABLE_STORAGE: 3 }; exports.AnnotationMode = AnnotationMode; +const AnnotationEditorPrefix = "pdfjs_internal_editor_"; +exports.AnnotationEditorPrefix = AnnotationEditorPrefix; +const AnnotationEditorType = { + DISABLE: -1, + NONE: 0, + FREETEXT: 3, + INK: 15 +}; +exports.AnnotationEditorType = AnnotationEditorType; +const AnnotationEditorParamsType = { + FREETEXT_SIZE: 0, + FREETEXT_COLOR: 1, + INK_COLOR: 2, + INK_THICKNESS: 3 +}; +exports.AnnotationEditorParamsType = AnnotationEditorParamsType; const PermissionFlag = { PRINT: 0x04, MODIFY_CONTENTS: 0x08, @@ -1767,8 +1797,7 @@ const Name = function NameClosure() { }
static get(name) { - const nameValue = nameCache[name]; - return nameValue ? nameValue : nameCache[name] = new Name(name); + return nameCache[name] || (nameCache[name] = new Name(name)); }
static _clearCache() { @@ -1791,8 +1820,7 @@ const Cmd = function CmdClosure() { }
static get(cmd) { - const cmdValue = cmdCache[cmd]; - return cmdValue ? cmdValue : cmdCache[cmd] = new Cmd(cmd); + return cmdCache[cmd] || (cmdCache[cmd] = new Cmd(cmd)); }
static _clearCache() { @@ -2002,8 +2030,7 @@ const Ref = function RefClosure() {
static get(num, gen) { const key = gen === 0 ? `${num}R` : `${num}R${gen}`; - const refValue = refCache[key]; - return refValue ? refValue : refCache[key] = new Ref(num, gen); + return refCache[key] || (refCache[key] = new Ref(num, gen)); }
static _clearCache() { @@ -2116,1388 +2143,1433 @@ function clearPrimitiveCaches() { Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.NetworkPdfManager = exports.LocalPdfManager = void 0; +exports.XRefParseException = exports.XRefEntryException = exports.ParserEOFException = exports.MissingDataException = exports.DocStats = void 0; +exports.collectActions = collectActions; +exports.encodeToXmlString = encodeToXmlString; +exports.escapePDFName = escapePDFName; +exports.getArrayLookupTableFactory = getArrayLookupTableFactory; +exports.getInheritableProperty = getInheritableProperty; +exports.getLookupTableFactory = getLookupTableFactory; +exports.getNewAnnotationsMap = getNewAnnotationsMap; +exports.isWhiteSpace = isWhiteSpace; +exports.log2 = log2; +exports.numberToString = numberToString; +exports.parseXFAPath = parseXFAPath; +exports.readInt8 = readInt8; +exports.readUint16 = readUint16; +exports.readUint32 = readUint32; +exports.recoverJsURL = recoverJsURL; +exports.toRomanNumerals = toRomanNumerals; +exports.validateCSSFont = validateCSSFont;
var _util = __w_pdfjs_require__(2);
-var _chunked_stream = __w_pdfjs_require__(7); - -var _core_utils = __w_pdfjs_require__(8); - -var _document = __w_pdfjs_require__(11); - -var _stream = __w_pdfjs_require__(10); +var _primitives = __w_pdfjs_require__(5);
-function parseDocBaseUrl(url) { - if (url) { - const absoluteUrl = (0, _util.createValidAbsoluteUrl)(url); +var _base_stream = __w_pdfjs_require__(7);
- if (absoluteUrl) { - return absoluteUrl.href; +function getLookupTableFactory(initializer) { + let lookup; + return function () { + if (initializer) { + lookup = Object.create(null); + initializer(lookup); + initializer = null; }
- (0, _util.warn)(`Invalid absolute docBaseUrl: "${url}".`); - } - - return null; + return lookup; + }; }
-class BasePdfManager { - constructor() { - if (this.constructor === BasePdfManager) { - (0, _util.unreachable)("Cannot initialize BasePdfManager."); - } - } - - get docId() { - return this._docId; - } +function getArrayLookupTableFactory(initializer) { + let lookup; + return function () { + if (initializer) { + let arr = initializer(); + initializer = null; + lookup = Object.create(null);
- get password() { - return this._password; - } + for (let i = 0, ii = arr.length; i < ii; i += 2) { + lookup[arr[i]] = arr[i + 1]; + }
- get docBaseUrl() { - const catalog = this.pdfDocument.catalog; - return (0, _util.shadow)(this, "docBaseUrl", catalog.baseUrl || this._docBaseUrl); - } + arr = null; + }
- onLoadedStream() { - (0, _util.unreachable)("Abstract method `onLoadedStream` called"); - } + return lookup; + }; +}
- ensureDoc(prop, args) { - return this.ensure(this.pdfDocument, prop, args); +class MissingDataException extends _util.BaseException { + constructor(begin, end) { + super(`Missing data [${begin}, ${end})`, "MissingDataException"); + this.begin = begin; + this.end = end; }
- ensureXRef(prop, args) { - return this.ensure(this.pdfDocument.xref, prop, args); - } +}
- ensureCatalog(prop, args) { - return this.ensure(this.pdfDocument.catalog, prop, args); - } +exports.MissingDataException = MissingDataException;
- getPage(pageIndex) { - return this.pdfDocument.getPage(pageIndex); +class ParserEOFException extends _util.BaseException { + constructor(msg) { + super(msg, "ParserEOFException"); }
- fontFallback(id, handler) { - return this.pdfDocument.fontFallback(id, handler); - } +}
- loadXfaFonts(handler, task) { - return this.pdfDocument.loadXfaFonts(handler, task); - } +exports.ParserEOFException = ParserEOFException;
- loadXfaImages() { - return this.pdfDocument.loadXfaImages(); +class XRefEntryException extends _util.BaseException { + constructor(msg) { + super(msg, "XRefEntryException"); }
- serializeXfaData(annotationStorage) { - return this.pdfDocument.serializeXfaData(annotationStorage); - } +}
- cleanup(manuallyTriggered = false) { - return this.pdfDocument.cleanup(manuallyTriggered); - } +exports.XRefEntryException = XRefEntryException;
- async ensure(obj, prop, args) { - (0, _util.unreachable)("Abstract method `ensure` called"); +class XRefParseException extends _util.BaseException { + constructor(msg) { + super(msg, "XRefParseException"); }
- requestRange(begin, end) { - (0, _util.unreachable)("Abstract method `requestRange` called"); - } +}
- requestLoadedStream() { - (0, _util.unreachable)("Abstract method `requestLoadedStream` called"); - } +exports.XRefParseException = XRefParseException;
- sendProgressiveData(chunk) { - (0, _util.unreachable)("Abstract method `sendProgressiveData` called"); +class DocStats { + constructor(handler) { + this._handler = handler; + this._streamTypes = new Set(); + this._fontTypes = new Set(); }
- updatePassword(password) { - this._password = password; - } + _send() { + const streamTypes = Object.create(null), + fontTypes = Object.create(null);
- terminate(reason) { - (0, _util.unreachable)("Abstract method `terminate` called"); - } + for (const type of this._streamTypes) { + streamTypes[type] = true; + }
-} + for (const type of this._fontTypes) { + fontTypes[type] = true; + }
-class LocalPdfManager extends BasePdfManager { - constructor(docId, data, password, msgHandler, evaluatorOptions, enableXfa, docBaseUrl) { - super(); - this._docId = docId; - this._password = password; - this._docBaseUrl = parseDocBaseUrl(docBaseUrl); - this.msgHandler = msgHandler; - this.evaluatorOptions = evaluatorOptions; - this.enableXfa = enableXfa; - const stream = new _stream.Stream(data); - this.pdfDocument = new _document.PDFDocument(this, stream); - this._loadedStreamPromise = Promise.resolve(stream); + this._handler.send("DocStats", { + streamTypes, + fontTypes + }); }
- async ensure(obj, prop, args) { - const value = obj[prop]; - - if (typeof value === "function") { - return value.apply(obj, args); + addStreamType(type) { + if (this._streamTypes.has(type)) { + return; }
- return value; - } + this._streamTypes.add(type);
- requestRange(begin, end) { - return Promise.resolve(); + this._send(); }
- requestLoadedStream() {} + addFontType(type) { + if (this._fontTypes.has(type)) { + return; + }
- onLoadedStream() { - return this._loadedStreamPromise; - } + this._fontTypes.add(type);
- terminate(reason) {} + this._send(); + }
}
-exports.LocalPdfManager = LocalPdfManager; +exports.DocStats = DocStats;
-class NetworkPdfManager extends BasePdfManager { - constructor(docId, pdfNetworkStream, args, evaluatorOptions, enableXfa, docBaseUrl) { - super(); - this._docId = docId; - this._password = args.password; - this._docBaseUrl = parseDocBaseUrl(docBaseUrl); - this.msgHandler = args.msgHandler; - this.evaluatorOptions = evaluatorOptions; - this.enableXfa = enableXfa; - this.streamManager = new _chunked_stream.ChunkedStreamManager(pdfNetworkStream, { - msgHandler: args.msgHandler, - length: args.length, - disableAutoFetch: args.disableAutoFetch, - rangeChunkSize: args.rangeChunkSize - }); - this.pdfDocument = new _document.PDFDocument(this, this.streamManager.getStream()); - } +function getInheritableProperty({ + dict, + key, + getArray = false, + stopWhenFound = true +}) { + let values; + const visited = new _primitives.RefSet();
- async ensure(obj, prop, args) { - try { - const value = obj[prop]; + while (dict instanceof _primitives.Dict && !(dict.objId && visited.has(dict.objId))) { + if (dict.objId) { + visited.put(dict.objId); + }
- if (typeof value === "function") { - return value.apply(obj, args); + const value = getArray ? dict.getArray(key) : dict.get(key); + + if (value !== undefined) { + if (stopWhenFound) { + return value; }
- return value; - } catch (ex) { - if (!(ex instanceof _core_utils.MissingDataException)) { - throw ex; + if (!values) { + values = []; }
- await this.requestRange(ex.begin, ex.end); - return this.ensure(obj, prop, args); + values.push(value); } - }
- requestRange(begin, end) { - return this.streamManager.requestRange(begin, end); + dict = dict.get("Parent"); }
- requestLoadedStream() { - this.streamManager.requestAllChunks(); - } + return values; +}
- sendProgressiveData(chunk) { - this.streamManager.onReceiveData({ - chunk - }); - } +const ROMAN_NUMBER_MAP = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"];
- onLoadedStream() { - return this.streamManager.onLoadedStream(); - } +function toRomanNumerals(number, lowerCase = false) { + (0, _util.assert)(Number.isInteger(number) && number > 0, "The number should be a positive integer."); + const romanBuf = []; + let pos;
- terminate(reason) { - this.streamManager.abort(reason); + while (number >= 1000) { + number -= 1000; + romanBuf.push("M"); }
+ pos = number / 100 | 0; + number %= 100; + romanBuf.push(ROMAN_NUMBER_MAP[pos]); + pos = number / 10 | 0; + number %= 10; + romanBuf.push(ROMAN_NUMBER_MAP[10 + pos]); + romanBuf.push(ROMAN_NUMBER_MAP[20 + number]); + const romanStr = romanBuf.join(""); + return lowerCase ? romanStr.toLowerCase() : romanStr; }
-exports.NetworkPdfManager = NetworkPdfManager; +function log2(x) { + if (x <= 0) { + return 0; + }
-/***/ }), -/* 7 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + return Math.ceil(Math.log2(x)); +}
+function readInt8(data, offset) { + return data[offset] << 24 >> 24; +}
+function readUint16(data, offset) { + return data[offset] << 8 | data[offset + 1]; +}
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.ChunkedStreamManager = exports.ChunkedStream = void 0; +function readUint32(data, offset) { + return (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]) >>> 0; +}
-var _util = __w_pdfjs_require__(2); +function isWhiteSpace(ch) { + return ch === 0x20 || ch === 0x09 || ch === 0x0d || ch === 0x0a; +}
-var _core_utils = __w_pdfjs_require__(8); +function parseXFAPath(path) { + const positionPattern = /(.+)[(\d+)]$/; + return path.split(".").map(component => { + const m = component.match(positionPattern);
-var _stream = __w_pdfjs_require__(10); + if (m) { + return { + name: m[1], + pos: parseInt(m[2], 10) + }; + }
-class ChunkedStream extends _stream.Stream { - constructor(length, chunkSize, manager) { - super(new Uint8Array(length), 0, length, null); - this.chunkSize = chunkSize; - this._loadedChunks = new Set(); - this.numChunks = Math.ceil(length / chunkSize); - this.manager = manager; - this.progressiveDataLength = 0; - this.lastSuccessfulEnsureByteChunk = -1; - } + return { + name: component, + pos: 0 + }; + }); +}
- getMissingChunks() { - const chunks = []; +function escapePDFName(str) { + const buffer = []; + let start = 0;
- for (let chunk = 0, n = this.numChunks; chunk < n; ++chunk) { - if (!this._loadedChunks.has(chunk)) { - chunks.push(chunk); + for (let i = 0, ii = str.length; i < ii; i++) { + const char = str.charCodeAt(i); + + if (char < 0x21 || char > 0x7e || char === 0x23 || char === 0x28 || char === 0x29 || char === 0x3c || char === 0x3e || char === 0x5b || char === 0x5d || char === 0x7b || char === 0x7d || char === 0x2f || char === 0x25) { + if (start < i) { + buffer.push(str.substring(start, i)); } - }
- return chunks; + buffer.push(`#${char.toString(16)}`); + start = i + 1; + } }
- get numChunksLoaded() { - return this._loadedChunks.size; + if (buffer.length === 0) { + return str; }
- get isDataLoaded() { - return this.numChunksLoaded === this.numChunks; + if (start < str.length) { + buffer.push(str.substring(start, str.length)); }
- onReceiveData(begin, chunk) { - const chunkSize = this.chunkSize; - - if (begin % chunkSize !== 0) { - throw new Error(`Bad begin offset: ${begin}`); - } - - const end = begin + chunk.byteLength; - - if (end % chunkSize !== 0 && end !== this.bytes.length) { - throw new Error(`Bad end offset: ${end}`); - } - - this.bytes.set(new Uint8Array(chunk), begin); - const beginChunk = Math.floor(begin / chunkSize); - const endChunk = Math.floor((end - 1) / chunkSize) + 1; + return buffer.join(""); +}
- for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) { - this._loadedChunks.add(curChunk); - } +function _collectJS(entry, xref, list, parents) { + if (!entry) { + return; }
- onReceiveProgressiveData(data) { - let position = this.progressiveDataLength; - const beginChunk = Math.floor(position / this.chunkSize); - this.bytes.set(new Uint8Array(data), position); - position += data.byteLength; - this.progressiveDataLength = position; - const endChunk = position >= this.end ? this.numChunks : Math.floor(position / this.chunkSize); + let parent = null;
- for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) { - this._loadedChunks.add(curChunk); + if (entry instanceof _primitives.Ref) { + if (parents.has(entry)) { + return; } + + parent = entry; + parents.put(parent); + entry = xref.fetch(entry); }
- ensureByte(pos) { - if (pos < this.progressiveDataLength) { - return; + if (Array.isArray(entry)) { + for (const element of entry) { + _collectJS(element, xref, list, parents); } + } else if (entry instanceof _primitives.Dict) { + if ((0, _primitives.isName)(entry.get("S"), "JavaScript")) { + const js = entry.get("JS"); + let code;
- const chunk = Math.floor(pos / this.chunkSize); + if (js instanceof _base_stream.BaseStream) { + code = js.getString(); + } else if (typeof js === "string") { + code = js; + }
- if (chunk > this.numChunks) { - return; - } + code = code && (0, _util.stringToPDFString)(code).replace(/\u0000/g, "");
- if (chunk === this.lastSuccessfulEnsureByteChunk) { - return; + if (code) { + list.push(code); + } }
- if (!this._loadedChunks.has(chunk)) { - throw new _core_utils.MissingDataException(pos, pos + 1); - } + _collectJS(entry.getRaw("Next"), xref, list, parents); + }
- this.lastSuccessfulEnsureByteChunk = chunk; + if (parent) { + parents.remove(parent); } +}
- ensureRange(begin, end) { - if (begin >= end) { - return; - } +function collectActions(xref, dict, eventType) { + const actions = Object.create(null); + const additionalActionsDicts = getInheritableProperty({ + dict, + key: "AA", + stopWhenFound: false + });
- if (end <= this.progressiveDataLength) { - return; - } + if (additionalActionsDicts) { + for (let i = additionalActionsDicts.length - 1; i >= 0; i--) { + const additionalActions = additionalActionsDicts[i];
- const beginChunk = Math.floor(begin / this.chunkSize); + if (!(additionalActions instanceof _primitives.Dict)) { + continue; + }
- if (beginChunk > this.numChunks) { - return; - } + for (const key of additionalActions.getKeys()) { + const action = eventType[key];
- const endChunk = Math.min(Math.floor((end - 1) / this.chunkSize) + 1, this.numChunks); + if (!action) { + continue; + }
- for (let chunk = beginChunk; chunk < endChunk; ++chunk) { - if (!this._loadedChunks.has(chunk)) { - throw new _core_utils.MissingDataException(begin, end); + const actionDict = additionalActions.getRaw(key); + const parents = new _primitives.RefSet(); + const list = []; + + _collectJS(actionDict, xref, list, parents); + + if (list.length > 0) { + actions[action] = list; + } } } }
- nextEmptyChunk(beginChunk) { - const numChunks = this.numChunks; + if (dict.has("A")) { + const actionDict = dict.get("A"); + const parents = new _primitives.RefSet(); + const list = [];
- for (let i = 0; i < numChunks; ++i) { - const chunk = (beginChunk + i) % numChunks; + _collectJS(actionDict, xref, list, parents);
- if (!this._loadedChunks.has(chunk)) { - return chunk; - } + if (list.length > 0) { + actions.Action = list; } - - return null; - } - - hasChunk(chunk) { - return this._loadedChunks.has(chunk); }
- getByte() { - const pos = this.pos; + return (0, _util.objectSize)(actions) > 0 ? actions : null; +}
- if (pos >= this.end) { - return -1; - } +const XMLEntities = { + 0x3c: "<", + 0x3e: ">", + 0x26: "&", + 0x22: """, + 0x27: "'" +};
- if (pos >= this.progressiveDataLength) { - this.ensureByte(pos); - } +function encodeToXmlString(str) { + const buffer = []; + let start = 0;
- return this.bytes[this.pos++]; - } + for (let i = 0, ii = str.length; i < ii; i++) { + const char = str.codePointAt(i);
- getBytes(length) { - const bytes = this.bytes; - const pos = this.pos; - const strEnd = this.end; + if (0x20 <= char && char <= 0x7e) { + const entity = XMLEntities[char];
- if (!length) { - if (strEnd > this.progressiveDataLength) { - this.ensureRange(pos, strEnd); + if (entity) { + if (start < i) { + buffer.push(str.substring(start, i)); + } + + buffer.push(entity); + start = i + 1; + } + } else { + if (start < i) { + buffer.push(str.substring(start, i)); }
- return bytes.subarray(pos, strEnd); - } + buffer.push(`&#x${char.toString(16).toUpperCase()};`);
- let end = pos + length; + if (char > 0xd7ff && (char < 0xe000 || char > 0xfffd)) { + i++; + }
- if (end > strEnd) { - end = strEnd; + start = i + 1; } + }
- if (end > this.progressiveDataLength) { - this.ensureRange(pos, end); - } + if (buffer.length === 0) { + return str; + }
- this.pos = end; - return bytes.subarray(pos, end); + if (start < str.length) { + buffer.push(str.substring(start, str.length)); }
- getByteRange(begin, end) { - if (begin < 0) { - begin = 0; - } + return buffer.join(""); +}
- if (end > this.end) { - end = this.end; - } +function validateCSSFont(cssFontInfo) { + const DEFAULT_CSS_FONT_OBLIQUE = "14"; + const DEFAULT_CSS_FONT_WEIGHT = "400"; + const CSS_FONT_WEIGHT_VALUES = new Set(["100", "200", "300", "400", "500", "600", "700", "800", "900", "1000", "normal", "bold", "bolder", "lighter"]); + const { + fontFamily, + fontWeight, + italicAngle + } = cssFontInfo;
- if (end > this.progressiveDataLength) { - this.ensureRange(begin, end); + if (/^".*"$/.test(fontFamily)) { + if (/[^\]"/.test(fontFamily.slice(1, fontFamily.length - 1))) { + (0, _util.warn)(`XFA - FontFamily contains some unescaped ": ${fontFamily}.`); + return false; } - - return this.bytes.subarray(begin, end); - } - - makeSubStream(start, length, dict = null) { - if (length) { - if (start + length > this.progressiveDataLength) { - this.ensureRange(start, start + length); - } - } else { - if (start >= this.progressiveDataLength) { - this.ensureByte(start); + } else if (/^'.*'$/.test(fontFamily)) { + if (/[^\]'/.test(fontFamily.slice(1, fontFamily.length - 1))) { + (0, _util.warn)(`XFA - FontFamily contains some unescaped ': ${fontFamily}.`); + return false; + } + } else { + for (const ident of fontFamily.split(/[ \t]+/)) { + if (/^(\d|(-(\d|-)))/.test(ident) || !/^[\w-\]+$/.test(ident)) { + (0, _util.warn)(`XFA - FontFamily contains some invalid <custom-ident>: ${fontFamily}.`); + return false; } } + }
- function ChunkedStreamSubstream() {} + const weight = fontWeight ? fontWeight.toString() : ""; + cssFontInfo.fontWeight = CSS_FONT_WEIGHT_VALUES.has(weight) ? weight : DEFAULT_CSS_FONT_WEIGHT; + const angle = parseFloat(italicAngle); + cssFontInfo.italicAngle = isNaN(angle) || angle < -90 || angle > 90 ? DEFAULT_CSS_FONT_OBLIQUE : italicAngle.toString(); + return true; +}
- ChunkedStreamSubstream.prototype = Object.create(this); +function recoverJsURL(str) { + const URL_OPEN_METHODS = ["app.launchURL", "window.open", "xfa.host.gotoURL"]; + const regex = new RegExp("^\s*(" + URL_OPEN_METHODS.join("|").split(".").join("\.") + ")\((?:'|")([^'"]*)(?:'|")(?:,\s*(\w+)\)|\))", "i"); + const jsUrl = regex.exec(str);
- ChunkedStreamSubstream.prototype.getMissingChunks = function () { - const chunkSize = this.chunkSize; - const beginChunk = Math.floor(this.start / chunkSize); - const endChunk = Math.floor((this.end - 1) / chunkSize) + 1; - const missingChunks = []; + if (jsUrl && jsUrl[2]) { + const url = jsUrl[2]; + let newWindow = false;
- for (let chunk = beginChunk; chunk < endChunk; ++chunk) { - if (!this._loadedChunks.has(chunk)) { - missingChunks.push(chunk); - } - } + if (jsUrl[3] === "true" && jsUrl[1] === "app.launchURL") { + newWindow = true; + }
- return missingChunks; + return { + url, + newWindow }; - - Object.defineProperty(ChunkedStreamSubstream.prototype, "isDataLoaded", { - get() { - if (this.numChunksLoaded === this.numChunks) { - return true; - } - - return this.getMissingChunks().length === 0; - }, - - configurable: true - }); - const subStream = new ChunkedStreamSubstream(); - subStream.pos = subStream.start = start; - subStream.end = start + length || this.end; - subStream.dict = dict; - return subStream; - } - - getBaseStreams() { - return [this]; }
+ return null; }
-exports.ChunkedStream = ChunkedStream; - -class ChunkedStreamManager { - constructor(pdfNetworkStream, args) { - this.length = args.length; - this.chunkSize = args.rangeChunkSize; - this.stream = new ChunkedStream(this.length, this.chunkSize, this); - this.pdfNetworkStream = pdfNetworkStream; - this.disableAutoFetch = args.disableAutoFetch; - this.msgHandler = args.msgHandler; - this.currRequestId = 0; - this._chunksNeededByRequest = new Map(); - this._requestsByChunk = new Map(); - this._promisesByRequest = new Map(); - this.progressiveDataLength = 0; - this.aborted = false; - this._loadedStreamCapability = (0, _util.createPromiseCapability)(); - } - - onLoadedStream() { - return this._loadedStreamCapability.promise; +function numberToString(value) { + if (Number.isInteger(value)) { + return value.toString(); }
- sendRequest(begin, end) { - const rangeReader = this.pdfNetworkStream.getRangeReader(begin, end); - - if (!rangeReader.isStreamingSupported) { - rangeReader.onProgress = this.onProgress.bind(this); - } - - let chunks = [], - loaded = 0; - return new Promise((resolve, reject) => { - const readChunk = chunk => { - try { - if (!chunk.done) { - const data = chunk.value; - chunks.push(data); - loaded += (0, _util.arrayByteLength)(data); - - if (rangeReader.isStreamingSupported) { - this.onProgress({ - loaded - }); - } - - rangeReader.read().then(readChunk, reject); - return; - } - - const chunkData = (0, _util.arraysToBytes)(chunks); - chunks = null; - resolve(chunkData); - } catch (e) { - reject(e); - } - }; - - rangeReader.read().then(readChunk, reject); - }).then(data => { - if (this.aborted) { - return; - } + const roundedValue = Math.round(value * 100);
- this.onReceiveData({ - chunk: data, - begin - }); - }); + if (roundedValue % 100 === 0) { + return (roundedValue / 100).toString(); }
- requestAllChunks() { - const missingChunks = this.stream.getMissingChunks(); + if (roundedValue % 10 === 0) { + return value.toFixed(1); + }
- this._requestChunks(missingChunks); + return value.toFixed(2); +}
- return this._loadedStreamCapability.promise; +function getNewAnnotationsMap(annotationStorage) { + if (!annotationStorage) { + return null; }
- _requestChunks(chunks) { - const requestId = this.currRequestId++; - const chunksNeeded = new Set(); - - this._chunksNeededByRequest.set(requestId, chunksNeeded); + const newAnnotationsByPage = new Map();
- for (const chunk of chunks) { - if (!this.stream.hasChunk(chunk)) { - chunksNeeded.add(chunk); - } + for (const [key, value] of annotationStorage) { + if (!key.startsWith(_util.AnnotationEditorPrefix)) { + continue; }
- if (chunksNeeded.size === 0) { - return Promise.resolve(); + let annotations = newAnnotationsByPage.get(value.pageIndex); + + if (!annotations) { + annotations = []; + newAnnotationsByPage.set(value.pageIndex, annotations); }
- const capability = (0, _util.createPromiseCapability)(); + annotations.push(value); + }
- this._promisesByRequest.set(requestId, capability); + return newAnnotationsByPage.size > 0 ? newAnnotationsByPage : null; +}
- const chunksToRequest = []; +/***/ }), +/* 7 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- for (const chunk of chunksNeeded) { - let requestIds = this._requestsByChunk.get(chunk);
- if (!requestIds) { - requestIds = [];
- this._requestsByChunk.set(chunk, requestIds); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.BaseStream = void 0;
- chunksToRequest.push(chunk); - } +var _util = __w_pdfjs_require__(2);
- requestIds.push(requestId); +class BaseStream { + constructor() { + if (this.constructor === BaseStream) { + (0, _util.unreachable)("Cannot initialize BaseStream."); } + }
- if (chunksToRequest.length > 0) { - const groupedChunksToRequest = this.groupChunks(chunksToRequest); + get length() { + (0, _util.unreachable)("Abstract getter `length` accessed"); + }
- for (const groupedChunk of groupedChunksToRequest) { - const begin = groupedChunk.beginChunk * this.chunkSize; - const end = Math.min(groupedChunk.endChunk * this.chunkSize, this.length); - this.sendRequest(begin, end).catch(capability.reject); - } - } + get isEmpty() { + (0, _util.unreachable)("Abstract getter `isEmpty` accessed"); + }
- return capability.promise.catch(reason => { - if (this.aborted) { - return; - } + get isDataLoaded() { + return (0, _util.shadow)(this, "isDataLoaded", true); + }
- throw reason; - }); + getByte() { + (0, _util.unreachable)("Abstract method `getByte` called"); }
- getStream() { - return this.stream; + getBytes(length) { + (0, _util.unreachable)("Abstract method `getBytes` called"); }
- requestRange(begin, end) { - end = Math.min(end, this.length); - const beginChunk = this.getBeginChunk(begin); - const endChunk = this.getEndChunk(end); - const chunks = []; + peekByte() { + const peekedByte = this.getByte();
- for (let chunk = beginChunk; chunk < endChunk; ++chunk) { - chunks.push(chunk); + if (peekedByte !== -1) { + this.pos--; }
- return this._requestChunks(chunks); + return peekedByte; }
- requestRanges(ranges = []) { - const chunksToRequest = []; + peekBytes(length) { + const bytes = this.getBytes(length); + this.pos -= bytes.length; + return bytes; + }
- for (const range of ranges) { - const beginChunk = this.getBeginChunk(range.begin); - const endChunk = this.getEndChunk(range.end); + getUint16() { + const b0 = this.getByte(); + const b1 = this.getByte();
- for (let chunk = beginChunk; chunk < endChunk; ++chunk) { - if (!chunksToRequest.includes(chunk)) { - chunksToRequest.push(chunk); - } - } + if (b0 === -1 || b1 === -1) { + return -1; }
- chunksToRequest.sort(function (a, b) { - return a - b; - }); - return this._requestChunks(chunksToRequest); + return (b0 << 8) + b1; }
- groupChunks(chunks) { - const groupedChunks = []; - let beginChunk = -1; - let prevChunk = -1; - - for (let i = 0, ii = chunks.length; i < ii; ++i) { - const chunk = chunks[i]; - - if (beginChunk < 0) { - beginChunk = chunk; - } + getInt32() { + const b0 = this.getByte(); + const b1 = this.getByte(); + const b2 = this.getByte(); + const b3 = this.getByte(); + return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; + }
- if (prevChunk >= 0 && prevChunk + 1 !== chunk) { - groupedChunks.push({ - beginChunk, - endChunk: prevChunk + 1 - }); - beginChunk = chunk; - } + getByteRange(begin, end) { + (0, _util.unreachable)("Abstract method `getByteRange` called"); + }
- if (i + 1 === chunks.length) { - groupedChunks.push({ - beginChunk, - endChunk: chunk + 1 - }); - } + getString(length) { + return (0, _util.bytesToString)(this.getBytes(length)); + }
- prevChunk = chunk; - } + skip(n) { + this.pos += n || 1; + }
- return groupedChunks; + reset() { + (0, _util.unreachable)("Abstract method `reset` called"); }
- onProgress(args) { - this.msgHandler.send("DocProgress", { - loaded: this.stream.numChunksLoaded * this.chunkSize + args.loaded, - total: this.length - }); + moveStart() { + (0, _util.unreachable)("Abstract method `moveStart` called"); }
- onReceiveData(args) { - const chunk = args.chunk; - const isProgressive = args.begin === undefined; - const begin = isProgressive ? this.progressiveDataLength : args.begin; - const end = begin + chunk.byteLength; - const beginChunk = Math.floor(begin / this.chunkSize); - const endChunk = end < this.length ? Math.floor(end / this.chunkSize) : Math.ceil(end / this.chunkSize); + makeSubStream(start, length, dict = null) { + (0, _util.unreachable)("Abstract method `makeSubStream` called"); + }
- if (isProgressive) { - this.stream.onReceiveProgressiveData(chunk); - this.progressiveDataLength = end; - } else { - this.stream.onReceiveData(begin, chunk); - } + getBaseStreams() { + return null; + }
- if (this.stream.isDataLoaded) { - this._loadedStreamCapability.resolve(this.stream); - } +}
- const loadedRequests = []; +exports.BaseStream = BaseStream;
- for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) { - const requestIds = this._requestsByChunk.get(curChunk); +/***/ }), +/* 8 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- if (!requestIds) { - continue; - }
- this._requestsByChunk.delete(curChunk);
- for (const requestId of requestIds) { - const chunksNeeded = this._chunksNeededByRequest.get(requestId); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.NetworkPdfManager = exports.LocalPdfManager = void 0;
- if (chunksNeeded.has(curChunk)) { - chunksNeeded.delete(curChunk); - } +var _util = __w_pdfjs_require__(2);
- if (chunksNeeded.size > 0) { - continue; - } +var _chunked_stream = __w_pdfjs_require__(9);
- loadedRequests.push(requestId); - } - } +var _core_utils = __w_pdfjs_require__(6);
- if (!this.disableAutoFetch && this._requestsByChunk.size === 0) { - let nextEmptyChunk; +var _document = __w_pdfjs_require__(11);
- if (this.stream.numChunksLoaded === 1) { - const lastChunk = this.stream.numChunks - 1; +var _stream = __w_pdfjs_require__(10);
- if (!this.stream.hasChunk(lastChunk)) { - nextEmptyChunk = lastChunk; - } - } else { - nextEmptyChunk = this.stream.nextEmptyChunk(endChunk); - } +function parseDocBaseUrl(url) { + if (url) { + const absoluteUrl = (0, _util.createValidAbsoluteUrl)(url);
- if (Number.isInteger(nextEmptyChunk)) { - this._requestChunks([nextEmptyChunk]); - } + if (absoluteUrl) { + return absoluteUrl.href; }
- for (const requestId of loadedRequests) { - const capability = this._promisesByRequest.get(requestId); + (0, _util.warn)(`Invalid absolute docBaseUrl: "${url}".`); + }
- this._promisesByRequest.delete(requestId); + return null; +}
- capability.resolve(); +class BasePdfManager { + constructor() { + if (this.constructor === BasePdfManager) { + (0, _util.unreachable)("Cannot initialize BasePdfManager."); } - - this.msgHandler.send("DocProgress", { - loaded: this.stream.numChunksLoaded * this.chunkSize, - total: this.length - }); }
- onError(err) { - this._loadedStreamCapability.reject(err); + get docId() { + return this._docId; }
- getBeginChunk(begin) { - return Math.floor(begin / this.chunkSize); + get password() { + return this._password; }
- getEndChunk(end) { - return Math.floor((end - 1) / this.chunkSize) + 1; + get docBaseUrl() { + const catalog = this.pdfDocument.catalog; + return (0, _util.shadow)(this, "docBaseUrl", catalog.baseUrl || this._docBaseUrl); }
- abort(reason) { - this.aborted = true; + onLoadedStream() { + (0, _util.unreachable)("Abstract method `onLoadedStream` called"); + }
- if (this.pdfNetworkStream) { - this.pdfNetworkStream.cancelAllRequests(reason); - } - - for (const capability of this._promisesByRequest.values()) { - capability.reject(reason); - } + ensureDoc(prop, args) { + return this.ensure(this.pdfDocument, prop, args); }
-} - -exports.ChunkedStreamManager = ChunkedStreamManager; - -/***/ }), -/* 8 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + ensureXRef(prop, args) { + return this.ensure(this.pdfDocument.xref, prop, args); + }
+ ensureCatalog(prop, args) { + return this.ensure(this.pdfDocument.catalog, prop, args); + }
+ getPage(pageIndex) { + return this.pdfDocument.getPage(pageIndex); + }
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.XRefParseException = exports.XRefEntryException = exports.ParserEOFException = exports.MissingDataException = exports.DocStats = void 0; -exports.collectActions = collectActions; -exports.encodeToXmlString = encodeToXmlString; -exports.escapePDFName = escapePDFName; -exports.getArrayLookupTableFactory = getArrayLookupTableFactory; -exports.getInheritableProperty = getInheritableProperty; -exports.getLookupTableFactory = getLookupTableFactory; -exports.isWhiteSpace = isWhiteSpace; -exports.log2 = log2; -exports.parseXFAPath = parseXFAPath; -exports.readInt8 = readInt8; -exports.readUint16 = readUint16; -exports.readUint32 = readUint32; -exports.recoverJsURL = recoverJsURL; -exports.toRomanNumerals = toRomanNumerals; -exports.validateCSSFont = validateCSSFont; + fontFallback(id, handler) { + return this.pdfDocument.fontFallback(id, handler); + }
-var _util = __w_pdfjs_require__(2); + loadXfaFonts(handler, task) { + return this.pdfDocument.loadXfaFonts(handler, task); + }
-var _primitives = __w_pdfjs_require__(5); + loadXfaImages() { + return this.pdfDocument.loadXfaImages(); + }
-var _base_stream = __w_pdfjs_require__(9); + serializeXfaData(annotationStorage) { + return this.pdfDocument.serializeXfaData(annotationStorage); + }
-function getLookupTableFactory(initializer) { - let lookup; - return function () { - if (initializer) { - lookup = Object.create(null); - initializer(lookup); - initializer = null; - } + cleanup(manuallyTriggered = false) { + return this.pdfDocument.cleanup(manuallyTriggered); + }
- return lookup; - }; -} + async ensure(obj, prop, args) { + (0, _util.unreachable)("Abstract method `ensure` called"); + }
-function getArrayLookupTableFactory(initializer) { - let lookup; - return function () { - if (initializer) { - let arr = initializer(); - initializer = null; - lookup = Object.create(null); + requestRange(begin, end) { + (0, _util.unreachable)("Abstract method `requestRange` called"); + }
- for (let i = 0, ii = arr.length; i < ii; i += 2) { - lookup[arr[i]] = arr[i + 1]; - } + requestLoadedStream() { + (0, _util.unreachable)("Abstract method `requestLoadedStream` called"); + }
- arr = null; - } + sendProgressiveData(chunk) { + (0, _util.unreachable)("Abstract method `sendProgressiveData` called"); + }
- return lookup; - }; -} + updatePassword(password) { + this._password = password; + }
-class MissingDataException extends _util.BaseException { - constructor(begin, end) { - super(`Missing data [${begin}, ${end})`, "MissingDataException"); - this.begin = begin; - this.end = end; + terminate(reason) { + (0, _util.unreachable)("Abstract method `terminate` called"); }
}
-exports.MissingDataException = MissingDataException; - -class ParserEOFException extends _util.BaseException { - constructor(msg) { - super(msg, "ParserEOFException"); +class LocalPdfManager extends BasePdfManager { + constructor(docId, data, password, msgHandler, evaluatorOptions, enableXfa, docBaseUrl) { + super(); + this._docId = docId; + this._password = password; + this._docBaseUrl = parseDocBaseUrl(docBaseUrl); + this.msgHandler = msgHandler; + this.evaluatorOptions = evaluatorOptions; + this.enableXfa = enableXfa; + const stream = new _stream.Stream(data); + this.pdfDocument = new _document.PDFDocument(this, stream); + this._loadedStreamPromise = Promise.resolve(stream); }
-} + async ensure(obj, prop, args) { + const value = obj[prop];
-exports.ParserEOFException = ParserEOFException; + if (typeof value === "function") { + return value.apply(obj, args); + }
-class XRefEntryException extends _util.BaseException { - constructor(msg) { - super(msg, "XRefEntryException"); + return value; }
-} + requestRange(begin, end) { + return Promise.resolve(); + }
-exports.XRefEntryException = XRefEntryException; + requestLoadedStream() {}
-class XRefParseException extends _util.BaseException { - constructor(msg) { - super(msg, "XRefParseException"); + onLoadedStream() { + return this._loadedStreamPromise; }
+ terminate(reason) {} + }
-exports.XRefParseException = XRefParseException; +exports.LocalPdfManager = LocalPdfManager;
-class DocStats { - constructor(handler) { - this._handler = handler; - this._streamTypes = new Set(); - this._fontTypes = new Set(); +class NetworkPdfManager extends BasePdfManager { + constructor(docId, pdfNetworkStream, args, evaluatorOptions, enableXfa, docBaseUrl) { + super(); + this._docId = docId; + this._password = args.password; + this._docBaseUrl = parseDocBaseUrl(docBaseUrl); + this.msgHandler = args.msgHandler; + this.evaluatorOptions = evaluatorOptions; + this.enableXfa = enableXfa; + this.streamManager = new _chunked_stream.ChunkedStreamManager(pdfNetworkStream, { + msgHandler: args.msgHandler, + length: args.length, + disableAutoFetch: args.disableAutoFetch, + rangeChunkSize: args.rangeChunkSize + }); + this.pdfDocument = new _document.PDFDocument(this, this.streamManager.getStream()); }
- _send() { - const streamTypes = Object.create(null), - fontTypes = Object.create(null); - - for (const type of this._streamTypes) { - streamTypes[type] = true; - } + async ensure(obj, prop, args) { + try { + const value = obj[prop];
- for (const type of this._fontTypes) { - fontTypes[type] = true; - } + if (typeof value === "function") { + return value.apply(obj, args); + }
- this._handler.send("DocStats", { - streamTypes, - fontTypes - }); - } + return value; + } catch (ex) { + if (!(ex instanceof _core_utils.MissingDataException)) { + throw ex; + }
- addStreamType(type) { - if (this._streamTypes.has(type)) { - return; + await this.requestRange(ex.begin, ex.end); + return this.ensure(obj, prop, args); } + }
- this._streamTypes.add(type); + requestRange(begin, end) { + return this.streamManager.requestRange(begin, end); + }
- this._send(); + requestLoadedStream() { + this.streamManager.requestAllChunks(); }
- addFontType(type) { - if (this._fontTypes.has(type)) { - return; - } + sendProgressiveData(chunk) { + this.streamManager.onReceiveData({ + chunk + }); + }
- this._fontTypes.add(type); + onLoadedStream() { + return this.streamManager.onLoadedStream(); + }
- this._send(); + terminate(reason) { + this.streamManager.abort(reason); }
}
-exports.DocStats = DocStats; +exports.NetworkPdfManager = NetworkPdfManager;
-function getInheritableProperty({ - dict, - key, - getArray = false, - stopWhenFound = true -}) { - let values; - const visited = new _primitives.RefSet(); +/***/ }), +/* 9 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- while (dict instanceof _primitives.Dict && !(dict.objId && visited.has(dict.objId))) { - if (dict.objId) { - visited.put(dict.objId); - }
- const value = getArray ? dict.getArray(key) : dict.get(key);
- if (value !== undefined) { - if (stopWhenFound) { - return value; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ChunkedStreamManager = exports.ChunkedStream = void 0;
- if (!values) { - values = []; - } +var _util = __w_pdfjs_require__(2);
- values.push(value); - } +var _core_utils = __w_pdfjs_require__(6);
- dict = dict.get("Parent"); - } +var _stream = __w_pdfjs_require__(10);
- return values; -} +class ChunkedStream extends _stream.Stream { + constructor(length, chunkSize, manager) { + super(new Uint8Array(length), 0, length, null); + this.chunkSize = chunkSize; + this._loadedChunks = new Set(); + this.numChunks = Math.ceil(length / chunkSize); + this.manager = manager; + this.progressiveDataLength = 0; + this.lastSuccessfulEnsureByteChunk = -1; + }
-const ROMAN_NUMBER_MAP = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]; + getMissingChunks() { + const chunks = [];
-function toRomanNumerals(number, lowerCase = false) { - (0, _util.assert)(Number.isInteger(number) && number > 0, "The number should be a positive integer."); - const romanBuf = []; - let pos; + for (let chunk = 0, n = this.numChunks; chunk < n; ++chunk) { + if (!this._loadedChunks.has(chunk)) { + chunks.push(chunk); + } + }
- while (number >= 1000) { - number -= 1000; - romanBuf.push("M"); + return chunks; }
- pos = number / 100 | 0; - number %= 100; - romanBuf.push(ROMAN_NUMBER_MAP[pos]); - pos = number / 10 | 0; - number %= 10; - romanBuf.push(ROMAN_NUMBER_MAP[10 + pos]); - romanBuf.push(ROMAN_NUMBER_MAP[20 + number]); - const romanStr = romanBuf.join(""); - return lowerCase ? romanStr.toLowerCase() : romanStr; -} - -function log2(x) { - if (x <= 0) { - return 0; + get numChunksLoaded() { + return this._loadedChunks.size; }
- return Math.ceil(Math.log2(x)); -} + get isDataLoaded() { + return this.numChunksLoaded === this.numChunks; + }
-function readInt8(data, offset) { - return data[offset] << 24 >> 24; -} + onReceiveData(begin, chunk) { + const chunkSize = this.chunkSize;
-function readUint16(data, offset) { - return data[offset] << 8 | data[offset + 1]; -} + if (begin % chunkSize !== 0) { + throw new Error(`Bad begin offset: ${begin}`); + }
-function readUint32(data, offset) { - return (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]) >>> 0; -} + const end = begin + chunk.byteLength;
-function isWhiteSpace(ch) { - return ch === 0x20 || ch === 0x09 || ch === 0x0d || ch === 0x0a; -} + if (end % chunkSize !== 0 && end !== this.bytes.length) { + throw new Error(`Bad end offset: ${end}`); + }
-function parseXFAPath(path) { - const positionPattern = /(.+)[(\d+)]$/; - return path.split(".").map(component => { - const m = component.match(positionPattern); + this.bytes.set(new Uint8Array(chunk), begin); + const beginChunk = Math.floor(begin / chunkSize); + const endChunk = Math.floor((end - 1) / chunkSize) + 1;
- if (m) { - return { - name: m[1], - pos: parseInt(m[2], 10) - }; + for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) { + this._loadedChunks.add(curChunk); } + }
- return { - name: component, - pos: 0 - }; - }); -} + onReceiveProgressiveData(data) { + let position = this.progressiveDataLength; + const beginChunk = Math.floor(position / this.chunkSize); + this.bytes.set(new Uint8Array(data), position); + position += data.byteLength; + this.progressiveDataLength = position; + const endChunk = position >= this.end ? this.numChunks : Math.floor(position / this.chunkSize);
-function escapePDFName(str) { - const buffer = []; - let start = 0; + for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) { + this._loadedChunks.add(curChunk); + } + }
- for (let i = 0, ii = str.length; i < ii; i++) { - const char = str.charCodeAt(i); + ensureByte(pos) { + if (pos < this.progressiveDataLength) { + return; + }
- if (char < 0x21 || char > 0x7e || char === 0x23 || char === 0x28 || char === 0x29 || char === 0x3c || char === 0x3e || char === 0x5b || char === 0x5d || char === 0x7b || char === 0x7d || char === 0x2f || char === 0x25) { - if (start < i) { - buffer.push(str.substring(start, i)); - } + const chunk = Math.floor(pos / this.chunkSize);
- buffer.push(`#${char.toString(16)}`); - start = i + 1; + if (chunk > this.numChunks) { + return; } - } - - if (buffer.length === 0) { - return str; - }
- if (start < str.length) { - buffer.push(str.substring(start, str.length)); - } + if (chunk === this.lastSuccessfulEnsureByteChunk) { + return; + }
- return buffer.join(""); -} + if (!this._loadedChunks.has(chunk)) { + throw new _core_utils.MissingDataException(pos, pos + 1); + }
-function _collectJS(entry, xref, list, parents) { - if (!entry) { - return; + this.lastSuccessfulEnsureByteChunk = chunk; }
- let parent = null; + ensureRange(begin, end) { + if (begin >= end) { + return; + }
- if (entry instanceof _primitives.Ref) { - if (parents.has(entry)) { + if (end <= this.progressiveDataLength) { return; }
- parent = entry; - parents.put(parent); - entry = xref.fetch(entry); - } + const beginChunk = Math.floor(begin / this.chunkSize);
- if (Array.isArray(entry)) { - for (const element of entry) { - _collectJS(element, xref, list, parents); + if (beginChunk > this.numChunks) { + return; } - } else if (entry instanceof _primitives.Dict) { - if ((0, _primitives.isName)(entry.get("S"), "JavaScript")) { - const js = entry.get("JS"); - let code;
- if (js instanceof _base_stream.BaseStream) { - code = js.getString(); - } else if (typeof js === "string") { - code = js; + const endChunk = Math.min(Math.floor((end - 1) / this.chunkSize) + 1, this.numChunks); + + for (let chunk = beginChunk; chunk < endChunk; ++chunk) { + if (!this._loadedChunks.has(chunk)) { + throw new _core_utils.MissingDataException(begin, end); } + } + }
- code = code && (0, _util.stringToPDFString)(code); + nextEmptyChunk(beginChunk) { + const numChunks = this.numChunks;
- if (code) { - list.push(code); + for (let i = 0; i < numChunks; ++i) { + const chunk = (beginChunk + i) % numChunks; + + if (!this._loadedChunks.has(chunk)) { + return chunk; } }
- _collectJS(entry.getRaw("Next"), xref, list, parents); + return null; }
- if (parent) { - parents.remove(parent); + hasChunk(chunk) { + return this._loadedChunks.has(chunk); } -} - -function collectActions(xref, dict, eventType) { - const actions = Object.create(null); - const additionalActionsDicts = getInheritableProperty({ - dict, - key: "AA", - stopWhenFound: false - }); - - if (additionalActionsDicts) { - for (let i = additionalActionsDicts.length - 1; i >= 0; i--) { - const additionalActions = additionalActionsDicts[i];
- if (!(additionalActions instanceof _primitives.Dict)) { - continue; - } + getByte() { + const pos = this.pos;
- for (const key of additionalActions.getKeys()) { - const action = eventType[key]; + if (pos >= this.end) { + return -1; + }
- if (!action) { - continue; - } + if (pos >= this.progressiveDataLength) { + this.ensureByte(pos); + }
- const actionDict = additionalActions.getRaw(key); - const parents = new _primitives.RefSet(); - const list = []; + return this.bytes[this.pos++]; + }
- _collectJS(actionDict, xref, list, parents); + getBytes(length) { + const bytes = this.bytes; + const pos = this.pos; + const strEnd = this.end;
- if (list.length > 0) { - actions[action] = list; - } + if (!length) { + if (strEnd > this.progressiveDataLength) { + this.ensureRange(pos, strEnd); } + + return bytes.subarray(pos, strEnd); } - }
- if (dict.has("A")) { - const actionDict = dict.get("A"); - const parents = new _primitives.RefSet(); - const list = []; + let end = pos + length;
- _collectJS(actionDict, xref, list, parents); + if (end > strEnd) { + end = strEnd; + }
- if (list.length > 0) { - actions.Action = list; + if (end > this.progressiveDataLength) { + this.ensureRange(pos, end); } - }
- return (0, _util.objectSize)(actions) > 0 ? actions : null; -} - -const XMLEntities = { - 0x3c: "<", - 0x3e: ">", - 0x26: "&", - 0x22: """, - 0x27: "'" -}; + this.pos = end; + return bytes.subarray(pos, end); + }
-function encodeToXmlString(str) { - const buffer = []; - let start = 0; + getByteRange(begin, end) { + if (begin < 0) { + begin = 0; + }
- for (let i = 0, ii = str.length; i < ii; i++) { - const char = str.codePointAt(i); + if (end > this.end) { + end = this.end; + }
- if (0x20 <= char && char <= 0x7e) { - const entity = XMLEntities[char]; + if (end > this.progressiveDataLength) { + this.ensureRange(begin, end); + }
- if (entity) { - if (start < i) { - buffer.push(str.substring(start, i)); - } + return this.bytes.subarray(begin, end); + }
- buffer.push(entity); - start = i + 1; + makeSubStream(start, length, dict = null) { + if (length) { + if (start + length > this.progressiveDataLength) { + this.ensureRange(start, start + length); } } else { - if (start < i) { - buffer.push(str.substring(start, i)); + if (start >= this.progressiveDataLength) { + this.ensureByte(start); } + }
- buffer.push(`&#x${char.toString(16).toUpperCase()};`); + function ChunkedStreamSubstream() {}
- if (char > 0xd7ff && (char < 0xe000 || char > 0xfffd)) { - i++; + ChunkedStreamSubstream.prototype = Object.create(this); + + ChunkedStreamSubstream.prototype.getMissingChunks = function () { + const chunkSize = this.chunkSize; + const beginChunk = Math.floor(this.start / chunkSize); + const endChunk = Math.floor((this.end - 1) / chunkSize) + 1; + const missingChunks = []; + + for (let chunk = beginChunk; chunk < endChunk; ++chunk) { + if (!this._loadedChunks.has(chunk)) { + missingChunks.push(chunk); + } }
- start = i + 1; - } - } + return missingChunks; + };
- if (buffer.length === 0) { - return str; + Object.defineProperty(ChunkedStreamSubstream.prototype, "isDataLoaded", { + get() { + if (this.numChunksLoaded === this.numChunks) { + return true; + } + + return this.getMissingChunks().length === 0; + }, + + configurable: true + }); + const subStream = new ChunkedStreamSubstream(); + subStream.pos = subStream.start = start; + subStream.end = start + length || this.end; + subStream.dict = dict; + return subStream; }
- if (start < str.length) { - buffer.push(str.substring(start, str.length)); + getBaseStreams() { + return [this]; }
- return buffer.join(""); }
-function validateCSSFont(cssFontInfo) { - const DEFAULT_CSS_FONT_OBLIQUE = "14"; - const DEFAULT_CSS_FONT_WEIGHT = "400"; - const CSS_FONT_WEIGHT_VALUES = new Set(["100", "200", "300", "400", "500", "600", "700", "800", "900", "1000", "normal", "bold", "bolder", "lighter"]); - const { - fontFamily, - fontWeight, - italicAngle - } = cssFontInfo; +exports.ChunkedStream = ChunkedStream;
- if (/^".*"$/.test(fontFamily)) { - if (/[^\]"/.test(fontFamily.slice(1, fontFamily.length - 1))) { - (0, _util.warn)(`XFA - FontFamily contains some unescaped ": ${fontFamily}.`); - return false; - } - } else if (/^'.*'$/.test(fontFamily)) { - if (/[^\]'/.test(fontFamily.slice(1, fontFamily.length - 1))) { - (0, _util.warn)(`XFA - FontFamily contains some unescaped ': ${fontFamily}.`); - return false; +class ChunkedStreamManager { + constructor(pdfNetworkStream, args) { + this.length = args.length; + this.chunkSize = args.rangeChunkSize; + this.stream = new ChunkedStream(this.length, this.chunkSize, this); + this.pdfNetworkStream = pdfNetworkStream; + this.disableAutoFetch = args.disableAutoFetch; + this.msgHandler = args.msgHandler; + this.currRequestId = 0; + this._chunksNeededByRequest = new Map(); + this._requestsByChunk = new Map(); + this._promisesByRequest = new Map(); + this.progressiveDataLength = 0; + this.aborted = false; + this._loadedStreamCapability = (0, _util.createPromiseCapability)(); + } + + onLoadedStream() { + return this._loadedStreamCapability.promise; + } + + sendRequest(begin, end) { + const rangeReader = this.pdfNetworkStream.getRangeReader(begin, end); + + if (!rangeReader.isStreamingSupported) { + rangeReader.onProgress = this.onProgress.bind(this); } - } else { - for (const ident of fontFamily.split(/[ \t]+/)) { - if (/^(\d|(-(\d|-)))/.test(ident) || !/^[\w-\]+$/.test(ident)) { - (0, _util.warn)(`XFA - FontFamily contains some invalid <custom-ident>: ${fontFamily}.`); - return false; + + let chunks = [], + loaded = 0; + return new Promise((resolve, reject) => { + const readChunk = chunk => { + try { + if (!chunk.done) { + const data = chunk.value; + chunks.push(data); + loaded += (0, _util.arrayByteLength)(data); + + if (rangeReader.isStreamingSupported) { + this.onProgress({ + loaded + }); + } + + rangeReader.read().then(readChunk, reject); + return; + } + + const chunkData = (0, _util.arraysToBytes)(chunks); + chunks = null; + resolve(chunkData); + } catch (e) { + reject(e); + } + }; + + rangeReader.read().then(readChunk, reject); + }).then(data => { + if (this.aborted) { + return; } - } + + this.onReceiveData({ + chunk: data, + begin + }); + }); }
- const weight = fontWeight ? fontWeight.toString() : ""; - cssFontInfo.fontWeight = CSS_FONT_WEIGHT_VALUES.has(weight) ? weight : DEFAULT_CSS_FONT_WEIGHT; - const angle = parseFloat(italicAngle); - cssFontInfo.italicAngle = isNaN(angle) || angle < -90 || angle > 90 ? DEFAULT_CSS_FONT_OBLIQUE : italicAngle.toString(); - return true; -} + requestAllChunks() { + const missingChunks = this.stream.getMissingChunks();
-function recoverJsURL(str) { - const URL_OPEN_METHODS = ["app.launchURL", "window.open", "xfa.host.gotoURL"]; - const regex = new RegExp("^\s*(" + URL_OPEN_METHODS.join("|").split(".").join("\.") + ")\((?:'|")([^'"]*)(?:'|")(?:,\s*(\w+)\)|\))", "i"); - const jsUrl = regex.exec(str); + this._requestChunks(missingChunks);
- if (jsUrl && jsUrl[2]) { - const url = jsUrl[2]; - let newWindow = false; + return this._loadedStreamCapability.promise; + }
- if (jsUrl[3] === "true" && jsUrl[1] === "app.launchURL") { - newWindow = true; + _requestChunks(chunks) { + const requestId = this.currRequestId++; + const chunksNeeded = new Set(); + + this._chunksNeededByRequest.set(requestId, chunksNeeded); + + for (const chunk of chunks) { + if (!this.stream.hasChunk(chunk)) { + chunksNeeded.add(chunk); + } }
- return { - url, - newWindow - }; - } + if (chunksNeeded.size === 0) { + return Promise.resolve(); + }
- return null; -} + const capability = (0, _util.createPromiseCapability)();
-/***/ }), -/* 9 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + this._promisesByRequest.set(requestId, capability);
+ const chunksToRequest = [];
+ for (const chunk of chunksNeeded) { + let requestIds = this._requestsByChunk.get(chunk);
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.BaseStream = void 0; + if (!requestIds) { + requestIds = [];
-var _util = __w_pdfjs_require__(2); + this._requestsByChunk.set(chunk, requestIds);
-class BaseStream { - constructor() { - if (this.constructor === BaseStream) { - (0, _util.unreachable)("Cannot initialize BaseStream."); + chunksToRequest.push(chunk); + } + + requestIds.push(requestId); } - }
- get length() { - (0, _util.unreachable)("Abstract getter `length` accessed"); - } + if (chunksToRequest.length > 0) { + const groupedChunksToRequest = this.groupChunks(chunksToRequest);
- get isEmpty() { - (0, _util.unreachable)("Abstract getter `isEmpty` accessed"); - } + for (const groupedChunk of groupedChunksToRequest) { + const begin = groupedChunk.beginChunk * this.chunkSize; + const end = Math.min(groupedChunk.endChunk * this.chunkSize, this.length); + this.sendRequest(begin, end).catch(capability.reject); + } + }
- get isDataLoaded() { - return (0, _util.shadow)(this, "isDataLoaded", true); - } + return capability.promise.catch(reason => { + if (this.aborted) { + return; + }
- getByte() { - (0, _util.unreachable)("Abstract method `getByte` called"); + throw reason; + }); }
- getBytes(length) { - (0, _util.unreachable)("Abstract method `getBytes` called"); + getStream() { + return this.stream; }
- peekByte() { - const peekedByte = this.getByte(); + requestRange(begin, end) { + end = Math.min(end, this.length); + const beginChunk = this.getBeginChunk(begin); + const endChunk = this.getEndChunk(end); + const chunks = [];
- if (peekedByte !== -1) { - this.pos--; + for (let chunk = beginChunk; chunk < endChunk; ++chunk) { + chunks.push(chunk); }
- return peekedByte; + return this._requestChunks(chunks); }
- peekBytes(length) { - const bytes = this.getBytes(length); - this.pos -= bytes.length; - return bytes; - } + requestRanges(ranges = []) { + const chunksToRequest = [];
- getUint16() { - const b0 = this.getByte(); - const b1 = this.getByte(); + for (const range of ranges) { + const beginChunk = this.getBeginChunk(range.begin); + const endChunk = this.getEndChunk(range.end);
- if (b0 === -1 || b1 === -1) { - return -1; + for (let chunk = beginChunk; chunk < endChunk; ++chunk) { + if (!chunksToRequest.includes(chunk)) { + chunksToRequest.push(chunk); + } + } }
- return (b0 << 8) + b1; + chunksToRequest.sort(function (a, b) { + return a - b; + }); + return this._requestChunks(chunksToRequest); }
- getInt32() { - const b0 = this.getByte(); - const b1 = this.getByte(); - const b2 = this.getByte(); - const b3 = this.getByte(); - return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; - } + groupChunks(chunks) { + const groupedChunks = []; + let beginChunk = -1; + let prevChunk = -1;
- getByteRange(begin, end) { - (0, _util.unreachable)("Abstract method `getByteRange` called"); + for (let i = 0, ii = chunks.length; i < ii; ++i) { + const chunk = chunks[i]; + + if (beginChunk < 0) { + beginChunk = chunk; + } + + if (prevChunk >= 0 && prevChunk + 1 !== chunk) { + groupedChunks.push({ + beginChunk, + endChunk: prevChunk + 1 + }); + beginChunk = chunk; + } + + if (i + 1 === chunks.length) { + groupedChunks.push({ + beginChunk, + endChunk: chunk + 1 + }); + } + + prevChunk = chunk; + } + + return groupedChunks; }
- getString(length) { - return (0, _util.bytesToString)(this.getBytes(length)); + onProgress(args) { + this.msgHandler.send("DocProgress", { + loaded: this.stream.numChunksLoaded * this.chunkSize + args.loaded, + total: this.length + }); }
- skip(n) { - this.pos += n || 1; + onReceiveData(args) { + const chunk = args.chunk; + const isProgressive = args.begin === undefined; + const begin = isProgressive ? this.progressiveDataLength : args.begin; + const end = begin + chunk.byteLength; + const beginChunk = Math.floor(begin / this.chunkSize); + const endChunk = end < this.length ? Math.floor(end / this.chunkSize) : Math.ceil(end / this.chunkSize); + + if (isProgressive) { + this.stream.onReceiveProgressiveData(chunk); + this.progressiveDataLength = end; + } else { + this.stream.onReceiveData(begin, chunk); + } + + if (this.stream.isDataLoaded) { + this._loadedStreamCapability.resolve(this.stream); + } + + const loadedRequests = []; + + for (let curChunk = beginChunk; curChunk < endChunk; ++curChunk) { + const requestIds = this._requestsByChunk.get(curChunk); + + if (!requestIds) { + continue; + } + + this._requestsByChunk.delete(curChunk); + + for (const requestId of requestIds) { + const chunksNeeded = this._chunksNeededByRequest.get(requestId); + + if (chunksNeeded.has(curChunk)) { + chunksNeeded.delete(curChunk); + } + + if (chunksNeeded.size > 0) { + continue; + } + + loadedRequests.push(requestId); + } + } + + if (!this.disableAutoFetch && this._requestsByChunk.size === 0) { + let nextEmptyChunk; + + if (this.stream.numChunksLoaded === 1) { + const lastChunk = this.stream.numChunks - 1; + + if (!this.stream.hasChunk(lastChunk)) { + nextEmptyChunk = lastChunk; + } + } else { + nextEmptyChunk = this.stream.nextEmptyChunk(endChunk); + } + + if (Number.isInteger(nextEmptyChunk)) { + this._requestChunks([nextEmptyChunk]); + } + } + + for (const requestId of loadedRequests) { + const capability = this._promisesByRequest.get(requestId); + + this._promisesByRequest.delete(requestId); + + capability.resolve(); + } + + this.msgHandler.send("DocProgress", { + loaded: this.stream.numChunksLoaded * this.chunkSize, + total: this.length + }); }
- reset() { - (0, _util.unreachable)("Abstract method `reset` called"); + onError(err) { + this._loadedStreamCapability.reject(err); }
- moveStart() { - (0, _util.unreachable)("Abstract method `moveStart` called"); + getBeginChunk(begin) { + return Math.floor(begin / this.chunkSize); }
- makeSubStream(start, length, dict = null) { - (0, _util.unreachable)("Abstract method `makeSubStream` called"); + getEndChunk(end) { + return Math.floor((end - 1) / this.chunkSize) + 1; }
- getBaseStreams() { - return null; + abort(reason) { + this.aborted = true; + + if (this.pdfNetworkStream) { + this.pdfNetworkStream.cancelAllRequests(reason); + } + + for (const capability of this._promisesByRequest.values()) { + capability.reject(reason); + } }
}
-exports.BaseStream = BaseStream; +exports.ChunkedStreamManager = ChunkedStreamManager;
/***/ }), /* 10 */ @@ -3510,7 +3582,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.StringStream = exports.Stream = exports.NullStream = void 0;
-var _base_stream = __w_pdfjs_require__(9); +var _base_stream = __w_pdfjs_require__(7);
var _util = __w_pdfjs_require__(2);
@@ -3618,7 +3690,7 @@ exports.Page = exports.PDFDocument = void 0;
var _util = __w_pdfjs_require__(2);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _primitives = __w_pdfjs_require__(5);
@@ -3626,13 +3698,13 @@ var _xfa_fonts = __w_pdfjs_require__(12);
var _annotation = __w_pdfjs_require__(22);
-var _base_stream = __w_pdfjs_require__(9); +var _base_stream = __w_pdfjs_require__(7);
-var _crypto = __w_pdfjs_require__(74); +var _crypto = __w_pdfjs_require__(67);
-var _catalog = __w_pdfjs_require__(65); +var _catalog = __w_pdfjs_require__(69);
-var _cleanup_helper = __w_pdfjs_require__(67); +var _cleanup_helper = __w_pdfjs_require__(71);
var _dataset_reader = __w_pdfjs_require__(100);
@@ -3640,7 +3712,7 @@ var _parser = __w_pdfjs_require__(27);
var _stream = __w_pdfjs_require__(10);
-var _object_loader = __w_pdfjs_require__(72); +var _object_loader = __w_pdfjs_require__(75);
var _operator_list = __w_pdfjs_require__(62);
@@ -3648,7 +3720,9 @@ var _evaluator = __w_pdfjs_require__(25);
var _decode_stream = __w_pdfjs_require__(29);
-var _struct_tree = __w_pdfjs_require__(71); +var _struct_tree = __w_pdfjs_require__(74); + +var _writer = __w_pdfjs_require__(65);
var _factory = __w_pdfjs_require__(76);
@@ -3727,7 +3801,9 @@ class Page { }
get resources() { - return (0, _util.shadow)(this, "resources", this._getInheritableProperty("Resources") || _primitives.Dict.empty); + const resources = this._getInheritableProperty("Resources"); + + return (0, _util.shadow)(this, "resources", resources instanceof _primitives.Dict ? resources : _primitives.Dict.empty); }
_getBoundingBox(name) { @@ -3834,6 +3910,55 @@ class Page { } : null); }
+ async saveNewAnnotations(handler, task, annotations) { + if (this.xfaFactory) { + throw new Error("XFA: Cannot save new annotations."); + } + + const partialEvaluator = new _evaluator.PartialEvaluator({ + xref: this.xref, + handler, + pageIndex: this.pageIndex, + idFactory: this._localIdFactory, + fontCache: this.fontCache, + builtInCMapCache: this.builtInCMapCache, + standardFontDataCache: this.standardFontDataCache, + globalImageCache: this.globalImageCache, + options: this.evaluatorOptions + }); + const pageDict = this.pageDict; + const annotationsArray = this.annotations.slice(); + const newData = await _annotation.AnnotationFactory.saveNewAnnotations(partialEvaluator, task, annotations); + + for (const { + ref + } of newData.annotations) { + annotationsArray.push(ref); + } + + const savedDict = pageDict.get("Annots"); + pageDict.set("Annots", annotationsArray); + const buffer = []; + let transform = null; + + if (this.xref.encrypt) { + transform = this.xref.encrypt.createCipherTransform(this.ref.num, this.ref.gen); + } + + (0, _writer.writeObject)(this.ref, pageDict, buffer, transform); + + if (savedDict) { + pageDict.set("Annots", savedDict); + } + + const objects = newData.dependencies; + objects.push({ + ref: this.ref, + data: buffer.join("") + }, ...newData.annotations); + return objects; + } + save(handler, task, annotationStorage) { const partialEvaluator = new _evaluator.PartialEvaluator({ xref: this.xref, @@ -3860,7 +3985,9 @@ class Page { })); }
- return Promise.all(newRefsPromises); + return Promise.all(newRefsPromises).then(function (newRefs) { + return newRefs.filter(newRef => !!newRef); + }); }); }
@@ -3896,6 +4023,17 @@ class Page { globalImageCache: this.globalImageCache, options: this.evaluatorOptions }); + const newAnnotationsByPage = !this.xfaFactory ? (0, _core_utils.getNewAnnotationsMap)(annotationStorage) : null; + let newAnnotationsPromise = Promise.resolve(null); + + if (newAnnotationsByPage) { + const newAnnotations = newAnnotationsByPage.get(this.pageIndex); + + if (newAnnotations) { + newAnnotationsPromise = _annotation.AnnotationFactory.printNewAnnotations(partialEvaluator, task, newAnnotations); + } + } + const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]); const pageListPromise = dataPromises.then(([contentStream]) => { const opList = new _operator_list.OperatorList(intent, sink); @@ -3913,7 +4051,11 @@ class Page { return opList; }); }); - return Promise.all([pageListPromise, this._parsedAnnotations]).then(function ([pageOpList, annotations]) { + return Promise.all([pageListPromise, this._parsedAnnotations, newAnnotationsPromise]).then(function ([pageOpList, annotations, newAnnotations]) { + if (newAnnotations) { + annotations = annotations.concat(newAnnotations); + } + if (annotations.length === 0 || intent & _util.RenderingIntentFlag.ANNOTATIONS_DISABLE) { pageOpList.flush(true); return { @@ -3937,13 +4079,10 @@ class Page { }
return Promise.all(opListPromises).then(function (opLists) { - pageOpList.addOp(_util.OPS.beginAnnotations, []); - for (const opList of opLists) { pageOpList.addOpList(opList); }
- pageOpList.addOp(_util.OPS.endAnnotations, []); pageOpList.flush(true); return { length: pageOpList.totalLength @@ -4488,7 +4627,7 @@ class PDFDocument { const pdfFonts = []; const initialState = { get font() { - return pdfFonts[pdfFonts.length - 1]; + return pdfFonts.at(-1); },
set font(font) { @@ -5088,7 +5227,7 @@ var _myriadpro_factors = __w_pdfjs_require__(16);
var _segoeui_factors = __w_pdfjs_require__(17);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _fonts_utils = __w_pdfjs_require__(18);
@@ -5285,7 +5424,7 @@ function getXfaFontDict(name) { dict.set("CIDToGIDMap", _primitives.Name.get("Identity")); dict.set("W", widths); dict.set("FirstChar", widths[0]); - dict.set("LastChar", widths[widths.length - 2] + widths[widths.length - 1].length - 1); + dict.set("LastChar", widths.at(-2) + widths.at(-1).length - 1); const descriptor = new _primitives.Dict(null); dict.set("FontDescriptor", descriptor); const systemInfo = new _primitives.Dict(null); @@ -5716,7 +5855,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.getGlyphsUnicode = exports.getDingbatsGlyphsUnicode = void 0;
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
const getGlyphsUnicode = (0, _core_utils.getArrayLookupTableFactory)(function () { return ["A", 0x0041, "AE", 0x00c6, "AEacute", 0x01fc, "AEmacron", 0x01e2, "AEsmall", 0xf7e6, "Aacute", 0x00c1, "Aacutesmall", 0xf7e1, "Abreve", 0x0102, "Abreveacute", 0x1eae, "Abrevecyrillic", 0x04d0, "Abrevedotbelow", 0x1eb6, "Abrevegrave", 0x1eb0, "Abrevehookabove", 0x1eb2, "Abrevetilde", 0x1eb4, "Acaron", 0x01cd, "Acircle", 0x24b6, "Acircumflex", 0x00c2, "Acircumflexacute", 0x1ea4, "Acircumflexdotbelow", 0x1eac, "Acircumflexgrave", 0x1ea6, "Acircumflexhookabove", 0x1ea8, "Acircumfle [...] @@ -5744,7 +5883,7 @@ exports.getUnicodeRangeFor = getUnicodeRangeFor; exports.mapSpecialUnicodeValues = mapSpecialUnicodeValues; exports.reverseIfRtl = reverseIfRtl;
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
const getSpecialPUASymbols = (0, _core_utils.getLookupTableFactory)(function (t) { t[63721] = 0x00a9; @@ -6278,34 +6417,32 @@ exports.getQuadPoints = getQuadPoints;
var _util = __w_pdfjs_require__(2);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _default_appearance = __w_pdfjs_require__(23);
var _primitives = __w_pdfjs_require__(5);
-var _base_stream = __w_pdfjs_require__(9); +var _writer = __w_pdfjs_require__(65); + +var _base_stream = __w_pdfjs_require__(7);
var _bidi = __w_pdfjs_require__(60);
-var _catalog = __w_pdfjs_require__(65); +var _catalog = __w_pdfjs_require__(69);
var _colorspace = __w_pdfjs_require__(24);
-var _file_spec = __w_pdfjs_require__(68); +var _file_spec = __w_pdfjs_require__(72);
-var _object_loader = __w_pdfjs_require__(72); +var _object_loader = __w_pdfjs_require__(75);
var _operator_list = __w_pdfjs_require__(62);
var _stream = __w_pdfjs_require__(10);
-var _writer = __w_pdfjs_require__(73); - var _factory = __w_pdfjs_require__(76);
-const LINE_FACTOR = 1.35; - class AnnotationFactory { static create(xref, ref, pdfManager, idFactory, collectFields) { return Promise.all([pdfManager.ensureCatalog("acroForm"), pdfManager.ensureCatalog("baseUrl"), pdfManager.ensureDoc("xfaDatasets"), collectFields ? this._getPageIndex(xref, ref, pdfManager) : -1]).then(([acroForm, baseUrl, xfaDatasets, pageIndex]) => pdfManager.ensure(this, "_create", [xref, ref, pdfManager, idFactory, acroForm, xfaDatasets, collectFields, pageIndex])); @@ -6445,6 +6582,74 @@ class AnnotationFactory { } }
+ static async saveNewAnnotations(evaluator, task, annotations) { + const xref = evaluator.xref; + let baseFontRef; + const dependencies = []; + const promises = []; + + for (const annotation of annotations) { + switch (annotation.annotationType) { + case _util.AnnotationEditorType.FREETEXT: + if (!baseFontRef) { + const baseFont = new _primitives.Dict(xref); + baseFont.set("BaseFont", _primitives.Name.get("Helvetica")); + baseFont.set("Type", _primitives.Name.get("Font")); + baseFont.set("Subtype", _primitives.Name.get("Type1")); + baseFont.set("Encoding", _primitives.Name.get("WinAnsiEncoding")); + const buffer = []; + baseFontRef = xref.getNewRef(); + (0, _writer.writeObject)(baseFontRef, baseFont, buffer, null); + dependencies.push({ + ref: baseFontRef, + data: buffer.join("") + }); + } + + promises.push(FreeTextAnnotation.createNewAnnotation(xref, annotation, dependencies, { + evaluator, + task, + baseFontRef + })); + break; + + case _util.AnnotationEditorType.INK: + promises.push(InkAnnotation.createNewAnnotation(xref, annotation, dependencies)); + } + } + + return { + annotations: await Promise.all(promises), + dependencies + }; + } + + static async printNewAnnotations(evaluator, task, annotations) { + if (!annotations) { + return null; + } + + const xref = evaluator.xref; + const promises = []; + + for (const annotation of annotations) { + switch (annotation.annotationType) { + case _util.AnnotationEditorType.FREETEXT: + promises.push(FreeTextAnnotation.createNewPrintAnnotation(xref, annotation, { + evaluator, + task + })); + break; + + case _util.AnnotationEditorType.INK: + promises.push(InkAnnotation.createNewPrintAnnotation(xref, annotation)); + break; + } + } + + return Promise.all(promises); + } + }
exports.AnnotationFactory = AnnotationFactory; @@ -6552,7 +6757,10 @@ class Annotation { this.setColor(dict.getArray("C")); this.setBorderStyle(dict); this.setAppearance(dict); - this.setBorderAndBackgroundColors(dict.get("MK")); + this.setOptionalContent(dict); + const MK = dict.get("MK"); + this.setBorderAndBackgroundColors(MK); + this.setRotation(MK); this._streams = [];
if (this.appearance) { @@ -6565,6 +6773,7 @@ class Annotation { color: this.color, backgroundColor: this.backgroundColor, borderColor: this.borderColor, + rotation: this.rotation, contentsObj: this._contents, hasAppearance: !!this.appearance, id: params.id, @@ -6696,6 +6905,57 @@ class Annotation { this.color = getRgbColor(color); }
+ setLineEndings(lineEndings) { + this.lineEndings = ["None", "None"]; + + if (Array.isArray(lineEndings) && lineEndings.length === 2) { + for (let i = 0; i < 2; i++) { + const obj = lineEndings[i]; + + if (obj instanceof _primitives.Name) { + switch (obj.name) { + case "None": + continue; + + case "Square": + case "Circle": + case "Diamond": + case "OpenArrow": + case "ClosedArrow": + case "Butt": + case "ROpenArrow": + case "RClosedArrow": + case "Slash": + this.lineEndings[i] = obj.name; + continue; + } + } + + (0, _util.warn)(`Ignoring invalid lineEnding: ${obj}`); + } + } + } + + setRotation(mk) { + this.rotation = 0; + + if (mk instanceof _primitives.Dict) { + let angle = mk.get("R") || 0; + + if (Number.isInteger(angle) && angle !== 0) { + angle %= 360; + + if (angle < 0) { + angle += 360; + } + + if (angle % 90 === 0) { + this.rotation = angle; + } + } + } + } + setBorderAndBackgroundColors(mk) { if (mk instanceof _primitives.Dict) { this.borderColor = getRgbColor(mk.getArray("BC"), null); @@ -6766,6 +7026,17 @@ class Annotation { this.appearance = normalAppearanceState.get(as.name); }
+ setOptionalContent(dict) { + this.oc = null; + const oc = dict.get("OC"); + + if (oc instanceof _primitives.Name) { + (0, _util.warn)("setOptionalContent: Support for /Name-entry is not implemented."); + } else if (oc instanceof _primitives.Dict) { + this.oc = oc; + } + } + loadResources(keys, appearance) { return appearance.dict.getAsync("Resources").then(resources => { if (!resources) { @@ -6779,14 +7050,14 @@ class Annotation { }); }
- getOperatorList(evaluator, task, intent, renderForms, annotationStorage) { + async getOperatorList(evaluator, task, intent, renderForms, annotationStorage) { const data = this.data; let appearance = this.appearance; - const isUsingOwnCanvas = data.hasOwnCanvas && intent & _util.RenderingIntentFlag.DISPLAY; + const isUsingOwnCanvas = this.data.hasOwnCanvas && intent & _util.RenderingIntentFlag.DISPLAY;
if (!appearance) { if (!isUsingOwnCanvas) { - return Promise.resolve(new _operator_list.OperatorList()); + return new _operator_list.OperatorList(); }
appearance = new _stream.StringStream(""); @@ -6794,25 +7065,37 @@ class Annotation { }
const appearanceDict = appearance.dict; - const resourcesPromise = this.loadResources(["ExtGState", "ColorSpace", "Pattern", "Shading", "XObject", "Font"], appearance); + const resources = await this.loadResources(["ExtGState", "ColorSpace", "Pattern", "Shading", "XObject", "Font"], appearance); const bbox = appearanceDict.getArray("BBox") || [0, 0, 1, 1]; const matrix = appearanceDict.getArray("Matrix") || [1, 0, 0, 1, 0, 0]; const transform = getTransformMatrix(data.rect, bbox, matrix); - return resourcesPromise.then(resources => { - const opList = new _operator_list.OperatorList(); - opList.addOp(_util.OPS.beginAnnotation, [data.id, data.rect, transform, matrix, isUsingOwnCanvas]); - return evaluator.getOperatorList({ - stream: appearance, - task, - resources, - operatorList: opList, - fallbackFontDict: this._fallbackFontDict - }).then(() => { - opList.addOp(_util.OPS.endAnnotation, []); - this.reset(); - return opList; - }); + const opList = new _operator_list.OperatorList(); + let optionalContent; + + if (this.oc) { + optionalContent = await evaluator.parseMarkedContentProps(this.oc, null); + } + + if (optionalContent !== undefined) { + opList.addOp(_util.OPS.beginMarkedContentProps, ["OC", optionalContent]); + } + + opList.addOp(_util.OPS.beginAnnotation, [data.id, data.rect, transform, matrix, isUsingOwnCanvas]); + await evaluator.getOperatorList({ + stream: appearance, + task, + resources, + operatorList: opList, + fallbackFontDict: this._fallbackFontDict }); + opList.addOp(_util.OPS.endAnnotation, []); + + if (optionalContent !== undefined) { + opList.addOp(_util.OPS.endMarkedContent, []); + } + + this.reset(); + return opList; }
async save(evaluator, task, annotationStorage) { @@ -6829,7 +7112,8 @@ class Annotation { fillColor: this.data.backgroundColor, type: "", kidIds: this.data.kidIds, - page: this.data.pageIndex + page: this.data.pageIndex, + rotation: this.rotation }; }
@@ -7146,6 +7430,40 @@ class MarkupAnnotation extends Annotation { this._streams.push(this.appearance, appearanceStream); }
+ static async createNewAnnotation(xref, annotation, dependencies, params) { + const annotationRef = xref.getNewRef(); + const apRef = xref.getNewRef(); + const annotationDict = this.createNewDict(annotation, xref, { + apRef + }); + const ap = await this.createNewAppearanceStream(annotation, xref, params); + const buffer = []; + let transform = xref.encrypt ? xref.encrypt.createCipherTransform(apRef.num, apRef.gen) : null; + (0, _writer.writeObject)(apRef, ap, buffer, transform); + dependencies.push({ + ref: apRef, + data: buffer.join("") + }); + buffer.length = 0; + transform = xref.encrypt ? xref.encrypt.createCipherTransform(annotationRef.num, annotationRef.gen) : null; + (0, _writer.writeObject)(annotationRef, annotationDict, buffer, transform); + return { + ref: annotationRef, + data: buffer.join("") + }; + } + + static async createNewPrintAnnotation(xref, annotation, params) { + const ap = await this.createNewAppearanceStream(annotation, xref, params); + const annotationDict = this.createNewDict(annotation, xref, { + ap + }); + return new this.prototype.constructor({ + dict: annotationDict, + xref + }); + } + }
exports.MarkupAnnotation = MarkupAnnotation; @@ -7230,6 +7548,7 @@ class WidgetAnnotation extends Annotation { }
data.readOnly = this.hasFieldFlag(_util.AnnotationFieldFlag.READONLY); + data.required = this.hasFieldFlag(_util.AnnotationFieldFlag.REQUIRED); data.hidden = this._hasFlag(data.annotationFlags, _util.AnnotationFlag.HIDDEN); }
@@ -7249,59 +7568,158 @@ class WidgetAnnotation extends Annotation { return !!(this.data.fieldFlags & flag); }
- getOperatorList(evaluator, task, intent, renderForms, annotationStorage) { + static _getRotationMatrix(rotation, width, height) { + switch (rotation) { + case 90: + return [0, 1, -1, 0, width, 0]; + + case 180: + return [-1, 0, 0, -1, width, height]; + + case 270: + return [0, -1, 1, 0, 0, height]; + + default: + throw new Error("Invalid rotation"); + } + } + + getRotationMatrix(annotationStorage) { + const storageEntry = annotationStorage ? annotationStorage.get(this.data.id) : undefined; + let rotation = storageEntry && storageEntry.rotation; + + if (rotation === undefined) { + rotation = this.rotation; + } + + if (rotation === 0) { + return _util.IDENTITY_MATRIX; + } + + const width = this.data.rect[2] - this.data.rect[0]; + const height = this.data.rect[3] - this.data.rect[1]; + return WidgetAnnotation._getRotationMatrix(rotation, width, height); + } + + getBorderAndBackgroundAppearances(annotationStorage) { + const storageEntry = annotationStorage ? annotationStorage.get(this.data.id) : undefined; + let rotation = storageEntry && storageEntry.rotation; + + if (rotation === undefined) { + rotation = this.rotation; + } + + if (!this.backgroundColor && !this.borderColor) { + return ""; + } + + const width = this.data.rect[2] - this.data.rect[0]; + const height = this.data.rect[3] - this.data.rect[1]; + const rect = rotation === 0 || rotation === 180 ? `0 0 ${width} ${height} re` : `0 0 ${height} ${width} re`; + let str = ""; + + if (this.backgroundColor) { + str = `${(0, _default_appearance.getPdfColor)(this.backgroundColor, true)} ${rect} f `; + } + + if (this.borderColor) { + const borderWidth = this.borderStyle.width || 1; + str += `${borderWidth} w ${(0, _default_appearance.getPdfColor)(this.borderColor, false)} ${rect} S `; + } + + return str; + } + + async getOperatorList(evaluator, task, intent, renderForms, annotationStorage) { if (renderForms && !(this instanceof SignatureWidgetAnnotation)) { - return Promise.resolve(new _operator_list.OperatorList()); + return new _operator_list.OperatorList(); }
if (!this._hasText) { return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage); }
- return this._getAppearance(evaluator, task, annotationStorage).then(content => { - if (this.appearance && content === null) { - return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage); - } + const content = await this._getAppearance(evaluator, task, annotationStorage);
- const operatorList = new _operator_list.OperatorList(); + if (this.appearance && content === null) { + return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage); + }
- if (!this._defaultAppearance || content === null) { - return operatorList; - } + const operatorList = new _operator_list.OperatorList();
- const matrix = [1, 0, 0, 1, 0, 0]; - const bbox = [0, 0, this.data.rect[2] - this.data.rect[0], this.data.rect[3] - this.data.rect[1]]; - const transform = getTransformMatrix(this.data.rect, bbox, matrix); - operatorList.addOp(_util.OPS.beginAnnotation, [this.data.id, this.data.rect, transform, matrix]); - const stream = new _stream.StringStream(content); - return evaluator.getOperatorList({ - stream, - task, - resources: this._fieldResources.mergedResources, - operatorList - }).then(function () { - operatorList.addOp(_util.OPS.endAnnotation, []); - return operatorList; - }); + if (!this._defaultAppearance || content === null) { + return operatorList; + } + + const matrix = [1, 0, 0, 1, 0, 0]; + const bbox = [0, 0, this.data.rect[2] - this.data.rect[0], this.data.rect[3] - this.data.rect[1]]; + const transform = getTransformMatrix(this.data.rect, bbox, matrix); + let optionalContent; + + if (this.oc) { + optionalContent = await evaluator.parseMarkedContentProps(this.oc, null); + } + + if (optionalContent !== undefined) { + operatorList.addOp(_util.OPS.beginMarkedContentProps, ["OC", optionalContent]); + } + + operatorList.addOp(_util.OPS.beginAnnotation, [this.data.id, this.data.rect, transform, this.getRotationMatrix(annotationStorage)]); + const stream = new _stream.StringStream(content); + await evaluator.getOperatorList({ + stream, + task, + resources: this._fieldResources.mergedResources, + operatorList }); + operatorList.addOp(_util.OPS.endAnnotation, []); + + if (optionalContent !== undefined) { + operatorList.addOp(_util.OPS.endMarkedContent, []); + } + + return operatorList; + } + + _getMKDict(rotation) { + const mk = new _primitives.Dict(null); + + if (rotation) { + mk.set("R", rotation); + } + + if (this.borderColor) { + mk.set("BC", Array.from(this.borderColor).map(c => c / 255)); + } + + if (this.backgroundColor) { + mk.set("BG", Array.from(this.backgroundColor).map(c => c / 255)); + } + + return mk.size > 0 ? mk : null; }
async save(evaluator, task, annotationStorage) { const storageEntry = annotationStorage ? annotationStorage.get(this.data.id) : undefined; let value = storageEntry && storageEntry.value; + let rotation = storageEntry && storageEntry.rotation;
if (value === this.data.fieldValue || value === undefined) { - if (!this._hasValueFromXFA) { + if (!this._hasValueFromXFA && rotation === undefined) { return null; }
value = value || this.data.fieldValue; }
- if (!this._hasValueFromXFA && Array.isArray(value) && Array.isArray(this.data.fieldValue) && value.length === this.data.fieldValue.length && value.every((x, i) => x === this.data.fieldValue[i])) { + if (rotation === undefined && !this._hasValueFromXFA && Array.isArray(value) && Array.isArray(this.data.fieldValue) && value.length === this.data.fieldValue.length && value.every((x, i) => x === this.data.fieldValue[i])) { return null; }
+ if (rotation === undefined) { + rotation = this.rotation; + } + let appearance = await this._getAppearance(evaluator, task, annotationStorage);
if (appearance === null) { @@ -7340,11 +7758,24 @@ class WidgetAnnotation extends Annotation { dict.set("V", Array.isArray(value) ? value.map(encoder) : encoder(value)); dict.set("AP", AP); dict.set("M", `D:${(0, _util.getModificationDate)()}`); + + const maybeMK = this._getMKDict(rotation); + + if (maybeMK) { + dict.set("MK", maybeMK); + } + const appearanceDict = new _primitives.Dict(xref); appearanceDict.set("Length", appearance.length); appearanceDict.set("Subtype", _primitives.Name.get("Form")); appearanceDict.set("Resources", this._getSaveFieldResources(xref)); appearanceDict.set("BBox", bbox); + const rotationMatrix = this.getRotationMatrix(annotationStorage); + + if (rotationMatrix !== _util.IDENTITY_MATRIX) { + appearanceDict.set("Matrix", rotationMatrix); + } + const bufferOriginal = [`${this.ref.num} ${this.ref.gen} obj\n`]; (0, _writer.writeDict)(dict, bufferOriginal, originalTransform); bufferOriginal.push("\nendobj\n"); @@ -7370,13 +7801,20 @@ class WidgetAnnotation extends Annotation { }
const storageEntry = annotationStorage ? annotationStorage.get(this.data.id) : undefined; - let value = storageEntry && (storageEntry.formattedValue || storageEntry.value); + let value, rotation;
- if (value === undefined) { + if (storageEntry) { + value = storageEntry.formattedValue || storageEntry.value; + rotation = storageEntry.rotation; + } + + if (rotation === undefined && value === undefined) { if (!this._hasValueFromXFA || this.appearance) { return null; } + }
+ if (value === undefined) { value = this.data.fieldValue;
if (!value) { @@ -7384,6 +7822,10 @@ class WidgetAnnotation extends Annotation { } }
+ if (Array.isArray(value) && value.length === 1) { + value = value[0]; + } + (0, _util.assert)(typeof value === "string", "Expected `value` to be a string."); value = value.trim();
@@ -7391,6 +7833,10 @@ class WidgetAnnotation extends Annotation { return ""; }
+ if (rotation === undefined) { + rotation = this.rotation; + } + let lineCount = -1;
if (this.data.multiLine) { @@ -7399,14 +7845,18 @@ class WidgetAnnotation extends Annotation {
const defaultPadding = 2; const hPadding = defaultPadding; - const totalHeight = this.data.rect[3] - this.data.rect[1]; - const totalWidth = this.data.rect[2] - this.data.rect[0]; + let totalHeight = this.data.rect[3] - this.data.rect[1]; + let totalWidth = this.data.rect[2] - this.data.rect[0]; + + if (rotation === 90 || rotation === 270) { + [totalWidth, totalHeight] = [totalHeight, totalWidth]; + }
if (!this._defaultAppearance) { this.data.defaultAppearanceData = (0, _default_appearance.parseDefaultAppearance)(this._defaultAppearance = "/Helvetica 0 Tf 0 g"); }
- const font = await this._getFontData(evaluator, task); + const font = await WidgetAnnotation._getFontData(evaluator, task, this.data.defaultAppearanceData, this._fieldResources.mergedResources);
const [defaultAppearance, fontSize] = this._computeFontSize(totalHeight - defaultPadding, totalWidth - 2 * hPadding, value, font, lineCount);
@@ -7416,29 +7866,32 @@ class WidgetAnnotation extends Annotation { descent = 0; }
- const vPadding = defaultPadding + Math.abs(descent) * fontSize; + const defaultVPadding = Math.min(Math.floor((totalHeight - fontSize) / 2), defaultPadding); + const vPadding = defaultVPadding + Math.abs(descent) * fontSize; const alignment = this.data.textAlignment;
if (this.data.multiLine) { - return this._getMultilineAppearance(defaultAppearance, value, font, fontSize, totalWidth, totalHeight, alignment, hPadding, vPadding); + return this._getMultilineAppearance(defaultAppearance, value, font, fontSize, totalWidth, totalHeight, alignment, hPadding, vPadding, annotationStorage); }
const encodedString = font.encodeString(value).join("");
if (this.data.comb) { - return this._getCombAppearance(defaultAppearance, font, encodedString, totalWidth, hPadding, vPadding); + return this._getCombAppearance(defaultAppearance, font, encodedString, totalWidth, hPadding, vPadding, annotationStorage); }
+ const colors = this.getBorderAndBackgroundAppearances(annotationStorage); + if (alignment === 0 || alignment > 2) { - return "/Tx BMC q BT " + defaultAppearance + ` 1 0 0 1 ${hPadding} ${vPadding} Tm (${(0, _util.escapeString)(encodedString)}) Tj` + " ET Q EMC"; + return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 ${hPadding} ${vPadding} Tm (${(0, _util.escapeString)(encodedString)}) Tj` + " ET Q EMC"; }
const renderedText = this._renderText(encodedString, font, fontSize, totalWidth, alignment, hPadding, vPadding);
- return "/Tx BMC q BT " + defaultAppearance + ` 1 0 0 1 0 0 Tm ${renderedText}` + " ET Q EMC"; + return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 0 0 Tm ${renderedText}` + " ET Q EMC"; }
- async _getFontData(evaluator, task) { + static async _getFontData(evaluator, task, appearanceData, resources) { const operatorList = new _operator_list.OperatorList(); const initialState = { font: null, @@ -7451,8 +7904,8 @@ class WidgetAnnotation extends Annotation { const { fontName, fontSize - } = this.data.defaultAppearanceData; - await evaluator.handleSetFont(this._fieldResources.mergedResources, [fontName && _primitives.Name.get(fontName), fontSize], null, operatorList, task, initialState, null); + } = appearanceData; + await evaluator.handleSetFont(resources, [fontName && _primitives.Name.get(fontName), fontSize], null, operatorList, task, initialState, null); return initialState.font; }
@@ -7471,7 +7924,7 @@ class WidgetAnnotation extends Annotation { if (lineCount === -1) { const textWidth = this._getTextWidth(text, font);
- fontSize = roundWithTwoDigits(Math.min(height / LINE_FACTOR, width / textWidth)); + fontSize = roundWithTwoDigits(Math.min(height / _util.LINE_FACTOR, width / textWidth)); } else { const lines = text.split(/\r\n?|\n/); const cachedLines = []; @@ -7504,13 +7957,13 @@ class WidgetAnnotation extends Annotation { };
fontSize = 12; - let lineHeight = fontSize * LINE_FACTOR; + let lineHeight = fontSize * _util.LINE_FACTOR; let numberOfLines = Math.round(height / lineHeight); numberOfLines = Math.max(numberOfLines, lineCount);
while (true) { lineHeight = height / numberOfLines; - fontSize = roundWithTwoDigits(lineHeight / LINE_FACTOR); + fontSize = roundWithTwoDigits(lineHeight / _util.LINE_FACTOR);
if (isTooBig(fontSize)) { numberOfLines++; @@ -7548,8 +8001,8 @@ class WidgetAnnotation extends Annotation { shift = hPadding; }
- shift = shift.toFixed(2); - vPadding = vPadding.toFixed(2); + shift = (0, _core_utils.numberToString)(shift); + vPadding = (0, _core_utils.numberToString)(vPadding); return `${shift} ${vPadding} Td (${(0, _util.escapeString)(text)}) Tj`; }
@@ -7632,10 +8085,11 @@ class TextWidgetAnnotation extends WidgetAnnotation { this.data.maxLen = maximumLength; this.data.multiLine = this.hasFieldFlag(_util.AnnotationFieldFlag.MULTILINE); this.data.comb = this.hasFieldFlag(_util.AnnotationFieldFlag.COMB) && !this.hasFieldFlag(_util.AnnotationFieldFlag.MULTILINE) && !this.hasFieldFlag(_util.AnnotationFieldFlag.PASSWORD) && !this.hasFieldFlag(_util.AnnotationFieldFlag.FILESELECT) && this.data.maxLen !== null; + this.data.doNotScroll = this.hasFieldFlag(_util.AnnotationFieldFlag.DONOTSCROLL); }
- _getCombAppearance(defaultAppearance, font, text, width, hPadding, vPadding) { - const combWidth = (width / this.data.maxLen).toFixed(2); + _getCombAppearance(defaultAppearance, font, text, width, hPadding, vPadding, annotationStorage) { + const combWidth = (0, _core_utils.numberToString)(width / this.data.maxLen); const buf = []; const positions = font.getCharPositions(text);
@@ -7643,11 +8097,12 @@ class TextWidgetAnnotation extends WidgetAnnotation { buf.push(`(${(0, _util.escapeString)(text.substring(start, end))}) Tj`); }
+ const colors = this.getBorderAndBackgroundAppearances(annotationStorage); const renderedComb = buf.join(` ${combWidth} 0 Td `); - return "/Tx BMC q BT " + defaultAppearance + ` 1 0 0 1 ${hPadding} ${vPadding} Tm ${renderedComb}` + " ET Q EMC"; + return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 ${hPadding} ${vPadding} Tm ${renderedComb}` + " ET Q EMC"; }
- _getMultilineAppearance(defaultAppearance, text, font, fontSize, width, height, alignment, hPadding, vPadding) { + _getMultilineAppearance(defaultAppearance, text, font, fontSize, width, height, alignment, hPadding, vPadding, annotationStorage) { const lines = text.split(/\r\n?|\n/); const buf = []; const totalWidth = width - 2 * hPadding; @@ -7662,7 +8117,8 @@ class TextWidgetAnnotation extends WidgetAnnotation { }
const renderedText = buf.join("\n"); - return "/Tx BMC q BT " + defaultAppearance + ` 1 0 0 1 0 ${height} Tm ${renderedText}` + " ET Q EMC"; + const colors = this.getBorderAndBackgroundAppearances(annotationStorage); + return `/Tx BMC q ${colors}BT ` + defaultAppearance + ` 1 0 0 1 0 ${height} Tm ${renderedText}` + " ET Q EMC"; }
_splitLine(line, font, fontSize, width, cache = {}) { @@ -7743,6 +8199,7 @@ class TextWidgetAnnotation extends WidgetAnnotation { page: this.data.pageIndex, strokeColor: this.data.borderColor, fillColor: this.data.backgroundColor, + rotation: this.rotation, type: "text" }; } @@ -7778,17 +8235,19 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { }
let value = null; + let rotation = null;
if (annotationStorage) { const storageEntry = annotationStorage.get(this.data.id); value = storageEntry ? storageEntry.value : null; + rotation = storageEntry ? storageEntry.rotation : null; }
- if (value === null) { - if (this.appearance) { - return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage); - } + if (value === null && this.appearance) { + return super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage); + }
+ if (value === null || value === undefined) { if (this.data.checkBox) { value = this.data.fieldValue === this.data.exportValue; } else { @@ -7800,9 +8259,17 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
if (appearance) { const savedAppearance = this.appearance; + + const savedMatrix = appearance.dict.getArray("Matrix") || _util.IDENTITY_MATRIX; + + if (rotation) { + appearance.dict.set("Matrix", this.getRotationMatrix(annotationStorage)); + } + this.appearance = appearance; const operatorList = super.getOperatorList(evaluator, task, intent, renderForms, annotationStorage); this.appearance = savedAppearance; + appearance.dict.set("Matrix", savedMatrix); return operatorList; }
@@ -7827,16 +8294,19 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { }
const storageEntry = annotationStorage.get(this.data.id); - const value = storageEntry && storageEntry.value; + let rotation = storageEntry && storageEntry.rotation; + let value = storageEntry && storageEntry.value;
- if (value === undefined) { - return null; - } + if (rotation === undefined) { + if (value === undefined) { + return null; + }
- const defaultValue = this.data.fieldValue === this.data.exportValue; + const defaultValue = this.data.fieldValue === this.data.exportValue;
- if (defaultValue === value) { - return null; + if (defaultValue === value) { + return null; + } }
const dict = evaluator.xref.fetchIfRef(this.ref); @@ -7845,6 +8315,14 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { return null; }
+ if (rotation === undefined) { + rotation = this.rotation; + } + + if (value === undefined) { + value = this.data.fieldValue === this.data.exportValue; + } + const xfa = { path: (0, _util.stringToPDFString)(dict.get("T") || ""), value: value ? this.data.exportValue : "" @@ -7855,6 +8333,13 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { dict.set("V", name); dict.set("AS", name); dict.set("M", `D:${(0, _util.getModificationDate)()}`); + + const maybeMK = this._getMKDict(rotation); + + if (maybeMK) { + dict.set("MK", maybeMK); + } + const encrypt = evaluator.xref.encrypt; let originalTransform = null;
@@ -7878,16 +8363,19 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { }
const storageEntry = annotationStorage.get(this.data.id); - const value = storageEntry && storageEntry.value; + let rotation = storageEntry && storageEntry.rotation; + let value = storageEntry && storageEntry.value;
- if (value === undefined) { - return null; - } + if (rotation === undefined) { + if (value === undefined) { + return null; + }
- const defaultValue = this.data.fieldValue === this.data.buttonValue; + const defaultValue = this.data.fieldValue === this.data.buttonValue;
- if (defaultValue === value) { - return null; + if (defaultValue === value) { + return null; + } }
const dict = evaluator.xref.fetchIfRef(this.ref); @@ -7896,6 +8384,14 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { return null; }
+ if (value === undefined) { + value = this.data.fieldValue === this.data.buttonValue; + } + + if (rotation === undefined) { + rotation = this.rotation; + } + const xfa = { path: (0, _util.stringToPDFString)(dict.get("T") || ""), value: value ? this.data.buttonValue : "" @@ -7926,6 +8422,13 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
dict.set("AS", name); dict.set("M", `D:${(0, _util.getModificationDate)()}`); + + const maybeMK = this._getMKDict(rotation); + + if (maybeMK) { + dict.set("MK", maybeMK); + } + let originalTransform = null;
if (encrypt) { @@ -7976,8 +8479,8 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { (0, _util.unreachable)(`_getDefaultCheckedAppearance - unsupported type: ${type}`); }
- const xShift = (width - metrics.width) / 2; - const yShift = (height - metrics.height) / 2; + const xShift = (0, _core_utils.numberToString)((width - metrics.width) / 2); + const yShift = (0, _core_utils.numberToString)((height - metrics.height) / 2); const appearance = `q BT /PdfJsZaDb ${fontSize} Tf 0 g ${xShift} ${yShift} Td (${char}) Tj ET Q`; const appearanceStreamDict = new _primitives.Dict(params.xref); appearanceStreamDict.set("FormType", 1); @@ -8145,6 +8648,7 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { page: this.data.pageIndex, strokeColor: this.data.borderColor, fillColor: this.data.backgroundColor, + rotation: this.rotation, type }; } @@ -8211,6 +8715,7 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation { page: this.data.pageIndex, strokeColor: this.data.borderColor, fillColor: this.data.backgroundColor, + rotation: this.rotation, type }; } @@ -8225,20 +8730,33 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation { }
const storageEntry = annotationStorage.get(this.data.id); - let exportedValue = storageEntry && storageEntry.value;
- if (exportedValue === undefined) { + if (!storageEntry) { + return null; + } + + const rotation = storageEntry.rotation; + let exportedValue = storageEntry.value; + + if (rotation === undefined && exportedValue === undefined) { return null; }
- if (!Array.isArray(exportedValue)) { + if (exportedValue === undefined) { + exportedValue = this.data.fieldValue; + } else if (!Array.isArray(exportedValue)) { exportedValue = [exportedValue]; }
const defaultPadding = 2; const hPadding = defaultPadding; - const totalHeight = this.data.rect[3] - this.data.rect[1]; - const totalWidth = this.data.rect[2] - this.data.rect[0]; + let totalHeight = this.data.rect[3] - this.data.rect[1]; + let totalWidth = this.data.rect[2] - this.data.rect[0]; + + if (rotation === 90 || rotation === 270) { + [totalWidth, totalHeight] = [totalHeight, totalWidth]; + } + const lineCount = this.data.options.length; const valueIndices = [];
@@ -8256,7 +8774,7 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation { this.data.defaultAppearanceData = (0, _default_appearance.parseDefaultAppearance)(this._defaultAppearance = "/Helvetica 0 Tf 0 g"); }
- const font = await this._getFontData(evaluator, task); + const font = await WidgetAnnotation._getFontData(evaluator, task, this.data.defaultAppearanceData, this._fieldResources.mergedResources); let defaultAppearance; let { fontSize @@ -8270,7 +8788,7 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation { for (const { displayValue } of this.data.options) { - const width = this._getTextWidth(displayValue); + const width = this._getTextWidth(displayValue, font);
if (width > lineWidth) { lineWidth = width; @@ -8283,7 +8801,7 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation { defaultAppearance = this._defaultAppearance; }
- const lineHeight = fontSize * LINE_FACTOR; + const lineHeight = fontSize * _util.LINE_FACTOR; const vPadding = (lineHeight - fontSize) / 2; const numberOfVisibleLines = Math.floor(totalHeight / lineHeight); let firstIndex; @@ -8379,6 +8897,8 @@ class LinkAnnotation extends Annotation { this.data.quadPoints = quadPoints; }
+ this.data.borderColor = this.data.borderColor || this.data.color; + _catalog.Catalog.parseDestDictionary({ destDict: params.dict, resultObj: this.data, @@ -8457,20 +8977,168 @@ class FreeTextAnnotation extends MarkupAnnotation { this.data.annotationType = _util.AnnotationType.FREETEXT; }
+ static createNewDict(annotation, xref, { + apRef, + ap + }) { + const { + color, + fontSize, + rect, + rotation, + user, + value + } = annotation; + const freetext = new _primitives.Dict(xref); + freetext.set("Type", _primitives.Name.get("Annot")); + freetext.set("Subtype", _primitives.Name.get("FreeText")); + freetext.set("CreationDate", `D:${(0, _util.getModificationDate)()}`); + freetext.set("Rect", rect); + const da = `/Helv ${fontSize} Tf ${(0, _default_appearance.getPdfColor)(color, true)}`; + freetext.set("DA", da); + freetext.set("Contents", value); + freetext.set("F", 4); + freetext.set("Border", [0, 0, 0]); + freetext.set("Rotate", rotation); + + if (user) { + freetext.set("T", (0, _util.stringToUTF8String)(user)); + } + + const n = new _primitives.Dict(xref); + freetext.set("AP", n); + + if (apRef) { + n.set("N", apRef); + } else { + n.set("N", ap); + } + + return freetext; + } + + static async createNewAppearanceStream(annotation, xref, params) { + const { + baseFontRef, + evaluator, + task + } = params; + const { + color, + fontSize, + rect, + rotation, + value + } = annotation; + const resources = new _primitives.Dict(xref); + const font = new _primitives.Dict(xref); + + if (baseFontRef) { + font.set("Helv", baseFontRef); + } else { + const baseFont = new _primitives.Dict(xref); + baseFont.set("BaseFont", _primitives.Name.get("Helvetica")); + baseFont.set("Type", _primitives.Name.get("Font")); + baseFont.set("Subtype", _primitives.Name.get("Type1")); + baseFont.set("Encoding", _primitives.Name.get("WinAnsiEncoding")); + font.set("Helv", baseFont); + } + + resources.set("Font", font); + const helv = await WidgetAnnotation._getFontData(evaluator, task, { + fontName: "Helvetica", + fontSize + }, resources); + const [x1, y1, x2, y2] = rect; + let w = x2 - x1; + let h = y2 - y1; + + if (rotation % 180 !== 0) { + [w, h] = [h, w]; + } + + const lines = value.split("\n"); + const scale = fontSize / 1000; + let totalWidth = -Infinity; + const encodedLines = []; + + for (let line of lines) { + line = helv.encodeString(line).join(""); + encodedLines.push(line); + let lineWidth = 0; + const glyphs = helv.charsToGlyphs(line); + + for (const glyph of glyphs) { + lineWidth += glyph.width * scale; + } + + totalWidth = Math.max(totalWidth, lineWidth); + } + + let hscale = 1; + + if (totalWidth > w) { + hscale = w / totalWidth; + } + + let vscale = 1; + const lineHeight = _util.LINE_FACTOR * fontSize; + const lineDescent = _util.LINE_DESCENT_FACTOR * fontSize; + const totalHeight = lineHeight * lines.length; + + if (totalHeight > h) { + vscale = h / totalHeight; + } + + const fscale = Math.min(hscale, vscale); + const newFontSize = fontSize * fscale; + const buffer = ["q", `0 0 ${(0, _core_utils.numberToString)(w)} ${(0, _core_utils.numberToString)(h)} re W n`, `BT`, `1 0 0 1 0 ${(0, _core_utils.numberToString)(h + lineDescent)} Tm 0 Tc ${(0, _default_appearance.getPdfColor)(color, true)}`, `/Helv ${(0, _core_utils.numberToString)(newFontSize)} Tf`]; + const vShift = (0, _core_utils.numberToString)(lineHeight); + + for (const line of encodedLines) { + buffer.push(`0 -${vShift} Td (${(0, _util.escapeString)(line)}) Tj`); + } + + buffer.push("ET", "Q"); + const appearance = buffer.join("\n"); + const appearanceStreamDict = new _primitives.Dict(xref); + appearanceStreamDict.set("FormType", 1); + appearanceStreamDict.set("Subtype", _primitives.Name.get("Form")); + appearanceStreamDict.set("Type", _primitives.Name.get("XObject")); + appearanceStreamDict.set("BBox", [0, 0, w, h]); + appearanceStreamDict.set("Length", appearance.length); + appearanceStreamDict.set("Resources", resources); + + if (rotation) { + const matrix = WidgetAnnotation._getRotationMatrix(rotation, w, h); + + appearanceStreamDict.set("Matrix", matrix); + } + + const ap = new _stream.StringStream(appearance); + ap.dict = appearanceStreamDict; + return ap; + } + }
class LineAnnotation extends MarkupAnnotation { constructor(parameters) { super(parameters); + const { + dict + } = parameters; this.data.annotationType = _util.AnnotationType.LINE; - const lineCoordinates = parameters.dict.getArray("L"); + const lineCoordinates = dict.getArray("L"); this.data.lineCoordinates = _util.Util.normalizeRect(lineCoordinates); + this.setLineEndings(dict.getArray("LE")); + this.data.lineEndings = this.lineEndings;
if (!this.appearance) { const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0]; - const strokeAlpha = parameters.dict.get("CA"); + const strokeAlpha = dict.get("CA"); let fillColor = null, - interiorColor = parameters.dict.getArray("IC"); + interiorColor = dict.getArray("IC");
if (interiorColor) { interiorColor = getRgbColor(interiorColor, null); @@ -8612,9 +9280,18 @@ class CircleAnnotation extends MarkupAnnotation { class PolylineAnnotation extends MarkupAnnotation { constructor(parameters) { super(parameters); + const { + dict + } = parameters; this.data.annotationType = _util.AnnotationType.POLYLINE; this.data.vertices = []; - const rawVertices = parameters.dict.getArray("Vertices"); + + if (!(this instanceof PolygonAnnotation)) { + this.setLineEndings(dict.getArray("LE")); + this.data.lineEndings = this.lineEndings; + } + + const rawVertices = dict.getArray("Vertices");
if (!Array.isArray(rawVertices)) { return; @@ -8629,7 +9306,7 @@ class PolylineAnnotation extends MarkupAnnotation {
if (!this.appearance) { const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0]; - const strokeAlpha = parameters.dict.get("CA"); + const strokeAlpha = dict.get("CA"); const borderWidth = this.borderStyle.width || 1, borderAdjust = 2 * borderWidth; const bbox = [Infinity, Infinity, -Infinity, -Infinity]; @@ -8746,6 +9423,89 @@ class InkAnnotation extends MarkupAnnotation { } }
+ static createNewDict(annotation, xref, { + apRef, + ap + }) { + const { + paths, + rect, + rotation + } = annotation; + const ink = new _primitives.Dict(xref); + ink.set("Type", _primitives.Name.get("Annot")); + ink.set("Subtype", _primitives.Name.get("Ink")); + ink.set("CreationDate", `D:${(0, _util.getModificationDate)()}`); + ink.set("Rect", rect); + ink.set("InkList", paths.map(p => p.points)); + ink.set("F", 4); + ink.set("Border", [0, 0, 0]); + ink.set("Rotate", rotation); + const n = new _primitives.Dict(xref); + ink.set("AP", n); + + if (apRef) { + n.set("N", apRef); + } else { + n.set("N", ap); + } + + return ink; + } + + static async createNewAppearanceStream(annotation, xref, params) { + const { + color, + rect, + rotation, + paths, + thickness + } = annotation; + const [x1, y1, x2, y2] = rect; + let w = x2 - x1; + let h = y2 - y1; + + if (rotation % 180 !== 0) { + [w, h] = [h, w]; + } + + const appearanceBuffer = [`${thickness} w 1 J 1 j`, `${(0, _default_appearance.getPdfColor)(color, false)}`]; + const buffer = []; + + for (const { + bezier + } of paths) { + buffer.length = 0; + buffer.push(`${(0, _core_utils.numberToString)(bezier[0])} ${(0, _core_utils.numberToString)(bezier[1])} m`); + + for (let i = 2, ii = bezier.length; i < ii; i += 6) { + const curve = bezier.slice(i, i + 6).map(_core_utils.numberToString).join(" "); + buffer.push(`${curve} c`); + } + + buffer.push("S"); + appearanceBuffer.push(buffer.join("\n")); + } + + const appearance = appearanceBuffer.join("\n"); + const appearanceStreamDict = new _primitives.Dict(xref); + appearanceStreamDict.set("FormType", 1); + appearanceStreamDict.set("Subtype", _primitives.Name.get("Form")); + appearanceStreamDict.set("Type", _primitives.Name.get("XObject")); + appearanceStreamDict.set("BBox", [0, 0, w, h]); + appearanceStreamDict.set("Length", appearance.length); + + if (rotation) { + const matrix = WidgetAnnotation._getRotationMatrix(rotation, w, h); + + appearanceStreamDict.set("Matrix", matrix); + } + + const ap = new _stream.StringStream(appearance); + ap.dict = appearanceStreamDict; + return ap; + } + }
class HighlightAnnotation extends MarkupAnnotation { @@ -8911,14 +9671,15 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.createDefaultAppearance = createDefaultAppearance; +exports.getPdfColor = getPdfColor; exports.parseDefaultAppearance = parseDefaultAppearance;
+var _core_utils = __w_pdfjs_require__(6); + var _util = __w_pdfjs_require__(2);
var _colorspace = __w_pdfjs_require__(24);
-var _core_utils = __w_pdfjs_require__(8); - var _evaluator = __w_pdfjs_require__(25);
var _primitives = __w_pdfjs_require__(5); @@ -9001,20 +9762,21 @@ function parseDefaultAppearance(str) { return new DefaultAppearanceEvaluator(str).parse(); }
+function getPdfColor(color, isFill) { + if (color[0] === color[1] && color[1] === color[2]) { + const gray = color[0] / 255; + return `${(0, _core_utils.numberToString)(gray)} ${isFill ? "g" : "G"}`; + } + + return Array.from(color).map(c => (0, _core_utils.numberToString)(c / 255)).join(" ") + ` ${isFill ? "rg" : "RG"}`; +} + function createDefaultAppearance({ fontSize, fontName, fontColor }) { - let colorCmd; - - if (fontColor.every(c => c === 0)) { - colorCmd = "0 g"; - } else { - colorCmd = Array.from(fontColor).map(c => (c / 255).toFixed(2)).join(" ") + " rg"; - } - - return `/${(0, _core_utils.escapePDFName)(fontName)} ${fontSize} Tf ${colorCmd}`; + return `/${(0, _core_utils.escapePDFName)(fontName)} ${fontSize} Tf ${getPdfColor(fontColor, true)}`; }
/***/ }), @@ -9032,9 +9794,9 @@ var _util = __w_pdfjs_require__(2);
var _primitives = __w_pdfjs_require__(5);
-var _base_stream = __w_pdfjs_require__(9); +var _base_stream = __w_pdfjs_require__(7);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
function resizeRgbImage(src, dest, w1, h1, w2, h2, alpha01) { const COMPONENTS = 3; @@ -10127,7 +10889,7 @@ var _image_utils = __w_pdfjs_require__(59);
var _stream = __w_pdfjs_require__(10);
-var _base_stream = __w_pdfjs_require__(9); +var _base_stream = __w_pdfjs_require__(7);
var _bidi = __w_pdfjs_require__(60);
@@ -10137,7 +10899,7 @@ var _decode_stream = __w_pdfjs_require__(29);
var _glyphlist = __w_pdfjs_require__(20);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _metrics = __w_pdfjs_require__(51);
@@ -11109,11 +11871,9 @@ class PartialEvaluator { let fontRef;
if (font) { - if (!(font instanceof _primitives.Ref)) { - throw new _util.FormatError('The "font" object should be a reference.'); + if (font instanceof _primitives.Ref) { + fontRef = font; } - - fontRef = font; } else { const fontRes = resources.get("Font");
@@ -12682,7 +13442,7 @@ class PartialEvaluator { } }
- const item = elements[elements.length - 1]; + const item = elements.at(-1);
if (typeof item === "string") { showSpacedTextBuffer.push(item); @@ -12901,6 +13661,8 @@ class PartialEvaluator { return;
case _util.OPS.beginMarkedContent: + flushTextContentItem(); + if (includeMarkedContent) { textContent.items.push({ type: "beginMarkedContent", @@ -12911,8 +13673,9 @@ class PartialEvaluator { break;
case _util.OPS.beginMarkedContentProps: + flushTextContentItem(); + if (includeMarkedContent) { - flushTextContentItem(); let mcid = null;
if (args[1] instanceof _primitives.Dict) { @@ -12929,8 +13692,9 @@ class PartialEvaluator { break;
case _util.OPS.endMarkedContent: + flushTextContentItem(); + if (includeMarkedContent) { - flushTextContentItem(); textContent.items.push({ type: "endMarkedContent" }); @@ -12985,10 +13749,18 @@ class PartialEvaluator { }; }
- const cidToGidMap = dict.get("CIDToGIDMap"); + try { + const cidToGidMap = dict.get("CIDToGIDMap"); + + if (cidToGidMap instanceof _base_stream.BaseStream) { + cidToGidBytes = cidToGidMap.getBytes(); + } + } catch (ex) { + if (!this.options.ignoreErrors) { + throw ex; + }
- if (cidToGidMap instanceof _base_stream.BaseStream) { - cidToGidBytes = cidToGidMap.getBytes(); + (0, _util.warn)(`extractDataStructures - ignoring CIDToGIDMap data: "${ex}".`); } }
@@ -13932,7 +14704,12 @@ class TranslatedFont { const charProcs = this.dict.get("CharProcs"); const fontResources = this.dict.get("Resources") || resources; const charProcOperatorList = Object.create(null); - const isEmptyBBox = !translatedFont.bbox || (0, _util.isArrayEqual)(translatedFont.bbox, [0, 0, 0, 0]); + + const fontBBox = _util.Util.normalizeRect(translatedFont.bbox || [0, 0, 0, 0]), + width = fontBBox[2] - fontBBox[0], + height = fontBBox[3] - fontBBox[1]; + + const fontBBoxSize = Math.hypot(width, height);
for (const key of charProcs.getKeys()) { loadCharProcsPromise = loadCharProcsPromise.then(() => { @@ -13945,7 +14722,7 @@ class TranslatedFont { operatorList }).then(() => { if (operatorList.fnArray[0] === _util.OPS.setCharWidthAndBounds) { - this._removeType3ColorOperators(operatorList, isEmptyBBox); + this._removeType3ColorOperators(operatorList, fontBBoxSize); }
charProcOperatorList[key] = operatorList.getIR(); @@ -13972,25 +14749,35 @@ class TranslatedFont { return this.type3Loaded; }
- _removeType3ColorOperators(operatorList, isEmptyBBox = false) { - if (isEmptyBBox) { + _removeType3ColorOperators(operatorList, fontBBoxSize = NaN) { + const charBBox = _util.Util.normalizeRect(operatorList.argsArray[0].slice(2)), + width = charBBox[2] - charBBox[0], + height = charBBox[3] - charBBox[1]; + + const charBBoxSize = Math.hypot(width, height); + + if (width === 0 || height === 0) { + operatorList.fnArray.splice(0, 1); + operatorList.argsArray.splice(0, 1); + } else if (fontBBoxSize === 0 || Math.round(charBBoxSize / fontBBoxSize) >= 10) { if (!this._bbox) { this._bbox = [Infinity, Infinity, -Infinity, -Infinity]; }
- const charBBox = _util.Util.normalizeRect(operatorList.argsArray[0].slice(2)); - this._bbox[0] = Math.min(this._bbox[0], charBBox[0]); this._bbox[1] = Math.min(this._bbox[1], charBBox[1]); this._bbox[2] = Math.max(this._bbox[2], charBBox[2]); this._bbox[3] = Math.max(this._bbox[3], charBBox[3]); }
- let i = 1, + let i = 0, ii = operatorList.length;
while (i < ii) { switch (operatorList.fnArray[i]) { + case _util.OPS.setCharWidthAndBounds: + break; + case _util.OPS.setStrokeColorSpace: case _util.OPS.setFillColorSpace: case _util.OPS.setStrokeColor: @@ -14540,6 +15327,7 @@ class EvaluatorPreprocessor { }); this.stateManager = stateManager; this.nonProcessedArgs = []; + this._isPathOp = false; this._numInvalidPathOPS = 0; }
@@ -14566,6 +15354,12 @@ class EvaluatorPreprocessor { const numArgs = opSpec.numArgs; let argsLength = args !== null ? args.length : 0;
+ if (!this._isPathOp) { + this._numInvalidPathOPS = 0; + } + + this._isPathOp = fn >= _util.OPS.moveTo && fn <= _util.OPS.endPath; + if (!opSpec.variableArgs) { if (argsLength !== numArgs) { const nonProcessedArgs = this.nonProcessedArgs; @@ -14588,7 +15382,7 @@ class EvaluatorPreprocessor { if (argsLength < numArgs) { const partialMsg = `command ${cmd}: expected ${numArgs} args, ` + `but received ${argsLength} args.`;
- if (fn >= _util.OPS.moveTo && fn <= _util.OPS.endPath && ++this._numInvalidPathOPS > EvaluatorPreprocessor.MAX_INVALID_PATH_OPS) { + if (this._isPathOp && ++this._numInvalidPathOPS > EvaluatorPreprocessor.MAX_INVALID_PATH_OPS) { throw new _util.FormatError(`Invalid ${partialMsg}`); }
@@ -14663,11 +15457,11 @@ var _util = __w_pdfjs_require__(2);
var _primitives = __w_pdfjs_require__(5);
-var _base_stream = __w_pdfjs_require__(9); +var _base_stream = __w_pdfjs_require__(7);
var _parser = __w_pdfjs_require__(27);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _stream = __w_pdfjs_require__(10);
@@ -15588,7 +16382,7 @@ var _util = __w_pdfjs_require__(2);
var _primitives = __w_pdfjs_require__(5);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _ascii_85_stream = __w_pdfjs_require__(28);
@@ -16969,7 +17763,7 @@ exports.Ascii85Stream = void 0;
var _decode_stream = __w_pdfjs_require__(29);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
class Ascii85Stream extends _decode_stream.DecodeStream { constructor(str, maybeLength) { @@ -17067,7 +17861,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.StreamsSequenceStream = exports.DecodeStream = void 0;
-var _base_stream = __w_pdfjs_require__(9); +var _base_stream = __w_pdfjs_require__(7);
var _stream = __w_pdfjs_require__(10);
@@ -18415,7 +19209,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.Jbig2Stream = void 0;
-var _base_stream = __w_pdfjs_require__(9); +var _base_stream = __w_pdfjs_require__(7);
var _decode_stream = __w_pdfjs_require__(29);
@@ -18495,7 +19289,7 @@ exports.Jbig2Image = void 0;
var _util = __w_pdfjs_require__(2);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _arithmetic_decoder = __w_pdfjs_require__(36);
@@ -19837,7 +20631,7 @@ function processSegment(segment, visitor) { break;
default: - throw new Jbig2Error(`segment type ${header.typeName}(${header.type})` + " is not implemented"); + throw new Jbig2Error(`segment type ${header.typeName}(${header.type}) is not implemented`); }
const callbackName = "on" + header.typeName; @@ -19866,55 +20660,7 @@ function parseJbig2Chunks(chunks) { }
function parseJbig2(data) { - const end = data.length; - let position = 0; - - if (data[position] !== 0x97 || data[position + 1] !== 0x4a || data[position + 2] !== 0x42 || data[position + 3] !== 0x32 || data[position + 4] !== 0x0d || data[position + 5] !== 0x0a || data[position + 6] !== 0x1a || data[position + 7] !== 0x0a) { - throw new Jbig2Error("parseJbig2 - invalid header."); - } - - const header = Object.create(null); - position += 8; - const flags = data[position++]; - header.randomAccess = !(flags & 1); - - if (!(flags & 2)) { - header.numberOfPages = (0, _core_utils.readUint32)(data, position); - position += 4; - } - - const segments = readSegments(header, data, position, end); - const visitor = new SimpleSegmentVisitor(); - processSegments(segments, visitor); - const { - width, - height - } = visitor.currentPageInfo; - const bitPacked = visitor.buffer; - const imgData = new Uint8ClampedArray(width * height); - let q = 0, - k = 0; - - for (let i = 0; i < height; i++) { - let mask = 0, - buffer; - - for (let j = 0; j < width; j++) { - if (!mask) { - mask = 128; - buffer = bitPacked[k++]; - } - - imgData[q++] = buffer & mask ? 0 : 255; - mask >>= 1; - } - } - - return { - imgData, - width, - height - }; + throw new Error("Not implemented: parseJbig2"); }
class SimpleSegmentVisitor { @@ -19924,9 +20670,7 @@ class SimpleSegmentVisitor { const buffer = new Uint8ClampedArray(rowSize * info.height);
if (info.defaultPixelValue) { - for (let i = 0, ii = buffer.length; i < ii; i++) { - buffer[i] = 0xff; - } + buffer.fill(0xff); }
this.buffer = buffer; @@ -20020,13 +20764,13 @@ class SimpleSegmentVisitor { this.symbols = symbols = {}; }
- let inputSymbols = []; + const inputSymbols = [];
- for (let i = 0, ii = referredSegments.length; i < ii; i++) { - const referredSymbols = symbols[referredSegments[i]]; + for (const referredSegment of referredSegments) { + const referredSymbols = symbols[referredSegment];
if (referredSymbols) { - inputSymbols = inputSymbols.concat(referredSymbols); + inputSymbols.push(...referredSymbols); } }
@@ -20038,13 +20782,13 @@ class SimpleSegmentVisitor { const regionInfo = region.info; let huffmanTables, huffmanInput; const symbols = this.symbols; - let inputSymbols = []; + const inputSymbols = [];
- for (let i = 0, ii = referredSegments.length; i < ii; i++) { - const referredSymbols = symbols[referredSegments[i]]; + for (const referredSegment of referredSegments) { + const referredSymbols = symbols[referredSegment];
if (referredSymbols) { - inputSymbols = inputSymbols.concat(referredSymbols); + inputSymbols.push(...referredSymbols); } }
@@ -20667,14 +21411,7 @@ class Jbig2Image { }
parse(data) { - const { - imgData, - width, - height - } = parseJbig2(data); - this.width = width; - this.height = height; - return imgData; + throw new Error("Not implemented: Jbig2Image.parse"); }
} @@ -21147,7 +21884,7 @@ exports.JpegImage = void 0;
var _util = __w_pdfjs_require__(2);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
class JpegError extends _util.BaseException { constructor(msg) { @@ -22474,7 +23211,7 @@ exports.JpxImage = void 0;
var _util = __w_pdfjs_require__(2);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _arithmetic_decoder = __w_pdfjs_require__(36);
@@ -25302,7 +26039,7 @@ var _cmap = __w_pdfjs_require__(26);
var _opentype_file_builder = __w_pdfjs_require__(53);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _stream = __w_pdfjs_require__(10);
@@ -25580,11 +26317,14 @@ function convertCidString(charCode, cid, shouldThrow = false) { return cid; }
-function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId) { +function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId, toUnicode) { const newMap = Object.create(null); + const toUnicodeExtraMap = new Map(); const toFontChar = []; + const usedGlyphIds = new Set(); let privateUseAreaIndex = 0; - let nextAvailableFontCharCode = PRIVATE_USE_AREAS[privateUseAreaIndex][0]; + const privateUseOffetStart = PRIVATE_USE_AREAS[privateUseAreaIndex][0]; + let nextAvailableFontCharCode = privateUseOffetStart; let privateUseOffetEnd = PRIVATE_USE_AREAS[privateUseAreaIndex][1];
for (let originalCharCode in charCodeToGlyphId) { @@ -25613,6 +26353,17 @@ function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId) { glyphId = newGlyphZeroId; }
+ let unicode = toUnicode.get(originalCharCode); + + if (typeof unicode === "string") { + unicode = unicode.codePointAt(0); + } + + if (unicode && unicode < privateUseOffetStart && !usedGlyphIds.has(glyphId)) { + toUnicodeExtraMap.set(unicode, glyphId); + usedGlyphIds.add(glyphId); + } + newMap[fontCharCode] = glyphId; toFontChar[originalCharCode] = fontCharCode; } @@ -25620,11 +26371,12 @@ function adjustMapping(charCodeToGlyphId, hasGlyph, newGlyphZeroId) { return { toFontChar, charCodeToGlyphId: newMap, + toUnicodeExtraMap, nextAvailableFontCharCode }; }
-function getRanges(glyphs, numGlyphs) { +function getRanges(glyphs, toUnicodeExtraMap, numGlyphs) { const codes = [];
for (const charCode in glyphs) { @@ -25638,6 +26390,19 @@ function getRanges(glyphs, numGlyphs) { }); }
+ if (toUnicodeExtraMap) { + for (const [unicode, glyphId] of toUnicodeExtraMap) { + if (glyphId >= numGlyphs) { + continue; + } + + codes.push({ + fontCharCode: unicode, + glyphId + }); + } + } + if (codes.length === 0) { codes.push({ fontCharCode: 0, @@ -25673,9 +26438,9 @@ function getRanges(glyphs, numGlyphs) { return ranges; }
-function createCmapTable(glyphs, numGlyphs) { - const ranges = getRanges(glyphs, numGlyphs); - const numTables = ranges[ranges.length - 1][1] > 0xffff ? 2 : 1; +function createCmapTable(glyphs, toUnicodeExtraMap, numGlyphs) { + const ranges = getRanges(glyphs, toUnicodeExtraMap, numGlyphs); + const numTables = ranges.at(-1)[1] > 0xffff ? 2 : 1; let cmap = "\x00\x00" + string16(numTables) + "\x00\x03" + "\x00\x01" + (0, _util.string32)(4 + numTables * 8); let i, ii, j, jj;
@@ -26236,7 +27001,7 @@ class Font { const offset = file.getInt32() >>> 0; const length = file.getInt32() >>> 0; const previousPosition = file.pos; - file.pos = file.start ? file.start : 0; + file.pos = file.start || 0; file.skip(offset); const data = file.getBytes(length); file.pos = previousPosition; @@ -26373,7 +27138,7 @@ class Font { }
let segment; - let start = (file.start ? file.start : 0) + cmap.offset; + let start = (file.start || 0) + cmap.offset; file.pos = start; file.skip(2); const numTables = file.getUint16(); @@ -26649,7 +27414,7 @@ class Font { return; }
- file.pos = (file.start ? file.start : 0) + header.offset; + file.pos = (file.start || 0) + header.offset; file.pos += 4; file.pos += 2; file.pos += 2; @@ -26971,7 +27736,7 @@ class Font { }
function readPostScriptTable(post, propertiesObj, maxpNumGlyphs) { - const start = (font.start ? font.start : 0) + post.offset; + const start = (font.start || 0) + post.offset; font.pos = start; const length = post.length, end = start + length; @@ -27059,7 +27824,7 @@ class Font { }
function readNameTable(nameTable) { - const start = (font.start ? font.start : 0) + nameTable.offset; + const start = (font.start || 0) + nameTable.offset; font.pos = start; const names = [[], []]; const length = nameTable.length, @@ -27191,7 +27956,7 @@ class Font { } } else if (op === 0x2b && !tooComplexToFollowFunctions) { if (!inFDEF && !inELSE) { - funcId = stack[stack.length - 1]; + funcId = stack.at(-1);
if (isNaN(funcId)) { (0, _util.info)("TT: CALL empty stack (or invalid entry)."); @@ -27279,7 +28044,7 @@ class Font { --ifLevel; } else if (op === 0x1c) { if (!inFDEF && !inELSE) { - const offset = stack[stack.length - 1]; + const offset = stack.at(-1);
if (offset > 0) { i += offset - 1; @@ -27740,11 +28505,11 @@ class Font { }
if (!properties.cssFontInfo) { - const newMapping = adjustMapping(charCodeToGlyphId, hasGlyph, glyphZeroId); + const newMapping = adjustMapping(charCodeToGlyphId, hasGlyph, glyphZeroId, this.toUnicode); this.toFontChar = newMapping.toFontChar; tables.cmap = { tag: "cmap", - data: createCmapTable(newMapping.charCodeToGlyphId, numGlyphsOut) + data: createCmapTable(newMapping.charCodeToGlyphId, newMapping.toUnicodeExtraMap, numGlyphsOut) };
if (!tables["OS/2"] || !validateOS2Table(tables["OS/2"], font)) { @@ -27804,11 +28569,13 @@ class Font { const mapping = font.getGlyphMapping(properties); let newMapping = null; let newCharCodeToGlyphId = mapping; + let toUnicodeExtraMap = null;
if (!properties.cssFontInfo) { - newMapping = adjustMapping(mapping, font.hasGlyphId.bind(font), glyphZeroId); + newMapping = adjustMapping(mapping, font.hasGlyphId.bind(font), glyphZeroId, this.toUnicode); this.toFontChar = newMapping.toFontChar; newCharCodeToGlyphId = newMapping.charCodeToGlyphId; + toUnicodeExtraMap = newMapping.toUnicodeExtraMap; }
const numGlyphs = font.numGlyphs; @@ -27889,7 +28656,7 @@ class Font { const builder = new _opentype_file_builder.OpenTypeFileBuilder("\x4F\x54\x54\x4F"); builder.addTable("CFF ", font.data); builder.addTable("OS/2", createOS2Table(properties, newCharCodeToGlyphId)); - builder.addTable("cmap", createCmapTable(newCharCodeToGlyphId, numGlyphs)); + builder.addTable("cmap", createCmapTable(newCharCodeToGlyphId, toUnicodeExtraMap, numGlyphs)); builder.addTable("head", "\x00\x01\x00\x00" + "\x00\x00\x10\x00" + "\x00\x00\x00\x00" + "\x5F\x0F\x3C\xF5" + "\x00\x00" + safeString16(unitsPerEm) + "\x00\x00\x00\x00\x9e\x0b\x7e\x27" + "\x00\x00\x00\x00\x9e\x0b\x7e\x27" + "\x00\x00" + safeString16(properties.descent) + "\x0F\xFF" + safeString16(properties.ascent) + string16(properties.italicAngle ? 2 : 0) + "\x00\x11" + "\x00\x00" + "\x00\x00" + "\x00\x00"); builder.addTable("hhea", "\x00\x01\x00\x00" + safeString16(properties.ascent) + safeString16(properties.descent) + "\x00\x00" + "\xFF\xFF" + "\x00\x00" + "\x00\x00" + "\x00\x00" + safeString16(properties.capHeight) + safeString16(Math.tan(properties.italicAngle) * properties.xHeight) + "\x00\x00" + "\x00\x00" + "\x00\x00" + "\x00\x00" + "\x00\x00" + "\x00\x00" + string16(numGlyphs)); builder.addTable("hmtx", function fontFieldsHmtx() { @@ -29528,10 +30295,12 @@ class CFFCompiler { const output = { data: [], length: 0, - add: function CFFCompiler_add(data) { + + add(data) { this.data = this.data.concat(data); this.length = this.data.length; } + }; const header = this.compileHeader(cff.header); output.add(header); @@ -29765,12 +30534,9 @@ class CFFCompiler { }
compileDict(dict, offsetTracker) { - let out = []; - const order = dict.order; - - for (let i = 0; i < order.length; ++i) { - const key = order[i]; + const out = [];
+ for (const key of dict.order) { if (!(key in dict.values)) { continue; } @@ -29797,7 +30563,7 @@ class CFFCompiler { switch (type) { case "num": case "sid": - out = out.concat(this.encodeNumber(value)); + out.push(...this.encodeNumber(value)); break;
case "offset": @@ -29807,15 +30573,15 @@ class CFFCompiler { offsetTracker.track(name, out.length); }
- out = out.concat([0x1d, 0, 0, 0, 0]); + out.push(0x1d, 0, 0, 0, 0); break;
case "array": case "delta": - out = out.concat(this.encodeNumber(value)); + out.push(...this.encodeNumber(value));
for (let k = 1, kk = values.length; k < kk; ++k) { - out = out.concat(this.encodeNumber(values[k])); + out.push(...this.encodeNumber(values[k])); }
break; @@ -29825,7 +30591,7 @@ class CFFCompiler { } }
- out = out.concat(dict.opcodes[key]); + out.push(...dict.opcodes[key]); }
return out; @@ -30050,7 +30816,7 @@ exports.getSerifFonts = exports.getNonStdFontMap = exports.getGlyphMapForStandar exports.getStandardFontName = getStandardFontName; exports.getSymbolsFonts = exports.getSupplementalGlyphMapForCalibri = exports.getSupplementalGlyphMapForArialBlack = exports.getStdFontMap = void 0;
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _fonts_utils = __w_pdfjs_require__(18);
@@ -30085,10 +30851,14 @@ const getStdFontMap = (0, _core_utils.getLookupTableFactory)(function (t) { t["Arial-Bold"] = "Helvetica-Bold"; t["Arial-BoldItalic"] = "Helvetica-BoldOblique"; t["Arial-Italic"] = "Helvetica-Oblique"; + t.ArialMT = "Helvetica"; t["Arial-BoldItalicMT"] = "Helvetica-BoldOblique"; t["Arial-BoldMT"] = "Helvetica-Bold"; t["Arial-ItalicMT"] = "Helvetica-Oblique"; - t.ArialMT = "Helvetica"; + t.ArialUnicodeMS = "Helvetica"; + t["ArialUnicodeMS-Bold"] = "Helvetica-Bold"; + t["ArialUnicodeMS-BoldItalic"] = "Helvetica-BoldOblique"; + t["ArialUnicodeMS-Italic"] = "Helvetica-Oblique"; t["Courier-BoldItalic"] = "Courier-BoldOblique"; t["Courier-Italic"] = "Courier-Oblique"; t.CourierNew = "Courier"; @@ -30547,6 +31317,33 @@ const getGlyphMapForStandardFonts = (0, _core_utils.getLookupTableFactory)(funct t[337] = 9552; t[493] = 1039; t[494] = 1040; + t[672] = 1488; + t[673] = 1489; + t[674] = 1490; + t[675] = 1491; + t[676] = 1492; + t[677] = 1493; + t[678] = 1494; + t[679] = 1495; + t[680] = 1496; + t[681] = 1497; + t[682] = 1498; + t[683] = 1499; + t[684] = 1500; + t[685] = 1501; + t[686] = 1502; + t[687] = 1503; + t[688] = 1504; + t[689] = 1505; + t[690] = 1506; + t[691] = 1507; + t[692] = 1508; + t[693] = 1509; + t[694] = 1510; + t[695] = 1511; + t[696] = 1512; + t[697] = 1513; + t[698] = 1514; t[705] = 1524; t[706] = 8362; t[710] = 64288; @@ -31369,7 +32166,7 @@ function compileGlyf(code, cmds, font) {
const instructionLength = getUint16(code, i); i += 2 + instructionLength; - const numberOfPoints = endPtsOfContours[endPtsOfContours.length - 1] + 1; + const numberOfPoints = endPtsOfContours.at(-1) + 1; const points = [];
while (points.length < numberOfPoints) { @@ -31433,13 +32230,13 @@ function compileGlyf(code, cmds, font) {
if (contour[0].flags & 1) { contour.push(contour[0]); - } else if (contour[contour.length - 1].flags & 1) { - contour.unshift(contour[contour.length - 1]); + } else if (contour.at(-1).flags & 1) { + contour.unshift(contour.at(-1)); } else { const p = { flags: 1, - x: (contour[0].x + contour[contour.length - 1].x) / 2, - y: (contour[0].y + contour[contour.length - 1].y) / 2 + x: (contour[0].x + contour.at(-1).x) / 2, + y: (contour[0].y + contour.at(-1).y) / 2 }; contour.unshift(p); contour.push(p); @@ -32081,7 +32878,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.getMetrics = exports.getFontBasicMetrics = void 0;
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
const getMetrics = (0, _core_utils.getLookupTableFactory)(function (t) { t.Courier = 600; @@ -35775,7 +36572,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.OpenTypeFileBuilder = void 0;
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _util = __w_pdfjs_require__(2);
@@ -35919,7 +36716,7 @@ var _cff_parser = __w_pdfjs_require__(45);
var _fonts_utils = __w_pdfjs_require__(18);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _stream = __w_pdfjs_require__(10);
@@ -36071,10 +36868,11 @@ class Type1Font {
getCharset() { const charset = [".notdef"]; - const charstrings = this.charstrings;
- for (let glyphId = 0; glyphId < charstrings.length; glyphId++) { - charset.push(charstrings[glyphId].glyphName); + for (const { + glyphName + } of this.charstrings) { + charset.push(glyphName); }
return charset; @@ -36282,7 +37080,7 @@ exports.Type1Parser = void 0;
var _encodings = __w_pdfjs_require__(19);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _stream = __w_pdfjs_require__(10);
@@ -36471,7 +37269,7 @@ const Type1CharString = function Type1CharStringClosure() {
case (12 << 8) + 6: if (seacAnalysisEnabled) { - const asb = this.stack[this.stack.length - 5]; + const asb = this.stack.at(-5); this.seac = this.stack.splice(-4, 4); this.seac[0] += this.lsb - asb; error = this.executeCommand(0, COMMAND_MAP.endchar); @@ -36782,7 +37580,7 @@ const Type1Parser = function Type1ParserClosure() { privateData } }; - let token, length, data, lenIV, encoded; + let token, length, data, lenIV;
while ((token = this.getToken()) !== null) { if (token !== "/") { @@ -36814,7 +37612,7 @@ const Type1Parser = function Type1ParserClosure() { this.getToken(); data = length > 0 ? stream.getBytes(length) : new Uint8Array(0); lenIV = program.properties.privateData.lenIV; - encoded = this.readCharStrings(data, lenIV); + const encoded = this.readCharStrings(data, lenIV); this.nextChar(); token = this.getToken();
@@ -36842,7 +37640,7 @@ const Type1Parser = function Type1ParserClosure() { this.getToken(); data = length > 0 ? stream.getBytes(length) : new Uint8Array(0); lenIV = program.properties.privateData.lenIV; - encoded = this.readCharStrings(data, lenIV); + const encoded = this.readCharStrings(data, lenIV); this.nextChar(); token = this.getToken();
@@ -36892,9 +37690,10 @@ const Type1Parser = function Type1ParserClosure() { } }
- for (let i = 0; i < charstrings.length; i++) { - const glyph = charstrings[i].glyph; - encoded = charstrings[i].encoded; + for (const { + encoded, + glyph + } of charstrings) { const charString = new Type1CharString(); const error = charString.convert(encoded, subrs, this.seacAnalysisEnabled); let output = charString.output; @@ -37013,11 +37812,11 @@ exports.getTilingPatternIR = getTilingPatternIR;
var _util = __w_pdfjs_require__(2);
-var _base_stream = __w_pdfjs_require__(9); +var _base_stream = __w_pdfjs_require__(7);
var _colorspace = __w_pdfjs_require__(24);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
const ShadingType = { FUNCTION_BASED: 1, @@ -37176,7 +37975,7 @@ class RadialAxialShading extends BaseShading { }
if (!extendEnd) { - colorStops[colorStops.length - 1][0] -= BaseShading.SMALL_NUMBER; + colorStops.at(-1)[0] -= BaseShading.SMALL_NUMBER; colorStops.push([1, background]); }
@@ -37461,12 +38260,12 @@ class MeshShading extends BaseShading { break;
case 1: - ps.push(ps[ps.length - 2], ps[ps.length - 1]); + ps.push(ps.at(-2), ps.at(-1)); verticesLeft = 1; break;
case 2: - ps.push(ps[ps.length - 3], ps[ps.length - 1]); + ps.push(ps.at(-3), ps.at(-1)); verticesLeft = 1; break; } @@ -37960,7 +38759,7 @@ var _util = __w_pdfjs_require__(2);
var _ps_parser = __w_pdfjs_require__(58);
-var _base_stream = __w_pdfjs_require__(9); +var _base_stream = __w_pdfjs_require__(7);
var _image_utils = __w_pdfjs_require__(59);
@@ -39188,7 +39987,7 @@ const PostScriptCompiler = function PostScriptCompilerClosure() { break; }
- ast1 = stack[stack.length - 1]; + ast1 = stack.at(-1);
if (ast1.type === "literal" || ast1.type === "var") { stack.push(ast1); @@ -39294,7 +40093,7 @@ var _util = __w_pdfjs_require__(2);
var _primitives = __w_pdfjs_require__(5);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
class PostScriptParser { constructor(lexer) { @@ -40309,7 +41108,7 @@ function addState(parentState, pattern, checkFn, iterateFn, processFn) { state = state[item] || (state[item] = []); }
- state[pattern[pattern.length - 1]] = { + state[pattern.at(-1)] = { checkFn, iterateFn, processFn @@ -40951,7 +41750,7 @@ var _util = __w_pdfjs_require__(2);
var _image_utils = __w_pdfjs_require__(64);
-var _base_stream = __w_pdfjs_require__(9); +var _base_stream = __w_pdfjs_require__(7);
var _colorspace = __w_pdfjs_require__(24);
@@ -41743,2086 +42542,2558 @@ function applyMaskImageData({ Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.Catalog = void 0; - -var _core_utils = __w_pdfjs_require__(8); +exports.incrementalUpdate = incrementalUpdate; +exports.writeDict = writeDict; +exports.writeObject = writeObject;
var _util = __w_pdfjs_require__(2);
var _primitives = __w_pdfjs_require__(5);
-var _name_number_tree = __w_pdfjs_require__(66); - -var _base_stream = __w_pdfjs_require__(9); - -var _cleanup_helper = __w_pdfjs_require__(67); - -var _colorspace = __w_pdfjs_require__(24); +var _core_utils = __w_pdfjs_require__(6);
-var _file_spec = __w_pdfjs_require__(68); +var _xml_parser = __w_pdfjs_require__(66);
-var _image_utils = __w_pdfjs_require__(59); +var _base_stream = __w_pdfjs_require__(7);
-var _metadata_parser = __w_pdfjs_require__(69); +var _crypto = __w_pdfjs_require__(67);
-var _struct_tree = __w_pdfjs_require__(71); +function writeObject(ref, obj, buffer, transform) { + buffer.push(`${ref.num} ${ref.gen} obj\n`);
-function fetchDestination(dest) { - if (dest instanceof _primitives.Dict) { - dest = dest.get("D"); + if (obj instanceof _primitives.Dict) { + writeDict(obj, buffer, transform); + } else if (obj instanceof _base_stream.BaseStream) { + writeStream(obj, buffer, transform); }
- return Array.isArray(dest) ? dest : null; + buffer.push("\nendobj\n"); }
-class Catalog { - constructor(pdfManager, xref) { - this.pdfManager = pdfManager; - this.xref = xref; - this._catDict = xref.getCatalogObj(); - - if (!(this._catDict instanceof _primitives.Dict)) { - throw new _util.FormatError("Catalog object is not a dictionary."); - } +function writeDict(dict, buffer, transform) { + buffer.push("<<");
- this.toplevelPagesDict; - this._actualNumPages = null; - this.fontCache = new _primitives.RefSetCache(); - this.builtInCMapCache = new Map(); - this.standardFontDataCache = new Map(); - this.globalImageCache = new _image_utils.GlobalImageCache(); - this.pageKidsCountCache = new _primitives.RefSetCache(); - this.pageIndexCache = new _primitives.RefSetCache(); - this.nonBlendModesSet = new _primitives.RefSet(); + for (const key of dict.getKeys()) { + buffer.push(` /${(0, _core_utils.escapePDFName)(key)} `); + writeValue(dict.getRaw(key), buffer, transform); }
- get version() { - const version = this._catDict.get("Version"); - - return (0, _util.shadow)(this, "version", version instanceof _primitives.Name ? version.name : null); - } + buffer.push(">>"); +}
- get lang() { - const lang = this._catDict.get("Lang"); +function writeStream(stream, buffer, transform) { + writeDict(stream.dict, buffer, transform); + buffer.push(" stream\n"); + let string = stream.getString();
- return (0, _util.shadow)(this, "lang", typeof lang === "string" ? (0, _util.stringToPDFString)(lang) : null); + if (transform !== null) { + string = transform.encryptString(string); }
- get needsRendering() { - const needsRendering = this._catDict.get("NeedsRendering"); + buffer.push(string, "\nendstream\n"); +}
- return (0, _util.shadow)(this, "needsRendering", typeof needsRendering === "boolean" ? needsRendering : false); - } +function writeArray(array, buffer, transform) { + buffer.push("["); + let first = true;
- get collection() { - let collection = null; + for (const val of array) { + if (!first) { + buffer.push(" "); + } else { + first = false; + }
- try { - const obj = this._catDict.get("Collection"); + writeValue(val, buffer, transform); + }
- if (obj instanceof _primitives.Dict && obj.size > 0) { - collection = obj; - } - } catch (ex) { - if (ex instanceof _core_utils.MissingDataException) { - throw ex; - } + buffer.push("]"); +}
- (0, _util.info)("Cannot fetch Collection entry; assuming no collection is present."); +function writeValue(value, buffer, transform) { + if (value instanceof _primitives.Name) { + buffer.push(`/${(0, _core_utils.escapePDFName)(value.name)}`); + } else if (value instanceof _primitives.Ref) { + buffer.push(`${value.num} ${value.gen} R`); + } else if (Array.isArray(value)) { + writeArray(value, buffer, transform); + } else if (typeof value === "string") { + if (transform !== null) { + value = transform.encryptString(value); }
- return (0, _util.shadow)(this, "collection", collection); + buffer.push(`(${(0, _util.escapeString)(value)})`); + } else if (typeof value === "number") { + buffer.push((0, _core_utils.numberToString)(value)); + } else if (typeof value === "boolean") { + buffer.push(value.toString()); + } else if (value instanceof _primitives.Dict) { + writeDict(value, buffer, transform); + } else if (value instanceof _base_stream.BaseStream) { + writeStream(value, buffer, transform); + } else if (value === null) { + buffer.push("null"); + } else { + (0, _util.warn)(`Unhandled value in writer: ${typeof value}, please file a bug.`); } +}
- get acroForm() { - let acroForm = null; +function writeInt(number, size, offset, buffer) { + for (let i = size + offset - 1; i > offset - 1; i--) { + buffer[i] = number & 0xff; + number >>= 8; + }
- try { - const obj = this._catDict.get("AcroForm"); + return offset + size; +}
- if (obj instanceof _primitives.Dict && obj.size > 0) { - acroForm = obj; - } - } catch (ex) { - if (ex instanceof _core_utils.MissingDataException) { - throw ex; - } +function writeString(string, offset, buffer) { + for (let i = 0, len = string.length; i < len; i++) { + buffer[offset + i] = string.charCodeAt(i) & 0xff; + } +}
- (0, _util.info)("Cannot fetch AcroForm entry; assuming no forms are present."); - } +function computeMD5(filesize, xrefInfo) { + const time = Math.floor(Date.now() / 1000); + const filename = xrefInfo.filename || ""; + const md5Buffer = [time.toString(), filename, filesize.toString()]; + let md5BufferLen = md5Buffer.reduce((a, str) => a + str.length, 0);
- return (0, _util.shadow)(this, "acroForm", acroForm); + for (const value of Object.values(xrefInfo.info)) { + md5Buffer.push(value); + md5BufferLen += value.length; }
- get acroFormRef() { - const value = this._catDict.getRaw("AcroForm"); + const array = new Uint8Array(md5BufferLen); + let offset = 0;
- return (0, _util.shadow)(this, "acroFormRef", value instanceof _primitives.Ref ? value : null); + for (const str of md5Buffer) { + writeString(str, offset, array); + offset += str.length; }
- get metadata() { - const streamRef = this._catDict.getRaw("Metadata"); + return (0, _util.bytesToString)((0, _crypto.calculateMD5)(array)); +}
- if (!(streamRef instanceof _primitives.Ref)) { - return (0, _util.shadow)(this, "metadata", null); - } +function writeXFADataForAcroform(str, newRefs) { + const xml = new _xml_parser.SimpleXMLParser({ + hasAttributes: true + }).parseFromString(str);
- let metadata = null; + for (const { + xfa + } of newRefs) { + if (!xfa) { + continue; + }
- try { - const suppressEncryption = !(this.xref.encrypt && this.xref.encrypt.encryptMetadata); - const stream = this.xref.fetch(streamRef, suppressEncryption); + const { + path, + value + } = xfa;
- if (stream instanceof _base_stream.BaseStream && stream.dict instanceof _primitives.Dict) { - const type = stream.dict.get("Type"); - const subtype = stream.dict.get("Subtype"); + if (!path) { + continue; + }
- if ((0, _primitives.isName)(type, "Metadata") && (0, _primitives.isName)(subtype, "XML")) { - const data = (0, _util.stringToUTF8String)(stream.getString()); + const node = xml.documentElement.searchNode((0, _core_utils.parseXFAPath)(path), 0);
- if (data) { - metadata = new _metadata_parser.MetadataParser(data).serializable; - } - } - } - } catch (ex) { - if (ex instanceof _core_utils.MissingDataException) { - throw ex; + if (node) { + if (Array.isArray(value)) { + node.childNodes = value.map(val => new _xml_parser.SimpleDOMNode("value", val)); + } else { + node.childNodes = [new _xml_parser.SimpleDOMNode("#text", value)]; } - - (0, _util.info)(`Skipping invalid Metadata: "${ex}".`); + } else { + (0, _util.warn)(`Node not found for path: ${path}`); } - - return (0, _util.shadow)(this, "metadata", metadata); }
- get markInfo() { - let markInfo = null; + const buffer = []; + xml.documentElement.dump(buffer); + return buffer.join(""); +}
- try { - markInfo = this._readMarkInfo(); - } catch (ex) { - if (ex instanceof _core_utils.MissingDataException) { - throw ex; - } +function updateXFA({ + xfaData, + xfaDatasetsRef, + hasXfaDatasetsEntry, + acroFormRef, + acroForm, + newRefs, + xref, + xrefInfo +}) { + if (xref === null) { + return; + }
- (0, _util.warn)("Unable to read mark info."); + if (!hasXfaDatasetsEntry) { + if (!acroFormRef) { + (0, _util.warn)("XFA - Cannot save it"); + return; }
- return (0, _util.shadow)(this, "markInfo", markInfo); - } - - _readMarkInfo() { - const obj = this._catDict.get("MarkInfo"); + const oldXfa = acroForm.get("XFA"); + const newXfa = oldXfa.slice(); + newXfa.splice(2, 0, "datasets"); + newXfa.splice(3, 0, xfaDatasetsRef); + acroForm.set("XFA", newXfa); + const encrypt = xref.encrypt; + let transform = null;
- if (!(obj instanceof _primitives.Dict)) { - return null; + if (encrypt) { + transform = encrypt.createCipherTransform(acroFormRef.num, acroFormRef.gen); }
- const markInfo = { - Marked: false, - UserProperties: false, - Suspects: false - }; + const buffer = [`${acroFormRef.num} ${acroFormRef.gen} obj\n`]; + writeDict(acroForm, buffer, transform); + buffer.push("\n"); + acroForm.set("XFA", oldXfa); + newRefs.push({ + ref: acroFormRef, + data: buffer.join("") + }); + }
- for (const key in markInfo) { - const value = obj.get(key); + if (xfaData === null) { + const datasets = xref.fetchIfRef(xfaDatasetsRef); + xfaData = writeXFADataForAcroform(datasets.getString(), newRefs); + }
- if (typeof value === "boolean") { - markInfo[key] = value; - } - } + const encrypt = xref.encrypt;
- return markInfo; + if (encrypt) { + const transform = encrypt.createCipherTransform(xfaDatasetsRef.num, xfaDatasetsRef.gen); + xfaData = transform.encryptString(xfaData); }
- get structTreeRoot() { - let structTree = null; + const data = `${xfaDatasetsRef.num} ${xfaDatasetsRef.gen} obj\n` + `<< /Type /EmbeddedFile /Length ${xfaData.length}>>\nstream\n` + xfaData + "\nendstream\nendobj\n"; + newRefs.push({ + ref: xfaDatasetsRef, + data + }); +}
- try { - structTree = this._readStructTreeRoot(); - } catch (ex) { - if (ex instanceof _core_utils.MissingDataException) { - throw ex; - } +function incrementalUpdate({ + originalData, + xrefInfo, + newRefs, + xref = null, + hasXfa = false, + xfaDatasetsRef = null, + hasXfaDatasetsEntry = false, + acroFormRef = null, + acroForm = null, + xfaData = null +}) { + if (hasXfa) { + updateXFA({ + xfaData, + xfaDatasetsRef, + hasXfaDatasetsEntry, + acroFormRef, + acroForm, + newRefs, + xref, + xrefInfo + }); + }
- (0, _util.warn)("Unable read to structTreeRoot info."); - } + const newXref = new _primitives.Dict(null); + const refForXrefTable = xrefInfo.newRef; + let buffer, baseOffset; + const lastByte = originalData.at(-1);
- return (0, _util.shadow)(this, "structTreeRoot", structTree); + if (lastByte === 0x0a || lastByte === 0x0d) { + buffer = []; + baseOffset = originalData.length; + } else { + buffer = ["\n"]; + baseOffset = originalData.length + 1; }
- _readStructTreeRoot() { - const obj = this._catDict.get("StructTreeRoot"); + newXref.set("Size", refForXrefTable.num + 1); + newXref.set("Prev", xrefInfo.startXRef); + newXref.set("Type", _primitives.Name.get("XRef"));
- if (!(obj instanceof _primitives.Dict)) { - return null; - } + if (xrefInfo.rootRef !== null) { + newXref.set("Root", xrefInfo.rootRef); + }
- const root = new _struct_tree.StructTreeRoot(obj); - root.init(); - return root; + if (xrefInfo.infoRef !== null) { + newXref.set("Info", xrefInfo.infoRef); }
- get toplevelPagesDict() { - const pagesObj = this._catDict.get("Pages"); + if (xrefInfo.encryptRef !== null) { + newXref.set("Encrypt", xrefInfo.encryptRef); + }
- if (!(pagesObj instanceof _primitives.Dict)) { - throw new _util.FormatError("Invalid top-level pages dictionary."); - } + newRefs.push({ + ref: refForXrefTable, + data: "" + }); + newRefs = newRefs.sort((a, b) => { + return a.ref.num - b.ref.num; + }); + const xrefTableData = [[0, 1, 0xffff]]; + const indexes = [0, 1]; + let maxOffset = 0;
- return (0, _util.shadow)(this, "toplevelPagesDict", pagesObj); + for (const { + ref, + data + } of newRefs) { + maxOffset = Math.max(maxOffset, baseOffset); + xrefTableData.push([1, baseOffset, Math.min(ref.gen, 0xffff)]); + baseOffset += data.length; + indexes.push(ref.num, 1); + buffer.push(data); }
- get documentOutline() { - let obj = null; - - try { - obj = this._readDocumentOutline(); - } catch (ex) { - if (ex instanceof _core_utils.MissingDataException) { - throw ex; - } + newXref.set("Index", indexes);
- (0, _util.warn)("Unable to read document outline."); - } + if (Array.isArray(xrefInfo.fileIds) && xrefInfo.fileIds.length > 0) { + const md5 = computeMD5(baseOffset, xrefInfo); + newXref.set("ID", [xrefInfo.fileIds[0], md5]); + }
- return (0, _util.shadow)(this, "documentOutline", obj); - } - - _readDocumentOutline() { - let obj = this._catDict.get("Outlines"); - - if (!(obj instanceof _primitives.Dict)) { - return null; - } - - obj = obj.getRaw("First"); + const offsetSize = Math.ceil(Math.log2(maxOffset) / 8); + const sizes = [1, offsetSize, 2]; + const structSize = sizes[0] + sizes[1] + sizes[2]; + const tableLength = structSize * xrefTableData.length; + newXref.set("W", sizes); + newXref.set("Length", tableLength); + buffer.push(`${refForXrefTable.num} ${refForXrefTable.gen} obj\n`); + writeDict(newXref, buffer, null); + buffer.push(" stream\n"); + const bufferLen = buffer.reduce((a, str) => a + str.length, 0); + const footer = `\nendstream\nendobj\nstartxref\n${baseOffset}\n%%EOF\n`; + const array = new Uint8Array(originalData.length + bufferLen + tableLength + footer.length); + array.set(originalData); + let offset = originalData.length;
- if (!(obj instanceof _primitives.Ref)) { - return null; - } + for (const str of buffer) { + writeString(str, offset, array); + offset += str.length; + }
- const root = { - items: [] - }; - const queue = [{ - obj, - parent: root - }]; - const processed = new _primitives.RefSet(); - processed.put(obj); - const xref = this.xref, - blackColor = new Uint8ClampedArray(3); + for (const [type, objOffset, gen] of xrefTableData) { + offset = writeInt(type, sizes[0], offset, array); + offset = writeInt(objOffset, sizes[1], offset, array); + offset = writeInt(gen, sizes[2], offset, array); + }
- while (queue.length > 0) { - const i = queue.shift(); - const outlineDict = xref.fetchIfRef(i.obj); + writeString(footer, offset, array); + return array; +}
- if (outlineDict === null) { - continue; - } +/***/ }), +/* 66 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- if (!outlineDict.has("Title")) { - throw new _util.FormatError("Invalid outline item encountered."); - }
- const data = { - url: null, - dest: null - }; - Catalog.parseDestDictionary({ - destDict: outlineDict, - resultObj: data, - docBaseUrl: this.pdfManager.docBaseUrl - }); - const title = outlineDict.get("Title"); - const flags = outlineDict.get("F") || 0; - const color = outlineDict.getArray("C"); - const count = outlineDict.get("Count"); - let rgbColor = blackColor;
- if (Array.isArray(color) && color.length === 3 && (color[0] !== 0 || color[1] !== 0 || color[2] !== 0)) { - rgbColor = _colorspace.ColorSpace.singletons.rgb.getRgb(color, 0); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.XMLParserErrorCode = exports.XMLParserBase = exports.SimpleXMLParser = exports.SimpleDOMNode = void 0;
- const outlineItem = { - dest: data.dest, - url: data.url, - unsafeUrl: data.unsafeUrl, - newWindow: data.newWindow, - title: (0, _util.stringToPDFString)(title), - color: rgbColor, - count: Number.isInteger(count) ? count : undefined, - bold: !!(flags & 2), - italic: !!(flags & 1), - items: [] - }; - i.parent.items.push(outlineItem); - obj = outlineDict.getRaw("First"); +var _core_utils = __w_pdfjs_require__(6);
- if (obj instanceof _primitives.Ref && !processed.has(obj)) { - queue.push({ - obj, - parent: outlineItem - }); - processed.put(obj); - } +const XMLParserErrorCode = { + NoError: 0, + EndOfDocument: -1, + UnterminatedCdat: -2, + UnterminatedXmlDeclaration: -3, + UnterminatedDoctypeDeclaration: -4, + UnterminatedComment: -5, + MalformedElement: -6, + OutOfMemory: -7, + UnterminatedAttributeValue: -8, + UnterminatedElement: -9, + ElementNeverBegun: -10 +}; +exports.XMLParserErrorCode = XMLParserErrorCode;
- obj = outlineDict.getRaw("Next"); +function isWhitespace(s, index) { + const ch = s[index]; + return ch === " " || ch === "\n" || ch === "\r" || ch === "\t"; +}
- if (obj instanceof _primitives.Ref && !processed.has(obj)) { - queue.push({ - obj, - parent: i.parent - }); - processed.put(obj); - } +function isWhitespaceString(s) { + for (let i = 0, ii = s.length; i < ii; i++) { + if (!isWhitespace(s, i)) { + return false; } - - return root.items.length > 0 ? root.items : null; }
- get permissions() { - let permissions = null; + return true; +}
- try { - permissions = this._readPermissions(); - } catch (ex) { - if (ex instanceof _core_utils.MissingDataException) { - throw ex; +class XMLParserBase { + _resolveEntities(s) { + return s.replace(/&([^;]+);/g, (all, entity) => { + if (entity.substring(0, 2) === "#x") { + return String.fromCodePoint(parseInt(entity.substring(2), 16)); + } else if (entity.substring(0, 1) === "#") { + return String.fromCodePoint(parseInt(entity.substring(1), 10)); }
- (0, _util.warn)("Unable to read permissions."); - } - - return (0, _util.shadow)(this, "permissions", permissions); - } + switch (entity) { + case "lt": + return "<";
- _readPermissions() { - const encrypt = this.xref.trailer.get("Encrypt"); + case "gt": + return ">";
- if (!(encrypt instanceof _primitives.Dict)) { - return null; - } + case "amp": + return "&";
- let flags = encrypt.get("P"); + case "quot": + return '"';
- if (typeof flags !== "number") { - return null; - } + case "apos": + return "'"; + }
- flags += 2 ** 32; - const permissions = []; + return this.onResolveEntity(entity); + }); + }
- for (const key in _util.PermissionFlag) { - const value = _util.PermissionFlag[key]; + _parseContent(s, start) { + const attributes = []; + let pos = start;
- if (flags & value) { - permissions.push(value); + function skipWs() { + while (pos < s.length && isWhitespace(s, pos)) { + ++pos; } }
- return permissions; - } + while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== ">" && s[pos] !== "/") { + ++pos; + }
- get optionalContentConfig() { - let config = null; + const name = s.substring(start, pos); + skipWs();
- try { - const properties = this._catDict.get("OCProperties"); + while (pos < s.length && s[pos] !== ">" && s[pos] !== "/" && s[pos] !== "?") { + skipWs(); + let attrName = "", + attrValue = "";
- if (!properties) { - return (0, _util.shadow)(this, "optionalContentConfig", null); + while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== "=") { + attrName += s[pos]; + ++pos; }
- const defaultConfig = properties.get("D"); + skipWs();
- if (!defaultConfig) { - return (0, _util.shadow)(this, "optionalContentConfig", null); + if (s[pos] !== "=") { + return null; }
- const groupsData = properties.get("OCGs"); + ++pos; + skipWs(); + const attrEndChar = s[pos];
- if (!Array.isArray(groupsData)) { - return (0, _util.shadow)(this, "optionalContentConfig", null); + if (attrEndChar !== '"' && attrEndChar !== "'") { + return null; }
- const groups = []; - const groupRefs = []; - - for (const groupRef of groupsData) { - if (!(groupRef instanceof _primitives.Ref)) { - continue; - } - - groupRefs.push(groupRef); - const group = this.xref.fetchIfRef(groupRef); - groups.push({ - id: groupRef.toString(), - name: typeof group.get("Name") === "string" ? (0, _util.stringToPDFString)(group.get("Name")) : null, - intent: typeof group.get("Intent") === "string" ? (0, _util.stringToPDFString)(group.get("Intent")) : null - }); - } + const attrEndIndex = s.indexOf(attrEndChar, ++pos);
- config = this._readOptionalContentConfig(defaultConfig, groupRefs); - config.groups = groups; - } catch (ex) { - if (ex instanceof _core_utils.MissingDataException) { - throw ex; + if (attrEndIndex < 0) { + return null; }
- (0, _util.warn)(`Unable to read optional content config: ${ex}`); + attrValue = s.substring(pos, attrEndIndex); + attributes.push({ + name: attrName, + value: this._resolveEntities(attrValue) + }); + pos = attrEndIndex + 1; + skipWs(); }
- return (0, _util.shadow)(this, "optionalContentConfig", config); + return { + name, + attributes, + parsed: pos - start + }; }
- _readOptionalContentConfig(config, contentGroupRefs) { - function parseOnOff(refs) { - const onParsed = []; - - if (Array.isArray(refs)) { - for (const value of refs) { - if (!(value instanceof _primitives.Ref)) { - continue; - } + _parseProcessingInstruction(s, start) { + let pos = start;
- if (contentGroupRefs.includes(value)) { - onParsed.push(value.toString()); - } - } + function skipWs() { + while (pos < s.length && isWhitespace(s, pos)) { + ++pos; } + }
- return onParsed; + while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== ">" && s[pos] !== "?" && s[pos] !== "/") { + ++pos; }
- function parseOrder(refs, nestedLevels = 0) { - if (!Array.isArray(refs)) { - return null; - } + const name = s.substring(start, pos); + skipWs(); + const attrStart = pos;
- const order = []; + while (pos < s.length && (s[pos] !== "?" || s[pos + 1] !== ">")) { + ++pos; + }
- for (const value of refs) { - if (value instanceof _primitives.Ref && contentGroupRefs.includes(value)) { - parsedOrderRefs.put(value); - order.push(value.toString()); - continue; - } + const value = s.substring(attrStart, pos); + return { + name, + value, + parsed: pos - start + }; + }
- const nestedOrder = parseNestedOrder(value, nestedLevels); + parseXml(s) { + let i = 0;
- if (nestedOrder) { - order.push(nestedOrder); - } - } + while (i < s.length) { + const ch = s[i]; + let j = i;
- if (nestedLevels > 0) { - return order; - } + if (ch === "<") { + ++j; + const ch2 = s[j]; + let q;
- const hiddenGroups = []; + switch (ch2) { + case "/": + ++j; + q = s.indexOf(">", j);
- for (const groupRef of contentGroupRefs) { - if (parsedOrderRefs.has(groupRef)) { - continue; - } + if (q < 0) { + this.onError(XMLParserErrorCode.UnterminatedElement); + return; + }
- hiddenGroups.push(groupRef.toString()); - } + this.onEndElement(s.substring(j, q)); + j = q + 1; + break;
- if (hiddenGroups.length) { - order.push({ - name: null, - order: hiddenGroups - }); - } + case "?": + ++j;
- return order; - } + const pi = this._parseProcessingInstruction(s, j);
- function parseNestedOrder(ref, nestedLevels) { - if (++nestedLevels > MAX_NESTED_LEVELS) { - (0, _util.warn)("parseNestedOrder - reached MAX_NESTED_LEVELS."); - return null; - } + if (s.substring(j + pi.parsed, j + pi.parsed + 2) !== "?>") { + this.onError(XMLParserErrorCode.UnterminatedXmlDeclaration); + return; + }
- const value = xref.fetchIfRef(ref); + this.onPi(pi.name, pi.value); + j += pi.parsed + 2; + break;
- if (!Array.isArray(value)) { - return null; - } + case "!": + if (s.substring(j + 1, j + 3) === "--") { + q = s.indexOf("-->", j + 3);
- const nestedName = xref.fetchIfRef(value[0]); + if (q < 0) { + this.onError(XMLParserErrorCode.UnterminatedComment); + return; + }
- if (typeof nestedName !== "string") { - return null; - } + this.onComment(s.substring(j + 3, q)); + j = q + 3; + } else if (s.substring(j + 1, j + 8) === "[CDATA[") { + q = s.indexOf("]]>", j + 8);
- const nestedOrder = parseOrder(value.slice(1), nestedLevels); + if (q < 0) { + this.onError(XMLParserErrorCode.UnterminatedCdat); + return; + }
- if (!nestedOrder || !nestedOrder.length) { - return null; - } + this.onCdata(s.substring(j + 8, q)); + j = q + 3; + } else if (s.substring(j + 1, j + 8) === "DOCTYPE") { + const q2 = s.indexOf("[", j + 8); + let complexDoctype = false; + q = s.indexOf(">", j + 8);
- return { - name: (0, _util.stringToPDFString)(nestedName), - order: nestedOrder - }; - } + if (q < 0) { + this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration); + return; + }
- const xref = this.xref, - parsedOrderRefs = new _primitives.RefSet(), - MAX_NESTED_LEVELS = 10; - return { - name: typeof config.get("Name") === "string" ? (0, _util.stringToPDFString)(config.get("Name")) : null, - creator: typeof config.get("Creator") === "string" ? (0, _util.stringToPDFString)(config.get("Creator")) : null, - baseState: config.get("BaseState") instanceof _primitives.Name ? config.get("BaseState").name : null, - on: parseOnOff(config.get("ON")), - off: parseOnOff(config.get("OFF")), - order: parseOrder(config.get("Order")), - groups: null - }; - } + if (q2 > 0 && q > q2) { + q = s.indexOf("]>", j + 8);
- setActualNumPages(num = null) { - this._actualNumPages = num; - } + if (q < 0) { + this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration); + return; + }
- get hasActualNumPages() { - return this._actualNumPages !== null; - } + complexDoctype = true; + }
- get _pagesCount() { - const obj = this.toplevelPagesDict.get("Count"); + const doctypeContent = s.substring(j + 8, q + (complexDoctype ? 1 : 0)); + this.onDoctype(doctypeContent); + j = q + (complexDoctype ? 2 : 1); + } else { + this.onError(XMLParserErrorCode.MalformedElement); + return; + }
- if (!Number.isInteger(obj)) { - throw new _util.FormatError("Page count in top-level pages dictionary is not an integer."); - } + break;
- return (0, _util.shadow)(this, "_pagesCount", obj); - } + default: + const content = this._parseContent(s, j);
- get numPages() { - return this.hasActualNumPages ? this._actualNumPages : this._pagesCount; - } + if (content === null) { + this.onError(XMLParserErrorCode.MalformedElement); + return; + }
- get destinations() { - const obj = this._readDests(), - dests = Object.create(null); + let isClosed = false;
- if (obj instanceof _name_number_tree.NameTree) { - for (const [key, value] of obj.getAll()) { - const dest = fetchDestination(value); + if (s.substring(j + content.parsed, j + content.parsed + 2) === "/>") { + isClosed = true; + } else if (s.substring(j + content.parsed, j + content.parsed + 1) !== ">") { + this.onError(XMLParserErrorCode.UnterminatedElement); + return; + }
- if (dest) { - dests[(0, _util.stringToPDFString)(key)] = dest; + this.onBeginElement(content.name, content.attributes, isClosed); + j += content.parsed + (isClosed ? 2 : 1); + break; + } + } else { + while (j < s.length && s[j] !== "<") { + j++; } + + const text = s.substring(i, j); + this.onText(this._resolveEntities(text)); } - } else if (obj instanceof _primitives.Dict) { - obj.forEach(function (key, value) { - const dest = fetchDestination(value);
- if (dest) { - dests[key] = dest; - } - }); + i = j; } + }
- return (0, _util.shadow)(this, "destinations", dests); + onResolveEntity(name) { + return `&${name};`; }
- getDestination(id) { - const obj = this._readDests(); + onPi(name, value) {}
- if (obj instanceof _name_number_tree.NameTree) { - const dest = fetchDestination(obj.get(id)); + onComment(text) {}
- if (dest) { - return dest; - } + onCdata(text) {}
- const allDest = this.destinations[id]; + onDoctype(doctypeContent) {}
- if (allDest) { - (0, _util.warn)(`Found "${id}" at an incorrect position in the NameTree.`); - return allDest; - } - } else if (obj instanceof _primitives.Dict) { - const dest = fetchDestination(obj.get(id)); + onText(text) {}
- if (dest) { - return dest; - } - } + onBeginElement(name, attributes, isEmpty) {}
- return null; - } + onEndElement(name) {}
- _readDests() { - const obj = this._catDict.get("Names"); + onError(code) {}
- if (obj && obj.has("Dests")) { - return new _name_number_tree.NameTree(obj.getRaw("Dests"), this.xref); - } else if (this._catDict.has("Dests")) { - return this._catDict.get("Dests"); - } +}
- return undefined; +exports.XMLParserBase = XMLParserBase; + +class SimpleDOMNode { + constructor(nodeName, nodeValue) { + this.nodeName = nodeName; + this.nodeValue = nodeValue; + Object.defineProperty(this, "parentNode", { + value: null, + writable: true + }); }
- get pageLabels() { - let obj = null; + get firstChild() { + return this.childNodes && this.childNodes[0]; + }
- try { - obj = this._readPageLabels(); - } catch (ex) { - if (ex instanceof _core_utils.MissingDataException) { - throw ex; - } + get nextSibling() { + const childNodes = this.parentNode.childNodes;
- (0, _util.warn)("Unable to read page labels."); + if (!childNodes) { + return undefined; }
- return (0, _util.shadow)(this, "pageLabels", obj); - } + const index = childNodes.indexOf(this);
- _readPageLabels() { - const obj = this._catDict.getRaw("PageLabels"); + if (index === -1) { + return undefined; + }
- if (!obj) { - return null; + return childNodes[index + 1]; + } + + get textContent() { + if (!this.childNodes) { + return this.nodeValue || ""; }
- const pageLabels = new Array(this.numPages); - let style = null, - prefix = ""; - const numberTree = new _name_number_tree.NumberTree(obj, this.xref); - const nums = numberTree.getAll(); - let currentLabel = "", - currentIndex = 1; + return this.childNodes.map(function (child) { + return child.textContent; + }).join(""); + }
- for (let i = 0, ii = this.numPages; i < ii; i++) { - const labelDict = nums.get(i); + get children() { + return this.childNodes || []; + }
- if (labelDict !== undefined) { - if (!(labelDict instanceof _primitives.Dict)) { - throw new _util.FormatError("PageLabel is not a dictionary."); - } + hasChildNodes() { + return this.childNodes && this.childNodes.length > 0; + }
- if (labelDict.has("Type") && !(0, _primitives.isName)(labelDict.get("Type"), "PageLabel")) { - throw new _util.FormatError("Invalid type in PageLabel dictionary."); - } + searchNode(paths, pos) { + if (pos >= paths.length) { + return this; + }
- if (labelDict.has("S")) { - const s = labelDict.get("S"); + const component = paths[pos]; + const stack = []; + let node = this;
- if (!(s instanceof _primitives.Name)) { - throw new _util.FormatError("Invalid style in PageLabel dictionary."); - } + while (true) { + if (component.name === node.nodeName) { + if (component.pos === 0) { + const res = node.searchNode(paths, pos + 1);
- style = s.name; + if (res !== null) { + return res; + } + } else if (stack.length === 0) { + return null; } else { - style = null; - } + const [parent] = stack.pop(); + let siblingPos = 0;
- if (labelDict.has("P")) { - const p = labelDict.get("P"); + for (const child of parent.childNodes) { + if (component.name === child.nodeName) { + if (siblingPos === component.pos) { + return child.searchNode(paths, pos + 1); + }
- if (typeof p !== "string") { - throw new _util.FormatError("Invalid prefix in PageLabel dictionary."); + siblingPos++; + } }
- prefix = (0, _util.stringToPDFString)(p); - } else { - prefix = ""; + return node.searchNode(paths, pos + 1); } + }
- if (labelDict.has("St")) { - const st = labelDict.get("St"); + if (node.childNodes && node.childNodes.length !== 0) { + stack.push([node, 0]); + node = node.childNodes[0]; + } else if (stack.length === 0) { + return null; + } else { + while (stack.length !== 0) { + const [parent, currentPos] = stack.pop(); + const newPos = currentPos + 1;
- if (!(Number.isInteger(st) && st >= 1)) { - throw new _util.FormatError("Invalid start in PageLabel dictionary."); + if (newPos < parent.childNodes.length) { + stack.push([parent, newPos]); + node = parent.childNodes[newPos]; + break; } + }
- currentIndex = st; - } else { - currentIndex = 1; + if (stack.length === 0) { + return null; } } + } + }
- switch (style) { - case "D": - currentLabel = currentIndex; - break; + dump(buffer) { + if (this.nodeName === "#text") { + buffer.push((0, _core_utils.encodeToXmlString)(this.nodeValue)); + return; + }
- case "R": - case "r": - currentLabel = (0, _core_utils.toRomanNumerals)(currentIndex, style === "r"); - break; + buffer.push(`<${this.nodeName}`);
- case "A": - case "a": - const LIMIT = 26; - const A_UPPER_CASE = 0x41, - A_LOWER_CASE = 0x61; - const baseCharCode = style === "a" ? A_LOWER_CASE : A_UPPER_CASE; - const letterIndex = currentIndex - 1; - const character = String.fromCharCode(baseCharCode + letterIndex % LIMIT); - currentLabel = character.repeat(Math.floor(letterIndex / LIMIT) + 1); - break; + if (this.attributes) { + for (const attribute of this.attributes) { + buffer.push(` ${attribute.name}="${(0, _core_utils.encodeToXmlString)(attribute.value)}"`); + } + }
- default: - if (style) { - throw new _util.FormatError(`Invalid style "${style}" in PageLabel dictionary.`); - } + if (this.hasChildNodes()) { + buffer.push(">");
- currentLabel = ""; + for (const child of this.childNodes) { + child.dump(buffer); }
- pageLabels[i] = prefix + currentLabel; - currentIndex++; + buffer.push(`</${this.nodeName}>`); + } else if (this.nodeValue) { + buffer.push(`>${(0, _core_utils.encodeToXmlString)(this.nodeValue)}</${this.nodeName}>`); + } else { + buffer.push("/>"); } - - return pageLabels; }
- get pageLayout() { - const obj = this._catDict.get("PageLayout"); - - let pageLayout = ""; +}
- if (obj instanceof _primitives.Name) { - switch (obj.name) { - case "SinglePage": - case "OneColumn": - case "TwoColumnLeft": - case "TwoColumnRight": - case "TwoPageLeft": - case "TwoPageRight": - pageLayout = obj.name; - } - } +exports.SimpleDOMNode = SimpleDOMNode;
- return (0, _util.shadow)(this, "pageLayout", pageLayout); +class SimpleXMLParser extends XMLParserBase { + constructor({ + hasAttributes = false, + lowerCaseName = false + }) { + super(); + this._currentFragment = null; + this._stack = null; + this._errorCode = XMLParserErrorCode.NoError; + this._hasAttributes = hasAttributes; + this._lowerCaseName = lowerCaseName; }
- get pageMode() { - const obj = this._catDict.get("PageMode"); + parseFromString(data) { + this._currentFragment = []; + this._stack = []; + this._errorCode = XMLParserErrorCode.NoError; + this.parseXml(data);
- let pageMode = "UseNone"; + if (this._errorCode !== XMLParserErrorCode.NoError) { + return undefined; + }
- if (obj instanceof _primitives.Name) { - switch (obj.name) { - case "UseNone": - case "UseOutlines": - case "UseThumbs": - case "FullScreen": - case "UseOC": - case "UseAttachments": - pageMode = obj.name; - } + const [documentElement] = this._currentFragment; + + if (!documentElement) { + return undefined; }
- return (0, _util.shadow)(this, "pageMode", pageMode); + return { + documentElement + }; }
- get viewerPreferences() { - const obj = this._catDict.get("ViewerPreferences"); - - if (!(obj instanceof _primitives.Dict)) { - return (0, _util.shadow)(this, "viewerPreferences", null); + onText(text) { + if (isWhitespaceString(text)) { + return; }
- let prefs = null; + const node = new SimpleDOMNode("#text", text);
- for (const key of obj.getKeys()) { - const value = obj.get(key); - let prefValue; + this._currentFragment.push(node); + }
- switch (key) { - case "HideToolbar": - case "HideMenubar": - case "HideWindowUI": - case "FitWindow": - case "CenterWindow": - case "DisplayDocTitle": - case "PickTrayByPDFSize": - if (typeof value === "boolean") { - prefValue = value; - } + onCdata(text) { + const node = new SimpleDOMNode("#text", text);
- break; + this._currentFragment.push(node); + }
- case "NonFullScreenPageMode": - if (value instanceof _primitives.Name) { - switch (value.name) { - case "UseNone": - case "UseOutlines": - case "UseThumbs": - case "UseOC": - prefValue = value.name; - break; + onBeginElement(name, attributes, isEmpty) { + if (this._lowerCaseName) { + name = name.toLowerCase(); + }
- default: - prefValue = "UseNone"; - } - } + const node = new SimpleDOMNode(name); + node.childNodes = [];
- break; + if (this._hasAttributes) { + node.attributes = attributes; + }
- case "Direction": - if (value instanceof _primitives.Name) { - switch (value.name) { - case "L2R": - case "R2L": - prefValue = value.name; - break; + this._currentFragment.push(node);
- default: - prefValue = "L2R"; - } - } + if (isEmpty) { + return; + }
- break; + this._stack.push(this._currentFragment);
- case "ViewArea": - case "ViewClip": - case "PrintArea": - case "PrintClip": - if (value instanceof _primitives.Name) { - switch (value.name) { - case "MediaBox": - case "CropBox": - case "BleedBox": - case "TrimBox": - case "ArtBox": - prefValue = value.name; - break; + this._currentFragment = node.childNodes; + }
- default: - prefValue = "CropBox"; - } - } + onEndElement(name) { + this._currentFragment = this._stack.pop() || [];
- break; + const lastElement = this._currentFragment.at(-1);
- case "PrintScaling": - if (value instanceof _primitives.Name) { - switch (value.name) { - case "None": - case "AppDefault": - prefValue = value.name; - break; + if (!lastElement) { + return null; + }
- default: - prefValue = "AppDefault"; - } - } + for (let i = 0, ii = lastElement.childNodes.length; i < ii; i++) { + lastElement.childNodes[i].parentNode = lastElement; + }
- break; + return lastElement; + }
- case "Duplex": - if (value instanceof _primitives.Name) { - switch (value.name) { - case "Simplex": - case "DuplexFlipShortEdge": - case "DuplexFlipLongEdge": - prefValue = value.name; - break; + onError(code) { + this._errorCode = code; + }
- default: - prefValue = "None"; - } - } +}
- break; +exports.SimpleXMLParser = SimpleXMLParser;
- case "PrintPageRange": - if (Array.isArray(value) && value.length % 2 === 0) { - const isValid = value.every((page, i, arr) => { - return Number.isInteger(page) && page > 0 && (i === 0 || page >= arr[i - 1]) && page <= this.numPages; - }); +/***/ }), +/* 67 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- if (isValid) { - prefValue = value; - } - }
- break;
- case "NumCopies": - if (Number.isInteger(value) && value > 0) { - prefValue = value; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.calculateSHA256 = exports.calculateMD5 = exports.PDF20 = exports.PDF17 = exports.CipherTransformFactory = exports.ARCFourCipher = exports.AES256Cipher = exports.AES128Cipher = void 0; +exports.calculateSHA384 = calculateSHA384; +exports.calculateSHA512 = void 0;
- break; +var _util = __w_pdfjs_require__(2);
- default: - (0, _util.warn)(`Ignoring non-standard key in ViewerPreferences: ${key}.`); - continue; - } +var _primitives = __w_pdfjs_require__(5);
- if (prefValue === undefined) { - (0, _util.warn)(`Bad value, for key "${key}", in ViewerPreferences: ${value}.`); - continue; - } +var _decrypt_stream = __w_pdfjs_require__(68);
- if (!prefs) { - prefs = Object.create(null); - } +class ARCFourCipher { + constructor(key) { + this.a = 0; + this.b = 0; + const s = new Uint8Array(256); + const keyLength = key.length;
- prefs[key] = prefValue; + for (let i = 0; i < 256; ++i) { + s[i] = i; }
- return (0, _util.shadow)(this, "viewerPreferences", prefs); - } - - get openAction() { - const obj = this._catDict.get("OpenAction"); + for (let i = 0, j = 0; i < 256; ++i) { + const tmp = s[i]; + j = j + tmp + key[i % keyLength] & 0xff; + s[i] = s[j]; + s[j] = tmp; + }
- const openAction = Object.create(null); + this.s = s; + }
- if (obj instanceof _primitives.Dict) { - const destDict = new _primitives.Dict(this.xref); - destDict.set("A", obj); - const resultObj = { - url: null, - dest: null, - action: null - }; - Catalog.parseDestDictionary({ - destDict, - resultObj - }); + encryptBlock(data) { + let a = this.a, + b = this.b; + const s = this.s; + const n = data.length; + const output = new Uint8Array(n);
- if (Array.isArray(resultObj.dest)) { - openAction.dest = resultObj.dest; - } else if (resultObj.action) { - openAction.action = resultObj.action; - } - } else if (Array.isArray(obj)) { - openAction.dest = obj; + for (let i = 0; i < n; ++i) { + a = a + 1 & 0xff; + const tmp = s[a]; + b = b + tmp & 0xff; + const tmp2 = s[b]; + s[a] = tmp2; + s[b] = tmp; + output[i] = data[i] ^ s[tmp + tmp2 & 0xff]; }
- return (0, _util.shadow)(this, "openAction", (0, _util.objectSize)(openAction) > 0 ? openAction : null); + this.a = a; + this.b = b; + return output; }
- get attachments() { - const obj = this._catDict.get("Names"); - - let attachments = null; + decryptBlock(data) { + return this.encryptBlock(data); + }
- if (obj instanceof _primitives.Dict && obj.has("EmbeddedFiles")) { - const nameTree = new _name_number_tree.NameTree(obj.getRaw("EmbeddedFiles"), this.xref); + encrypt(data) { + return this.encryptBlock(data); + }
- for (const [key, value] of nameTree.getAll()) { - const fs = new _file_spec.FileSpec(value, this.xref); +}
- if (!attachments) { - attachments = Object.create(null); - } +exports.ARCFourCipher = ARCFourCipher;
- attachments[(0, _util.stringToPDFString)(key)] = fs.serializable; - } - } - - return (0, _util.shadow)(this, "attachments", attachments); - } - - get xfaImages() { - const obj = this._catDict.get("Names"); - - let xfaImages = null; - - if (obj instanceof _primitives.Dict && obj.has("XFAImages")) { - const nameTree = new _name_number_tree.NameTree(obj.getRaw("XFAImages"), this.xref); +const calculateMD5 = function calculateMD5Closure() { + const r = new Uint8Array([7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]); + const k = new Int32Array([-680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, 1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632, 643717713, -373897302, -701558691, 38016083, -660478335, -405537848, 568446438, -1019803690, -187363961, 1163531501, -1444681467, -51403784, 1735328473, -1926607734, -378558, -2022574463, 1839030562, -35309556, -1530992060, 1272893353, -155497632, - [...]
- for (const [key, value] of nameTree.getAll()) { - if (!xfaImages) { - xfaImages = new _primitives.Dict(this.xref); - } + function hash(data, offset, length) { + let h0 = 1732584193, + h1 = -271733879, + h2 = -1732584194, + h3 = 271733878; + const paddedLength = length + 72 & ~63; + const padded = new Uint8Array(paddedLength); + let i, j;
- xfaImages.set((0, _util.stringToPDFString)(key), value); - } + for (i = 0; i < length; ++i) { + padded[i] = data[offset++]; }
- return (0, _util.shadow)(this, "xfaImages", xfaImages); - } - - _collectJavaScript() { - const obj = this._catDict.get("Names"); + padded[i++] = 0x80; + const n = paddedLength - 8;
- let javaScript = null; + while (i < n) { + padded[i++] = 0; + }
- function appendIfJavaScriptDict(name, jsDict) { - if (!(jsDict instanceof _primitives.Dict)) { - return; - } + padded[i++] = length << 3 & 0xff; + padded[i++] = length >> 5 & 0xff; + padded[i++] = length >> 13 & 0xff; + padded[i++] = length >> 21 & 0xff; + padded[i++] = length >>> 29 & 0xff; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + const w = new Int32Array(16);
- if (!(0, _primitives.isName)(jsDict.get("S"), "JavaScript")) { - return; + for (i = 0; i < paddedLength;) { + for (j = 0; j < 16; ++j, i += 4) { + w[j] = padded[i] | padded[i + 1] << 8 | padded[i + 2] << 16 | padded[i + 3] << 24; }
- let js = jsDict.get("JS"); + let a = h0, + b = h1, + c = h2, + d = h3, + f, + g;
- if (js instanceof _base_stream.BaseStream) { - js = js.getString(); - } else if (typeof js !== "string") { - return; - } + for (j = 0; j < 64; ++j) { + if (j < 16) { + f = b & c | ~b & d; + g = j; + } else if (j < 32) { + f = d & b | ~d & c; + g = 5 * j + 1 & 15; + } else if (j < 48) { + f = b ^ c ^ d; + g = 3 * j + 5 & 15; + } else { + f = c ^ (b | ~d); + g = 7 * j & 15; + }
- if (javaScript === null) { - javaScript = new Map(); + const tmp = d, + rotateArg = a + f + k[j] + w[g] | 0, + rotate = r[j]; + d = c; + c = b; + b = b + (rotateArg << rotate | rotateArg >>> 32 - rotate) | 0; + a = tmp; }
- javaScript.set(name, (0, _util.stringToPDFString)(js)); + h0 = h0 + a | 0; + h1 = h1 + b | 0; + h2 = h2 + c | 0; + h3 = h3 + d | 0; }
- if (obj instanceof _primitives.Dict && obj.has("JavaScript")) { - const nameTree = new _name_number_tree.NameTree(obj.getRaw("JavaScript"), this.xref); + return new Uint8Array([h0 & 0xFF, h0 >> 8 & 0xFF, h0 >> 16 & 0xFF, h0 >>> 24 & 0xFF, h1 & 0xFF, h1 >> 8 & 0xFF, h1 >> 16 & 0xFF, h1 >>> 24 & 0xFF, h2 & 0xFF, h2 >> 8 & 0xFF, h2 >> 16 & 0xFF, h2 >>> 24 & 0xFF, h3 & 0xFF, h3 >> 8 & 0xFF, h3 >> 16 & 0xFF, h3 >>> 24 & 0xFF]); + }
- for (const [key, value] of nameTree.getAll()) { - appendIfJavaScriptDict((0, _util.stringToPDFString)(key), value); - } - } + return hash; +}();
- const openAction = this._catDict.get("OpenAction"); +exports.calculateMD5 = calculateMD5;
- if (openAction) { - appendIfJavaScriptDict("OpenAction", openAction); - } +class Word64 { + constructor(highInteger, lowInteger) { + this.high = highInteger | 0; + this.low = lowInteger | 0; + }
- return javaScript; + and(word) { + this.high &= word.high; + this.low &= word.low; }
- get javaScript() { - const javaScript = this._collectJavaScript(); + xor(word) { + this.high ^= word.high; + this.low ^= word.low; + }
- return (0, _util.shadow)(this, "javaScript", javaScript ? [...javaScript.values()] : null); + or(word) { + this.high |= word.high; + this.low |= word.low; }
- get jsActions() { - const javaScript = this._collectJavaScript(); + shiftRight(places) { + if (places >= 32) { + this.low = this.high >>> places - 32 | 0; + this.high = 0; + } else { + this.low = this.low >>> places | this.high << 32 - places; + this.high = this.high >>> places | 0; + } + }
- let actions = (0, _core_utils.collectActions)(this.xref, this._catDict, _util.DocumentActionEventType); + shiftLeft(places) { + if (places >= 32) { + this.high = this.low << places - 32; + this.low = 0; + } else { + this.high = this.high << places | this.low >>> 32 - places; + this.low <<= places; + } + }
- if (javaScript) { - if (!actions) { - actions = Object.create(null); - } + rotateRight(places) { + let low, high;
- for (const [key, val] of javaScript) { - if (key in actions) { - actions[key].push(val); - } else { - actions[key] = [val]; - } - } + if (places & 32) { + high = this.low; + low = this.high; + } else { + low = this.low; + high = this.high; }
- return (0, _util.shadow)(this, "jsActions", actions); + places &= 31; + this.low = low >>> places | high << 32 - places; + this.high = high >>> places | low << 32 - places; }
- async fontFallback(id, handler) { - const translatedFonts = await Promise.all(this.fontCache); - - for (const translatedFont of translatedFonts) { - if (translatedFont.loadedName === id) { - translatedFont.fallback(handler); - return; - } - } + not() { + this.high = ~this.high; + this.low = ~this.low; }
- async cleanup(manuallyTriggered = false) { - (0, _cleanup_helper.clearGlobalCaches)(); - this.globalImageCache.clear(manuallyTriggered); - this.pageKidsCountCache.clear(); - this.pageIndexCache.clear(); - this.nonBlendModesSet.clear(); - const translatedFonts = await Promise.all(this.fontCache); + add(word) { + const lowAdd = (this.low >>> 0) + (word.low >>> 0); + let highAdd = (this.high >>> 0) + (word.high >>> 0);
- for (const { - dict - } of translatedFonts) { - delete dict.cacheKey; + if (lowAdd > 0xffffffff) { + highAdd += 1; }
- this.fontCache.clear(); - this.builtInCMapCache.clear(); - this.standardFontDataCache.clear(); + this.low = lowAdd | 0; + this.high = highAdd | 0; }
- async getPageDict(pageIndex) { - const nodesToVisit = [this.toplevelPagesDict]; - const visitedNodes = new _primitives.RefSet(); + copyTo(bytes, offset) { + bytes[offset] = this.high >>> 24 & 0xff; + bytes[offset + 1] = this.high >> 16 & 0xff; + bytes[offset + 2] = this.high >> 8 & 0xff; + bytes[offset + 3] = this.high & 0xff; + bytes[offset + 4] = this.low >>> 24 & 0xff; + bytes[offset + 5] = this.low >> 16 & 0xff; + bytes[offset + 6] = this.low >> 8 & 0xff; + bytes[offset + 7] = this.low & 0xff; + }
- const pagesRef = this._catDict.getRaw("Pages"); + assign(word) { + this.high = word.high; + this.low = word.low; + }
- if (pagesRef instanceof _primitives.Ref) { - visitedNodes.put(pagesRef); - } +}
- const xref = this.xref, - pageKidsCountCache = this.pageKidsCountCache, - pageIndexCache = this.pageIndexCache; - let currentPageIndex = 0; +const calculateSHA256 = function calculateSHA256Closure() { + function rotr(x, n) { + return x >>> n | x << 32 - n; + }
- while (nodesToVisit.length) { - const currentNode = nodesToVisit.pop(); + function ch(x, y, z) { + return x & y ^ ~x & z; + }
- if (currentNode instanceof _primitives.Ref) { - const count = pageKidsCountCache.get(currentNode); + function maj(x, y, z) { + return x & y ^ x & z ^ y & z; + }
- if (count >= 0 && currentPageIndex + count <= pageIndex) { - currentPageIndex += count; - continue; - } + function sigma(x) { + return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22); + }
- if (visitedNodes.has(currentNode)) { - throw new _util.FormatError("Pages tree contains circular reference."); - } + function sigmaPrime(x) { + return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25); + }
- visitedNodes.put(currentNode); - const obj = await xref.fetchAsync(currentNode); + function littleSigma(x) { + return rotr(x, 7) ^ rotr(x, 18) ^ x >>> 3; + }
- if (obj instanceof _primitives.Dict) { - let type = obj.getRaw("Type"); + function littleSigmaPrime(x) { + return rotr(x, 17) ^ rotr(x, 19) ^ x >>> 10; + }
- if (type instanceof _primitives.Ref) { - type = await xref.fetchAsync(type); - } + const k = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, [...]
- if ((0, _primitives.isName)(type, "Page") || !obj.has("Kids")) { - if (!pageKidsCountCache.has(currentNode)) { - pageKidsCountCache.put(currentNode, 1); - } + function hash(data, offset, length) { + let h0 = 0x6a09e667, + h1 = 0xbb67ae85, + h2 = 0x3c6ef372, + h3 = 0xa54ff53a, + h4 = 0x510e527f, + h5 = 0x9b05688c, + h6 = 0x1f83d9ab, + h7 = 0x5be0cd19; + const paddedLength = Math.ceil((length + 9) / 64) * 64; + const padded = new Uint8Array(paddedLength); + let i, j;
- if (!pageIndexCache.has(currentNode)) { - pageIndexCache.put(currentNode, currentPageIndex); - } + for (i = 0; i < length; ++i) { + padded[i] = data[offset++]; + }
- if (currentPageIndex === pageIndex) { - return [obj, currentNode]; - } + padded[i++] = 0x80; + const n = paddedLength - 8;
- currentPageIndex++; - continue; - } - } + while (i < n) { + padded[i++] = 0; + }
- nodesToVisit.push(obj); - continue; - } + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = length >>> 29 & 0xff; + padded[i++] = length >> 21 & 0xff; + padded[i++] = length >> 13 & 0xff; + padded[i++] = length >> 5 & 0xff; + padded[i++] = length << 3 & 0xff; + const w = new Uint32Array(64);
- if (!(currentNode instanceof _primitives.Dict)) { - throw new _util.FormatError("Page dictionary kid reference points to wrong type of object."); + for (i = 0; i < paddedLength;) { + for (j = 0; j < 16; ++j) { + w[j] = padded[i] << 24 | padded[i + 1] << 16 | padded[i + 2] << 8 | padded[i + 3]; + i += 4; }
- const { - objId - } = currentNode; - let count = currentNode.getRaw("Count"); - - if (count instanceof _primitives.Ref) { - count = await xref.fetchAsync(count); + for (j = 16; j < 64; ++j) { + w[j] = littleSigmaPrime(w[j - 2]) + w[j - 7] + littleSigma(w[j - 15]) + w[j - 16] | 0; }
- if (Number.isInteger(count) && count >= 0) { - if (objId && !pageKidsCountCache.has(objId)) { - pageKidsCountCache.put(objId, count); - } + let a = h0, + b = h1, + c = h2, + d = h3, + e = h4, + f = h5, + g = h6, + h = h7, + t1, + t2;
- if (currentPageIndex + count <= pageIndex) { - currentPageIndex += count; - continue; - } + for (j = 0; j < 64; ++j) { + t1 = h + sigmaPrime(e) + ch(e, f, g) + k[j] + w[j]; + t2 = sigma(a) + maj(a, b, c); + h = g; + g = f; + f = e; + e = d + t1 | 0; + d = c; + c = b; + b = a; + a = t1 + t2 | 0; }
- let kids = currentNode.getRaw("Kids"); + h0 = h0 + a | 0; + h1 = h1 + b | 0; + h2 = h2 + c | 0; + h3 = h3 + d | 0; + h4 = h4 + e | 0; + h5 = h5 + f | 0; + h6 = h6 + g | 0; + h7 = h7 + h | 0; + }
- if (kids instanceof _primitives.Ref) { - kids = await xref.fetchAsync(kids); - } + return new Uint8Array([h0 >> 24 & 0xFF, h0 >> 16 & 0xFF, h0 >> 8 & 0xFF, h0 & 0xFF, h1 >> 24 & 0xFF, h1 >> 16 & 0xFF, h1 >> 8 & 0xFF, h1 & 0xFF, h2 >> 24 & 0xFF, h2 >> 16 & 0xFF, h2 >> 8 & 0xFF, h2 & 0xFF, h3 >> 24 & 0xFF, h3 >> 16 & 0xFF, h3 >> 8 & 0xFF, h3 & 0xFF, h4 >> 24 & 0xFF, h4 >> 16 & 0xFF, h4 >> 8 & 0xFF, h4 & 0xFF, h5 >> 24 & 0xFF, h5 >> 16 & 0xFF, h5 >> 8 & 0xFF, h5 & 0xFF, h6 >> 24 & 0xFF, h6 >> 16 & 0xFF, h6 >> 8 & 0xFF, h6 & 0xFF, h7 >> 24 & 0xFF, h7 >> 16 & 0xFF, h7 > [...] + }
- if (!Array.isArray(kids)) { - let type = currentNode.getRaw("Type"); + return hash; +}();
- if (type instanceof _primitives.Ref) { - type = await xref.fetchAsync(type); - } +exports.calculateSHA256 = calculateSHA256;
- if ((0, _primitives.isName)(type, "Page") || !currentNode.has("Kids")) { - if (currentPageIndex === pageIndex) { - return [currentNode, null]; - } +const calculateSHA512 = function calculateSHA512Closure() { + function ch(result, x, y, z, tmp) { + result.assign(x); + result.and(y); + tmp.assign(x); + tmp.not(); + tmp.and(z); + result.xor(tmp); + }
- currentPageIndex++; - continue; - } + function maj(result, x, y, z, tmp) { + result.assign(x); + result.and(y); + tmp.assign(x); + tmp.and(z); + result.xor(tmp); + tmp.assign(y); + tmp.and(z); + result.xor(tmp); + }
- throw new _util.FormatError("Page dictionary kids object is not an array."); - } + function sigma(result, x, tmp) { + result.assign(x); + result.rotateRight(28); + tmp.assign(x); + tmp.rotateRight(34); + result.xor(tmp); + tmp.assign(x); + tmp.rotateRight(39); + result.xor(tmp); + }
- for (let last = kids.length - 1; last >= 0; last--) { - nodesToVisit.push(kids[last]); - } - } + function sigmaPrime(result, x, tmp) { + result.assign(x); + result.rotateRight(14); + tmp.assign(x); + tmp.rotateRight(18); + result.xor(tmp); + tmp.assign(x); + tmp.rotateRight(41); + result.xor(tmp); + }
- throw new Error(`Page index ${pageIndex} not found.`); + function littleSigma(result, x, tmp) { + result.assign(x); + result.rotateRight(1); + tmp.assign(x); + tmp.rotateRight(8); + result.xor(tmp); + tmp.assign(x); + tmp.shiftRight(7); + result.xor(tmp); }
- async getAllPageDicts(recoveryMode = false) { - const queue = [{ - currentNode: this.toplevelPagesDict, - posInKids: 0 - }]; - const visitedNodes = new _primitives.RefSet(); + function littleSigmaPrime(result, x, tmp) { + result.assign(x); + result.rotateRight(19); + tmp.assign(x); + tmp.rotateRight(61); + result.xor(tmp); + tmp.assign(x); + tmp.shiftRight(6); + result.xor(tmp); + }
- const pagesRef = this._catDict.getRaw("Pages"); + const k = [new Word64(0x428a2f98, 0xd728ae22), new Word64(0x71374491, 0x23ef65cd), new Word64(0xb5c0fbcf, 0xec4d3b2f), new Word64(0xe9b5dba5, 0x8189dbbc), new Word64(0x3956c25b, 0xf348b538), new Word64(0x59f111f1, 0xb605d019), new Word64(0x923f82a4, 0xaf194f9b), new Word64(0xab1c5ed5, 0xda6d8118), new Word64(0xd807aa98, 0xa3030242), new Word64(0x12835b01, 0x45706fbe), new Word64(0x243185be, 0x4ee4b28c), new Word64(0x550c7dc3, 0xd5ffb4e2), new Word64(0x72be5d74, 0xf27b896f), new Word64( [...]
- if (pagesRef instanceof _primitives.Ref) { - visitedNodes.put(pagesRef); - } + function hash(data, offset, length, mode384 = false) { + let h0, h1, h2, h3, h4, h5, h6, h7;
- const map = new Map(), - xref = this.xref, - pageIndexCache = this.pageIndexCache; - let pageIndex = 0; + if (!mode384) { + h0 = new Word64(0x6a09e667, 0xf3bcc908); + h1 = new Word64(0xbb67ae85, 0x84caa73b); + h2 = new Word64(0x3c6ef372, 0xfe94f82b); + h3 = new Word64(0xa54ff53a, 0x5f1d36f1); + h4 = new Word64(0x510e527f, 0xade682d1); + h5 = new Word64(0x9b05688c, 0x2b3e6c1f); + h6 = new Word64(0x1f83d9ab, 0xfb41bd6b); + h7 = new Word64(0x5be0cd19, 0x137e2179); + } else { + h0 = new Word64(0xcbbb9d5d, 0xc1059ed8); + h1 = new Word64(0x629a292a, 0x367cd507); + h2 = new Word64(0x9159015a, 0x3070dd17); + h3 = new Word64(0x152fecd8, 0xf70e5939); + h4 = new Word64(0x67332667, 0xffc00b31); + h5 = new Word64(0x8eb44a87, 0x68581511); + h6 = new Word64(0xdb0c2e0d, 0x64f98fa7); + h7 = new Word64(0x47b5481d, 0xbefa4fa4); + }
- function addPageDict(pageDict, pageRef) { - if (pageRef && !pageIndexCache.has(pageRef)) { - pageIndexCache.put(pageRef, pageIndex); - } + const paddedLength = Math.ceil((length + 17) / 128) * 128; + const padded = new Uint8Array(paddedLength); + let i, j;
- map.set(pageIndex++, [pageDict, pageRef]); + for (i = 0; i < length; ++i) { + padded[i] = data[offset++]; }
- function addPageError(error) { - if (error instanceof _core_utils.XRefEntryException && !recoveryMode) { - throw error; - } + padded[i++] = 0x80; + const n = paddedLength - 16;
- map.set(pageIndex++, [error, null]); + while (i < n) { + padded[i++] = 0; }
- while (queue.length > 0) { - const queueItem = queue[queue.length - 1]; - const { - currentNode, - posInKids - } = queueItem; - let kids = currentNode.getRaw("Kids"); + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = 0; + padded[i++] = length >>> 29 & 0xff; + padded[i++] = length >> 21 & 0xff; + padded[i++] = length >> 13 & 0xff; + padded[i++] = length >> 5 & 0xff; + padded[i++] = length << 3 & 0xff; + const w = new Array(80);
- if (kids instanceof _primitives.Ref) { - try { - kids = await xref.fetchAsync(kids); - } catch (ex) { - addPageError(ex); - break; - } - } + for (i = 0; i < 80; i++) { + w[i] = new Word64(0, 0); + }
- if (!Array.isArray(kids)) { - addPageError(new _util.FormatError("Page dictionary kids object is not an array.")); - break; + let a = new Word64(0, 0), + b = new Word64(0, 0), + c = new Word64(0, 0); + let d = new Word64(0, 0), + e = new Word64(0, 0), + f = new Word64(0, 0); + let g = new Word64(0, 0), + h = new Word64(0, 0); + const t1 = new Word64(0, 0), + t2 = new Word64(0, 0); + const tmp1 = new Word64(0, 0), + tmp2 = new Word64(0, 0); + let tmp3; + + for (i = 0; i < paddedLength;) { + for (j = 0; j < 16; ++j) { + w[j].high = padded[i] << 24 | padded[i + 1] << 16 | padded[i + 2] << 8 | padded[i + 3]; + w[j].low = padded[i + 4] << 24 | padded[i + 5] << 16 | padded[i + 6] << 8 | padded[i + 7]; + i += 8; }
- if (posInKids >= kids.length) { - queue.pop(); - continue; + for (j = 16; j < 80; ++j) { + tmp3 = w[j]; + littleSigmaPrime(tmp3, w[j - 2], tmp2); + tmp3.add(w[j - 7]); + littleSigma(tmp1, w[j - 15], tmp2); + tmp3.add(tmp1); + tmp3.add(w[j - 16]); }
- const kidObj = kids[posInKids]; - let obj; + a.assign(h0); + b.assign(h1); + c.assign(h2); + d.assign(h3); + e.assign(h4); + f.assign(h5); + g.assign(h6); + h.assign(h7);
- if (kidObj instanceof _primitives.Ref) { - if (visitedNodes.has(kidObj)) { - addPageError(new _util.FormatError("Pages tree contains circular reference.")); - break; - } + for (j = 0; j < 80; ++j) { + t1.assign(h); + sigmaPrime(tmp1, e, tmp2); + t1.add(tmp1); + ch(tmp1, e, f, g, tmp2); + t1.add(tmp1); + t1.add(k[j]); + t1.add(w[j]); + sigma(t2, a, tmp2); + maj(tmp1, a, b, c, tmp2); + t2.add(tmp1); + tmp3 = h; + h = g; + g = f; + f = e; + d.add(t1); + e = d; + d = c; + c = b; + b = a; + tmp3.assign(t1); + tmp3.add(t2); + a = tmp3; + }
- visitedNodes.put(kidObj); + h0.add(a); + h1.add(b); + h2.add(c); + h3.add(d); + h4.add(e); + h5.add(f); + h6.add(g); + h7.add(h); + }
- try { - obj = await xref.fetchAsync(kidObj); - } catch (ex) { - addPageError(ex); - break; - } - } else { - obj = kidObj; - } + let result;
- if (!(obj instanceof _primitives.Dict)) { - addPageError(new _util.FormatError("Page dictionary kid reference points to wrong type of object.")); - break; - } + if (!mode384) { + result = new Uint8Array(64); + h0.copyTo(result, 0); + h1.copyTo(result, 8); + h2.copyTo(result, 16); + h3.copyTo(result, 24); + h4.copyTo(result, 32); + h5.copyTo(result, 40); + h6.copyTo(result, 48); + h7.copyTo(result, 56); + } else { + result = new Uint8Array(48); + h0.copyTo(result, 0); + h1.copyTo(result, 8); + h2.copyTo(result, 16); + h3.copyTo(result, 24); + h4.copyTo(result, 32); + h5.copyTo(result, 40); + }
- let type = obj.getRaw("Type"); + return result; + }
- if (type instanceof _primitives.Ref) { - try { - type = await xref.fetchAsync(type); - } catch (ex) { - addPageError(ex); - break; - } - } + return hash; +}();
- if ((0, _primitives.isName)(type, "Page") || !obj.has("Kids")) { - addPageDict(obj, kidObj instanceof _primitives.Ref ? kidObj : null); - } else { - queue.push({ - currentNode: obj, - posInKids: 0 - }); - } +exports.calculateSHA512 = calculateSHA512;
- queueItem.posInKids++; - } +function calculateSHA384(data, offset, length) { + return calculateSHA512(data, offset, length, true); +}
- return map; +class NullCipher { + decryptBlock(data) { + return data; }
- getPageIndex(pageRef) { - const cachedPageIndex = this.pageIndexCache.get(pageRef); + encrypt(data) { + return data; + }
- if (cachedPageIndex !== undefined) { - return Promise.resolve(cachedPageIndex); +} + +class AESBaseCipher { + constructor() { + if (this.constructor === AESBaseCipher) { + (0, _util.unreachable)("Cannot initialize AESBaseCipher."); }
- const xref = this.xref; + this._s = new Uint8Array([0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, [...] + this._inv_s = new Uint8Array([0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x [...] + this._mix = new Uint32Array([0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xf [...] + this._mixCol = new Uint8Array(256);
- function pagesBeforeRef(kidRef) { - let total = 0, - parentRef; - return xref.fetchAsync(kidRef).then(function (node) { - if ((0, _primitives.isRefsEqual)(kidRef, pageRef) && !(0, _primitives.isDict)(node, "Page") && !(node instanceof _primitives.Dict && !node.has("Type") && node.has("Contents"))) { - throw new _util.FormatError("The reference does not point to a /Page dictionary."); - } + for (let i = 0; i < 256; i++) { + if (i < 128) { + this._mixCol[i] = i << 1; + } else { + this._mixCol[i] = i << 1 ^ 0x1b; + } + }
- if (!node) { - return null; - } + this.buffer = new Uint8Array(16); + this.bufferPosition = 0; + }
- if (!(node instanceof _primitives.Dict)) { - throw new _util.FormatError("Node must be a dictionary."); - } + _expandKey(cipherKey) { + (0, _util.unreachable)("Cannot call `_expandKey` on the base class"); + }
- parentRef = node.getRaw("Parent"); - return node.getAsync("Parent"); - }).then(function (parent) { - if (!parent) { - return null; - } + _decrypt(input, key) { + let t, u, v; + const state = new Uint8Array(16); + state.set(input);
- if (!(parent instanceof _primitives.Dict)) { - throw new _util.FormatError("Parent must be a dictionary."); - } + for (let j = 0, k = this._keySize; j < 16; ++j, ++k) { + state[j] ^= key[k]; + }
- return parent.getAsync("Kids"); - }).then(function (kids) { - if (!kids) { - return null; - } + for (let i = this._cyclesOfRepetition - 1; i >= 1; --i) { + t = state[13]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = state[1]; + state[1] = t; + t = state[14]; + u = state[10]; + state[14] = state[6]; + state[10] = state[2]; + state[6] = t; + state[2] = u; + t = state[15]; + u = state[11]; + v = state[7]; + state[15] = state[3]; + state[11] = t; + state[7] = u; + state[3] = v;
- const kidPromises = []; - let found = false; + for (let j = 0; j < 16; ++j) { + state[j] = this._inv_s[state[j]]; + }
- for (let i = 0, ii = kids.length; i < ii; i++) { - const kid = kids[i]; + for (let j = 0, k = i * 16; j < 16; ++j, ++k) { + state[j] ^= key[k]; + }
- if (!(kid instanceof _primitives.Ref)) { - throw new _util.FormatError("Kid must be a reference."); - } + for (let j = 0; j < 16; j += 4) { + const s0 = this._mix[state[j]]; + const s1 = this._mix[state[j + 1]]; + const s2 = this._mix[state[j + 2]]; + const s3 = this._mix[state[j + 3]]; + t = s0 ^ s1 >>> 8 ^ s1 << 24 ^ s2 >>> 16 ^ s2 << 16 ^ s3 >>> 24 ^ s3 << 8; + state[j] = t >>> 24 & 0xff; + state[j + 1] = t >> 16 & 0xff; + state[j + 2] = t >> 8 & 0xff; + state[j + 3] = t & 0xff; + } + }
- if ((0, _primitives.isRefsEqual)(kid, kidRef)) { - found = true; - break; - } + t = state[13]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = state[1]; + state[1] = t; + t = state[14]; + u = state[10]; + state[14] = state[6]; + state[10] = state[2]; + state[6] = t; + state[2] = u; + t = state[15]; + u = state[11]; + v = state[7]; + state[15] = state[3]; + state[11] = t; + state[7] = u; + state[3] = v;
- kidPromises.push(xref.fetchAsync(kid).then(function (obj) { - if (!(obj instanceof _primitives.Dict)) { - throw new _util.FormatError("Kid node must be a dictionary."); - } + for (let j = 0; j < 16; ++j) { + state[j] = this._inv_s[state[j]]; + state[j] ^= key[j]; + }
- if (obj.has("Count")) { - total += obj.get("Count"); - } else { - total++; - } - })); - } + return state; + }
- if (!found) { - throw new _util.FormatError("Kid reference not found in parent's kids."); - } + _encrypt(input, key) { + const s = this._s; + let t, u, v; + const state = new Uint8Array(16); + state.set(input);
- return Promise.all(kidPromises).then(function () { - return [total, parentRef]; - }); - }); + for (let j = 0; j < 16; ++j) { + state[j] ^= key[j]; }
- let total = 0; - - const next = ref => pagesBeforeRef(ref).then(args => { - if (!args) { - this.pageIndexCache.put(pageRef, total); - return total; + for (let i = 1; i < this._cyclesOfRepetition; i++) { + for (let j = 0; j < 16; ++j) { + state[j] = s[state[j]]; }
- const [count, parentRef] = args; - total += count; - return next(parentRef); - }); + v = state[1]; + state[1] = state[5]; + state[5] = state[9]; + state[9] = state[13]; + state[13] = v; + v = state[2]; + u = state[6]; + state[2] = state[10]; + state[6] = state[14]; + state[10] = v; + state[14] = u; + v = state[3]; + u = state[7]; + t = state[11]; + state[3] = state[15]; + state[7] = v; + state[11] = u; + state[15] = t;
- return next(pageRef); - } + for (let j = 0; j < 16; j += 4) { + const s0 = state[j + 0]; + const s1 = state[j + 1]; + const s2 = state[j + 2]; + const s3 = state[j + 3]; + t = s0 ^ s1 ^ s2 ^ s3; + state[j + 0] ^= t ^ this._mixCol[s0 ^ s1]; + state[j + 1] ^= t ^ this._mixCol[s1 ^ s2]; + state[j + 2] ^= t ^ this._mixCol[s2 ^ s3]; + state[j + 3] ^= t ^ this._mixCol[s3 ^ s0]; + }
- get baseUrl() { - const uri = this._catDict.get("URI"); + for (let j = 0, k = i * 16; j < 16; ++j, ++k) { + state[j] ^= key[k]; + } + }
- if (uri instanceof _primitives.Dict) { - const base = uri.get("Base"); + for (let j = 0; j < 16; ++j) { + state[j] = s[state[j]]; + }
- if (typeof base === "string") { - const absoluteUrl = (0, _util.createValidAbsoluteUrl)(base, null, { - tryConvertEncoding: true - }); + v = state[1]; + state[1] = state[5]; + state[5] = state[9]; + state[9] = state[13]; + state[13] = v; + v = state[2]; + u = state[6]; + state[2] = state[10]; + state[6] = state[14]; + state[10] = v; + state[14] = u; + v = state[3]; + u = state[7]; + t = state[11]; + state[3] = state[15]; + state[7] = v; + state[11] = u; + state[15] = t;
- if (absoluteUrl) { - return (0, _util.shadow)(this, "baseUrl", absoluteUrl.href); - } - } + for (let j = 0, k = this._keySize; j < 16; ++j, ++k) { + state[j] ^= key[k]; }
- return (0, _util.shadow)(this, "baseUrl", null); + return state; }
- static parseDestDictionary(params) { - const destDict = params.destDict; + _decryptBlock2(data, finalize) { + const sourceLength = data.length; + let buffer = this.buffer, + bufferLength = this.bufferPosition; + const result = []; + let iv = this.iv;
- if (!(destDict instanceof _primitives.Dict)) { - (0, _util.warn)("parseDestDictionary: `destDict` must be a dictionary."); - return; + for (let i = 0; i < sourceLength; ++i) { + buffer[bufferLength] = data[i]; + ++bufferLength; + + if (bufferLength < 16) { + continue; + } + + const plain = this._decrypt(buffer, this._key); + + for (let j = 0; j < 16; ++j) { + plain[j] ^= iv[j]; + } + + iv = buffer; + result.push(plain); + buffer = new Uint8Array(16); + bufferLength = 0; }
- const resultObj = params.resultObj; + this.buffer = buffer; + this.bufferLength = bufferLength; + this.iv = iv;
- if (typeof resultObj !== "object") { - (0, _util.warn)("parseDestDictionary: `resultObj` must be an object."); - return; + if (result.length === 0) { + return new Uint8Array(0); }
- const docBaseUrl = params.docBaseUrl || null; - let action = destDict.get("A"), - url, - dest; + let outputLength = 16 * result.length;
- if (!(action instanceof _primitives.Dict)) { - if (destDict.has("Dest")) { - action = destDict.get("Dest"); - } else { - action = destDict.get("AA"); + if (finalize) { + const lastBlock = result.at(-1); + let psLen = lastBlock[15];
- if (action instanceof _primitives.Dict) { - if (action.has("D")) { - action = action.get("D"); - } else if (action.has("U")) { - action = action.get("U"); + if (psLen <= 16) { + for (let i = 15, ii = 16 - psLen; i >= ii; --i) { + if (lastBlock[i] !== psLen) { + psLen = 0; + break; } } + + outputLength -= psLen; + result[result.length - 1] = lastBlock.subarray(0, 16 - psLen); } }
- if (action instanceof _primitives.Dict) { - const actionType = action.get("S"); + const output = new Uint8Array(outputLength);
- if (!(actionType instanceof _primitives.Name)) { - (0, _util.warn)("parseDestDictionary: Invalid type in Action dictionary."); - return; - } + for (let i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) { + output.set(result[i], j); + }
- const actionName = actionType.name; + return output; + }
- switch (actionName) { - case "ResetForm": - const flags = action.get("Flags"); - const include = ((typeof flags === "number" ? flags : 0) & 1) === 0; - const fields = []; - const refs = []; + decryptBlock(data, finalize, iv = null) { + const sourceLength = data.length; + const buffer = this.buffer; + let bufferLength = this.bufferPosition;
- for (const obj of action.get("Fields") || []) { - if (obj instanceof _primitives.Ref) { - refs.push(obj.toString()); - } else if (typeof obj === "string") { - fields.push((0, _util.stringToPDFString)(obj)); - } - } + if (iv) { + this.iv = iv; + } else { + for (let i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) { + buffer[bufferLength] = data[i]; + }
- resultObj.resetForm = { - fields, - refs, - include - }; - break; + if (bufferLength < 16) { + this.bufferLength = bufferLength; + return new Uint8Array(0); + }
- case "URI": - url = action.get("URI"); + this.iv = buffer; + data = data.subarray(16); + }
- if (url instanceof _primitives.Name) { - url = "/" + url.name; - } + this.buffer = new Uint8Array(16); + this.bufferLength = 0; + this.decryptBlock = this._decryptBlock2; + return this.decryptBlock(data, finalize); + }
- break; + encrypt(data, iv) { + const sourceLength = data.length; + let buffer = this.buffer, + bufferLength = this.bufferPosition; + const result = [];
- case "GoTo": - dest = action.get("D"); - break; + if (!iv) { + iv = new Uint8Array(16); + }
- case "Launch": - case "GoToR": - const urlDict = action.get("F"); + for (let i = 0; i < sourceLength; ++i) { + buffer[bufferLength] = data[i]; + ++bufferLength;
- if (urlDict instanceof _primitives.Dict) { - url = urlDict.get("F") || null; - } else if (typeof urlDict === "string") { - url = urlDict; - } + if (bufferLength < 16) { + continue; + }
- let remoteDest = action.get("D"); + for (let j = 0; j < 16; ++j) { + buffer[j] ^= iv[j]; + }
- if (remoteDest) { - if (remoteDest instanceof _primitives.Name) { - remoteDest = remoteDest.name; - } + const cipher = this._encrypt(buffer, this._key);
- if (typeof url === "string") { - const baseUrl = url.split("#")[0]; + iv = cipher; + result.push(cipher); + buffer = new Uint8Array(16); + bufferLength = 0; + }
- if (typeof remoteDest === "string") { - url = baseUrl + "#" + remoteDest; - } else if (Array.isArray(remoteDest)) { - url = baseUrl + "#" + JSON.stringify(remoteDest); - } - } - } + this.buffer = buffer; + this.bufferLength = bufferLength; + this.iv = iv;
- const newWindow = action.get("NewWindow"); + if (result.length === 0) { + return new Uint8Array(0); + }
- if (typeof newWindow === "boolean") { - resultObj.newWindow = newWindow; - } + const outputLength = 16 * result.length; + const output = new Uint8Array(outputLength);
- break; + for (let i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) { + output.set(result[i], j); + }
- case "Named": - const namedAction = action.get("N"); + return output; + }
- if (namedAction instanceof _primitives.Name) { - resultObj.action = namedAction.name; - } +}
- break; +class AES128Cipher extends AESBaseCipher { + constructor(key) { + super(); + this._cyclesOfRepetition = 10; + this._keySize = 160; + this._rcon = new Uint8Array([0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb [...] + this._key = this._expandKey(key); + }
- case "JavaScript": - const jsAction = action.get("JS"); - let js; + _expandKey(cipherKey) { + const b = 176; + const s = this._s; + const rcon = this._rcon; + const result = new Uint8Array(b); + result.set(cipherKey);
- if (jsAction instanceof _base_stream.BaseStream) { - js = jsAction.getString(); - } else if (typeof jsAction === "string") { - js = jsAction; - } + for (let j = 16, i = 1; j < b; ++i) { + let t1 = result[j - 3]; + let t2 = result[j - 2]; + let t3 = result[j - 1]; + let t4 = result[j - 4]; + t1 = s[t1]; + t2 = s[t2]; + t3 = s[t3]; + t4 = s[t4]; + t1 ^= rcon[i];
- const jsURL = js && (0, _core_utils.recoverJsURL)((0, _util.stringToPDFString)(js)); + for (let n = 0; n < 4; ++n) { + result[j] = t1 ^= result[j - 16]; + j++; + result[j] = t2 ^= result[j - 16]; + j++; + result[j] = t3 ^= result[j - 16]; + j++; + result[j] = t4 ^= result[j - 16]; + j++; + } + }
- if (jsURL) { - url = jsURL.url; - resultObj.newWindow = jsURL.newWindow; - break; - } + return result; + }
- default: - if (actionName === "JavaScript" || actionName === "SubmitForm") { - break; - } +}
- (0, _util.warn)(`parseDestDictionary - unsupported action: "${actionName}".`); - break; - } - } else if (destDict.has("Dest")) { - dest = destDict.get("Dest"); - } +exports.AES128Cipher = AES128Cipher;
- if (typeof url === "string") { - const absoluteUrl = (0, _util.createValidAbsoluteUrl)(url, docBaseUrl, { - addDefaultProtocol: true, - tryConvertEncoding: true - }); +class AES256Cipher extends AESBaseCipher { + constructor(key) { + super(); + this._cyclesOfRepetition = 14; + this._keySize = 224; + this._key = this._expandKey(key); + }
- if (absoluteUrl) { - resultObj.url = absoluteUrl.href; - } + _expandKey(cipherKey) { + const b = 240; + const s = this._s; + const result = new Uint8Array(b); + result.set(cipherKey); + let r = 1; + let t1, t2, t3, t4;
- resultObj.unsafeUrl = url; - } + for (let j = 32, i = 1; j < b; ++i) { + if (j % 32 === 16) { + t1 = s[t1]; + t2 = s[t2]; + t3 = s[t3]; + t4 = s[t4]; + } else if (j % 32 === 0) { + t1 = result[j - 3]; + t2 = result[j - 2]; + t3 = result[j - 1]; + t4 = result[j - 4]; + t1 = s[t1]; + t2 = s[t2]; + t3 = s[t3]; + t4 = s[t4]; + t1 ^= r;
- if (dest) { - if (dest instanceof _primitives.Name) { - dest = dest.name; + if ((r <<= 1) >= 256) { + r = (r ^ 0x1b) & 0xff; + } }
- if (typeof dest === "string") { - resultObj.dest = (0, _util.stringToPDFString)(dest); - } else if (Array.isArray(dest)) { - resultObj.dest = dest; + for (let n = 0; n < 4; ++n) { + result[j] = t1 ^= result[j - 32]; + j++; + result[j] = t2 ^= result[j - 32]; + j++; + result[j] = t3 ^= result[j - 32]; + j++; + result[j] = t4 ^= result[j - 32]; + j++; } } + + return result; }
}
-exports.Catalog = Catalog; - -/***/ }), -/* 66 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.NumberTree = exports.NameTree = void 0; +exports.AES256Cipher = AES256Cipher;
-var _primitives = __w_pdfjs_require__(5); +class PDF17 { + checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) { + const hashData = new Uint8Array(password.length + 56); + hashData.set(password, 0); + hashData.set(ownerValidationSalt, password.length); + hashData.set(userBytes, password.length + ownerValidationSalt.length); + const result = calculateSHA256(hashData, 0, hashData.length); + return (0, _util.isArrayEqual)(result, ownerPassword); + }
-var _util = __w_pdfjs_require__(2); + checkUserPassword(password, userValidationSalt, userPassword) { + const hashData = new Uint8Array(password.length + 8); + hashData.set(password, 0); + hashData.set(userValidationSalt, password.length); + const result = calculateSHA256(hashData, 0, hashData.length); + return (0, _util.isArrayEqual)(result, userPassword); + }
-class NameOrNumberTree { - constructor(root, xref, type) { - if (this.constructor === NameOrNumberTree) { - (0, _util.unreachable)("Cannot initialize NameOrNumberTree."); - } + getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) { + const hashData = new Uint8Array(password.length + 56); + hashData.set(password, 0); + hashData.set(ownerKeySalt, password.length); + hashData.set(userBytes, password.length + ownerKeySalt.length); + const key = calculateSHA256(hashData, 0, hashData.length); + const cipher = new AES256Cipher(key); + return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16)); + }
- this.root = root; - this.xref = xref; - this._type = type; + getUserKey(password, userKeySalt, userEncryption) { + const hashData = new Uint8Array(password.length + 8); + hashData.set(password, 0); + hashData.set(userKeySalt, password.length); + const key = calculateSHA256(hashData, 0, hashData.length); + const cipher = new AES256Cipher(key); + return cipher.decryptBlock(userEncryption, false, new Uint8Array(16)); }
- getAll() { - const map = new Map(); +}
- if (!this.root) { - return map; - } +exports.PDF17 = PDF17;
- const xref = this.xref; - const processed = new _primitives.RefSet(); - processed.put(this.root); - const queue = [this.root]; +const PDF20 = function PDF20Closure() { + function calculatePDF20Hash(password, input, userBytes) { + let k = calculateSHA256(input, 0, input.length).subarray(0, 32); + let e = [0]; + let i = 0;
- while (queue.length > 0) { - const obj = xref.fetchIfRef(queue.shift()); + while (i < 64 || e.at(-1) > i - 32) { + const combinedLength = password.length + k.length + userBytes.length, + combinedArray = new Uint8Array(combinedLength); + let writeOffset = 0; + combinedArray.set(password, writeOffset); + writeOffset += password.length; + combinedArray.set(k, writeOffset); + writeOffset += k.length; + combinedArray.set(userBytes, writeOffset); + const k1 = new Uint8Array(combinedLength * 64);
- if (!(obj instanceof _primitives.Dict)) { - continue; + for (let j = 0, pos = 0; j < 64; j++, pos += combinedLength) { + k1.set(combinedArray, pos); }
- if (obj.has("Kids")) { - const kids = obj.get("Kids"); - - if (!Array.isArray(kids)) { - continue; - } - - for (const kid of kids) { - if (processed.has(kid)) { - throw new _util.FormatError(`Duplicate entry in "${this._type}" tree.`); - } - - queue.push(kid); - processed.put(kid); - } + const cipher = new AES128Cipher(k.subarray(0, 16)); + e = cipher.encrypt(k1, k.subarray(16, 32)); + let remainder = 0;
- continue; + for (let z = 0; z < 16; z++) { + remainder *= 256 % 3; + remainder %= 3; + remainder += (e[z] >>> 0) % 3; + remainder %= 3; }
- const entries = obj.get(this._type); - - if (!Array.isArray(entries)) { - continue; + if (remainder === 0) { + k = calculateSHA256(e, 0, e.length); + } else if (remainder === 1) { + k = calculateSHA384(e, 0, e.length); + } else if (remainder === 2) { + k = calculateSHA512(e, 0, e.length); }
- for (let i = 0, ii = entries.length; i < ii; i += 2) { - map.set(xref.fetchIfRef(entries[i]), xref.fetchIfRef(entries[i + 1])); - } + i++; }
- return map; + return k.subarray(0, 32); }
- get(key) { - if (!this.root) { - return null; + class PDF20 { + hash(password, concatBytes, userBytes) { + return calculatePDF20Hash(password, concatBytes, userBytes); }
- const xref = this.xref; - let kidsOrEntries = xref.fetchIfRef(this.root); - let loopCount = 0; - const MAX_LEVELS = 10; + checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) { + const hashData = new Uint8Array(password.length + 56); + hashData.set(password, 0); + hashData.set(ownerValidationSalt, password.length); + hashData.set(userBytes, password.length + ownerValidationSalt.length); + const result = calculatePDF20Hash(password, hashData, userBytes); + return (0, _util.isArrayEqual)(result, ownerPassword); + }
- while (kidsOrEntries.has("Kids")) { - if (++loopCount > MAX_LEVELS) { - (0, _util.warn)(`Search depth limit reached for "${this._type}" tree.`); - return null; - } + checkUserPassword(password, userValidationSalt, userPassword) { + const hashData = new Uint8Array(password.length + 8); + hashData.set(password, 0); + hashData.set(userValidationSalt, password.length); + const result = calculatePDF20Hash(password, hashData, []); + return (0, _util.isArrayEqual)(result, userPassword); + }
- const kids = kidsOrEntries.get("Kids"); + getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) { + const hashData = new Uint8Array(password.length + 56); + hashData.set(password, 0); + hashData.set(ownerKeySalt, password.length); + hashData.set(userBytes, password.length + ownerKeySalt.length); + const key = calculatePDF20Hash(password, hashData, userBytes); + const cipher = new AES256Cipher(key); + return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16)); + }
- if (!Array.isArray(kids)) { - return null; - } + getUserKey(password, userKeySalt, userEncryption) { + const hashData = new Uint8Array(password.length + 8); + hashData.set(password, 0); + hashData.set(userKeySalt, password.length); + const key = calculatePDF20Hash(password, hashData, []); + const cipher = new AES256Cipher(key); + return cipher.decryptBlock(userEncryption, false, new Uint8Array(16)); + }
- let l = 0, - r = kids.length - 1; + }
- while (l <= r) { - const m = l + r >> 1; - const kid = xref.fetchIfRef(kids[m]); - const limits = kid.get("Limits"); + return PDF20; +}();
- if (key < xref.fetchIfRef(limits[0])) { - r = m - 1; - } else if (key > xref.fetchIfRef(limits[1])) { - l = m + 1; - } else { - kidsOrEntries = kid; - break; - } - } +exports.PDF20 = PDF20;
- if (l > r) { - return null; - } - } +class CipherTransform { + constructor(stringCipherConstructor, streamCipherConstructor) { + this.StringCipherConstructor = stringCipherConstructor; + this.StreamCipherConstructor = streamCipherConstructor; + }
- const entries = kidsOrEntries.get(this._type); + createStream(stream, length) { + const cipher = new this.StreamCipherConstructor(); + return new _decrypt_stream.DecryptStream(stream, length, function cipherTransformDecryptStream(data, finalize) { + return cipher.decryptBlock(data, finalize); + }); + }
- if (Array.isArray(entries)) { - let l = 0, - r = entries.length - 2; + decryptString(s) { + const cipher = new this.StringCipherConstructor(); + let data = (0, _util.stringToBytes)(s); + data = cipher.decryptBlock(data, true); + return (0, _util.bytesToString)(data); + }
- while (l <= r) { - const tmp = l + r >> 1, - m = tmp + (tmp & 1); - const currentKey = xref.fetchIfRef(entries[m]); + encryptString(s) { + const cipher = new this.StringCipherConstructor();
- if (key < currentKey) { - r = m - 2; - } else if (key > currentKey) { - l = m + 2; - } else { - return xref.fetchIfRef(entries[m + 1]); + if (cipher instanceof AESBaseCipher) { + const strLen = s.length; + const pad = 16 - strLen % 16; + s += String.fromCharCode(pad).repeat(pad); + const iv = new Uint8Array(16); + + if (typeof crypto !== "undefined") { + crypto.getRandomValues(iv); + } else { + for (let i = 0; i < 16; i++) { + iv[i] = Math.floor(256 * Math.random()); } } + + let data = (0, _util.stringToBytes)(s); + data = cipher.encrypt(data, iv); + const buf = new Uint8Array(16 + data.length); + buf.set(iv); + buf.set(data, 16); + return (0, _util.bytesToString)(buf); }
- return null; + let data = (0, _util.stringToBytes)(s); + data = cipher.encrypt(data); + return (0, _util.bytesToString)(data); }
}
-class NameTree extends NameOrNumberTree { - constructor(root, xref) { - super(root, xref, "Names"); - } +const CipherTransformFactory = function CipherTransformFactoryClosure() { + const defaultPasswordBytes = new Uint8Array([0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a]);
-} + function createEncryptionKey20(revision, password, ownerPassword, ownerValidationSalt, ownerKeySalt, uBytes, userPassword, userValidationSalt, userKeySalt, ownerEncryption, userEncryption, perms) { + if (password) { + const passwordLength = Math.min(127, password.length); + password = password.subarray(0, passwordLength); + } else { + password = []; + }
-exports.NameTree = NameTree; + let pdfAlgorithm;
-class NumberTree extends NameOrNumberTree { - constructor(root, xref) { - super(root, xref, "Nums"); + if (revision === 6) { + pdfAlgorithm = new PDF20(); + } else { + pdfAlgorithm = new PDF17(); + } + + if (pdfAlgorithm.checkUserPassword(password, userValidationSalt, userPassword)) { + return pdfAlgorithm.getUserKey(password, userKeySalt, userEncryption); + } else if (password.length && pdfAlgorithm.checkOwnerPassword(password, ownerValidationSalt, uBytes, ownerPassword)) { + return pdfAlgorithm.getOwnerKey(password, ownerKeySalt, uBytes, ownerEncryption); + } + + return null; }
-} + function prepareKeyData(fileId, password, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata) { + const hashDataSize = 40 + ownerPassword.length + fileId.length; + const hashData = new Uint8Array(hashDataSize); + let i = 0, + j, + n;
-exports.NumberTree = NumberTree; + if (password) { + n = Math.min(32, password.length);
-/***/ }), -/* 67 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + for (; i < n; ++i) { + hashData[i] = password[i]; + } + }
+ j = 0;
+ while (i < 32) { + hashData[i++] = defaultPasswordBytes[j++]; + }
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.clearGlobalCaches = clearGlobalCaches; + for (j = 0, n = ownerPassword.length; j < n; ++j) { + hashData[i++] = ownerPassword[j]; + }
-var _primitives = __w_pdfjs_require__(5); + hashData[i++] = flags & 0xff; + hashData[i++] = flags >> 8 & 0xff; + hashData[i++] = flags >> 16 & 0xff; + hashData[i++] = flags >>> 24 & 0xff;
-var _unicode = __w_pdfjs_require__(21); + for (j = 0, n = fileId.length; j < n; ++j) { + hashData[i++] = fileId[j]; + }
-function clearGlobalCaches() { - (0, _primitives.clearPrimitiveCaches)(); - (0, _unicode.clearUnicodeCaches)(); -} + if (revision >= 4 && !encryptMetadata) { + hashData[i++] = 0xff; + hashData[i++] = 0xff; + hashData[i++] = 0xff; + hashData[i++] = 0xff; + }
-/***/ }), -/* 68 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + let hash = calculateMD5(hashData, 0, i); + const keyLengthInBytes = keyLength >> 3;
+ if (revision >= 3) { + for (j = 0; j < 50; ++j) { + hash = calculateMD5(hash, 0, keyLengthInBytes); + } + }
+ const encryptionKey = hash.subarray(0, keyLengthInBytes); + let cipher, checkData;
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.FileSpec = void 0; + if (revision >= 3) { + for (i = 0; i < 32; ++i) { + hashData[i] = defaultPasswordBytes[i]; + }
-var _util = __w_pdfjs_require__(2); + for (j = 0, n = fileId.length; j < n; ++j) { + hashData[i++] = fileId[j]; + }
-var _base_stream = __w_pdfjs_require__(9); + cipher = new ARCFourCipher(encryptionKey); + checkData = cipher.encryptBlock(calculateMD5(hashData, 0, i)); + n = encryptionKey.length; + const derivedKey = new Uint8Array(n);
-var _primitives = __w_pdfjs_require__(5); + for (j = 1; j <= 19; ++j) { + for (let k = 0; k < n; ++k) { + derivedKey[k] = encryptionKey[k] ^ j; + }
-function pickPlatformItem(dict) { - if (dict.has("UF")) { - return dict.get("UF"); - } else if (dict.has("F")) { - return dict.get("F"); - } else if (dict.has("Unix")) { - return dict.get("Unix"); - } else if (dict.has("Mac")) { - return dict.get("Mac"); - } else if (dict.has("DOS")) { - return dict.get("DOS"); + cipher = new ARCFourCipher(derivedKey); + checkData = cipher.encryptBlock(checkData); + } + + for (j = 0, n = checkData.length; j < n; ++j) { + if (userPassword[j] !== checkData[j]) { + return null; + } + } + } else { + cipher = new ARCFourCipher(encryptionKey); + checkData = cipher.encryptBlock(defaultPasswordBytes); + + for (j = 0, n = checkData.length; j < n; ++j) { + if (userPassword[j] !== checkData[j]) { + return null; + } + } + } + + return encryptionKey; }
- return null; -} + function decodeUserPassword(password, ownerPassword, revision, keyLength) { + const hashData = new Uint8Array(32); + let i = 0; + const n = Math.min(32, password.length);
-class FileSpec { - constructor(root, xref) { - if (!(root instanceof _primitives.Dict)) { - return; + for (; i < n; ++i) { + hashData[i] = password[i]; }
- this.xref = xref; - this.root = root; + let j = 0;
- if (root.has("FS")) { - this.fs = root.get("FS"); + while (i < 32) { + hashData[i++] = defaultPasswordBytes[j++]; }
- this.description = root.has("Desc") ? (0, _util.stringToPDFString)(root.get("Desc")) : ""; + let hash = calculateMD5(hashData, 0, i); + const keyLengthInBytes = keyLength >> 3;
- if (root.has("RF")) { - (0, _util.warn)("Related file specifications are not supported"); + if (revision >= 3) { + for (j = 0; j < 50; ++j) { + hash = calculateMD5(hash, 0, hash.length); + } }
- this.contentAvailable = true; + let cipher, userPassword;
- if (!root.has("EF")) { - this.contentAvailable = false; - (0, _util.warn)("Non-embedded file specifications are not supported"); + if (revision >= 3) { + userPassword = ownerPassword; + const derivedKey = new Uint8Array(keyLengthInBytes); + + for (j = 19; j >= 0; j--) { + for (let k = 0; k < keyLengthInBytes; ++k) { + derivedKey[k] = hash[k] ^ j; + } + + cipher = new ARCFourCipher(derivedKey); + userPassword = cipher.encryptBlock(userPassword); + } + } else { + cipher = new ARCFourCipher(hash.subarray(0, keyLengthInBytes)); + userPassword = cipher.encryptBlock(ownerPassword); } + + return userPassword; }
- get filename() { - if (!this._filename && this.root) { - const filename = pickPlatformItem(this.root) || "unnamed"; - this._filename = (0, _util.stringToPDFString)(filename).replace(/\\/g, "\").replace(/\//g, "/").replace(/\/g, "/"); + const identityName = _primitives.Name.get("Identity"); + + function buildObjectKey(num, gen, encryptionKey, isAes = false) { + const key = new Uint8Array(encryptionKey.length + 9); + const n = encryptionKey.length; + let i; + + for (i = 0; i < n; ++i) { + key[i] = encryptionKey[i]; }
- return this._filename; + key[i++] = num & 0xff; + key[i++] = num >> 8 & 0xff; + key[i++] = num >> 16 & 0xff; + key[i++] = gen & 0xff; + key[i++] = gen >> 8 & 0xff; + + if (isAes) { + key[i++] = 0x73; + key[i++] = 0x41; + key[i++] = 0x6c; + key[i++] = 0x54; + } + + const hash = calculateMD5(key, 0, i); + return hash.subarray(0, Math.min(encryptionKey.length + 5, 16)); }
- get content() { - if (!this.contentAvailable) { - return null; + function buildCipherConstructor(cf, name, num, gen, key) { + if (!(name instanceof _primitives.Name)) { + throw new _util.FormatError("Invalid crypt filter name."); }
- if (!this.contentRef && this.root) { - this.contentRef = pickPlatformItem(this.root.get("EF")); + const cryptFilter = cf.get(name.name); + let cfm; + + if (cryptFilter !== null && cryptFilter !== undefined) { + cfm = cryptFilter.get("CFM"); }
- let content = null; + if (!cfm || cfm.name === "None") { + return function cipherTransformFactoryBuildCipherConstructorNone() { + return new NullCipher(); + }; + }
- if (this.contentRef) { - const fileObj = this.xref.fetchIfRef(this.contentRef); + if (cfm.name === "V2") { + return function cipherTransformFactoryBuildCipherConstructorV2() { + return new ARCFourCipher(buildObjectKey(num, gen, key, false)); + }; + }
- if (fileObj instanceof _base_stream.BaseStream) { - content = fileObj.getBytes(); - } else { - (0, _util.warn)("Embedded file specification points to non-existing/invalid content"); - } - } else { - (0, _util.warn)("Embedded file specification does not have a content"); + if (cfm.name === "AESV2") { + return function cipherTransformFactoryBuildCipherConstructorAESV2() { + return new AES128Cipher(buildObjectKey(num, gen, key, true)); + }; }
- return content; - } + if (cfm.name === "AESV3") { + return function cipherTransformFactoryBuildCipherConstructorAESV3() { + return new AES256Cipher(key); + }; + }
- get serializable() { - return { - filename: this.filename, - content: this.content - }; + throw new _util.FormatError("Unknown crypto method"); }
-} + class CipherTransformFactory { + constructor(dict, fileId, password) { + const filter = dict.get("Filter");
-exports.FileSpec = FileSpec; + if (!(0, _primitives.isName)(filter, "Standard")) { + throw new _util.FormatError("unknown encryption method"); + }
-/***/ }), -/* 69 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + this.filterName = filter.name; + this.dict = dict; + const algorithm = dict.get("V");
+ if (!Number.isInteger(algorithm) || algorithm !== 1 && algorithm !== 2 && algorithm !== 4 && algorithm !== 5) { + throw new _util.FormatError("unsupported encryption algorithm"); + }
+ this.algorithm = algorithm; + let keyLength = dict.get("Length");
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.MetadataParser = void 0; + if (!keyLength) { + if (algorithm <= 3) { + keyLength = 40; + } else { + const cfDict = dict.get("CF"); + const streamCryptoName = dict.get("StmF");
-var _xml_parser = __w_pdfjs_require__(70); + if (cfDict instanceof _primitives.Dict && streamCryptoName instanceof _primitives.Name) { + cfDict.suppressEncryption = true; + const handlerDict = cfDict.get(streamCryptoName.name); + keyLength = handlerDict && handlerDict.get("Length") || 128;
-class MetadataParser { - constructor(data) { - data = this._repair(data); - const parser = new _xml_parser.SimpleXMLParser({ - lowerCaseName: true - }); - const xmlDocument = parser.parseFromString(data); - this._metadataMap = new Map(); - this._data = data; + if (keyLength < 40) { + keyLength <<= 3; + } + } + } + }
- if (xmlDocument) { - this._parse(xmlDocument); - } - } + if (!Number.isInteger(keyLength) || keyLength < 40 || keyLength % 8 !== 0) { + throw new _util.FormatError("invalid key length"); + }
- _repair(data) { - return data.replace(/^[^<]+/, "").replace(/>\376\377([^<]+)/g, function (all, codes) { - const bytes = codes.replace(/\([0-3])([0-7])([0-7])/g, function (code, d1, d2, d3) { - return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1); - }).replace(/&(amp|apos|gt|lt|quot);/g, function (str, name) { - switch (name) { - case "amp": - return "&"; + const ownerPassword = (0, _util.stringToBytes)(dict.get("O")).subarray(0, 32); + const userPassword = (0, _util.stringToBytes)(dict.get("U")).subarray(0, 32); + const flags = dict.get("P"); + const revision = dict.get("R"); + const encryptMetadata = (algorithm === 4 || algorithm === 5) && dict.get("EncryptMetadata") !== false; + this.encryptMetadata = encryptMetadata; + const fileIdBytes = (0, _util.stringToBytes)(fileId); + let passwordBytes;
- case "apos": - return "'"; + if (password) { + if (revision === 6) { + try { + password = (0, _util.utf8StringToString)(password); + } catch (ex) { + (0, _util.warn)("CipherTransformFactory: " + "Unable to convert UTF8 encoded password."); + } + }
- case "gt": - return ">"; + passwordBytes = (0, _util.stringToBytes)(password); + }
- case "lt": - return "<"; + let encryptionKey;
- case "quot": - return '"'; - } + if (algorithm !== 5) { + encryptionKey = prepareKeyData(fileIdBytes, passwordBytes, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata); + } else { + const ownerValidationSalt = (0, _util.stringToBytes)(dict.get("O")).subarray(32, 40); + const ownerKeySalt = (0, _util.stringToBytes)(dict.get("O")).subarray(40, 48); + const uBytes = (0, _util.stringToBytes)(dict.get("U")).subarray(0, 48); + const userValidationSalt = (0, _util.stringToBytes)(dict.get("U")).subarray(32, 40); + const userKeySalt = (0, _util.stringToBytes)(dict.get("U")).subarray(40, 48); + const ownerEncryption = (0, _util.stringToBytes)(dict.get("OE")); + const userEncryption = (0, _util.stringToBytes)(dict.get("UE")); + const perms = (0, _util.stringToBytes)(dict.get("Perms")); + encryptionKey = createEncryptionKey20(revision, passwordBytes, ownerPassword, ownerValidationSalt, ownerKeySalt, uBytes, userPassword, userValidationSalt, userKeySalt, ownerEncryption, userEncryption, perms); + }
- throw new Error(`_repair: ${name} isn't defined.`); - }); - const charBuf = []; + if (!encryptionKey && !password) { + throw new _util.PasswordException("No password given", _util.PasswordResponses.NEED_PASSWORD); + } else if (!encryptionKey && password) { + const decodedPassword = decodeUserPassword(passwordBytes, ownerPassword, revision, keyLength); + encryptionKey = prepareKeyData(fileIdBytes, decodedPassword, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata); + }
- for (let i = 0, ii = bytes.length; i < ii; i += 2) { - const code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1); + if (!encryptionKey) { + throw new _util.PasswordException("Incorrect Password", _util.PasswordResponses.INCORRECT_PASSWORD); + }
- if (code >= 32 && code < 127 && code !== 60 && code !== 62 && code !== 38) { - charBuf.push(String.fromCharCode(code)); - } else { - charBuf.push("&#x" + (0x10000 + code).toString(16).substring(1) + ";"); + this.encryptionKey = encryptionKey; + + if (algorithm >= 4) { + const cf = dict.get("CF"); + + if (cf instanceof _primitives.Dict) { + cf.suppressEncryption = true; } + + this.cf = cf; + this.stmf = dict.get("StmF") || identityName; + this.strf = dict.get("StrF") || identityName; + this.eff = dict.get("EFF") || this.stmf; } + }
- return ">" + charBuf.join(""); - }); - } + createCipherTransform(num, gen) { + if (this.algorithm === 4 || this.algorithm === 5) { + return new CipherTransform(buildCipherConstructor(this.cf, this.stmf, num, gen, this.encryptionKey), buildCipherConstructor(this.cf, this.strf, num, gen, this.encryptionKey)); + }
- _getSequence(entry) { - const name = entry.nodeName; + const key = buildObjectKey(num, gen, this.encryptionKey, false);
- if (name !== "rdf:bag" && name !== "rdf:seq" && name !== "rdf:alt") { - return null; + const cipherConstructor = function buildCipherCipherConstructor() { + return new ARCFourCipher(key); + }; + + return new CipherTransform(cipherConstructor, cipherConstructor); }
- return entry.childNodes.filter(node => node.nodeName === "rdf:li"); }
- _parseArray(entry) { - if (!entry.hasChildNodes()) { - return; - } + return CipherTransformFactory; +}();
- const [seqNode] = entry.childNodes; - const sequence = this._getSequence(seqNode) || []; +exports.CipherTransformFactory = CipherTransformFactory;
- this._metadataMap.set(entry.nodeName, sequence.map(node => node.textContent.trim())); - } +/***/ }), +/* 68 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- _parse(xmlDocument) { - let rdf = xmlDocument.documentElement;
- if (rdf.nodeName !== "rdf:rdf") { - rdf = rdf.firstChild;
- while (rdf && rdf.nodeName !== "rdf:rdf") { - rdf = rdf.nextSibling; - } - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.DecryptStream = void 0;
- if (!rdf || rdf.nodeName !== "rdf:rdf" || !rdf.hasChildNodes()) { - return; - } +var _decode_stream = __w_pdfjs_require__(29);
- for (const desc of rdf.childNodes) { - if (desc.nodeName !== "rdf:description") { - continue; - } +const chunkSize = 512;
- for (const entry of desc.childNodes) { - const name = entry.nodeName; +class DecryptStream extends _decode_stream.DecodeStream { + constructor(str, maybeLength, decrypt) { + super(maybeLength); + this.str = str; + this.dict = str.dict; + this.decrypt = decrypt; + this.nextChunk = null; + this.initialized = false; + }
- switch (name) { - case "#text": - continue; + readBlock() { + let chunk;
- case "dc:creator": - case "dc:subject": - this._parseArray(entry); + if (this.initialized) { + chunk = this.nextChunk; + } else { + chunk = this.str.getBytes(chunkSize); + this.initialized = true; + }
- continue; - } + if (!chunk || chunk.length === 0) { + this.eof = true; + return; + }
- this._metadataMap.set(name, entry.textContent.trim()); - } + this.nextChunk = this.str.getBytes(chunkSize); + const hasMoreData = this.nextChunk && this.nextChunk.length > 0; + const decrypt = this.decrypt; + chunk = decrypt(chunk, !hasMoreData); + let bufferLength = this.bufferLength; + const n = chunk.length, + buffer = this.ensureBuffer(bufferLength + n); + + for (let i = 0; i < n; i++) { + buffer[bufferLength++] = chunk[i]; } - }
- get serializable() { - return { - parsedData: this._metadataMap, - rawData: this._data - }; + this.bufferLength = bufferLength; }
}
-exports.MetadataParser = MetadataParser; +exports.DecryptStream = DecryptStream;
/***/ }), -/* 70 */ +/* 69 */ /***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
@@ -43830,3078 +45101,2603 @@ exports.MetadataParser = MetadataParser; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.XMLParserErrorCode = exports.XMLParserBase = exports.SimpleXMLParser = exports.SimpleDOMNode = void 0; +exports.Catalog = void 0;
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
-const XMLParserErrorCode = { - NoError: 0, - EndOfDocument: -1, - UnterminatedCdat: -2, - UnterminatedXmlDeclaration: -3, - UnterminatedDoctypeDeclaration: -4, - UnterminatedComment: -5, - MalformedElement: -6, - OutOfMemory: -7, - UnterminatedAttributeValue: -8, - UnterminatedElement: -9, - ElementNeverBegun: -10 -}; -exports.XMLParserErrorCode = XMLParserErrorCode; +var _util = __w_pdfjs_require__(2);
-function isWhitespace(s, index) { - const ch = s[index]; - return ch === " " || ch === "\n" || ch === "\r" || ch === "\t"; -} +var _primitives = __w_pdfjs_require__(5);
-function isWhitespaceString(s) { - for (let i = 0, ii = s.length; i < ii; i++) { - if (!isWhitespace(s, i)) { - return false; - } - } +var _name_number_tree = __w_pdfjs_require__(70);
- return true; -} +var _base_stream = __w_pdfjs_require__(7);
-class XMLParserBase { - _resolveEntities(s) { - return s.replace(/&([^;]+);/g, (all, entity) => { - if (entity.substring(0, 2) === "#x") { - return String.fromCodePoint(parseInt(entity.substring(2), 16)); - } else if (entity.substring(0, 1) === "#") { - return String.fromCodePoint(parseInt(entity.substring(1), 10)); - } +var _cleanup_helper = __w_pdfjs_require__(71);
- switch (entity) { - case "lt": - return "<"; +var _colorspace = __w_pdfjs_require__(24);
- case "gt": - return ">"; +var _file_spec = __w_pdfjs_require__(72);
- case "amp": - return "&"; +var _image_utils = __w_pdfjs_require__(59);
- case "quot": - return '"'; +var _metadata_parser = __w_pdfjs_require__(73);
- case "apos": - return "'"; - } +var _struct_tree = __w_pdfjs_require__(74);
- return this.onResolveEntity(entity); - }); +function fetchDestination(dest) { + if (dest instanceof _primitives.Dict) { + dest = dest.get("D"); }
- _parseContent(s, start) { - const attributes = []; - let pos = start; + return Array.isArray(dest) ? dest : null; +}
- function skipWs() { - while (pos < s.length && isWhitespace(s, pos)) { - ++pos; - } - } +class Catalog { + constructor(pdfManager, xref) { + this.pdfManager = pdfManager; + this.xref = xref; + this._catDict = xref.getCatalogObj();
- while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== ">" && s[pos] !== "/") { - ++pos; + if (!(this._catDict instanceof _primitives.Dict)) { + throw new _util.FormatError("Catalog object is not a dictionary."); }
- const name = s.substring(start, pos); - skipWs(); + this.toplevelPagesDict; + this._actualNumPages = null; + this.fontCache = new _primitives.RefSetCache(); + this.builtInCMapCache = new Map(); + this.standardFontDataCache = new Map(); + this.globalImageCache = new _image_utils.GlobalImageCache(); + this.pageKidsCountCache = new _primitives.RefSetCache(); + this.pageIndexCache = new _primitives.RefSetCache(); + this.nonBlendModesSet = new _primitives.RefSet(); + }
- while (pos < s.length && s[pos] !== ">" && s[pos] !== "/" && s[pos] !== "?") { - skipWs(); - let attrName = "", - attrValue = ""; + get version() { + const version = this._catDict.get("Version");
- while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== "=") { - attrName += s[pos]; - ++pos; - } + return (0, _util.shadow)(this, "version", version instanceof _primitives.Name ? version.name : null); + }
- skipWs(); + get lang() { + const lang = this._catDict.get("Lang");
- if (s[pos] !== "=") { - return null; - } + return (0, _util.shadow)(this, "lang", typeof lang === "string" ? (0, _util.stringToPDFString)(lang) : null); + }
- ++pos; - skipWs(); - const attrEndChar = s[pos]; + get needsRendering() { + const needsRendering = this._catDict.get("NeedsRendering");
- if (attrEndChar !== '"' && attrEndChar !== "'") { - return null; - } + return (0, _util.shadow)(this, "needsRendering", typeof needsRendering === "boolean" ? needsRendering : false); + }
- const attrEndIndex = s.indexOf(attrEndChar, ++pos); + get collection() { + let collection = null;
- if (attrEndIndex < 0) { - return null; + try { + const obj = this._catDict.get("Collection"); + + if (obj instanceof _primitives.Dict && obj.size > 0) { + collection = obj; + } + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; }
- attrValue = s.substring(pos, attrEndIndex); - attributes.push({ - name: attrName, - value: this._resolveEntities(attrValue) - }); - pos = attrEndIndex + 1; - skipWs(); + (0, _util.info)("Cannot fetch Collection entry; assuming no collection is present."); }
- return { - name, - attributes, - parsed: pos - start - }; + return (0, _util.shadow)(this, "collection", collection); }
- _parseProcessingInstruction(s, start) { - let pos = start; + get acroForm() { + let acroForm = null;
- function skipWs() { - while (pos < s.length && isWhitespace(s, pos)) { - ++pos; + try { + const obj = this._catDict.get("AcroForm"); + + if (obj instanceof _primitives.Dict && obj.size > 0) { + acroForm = obj; + } + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; } - }
- while (pos < s.length && !isWhitespace(s, pos) && s[pos] !== ">" && s[pos] !== "?" && s[pos] !== "/") { - ++pos; + (0, _util.info)("Cannot fetch AcroForm entry; assuming no forms are present."); }
- const name = s.substring(start, pos); - skipWs(); - const attrStart = pos; + return (0, _util.shadow)(this, "acroForm", acroForm); + }
- while (pos < s.length && (s[pos] !== "?" || s[pos + 1] !== ">")) { - ++pos; - } + get acroFormRef() { + const value = this._catDict.getRaw("AcroForm");
- const value = s.substring(attrStart, pos); - return { - name, - value, - parsed: pos - start - }; + return (0, _util.shadow)(this, "acroFormRef", value instanceof _primitives.Ref ? value : null); }
- parseXml(s) { - let i = 0; + get metadata() { + const streamRef = this._catDict.getRaw("Metadata");
- while (i < s.length) { - const ch = s[i]; - let j = i; + if (!(streamRef instanceof _primitives.Ref)) { + return (0, _util.shadow)(this, "metadata", null); + }
- if (ch === "<") { - ++j; - const ch2 = s[j]; - let q; + let metadata = null;
- switch (ch2) { - case "/": - ++j; - q = s.indexOf(">", j); + try { + const suppressEncryption = !(this.xref.encrypt && this.xref.encrypt.encryptMetadata); + const stream = this.xref.fetch(streamRef, suppressEncryption);
- if (q < 0) { - this.onError(XMLParserErrorCode.UnterminatedElement); - return; - } + if (stream instanceof _base_stream.BaseStream && stream.dict instanceof _primitives.Dict) { + const type = stream.dict.get("Type"); + const subtype = stream.dict.get("Subtype");
- this.onEndElement(s.substring(j, q)); - j = q + 1; - break; + if ((0, _primitives.isName)(type, "Metadata") && (0, _primitives.isName)(subtype, "XML")) { + const data = (0, _util.stringToUTF8String)(stream.getString());
- case "?": - ++j; + if (data) { + metadata = new _metadata_parser.MetadataParser(data).serializable; + } + } + } + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + }
- const pi = this._parseProcessingInstruction(s, j); + (0, _util.info)(`Skipping invalid Metadata: "${ex}".`); + }
- if (s.substring(j + pi.parsed, j + pi.parsed + 2) !== "?>") { - this.onError(XMLParserErrorCode.UnterminatedXmlDeclaration); - return; - } + return (0, _util.shadow)(this, "metadata", metadata); + }
- this.onPi(pi.name, pi.value); - j += pi.parsed + 2; - break; + get markInfo() { + let markInfo = null;
- case "!": - if (s.substring(j + 1, j + 3) === "--") { - q = s.indexOf("-->", j + 3); + try { + markInfo = this._readMarkInfo(); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + }
- if (q < 0) { - this.onError(XMLParserErrorCode.UnterminatedComment); - return; - } + (0, _util.warn)("Unable to read mark info."); + }
- this.onComment(s.substring(j + 3, q)); - j = q + 3; - } else if (s.substring(j + 1, j + 8) === "[CDATA[") { - q = s.indexOf("]]>", j + 8); + return (0, _util.shadow)(this, "markInfo", markInfo); + }
- if (q < 0) { - this.onError(XMLParserErrorCode.UnterminatedCdat); - return; - } + _readMarkInfo() { + const obj = this._catDict.get("MarkInfo");
- this.onCdata(s.substring(j + 8, q)); - j = q + 3; - } else if (s.substring(j + 1, j + 8) === "DOCTYPE") { - const q2 = s.indexOf("[", j + 8); - let complexDoctype = false; - q = s.indexOf(">", j + 8); + if (!(obj instanceof _primitives.Dict)) { + return null; + }
- if (q < 0) { - this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration); - return; - } + const markInfo = { + Marked: false, + UserProperties: false, + Suspects: false + };
- if (q2 > 0 && q > q2) { - q = s.indexOf("]>", j + 8); + for (const key in markInfo) { + const value = obj.get(key);
- if (q < 0) { - this.onError(XMLParserErrorCode.UnterminatedDoctypeDeclaration); - return; - } + if (typeof value === "boolean") { + markInfo[key] = value; + } + }
- complexDoctype = true; - } + return markInfo; + }
- const doctypeContent = s.substring(j + 8, q + (complexDoctype ? 1 : 0)); - this.onDoctype(doctypeContent); - j = q + (complexDoctype ? 2 : 1); - } else { - this.onError(XMLParserErrorCode.MalformedElement); - return; - } + get structTreeRoot() { + let structTree = null;
- break; + try { + structTree = this._readStructTreeRoot(); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + }
- default: - const content = this._parseContent(s, j); + (0, _util.warn)("Unable read to structTreeRoot info."); + }
- if (content === null) { - this.onError(XMLParserErrorCode.MalformedElement); - return; - } + return (0, _util.shadow)(this, "structTreeRoot", structTree); + }
- let isClosed = false; + _readStructTreeRoot() { + const obj = this._catDict.get("StructTreeRoot");
- if (s.substring(j + content.parsed, j + content.parsed + 2) === "/>") { - isClosed = true; - } else if (s.substring(j + content.parsed, j + content.parsed + 1) !== ">") { - this.onError(XMLParserErrorCode.UnterminatedElement); - return; - } + if (!(obj instanceof _primitives.Dict)) { + return null; + }
- this.onBeginElement(content.name, content.attributes, isClosed); - j += content.parsed + (isClosed ? 2 : 1); - break; - } - } else { - while (j < s.length && s[j] !== "<") { - j++; - } + const root = new _struct_tree.StructTreeRoot(obj); + root.init(); + return root; + }
- const text = s.substring(i, j); - this.onText(this._resolveEntities(text)); - } + get toplevelPagesDict() { + const pagesObj = this._catDict.get("Pages");
- i = j; + if (!(pagesObj instanceof _primitives.Dict)) { + throw new _util.FormatError("Invalid top-level pages dictionary."); } - }
- onResolveEntity(name) { - return `&${name};`; + return (0, _util.shadow)(this, "toplevelPagesDict", pagesObj); }
- onPi(name, value) {} + get documentOutline() { + let obj = null;
- onComment(text) {} + try { + obj = this._readDocumentOutline(); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + }
- onCdata(text) {} + (0, _util.warn)("Unable to read document outline."); + }
- onDoctype(doctypeContent) {} + return (0, _util.shadow)(this, "documentOutline", obj); + }
- onText(text) {} + _readDocumentOutline() { + let obj = this._catDict.get("Outlines");
- onBeginElement(name, attributes, isEmpty) {} + if (!(obj instanceof _primitives.Dict)) { + return null; + }
- onEndElement(name) {} + obj = obj.getRaw("First");
- onError(code) {} + if (!(obj instanceof _primitives.Ref)) { + return null; + }
-} + const root = { + items: [] + }; + const queue = [{ + obj, + parent: root + }]; + const processed = new _primitives.RefSet(); + processed.put(obj); + const xref = this.xref, + blackColor = new Uint8ClampedArray(3);
-exports.XMLParserBase = XMLParserBase; + while (queue.length > 0) { + const i = queue.shift(); + const outlineDict = xref.fetchIfRef(i.obj);
-class SimpleDOMNode { - constructor(nodeName, nodeValue) { - this.nodeName = nodeName; - this.nodeValue = nodeValue; - Object.defineProperty(this, "parentNode", { - value: null, - writable: true - }); - } + if (outlineDict === null) { + continue; + }
- get firstChild() { - return this.childNodes && this.childNodes[0]; - } + if (!outlineDict.has("Title")) { + throw new _util.FormatError("Invalid outline item encountered."); + }
- get nextSibling() { - const childNodes = this.parentNode.childNodes; + const data = { + url: null, + dest: null + }; + Catalog.parseDestDictionary({ + destDict: outlineDict, + resultObj: data, + docBaseUrl: this.pdfManager.docBaseUrl + }); + const title = outlineDict.get("Title"); + const flags = outlineDict.get("F") || 0; + const color = outlineDict.getArray("C"); + const count = outlineDict.get("Count"); + let rgbColor = blackColor;
- if (!childNodes) { - return undefined; - } + if (Array.isArray(color) && color.length === 3 && (color[0] !== 0 || color[1] !== 0 || color[2] !== 0)) { + rgbColor = _colorspace.ColorSpace.singletons.rgb.getRgb(color, 0); + }
- const index = childNodes.indexOf(this); + const outlineItem = { + dest: data.dest, + url: data.url, + unsafeUrl: data.unsafeUrl, + newWindow: data.newWindow, + title: (0, _util.stringToPDFString)(title), + color: rgbColor, + count: Number.isInteger(count) ? count : undefined, + bold: !!(flags & 2), + italic: !!(flags & 1), + items: [] + }; + i.parent.items.push(outlineItem); + obj = outlineDict.getRaw("First");
- if (index === -1) { - return undefined; - } + if (obj instanceof _primitives.Ref && !processed.has(obj)) { + queue.push({ + obj, + parent: outlineItem + }); + processed.put(obj); + }
- return childNodes[index + 1]; - } + obj = outlineDict.getRaw("Next");
- get textContent() { - if (!this.childNodes) { - return this.nodeValue || ""; + if (obj instanceof _primitives.Ref && !processed.has(obj)) { + queue.push({ + obj, + parent: i.parent + }); + processed.put(obj); + } }
- return this.childNodes.map(function (child) { - return child.textContent; - }).join(""); + return root.items.length > 0 ? root.items : null; }
- get children() { - return this.childNodes || []; - } + get permissions() { + let permissions = null;
- hasChildNodes() { - return this.childNodes && this.childNodes.length > 0; - } + try { + permissions = this._readPermissions(); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + }
- searchNode(paths, pos) { - if (pos >= paths.length) { - return this; + (0, _util.warn)("Unable to read permissions."); }
- const component = paths[pos]; - const stack = []; - let node = this; + return (0, _util.shadow)(this, "permissions", permissions); + }
- while (true) { - if (component.name === node.nodeName) { - if (component.pos === 0) { - const res = node.searchNode(paths, pos + 1); + _readPermissions() { + const encrypt = this.xref.trailer.get("Encrypt");
- if (res !== null) { - return res; - } - } else if (stack.length === 0) { - return null; - } else { - const [parent] = stack.pop(); - let siblingPos = 0; - - for (const child of parent.childNodes) { - if (component.name === child.nodeName) { - if (siblingPos === component.pos) { - return child.searchNode(paths, pos + 1); - } + if (!(encrypt instanceof _primitives.Dict)) { + return null; + }
- siblingPos++; - } - } + let flags = encrypt.get("P");
- return node.searchNode(paths, pos + 1); - } - } + if (typeof flags !== "number") { + return null; + }
- if (node.childNodes && node.childNodes.length !== 0) { - stack.push([node, 0]); - node = node.childNodes[0]; - } else if (stack.length === 0) { - return null; - } else { - while (stack.length !== 0) { - const [parent, currentPos] = stack.pop(); - const newPos = currentPos + 1; + flags += 2 ** 32; + const permissions = [];
- if (newPos < parent.childNodes.length) { - stack.push([parent, newPos]); - node = parent.childNodes[newPos]; - break; - } - } + for (const key in _util.PermissionFlag) { + const value = _util.PermissionFlag[key];
- if (stack.length === 0) { - return null; - } + if (flags & value) { + permissions.push(value); } } + + return permissions; }
- dump(buffer) { - if (this.nodeName === "#text") { - buffer.push((0, _core_utils.encodeToXmlString)(this.nodeValue)); - return; - } + get optionalContentConfig() { + let config = null;
- buffer.push(`<${this.nodeName}`); + try { + const properties = this._catDict.get("OCProperties");
- if (this.attributes) { - for (const attribute of this.attributes) { - buffer.push(` ${attribute.name}="${(0, _core_utils.encodeToXmlString)(attribute.value)}"`); + if (!properties) { + return (0, _util.shadow)(this, "optionalContentConfig", null); } - }
- if (this.hasChildNodes()) { - buffer.push(">"); + const defaultConfig = properties.get("D");
- for (const child of this.childNodes) { - child.dump(buffer); + if (!defaultConfig) { + return (0, _util.shadow)(this, "optionalContentConfig", null); }
- buffer.push(`</${this.nodeName}>`); - } else if (this.nodeValue) { - buffer.push(`>${(0, _core_utils.encodeToXmlString)(this.nodeValue)}</${this.nodeName}>`); - } else { - buffer.push("/>"); - } - } - -} + const groupsData = properties.get("OCGs");
-exports.SimpleDOMNode = SimpleDOMNode; + if (!Array.isArray(groupsData)) { + return (0, _util.shadow)(this, "optionalContentConfig", null); + }
-class SimpleXMLParser extends XMLParserBase { - constructor({ - hasAttributes = false, - lowerCaseName = false - }) { - super(); - this._currentFragment = null; - this._stack = null; - this._errorCode = XMLParserErrorCode.NoError; - this._hasAttributes = hasAttributes; - this._lowerCaseName = lowerCaseName; - } + const groups = []; + const groupRefs = [];
- parseFromString(data) { - this._currentFragment = []; - this._stack = []; - this._errorCode = XMLParserErrorCode.NoError; - this.parseXml(data); + for (const groupRef of groupsData) { + if (!(groupRef instanceof _primitives.Ref)) { + continue; + }
- if (this._errorCode !== XMLParserErrorCode.NoError) { - return undefined; - } + groupRefs.push(groupRef); + const group = this.xref.fetchIfRef(groupRef); + groups.push({ + id: groupRef.toString(), + name: typeof group.get("Name") === "string" ? (0, _util.stringToPDFString)(group.get("Name")) : null, + intent: typeof group.get("Intent") === "string" ? (0, _util.stringToPDFString)(group.get("Intent")) : null + }); + }
- const [documentElement] = this._currentFragment; + config = this._readOptionalContentConfig(defaultConfig, groupRefs); + config.groups = groups; + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + }
- if (!documentElement) { - return undefined; + (0, _util.warn)(`Unable to read optional content config: ${ex}`); }
- return { - documentElement - }; + return (0, _util.shadow)(this, "optionalContentConfig", config); }
- onText(text) { - if (isWhitespaceString(text)) { - return; - } - - const node = new SimpleDOMNode("#text", text); - - this._currentFragment.push(node); - } + _readOptionalContentConfig(config, contentGroupRefs) { + function parseOnOff(refs) { + const onParsed = [];
- onCdata(text) { - const node = new SimpleDOMNode("#text", text); + if (Array.isArray(refs)) { + for (const value of refs) { + if (!(value instanceof _primitives.Ref)) { + continue; + }
- this._currentFragment.push(node); - } + if (contentGroupRefs.includes(value)) { + onParsed.push(value.toString()); + } + } + }
- onBeginElement(name, attributes, isEmpty) { - if (this._lowerCaseName) { - name = name.toLowerCase(); + return onParsed; }
- const node = new SimpleDOMNode(name); - node.childNodes = []; - - if (this._hasAttributes) { - node.attributes = attributes; - } + function parseOrder(refs, nestedLevels = 0) { + if (!Array.isArray(refs)) { + return null; + }
- this._currentFragment.push(node); + const order = [];
- if (isEmpty) { - return; - } + for (const value of refs) { + if (value instanceof _primitives.Ref && contentGroupRefs.includes(value)) { + parsedOrderRefs.put(value); + order.push(value.toString()); + continue; + }
- this._stack.push(this._currentFragment); + const nestedOrder = parseNestedOrder(value, nestedLevels);
- this._currentFragment = node.childNodes; - } + if (nestedOrder) { + order.push(nestedOrder); + } + }
- onEndElement(name) { - this._currentFragment = this._stack.pop() || []; - const lastElement = this._currentFragment[this._currentFragment.length - 1]; + if (nestedLevels > 0) { + return order; + }
- if (!lastElement) { - return null; - } + const hiddenGroups = [];
- for (let i = 0, ii = lastElement.childNodes.length; i < ii; i++) { - lastElement.childNodes[i].parentNode = lastElement; - } + for (const groupRef of contentGroupRefs) { + if (parsedOrderRefs.has(groupRef)) { + continue; + }
- return lastElement; - } + hiddenGroups.push(groupRef.toString()); + }
- onError(code) { - this._errorCode = code; - } + if (hiddenGroups.length) { + order.push({ + name: null, + order: hiddenGroups + }); + }
-} + return order; + }
-exports.SimpleXMLParser = SimpleXMLParser; + function parseNestedOrder(ref, nestedLevels) { + if (++nestedLevels > MAX_NESTED_LEVELS) { + (0, _util.warn)("parseNestedOrder - reached MAX_NESTED_LEVELS."); + return null; + }
-/***/ }), -/* 71 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + const value = xref.fetchIfRef(ref);
+ if (!Array.isArray(value)) { + return null; + }
+ const nestedName = xref.fetchIfRef(value[0]);
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.StructTreeRoot = exports.StructTreePage = void 0; + if (typeof nestedName !== "string") { + return null; + }
-var _primitives = __w_pdfjs_require__(5); + const nestedOrder = parseOrder(value.slice(1), nestedLevels);
-var _util = __w_pdfjs_require__(2); + if (!nestedOrder || !nestedOrder.length) { + return null; + }
-var _name_number_tree = __w_pdfjs_require__(66); + return { + name: (0, _util.stringToPDFString)(nestedName), + order: nestedOrder + }; + }
-const MAX_DEPTH = 40; -const StructElementType = { - PAGE_CONTENT: "PAGE_CONTENT", - STREAM_CONTENT: "STREAM_CONTENT", - OBJECT: "OBJECT", - ELEMENT: "ELEMENT" -}; + const xref = this.xref, + parsedOrderRefs = new _primitives.RefSet(), + MAX_NESTED_LEVELS = 10; + return { + name: typeof config.get("Name") === "string" ? (0, _util.stringToPDFString)(config.get("Name")) : null, + creator: typeof config.get("Creator") === "string" ? (0, _util.stringToPDFString)(config.get("Creator")) : null, + baseState: config.get("BaseState") instanceof _primitives.Name ? config.get("BaseState").name : null, + on: parseOnOff(config.get("ON")), + off: parseOnOff(config.get("OFF")), + order: parseOrder(config.get("Order")), + groups: null + }; + }
-class StructTreeRoot { - constructor(rootDict) { - this.dict = rootDict; - this.roleMap = new Map(); + setActualNumPages(num = null) { + this._actualNumPages = num; }
- init() { - this.readRoleMap(); + get hasActualNumPages() { + return this._actualNumPages !== null; }
- readRoleMap() { - const roleMapDict = this.dict.get("RoleMap"); + get _pagesCount() { + const obj = this.toplevelPagesDict.get("Count");
- if (!(roleMapDict instanceof _primitives.Dict)) { - return; + if (!Number.isInteger(obj)) { + throw new _util.FormatError("Page count in top-level pages dictionary is not an integer."); }
- roleMapDict.forEach((key, value) => { - if (!(value instanceof _primitives.Name)) { - return; - } - - this.roleMap.set(key, value.name); - }); + return (0, _util.shadow)(this, "_pagesCount", obj); }
-} + get numPages() { + return this.hasActualNumPages ? this._actualNumPages : this._pagesCount; + }
-exports.StructTreeRoot = StructTreeRoot; + get destinations() { + const obj = this._readDests(), + dests = Object.create(null);
-class StructElementNode { - constructor(tree, dict) { - this.tree = tree; - this.dict = dict; - this.kids = []; - this.parseKids(); - } + if (obj instanceof _name_number_tree.NameTree) { + for (const [key, value] of obj.getAll()) { + const dest = fetchDestination(value);
- get role() { - const nameObj = this.dict.get("S"); - const name = nameObj instanceof _primitives.Name ? nameObj.name : ""; - const { - root - } = this.tree; + if (dest) { + dests[(0, _util.stringToPDFString)(key)] = dest; + } + } + } else if (obj instanceof _primitives.Dict) { + obj.forEach(function (key, value) { + const dest = fetchDestination(value);
- if (root.roleMap.has(name)) { - return root.roleMap.get(name); + if (dest) { + dests[key] = dest; + } + }); }
- return name; + return (0, _util.shadow)(this, "destinations", dests); }
- parseKids() { - let pageObjId = null; - const objRef = this.dict.getRaw("Pg"); + getDestination(id) { + const obj = this._readDests();
- if (objRef instanceof _primitives.Ref) { - pageObjId = objRef.toString(); - } + if (obj instanceof _name_number_tree.NameTree) { + const dest = fetchDestination(obj.get(id));
- const kids = this.dict.get("K"); + if (dest) { + return dest; + }
- if (Array.isArray(kids)) { - for (const kid of kids) { - const element = this.parseKid(pageObjId, kid); + const allDest = this.destinations[id];
- if (element) { - this.kids.push(element); - } + if (allDest) { + (0, _util.warn)(`Found "${id}" at an incorrect position in the NameTree.`); + return allDest; } - } else { - const element = this.parseKid(pageObjId, kids); + } else if (obj instanceof _primitives.Dict) { + const dest = fetchDestination(obj.get(id));
- if (element) { - this.kids.push(element); + if (dest) { + return dest; } } + + return null; }
- parseKid(pageObjId, kid) { - if (Number.isInteger(kid)) { - if (this.tree.pageDict.objId !== pageObjId) { - return null; - } + _readDests() { + const obj = this._catDict.get("Names");
- return new StructElement({ - type: StructElementType.PAGE_CONTENT, - mcid: kid, - pageObjId - }); + if (obj && obj.has("Dests")) { + return new _name_number_tree.NameTree(obj.getRaw("Dests"), this.xref); + } else if (this._catDict.has("Dests")) { + return this._catDict.get("Dests"); }
- let kidDict = null; - - if (kid instanceof _primitives.Ref) { - kidDict = this.dict.xref.fetch(kid); - } else if (kid instanceof _primitives.Dict) { - kidDict = kid; - } + return undefined; + }
- if (!kidDict) { - return null; - } + get pageLabels() { + let obj = null;
- const pageRef = kidDict.getRaw("Pg"); + try { + obj = this._readPageLabels(); + } catch (ex) { + if (ex instanceof _core_utils.MissingDataException) { + throw ex; + }
- if (pageRef instanceof _primitives.Ref) { - pageObjId = pageRef.toString(); + (0, _util.warn)("Unable to read page labels."); }
- const type = kidDict.get("Type") instanceof _primitives.Name ? kidDict.get("Type").name : null; + return (0, _util.shadow)(this, "pageLabels", obj); + }
- if (type === "MCR") { - if (this.tree.pageDict.objId !== pageObjId) { - return null; - } + _readPageLabels() { + const obj = this._catDict.getRaw("PageLabels");
- return new StructElement({ - type: StructElementType.STREAM_CONTENT, - refObjId: kidDict.getRaw("Stm") instanceof _primitives.Ref ? kidDict.getRaw("Stm").toString() : null, - pageObjId, - mcid: kidDict.get("MCID") - }); + if (!obj) { + return null; }
- if (type === "OBJR") { - if (this.tree.pageDict.objId !== pageObjId) { - return null; - } - - return new StructElement({ - type: StructElementType.OBJECT, - refObjId: kidDict.getRaw("Obj") instanceof _primitives.Ref ? kidDict.getRaw("Obj").toString() : null, - pageObjId - }); - } + const pageLabels = new Array(this.numPages); + let style = null, + prefix = ""; + const numberTree = new _name_number_tree.NumberTree(obj, this.xref); + const nums = numberTree.getAll(); + let currentLabel = "", + currentIndex = 1;
- return new StructElement({ - type: StructElementType.ELEMENT, - dict: kidDict - }); - } + for (let i = 0, ii = this.numPages; i < ii; i++) { + const labelDict = nums.get(i);
-} + if (labelDict !== undefined) { + if (!(labelDict instanceof _primitives.Dict)) { + throw new _util.FormatError("PageLabel is not a dictionary."); + }
-class StructElement { - constructor({ - type, - dict = null, - mcid = null, - pageObjId = null, - refObjId = null - }) { - this.type = type; - this.dict = dict; - this.mcid = mcid; - this.pageObjId = pageObjId; - this.refObjId = refObjId; - this.parentNode = null; - } + if (labelDict.has("Type") && !(0, _primitives.isName)(labelDict.get("Type"), "PageLabel")) { + throw new _util.FormatError("Invalid type in PageLabel dictionary."); + }
-} + if (labelDict.has("S")) { + const s = labelDict.get("S");
-class StructTreePage { - constructor(structTreeRoot, pageDict) { - this.root = structTreeRoot; - this.rootDict = structTreeRoot ? structTreeRoot.dict : null; - this.pageDict = pageDict; - this.nodes = []; - } + if (!(s instanceof _primitives.Name)) { + throw new _util.FormatError("Invalid style in PageLabel dictionary."); + }
- parse() { - if (!this.root || !this.rootDict) { - return; - } + style = s.name; + } else { + style = null; + }
- const parentTree = this.rootDict.get("ParentTree"); + if (labelDict.has("P")) { + const p = labelDict.get("P");
- if (!parentTree) { - return; - } + if (typeof p !== "string") { + throw new _util.FormatError("Invalid prefix in PageLabel dictionary."); + }
- const id = this.pageDict.get("StructParents"); - - if (!Number.isInteger(id)) { - return; - } - - const numberTree = new _name_number_tree.NumberTree(parentTree, this.rootDict.xref); - const parentArray = numberTree.get(id); + prefix = (0, _util.stringToPDFString)(p); + } else { + prefix = ""; + }
- if (!Array.isArray(parentArray)) { - return; - } + if (labelDict.has("St")) { + const st = labelDict.get("St");
- const map = new Map(); + if (!(Number.isInteger(st) && st >= 1)) { + throw new _util.FormatError("Invalid start in PageLabel dictionary."); + }
- for (const ref of parentArray) { - if (ref instanceof _primitives.Ref) { - this.addNode(this.rootDict.xref.fetch(ref), map); + currentIndex = st; + } else { + currentIndex = 1; + } } - } - }
- addNode(dict, map, level = 0) { - if (level > MAX_DEPTH) { - (0, _util.warn)("StructTree MAX_DEPTH reached."); - return null; - } + switch (style) { + case "D": + currentLabel = currentIndex; + break;
- if (map.has(dict)) { - return map.get(dict); - } + case "R": + case "r": + currentLabel = (0, _core_utils.toRomanNumerals)(currentIndex, style === "r"); + break;
- const element = new StructElementNode(this, dict); - map.set(dict, element); - const parent = dict.get("P"); + case "A": + case "a": + const LIMIT = 26; + const A_UPPER_CASE = 0x41, + A_LOWER_CASE = 0x61; + const baseCharCode = style === "a" ? A_LOWER_CASE : A_UPPER_CASE; + const letterIndex = currentIndex - 1; + const character = String.fromCharCode(baseCharCode + letterIndex % LIMIT); + currentLabel = character.repeat(Math.floor(letterIndex / LIMIT) + 1); + break;
- if (!parent || (0, _primitives.isName)(parent.get("Type"), "StructTreeRoot")) { - if (!this.addTopLevelNode(dict, element)) { - map.delete(dict); + default: + if (style) { + throw new _util.FormatError(`Invalid style "${style}" in PageLabel dictionary.`); + } + + currentLabel = ""; }
- return element; + pageLabels[i] = prefix + currentLabel; + currentIndex++; }
- const parentNode = this.addNode(parent, map, level + 1); + return pageLabels; + }
- if (!parentNode) { - return element; - } + get pageLayout() { + const obj = this._catDict.get("PageLayout");
- let save = false; + let pageLayout = "";
- for (const kid of parentNode.kids) { - if (kid.type === StructElementType.ELEMENT && kid.dict === dict) { - kid.parentNode = element; - save = true; + if (obj instanceof _primitives.Name) { + switch (obj.name) { + case "SinglePage": + case "OneColumn": + case "TwoColumnLeft": + case "TwoColumnRight": + case "TwoPageLeft": + case "TwoPageRight": + pageLayout = obj.name; } }
- if (!save) { - map.delete(dict); - } - - return element; + return (0, _util.shadow)(this, "pageLayout", pageLayout); }
- addTopLevelNode(dict, element) { - const obj = this.rootDict.get("K"); + get pageMode() { + const obj = this._catDict.get("PageMode");
- if (!obj) { - return false; - } + let pageMode = "UseNone";
- if (obj instanceof _primitives.Dict) { - if (obj.objId !== dict.objId) { - return false; + if (obj instanceof _primitives.Name) { + switch (obj.name) { + case "UseNone": + case "UseOutlines": + case "UseThumbs": + case "FullScreen": + case "UseOC": + case "UseAttachments": + pageMode = obj.name; } - - this.nodes[0] = element; - return true; }
- if (!Array.isArray(obj)) { - return true; + return (0, _util.shadow)(this, "pageMode", pageMode); + } + + get viewerPreferences() { + const obj = this._catDict.get("ViewerPreferences"); + + if (!(obj instanceof _primitives.Dict)) { + return (0, _util.shadow)(this, "viewerPreferences", null); }
- let save = false; + let prefs = null;
- for (let i = 0; i < obj.length; i++) { - const kidRef = obj[i]; + for (const key of obj.getKeys()) { + const value = obj.get(key); + let prefValue;
- if (kidRef && kidRef.toString() === dict.objId) { - this.nodes[i] = element; - save = true; - } - } + switch (key) { + case "HideToolbar": + case "HideMenubar": + case "HideWindowUI": + case "FitWindow": + case "CenterWindow": + case "DisplayDocTitle": + case "PickTrayByPDFSize": + if (typeof value === "boolean") { + prefValue = value; + }
- return save; - } + break;
- get serializable() { - function nodeToSerializable(node, parent, level = 0) { - if (level > MAX_DEPTH) { - (0, _util.warn)("StructTree too deep to be fully serialized."); - return; - } + case "NonFullScreenPageMode": + if (value instanceof _primitives.Name) { + switch (value.name) { + case "UseNone": + case "UseOutlines": + case "UseThumbs": + case "UseOC": + prefValue = value.name; + break;
- const obj = Object.create(null); - obj.role = node.role; - obj.children = []; - parent.children.push(obj); - const alt = node.dict.get("Alt"); + default: + prefValue = "UseNone"; + } + }
- if (typeof alt === "string") { - obj.alt = (0, _util.stringToPDFString)(alt); - } + break;
- const lang = node.dict.get("Lang"); + case "Direction": + if (value instanceof _primitives.Name) { + switch (value.name) { + case "L2R": + case "R2L": + prefValue = value.name; + break;
- if (typeof lang === "string") { - obj.lang = (0, _util.stringToPDFString)(lang); - } + default: + prefValue = "L2R"; + } + }
- for (const kid of node.kids) { - const kidElement = kid.type === StructElementType.ELEMENT ? kid.parentNode : null; + break;
- if (kidElement) { - nodeToSerializable(kidElement, obj, level + 1); - continue; - } else if (kid.type === StructElementType.PAGE_CONTENT || kid.type === StructElementType.STREAM_CONTENT) { - obj.children.push({ - type: "content", - id: `page${kid.pageObjId}_mcid${kid.mcid}` - }); - } else if (kid.type === StructElementType.OBJECT) { - obj.children.push({ - type: "object", - id: kid.refObjId - }); - } - } - } + case "ViewArea": + case "ViewClip": + case "PrintArea": + case "PrintClip": + if (value instanceof _primitives.Name) { + switch (value.name) { + case "MediaBox": + case "CropBox": + case "BleedBox": + case "TrimBox": + case "ArtBox": + prefValue = value.name; + break;
- const root = Object.create(null); - root.children = []; - root.role = "Root"; + default: + prefValue = "CropBox"; + } + }
- for (const child of this.nodes) { - if (!child) { - continue; - } + break;
- nodeToSerializable(child, root); - } + case "PrintScaling": + if (value instanceof _primitives.Name) { + switch (value.name) { + case "None": + case "AppDefault": + prefValue = value.name; + break;
- return root; - } + default: + prefValue = "AppDefault"; + } + }
-} + break;
-exports.StructTreePage = StructTreePage; + case "Duplex": + if (value instanceof _primitives.Name) { + switch (value.name) { + case "Simplex": + case "DuplexFlipShortEdge": + case "DuplexFlipLongEdge": + prefValue = value.name; + break;
-/***/ }), -/* 72 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + default: + prefValue = "None"; + } + }
+ break;
+ case "PrintPageRange": + if (Array.isArray(value) && value.length % 2 === 0) { + const isValid = value.every((page, i, arr) => { + return Number.isInteger(page) && page > 0 && (i === 0 || page >= arr[i - 1]) && page <= this.numPages; + });
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.ObjectLoader = void 0; + if (isValid) { + prefValue = value; + } + }
-var _primitives = __w_pdfjs_require__(5); + break;
-var _base_stream = __w_pdfjs_require__(9); + case "NumCopies": + if (Number.isInteger(value) && value > 0) { + prefValue = value; + }
-var _core_utils = __w_pdfjs_require__(8); + break;
-var _util = __w_pdfjs_require__(2); + default: + (0, _util.warn)(`Ignoring non-standard key in ViewerPreferences: ${key}.`); + continue; + }
-function mayHaveChildren(value) { - return value instanceof _primitives.Ref || value instanceof _primitives.Dict || value instanceof _base_stream.BaseStream || Array.isArray(value); -} + if (prefValue === undefined) { + (0, _util.warn)(`Bad value, for key "${key}", in ViewerPreferences: ${value}.`); + continue; + }
-function addChildren(node, nodesToVisit) { - if (node instanceof _primitives.Dict) { - node = node.getRawValues(); - } else if (node instanceof _base_stream.BaseStream) { - node = node.dict.getRawValues(); - } else if (!Array.isArray(node)) { - return; - } + if (!prefs) { + prefs = Object.create(null); + }
- for (const rawValue of node) { - if (mayHaveChildren(rawValue)) { - nodesToVisit.push(rawValue); + prefs[key] = prefValue; } - } -}
-class ObjectLoader { - constructor(dict, keys, xref) { - this.dict = dict; - this.keys = keys; - this.xref = xref; - this.refSet = null; + return (0, _util.shadow)(this, "viewerPreferences", prefs); }
- async load() { - if (this.xref.stream.isDataLoaded) { - return undefined; - } + get openAction() { + const obj = this._catDict.get("OpenAction");
- const { - keys, - dict - } = this; - this.refSet = new _primitives.RefSet(); - const nodesToVisit = []; + const openAction = Object.create(null);
- for (let i = 0, ii = keys.length; i < ii; i++) { - const rawValue = dict.getRaw(keys[i]); + if (obj instanceof _primitives.Dict) { + const destDict = new _primitives.Dict(this.xref); + destDict.set("A", obj); + const resultObj = { + url: null, + dest: null, + action: null + }; + Catalog.parseDestDictionary({ + destDict, + resultObj + });
- if (rawValue !== undefined) { - nodesToVisit.push(rawValue); + if (Array.isArray(resultObj.dest)) { + openAction.dest = resultObj.dest; + } else if (resultObj.action) { + openAction.action = resultObj.action; } + } else if (Array.isArray(obj)) { + openAction.dest = obj; }
- return this._walk(nodesToVisit); + return (0, _util.shadow)(this, "openAction", (0, _util.objectSize)(openAction) > 0 ? openAction : null); }
- async _walk(nodesToVisit) { - const nodesToRevisit = []; - const pendingRequests = []; + get attachments() { + const obj = this._catDict.get("Names");
- while (nodesToVisit.length) { - let currentNode = nodesToVisit.pop(); + let attachments = null;
- if (currentNode instanceof _primitives.Ref) { - if (this.refSet.has(currentNode)) { - continue; - } + if (obj instanceof _primitives.Dict && obj.has("EmbeddedFiles")) { + const nameTree = new _name_number_tree.NameTree(obj.getRaw("EmbeddedFiles"), this.xref);
- try { - this.refSet.put(currentNode); - currentNode = this.xref.fetch(currentNode); - } catch (ex) { - if (!(ex instanceof _core_utils.MissingDataException)) { - (0, _util.warn)(`ObjectLoader._walk - requesting all data: "${ex}".`); - this.refSet = null; - const { - manager - } = this.xref.stream; - return manager.requestAllChunks(); - } + for (const [key, value] of nameTree.getAll()) { + const fs = new _file_spec.FileSpec(value, this.xref);
- nodesToRevisit.push(currentNode); - pendingRequests.push({ - begin: ex.begin, - end: ex.end - }); + if (!attachments) { + attachments = Object.create(null); } + + attachments[(0, _util.stringToPDFString)(key)] = fs.serializable; } + }
- if (currentNode instanceof _base_stream.BaseStream) { - const baseStreams = currentNode.getBaseStreams(); + return (0, _util.shadow)(this, "attachments", attachments); + }
- if (baseStreams) { - let foundMissingData = false; + get xfaImages() { + const obj = this._catDict.get("Names");
- for (const stream of baseStreams) { - if (stream.isDataLoaded) { - continue; - } + let xfaImages = null;
- foundMissingData = true; - pendingRequests.push({ - begin: stream.start, - end: stream.end - }); - } + if (obj instanceof _primitives.Dict && obj.has("XFAImages")) { + const nameTree = new _name_number_tree.NameTree(obj.getRaw("XFAImages"), this.xref);
- if (foundMissingData) { - nodesToRevisit.push(currentNode); - } + for (const [key, value] of nameTree.getAll()) { + if (!xfaImages) { + xfaImages = new _primitives.Dict(this.xref); } - } - - addChildren(currentNode, nodesToVisit); - } - - if (pendingRequests.length) { - await this.xref.stream.manager.requestRanges(pendingRequests);
- for (const node of nodesToRevisit) { - if (node instanceof _primitives.Ref) { - this.refSet.remove(node); - } + xfaImages.set((0, _util.stringToPDFString)(key), value); } - - return this._walk(nodesToRevisit); }
- this.refSet = null; - return undefined; + return (0, _util.shadow)(this, "xfaImages", xfaImages); }
-} + _collectJavaScript() { + const obj = this._catDict.get("Names");
-exports.ObjectLoader = ObjectLoader; + let javaScript = null;
-/***/ }), -/* 73 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + function appendIfJavaScriptDict(name, jsDict) { + if (!(jsDict instanceof _primitives.Dict)) { + return; + }
+ if (!(0, _primitives.isName)(jsDict.get("S"), "JavaScript")) { + return; + }
+ let js = jsDict.get("JS");
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.incrementalUpdate = incrementalUpdate; -exports.writeDict = writeDict; + if (js instanceof _base_stream.BaseStream) { + js = js.getString(); + } else if (typeof js !== "string") { + return; + }
-var _util = __w_pdfjs_require__(2); + if (javaScript === null) { + javaScript = new Map(); + }
-var _primitives = __w_pdfjs_require__(5); + js = (0, _util.stringToPDFString)(js).replace(/\u0000/g, ""); + javaScript.set(name, js); + } + + if (obj instanceof _primitives.Dict && obj.has("JavaScript")) { + const nameTree = new _name_number_tree.NameTree(obj.getRaw("JavaScript"), this.xref);
-var _core_utils = __w_pdfjs_require__(8); + for (const [key, value] of nameTree.getAll()) { + appendIfJavaScriptDict((0, _util.stringToPDFString)(key), value); + } + }
-var _xml_parser = __w_pdfjs_require__(70); + const openAction = this._catDict.get("OpenAction");
-var _base_stream = __w_pdfjs_require__(9); + if (openAction) { + appendIfJavaScriptDict("OpenAction", openAction); + }
-var _crypto = __w_pdfjs_require__(74); + return javaScript; + }
-function writeDict(dict, buffer, transform) { - buffer.push("<<"); + get javaScript() { + const javaScript = this._collectJavaScript();
- for (const key of dict.getKeys()) { - buffer.push(` /${(0, _core_utils.escapePDFName)(key)} `); - writeValue(dict.getRaw(key), buffer, transform); + return (0, _util.shadow)(this, "javaScript", javaScript ? [...javaScript.values()] : null); }
- buffer.push(">>"); -} + get jsActions() { + const javaScript = this._collectJavaScript();
-function writeStream(stream, buffer, transform) { - writeDict(stream.dict, buffer, transform); - buffer.push(" stream\n"); - let string = stream.getString(); - - if (transform !== null) { - string = transform.encryptString(string); - } - - buffer.push(string, "\nendstream\n"); -} + let actions = (0, _core_utils.collectActions)(this.xref, this._catDict, _util.DocumentActionEventType);
-function writeArray(array, buffer, transform) { - buffer.push("["); - let first = true; + if (javaScript) { + if (!actions) { + actions = Object.create(null); + }
- for (const val of array) { - if (!first) { - buffer.push(" "); - } else { - first = false; + for (const [key, val] of javaScript) { + if (key in actions) { + actions[key].push(val); + } else { + actions[key] = [val]; + } + } }
- writeValue(val, buffer, transform); + return (0, _util.shadow)(this, "jsActions", actions); }
- buffer.push("]"); -} + async fontFallback(id, handler) { + const translatedFonts = await Promise.all(this.fontCache);
-function numberToString(value) { - if (Number.isInteger(value)) { - return value.toString(); + for (const translatedFont of translatedFonts) { + if (translatedFont.loadedName === id) { + translatedFont.fallback(handler); + return; + } + } }
- const roundedValue = Math.round(value * 100); + async cleanup(manuallyTriggered = false) { + (0, _cleanup_helper.clearGlobalCaches)(); + this.globalImageCache.clear(manuallyTriggered); + this.pageKidsCountCache.clear(); + this.pageIndexCache.clear(); + this.nonBlendModesSet.clear(); + const translatedFonts = await Promise.all(this.fontCache);
- if (roundedValue % 100 === 0) { - return (roundedValue / 100).toString(); - } + for (const { + dict + } of translatedFonts) { + delete dict.cacheKey; + }
- if (roundedValue % 10 === 0) { - return value.toFixed(1); + this.fontCache.clear(); + this.builtInCMapCache.clear(); + this.standardFontDataCache.clear(); }
- return value.toFixed(2); -} + async getPageDict(pageIndex) { + const nodesToVisit = [this.toplevelPagesDict]; + const visitedNodes = new _primitives.RefSet();
-function writeValue(value, buffer, transform) { - if (value instanceof _primitives.Name) { - buffer.push(`/${(0, _core_utils.escapePDFName)(value.name)}`); - } else if (value instanceof _primitives.Ref) { - buffer.push(`${value.num} ${value.gen} R`); - } else if (Array.isArray(value)) { - writeArray(value, buffer, transform); - } else if (typeof value === "string") { - if (transform !== null) { - value = transform.encryptString(value); - } + const pagesRef = this._catDict.getRaw("Pages");
- buffer.push(`(${(0, _util.escapeString)(value)})`); - } else if (typeof value === "number") { - buffer.push(numberToString(value)); - } else if (typeof value === "boolean") { - buffer.push(value.toString()); - } else if (value instanceof _primitives.Dict) { - writeDict(value, buffer, transform); - } else if (value instanceof _base_stream.BaseStream) { - writeStream(value, buffer, transform); - } else if (value === null) { - buffer.push("null"); - } else { - (0, _util.warn)(`Unhandled value in writer: ${typeof value}, please file a bug.`); - } -} + if (pagesRef instanceof _primitives.Ref) { + visitedNodes.put(pagesRef); + }
-function writeInt(number, size, offset, buffer) { - for (let i = size + offset - 1; i > offset - 1; i--) { - buffer[i] = number & 0xff; - number >>= 8; - } + const xref = this.xref, + pageKidsCountCache = this.pageKidsCountCache, + pageIndexCache = this.pageIndexCache; + let currentPageIndex = 0;
- return offset + size; -} + while (nodesToVisit.length) { + const currentNode = nodesToVisit.pop();
-function writeString(string, offset, buffer) { - for (let i = 0, len = string.length; i < len; i++) { - buffer[offset + i] = string.charCodeAt(i) & 0xff; - } -} + if (currentNode instanceof _primitives.Ref) { + const count = pageKidsCountCache.get(currentNode);
-function computeMD5(filesize, xrefInfo) { - const time = Math.floor(Date.now() / 1000); - const filename = xrefInfo.filename || ""; - const md5Buffer = [time.toString(), filename, filesize.toString()]; - let md5BufferLen = md5Buffer.reduce((a, str) => a + str.length, 0); + if (count >= 0 && currentPageIndex + count <= pageIndex) { + currentPageIndex += count; + continue; + }
- for (const value of Object.values(xrefInfo.info)) { - md5Buffer.push(value); - md5BufferLen += value.length; - } + if (visitedNodes.has(currentNode)) { + throw new _util.FormatError("Pages tree contains circular reference."); + }
- const array = new Uint8Array(md5BufferLen); - let offset = 0; + visitedNodes.put(currentNode); + const obj = await xref.fetchAsync(currentNode);
- for (const str of md5Buffer) { - writeString(str, offset, array); - offset += str.length; - } + if (obj instanceof _primitives.Dict) { + let type = obj.getRaw("Type");
- return (0, _util.bytesToString)((0, _crypto.calculateMD5)(array)); -} + if (type instanceof _primitives.Ref) { + type = await xref.fetchAsync(type); + }
-function writeXFADataForAcroform(str, newRefs) { - const xml = new _xml_parser.SimpleXMLParser({ - hasAttributes: true - }).parseFromString(str); + if ((0, _primitives.isName)(type, "Page") || !obj.has("Kids")) { + if (!pageKidsCountCache.has(currentNode)) { + pageKidsCountCache.put(currentNode, 1); + }
- for (const { - xfa - } of newRefs) { - if (!xfa) { - continue; - } + if (!pageIndexCache.has(currentNode)) { + pageIndexCache.put(currentNode, currentPageIndex); + }
- const { - path, - value - } = xfa; + if (currentPageIndex === pageIndex) { + return [obj, currentNode]; + }
- if (!path) { - continue; - } + currentPageIndex++; + continue; + } + }
- const node = xml.documentElement.searchNode((0, _core_utils.parseXFAPath)(path), 0); + nodesToVisit.push(obj); + continue; + }
- if (node) { - if (Array.isArray(value)) { - node.childNodes = value.map(val => new _xml_parser.SimpleDOMNode("value", val)); - } else { - node.childNodes = [new _xml_parser.SimpleDOMNode("#text", value)]; + if (!(currentNode instanceof _primitives.Dict)) { + throw new _util.FormatError("Page dictionary kid reference points to wrong type of object."); } - } else { - (0, _util.warn)(`Node not found for path: ${path}`); - } - }
- const buffer = []; - xml.documentElement.dump(buffer); - return buffer.join(""); -} + const { + objId + } = currentNode; + let count = currentNode.getRaw("Count");
-function updateXFA({ - xfaData, - xfaDatasetsRef, - hasXfaDatasetsEntry, - acroFormRef, - acroForm, - newRefs, - xref, - xrefInfo -}) { - if (xref === null) { - return; - } + if (count instanceof _primitives.Ref) { + count = await xref.fetchAsync(count); + }
- if (!hasXfaDatasetsEntry) { - if (!acroFormRef) { - (0, _util.warn)("XFA - Cannot save it"); - return; - } + if (Number.isInteger(count) && count >= 0) { + if (objId && !pageKidsCountCache.has(objId)) { + pageKidsCountCache.put(objId, count); + }
- const oldXfa = acroForm.get("XFA"); - const newXfa = oldXfa.slice(); - newXfa.splice(2, 0, "datasets"); - newXfa.splice(3, 0, xfaDatasetsRef); - acroForm.set("XFA", newXfa); - const encrypt = xref.encrypt; - let transform = null; + if (currentPageIndex + count <= pageIndex) { + currentPageIndex += count; + continue; + } + }
- if (encrypt) { - transform = encrypt.createCipherTransform(acroFormRef.num, acroFormRef.gen); - } + let kids = currentNode.getRaw("Kids");
- const buffer = [`${acroFormRef.num} ${acroFormRef.gen} obj\n`]; - writeDict(acroForm, buffer, transform); - buffer.push("\n"); - acroForm.set("XFA", oldXfa); - newRefs.push({ - ref: acroFormRef, - data: buffer.join("") - }); - } + if (kids instanceof _primitives.Ref) { + kids = await xref.fetchAsync(kids); + }
- if (xfaData === null) { - const datasets = xref.fetchIfRef(xfaDatasetsRef); - xfaData = writeXFADataForAcroform(datasets.getString(), newRefs); - } + if (!Array.isArray(kids)) { + let type = currentNode.getRaw("Type");
- const encrypt = xref.encrypt; + if (type instanceof _primitives.Ref) { + type = await xref.fetchAsync(type); + }
- if (encrypt) { - const transform = encrypt.createCipherTransform(xfaDatasetsRef.num, xfaDatasetsRef.gen); - xfaData = transform.encryptString(xfaData); - } + if ((0, _primitives.isName)(type, "Page") || !currentNode.has("Kids")) { + if (currentPageIndex === pageIndex) { + return [currentNode, null]; + }
- const data = `${xfaDatasetsRef.num} ${xfaDatasetsRef.gen} obj\n` + `<< /Type /EmbeddedFile /Length ${xfaData.length}>>\nstream\n` + xfaData + "\nendstream\nendobj\n"; - newRefs.push({ - ref: xfaDatasetsRef, - data - }); -} + currentPageIndex++; + continue; + }
-function incrementalUpdate({ - originalData, - xrefInfo, - newRefs, - xref = null, - hasXfa = false, - xfaDatasetsRef = null, - hasXfaDatasetsEntry = false, - acroFormRef = null, - acroForm = null, - xfaData = null -}) { - if (hasXfa) { - updateXFA({ - xfaData, - xfaDatasetsRef, - hasXfaDatasetsEntry, - acroFormRef, - acroForm, - newRefs, - xref, - xrefInfo - }); - } + throw new _util.FormatError("Page dictionary kids object is not an array."); + }
- const newXref = new _primitives.Dict(null); - const refForXrefTable = xrefInfo.newRef; - let buffer, baseOffset; - const lastByte = originalData[originalData.length - 1]; + for (let last = kids.length - 1; last >= 0; last--) { + nodesToVisit.push(kids[last]); + } + }
- if (lastByte === 0x0a || lastByte === 0x0d) { - buffer = []; - baseOffset = originalData.length; - } else { - buffer = ["\n"]; - baseOffset = originalData.length + 1; + throw new Error(`Page index ${pageIndex} not found.`); }
- newXref.set("Size", refForXrefTable.num + 1); - newXref.set("Prev", xrefInfo.startXRef); - newXref.set("Type", _primitives.Name.get("XRef")); - - if (xrefInfo.rootRef !== null) { - newXref.set("Root", xrefInfo.rootRef); - } + async getAllPageDicts(recoveryMode = false) { + const queue = [{ + currentNode: this.toplevelPagesDict, + posInKids: 0 + }]; + const visitedNodes = new _primitives.RefSet();
- if (xrefInfo.infoRef !== null) { - newXref.set("Info", xrefInfo.infoRef); - } + const pagesRef = this._catDict.getRaw("Pages");
- if (xrefInfo.encryptRef !== null) { - newXref.set("Encrypt", xrefInfo.encryptRef); - } + if (pagesRef instanceof _primitives.Ref) { + visitedNodes.put(pagesRef); + }
- newRefs.push({ - ref: refForXrefTable, - data: "" - }); - newRefs = newRefs.sort((a, b) => { - return a.ref.num - b.ref.num; - }); - const xrefTableData = [[0, 1, 0xffff]]; - const indexes = [0, 1]; - let maxOffset = 0; + const map = new Map(), + xref = this.xref, + pageIndexCache = this.pageIndexCache; + let pageIndex = 0;
- for (const { - ref, - data - } of newRefs) { - maxOffset = Math.max(maxOffset, baseOffset); - xrefTableData.push([1, baseOffset, Math.min(ref.gen, 0xffff)]); - baseOffset += data.length; - indexes.push(ref.num, 1); - buffer.push(data); - } + function addPageDict(pageDict, pageRef) { + if (pageRef && !pageIndexCache.has(pageRef)) { + pageIndexCache.put(pageRef, pageIndex); + }
- newXref.set("Index", indexes); + map.set(pageIndex++, [pageDict, pageRef]); + }
- if (Array.isArray(xrefInfo.fileIds) && xrefInfo.fileIds.length > 0) { - const md5 = computeMD5(baseOffset, xrefInfo); - newXref.set("ID", [xrefInfo.fileIds[0], md5]); - } + function addPageError(error) { + if (error instanceof _core_utils.XRefEntryException && !recoveryMode) { + throw error; + }
- const offsetSize = Math.ceil(Math.log2(maxOffset) / 8); - const sizes = [1, offsetSize, 2]; - const structSize = sizes[0] + sizes[1] + sizes[2]; - const tableLength = structSize * xrefTableData.length; - newXref.set("W", sizes); - newXref.set("Length", tableLength); - buffer.push(`${refForXrefTable.num} ${refForXrefTable.gen} obj\n`); - writeDict(newXref, buffer, null); - buffer.push(" stream\n"); - const bufferLen = buffer.reduce((a, str) => a + str.length, 0); - const footer = `\nendstream\nendobj\nstartxref\n${baseOffset}\n%%EOF\n`; - const array = new Uint8Array(originalData.length + bufferLen + tableLength + footer.length); - array.set(originalData); - let offset = originalData.length; + map.set(pageIndex++, [error, null]); + }
- for (const str of buffer) { - writeString(str, offset, array); - offset += str.length; - } + while (queue.length > 0) { + const queueItem = queue.at(-1); + const { + currentNode, + posInKids + } = queueItem; + let kids = currentNode.getRaw("Kids");
- for (const [type, objOffset, gen] of xrefTableData) { - offset = writeInt(type, sizes[0], offset, array); - offset = writeInt(objOffset, sizes[1], offset, array); - offset = writeInt(gen, sizes[2], offset, array); - } + if (kids instanceof _primitives.Ref) { + try { + kids = await xref.fetchAsync(kids); + } catch (ex) { + addPageError(ex); + break; + } + }
- writeString(footer, offset, array); - return array; -} + if (!Array.isArray(kids)) { + addPageError(new _util.FormatError("Page dictionary kids object is not an array.")); + break; + }
-/***/ }), -/* 74 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + if (posInKids >= kids.length) { + queue.pop(); + continue; + }
+ const kidObj = kids[posInKids]; + let obj;
+ if (kidObj instanceof _primitives.Ref) { + if (visitedNodes.has(kidObj)) { + addPageError(new _util.FormatError("Pages tree contains circular reference.")); + break; + }
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.calculateSHA256 = exports.calculateMD5 = exports.PDF20 = exports.PDF17 = exports.CipherTransformFactory = exports.ARCFourCipher = exports.AES256Cipher = exports.AES128Cipher = void 0; -exports.calculateSHA384 = calculateSHA384; -exports.calculateSHA512 = void 0; + visitedNodes.put(kidObj);
-var _util = __w_pdfjs_require__(2); + try { + obj = await xref.fetchAsync(kidObj); + } catch (ex) { + addPageError(ex); + break; + } + } else { + obj = kidObj; + }
-var _primitives = __w_pdfjs_require__(5); + if (!(obj instanceof _primitives.Dict)) { + addPageError(new _util.FormatError("Page dictionary kid reference points to wrong type of object.")); + break; + }
-var _decrypt_stream = __w_pdfjs_require__(75); + let type = obj.getRaw("Type");
-class ARCFourCipher { - constructor(key) { - this.a = 0; - this.b = 0; - const s = new Uint8Array(256); - const keyLength = key.length; + if (type instanceof _primitives.Ref) { + try { + type = await xref.fetchAsync(type); + } catch (ex) { + addPageError(ex); + break; + } + }
- for (let i = 0; i < 256; ++i) { - s[i] = i; - } + if ((0, _primitives.isName)(type, "Page") || !obj.has("Kids")) { + addPageDict(obj, kidObj instanceof _primitives.Ref ? kidObj : null); + } else { + queue.push({ + currentNode: obj, + posInKids: 0 + }); + }
- for (let i = 0, j = 0; i < 256; ++i) { - const tmp = s[i]; - j = j + tmp + key[i % keyLength] & 0xff; - s[i] = s[j]; - s[j] = tmp; + queueItem.posInKids++; }
- this.s = s; + return map; }
- encryptBlock(data) { - let a = this.a, - b = this.b; - const s = this.s; - const n = data.length; - const output = new Uint8Array(n); + getPageIndex(pageRef) { + const cachedPageIndex = this.pageIndexCache.get(pageRef);
- for (let i = 0; i < n; ++i) { - a = a + 1 & 0xff; - const tmp = s[a]; - b = b + tmp & 0xff; - const tmp2 = s[b]; - s[a] = tmp2; - s[b] = tmp; - output[i] = data[i] ^ s[tmp + tmp2 & 0xff]; + if (cachedPageIndex !== undefined) { + return Promise.resolve(cachedPageIndex); }
- this.a = a; - this.b = b; - return output; - } - - decryptBlock(data) { - return this.encryptBlock(data); - } + const xref = this.xref;
- encrypt(data) { - return this.encryptBlock(data); - } + function pagesBeforeRef(kidRef) { + let total = 0, + parentRef; + return xref.fetchAsync(kidRef).then(function (node) { + if ((0, _primitives.isRefsEqual)(kidRef, pageRef) && !(0, _primitives.isDict)(node, "Page") && !(node instanceof _primitives.Dict && !node.has("Type") && node.has("Contents"))) { + throw new _util.FormatError("The reference does not point to a /Page dictionary."); + }
-} + if (!node) { + return null; + }
-exports.ARCFourCipher = ARCFourCipher; + if (!(node instanceof _primitives.Dict)) { + throw new _util.FormatError("Node must be a dictionary."); + }
-const calculateMD5 = function calculateMD5Closure() { - const r = new Uint8Array([7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]); - const k = new Int32Array([-680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, 1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632, 643717713, -373897302, -701558691, 38016083, -660478335, -405537848, 568446438, -1019803690, -187363961, 1163531501, -1444681467, -51403784, 1735328473, -1926607734, -378558, -2022574463, 1839030562, -35309556, -1530992060, 1272893353, -155497632, - [...] + parentRef = node.getRaw("Parent"); + return node.getAsync("Parent"); + }).then(function (parent) { + if (!parent) { + return null; + }
- function hash(data, offset, length) { - let h0 = 1732584193, - h1 = -271733879, - h2 = -1732584194, - h3 = 271733878; - const paddedLength = length + 72 & ~63; - const padded = new Uint8Array(paddedLength); - let i, j; + if (!(parent instanceof _primitives.Dict)) { + throw new _util.FormatError("Parent must be a dictionary."); + }
- for (i = 0; i < length; ++i) { - padded[i] = data[offset++]; - } + return parent.getAsync("Kids"); + }).then(function (kids) { + if (!kids) { + return null; + }
- padded[i++] = 0x80; - const n = paddedLength - 8; + const kidPromises = []; + let found = false;
- while (i < n) { - padded[i++] = 0; - } + for (let i = 0, ii = kids.length; i < ii; i++) { + const kid = kids[i];
- padded[i++] = length << 3 & 0xff; - padded[i++] = length >> 5 & 0xff; - padded[i++] = length >> 13 & 0xff; - padded[i++] = length >> 21 & 0xff; - padded[i++] = length >>> 29 & 0xff; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - const w = new Int32Array(16); + if (!(kid instanceof _primitives.Ref)) { + throw new _util.FormatError("Kid must be a reference."); + }
- for (i = 0; i < paddedLength;) { - for (j = 0; j < 16; ++j, i += 4) { - w[j] = padded[i] | padded[i + 1] << 8 | padded[i + 2] << 16 | padded[i + 3] << 24; - } + if ((0, _primitives.isRefsEqual)(kid, kidRef)) { + found = true; + break; + }
- let a = h0, - b = h1, - c = h2, - d = h3, - f, - g; + kidPromises.push(xref.fetchAsync(kid).then(function (obj) { + if (!(obj instanceof _primitives.Dict)) { + throw new _util.FormatError("Kid node must be a dictionary."); + }
- for (j = 0; j < 64; ++j) { - if (j < 16) { - f = b & c | ~b & d; - g = j; - } else if (j < 32) { - f = d & b | ~d & c; - g = 5 * j + 1 & 15; - } else if (j < 48) { - f = b ^ c ^ d; - g = 3 * j + 5 & 15; - } else { - f = c ^ (b | ~d); - g = 7 * j & 15; + if (obj.has("Count")) { + total += obj.get("Count"); + } else { + total++; + } + })); }
- const tmp = d, - rotateArg = a + f + k[j] + w[g] | 0, - rotate = r[j]; - d = c; - c = b; - b = b + (rotateArg << rotate | rotateArg >>> 32 - rotate) | 0; - a = tmp; - } + if (!found) { + throw new _util.FormatError("Kid reference not found in parent's kids."); + }
- h0 = h0 + a | 0; - h1 = h1 + b | 0; - h2 = h2 + c | 0; - h3 = h3 + d | 0; + return Promise.all(kidPromises).then(function () { + return [total, parentRef]; + }); + }); }
- return new Uint8Array([h0 & 0xFF, h0 >> 8 & 0xFF, h0 >> 16 & 0xFF, h0 >>> 24 & 0xFF, h1 & 0xFF, h1 >> 8 & 0xFF, h1 >> 16 & 0xFF, h1 >>> 24 & 0xFF, h2 & 0xFF, h2 >> 8 & 0xFF, h2 >> 16 & 0xFF, h2 >>> 24 & 0xFF, h3 & 0xFF, h3 >> 8 & 0xFF, h3 >> 16 & 0xFF, h3 >>> 24 & 0xFF]); - } + let total = 0;
- return hash; -}(); + const next = ref => pagesBeforeRef(ref).then(args => { + if (!args) { + this.pageIndexCache.put(pageRef, total); + return total; + }
-exports.calculateMD5 = calculateMD5; + const [count, parentRef] = args; + total += count; + return next(parentRef); + });
-class Word64 { - constructor(highInteger, lowInteger) { - this.high = highInteger | 0; - this.low = lowInteger | 0; + return next(pageRef); }
- and(word) { - this.high &= word.high; - this.low &= word.low; - } + get baseUrl() { + const uri = this._catDict.get("URI");
- xor(word) { - this.high ^= word.high; - this.low ^= word.low; - } + if (uri instanceof _primitives.Dict) { + const base = uri.get("Base");
- or(word) { - this.high |= word.high; - this.low |= word.low; - } + if (typeof base === "string") { + const absoluteUrl = (0, _util.createValidAbsoluteUrl)(base, null, { + tryConvertEncoding: true + });
- shiftRight(places) { - if (places >= 32) { - this.low = this.high >>> places - 32 | 0; - this.high = 0; - } else { - this.low = this.low >>> places | this.high << 32 - places; - this.high = this.high >>> places | 0; + if (absoluteUrl) { + return (0, _util.shadow)(this, "baseUrl", absoluteUrl.href); + } + } } - }
- shiftLeft(places) { - if (places >= 32) { - this.high = this.low << places - 32; - this.low = 0; - } else { - this.high = this.high << places | this.low >>> 32 - places; - this.low <<= places; - } + return (0, _util.shadow)(this, "baseUrl", null); }
- rotateRight(places) { - let low, high; + static parseDestDictionary(params) { + const destDict = params.destDict;
- if (places & 32) { - high = this.low; - low = this.high; - } else { - low = this.low; - high = this.high; + if (!(destDict instanceof _primitives.Dict)) { + (0, _util.warn)("parseDestDictionary: `destDict` must be a dictionary."); + return; }
- places &= 31; - this.low = low >>> places | high << 32 - places; - this.high = high >>> places | low << 32 - places; - } - - not() { - this.high = ~this.high; - this.low = ~this.low; - } - - add(word) { - const lowAdd = (this.low >>> 0) + (word.low >>> 0); - let highAdd = (this.high >>> 0) + (word.high >>> 0); + const resultObj = params.resultObj;
- if (lowAdd > 0xffffffff) { - highAdd += 1; + if (typeof resultObj !== "object") { + (0, _util.warn)("parseDestDictionary: `resultObj` must be an object."); + return; }
- this.low = lowAdd | 0; - this.high = highAdd | 0; - } - - copyTo(bytes, offset) { - bytes[offset] = this.high >>> 24 & 0xff; - bytes[offset + 1] = this.high >> 16 & 0xff; - bytes[offset + 2] = this.high >> 8 & 0xff; - bytes[offset + 3] = this.high & 0xff; - bytes[offset + 4] = this.low >>> 24 & 0xff; - bytes[offset + 5] = this.low >> 16 & 0xff; - bytes[offset + 6] = this.low >> 8 & 0xff; - bytes[offset + 7] = this.low & 0xff; - } - - assign(word) { - this.high = word.high; - this.low = word.low; - } - -} - -const calculateSHA256 = function calculateSHA256Closure() { - function rotr(x, n) { - return x >>> n | x << 32 - n; - } - - function ch(x, y, z) { - return x & y ^ ~x & z; - } - - function maj(x, y, z) { - return x & y ^ x & z ^ y & z; - } - - function sigma(x) { - return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22); - } - - function sigmaPrime(x) { - return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25); - } - - function littleSigma(x) { - return rotr(x, 7) ^ rotr(x, 18) ^ x >>> 3; - } - - function littleSigmaPrime(x) { - return rotr(x, 17) ^ rotr(x, 19) ^ x >>> 10; - } - - const k = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, [...] - - function hash(data, offset, length) { - let h0 = 0x6a09e667, - h1 = 0xbb67ae85, - h2 = 0x3c6ef372, - h3 = 0xa54ff53a, - h4 = 0x510e527f, - h5 = 0x9b05688c, - h6 = 0x1f83d9ab, - h7 = 0x5be0cd19; - const paddedLength = Math.ceil((length + 9) / 64) * 64; - const padded = new Uint8Array(paddedLength); - let i, j; - - for (i = 0; i < length; ++i) { - padded[i] = data[offset++]; - } + const docBaseUrl = params.docBaseUrl || null; + let action = destDict.get("A"), + url, + dest;
- padded[i++] = 0x80; - const n = paddedLength - 8; + if (!(action instanceof _primitives.Dict)) { + if (destDict.has("Dest")) { + action = destDict.get("Dest"); + } else { + action = destDict.get("AA");
- while (i < n) { - padded[i++] = 0; + if (action instanceof _primitives.Dict) { + if (action.has("D")) { + action = action.get("D"); + } else if (action.has("U")) { + action = action.get("U"); + } + } + } }
- padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = length >>> 29 & 0xff; - padded[i++] = length >> 21 & 0xff; - padded[i++] = length >> 13 & 0xff; - padded[i++] = length >> 5 & 0xff; - padded[i++] = length << 3 & 0xff; - const w = new Uint32Array(64); - - for (i = 0; i < paddedLength;) { - for (j = 0; j < 16; ++j) { - w[j] = padded[i] << 24 | padded[i + 1] << 16 | padded[i + 2] << 8 | padded[i + 3]; - i += 4; - } + if (action instanceof _primitives.Dict) { + const actionType = action.get("S");
- for (j = 16; j < 64; ++j) { - w[j] = littleSigmaPrime(w[j - 2]) + w[j - 7] + littleSigma(w[j - 15]) + w[j - 16] | 0; + if (!(actionType instanceof _primitives.Name)) { + (0, _util.warn)("parseDestDictionary: Invalid type in Action dictionary."); + return; }
- let a = h0, - b = h1, - c = h2, - d = h3, - e = h4, - f = h5, - g = h6, - h = h7, - t1, - t2; + const actionName = actionType.name;
- for (j = 0; j < 64; ++j) { - t1 = h + sigmaPrime(e) + ch(e, f, g) + k[j] + w[j]; - t2 = sigma(a) + maj(a, b, c); - h = g; - g = f; - f = e; - e = d + t1 | 0; - d = c; - c = b; - b = a; - a = t1 + t2 | 0; - } + switch (actionName) { + case "ResetForm": + const flags = action.get("Flags"); + const include = ((typeof flags === "number" ? flags : 0) & 1) === 0; + const fields = []; + const refs = [];
- h0 = h0 + a | 0; - h1 = h1 + b | 0; - h2 = h2 + c | 0; - h3 = h3 + d | 0; - h4 = h4 + e | 0; - h5 = h5 + f | 0; - h6 = h6 + g | 0; - h7 = h7 + h | 0; - } + for (const obj of action.get("Fields") || []) { + if (obj instanceof _primitives.Ref) { + refs.push(obj.toString()); + } else if (typeof obj === "string") { + fields.push((0, _util.stringToPDFString)(obj)); + } + }
- return new Uint8Array([h0 >> 24 & 0xFF, h0 >> 16 & 0xFF, h0 >> 8 & 0xFF, h0 & 0xFF, h1 >> 24 & 0xFF, h1 >> 16 & 0xFF, h1 >> 8 & 0xFF, h1 & 0xFF, h2 >> 24 & 0xFF, h2 >> 16 & 0xFF, h2 >> 8 & 0xFF, h2 & 0xFF, h3 >> 24 & 0xFF, h3 >> 16 & 0xFF, h3 >> 8 & 0xFF, h3 & 0xFF, h4 >> 24 & 0xFF, h4 >> 16 & 0xFF, h4 >> 8 & 0xFF, h4 & 0xFF, h5 >> 24 & 0xFF, h5 >> 16 & 0xFF, h5 >> 8 & 0xFF, h5 & 0xFF, h6 >> 24 & 0xFF, h6 >> 16 & 0xFF, h6 >> 8 & 0xFF, h6 & 0xFF, h7 >> 24 & 0xFF, h7 >> 16 & 0xFF, h7 > [...] - } + resultObj.resetForm = { + fields, + refs, + include + }; + break;
- return hash; -}(); + case "URI": + url = action.get("URI");
-exports.calculateSHA256 = calculateSHA256; + if (url instanceof _primitives.Name) { + url = "/" + url.name; + }
-const calculateSHA512 = function calculateSHA512Closure() { - function ch(result, x, y, z, tmp) { - result.assign(x); - result.and(y); - tmp.assign(x); - tmp.not(); - tmp.and(z); - result.xor(tmp); - } + break;
- function maj(result, x, y, z, tmp) { - result.assign(x); - result.and(y); - tmp.assign(x); - tmp.and(z); - result.xor(tmp); - tmp.assign(y); - tmp.and(z); - result.xor(tmp); - } + case "GoTo": + dest = action.get("D"); + break;
- function sigma(result, x, tmp) { - result.assign(x); - result.rotateRight(28); - tmp.assign(x); - tmp.rotateRight(34); - result.xor(tmp); - tmp.assign(x); - tmp.rotateRight(39); - result.xor(tmp); - } + case "Launch": + case "GoToR": + const urlDict = action.get("F");
- function sigmaPrime(result, x, tmp) { - result.assign(x); - result.rotateRight(14); - tmp.assign(x); - tmp.rotateRight(18); - result.xor(tmp); - tmp.assign(x); - tmp.rotateRight(41); - result.xor(tmp); - } + if (urlDict instanceof _primitives.Dict) { + url = urlDict.get("F") || null; + } else if (typeof urlDict === "string") { + url = urlDict; + }
- function littleSigma(result, x, tmp) { - result.assign(x); - result.rotateRight(1); - tmp.assign(x); - tmp.rotateRight(8); - result.xor(tmp); - tmp.assign(x); - tmp.shiftRight(7); - result.xor(tmp); - } + let remoteDest = action.get("D");
- function littleSigmaPrime(result, x, tmp) { - result.assign(x); - result.rotateRight(19); - tmp.assign(x); - tmp.rotateRight(61); - result.xor(tmp); - tmp.assign(x); - tmp.shiftRight(6); - result.xor(tmp); - } + if (remoteDest) { + if (remoteDest instanceof _primitives.Name) { + remoteDest = remoteDest.name; + }
- const k = [new Word64(0x428a2f98, 0xd728ae22), new Word64(0x71374491, 0x23ef65cd), new Word64(0xb5c0fbcf, 0xec4d3b2f), new Word64(0xe9b5dba5, 0x8189dbbc), new Word64(0x3956c25b, 0xf348b538), new Word64(0x59f111f1, 0xb605d019), new Word64(0x923f82a4, 0xaf194f9b), new Word64(0xab1c5ed5, 0xda6d8118), new Word64(0xd807aa98, 0xa3030242), new Word64(0x12835b01, 0x45706fbe), new Word64(0x243185be, 0x4ee4b28c), new Word64(0x550c7dc3, 0xd5ffb4e2), new Word64(0x72be5d74, 0xf27b896f), new Word64( [...] + if (typeof url === "string") { + const baseUrl = url.split("#")[0];
- function hash(data, offset, length, mode384 = false) { - let h0, h1, h2, h3, h4, h5, h6, h7; + if (typeof remoteDest === "string") { + url = baseUrl + "#" + remoteDest; + } else if (Array.isArray(remoteDest)) { + url = baseUrl + "#" + JSON.stringify(remoteDest); + } + } + }
- if (!mode384) { - h0 = new Word64(0x6a09e667, 0xf3bcc908); - h1 = new Word64(0xbb67ae85, 0x84caa73b); - h2 = new Word64(0x3c6ef372, 0xfe94f82b); - h3 = new Word64(0xa54ff53a, 0x5f1d36f1); - h4 = new Word64(0x510e527f, 0xade682d1); - h5 = new Word64(0x9b05688c, 0x2b3e6c1f); - h6 = new Word64(0x1f83d9ab, 0xfb41bd6b); - h7 = new Word64(0x5be0cd19, 0x137e2179); - } else { - h0 = new Word64(0xcbbb9d5d, 0xc1059ed8); - h1 = new Word64(0x629a292a, 0x367cd507); - h2 = new Word64(0x9159015a, 0x3070dd17); - h3 = new Word64(0x152fecd8, 0xf70e5939); - h4 = new Word64(0x67332667, 0xffc00b31); - h5 = new Word64(0x8eb44a87, 0x68581511); - h6 = new Word64(0xdb0c2e0d, 0x64f98fa7); - h7 = new Word64(0x47b5481d, 0xbefa4fa4); - } + const newWindow = action.get("NewWindow");
- const paddedLength = Math.ceil((length + 17) / 128) * 128; - const padded = new Uint8Array(paddedLength); - let i, j; + if (typeof newWindow === "boolean") { + resultObj.newWindow = newWindow; + }
- for (i = 0; i < length; ++i) { - padded[i] = data[offset++]; - } + break;
- padded[i++] = 0x80; - const n = paddedLength - 16; + case "Named": + const namedAction = action.get("N");
- while (i < n) { - padded[i++] = 0; - } + if (namedAction instanceof _primitives.Name) { + resultObj.action = namedAction.name; + }
- padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = length >>> 29 & 0xff; - padded[i++] = length >> 21 & 0xff; - padded[i++] = length >> 13 & 0xff; - padded[i++] = length >> 5 & 0xff; - padded[i++] = length << 3 & 0xff; - const w = new Array(80); + break;
- for (i = 0; i < 80; i++) { - w[i] = new Word64(0, 0); - } + case "JavaScript": + const jsAction = action.get("JS"); + let js;
- let a = new Word64(0, 0), - b = new Word64(0, 0), - c = new Word64(0, 0); - let d = new Word64(0, 0), - e = new Word64(0, 0), - f = new Word64(0, 0); - let g = new Word64(0, 0), - h = new Word64(0, 0); - const t1 = new Word64(0, 0), - t2 = new Word64(0, 0); - const tmp1 = new Word64(0, 0), - tmp2 = new Word64(0, 0); - let tmp3; + if (jsAction instanceof _base_stream.BaseStream) { + js = jsAction.getString(); + } else if (typeof jsAction === "string") { + js = jsAction; + }
- for (i = 0; i < paddedLength;) { - for (j = 0; j < 16; ++j) { - w[j].high = padded[i] << 24 | padded[i + 1] << 16 | padded[i + 2] << 8 | padded[i + 3]; - w[j].low = padded[i + 4] << 24 | padded[i + 5] << 16 | padded[i + 6] << 8 | padded[i + 7]; - i += 8; - } + const jsURL = js && (0, _core_utils.recoverJsURL)((0, _util.stringToPDFString)(js));
- for (j = 16; j < 80; ++j) { - tmp3 = w[j]; - littleSigmaPrime(tmp3, w[j - 2], tmp2); - tmp3.add(w[j - 7]); - littleSigma(tmp1, w[j - 15], tmp2); - tmp3.add(tmp1); - tmp3.add(w[j - 16]); - } + if (jsURL) { + url = jsURL.url; + resultObj.newWindow = jsURL.newWindow; + break; + }
- a.assign(h0); - b.assign(h1); - c.assign(h2); - d.assign(h3); - e.assign(h4); - f.assign(h5); - g.assign(h6); - h.assign(h7); + default: + if (actionName === "JavaScript" || actionName === "SubmitForm") { + break; + }
- for (j = 0; j < 80; ++j) { - t1.assign(h); - sigmaPrime(tmp1, e, tmp2); - t1.add(tmp1); - ch(tmp1, e, f, g, tmp2); - t1.add(tmp1); - t1.add(k[j]); - t1.add(w[j]); - sigma(t2, a, tmp2); - maj(tmp1, a, b, c, tmp2); - t2.add(tmp1); - tmp3 = h; - h = g; - g = f; - f = e; - d.add(t1); - e = d; - d = c; - c = b; - b = a; - tmp3.assign(t1); - tmp3.add(t2); - a = tmp3; + (0, _util.warn)(`parseDestDictionary - unsupported action: "${actionName}".`); + break; } - - h0.add(a); - h1.add(b); - h2.add(c); - h3.add(d); - h4.add(e); - h5.add(f); - h6.add(g); - h7.add(h); + } else if (destDict.has("Dest")) { + dest = destDict.get("Dest"); }
- let result; + if (typeof url === "string") { + const absoluteUrl = (0, _util.createValidAbsoluteUrl)(url, docBaseUrl, { + addDefaultProtocol: true, + tryConvertEncoding: true + });
- if (!mode384) { - result = new Uint8Array(64); - h0.copyTo(result, 0); - h1.copyTo(result, 8); - h2.copyTo(result, 16); - h3.copyTo(result, 24); - h4.copyTo(result, 32); - h5.copyTo(result, 40); - h6.copyTo(result, 48); - h7.copyTo(result, 56); - } else { - result = new Uint8Array(48); - h0.copyTo(result, 0); - h1.copyTo(result, 8); - h2.copyTo(result, 16); - h3.copyTo(result, 24); - h4.copyTo(result, 32); - h5.copyTo(result, 40); + if (absoluteUrl) { + resultObj.url = absoluteUrl.href; + } + + resultObj.unsafeUrl = url; }
- return result; + if (dest) { + if (dest instanceof _primitives.Name) { + dest = dest.name; + } + + if (typeof dest === "string") { + resultObj.dest = (0, _util.stringToPDFString)(dest); + } else if (Array.isArray(dest)) { + resultObj.dest = dest; + } + } }
- return hash; -}(); +}
-exports.calculateSHA512 = calculateSHA512; +exports.Catalog = Catalog;
-function calculateSHA384(data, offset, length) { - return calculateSHA512(data, offset, length, true); -} +/***/ }), +/* 70 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
-class NullCipher { - decryptBlock(data) { - return data; - }
- encrypt(data) { - return data; - }
-} +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.NumberTree = exports.NameTree = void 0;
-class AESBaseCipher { - constructor() { - if (this.constructor === AESBaseCipher) { - (0, _util.unreachable)("Cannot initialize AESBaseCipher."); - } +var _primitives = __w_pdfjs_require__(5);
- this._s = new Uint8Array([0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, [...] - this._inv_s = new Uint8Array([0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x [...] - this._mix = new Uint32Array([0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381, 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xf [...] - this._mixCol = new Uint8Array(256); +var _util = __w_pdfjs_require__(2);
- for (let i = 0; i < 256; i++) { - if (i < 128) { - this._mixCol[i] = i << 1; - } else { - this._mixCol[i] = i << 1 ^ 0x1b; - } +class NameOrNumberTree { + constructor(root, xref, type) { + if (this.constructor === NameOrNumberTree) { + (0, _util.unreachable)("Cannot initialize NameOrNumberTree."); }
- this.buffer = new Uint8Array(16); - this.bufferPosition = 0; - } - - _expandKey(cipherKey) { - (0, _util.unreachable)("Cannot call `_expandKey` on the base class"); + this.root = root; + this.xref = xref; + this._type = type; }
- _decrypt(input, key) { - let t, u, v; - const state = new Uint8Array(16); - state.set(input); + getAll() { + const map = new Map();
- for (let j = 0, k = this._keySize; j < 16; ++j, ++k) { - state[j] ^= key[k]; + if (!this.root) { + return map; }
- for (let i = this._cyclesOfRepetition - 1; i >= 1; --i) { - t = state[13]; - state[13] = state[9]; - state[9] = state[5]; - state[5] = state[1]; - state[1] = t; - t = state[14]; - u = state[10]; - state[14] = state[6]; - state[10] = state[2]; - state[6] = t; - state[2] = u; - t = state[15]; - u = state[11]; - v = state[7]; - state[15] = state[3]; - state[11] = t; - state[7] = u; - state[3] = v; + const xref = this.xref; + const processed = new _primitives.RefSet(); + processed.put(this.root); + const queue = [this.root];
- for (let j = 0; j < 16; ++j) { - state[j] = this._inv_s[state[j]]; + while (queue.length > 0) { + const obj = xref.fetchIfRef(queue.shift()); + + if (!(obj instanceof _primitives.Dict)) { + continue; }
- for (let j = 0, k = i * 16; j < 16; ++j, ++k) { - state[j] ^= key[k]; + if (obj.has("Kids")) { + const kids = obj.get("Kids"); + + if (!Array.isArray(kids)) { + continue; + } + + for (const kid of kids) { + if (processed.has(kid)) { + throw new _util.FormatError(`Duplicate entry in "${this._type}" tree.`); + } + + queue.push(kid); + processed.put(kid); + } + + continue; }
- for (let j = 0; j < 16; j += 4) { - const s0 = this._mix[state[j]]; - const s1 = this._mix[state[j + 1]]; - const s2 = this._mix[state[j + 2]]; - const s3 = this._mix[state[j + 3]]; - t = s0 ^ s1 >>> 8 ^ s1 << 24 ^ s2 >>> 16 ^ s2 << 16 ^ s3 >>> 24 ^ s3 << 8; - state[j] = t >>> 24 & 0xff; - state[j + 1] = t >> 16 & 0xff; - state[j + 2] = t >> 8 & 0xff; - state[j + 3] = t & 0xff; + const entries = obj.get(this._type); + + if (!Array.isArray(entries)) { + continue; + } + + for (let i = 0, ii = entries.length; i < ii; i += 2) { + map.set(xref.fetchIfRef(entries[i]), xref.fetchIfRef(entries[i + 1])); } }
- t = state[13]; - state[13] = state[9]; - state[9] = state[5]; - state[5] = state[1]; - state[1] = t; - t = state[14]; - u = state[10]; - state[14] = state[6]; - state[10] = state[2]; - state[6] = t; - state[2] = u; - t = state[15]; - u = state[11]; - v = state[7]; - state[15] = state[3]; - state[11] = t; - state[7] = u; - state[3] = v; + return map; + }
- for (let j = 0; j < 16; ++j) { - state[j] = this._inv_s[state[j]]; - state[j] ^= key[j]; + get(key) { + if (!this.root) { + return null; }
- return state; - } + const xref = this.xref; + let kidsOrEntries = xref.fetchIfRef(this.root); + let loopCount = 0; + const MAX_LEVELS = 10;
- _encrypt(input, key) { - const s = this._s; - let t, u, v; - const state = new Uint8Array(16); - state.set(input); + while (kidsOrEntries.has("Kids")) { + if (++loopCount > MAX_LEVELS) { + (0, _util.warn)(`Search depth limit reached for "${this._type}" tree.`); + return null; + }
- for (let j = 0; j < 16; ++j) { - state[j] ^= key[j]; - } + const kids = kidsOrEntries.get("Kids");
- for (let i = 1; i < this._cyclesOfRepetition; i++) { - for (let j = 0; j < 16; ++j) { - state[j] = s[state[j]]; + if (!Array.isArray(kids)) { + return null; }
- v = state[1]; - state[1] = state[5]; - state[5] = state[9]; - state[9] = state[13]; - state[13] = v; - v = state[2]; - u = state[6]; - state[2] = state[10]; - state[6] = state[14]; - state[10] = v; - state[14] = u; - v = state[3]; - u = state[7]; - t = state[11]; - state[3] = state[15]; - state[7] = v; - state[11] = u; - state[15] = t; + let l = 0, + r = kids.length - 1;
- for (let j = 0; j < 16; j += 4) { - const s0 = state[j + 0]; - const s1 = state[j + 1]; - const s2 = state[j + 2]; - const s3 = state[j + 3]; - t = s0 ^ s1 ^ s2 ^ s3; - state[j + 0] ^= t ^ this._mixCol[s0 ^ s1]; - state[j + 1] ^= t ^ this._mixCol[s1 ^ s2]; - state[j + 2] ^= t ^ this._mixCol[s2 ^ s3]; - state[j + 3] ^= t ^ this._mixCol[s3 ^ s0]; + while (l <= r) { + const m = l + r >> 1; + const kid = xref.fetchIfRef(kids[m]); + const limits = kid.get("Limits"); + + if (key < xref.fetchIfRef(limits[0])) { + r = m - 1; + } else if (key > xref.fetchIfRef(limits[1])) { + l = m + 1; + } else { + kidsOrEntries = kid; + break; + } }
- for (let j = 0, k = i * 16; j < 16; ++j, ++k) { - state[j] ^= key[k]; + if (l > r) { + return null; } }
- for (let j = 0; j < 16; ++j) { - state[j] = s[state[j]]; - } + const entries = kidsOrEntries.get(this._type);
- v = state[1]; - state[1] = state[5]; - state[5] = state[9]; - state[9] = state[13]; - state[13] = v; - v = state[2]; - u = state[6]; - state[2] = state[10]; - state[6] = state[14]; - state[10] = v; - state[14] = u; - v = state[3]; - u = state[7]; - t = state[11]; - state[3] = state[15]; - state[7] = v; - state[11] = u; - state[15] = t; + if (Array.isArray(entries)) { + let l = 0, + r = entries.length - 2;
- for (let j = 0, k = this._keySize; j < 16; ++j, ++k) { - state[j] ^= key[k]; + while (l <= r) { + const tmp = l + r >> 1, + m = tmp + (tmp & 1); + const currentKey = xref.fetchIfRef(entries[m]); + + if (key < currentKey) { + r = m - 2; + } else if (key > currentKey) { + l = m + 2; + } else { + return xref.fetchIfRef(entries[m + 1]); + } + } }
- return state; + return null; }
- _decryptBlock2(data, finalize) { - const sourceLength = data.length; - let buffer = this.buffer, - bufferLength = this.bufferPosition; - const result = []; - let iv = this.iv; +}
- for (let i = 0; i < sourceLength; ++i) { - buffer[bufferLength] = data[i]; - ++bufferLength; +class NameTree extends NameOrNumberTree { + constructor(root, xref) { + super(root, xref, "Names"); + }
- if (bufferLength < 16) { - continue; - } +}
- const plain = this._decrypt(buffer, this._key); +exports.NameTree = NameTree;
- for (let j = 0; j < 16; ++j) { - plain[j] ^= iv[j]; - } +class NumberTree extends NameOrNumberTree { + constructor(root, xref) { + super(root, xref, "Nums"); + }
- iv = buffer; - result.push(plain); - buffer = new Uint8Array(16); - bufferLength = 0; - } +}
- this.buffer = buffer; - this.bufferLength = bufferLength; - this.iv = iv; +exports.NumberTree = NumberTree;
- if (result.length === 0) { - return new Uint8Array(0); - } +/***/ }), +/* 71 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- let outputLength = 16 * result.length;
- if (finalize) { - const lastBlock = result[result.length - 1]; - let psLen = lastBlock[15];
- if (psLen <= 16) { - for (let i = 15, ii = 16 - psLen; i >= ii; --i) { - if (lastBlock[i] !== psLen) { - psLen = 0; - break; - } - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.clearGlobalCaches = clearGlobalCaches;
- outputLength -= psLen; - result[result.length - 1] = lastBlock.subarray(0, 16 - psLen); - } - } +var _primitives = __w_pdfjs_require__(5);
- const output = new Uint8Array(outputLength); +var _unicode = __w_pdfjs_require__(21);
- for (let i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) { - output.set(result[i], j); - } +function clearGlobalCaches() { + (0, _primitives.clearPrimitiveCaches)(); + (0, _unicode.clearUnicodeCaches)(); +}
- return output; - } +/***/ }), +/* 72 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- decryptBlock(data, finalize, iv = null) { - const sourceLength = data.length; - const buffer = this.buffer; - let bufferLength = this.bufferPosition;
- if (iv) { - this.iv = iv; - } else { - for (let i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) { - buffer[bufferLength] = data[i]; - }
- if (bufferLength < 16) { - this.bufferLength = bufferLength; - return new Uint8Array(0); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.FileSpec = void 0;
- this.iv = buffer; - data = data.subarray(16); - } +var _util = __w_pdfjs_require__(2);
- this.buffer = new Uint8Array(16); - this.bufferLength = 0; - this.decryptBlock = this._decryptBlock2; - return this.decryptBlock(data, finalize); +var _base_stream = __w_pdfjs_require__(7); + +var _primitives = __w_pdfjs_require__(5); + +function pickPlatformItem(dict) { + if (dict.has("UF")) { + return dict.get("UF"); + } else if (dict.has("F")) { + return dict.get("F"); + } else if (dict.has("Unix")) { + return dict.get("Unix"); + } else if (dict.has("Mac")) { + return dict.get("Mac"); + } else if (dict.has("DOS")) { + return dict.get("DOS"); }
- encrypt(data, iv) { - const sourceLength = data.length; - let buffer = this.buffer, - bufferLength = this.bufferPosition; - const result = []; + return null; +}
- if (!iv) { - iv = new Uint8Array(16); +class FileSpec { + constructor(root, xref) { + if (!(root instanceof _primitives.Dict)) { + return; }
- for (let i = 0; i < sourceLength; ++i) { - buffer[bufferLength] = data[i]; - ++bufferLength; + this.xref = xref; + this.root = root;
- if (bufferLength < 16) { - continue; - } + if (root.has("FS")) { + this.fs = root.get("FS"); + }
- for (let j = 0; j < 16; ++j) { - buffer[j] ^= iv[j]; - } + this.description = root.has("Desc") ? (0, _util.stringToPDFString)(root.get("Desc")) : "";
- const cipher = this._encrypt(buffer, this._key); + if (root.has("RF")) { + (0, _util.warn)("Related file specifications are not supported"); + }
- iv = cipher; - result.push(cipher); - buffer = new Uint8Array(16); - bufferLength = 0; + this.contentAvailable = true; + + if (!root.has("EF")) { + this.contentAvailable = false; + (0, _util.warn)("Non-embedded file specifications are not supported"); } + }
- this.buffer = buffer; - this.bufferLength = bufferLength; - this.iv = iv; + get filename() { + if (!this._filename && this.root) { + const filename = pickPlatformItem(this.root) || "unnamed"; + this._filename = (0, _util.stringToPDFString)(filename).replace(/\\/g, "\").replace(/\//g, "/").replace(/\/g, "/"); + }
- if (result.length === 0) { - return new Uint8Array(0); + return this._filename; + } + + get content() { + if (!this.contentAvailable) { + return null; }
- const outputLength = 16 * result.length; - const output = new Uint8Array(outputLength); + if (!this.contentRef && this.root) { + this.contentRef = pickPlatformItem(this.root.get("EF")); + }
- for (let i = 0, j = 0, ii = result.length; i < ii; ++i, j += 16) { - output.set(result[i], j); + let content = null; + + if (this.contentRef) { + const fileObj = this.xref.fetchIfRef(this.contentRef); + + if (fileObj instanceof _base_stream.BaseStream) { + content = fileObj.getBytes(); + } else { + (0, _util.warn)("Embedded file specification points to non-existing/invalid content"); + } + } else { + (0, _util.warn)("Embedded file specification does not have a content"); }
- return output; + return content; + } + + get serializable() { + return { + filename: this.filename, + content: this.content + }; }
}
-class AES128Cipher extends AESBaseCipher { - constructor(key) { - super(); - this._cyclesOfRepetition = 10; - this._keySize = 160; - this._rcon = new Uint8Array([0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb [...] - this._key = this._expandKey(key); - } +exports.FileSpec = FileSpec;
- _expandKey(cipherKey) { - const b = 176; - const s = this._s; - const rcon = this._rcon; - const result = new Uint8Array(b); - result.set(cipherKey); +/***/ }), +/* 73 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- for (let j = 16, i = 1; j < b; ++i) { - let t1 = result[j - 3]; - let t2 = result[j - 2]; - let t3 = result[j - 1]; - let t4 = result[j - 4]; - t1 = s[t1]; - t2 = s[t2]; - t3 = s[t3]; - t4 = s[t4]; - t1 ^= rcon[i];
- for (let n = 0; n < 4; ++n) { - result[j] = t1 ^= result[j - 16]; - j++; - result[j] = t2 ^= result[j - 16]; - j++; - result[j] = t3 ^= result[j - 16]; - j++; - result[j] = t4 ^= result[j - 16]; - j++; - } - }
- return result; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.MetadataParser = void 0;
-} +var _xml_parser = __w_pdfjs_require__(66);
-exports.AES128Cipher = AES128Cipher; +class MetadataParser { + constructor(data) { + data = this._repair(data); + const parser = new _xml_parser.SimpleXMLParser({ + lowerCaseName: true + }); + const xmlDocument = parser.parseFromString(data); + this._metadataMap = new Map(); + this._data = data;
-class AES256Cipher extends AESBaseCipher { - constructor(key) { - super(); - this._cyclesOfRepetition = 14; - this._keySize = 224; - this._key = this._expandKey(key); + if (xmlDocument) { + this._parse(xmlDocument); + } }
- _expandKey(cipherKey) { - const b = 240; - const s = this._s; - const result = new Uint8Array(b); - result.set(cipherKey); - let r = 1; - let t1, t2, t3, t4; + _repair(data) { + return data.replace(/^[^<]+/, "").replace(/>\376\377([^<]+)/g, function (all, codes) { + const bytes = codes.replace(/\([0-3])([0-7])([0-7])/g, function (code, d1, d2, d3) { + return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1); + }).replace(/&(amp|apos|gt|lt|quot);/g, function (str, name) { + switch (name) { + case "amp": + return "&";
- for (let j = 32, i = 1; j < b; ++i) { - if (j % 32 === 16) { - t1 = s[t1]; - t2 = s[t2]; - t3 = s[t3]; - t4 = s[t4]; - } else if (j % 32 === 0) { - t1 = result[j - 3]; - t2 = result[j - 2]; - t3 = result[j - 1]; - t4 = result[j - 4]; - t1 = s[t1]; - t2 = s[t2]; - t3 = s[t3]; - t4 = s[t4]; - t1 ^= r; + case "apos": + return "'";
- if ((r <<= 1) >= 256) { - r = (r ^ 0x1b) & 0xff; + case "gt": + return ">"; + + case "lt": + return "<"; + + case "quot": + return '"'; } - }
- for (let n = 0; n < 4; ++n) { - result[j] = t1 ^= result[j - 32]; - j++; - result[j] = t2 ^= result[j - 32]; - j++; - result[j] = t3 ^= result[j - 32]; - j++; - result[j] = t4 ^= result[j - 32]; - j++; + throw new Error(`_repair: ${name} isn't defined.`); + }); + const charBuf = []; + + for (let i = 0, ii = bytes.length; i < ii; i += 2) { + const code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1); + + if (code >= 32 && code < 127 && code !== 60 && code !== 62 && code !== 38) { + charBuf.push(String.fromCharCode(code)); + } else { + charBuf.push("&#x" + (0x10000 + code).toString(16).substring(1) + ";"); + } } - }
- return result; + return ">" + charBuf.join(""); + }); }
-} + _getSequence(entry) { + const name = entry.nodeName;
-exports.AES256Cipher = AES256Cipher; + if (name !== "rdf:bag" && name !== "rdf:seq" && name !== "rdf:alt") { + return null; + }
-class PDF17 { - checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) { - const hashData = new Uint8Array(password.length + 56); - hashData.set(password, 0); - hashData.set(ownerValidationSalt, password.length); - hashData.set(userBytes, password.length + ownerValidationSalt.length); - const result = calculateSHA256(hashData, 0, hashData.length); - return (0, _util.isArrayEqual)(result, ownerPassword); + return entry.childNodes.filter(node => node.nodeName === "rdf:li"); }
- checkUserPassword(password, userValidationSalt, userPassword) { - const hashData = new Uint8Array(password.length + 8); - hashData.set(password, 0); - hashData.set(userValidationSalt, password.length); - const result = calculateSHA256(hashData, 0, hashData.length); - return (0, _util.isArrayEqual)(result, userPassword); - } + _parseArray(entry) { + if (!entry.hasChildNodes()) { + return; + }
- getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) { - const hashData = new Uint8Array(password.length + 56); - hashData.set(password, 0); - hashData.set(ownerKeySalt, password.length); - hashData.set(userBytes, password.length + ownerKeySalt.length); - const key = calculateSHA256(hashData, 0, hashData.length); - const cipher = new AES256Cipher(key); - return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16)); - } + const [seqNode] = entry.childNodes; + const sequence = this._getSequence(seqNode) || [];
- getUserKey(password, userKeySalt, userEncryption) { - const hashData = new Uint8Array(password.length + 8); - hashData.set(password, 0); - hashData.set(userKeySalt, password.length); - const key = calculateSHA256(hashData, 0, hashData.length); - const cipher = new AES256Cipher(key); - return cipher.decryptBlock(userEncryption, false, new Uint8Array(16)); + this._metadataMap.set(entry.nodeName, sequence.map(node => node.textContent.trim())); }
-} + _parse(xmlDocument) { + let rdf = xmlDocument.documentElement;
-exports.PDF17 = PDF17; + if (rdf.nodeName !== "rdf:rdf") { + rdf = rdf.firstChild;
-const PDF20 = function PDF20Closure() { - function calculatePDF20Hash(password, input, userBytes) { - let k = calculateSHA256(input, 0, input.length).subarray(0, 32); - let e = [0]; - let i = 0; + while (rdf && rdf.nodeName !== "rdf:rdf") { + rdf = rdf.nextSibling; + } + }
- while (i < 64 || e[e.length - 1] > i - 32) { - const combinedLength = password.length + k.length + userBytes.length, - combinedArray = new Uint8Array(combinedLength); - let writeOffset = 0; - combinedArray.set(password, writeOffset); - writeOffset += password.length; - combinedArray.set(k, writeOffset); - writeOffset += k.length; - combinedArray.set(userBytes, writeOffset); - const k1 = new Uint8Array(combinedLength * 64); + if (!rdf || rdf.nodeName !== "rdf:rdf" || !rdf.hasChildNodes()) { + return; + }
- for (let j = 0, pos = 0; j < 64; j++, pos += combinedLength) { - k1.set(combinedArray, pos); + for (const desc of rdf.childNodes) { + if (desc.nodeName !== "rdf:description") { + continue; }
- const cipher = new AES128Cipher(k.subarray(0, 16)); - e = cipher.encrypt(k1, k.subarray(16, 32)); - let remainder = 0; + for (const entry of desc.childNodes) { + const name = entry.nodeName;
- for (let z = 0; z < 16; z++) { - remainder *= 256 % 3; - remainder %= 3; - remainder += (e[z] >>> 0) % 3; - remainder %= 3; - } + switch (name) { + case "#text": + continue;
- if (remainder === 0) { - k = calculateSHA256(e, 0, e.length); - } else if (remainder === 1) { - k = calculateSHA384(e, 0, e.length); - } else if (remainder === 2) { - k = calculateSHA512(e, 0, e.length); - } + case "dc:creator": + case "dc:subject": + this._parseArray(entry);
- i++; + continue; + } + + this._metadataMap.set(name, entry.textContent.trim()); + } } + }
- return k.subarray(0, 32); + get serializable() { + return { + parsedData: this._metadataMap, + rawData: this._data + }; }
- class PDF20 { - hash(password, concatBytes, userBytes) { - return calculatePDF20Hash(password, concatBytes, userBytes); - } +}
- checkOwnerPassword(password, ownerValidationSalt, userBytes, ownerPassword) { - const hashData = new Uint8Array(password.length + 56); - hashData.set(password, 0); - hashData.set(ownerValidationSalt, password.length); - hashData.set(userBytes, password.length + ownerValidationSalt.length); - const result = calculatePDF20Hash(password, hashData, userBytes); - return (0, _util.isArrayEqual)(result, ownerPassword); - } +exports.MetadataParser = MetadataParser;
- checkUserPassword(password, userValidationSalt, userPassword) { - const hashData = new Uint8Array(password.length + 8); - hashData.set(password, 0); - hashData.set(userValidationSalt, password.length); - const result = calculatePDF20Hash(password, hashData, []); - return (0, _util.isArrayEqual)(result, userPassword); - } +/***/ }), +/* 74 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- getOwnerKey(password, ownerKeySalt, userBytes, ownerEncryption) { - const hashData = new Uint8Array(password.length + 56); - hashData.set(password, 0); - hashData.set(ownerKeySalt, password.length); - hashData.set(userBytes, password.length + ownerKeySalt.length); - const key = calculatePDF20Hash(password, hashData, userBytes); - const cipher = new AES256Cipher(key); - return cipher.decryptBlock(ownerEncryption, false, new Uint8Array(16)); - }
- getUserKey(password, userKeySalt, userEncryption) { - const hashData = new Uint8Array(password.length + 8); - hashData.set(password, 0); - hashData.set(userKeySalt, password.length); - const key = calculatePDF20Hash(password, hashData, []); - const cipher = new AES256Cipher(key); - return cipher.decryptBlock(userEncryption, false, new Uint8Array(16)); - }
- } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.StructTreeRoot = exports.StructTreePage = void 0;
- return PDF20; -}(); +var _primitives = __w_pdfjs_require__(5);
-exports.PDF20 = PDF20; +var _util = __w_pdfjs_require__(2);
-class CipherTransform { - constructor(stringCipherConstructor, streamCipherConstructor) { - this.StringCipherConstructor = stringCipherConstructor; - this.StreamCipherConstructor = streamCipherConstructor; - } +var _name_number_tree = __w_pdfjs_require__(70);
- createStream(stream, length) { - const cipher = new this.StreamCipherConstructor(); - return new _decrypt_stream.DecryptStream(stream, length, function cipherTransformDecryptStream(data, finalize) { - return cipher.decryptBlock(data, finalize); - }); +const MAX_DEPTH = 40; +const StructElementType = { + PAGE_CONTENT: "PAGE_CONTENT", + STREAM_CONTENT: "STREAM_CONTENT", + OBJECT: "OBJECT", + ELEMENT: "ELEMENT" +}; + +class StructTreeRoot { + constructor(rootDict) { + this.dict = rootDict; + this.roleMap = new Map(); }
- decryptString(s) { - const cipher = new this.StringCipherConstructor(); - let data = (0, _util.stringToBytes)(s); - data = cipher.decryptBlock(data, true); - return (0, _util.bytesToString)(data); + init() { + this.readRoleMap(); }
- encryptString(s) { - const cipher = new this.StringCipherConstructor(); + readRoleMap() { + const roleMapDict = this.dict.get("RoleMap");
- if (cipher instanceof AESBaseCipher) { - const strLen = s.length; - const pad = 16 - strLen % 16; - s += String.fromCharCode(pad).repeat(pad); - const iv = new Uint8Array(16); + if (!(roleMapDict instanceof _primitives.Dict)) { + return; + }
- if (typeof crypto !== "undefined") { - crypto.getRandomValues(iv); - } else { - for (let i = 0; i < 16; i++) { - iv[i] = Math.floor(256 * Math.random()); - } + roleMapDict.forEach((key, value) => { + if (!(value instanceof _primitives.Name)) { + return; }
- let data = (0, _util.stringToBytes)(s); - data = cipher.encrypt(data, iv); - const buf = new Uint8Array(16 + data.length); - buf.set(iv); - buf.set(data, 16); - return (0, _util.bytesToString)(buf); - } - - let data = (0, _util.stringToBytes)(s); - data = cipher.encrypt(data); - return (0, _util.bytesToString)(data); + this.roleMap.set(key, value.name); + }); }
}
-const CipherTransformFactory = function CipherTransformFactoryClosure() { - const defaultPasswordBytes = new Uint8Array([0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a]); +exports.StructTreeRoot = StructTreeRoot;
- function createEncryptionKey20(revision, password, ownerPassword, ownerValidationSalt, ownerKeySalt, uBytes, userPassword, userValidationSalt, userKeySalt, ownerEncryption, userEncryption, perms) { - if (password) { - const passwordLength = Math.min(127, password.length); - password = password.subarray(0, passwordLength); - } else { - password = []; - } +class StructElementNode { + constructor(tree, dict) { + this.tree = tree; + this.dict = dict; + this.kids = []; + this.parseKids(); + }
- let pdfAlgorithm; + get role() { + const nameObj = this.dict.get("S"); + const name = nameObj instanceof _primitives.Name ? nameObj.name : ""; + const { + root + } = this.tree;
- if (revision === 6) { - pdfAlgorithm = new PDF20(); - } else { - pdfAlgorithm = new PDF17(); + if (root.roleMap.has(name)) { + return root.roleMap.get(name); }
- if (pdfAlgorithm.checkUserPassword(password, userValidationSalt, userPassword)) { - return pdfAlgorithm.getUserKey(password, userKeySalt, userEncryption); - } else if (password.length && pdfAlgorithm.checkOwnerPassword(password, ownerValidationSalt, uBytes, ownerPassword)) { - return pdfAlgorithm.getOwnerKey(password, ownerKeySalt, uBytes, ownerEncryption); + return name; + } + + parseKids() { + let pageObjId = null; + const objRef = this.dict.getRaw("Pg"); + + if (objRef instanceof _primitives.Ref) { + pageObjId = objRef.toString(); }
- return null; - } + const kids = this.dict.get("K");
- function prepareKeyData(fileId, password, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata) { - const hashDataSize = 40 + ownerPassword.length + fileId.length; - const hashData = new Uint8Array(hashDataSize); - let i = 0, - j, - n; + if (Array.isArray(kids)) { + for (const kid of kids) { + const element = this.parseKid(pageObjId, kid);
- if (password) { - n = Math.min(32, password.length); + if (element) { + this.kids.push(element); + } + } + } else { + const element = this.parseKid(pageObjId, kids);
- for (; i < n; ++i) { - hashData[i] = password[i]; + if (element) { + this.kids.push(element); } } + }
- j = 0; + parseKid(pageObjId, kid) { + if (Number.isInteger(kid)) { + if (this.tree.pageDict.objId !== pageObjId) { + return null; + }
- while (i < 32) { - hashData[i++] = defaultPasswordBytes[j++]; + return new StructElement({ + type: StructElementType.PAGE_CONTENT, + mcid: kid, + pageObjId + }); }
- for (j = 0, n = ownerPassword.length; j < n; ++j) { - hashData[i++] = ownerPassword[j]; - } + let kidDict = null;
- hashData[i++] = flags & 0xff; - hashData[i++] = flags >> 8 & 0xff; - hashData[i++] = flags >> 16 & 0xff; - hashData[i++] = flags >>> 24 & 0xff; + if (kid instanceof _primitives.Ref) { + kidDict = this.dict.xref.fetch(kid); + } else if (kid instanceof _primitives.Dict) { + kidDict = kid; + }
- for (j = 0, n = fileId.length; j < n; ++j) { - hashData[i++] = fileId[j]; + if (!kidDict) { + return null; }
- if (revision >= 4 && !encryptMetadata) { - hashData[i++] = 0xff; - hashData[i++] = 0xff; - hashData[i++] = 0xff; - hashData[i++] = 0xff; + const pageRef = kidDict.getRaw("Pg"); + + if (pageRef instanceof _primitives.Ref) { + pageObjId = pageRef.toString(); }
- let hash = calculateMD5(hashData, 0, i); - const keyLengthInBytes = keyLength >> 3; + const type = kidDict.get("Type") instanceof _primitives.Name ? kidDict.get("Type").name : null;
- if (revision >= 3) { - for (j = 0; j < 50; ++j) { - hash = calculateMD5(hash, 0, keyLengthInBytes); + if (type === "MCR") { + if (this.tree.pageDict.objId !== pageObjId) { + return null; } - }
- const encryptionKey = hash.subarray(0, keyLengthInBytes); - let cipher, checkData; + return new StructElement({ + type: StructElementType.STREAM_CONTENT, + refObjId: kidDict.getRaw("Stm") instanceof _primitives.Ref ? kidDict.getRaw("Stm").toString() : null, + pageObjId, + mcid: kidDict.get("MCID") + }); + }
- if (revision >= 3) { - for (i = 0; i < 32; ++i) { - hashData[i] = defaultPasswordBytes[i]; + if (type === "OBJR") { + if (this.tree.pageDict.objId !== pageObjId) { + return null; }
- for (j = 0, n = fileId.length; j < n; ++j) { - hashData[i++] = fileId[j]; - } + return new StructElement({ + type: StructElementType.OBJECT, + refObjId: kidDict.getRaw("Obj") instanceof _primitives.Ref ? kidDict.getRaw("Obj").toString() : null, + pageObjId + }); + } + + return new StructElement({ + type: StructElementType.ELEMENT, + dict: kidDict + }); + }
- cipher = new ARCFourCipher(encryptionKey); - checkData = cipher.encryptBlock(calculateMD5(hashData, 0, i)); - n = encryptionKey.length; - const derivedKey = new Uint8Array(n); +}
- for (j = 1; j <= 19; ++j) { - for (let k = 0; k < n; ++k) { - derivedKey[k] = encryptionKey[k] ^ j; - } +class StructElement { + constructor({ + type, + dict = null, + mcid = null, + pageObjId = null, + refObjId = null + }) { + this.type = type; + this.dict = dict; + this.mcid = mcid; + this.pageObjId = pageObjId; + this.refObjId = refObjId; + this.parentNode = null; + }
- cipher = new ARCFourCipher(derivedKey); - checkData = cipher.encryptBlock(checkData); - } +}
- for (j = 0, n = checkData.length; j < n; ++j) { - if (userPassword[j] !== checkData[j]) { - return null; - } - } - } else { - cipher = new ARCFourCipher(encryptionKey); - checkData = cipher.encryptBlock(defaultPasswordBytes); +class StructTreePage { + constructor(structTreeRoot, pageDict) { + this.root = structTreeRoot; + this.rootDict = structTreeRoot ? structTreeRoot.dict : null; + this.pageDict = pageDict; + this.nodes = []; + }
- for (j = 0, n = checkData.length; j < n; ++j) { - if (userPassword[j] !== checkData[j]) { - return null; - } - } + parse() { + if (!this.root || !this.rootDict) { + return; }
- return encryptionKey; - } + const parentTree = this.rootDict.get("ParentTree");
- function decodeUserPassword(password, ownerPassword, revision, keyLength) { - const hashData = new Uint8Array(32); - let i = 0; - const n = Math.min(32, password.length); + if (!parentTree) { + return; + }
- for (; i < n; ++i) { - hashData[i] = password[i]; + const id = this.pageDict.get("StructParents"); + + if (!Number.isInteger(id)) { + return; }
- let j = 0; + const numberTree = new _name_number_tree.NumberTree(parentTree, this.rootDict.xref); + const parentArray = numberTree.get(id);
- while (i < 32) { - hashData[i++] = defaultPasswordBytes[j++]; + if (!Array.isArray(parentArray)) { + return; }
- let hash = calculateMD5(hashData, 0, i); - const keyLengthInBytes = keyLength >> 3; + const map = new Map();
- if (revision >= 3) { - for (j = 0; j < 50; ++j) { - hash = calculateMD5(hash, 0, hash.length); + for (const ref of parentArray) { + if (ref instanceof _primitives.Ref) { + this.addNode(this.rootDict.xref.fetch(ref), map); } } + }
- let cipher, userPassword; + addNode(dict, map, level = 0) { + if (level > MAX_DEPTH) { + (0, _util.warn)("StructTree MAX_DEPTH reached."); + return null; + }
- if (revision >= 3) { - userPassword = ownerPassword; - const derivedKey = new Uint8Array(keyLengthInBytes); + if (map.has(dict)) { + return map.get(dict); + }
- for (j = 19; j >= 0; j--) { - for (let k = 0; k < keyLengthInBytes; ++k) { - derivedKey[k] = hash[k] ^ j; - } + const element = new StructElementNode(this, dict); + map.set(dict, element); + const parent = dict.get("P");
- cipher = new ARCFourCipher(derivedKey); - userPassword = cipher.encryptBlock(userPassword); + if (!parent || (0, _primitives.isName)(parent.get("Type"), "StructTreeRoot")) { + if (!this.addTopLevelNode(dict, element)) { + map.delete(dict); } - } else { - cipher = new ARCFourCipher(hash.subarray(0, keyLengthInBytes)); - userPassword = cipher.encryptBlock(ownerPassword); + + return element; }
- return userPassword; - } + const parentNode = this.addNode(parent, map, level + 1);
- const identityName = _primitives.Name.get("Identity"); + if (!parentNode) { + return element; + }
- function buildObjectKey(num, gen, encryptionKey, isAes = false) { - const key = new Uint8Array(encryptionKey.length + 9); - const n = encryptionKey.length; - let i; + let save = false;
- for (i = 0; i < n; ++i) { - key[i] = encryptionKey[i]; + for (const kid of parentNode.kids) { + if (kid.type === StructElementType.ELEMENT && kid.dict === dict) { + kid.parentNode = element; + save = true; + } }
- key[i++] = num & 0xff; - key[i++] = num >> 8 & 0xff; - key[i++] = num >> 16 & 0xff; - key[i++] = gen & 0xff; - key[i++] = gen >> 8 & 0xff; - - if (isAes) { - key[i++] = 0x73; - key[i++] = 0x41; - key[i++] = 0x6c; - key[i++] = 0x54; + if (!save) { + map.delete(dict); }
- const hash = calculateMD5(key, 0, i); - return hash.subarray(0, Math.min(encryptionKey.length + 5, 16)); + return element; }
- function buildCipherConstructor(cf, name, num, gen, key) { - if (!(name instanceof _primitives.Name)) { - throw new _util.FormatError("Invalid crypt filter name."); + addTopLevelNode(dict, element) { + const obj = this.rootDict.get("K"); + + if (!obj) { + return false; }
- const cryptFilter = cf.get(name.name); - let cfm; + if (obj instanceof _primitives.Dict) { + if (obj.objId !== dict.objId) { + return false; + }
- if (cryptFilter !== null && cryptFilter !== undefined) { - cfm = cryptFilter.get("CFM"); + this.nodes[0] = element; + return true; }
- if (!cfm || cfm.name === "None") { - return function cipherTransformFactoryBuildCipherConstructorNone() { - return new NullCipher(); - }; + if (!Array.isArray(obj)) { + return true; }
- if (cfm.name === "V2") { - return function cipherTransformFactoryBuildCipherConstructorV2() { - return new ARCFourCipher(buildObjectKey(num, gen, key, false)); - }; - } + let save = false;
- if (cfm.name === "AESV2") { - return function cipherTransformFactoryBuildCipherConstructorAESV2() { - return new AES128Cipher(buildObjectKey(num, gen, key, true)); - }; - } + for (let i = 0; i < obj.length; i++) { + const kidRef = obj[i];
- if (cfm.name === "AESV3") { - return function cipherTransformFactoryBuildCipherConstructorAESV3() { - return new AES256Cipher(key); - }; + if (kidRef && kidRef.toString() === dict.objId) { + this.nodes[i] = element; + save = true; + } }
- throw new _util.FormatError("Unknown crypto method"); + return save; }
- class CipherTransformFactory { - constructor(dict, fileId, password) { - const filter = dict.get("Filter"); - - if (!(0, _primitives.isName)(filter, "Standard")) { - throw new _util.FormatError("unknown encryption method"); + get serializable() { + function nodeToSerializable(node, parent, level = 0) { + if (level > MAX_DEPTH) { + (0, _util.warn)("StructTree too deep to be fully serialized."); + return; }
- this.filterName = filter.name; - this.dict = dict; - const algorithm = dict.get("V"); + const obj = Object.create(null); + obj.role = node.role; + obj.children = []; + parent.children.push(obj); + const alt = node.dict.get("Alt");
- if (!Number.isInteger(algorithm) || algorithm !== 1 && algorithm !== 2 && algorithm !== 4 && algorithm !== 5) { - throw new _util.FormatError("unsupported encryption algorithm"); + if (typeof alt === "string") { + obj.alt = (0, _util.stringToPDFString)(alt); }
- this.algorithm = algorithm; - let keyLength = dict.get("Length"); + const lang = node.dict.get("Lang");
- if (!keyLength) { - if (algorithm <= 3) { - keyLength = 40; - } else { - const cfDict = dict.get("CF"); - const streamCryptoName = dict.get("StmF"); + if (typeof lang === "string") { + obj.lang = (0, _util.stringToPDFString)(lang); + }
- if (cfDict instanceof _primitives.Dict && streamCryptoName instanceof _primitives.Name) { - cfDict.suppressEncryption = true; - const handlerDict = cfDict.get(streamCryptoName.name); - keyLength = handlerDict && handlerDict.get("Length") || 128; + for (const kid of node.kids) { + const kidElement = kid.type === StructElementType.ELEMENT ? kid.parentNode : null;
- if (keyLength < 40) { - keyLength <<= 3; - } - } + if (kidElement) { + nodeToSerializable(kidElement, obj, level + 1); + continue; + } else if (kid.type === StructElementType.PAGE_CONTENT || kid.type === StructElementType.STREAM_CONTENT) { + obj.children.push({ + type: "content", + id: `page${kid.pageObjId}_mcid${kid.mcid}` + }); + } else if (kid.type === StructElementType.OBJECT) { + obj.children.push({ + type: "object", + id: kid.refObjId + }); } } + }
- if (!Number.isInteger(keyLength) || keyLength < 40 || keyLength % 8 !== 0) { - throw new _util.FormatError("invalid key length"); + const root = Object.create(null); + root.children = []; + root.role = "Root"; + + for (const child of this.nodes) { + if (!child) { + continue; }
- const ownerPassword = (0, _util.stringToBytes)(dict.get("O")).subarray(0, 32); - const userPassword = (0, _util.stringToBytes)(dict.get("U")).subarray(0, 32); - const flags = dict.get("P"); - const revision = dict.get("R"); - const encryptMetadata = (algorithm === 4 || algorithm === 5) && dict.get("EncryptMetadata") !== false; - this.encryptMetadata = encryptMetadata; - const fileIdBytes = (0, _util.stringToBytes)(fileId); - let passwordBytes; + nodeToSerializable(child, root); + }
- if (password) { - if (revision === 6) { - try { - password = (0, _util.utf8StringToString)(password); - } catch (ex) { - (0, _util.warn)("CipherTransformFactory: " + "Unable to convert UTF8 encoded password."); - } - } + return root; + }
- passwordBytes = (0, _util.stringToBytes)(password); - } +}
- let encryptionKey; +exports.StructTreePage = StructTreePage;
- if (algorithm !== 5) { - encryptionKey = prepareKeyData(fileIdBytes, passwordBytes, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata); - } else { - const ownerValidationSalt = (0, _util.stringToBytes)(dict.get("O")).subarray(32, 40); - const ownerKeySalt = (0, _util.stringToBytes)(dict.get("O")).subarray(40, 48); - const uBytes = (0, _util.stringToBytes)(dict.get("U")).subarray(0, 48); - const userValidationSalt = (0, _util.stringToBytes)(dict.get("U")).subarray(32, 40); - const userKeySalt = (0, _util.stringToBytes)(dict.get("U")).subarray(40, 48); - const ownerEncryption = (0, _util.stringToBytes)(dict.get("OE")); - const userEncryption = (0, _util.stringToBytes)(dict.get("UE")); - const perms = (0, _util.stringToBytes)(dict.get("Perms")); - encryptionKey = createEncryptionKey20(revision, passwordBytes, ownerPassword, ownerValidationSalt, ownerKeySalt, uBytes, userPassword, userValidationSalt, userKeySalt, ownerEncryption, userEncryption, perms); - } +/***/ }), +/* 75 */ +/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
- if (!encryptionKey && !password) { - throw new _util.PasswordException("No password given", _util.PasswordResponses.NEED_PASSWORD); - } else if (!encryptionKey && password) { - const decodedPassword = decodeUserPassword(passwordBytes, ownerPassword, revision, keyLength); - encryptionKey = prepareKeyData(fileIdBytes, decodedPassword, ownerPassword, userPassword, flags, revision, keyLength, encryptMetadata); - }
- if (!encryptionKey) { - throw new _util.PasswordException("Incorrect Password", _util.PasswordResponses.INCORRECT_PASSWORD); - }
- this.encryptionKey = encryptionKey; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.ObjectLoader = void 0;
- if (algorithm >= 4) { - const cf = dict.get("CF"); +var _primitives = __w_pdfjs_require__(5);
- if (cf instanceof _primitives.Dict) { - cf.suppressEncryption = true; - } +var _base_stream = __w_pdfjs_require__(7);
- this.cf = cf; - this.stmf = dict.get("StmF") || identityName; - this.strf = dict.get("StrF") || identityName; - this.eff = dict.get("EFF") || this.stmf; - } +var _core_utils = __w_pdfjs_require__(6); + +var _util = __w_pdfjs_require__(2); + +function mayHaveChildren(value) { + return value instanceof _primitives.Ref || value instanceof _primitives.Dict || value instanceof _base_stream.BaseStream || Array.isArray(value); +} + +function addChildren(node, nodesToVisit) { + if (node instanceof _primitives.Dict) { + node = node.getRawValues(); + } else if (node instanceof _base_stream.BaseStream) { + node = node.dict.getRawValues(); + } else if (!Array.isArray(node)) { + return; + } + + for (const rawValue of node) { + if (mayHaveChildren(rawValue)) { + nodesToVisit.push(rawValue); } + } +}
- createCipherTransform(num, gen) { - if (this.algorithm === 4 || this.algorithm === 5) { - return new CipherTransform(buildCipherConstructor(this.cf, this.stmf, num, gen, this.encryptionKey), buildCipherConstructor(this.cf, this.strf, num, gen, this.encryptionKey)); - } +class ObjectLoader { + constructor(dict, keys, xref) { + this.dict = dict; + this.keys = keys; + this.xref = xref; + this.refSet = null; + }
- const key = buildObjectKey(num, gen, this.encryptionKey, false); + async load() { + if (this.xref.stream.isDataLoaded) { + return undefined; + }
- const cipherConstructor = function buildCipherCipherConstructor() { - return new ARCFourCipher(key); - }; + const { + keys, + dict + } = this; + this.refSet = new _primitives.RefSet(); + const nodesToVisit = [];
- return new CipherTransform(cipherConstructor, cipherConstructor); + for (let i = 0, ii = keys.length; i < ii; i++) { + const rawValue = dict.getRaw(keys[i]); + + if (rawValue !== undefined) { + nodesToVisit.push(rawValue); + } }
+ return this._walk(nodesToVisit); }
- return CipherTransformFactory; -}(); + async _walk(nodesToVisit) { + const nodesToRevisit = []; + const pendingRequests = [];
-exports.CipherTransformFactory = CipherTransformFactory; + while (nodesToVisit.length) { + let currentNode = nodesToVisit.pop();
-/***/ }), -/* 75 */ -/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => { + if (currentNode instanceof _primitives.Ref) { + if (this.refSet.has(currentNode)) { + continue; + }
+ try { + this.refSet.put(currentNode); + currentNode = this.xref.fetch(currentNode); + } catch (ex) { + if (!(ex instanceof _core_utils.MissingDataException)) { + (0, _util.warn)(`ObjectLoader._walk - requesting all data: "${ex}".`); + this.refSet = null; + const { + manager + } = this.xref.stream; + return manager.requestAllChunks(); + }
+ nodesToRevisit.push(currentNode); + pendingRequests.push({ + begin: ex.begin, + end: ex.end + }); + } + }
-Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.DecryptStream = void 0; + if (currentNode instanceof _base_stream.BaseStream) { + const baseStreams = currentNode.getBaseStreams();
-var _decode_stream = __w_pdfjs_require__(29); + if (baseStreams) { + let foundMissingData = false;
-const chunkSize = 512; + for (const stream of baseStreams) { + if (stream.isDataLoaded) { + continue; + }
-class DecryptStream extends _decode_stream.DecodeStream { - constructor(str, maybeLength, decrypt) { - super(maybeLength); - this.str = str; - this.dict = str.dict; - this.decrypt = decrypt; - this.nextChunk = null; - this.initialized = false; - } + foundMissingData = true; + pendingRequests.push({ + begin: stream.start, + end: stream.end + }); + }
- readBlock() { - let chunk; + if (foundMissingData) { + nodesToRevisit.push(currentNode); + } + } + }
- if (this.initialized) { - chunk = this.nextChunk; - } else { - chunk = this.str.getBytes(chunkSize); - this.initialized = true; + addChildren(currentNode, nodesToVisit); }
- if (!chunk || chunk.length === 0) { - this.eof = true; - return; - } + if (pendingRequests.length) { + await this.xref.stream.manager.requestRanges(pendingRequests);
- this.nextChunk = this.str.getBytes(chunkSize); - const hasMoreData = this.nextChunk && this.nextChunk.length > 0; - const decrypt = this.decrypt; - chunk = decrypt(chunk, !hasMoreData); - let bufferLength = this.bufferLength; - const n = chunk.length, - buffer = this.ensureBuffer(bufferLength + n); + for (const node of nodesToRevisit) { + if (node instanceof _primitives.Ref) { + this.refSet.remove(node); + } + }
- for (let i = 0; i < n; i++) { - buffer[bufferLength++] = chunk[i]; + return this._walk(nodesToRevisit); }
- this.bufferLength = bufferLength; + this.refSet = null; + return undefined; }
}
-exports.DecryptStream = DecryptStream; +exports.ObjectLoader = ObjectLoader;
/***/ }), /* 76 */ @@ -47114,7 +47910,7 @@ var _utils = __w_pdfjs_require__(78);
var _util = __w_pdfjs_require__(2);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _namespaces = __w_pdfjs_require__(79);
@@ -48715,7 +49511,7 @@ function parseExpression(expr, dotDotAllowed, noExpr = true) { return null; }
- parsed[parsed.length - 1].index = parseIndex(match[0]); + parsed.at(-1).index = parseIndex(match[0]); pos += match[0].length + 1; continue; } @@ -48880,7 +49676,7 @@ function searchNode(root, container, expr, dotDotAllowed = true, useCache = true if (isFinite(index)) { root = nodes.filter(node => index < node.length).map(node => node[index]); } else { - root = nodes.reduce((acc, node) => acc.concat(node), []); + root = nodes.flat(); } }
@@ -49616,7 +50412,7 @@ var _util = __w_pdfjs_require__(2);
var _fonts = __w_pdfjs_require__(85);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _som = __w_pdfjs_require__(80);
@@ -49679,6 +50475,10 @@ function* getContainedChildren(node) { } }
+function isRequired(node) { + return node.validate && node.validate.nullTest === "error"; +} + function setTabIndex(node) { while (node) { if (!node.traversal) { @@ -49946,7 +50746,7 @@ class Arc extends _xfa_object.XFAObject { }
[_xfa_object.$toHTML]() { - const edge = this.edge ? this.edge : new Edge({}); + const edge = this.edge || new Edge({});
const edgeStyle = edge[_xfa_object.$toStyle]();
@@ -50279,7 +51079,7 @@ class Border extends _xfa_object.XFAObject { const edges = this.edge.children.slice();
if (edges.length < 4) { - const defaultEdge = edges[edges.length - 1] || new Edge({}); + const defaultEdge = edges.at(-1) || new Edge({});
for (let i = edges.length; i < 4; i++) { edges.push(defaultEdge); @@ -50331,7 +51131,7 @@ class Border extends _xfa_object.XFAObject { const cornerStyles = this.corner.children.map(node => node[_xfa_object.$toStyle]());
if (cornerStyles.length === 2 || cornerStyles.length === 3) { - const last = cornerStyles[cornerStyles.length - 1]; + const last = cornerStyles.at(-1);
for (let i = cornerStyles.length; i < 4; i++) { cornerStyles.push(last); @@ -50730,7 +51530,8 @@ class CheckButton extends _xfa_object.XFAObject { checked, xfaOn: exportedValue.on, xfaOff: exportedValue.off, - "aria-label": ariaLabel(field) + "aria-label": ariaLabel(field), + "aria-required": false } };
@@ -50738,6 +51539,11 @@ class CheckButton extends _xfa_object.XFAObject { input.attributes.name = groupId; }
+ if (isRequired(field)) { + input.attributes["aria-required"] = true; + input.attributes.required = true; + } + return _utils.HTMLResult.success({ name: "label", attributes: { @@ -50776,7 +51582,7 @@ class ChoiceList extends _xfa_object.XFAObject {
const fontSize = field.font && field.font.size || 10; const optionStyle = { - fontSize: `calc(${fontSize}px * var(--zoom-factor))` + fontSize: `calc(${fontSize}px * var(--scale-factor))` }; const children = [];
@@ -50831,9 +51637,15 @@ class ChoiceList extends _xfa_object.XFAObject { fieldId: field[_xfa_object.$uid], dataId: field[_xfa_object.$data] && field[_xfa_object.$data][_xfa_object.$uid] || field[_xfa_object.$uid], style, - "aria-label": ariaLabel(field) + "aria-label": ariaLabel(field), + "aria-required": false };
+ if (isRequired(field)) { + selectAttributes["aria-required"] = true; + selectAttributes.required = true; + } + if (this.open === "multiSelect") { selectAttributes.multiple = true; } @@ -51044,9 +51856,16 @@ class DateTimeEdit extends _xfa_object.XFAObject { dataId: field[_xfa_object.$data] && field[_xfa_object.$data][_xfa_object.$uid] || field[_xfa_object.$uid], class: ["xfaTextfield"], style, - "aria-label": ariaLabel(field) + "aria-label": ariaLabel(field), + "aria-required": false } }; + + if (isRequired(field)) { + html.attributes["aria-required"] = true; + html.attributes.required = true; + } + return _utils.HTMLResult.success({ name: "label", attributes: { @@ -52754,7 +53573,7 @@ class Line extends _xfa_object.XFAObject { [_xfa_object.$toHTML]() { const parent = this[_xfa_object.$getParent]()[_xfa_object.$getParent]();
- const edge = this.edge ? this.edge : new Edge({}); + const edge = this.edge || new Edge({});
const edgeStyle = edge[_xfa_object.$toStyle]();
@@ -52964,9 +53783,16 @@ class NumericEdit extends _xfa_object.XFAObject { dataId: field[_xfa_object.$data] && field[_xfa_object.$data][_xfa_object.$uid] || field[_xfa_object.$uid], class: ["xfaTextfield"], style, - "aria-label": ariaLabel(field) + "aria-label": ariaLabel(field), + "aria-required": false } }; + + if (isRequired(field)) { + html.attributes["aria-required"] = true; + html.attributes.required = true; + } + return _utils.HTMLResult.success({ name: "label", attributes: { @@ -54548,7 +55374,7 @@ class Template extends _xfa_object.XFAObject { if (target instanceof PageArea) { targetPageArea = target; } else if (target instanceof ContentArea) { - const index = contentAreas.findIndex(e => e === target); + const index = contentAreas.indexOf(target);
if (index !== -1) { if (index > currentIndex) { @@ -54558,7 +55384,7 @@ class Template extends _xfa_object.XFAObject { } } else { targetPageArea = target[_xfa_object.$getParent](); - startIndex = targetPageArea.contentArea.children.findIndex(e => e === target); + startIndex = targetPageArea.contentArea.children.indexOf(target); } }
@@ -54732,7 +55558,8 @@ class TextEdit extends _xfa_object.XFAObject { fieldId: field[_xfa_object.$uid], class: ["xfaTextfield"], style, - "aria-label": ariaLabel(field) + "aria-label": ariaLabel(field), + "aria-required": false } }; } else { @@ -54744,11 +55571,17 @@ class TextEdit extends _xfa_object.XFAObject { fieldId: field[_xfa_object.$uid], class: ["xfaTextfield"], style, - "aria-label": ariaLabel(field) + "aria-label": ariaLabel(field), + "aria-required": false } }; }
+ if (isRequired(field)) { + html.attributes["aria-required"] = true; + html.attributes.required = true; + } + return _utils.HTMLResult.success({ name: "label", attributes: { @@ -56143,7 +56976,7 @@ function layoutNode(node, availableSpace) { } }
- const maxWidth = (!node.w ? availableSpace.width : node.w) - marginH; + const maxWidth = (node.w || availableSpace.width) - marginH; const fontFinder = node[_xfa_object.$globalData].fontFinder;
if (node.value.exData && node.value.exData[_xfa_object.$content] && node.value.exData.contentType === "text/html") { @@ -56457,7 +57290,7 @@ function isPrintOnly(node) { function getCurrentPara(node) { const stack = node[_xfa_object.$getTemplateRoot]()[_xfa_object.$extra].paraStack;
- return stack.length ? stack[stack.length - 1] : null; + return stack.length ? stack.at(-1) : null; }
function setPara(node, nodeStyle, value) { @@ -56844,7 +57677,7 @@ class FontSelector { }
pushData(xfaFont, margin, lineHeight) { - const lastFont = this.stack[this.stack.length - 1]; + const lastFont = this.stack.at(-1);
for (const name of ["typeface", "posture", "weight", "size", "letterSpacing"]) { if (!xfaFont[name]) { @@ -56872,7 +57705,7 @@ class FontSelector { }
topFont() { - return this.stack[this.stack.length - 1]; + return this.stack.at(-1); }
} @@ -57049,7 +57882,7 @@ class DataHandler { const stack = [[-1, this.data[_xfa_object.$getChildren]()]];
while (stack.length > 0) { - const last = stack[stack.length - 1]; + const last = stack.at(-1); const [i, children] = last;
if (i + 1 === children.length) { @@ -57116,7 +57949,7 @@ exports.XFAParser = void 0;
var _xfa_object = __w_pdfjs_require__(77);
-var _xml_parser = __w_pdfjs_require__(70); +var _xml_parser = __w_pdfjs_require__(66);
var _builder = __w_pdfjs_require__(89);
@@ -57494,7 +58327,7 @@ class Builder { const prefixStack = this._namespacePrefixes.get(prefix);
if (prefixStack && prefixStack.length > 0) { - return prefixStack[prefixStack.length - 1]; + return prefixStack.at(-1); }
(0, _util.warn)(`Unknown namespace prefix: ${prefix}.`); @@ -60300,6 +61133,10 @@ function mapStyle(styleStr, node, richText) { style.verticalAlign = (0, _html_utils.measureToString)(Math.sign((0, _utils.getMeasurement)(style.verticalAlign)) * fontSize * VERTICAL_FACTOR); }
+ if (richText && style.fontSize) { + style.fontSize = `calc(${style.fontSize} * var(--scale-factor))`; + } + (0, _html_utils.fixTextIndent)(style); return style; } @@ -60649,7 +61486,7 @@ class P extends XhtmlObject { [_xfa_object.$text]() { const siblings = this[_xfa_object.$getParent]()[_xfa_object.$getChildren]();
- if (siblings[siblings.length - 1] === this) { + if (siblings.at(-1) === this) { return super[_xfa_object.$text](); }
@@ -60792,9 +61629,9 @@ exports.DatasetReader = void 0;
var _util = __w_pdfjs_require__(2);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
-var _xml_parser = __w_pdfjs_require__(70); +var _xml_parser = __w_pdfjs_require__(66);
function decodeString(str) { try { @@ -60880,13 +61717,13 @@ var _util = __w_pdfjs_require__(2);
var _primitives = __w_pdfjs_require__(5);
-var _core_utils = __w_pdfjs_require__(8); +var _core_utils = __w_pdfjs_require__(6);
var _parser = __w_pdfjs_require__(27);
-var _base_stream = __w_pdfjs_require__(9); +var _base_stream = __w_pdfjs_require__(7);
-var _crypto = __w_pdfjs_require__(74); +var _crypto = __w_pdfjs_require__(67);
class XRef { constructor(stream, pdfManager) { @@ -60902,7 +61739,7 @@ class XRef {
getNewRef() { if (this._newRefNum === null) { - this._newRefNum = this.entries.length; + this._newRefNum = this.entries.length || 1; }
return _primitives.Ref.get(this._newRefNum++, 0); @@ -62433,8 +63270,8 @@ Object.defineProperty(exports, "WorkerMessageHandler", ({
var _worker = __w_pdfjs_require__(1);
-const pdfjsVersion = '2.14.290'; -const pdfjsBuild = '38c82357b'; +const pdfjsVersion = '2.15.305'; +const pdfjsBuild = '2a386eff9'; })();
/******/ return __webpack_exports__; diff --git a/toolkit/components/pdfjs/content/web/debugger.js b/toolkit/components/pdfjs/content/web/debugger.js index 1d5571007306f..210e388ad07d2 100644 --- a/toolkit/components/pdfjs/content/web/debugger.js +++ b/toolkit/components/pdfjs/content/web/debugger.js @@ -68,10 +68,10 @@ const FontInspector = (function FontInspectorClosure() { const tmp = document.createElement("button"); tmp.addEventListener("click", resetSelection); tmp.textContent = "Refresh"; - panel.appendChild(tmp); + panel.append(tmp);
fonts = document.createElement("div"); - panel.appendChild(fonts); + panel.append(fonts); }, cleanup() { fonts.textContent = ""; @@ -98,11 +98,11 @@ const FontInspector = (function FontInspectorClosure() { const tr = document.createElement("tr"); const td1 = document.createElement("td"); td1.textContent = entry; - tr.appendChild(td1); + tr.append(td1); const td2 = document.createElement("td"); td2.textContent = obj[entry].toString(); - tr.appendChild(td2); - moreInfo.appendChild(tr); + tr.append(td2); + moreInfo.append(tr); } return moreInfo; } @@ -117,7 +117,7 @@ const FontInspector = (function FontInspectorClosure() { download.href = url[1]; } else if (fontObj.data) { download.href = URL.createObjectURL( - new Blob([fontObj.data], { type: fontObj.mimeType }) + new Blob([fontObj.data], { type: fontObj.mimetype }) ); } download.textContent = "Download"; @@ -134,14 +134,8 @@ const FontInspector = (function FontInspectorClosure() { select.addEventListener("click", function () { selectFont(fontName, select.checked); }); - font.appendChild(select); - font.appendChild(name); - font.appendChild(document.createTextNode(" ")); - font.appendChild(download); - font.appendChild(document.createTextNode(" ")); - font.appendChild(logIt); - font.appendChild(moreInfo); - fonts.appendChild(font); + font.append(select, name, " ", download, " ", logIt, moreInfo); + fonts.append(font); // Somewhat of a hack, should probably add a hook for when the text layer // is done rendering. setTimeout(() => { @@ -173,10 +167,9 @@ const StepperManager = (function StepperManagerClosure() { stepperChooser.addEventListener("change", function (event) { self.selectStepper(this.value); }); - stepperControls.appendChild(stepperChooser); + stepperControls.append(stepperChooser); stepperDiv = document.createElement("div"); - this.panel.appendChild(stepperControls); - this.panel.appendChild(stepperDiv); + this.panel.append(stepperControls, stepperDiv); if (sessionStorage.getItem("pdfjsBreakPoints")) { breakPoints = JSON.parse(sessionStorage.getItem("pdfjsBreakPoints")); } @@ -199,11 +192,11 @@ const StepperManager = (function StepperManagerClosure() { debug.id = "stepper" + pageIndex; debug.hidden = true; debug.className = "stepper"; - stepperDiv.appendChild(debug); + stepperDiv.append(debug); const b = document.createElement("option"); b.textContent = "Page " + (pageIndex + 1); b.value = pageIndex; - stepperChooser.appendChild(b); + stepperChooser.append(b); const initBreakPoints = breakPoints[pageIndex] || []; const stepper = new Stepper(debug, pageIndex, initBreakPoints); steppers.push(stepper); @@ -289,15 +282,17 @@ const Stepper = (function StepperClosure() { const panel = this.panel; const content = c("div", "c=continue, s=step"); const table = c("table"); - content.appendChild(table); + content.append(table); table.cellSpacing = 0; const headerRow = c("tr"); - table.appendChild(headerRow); - headerRow.appendChild(c("th", "Break")); - headerRow.appendChild(c("th", "Idx")); - headerRow.appendChild(c("th", "fn")); - headerRow.appendChild(c("th", "args")); - panel.appendChild(content); + table.append(headerRow); + headerRow.append( + c("th", "Break"), + c("th", "Idx"), + c("th", "fn"), + c("th", "args") + ); + panel.append(content); this.table = table; this.updateOperatorList(operatorList); } @@ -329,7 +324,7 @@ const Stepper = (function StepperClosure() { const line = c("tr"); line.className = "line"; line.dataset.idx = i; - chunk.appendChild(line); + chunk.append(line); const checked = this.breakPoints.includes(i); const args = operatorList.argsArray[i] || [];
@@ -341,9 +336,8 @@ const Stepper = (function StepperClosure() { cbox.dataset.idx = i; cbox.onclick = cboxOnClick;
- breakCell.appendChild(cbox); - line.appendChild(breakCell); - line.appendChild(c("td", i.toString())); + breakCell.append(cbox); + line.append(breakCell, c("td", i.toString())); const fn = opMap[operatorList.fnArray[i]]; let decArgs = args; if (fn === "showText") { @@ -353,46 +347,44 @@ const Stepper = (function StepperClosure() { const unicodeRow = c("tr"); for (const glyph of glyphs) { if (typeof glyph === "object" && glyph !== null) { - charCodeRow.appendChild(c("td", glyph.originalCharCode)); - fontCharRow.appendChild(c("td", glyph.fontChar)); - unicodeRow.appendChild(c("td", glyph.unicode)); + charCodeRow.append(c("td", glyph.originalCharCode)); + fontCharRow.append(c("td", glyph.fontChar)); + unicodeRow.append(c("td", glyph.unicode)); } else { // null or number const advanceEl = c("td", glyph); advanceEl.classList.add("advance"); - charCodeRow.appendChild(advanceEl); - fontCharRow.appendChild(c("td")); - unicodeRow.appendChild(c("td")); + charCodeRow.append(advanceEl); + fontCharRow.append(c("td")); + unicodeRow.append(c("td")); } } decArgs = c("td"); const table = c("table"); table.classList.add("showText"); - decArgs.appendChild(table); - table.appendChild(charCodeRow); - table.appendChild(fontCharRow); - table.appendChild(unicodeRow); + decArgs.append(table); + table.append(charCodeRow, fontCharRow, unicodeRow); } else if (fn === "restore") { this.indentLevel--; } - line.appendChild(c("td", " ".repeat(this.indentLevel * 2) + fn)); + line.append(c("td", " ".repeat(this.indentLevel * 2) + fn)); if (fn === "save") { this.indentLevel++; }
if (decArgs instanceof HTMLElement) { - line.appendChild(decArgs); + line.append(decArgs); } else { - line.appendChild(c("td", JSON.stringify(simplifyArgs(decArgs)))); + line.append(c("td", JSON.stringify(simplifyArgs(decArgs)))); } } if (operatorsToDisplay < operatorList.fnArray.length) { const lastCell = c("td", "..."); lastCell.colspan = 4; - chunk.appendChild(lastCell); + chunk.append(lastCell); } this.operatorListIdx = operatorList.fnArray.length; - this.table.appendChild(chunk); + this.table.append(chunk); }
getNextBreakPoint() { @@ -485,15 +477,14 @@ const Stats = (function Stats() { title.textContent = "Page: " + pageNumber; const statsDiv = document.createElement("div"); statsDiv.textContent = stat.toString(); - wrapper.appendChild(title); - wrapper.appendChild(statsDiv); + wrapper.append(title, statsDiv); stats.push({ pageNumber, div: wrapper }); stats.sort(function (a, b) { return a.pageNumber - b.pageNumber; }); clear(this.panel); for (const entry of stats) { - this.panel.appendChild(entry.div); + this.panel.append(entry.div); } }, cleanup() { @@ -547,13 +538,13 @@ const PDFBug = (function PDFBugClosure() {
const controls = document.createElement("div"); controls.setAttribute("class", "controls"); - ui.appendChild(controls); + ui.append(controls);
const panels = document.createElement("div"); panels.setAttribute("class", "panels"); - ui.appendChild(panels); + ui.append(panels);
- container.appendChild(ui); + container.append(ui); container.style.right = panelWidth + "px";
// Initialize all the debugging tools. @@ -565,8 +556,8 @@ const PDFBug = (function PDFBugClosure() { event.preventDefault(); this.selectPanel(tool); }); - controls.appendChild(panelButton); - panels.appendChild(panel); + controls.append(panelButton); + panels.append(panel); tool.panel = panel; tool.manager = this; if (tool.enabled) { @@ -587,7 +578,7 @@ const PDFBug = (function PDFBugClosure() { link.rel = "stylesheet"; link.href = url.replace(/.js$/, ".css");
- document.head.appendChild(link); + document.head.append(link); }, cleanup() { for (const tool of this.tools) { diff --git a/toolkit/components/pdfjs/content/web/images/toolbarButton-editorFreeText.svg b/toolkit/components/pdfjs/content/web/images/toolbarButton-editorFreeText.svg new file mode 100644 index 0000000000000..7f4f20458ddb0 --- /dev/null +++ b/toolkit/components/pdfjs/content/web/images/toolbarButton-editorFreeText.svg @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!-- copied from https://www.svgrepo.com/svg/255881/text --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve"> +<g> + <g transform="scale(0.03125)"> + <path d="M405.787,43.574H8.17c-4.513,0-8.17,3.658-8.17,8.17v119.83c0,4.512,3.657,8.17,8.17,8.17h32.681 + c4.513,0,8.17-3.658,8.17-8.17v-24.511h95.319v119.83c0,4.512,3.657,8.17,8.17,8.17c4.513,0,8.17-3.658,8.17-8.17v-128 + c0-4.512-3.657-8.17-8.17-8.17H40.851c-4.513,0-8.17,3.658-8.17,8.17v24.511H16.34V59.915h381.277v103.489h-16.34v-24.511 + c0-4.512-3.657-8.17-8.17-8.17h-111.66c-4.513,0-8.17,3.658-8.17,8.17v288.681c0,4.512,3.657,8.17,8.17,8.17h57.191v16.34H95.319 + v-16.34h57.191c4.513,0,8.17-3.658,8.17-8.17v-128c0-4.512-3.657-8.17-8.17-8.17c-4.513,0-8.17,3.658-8.17,8.17v119.83H87.149 + c-4.513,0-8.17,3.658-8.17,8.17v32.681c0,4.512,3.657,8.17,8.17,8.17h239.66c4.513,0,8.17-3.658,8.17-8.17v-32.681 + c0-4.512-3.657-8.17-8.17-8.17h-57.192v-272.34h95.319v24.511c0,4.512,3.657,8.17,8.17,8.17h32.681c4.513,0,8.17-3.658,8.17-8.17 + V51.745C413.957,47.233,410.3,43.574,405.787,43.574z"/> + </g> +</g> +<g> + <g transform="scale(0.03125)"> + <path d="M503.83,452.085h-24.511V59.915h24.511c4.513,0,8.17-3.658,8.17-8.17s-3.657-8.17-8.17-8.17h-65.362 + c-4.513,0-8.17,3.658-8.17,8.17s3.657,8.17,8.17,8.17h24.511v392.17h-24.511c-4.513,0-8.17,3.658-8.17,8.17s3.657,8.17,8.17,8.17 + h65.362c4.513,0,8.17-3.658,8.17-8.17S508.343,452.085,503.83,452.085z"/> + </g> +</g> +</svg> diff --git a/toolkit/components/pdfjs/content/web/images/toolbarButton-editorInk.svg b/toolkit/components/pdfjs/content/web/images/toolbarButton-editorInk.svg new file mode 100644 index 0000000000000..e51484dd2c84a --- /dev/null +++ b/toolkit/components/pdfjs/content/web/images/toolbarButton-editorInk.svg @@ -0,0 +1,9 @@ +<?xml version='1.0' encoding='utf-8'?> +<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 16 16"> + <g> + <g transform="scale(0.03125)"> + <path d="m455.1,137.9l-32.4,32.4-81-81.1 32.4-32.4c6.6-6.6 18.1-6.6 24.7,0l56.3,56.4c6.8,6.8 6.8,17.9 0,24.7zm-270.7,271l-81-81.1 209.4-209.7 81,81.1-209.4,209.7zm-99.7-42l60.6,60.7-84.4,23.8 23.8-84.5zm399.3-282.6l-56.3-56.4c-11-11-50.7-31.8-82.4,0l-285.3,285.5c-2.5,2.5-4.3,5.5-5.2,8.9l-43,153.1c-2,7.1 0.1,14.7 5.2,20 5.2,5.3 15.6,6.2 20,5.2l153-43.1c3.4-0.9 6.4-2.7 8.9-5.2l285.1-285.5c22.7-22.7 22.7-59.7 0-82.5z"/> + </g> + </g> +</svg> diff --git a/toolkit/components/pdfjs/content/web/images/toolbarButton-editorNone.svg b/toolkit/components/pdfjs/content/web/images/toolbarButton-editorNone.svg new file mode 100644 index 0000000000000..4d1e7f29c64fe --- /dev/null +++ b/toolkit/components/pdfjs/content/web/images/toolbarButton-editorNone.svg @@ -0,0 +1,4 @@ +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M12.407 8.217l-8.083-6.7A.2.2 0 0 0 4 1.672V12.3a.2.2 0 0 0 .333.146l2.56-2.372 1.857 3.9A1.125 1.125 0 1 0 10.782 13L8.913 9.075l3.4-.51a.2.2 0 0 0 .095-.348z"></path></svg> \ No newline at end of file diff --git a/toolkit/components/pdfjs/content/web/viewer.css b/toolkit/components/pdfjs/content/web/viewer.css index 09a5705989fb7..298199fab0156 100644 --- a/toolkit/components/pdfjs/content/web/viewer.css +++ b/toolkit/components/pdfjs/content/web/viewer.css @@ -100,9 +100,30 @@ --annotation-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,<svg width='1px' height='1px' xmlns='http://www.w3.org/2000/svg'><rect width='100%' height='100%' style='fill:rgba(0, 54, 255, 0.13);'/></svg>"); }
+@media (forced-colors: active) { + .annotationLayer .textWidgetAnnotation input:required, + .annotationLayer .textWidgetAnnotation textarea:required, + .annotationLayer .choiceWidgetAnnotation select:required, + .annotationLayer .buttonWidgetAnnotation.checkBox input:required, + .annotationLayer .buttonWidgetAnnotation.radioButton input:required { + outline: 1.5px solid selectedItem; + } +} + +.annotationLayer { + position: absolute; + top: 0; + left: 0; + pointer-events: none; + transform-origin: 0 0; +} + .annotationLayer section { position: absolute; text-align: initial; + pointer-events: auto; + box-sizing: border-box; + transform-origin: 0 0; }
.annotationLayer .linkAnnotation > a, @@ -116,10 +137,8 @@ }
.annotationLayer .buttonWidgetAnnotation.pushButton > canvas { - position: relative; - top: 0; - left: 0; - z-index: -1; + width: 100%; + height: 100%; }
.annotationLayer .linkAnnotation > a:hover, @@ -132,6 +151,8 @@ .annotationLayer .textAnnotation img { position: absolute; cursor: pointer; + width: 100%; + height: 100%; }
.annotationLayer .textWidgetAnnotation input, @@ -142,14 +163,21 @@ background-image: var(--annotation-unfocused-field-background); border: 1px solid transparent; box-sizing: border-box; - font-size: 9px; + font: calc(9px * var(--scale-factor)) sans-serif; height: 100%; margin: 0; - padding: 0 3px; vertical-align: top; width: 100%; }
+.annotationLayer .textWidgetAnnotation input:required, +.annotationLayer .textWidgetAnnotation textarea:required, +.annotationLayer .choiceWidgetAnnotation select:required, +.annotationLayer .buttonWidgetAnnotation.checkBox input:required, +.annotationLayer .buttonWidgetAnnotation.radioButton input:required { + outline: 1.5px solid red; +} + .annotationLayer .choiceWidgetAnnotation select option { padding: 0; } @@ -159,8 +187,6 @@ }
.annotationLayer .textWidgetAnnotation textarea { - font: message-box; - font-size: 9px; resize: none; }
@@ -202,7 +228,7 @@ .annotationLayer .buttonWidgetAnnotation.checkBox input:checked:before, .annotationLayer .buttonWidgetAnnotation.checkBox input:checked:after, .annotationLayer .buttonWidgetAnnotation.radioButton input:checked:before { - background-color: rgba(0, 0, 0, 1); + background-color: CanvasText; content: ""; display: block; position: absolute; @@ -250,32 +276,40 @@ .annotationLayer .buttonWidgetAnnotation.checkBox input, .annotationLayer .buttonWidgetAnnotation.radioButton input { appearance: none; - padding: 0; +} + +.annotationLayer .popupTriggerArea { + height: 100%; + width: 100%; }
.annotationLayer .popupWrapper { position: absolute; - width: 20em; + font-size: calc(9px * var(--scale-factor)); + width: 100%; + min-width: calc(180px * var(--scale-factor)); + pointer-events: none; }
.annotationLayer .popup { position: absolute; z-index: 200; - max-width: 20em; + max-width: calc(180px * var(--scale-factor)); background-color: rgba(255, 255, 153, 1); - box-shadow: 0 2px 5px rgba(136, 136, 136, 1); - border-radius: 2px; - padding: 6px; - margin-left: 5px; + box-shadow: 0 calc(2px * var(--scale-factor)) calc(5px * var(--scale-factor)) + rgba(136, 136, 136, 1); + border-radius: calc(2px * var(--scale-factor)); + padding: calc(6px * var(--scale-factor)); + margin-left: calc(5px * var(--scale-factor)); cursor: pointer; font: message-box; - font-size: 9px; white-space: normal; word-wrap: break-word; + pointer-events: auto; }
.annotationLayer .popup > * { - font-size: 9px; + font-size: calc(9px * var(--scale-factor)); }
.annotationLayer .popup h1 { @@ -284,17 +318,18 @@
.annotationLayer .popupDate { display: inline-block; - margin-left: 5px; + margin-left: calc(5px * var(--scale-factor)); }
.annotationLayer .popupContent { border-top: 1px solid rgba(51, 51, 51, 1); - margin-top: 2px; - padding-top: 2px; + margin-top: calc(2px * var(--scale-factor)); + padding-top: calc(2px * var(--scale-factor)); }
.annotationLayer .richText > * { white-space: pre-wrap; + font-size: calc(9px * var(--scale-factor)); }
.annotationLayer .highlightAnnotation, @@ -314,11 +349,23 @@ cursor: pointer; }
+.annotationLayer section svg { + position: absolute; + width: 100%; + height: 100%; +} +
:root { --xfa-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,<svg width='1px' height='1px' xmlns='http://www.w3.org/2000/svg'><rect width='100%' height='100%' style='fill:rgba(0, 54, 255, 0.13);'/></svg>"); }
+@media (forced-colors: active) { + .xfaLayer *:required { + outline: 1.5px solid selectedItem; + } +} + .xfaLayer .highlight { margin: -1px; padding: 1px; @@ -389,6 +436,10 @@ line-height: inherit; }
+.xfaLayer *:required { + outline: 1.5px solid red; +} + .xfaLayer div { pointer-events: none; } @@ -633,24 +684,163 @@ } }
+ +:root { + --focus-outline: solid 2px red; + --hover-outline: dashed 2px blue; + --freetext-line-height: 1.35; + --freetext-padding: 2px; + --editorInk-editing-cursor: url(images/toolbarButton-editorInk.svg) 0 16; +} + +@media (forced-colors: active) { + :root { + --focus-outline: solid 3px ButtonText; + --hover-outline: dashed 3px ButtonText; + } +} + +[data-editor-rotation="90"] { + transform: rotate(90deg); +} +[data-editor-rotation="180"] { + transform: rotate(180deg); +} +[data-editor-rotation="270"] { + transform: rotate(270deg); +} + +.annotationEditorLayer { + background: transparent; + position: absolute; + top: 0; + left: 0; + font-size: calc(100px * var(--scale-factor)); + transform-origin: 0 0; +} + +.annotationEditorLayer .selectedEditor { + outline: var(--focus-outline); + resize: none; +} + +.annotationEditorLayer .freeTextEditor { + position: absolute; + background: transparent; + border-radius: 3px; + padding: calc(var(--freetext-padding) * var(--scale-factor)); + resize: none; + width: auto; + height: auto; + z-index: 1; + transform-origin: 0 0; + touch-action: none; +} + +.annotationEditorLayer .freeTextEditor .internal { + background: transparent; + border: none; + top: 0; + left: 0; + overflow: visible; + white-space: nowrap; + resize: none; + font: 10px sans-serif; + line-height: var(--freetext-line-height); +} + +.annotationEditorLayer .freeTextEditor .overlay { + position: absolute; + display: none; + background: transparent; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.annotationEditorLayer .freeTextEditor .overlay.enabled { + display: block; +} + +.annotationEditorLayer .freeTextEditor .internal:empty::before { + content: attr(default-content); + color: gray; +} + +.annotationEditorLayer .freeTextEditor .internal:focus { + outline: none; +} + +.annotationEditorLayer .inkEditor.disabled { + resize: none; +} + +.annotationEditorLayer .inkEditor.disabled.selectedEditor { + resize: horizontal; +} + +.annotationEditorLayer .freeTextEditor:hover:not(.selectedEditor), +.annotationEditorLayer .inkEditor:hover:not(.selectedEditor) { + outline: var(--hover-outline); +} + +.annotationEditorLayer .inkEditor { + position: absolute; + background: transparent; + border-radius: 3px; + overflow: auto; + width: 100%; + height: 100%; + z-index: 1; + transform-origin: 0 0; + cursor: auto; +} + +.annotationEditorLayer .inkEditor.editing { + resize: none; + cursor: var(--editorInk-editing-cursor), pointer; +} + +.annotationEditorLayer .inkEditor .inkEditorCanvas { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + touch-action: none; +} + :root { --viewer-container-height: 0; --pdfViewer-padding-bottom: 0; --page-margin: 1px auto -8px; --page-border: 9px solid transparent; + --page-border-image: url(images/shadow.png) 9 9 repeat; --spreadHorizontalWrapped-margin-LR: -3.5px; - --zoom-factor: 1; + --scale-factor: 1; }
@media screen and (forced-colors: active) { :root { --pdfViewer-padding-bottom: 9px; - --page-margin: 9px auto 0; - --page-border: none; - --spreadHorizontalWrapped-margin-LR: 4.5px; + --page-margin: 8px auto -1px; + --page-border: 1px solid CanvasText; + --page-border-image: none; + --spreadHorizontalWrapped-margin-LR: 3.5px; } }
+[data-main-rotation="90"] { + transform: rotate(90deg) translateY(-100%); +} +[data-main-rotation="180"] { + transform: rotate(180deg) translate(-100%, -100%); +} +[data-main-rotation="270"] { + transform: rotate(270deg) translateX(-100%); +} + .pdfViewer { padding-bottom: var(--pdfViewer-padding-bottom); } @@ -667,8 +857,8 @@ position: relative; overflow: visible; border: var(--page-border); + border-image: var(--page-border-image); background-clip: content-box; - border-image: url(images/shadow.png) 9 9 repeat; background-color: rgba(255, 255, 255, 1); }
@@ -783,13 +973,14 @@ --sidebar-transition-timing-function: ease; --scale-select-container-width: 140px; --scale-select-overflow: 22px; - --loadingBar-end-offset: 0;
--toolbar-icon-opacity: 0.7; --doorhanger-icon-opacity: 0.9;
--main-color: rgba(12, 12, 13, 1); --body-bg-color: rgba(237, 237, 240, 1); + --progressBar-percent: 0%; + --progressBar-end-offset: 0; --progressBar-color: rgba(10, 132, 255, 1); --progressBar-indeterminate-bg-color: rgba(221, 221, 222, 1); --progressBar-indeterminate-blend-color: rgba(116, 177, 239, 1); @@ -828,6 +1019,9 @@ --loading-icon: url(images/loading.svg); --treeitem-expanded-icon: url(images/treeitem-expanded.svg); --treeitem-collapsed-icon: url(images/treeitem-collapsed.svg); + --toolbarButton-editorNone-icon: url(images/toolbarButton-editorNone.svg); + --toolbarButton-editorFreeText-icon: url(images/toolbarButton-editorFreeText.svg); + --toolbarButton-editorInk-icon: url(images/toolbarButton-editorInk.svg); --toolbarButton-menuArrow-icon: url(images/toolbarButton-menuArrow.svg); --toolbarButton-sidebarToggle-icon: url(images/toolbarButton-sidebarToggle.svg); --toolbarButton-secondaryToolbarToggle-icon: url(images/toolbarButton-secondaryToolbarToggle.svg); @@ -1018,7 +1212,7 @@ select { right: 0; bottom: 0; left: 0; - min-width: 320px; + min-width: 350px; }
#sidebarContent { @@ -1083,7 +1277,8 @@ select {
#toolbarContainer, .findbar, -.secondaryToolbar { +.secondaryToolbar, +.editorParamsToolbar { position: relative; height: 32px; background-color: var(--toolbar-bg-color); @@ -1096,7 +1291,7 @@ select {
#loadingBar { position: absolute; - inset-inline: 0 var(--loadingBar-end-offset); + inset-inline: 0 var(--progressBar-end-offset); height: 4px; background-color: var(--body-bg-color); border-bottom: 1px solid var(--toolbar-border-color); @@ -1113,28 +1308,31 @@ select { position: absolute; top: 0; left: 0; - width: 0%; + width: 100%; + transform: scaleX(var(--progressBar-percent)); + transform-origin: 0 0; height: 100%; background-color: var(--progressBar-color); overflow: hidden; - transition: width 200ms; + transition: transform 200ms; }
@keyframes progressIndeterminate { 0% { - left: -142px; + transform: translateX(-142px); } 100% { - left: 0; + transform: translateX(0); } }
-#loadingBar .progress.indeterminate { +#loadingBar.indeterminate .progress { + transform: none; background-color: var(--progressBar-indeterminate-bg-color); transition: none; }
-#loadingBar .progress.indeterminate .glimmer { +#loadingBar.indeterminate .progress .glimmer { position: absolute; top: 0; left: 0; @@ -1160,7 +1358,8 @@ select { }
.findbar, -.secondaryToolbar { +.secondaryToolbar, +.editorParamsToolbar { top: 32px; position: absolute; z-index: 10000; @@ -1227,7 +1426,8 @@ select { background-color: rgba(255, 102, 102, 1); }
-.secondaryToolbar { +.secondaryToolbar, +.editorParamsToolbar { padding: 6px 0 10px; inset-inline-end: 4px; height: auto; @@ -1235,6 +1435,50 @@ select { background-color: var(--doorhanger-bg-color); }
+.editorParamsToolbarContainer { + width: 220px; + margin-bottom: -4px; +} + +.editorParamsToolbarContainer > .editorParamsSetter { + min-height: 26px; + display: flex; + align-items: center; + justify-content: space-between; + padding-inline: 10px; +} + +.editorParamsToolbarContainer .editorParamsLabel { + padding-inline-end: 10px; + flex: none; + color: var(--main-color); +} + +.editorParamsToolbarContainer .editorParamsColor { + width: 32px; + height: 32px; + flex: none; +} + +.editorParamsToolbarContainer .editorParamsSlider { + background-color: transparent; + width: 90px; + flex: 0 1 0; +} + +.editorParamsToolbarContainer .editorParamsSlider::-moz-range-progress { + background-color: black; +} +.editorParamsToolbarContainer .editorParamsSlider::-moz-range-track, +.editorParamsToolbarContainer + .editorParamsSlider::-webkit-slider-runnable-track { + background-color: black; +} +.editorParamsToolbarContainer .editorParamsSlider::-moz-range-thumb, +.editorParamsToolbarContainer .editorParamsSlider::-webkit-slider-thumb { + background-color: white; +} + #secondaryToolbarButtonContainer { max-width: 220px; min-height: 26px; @@ -1243,6 +1487,16 @@ select { margin-bottom: -4px; }
+#editorInkParamsToolbar { + inset-inline-end: 40px; + background-color: var(--toolbar-bg-color); +} + +#editorFreeTextParamsToolbar { + inset-inline-end: 68px; + background-color: var(--toolbar-bg-color); +} + .doorHanger, .doorHangerRight { border-radius: 2px; @@ -1567,12 +1821,23 @@ select { mask-image: var(--toolbarButton-presentationMode-icon); }
+#editorNone::before { + mask-image: var(--toolbarButton-editorNone-icon); +} + +#editorFreeText::before { + mask-image: var(--toolbarButton-editorFreeText-icon); +} + +#editorInk::before { + mask-image: var(--toolbarButton-editorInk-icon); +} + #print::before, #secondaryPrint::before { mask-image: var(--toolbarButton-print-icon); }
- #download::before, #secondaryDownload::before { mask-image: var(--toolbarButton-download-icon); @@ -1873,12 +2138,16 @@ a:focus > .thumbnail > .thumbnailSelectionRing, cursor: pointer; }
-#layersView .treeItem > a > * { +#layersView .treeItem > a * { cursor: pointer; } #layersView .treeItem > a > label { padding-inline-start: 4px; } +#layersView .treeItem > a > label > input { + float: inline-start; + margin-top: 1px; +}
.treeItemToggler { position: relative; @@ -1921,7 +2190,6 @@ a:focus > .thumbnail > .thumbnailSelectionRing, background: rgba(0, 0, 255, 0.3); }
- .dialogButton { width: auto; margin: 3px 4px 2px !important; @@ -2107,7 +2375,7 @@ dialog :link { } }
-@media all and (max-width: 770px) { +@media all and (max-width: 820px) { #outerContainer .hiddenLargeView { display: none; } @@ -2116,7 +2384,7 @@ dialog :link { } }
-@media all and (max-width: 700px) { +@media all and (max-width: 750px) { #outerContainer .hiddenMediumView { display: none; } @@ -2125,7 +2393,7 @@ dialog :link { } }
-@media all and (max-width: 640px) { +@media all and (max-width: 690px) { .hiddenSmallView, .hiddenSmallView * { display: none; @@ -2141,7 +2409,7 @@ dialog :link { } }
-@media all and (max-width: 535px) { +@media all and (max-width: 560px) { #scaleSelectContainer { display: none; } diff --git a/toolkit/components/pdfjs/content/web/viewer.html b/toolkit/components/pdfjs/content/web/viewer.html index 4b1cd13a81b91..02187731697c1 100644 --- a/toolkit/components/pdfjs/content/web/viewer.html +++ b/toolkit/components/pdfjs/content/web/viewer.html @@ -30,11 +30,8 @@ See https://github.com/adobe-type-tools/cmap-resources <base href="resource://pdf.js/web/"> <script src="../build/pdf.js"></script>
- <link rel="stylesheet" href="viewer.css">
- - <script src="viewer.js"></script>
</head> @@ -118,13 +115,38 @@ See https://github.com/adobe-type-tools/cmap-resources </div> </div> <!-- findbar -->
+ <div class="editorParamsToolbar hidden doorHangerRight" id="editorFreeTextParamsToolbar"> + <div class="editorParamsToolbarContainer"> + <div class="editorParamsSetter"> + <label for="editorFreeTextColor" class="editorParamsLabel" data-l10n-id="editor_free_text_font_color">Font Color</label> + <input type="color" id="editorFreeTextColor" class="editorParamsColor" tabindex="100"> + </div> + <div class="editorParamsSetter"> + <label for="editorFreeTextFontSize" class="editorParamsLabel" data-l10n-id="editor_free_text_font_size">Font Size</label> + <input type="range" id="editorFreeTextFontSize" class="editorParamsSlider" value="10" min="5" max="100" step="1" tabindex="101"> + </div> + </div> + </div> + + <div class="editorParamsToolbar hidden doorHangerRight" id="editorInkParamsToolbar"> + <div class="editorParamsToolbarContainer"> + <div class="editorParamsSetter"> + <label for="editorInkColor" class="editorParamsLabel" data-l10n-id="editor_ink_line_color">Line Color</label> + <input type="color" id="editorInkColor" class="editorParamsColor" tabindex="102"> + </div> + <div class="editorParamsSetter"> + <label for="editorInkThickness" class="editorParamsLabel" data-l10n-id="editor_ink_line_thickness">Line Thickness</label> + <input type="range" id="editorInkThickness" class="editorParamsSlider" value="1" min="1" max="20" step="1" tabindex="103"> + </div> + </div> + </div> + <div id="secondaryToolbar" class="secondaryToolbar hidden doorHangerRight"> <div id="secondaryToolbarButtonContainer"> <button id="secondaryPresentationMode" class="secondaryToolbarButton visibleLargeView" title="Switch to Presentation Mode" tabindex="51" data-l10n-id="presentation_mode"> <span data-l10n-id="presentation_mode_label">Presentation Mode</span> </button>
- <button id="secondaryPrint" class="secondaryToolbarButton visibleMediumView" title="Print" tabindex="53" data-l10n-id="print"> <span data-l10n-id="print_label">Print</span> </button> @@ -233,7 +255,6 @@ See https://github.com/adobe-type-tools/cmap-resources <span data-l10n-id="presentation_mode_label">Presentation Mode</span> </button>
- <button id="print" class="toolbarButton hiddenMediumView" title="Print" tabindex="33" data-l10n-id="print"> <span data-l10n-id="print_label">Print</span> </button> @@ -247,7 +268,22 @@ See https://github.com/adobe-type-tools/cmap-resources
<div class="verticalToolbarSeparator hiddenSmallView"></div>
- <button id="secondaryToolbarToggle" class="toolbarButton" title="Tools" tabindex="36" data-l10n-id="tools" aria-expanded="false" aria-controls="secondaryToolbar"> + <div id="editorModeButtons" class="splitToolbarButton toggled hidden" role="radiogroup"> + <button id="editorNone" class="toolbarButton toggled" disabled="disabled" title="Disable Annotation Editing" role="radio" aria-checked="true" tabindex="36" data-l10n-id="editor_none"> + <span data-l10n-id="editor_none_label">Disable Editing</span> + </button> + <button id="editorFreeText" class="toolbarButton" disabled="disabled" title="Add FreeText Annotation" role="radio" aria-checked="false" tabindex="37" data-l10n-id="editor_free_text"> + <span data-l10n-id="editor_free_text_label">FreeText Annotation</span> + </button> + <button id="editorInk" class="toolbarButton" disabled="disabled" title="Add Ink Annotation" role="radio" aria-checked="false" tabindex="38" data-l10n-id="editor_ink"> + <span data-l10n-id="editor_ink_label">Ink Annotation</span> + </button> + </div> + + <!-- Should be visible when the "editorModeButtons" are visible. --> + <div id="editorModeSeparator" class="verticalToolbarSeparator hidden"></div> + + <button id="secondaryToolbarToggle" class="toolbarButton" title="Tools" tabindex="48" data-l10n-id="tools" aria-expanded="false" aria-controls="secondaryToolbar"> <span data-l10n-id="tools_label">Tools</span> </button> </div> diff --git a/toolkit/components/pdfjs/content/web/viewer.js b/toolkit/components/pdfjs/content/web/viewer.js index 6df7f42928480..7fab34d096f41 100644 --- a/toolkit/components/pdfjs/content/web/viewer.js +++ b/toolkit/components/pdfjs/content/web/viewer.js @@ -44,6 +44,10 @@ const OptionKind = { }; exports.OptionKind = OptionKind; const defaultOptions = { + annotationEditorMode: { + value: -1, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, annotationMode: { value: 2, kind: OptionKind.VIEWER + OptionKind.PREFERENCE @@ -52,10 +56,6 @@ const defaultOptions = { value: 0, kind: OptionKind.VIEWER + OptionKind.PREFERENCE }, - defaultUrl: { - value: "compressed.tracemonkey-pldi-09.pdf", - kind: OptionKind.VIEWER - }, defaultZoomValue: { value: "", kind: OptionKind.VIEWER + OptionKind.PREFERENCE @@ -102,9 +102,12 @@ const defaultOptions = { }, maxCanvasPixels: { value: 16777216, - compatibility: compatibilityParams.maxCanvasPixels, kind: OptionKind.VIEWER }, + forcePageColors: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, pageColorsBackground: { value: "Canvas", kind: OptionKind.VIEWER + OptionKind.PREFERENCE @@ -121,10 +124,6 @@ const defaultOptions = { value: 150, kind: OptionKind.VIEWER }, - renderer: { - value: "canvas", - kind: OptionKind.VIEWER - }, sidebarViewOnLoad: { value: -1, kind: OptionKind.VIEWER + OptionKind.PREFERENCE @@ -236,7 +235,7 @@ class AppOptions { const defaultOption = defaultOptions[name];
if (defaultOption !== undefined) { - return defaultOption.compatibility ?? defaultOption.value; + return compatibilityParams[name] ?? defaultOption.value; }
return undefined; @@ -267,7 +266,7 @@ class AppOptions { }
const userOption = userOptions[name]; - options[name] = userOption !== undefined ? userOption : defaultOption.compatibility ?? defaultOption.value; + options[name] = userOption !== undefined ? userOption : compatibilityParams[name] ?? defaultOption.value; }
return options; @@ -308,53 +307,55 @@ exports.PDFViewerApplication = exports.PDFPrintServiceFactory = exports.DefaultE
var _ui_utils = __webpack_require__(3);
-var _app_options = __webpack_require__(1); +var _pdfjsLib = __webpack_require__(4);
-var _event_utils = __webpack_require__(4); +var _app_options = __webpack_require__(1);
-var _pdfjsLib = __webpack_require__(5); +var _event_utils = __webpack_require__(5);
var _pdf_cursor_tools = __webpack_require__(6);
var _pdf_link_service = __webpack_require__(8);
-var _overlay_manager = __webpack_require__(9); +var _annotation_editor_params = __webpack_require__(9);
-var _password_prompt = __webpack_require__(10); +var _overlay_manager = __webpack_require__(10);
-var _pdf_attachment_viewer = __webpack_require__(11); +var _password_prompt = __webpack_require__(11);
-var _pdf_document_properties = __webpack_require__(13); +var _pdf_attachment_viewer = __webpack_require__(12);
-var _pdf_find_bar = __webpack_require__(14); +var _pdf_document_properties = __webpack_require__(14);
-var _pdf_find_controller = __webpack_require__(15); +var _pdf_find_bar = __webpack_require__(15);
-var _pdf_history = __webpack_require__(17); +var _pdf_find_controller = __webpack_require__(16);
-var _pdf_layer_viewer = __webpack_require__(18); +var _pdf_history = __webpack_require__(18);
-var _pdf_outline_viewer = __webpack_require__(19); +var _pdf_layer_viewer = __webpack_require__(19);
-var _pdf_presentation_mode = __webpack_require__(20); +var _pdf_outline_viewer = __webpack_require__(20);
-var _pdf_rendering_queue = __webpack_require__(21); +var _pdf_presentation_mode = __webpack_require__(21);
-var _pdf_scripting_manager = __webpack_require__(22); +var _pdf_rendering_queue = __webpack_require__(22);
-var _pdf_sidebar = __webpack_require__(23); +var _pdf_scripting_manager = __webpack_require__(23);
-var _pdf_sidebar_resizer = __webpack_require__(24); +var _pdf_sidebar = __webpack_require__(24);
-var _pdf_thumbnail_viewer = __webpack_require__(25); +var _pdf_sidebar_resizer = __webpack_require__(25);
-var _pdf_viewer = __webpack_require__(27); +var _pdf_thumbnail_viewer = __webpack_require__(26);
-var _secondary_toolbar = __webpack_require__(36); +var _pdf_viewer = __webpack_require__(28);
-var _toolbar = __webpack_require__(37); +var _secondary_toolbar = __webpack_require__(38);
-var _view_history = __webpack_require__(38); +var _toolbar = __webpack_require__(39); + +var _view_history = __webpack_require__(40);
const DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000; const FORCE_PAGES_LOADED_TIMEOUT = 10000; @@ -420,6 +421,10 @@ class DefaultExternalServices { return (0, _pdfjsLib.shadow)(this, "isInAutomation", false); }
+ static updateEditorStates(data) { + throw new Error("Not implemented: updateEditorStates"); + } + }
exports.DefaultExternalServices = DefaultExternalServices; @@ -452,6 +457,7 @@ const PDFViewerApplication = { secondaryToolbar: null, eventBus: null, l10n: null, + annotationEditorParams: null, isInitialViewSet: false, downloadComplete: false, isViewerEmbedded: window.parent !== window, @@ -469,6 +475,7 @@ const PDFViewerApplication = { _wheelUnusedTicks: 0, _idleCallbacks: new Set(), _PDFBug: null, + _printAnnotationStoragePromise: null,
async initialize(appConfig) { this.preferences = this.externalServices.createPreferences(); @@ -670,8 +677,15 @@ const PDFViewerApplication = { docPropertiesLookup: this._scriptingDocProperties.bind(this) }); this.pdfScriptingManager = pdfScriptingManager; - const container = appConfig.mainContainer; - const viewer = appConfig.viewerContainer; + const container = appConfig.mainContainer, + viewer = appConfig.viewerContainer; + + const annotationEditorMode = _app_options.AppOptions.get("annotationEditorMode"); + + const pageColors = _app_options.AppOptions.get("forcePageColors") || window.matchMedia("(forced-colors: active)").matches ? { + background: _app_options.AppOptions.get("pageColorsBackground"), + foreground: _app_options.AppOptions.get("pageColorsForeground") + } : null; this.pdfViewer = new _pdf_viewer.PDFViewer({ container, viewer, @@ -681,19 +695,17 @@ const PDFViewerApplication = { downloadManager, findController, scriptingManager: _app_options.AppOptions.get("enableScripting") && pdfScriptingManager, - renderer: _app_options.AppOptions.get("renderer"), + renderer: null, l10n: this.l10n, textLayerMode: _app_options.AppOptions.get("textLayerMode"), annotationMode: _app_options.AppOptions.get("annotationMode"), + annotationEditorMode, imageResourcesPath: _app_options.AppOptions.get("imageResourcesPath"), enablePrintAutoRotate: _app_options.AppOptions.get("enablePrintAutoRotate"), useOnlyCssZoom: _app_options.AppOptions.get("useOnlyCssZoom"), maxCanvasPixels: _app_options.AppOptions.get("maxCanvasPixels"), enablePermissions: _app_options.AppOptions.get("enablePermissions"), - pageColors: { - background: _app_options.AppOptions.get("pageColorsBackground"), - foreground: _app_options.AppOptions.get("pageColorsForeground") - } + pageColors }); pdfRenderingQueue.setViewer(this.pdfViewer); pdfLinkService.setViewer(this.pdfViewer); @@ -703,7 +715,8 @@ const PDFViewerApplication = { eventBus, renderingQueue: pdfRenderingQueue, linkService: pdfLinkService, - l10n: this.l10n + l10n: this.l10n, + pageColors }); pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
@@ -719,7 +732,17 @@ const PDFViewerApplication = { this.findBar = new _pdf_find_bar.PDFFindBar(appConfig.findBar, eventBus, this.l10n); }
- this.pdfDocumentProperties = new _pdf_document_properties.PDFDocumentProperties(appConfig.documentProperties, this.overlayManager, eventBus, this.l10n); + if (annotationEditorMode !== _pdfjsLib.AnnotationEditorType.DISABLE) { + this.annotationEditorParams = new _annotation_editor_params.AnnotationEditorParams(appConfig.annotationEditorParams, eventBus); + + for (const element of [document.getElementById("editorModeButtons"), document.getElementById("editorModeSeparator")]) { + element.classList.remove("hidden"); + } + } + + this.pdfDocumentProperties = new _pdf_document_properties.PDFDocumentProperties(appConfig.documentProperties, this.overlayManager, eventBus, this.l10n, () => { + return this._docFilename; + }); this.pdfCursorTools = new _pdf_cursor_tools.PDFCursorTools({ container, eventBus, @@ -828,7 +851,7 @@ const PDFViewerApplication = { },
get loadingBar() { - const bar = new _ui_utils.ProgressBar("#loadingBar"); + const bar = new _ui_utils.ProgressBar("loadingBar"); return (0, _pdfjsLib.shadow)(this, "loadingBar", bar); },
@@ -1069,9 +1092,7 @@ const PDFViewerApplication = { throw new Error("PDF document not downloaded."); },
- async download({ - sourceEventType = "download" - } = {}) { + async download() { const url = this._downloadUrl, filename = this._docFilename;
@@ -1082,15 +1103,13 @@ const PDFViewerApplication = { const blob = new Blob([data], { type: "application/pdf" }); - await this.downloadManager.download(blob, url, filename, sourceEventType); + await this.downloadManager.download(blob, url, filename); } catch (reason) { await this.downloadManager.downloadUrl(url, filename); } },
- async save({ - sourceEventType = "download" - } = {}) { + async save() { if (this._saveInProgress) { return; } @@ -1107,23 +1126,21 @@ const PDFViewerApplication = { const blob = new Blob([data], { type: "application/pdf" }); - await this.downloadManager.download(blob, url, filename, sourceEventType); + await this.downloadManager.download(blob, url, filename); } catch (reason) { console.error(`Error when saving the document: ${reason.message}`); - await this.download({ - sourceEventType - }); + await this.download(); } finally { await this.pdfScriptingManager.dispatchDidSave(); this._saveInProgress = false; } },
- downloadOrSave(options) { + downloadOrSave() { if (this.pdfDocument?.annotationStorage.size > 0) { - this.save(options); + this.save(); } else { - this.download(options); + this.download(); } },
@@ -1189,23 +1206,28 @@ const PDFViewerApplication = {
const percent = Math.round(level * 100);
- if (percent > this.loadingBar.percent || isNaN(percent)) { - this.loadingBar.percent = percent; - const disableAutoFetch = this.pdfDocument ? this.pdfDocument.loadingParams.disableAutoFetch : _app_options.AppOptions.get("disableAutoFetch"); + if (percent <= this.loadingBar.percent) { + return; + }
- if (disableAutoFetch && percent) { - if (this.disableAutoFetchLoadingBarTimeout) { - clearTimeout(this.disableAutoFetchLoadingBarTimeout); - this.disableAutoFetchLoadingBarTimeout = null; - } + this.loadingBar.percent = percent;
- this.loadingBar.show(); - this.disableAutoFetchLoadingBarTimeout = setTimeout(() => { - this.loadingBar.hide(); - this.disableAutoFetchLoadingBarTimeout = null; - }, DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT); - } + const disableAutoFetch = this.pdfDocument?.loadingParams.disableAutoFetch ?? _app_options.AppOptions.get("disableAutoFetch"); + + if (!disableAutoFetch || isNaN(percent)) { + return; + } + + if (this.disableAutoFetchLoadingBarTimeout) { + clearTimeout(this.disableAutoFetchLoadingBarTimeout); + this.disableAutoFetchLoadingBarTimeout = null; } + + this.loadingBar.show(); + this.disableAutoFetchLoadingBarTimeout = setTimeout(() => { + this.loadingBar.hide(); + this.disableAutoFetchLoadingBarTimeout = null; + }, DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT); },
load(pdfDocument) { @@ -1230,7 +1252,7 @@ const PDFViewerApplication = { let baseDocumentUrl; baseDocumentUrl = this.baseUrl; this.pdfLinkService.setDocument(pdfDocument, baseDocumentUrl); - this.pdfDocumentProperties.setDocument(pdfDocument, this.url); + this.pdfDocumentProperties.setDocument(pdfDocument); const pdfViewer = this.pdfViewer; pdfViewer.setDocument(pdfDocument); const { @@ -1507,7 +1529,7 @@ const PDFViewerApplication = { this._contentDispositionFilename ??= contentDispositionFilename; this._contentLength ??= contentLength; console.log(`PDF ${pdfDocument.fingerprints[0]} [${info.PDFFormatVersion} ` + `${(info.Producer || "-").trim()} / ${(info.Creator || "-").trim()}] ` + `(PDF.js: ${_pdfjsLib.version || "-"})`); - let pdfTitle = info?.Title; + let pdfTitle = info.Title; const metadataTitle = metadata?.get("dc:title");
if (metadataTitle) { @@ -1517,9 +1539,9 @@ const PDFViewerApplication = { }
if (pdfTitle) { - this.setTitle(`${pdfTitle} - ${contentDispositionFilename || document.title}`); - } else if (contentDispositionFilename) { - this.setTitle(contentDispositionFilename); + this.setTitle(`${pdfTitle} - ${this._contentDispositionFilename || document.title}`); + } else if (this._contentDispositionFilename) { + this.setTitle(this._contentDispositionFilename); }
if (info.IsXFAPresent && !info.IsAcroFormPresent && !pdfDocument.isPureXfa) { @@ -1719,17 +1741,19 @@ const PDFViewerApplication = {
this.pdfViewer.cleanup(); this.pdfThumbnailViewer.cleanup(); - this.pdfDocument.cleanup(this.pdfViewer.renderer === _ui_utils.RendererType.SVG); + this.pdfDocument.cleanup(); },
forceRendering() { this.pdfRenderingQueue.printing = !!this.printService; - this.pdfRenderingQueue.isThumbnailViewEnabled = this.pdfSidebar.isThumbnailViewVisible; + this.pdfRenderingQueue.isThumbnailViewEnabled = this.pdfSidebar.visibleView === _ui_utils.SidebarView.THUMBS; this.pdfRenderingQueue.renderHighestPriority(); },
beforePrint() { - this.pdfScriptingManager.dispatchWillPrint(); + this._printAnnotationStoragePromise = this.pdfScriptingManager.dispatchWillPrint().catch(() => {}).then(() => { + return this.pdfDocument?.annotationStorage.print; + });
if (this.printService) { return; @@ -1755,7 +1779,7 @@ const PDFViewerApplication = { const printResolution = _app_options.AppOptions.get("printResolution");
const optionalContentConfigPromise = this.pdfViewer.optionalContentConfigPromise; - const printService = PDFPrintServiceFactory.instance.createPrintService(this.pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise, this.l10n); + const printService = PDFPrintServiceFactory.instance.createPrintService(this.pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise, this._printAnnotationStoragePromise, this.l10n); this.printService = printService; this.forceRendering(); printService.layout(); @@ -1765,7 +1789,13 @@ const PDFViewerApplication = { },
afterPrint() { - this.pdfScriptingManager.dispatchDidPrint(); + if (this._printAnnotationStoragePromise) { + this._printAnnotationStoragePromise.then(() => { + this.pdfScriptingManager.dispatchDidPrint(); + }); + + this._printAnnotationStoragePromise = null; + }
if (this.printService) { this.printService.destroy(); @@ -1828,12 +1858,14 @@ const PDFViewerApplication = {
eventBus._on("presentationmode", webViewerPresentationMode);
+ eventBus._on("switchannotationeditormode", webViewerSwitchAnnotationEditorMode); + + eventBus._on("switchannotationeditorparams", webViewerSwitchAnnotationEditorParams); + eventBus._on("print", webViewerPrint);
eventBus._on("download", webViewerDownload);
- eventBus._on("save", webViewerSave); - eventBus._on("firstpage", webViewerFirstPage);
eventBus._on("lastpage", webViewerLastPage); @@ -1881,6 +1913,8 @@ const PDFViewerApplication = {
eventBus._on("pagechanging", _boundEvents.reportPageStatsPDFBug); } + + eventBus._on("annotationeditorstateschanged", webViewerAnnotationEditorStatesChanged); },
bindWindowEvents() { @@ -2067,7 +2101,7 @@ function webViewerPageRendered({ PDFViewerApplication.toolbar.updateLoadingIndicatorState(false); }
- if (PDFViewerApplication.pdfSidebar.isThumbnailViewVisible) { + if (PDFViewerApplication.pdfSidebar.visibleView === _ui_utils.SidebarView.THUMBS) { const pageView = PDFViewerApplication.pdfViewer.getPageView(pageNumber - 1); const thumbnailView = PDFViewerApplication.pdfThumbnailViewer.getThumbnail(pageNumber - 1);
@@ -2138,7 +2172,7 @@ function webViewerNamedAction(evt) { break;
case "SaveAs": - webViewerSave(); + PDFViewerApplication.downloadOrSave(); break; } } @@ -2147,17 +2181,19 @@ function webViewerPresentationModeChanged(evt) { PDFViewerApplication.pdfViewer.presentationModeState = evt.state; }
-function webViewerSidebarViewChanged(evt) { - PDFViewerApplication.pdfRenderingQueue.isThumbnailViewEnabled = PDFViewerApplication.pdfSidebar.isThumbnailViewVisible; +function webViewerSidebarViewChanged({ + view +}) { + PDFViewerApplication.pdfRenderingQueue.isThumbnailViewEnabled = view === _ui_utils.SidebarView.THUMBS;
if (PDFViewerApplication.isInitialViewSet) { - PDFViewerApplication.store?.set("sidebarView", evt.view).catch(() => {}); + PDFViewerApplication.store?.set("sidebarView", view).catch(() => {}); } }
-function webViewerUpdateViewarea(evt) { - const location = evt.location; - +function webViewerUpdateViewarea({ + location +}) { if (PDFViewerApplication.isInitialViewSet) { PDFViewerApplication.store?.setMultiple({ page: location.pageNumber, @@ -2228,20 +2264,20 @@ function webViewerPresentationMode() { PDFViewerApplication.requestPresentationMode(); }
+function webViewerSwitchAnnotationEditorMode(evt) { + PDFViewerApplication.pdfViewer.annotationEditorMode = evt.mode; +} + +function webViewerSwitchAnnotationEditorParams(evt) { + PDFViewerApplication.pdfViewer.annotationEditorParams = evt; +} + function webViewerPrint() { PDFViewerApplication.triggerPrinting(); }
function webViewerDownload() { - PDFViewerApplication.downloadOrSave({ - sourceEventType: "download" - }); -} - -function webViewerSave() { - PDFViewerApplication.downloadOrSave({ - sourceEventType: "save" - }); + PDFViewerApplication.downloadOrSave(); }
function webViewerFirstPage() { @@ -2376,7 +2412,7 @@ function webViewerPageChanging({ PDFViewerApplication.toolbar.setPageNumber(pageNumber, pageLabel); PDFViewerApplication.secondaryToolbar.setPageNumber(pageNumber);
- if (PDFViewerApplication.pdfSidebar.isThumbnailViewVisible) { + if (PDFViewerApplication.pdfSidebar.visibleView === _ui_utils.SidebarView.THUMBS) { PDFViewerApplication.pdfThumbnailViewer.scrollThumbnailIntoView(pageNumber); } } @@ -2757,6 +2793,10 @@ function beforeUnload(evt) { return false; }
+function webViewerAnnotationEditorStatesChanged(data) { + PDFViewerApplication.externalServices.updateEditorStates(data); +} + const PDFPrintServiceFactory = { instance: { supportsPrinting: false, @@ -2771,7 +2811,7 @@ exports.PDFPrintServiceFactory = PDFPrintServiceFactory;
/***/ }), /* 3 */ -/***/ ((__unused_webpack_module, exports) => { +/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -2783,7 +2823,7 @@ exports.apiPageLayoutToViewerModes = apiPageLayoutToViewerModes; exports.apiPageModeToSidebarView = apiPageModeToSidebarView; exports.approximateFraction = approximateFraction; exports.backtrackBeforeAllVisibleElements = backtrackBeforeAllVisibleElements; -exports.binarySearchFirstItem = binarySearchFirstItem; +exports.docStyle = void 0; exports.getActiveOrFocusedElement = getActiveOrFocusedElement; exports.getPageSizeInches = getPageSizeInches; exports.getVisibleElements = getVisibleElements; @@ -2799,6 +2839,9 @@ exports.removeNullCharacters = removeNullCharacters; exports.roundToDivide = roundToDivide; exports.scrollIntoView = scrollIntoView; exports.watchScroll = watchScroll; + +var _pdfjsLib = __webpack_require__(4); + const DEFAULT_SCALE_VALUE = "auto"; exports.DEFAULT_SCALE_VALUE = DEFAULT_SCALE_VALUE; const DEFAULT_SCALE = 1.0; @@ -2817,7 +2860,6 @@ const SCROLLBAR_PADDING = 40; exports.SCROLLBAR_PADDING = SCROLLBAR_PADDING; const VERTICAL_PADDING = 5; exports.VERTICAL_PADDING = VERTICAL_PADDING; -const LOADINGBAR_END_OFFSET_VAR = "--loadingBar-end-offset"; const RenderingStates = { INITIAL: 0, RUNNING: 1, @@ -2841,10 +2883,7 @@ const SidebarView = { LAYERS: 4 }; exports.SidebarView = SidebarView; -const RendererType = { - CANVAS: "canvas", - SVG: "svg" -}; +const RendererType = null; exports.RendererType = RendererType; const TextLayerMode = { DISABLE: 0, @@ -2986,32 +3025,6 @@ function removeNullCharacters(str, replaceInvisible = false) { return str.replace(NullCharactersRegExp, ""); }
-function binarySearchFirstItem(items, condition, start = 0) { - let minIndex = start; - let maxIndex = items.length - 1; - - if (maxIndex < 0 || !condition(items[maxIndex])) { - return items.length; - } - - if (condition(items[minIndex])) { - return minIndex; - } - - while (minIndex < maxIndex) { - const currentIndex = minIndex + maxIndex >> 1; - const currentItem = items[currentIndex]; - - if (condition(currentItem)) { - maxIndex = currentIndex; - } else { - minIndex = currentIndex + 1; - } - } - - return minIndex; -} - function approximateFraction(x) { if (Math.floor(x) === x) { return [x, 1]; @@ -3134,7 +3147,7 @@ function getVisibleElements({ const visible = [], ids = new Set(), numViews = views.length; - let firstVisibleElementInd = binarySearchFirstItem(views, horizontal ? isElementNextAfterViewHorizontally : isElementBottomAfterViewTop); + let firstVisibleElementInd = (0, _pdfjsLib.binarySearchFirstItem)(views, horizontal ? isElementNextAfterViewHorizontally : isElementBottomAfterViewTop);
if (firstVisibleElementInd > 0 && firstVisibleElementInd < numViews && !horizontal) { firstVisibleElementInd = backtrackBeforeAllVisibleElements(firstVisibleElementInd, views, top); @@ -3181,7 +3194,7 @@ function getVisibleElements({ }
const first = visible[0], - last = visible[visible.length - 1]; + last = visible.at(-1);
if (sortByVisibility) { visible.sort(function (a, b) { @@ -3254,48 +3267,37 @@ const animationStarted = new Promise(function (resolve) { window.requestAnimationFrame(resolve); }); exports.animationStarted = animationStarted; +const docStyle = document.documentElement.style; +exports.docStyle = docStyle;
function clamp(v, min, max) { return Math.min(Math.max(v, min), max); }
class ProgressBar { - constructor(id, { - height, - width, - units - } = {}) { - this.visible = true; - this.div = document.querySelector(id + " .progress"); - this.bar = this.div.parentNode; - this.height = height || 100; - this.width = width || 100; - this.units = units || "%"; - this.div.style.height = this.height + this.units; - this.percent = 0; - } - - _updateBar() { - if (this._indeterminate) { - this.div.classList.add("indeterminate"); - this.div.style.width = this.width + this.units; - return; - } + #classList = null; + #percent = 0; + #visible = true;
- this.div.classList.remove("indeterminate"); - const progressSize = this.width * this._percent / 100; - this.div.style.width = progressSize + this.units; + constructor(id) { + const bar = document.getElementById(id); + this.#classList = bar.classList; }
get percent() { - return this._percent; + return this.#percent; }
set percent(val) { - this._indeterminate = isNaN(val); - this._percent = clamp(val, 0, 100); + this.#percent = clamp(val, 0, 100); + + if (isNaN(val)) { + this.#classList.add("indeterminate"); + return; + }
- this._updateBar(); + this.#classList.remove("indeterminate"); + docStyle.setProperty("--progressBar-percent", `${this.#percent}%`); }
setWidth(viewer) { @@ -3307,27 +3309,26 @@ class ProgressBar { const scrollbarWidth = container.offsetWidth - viewer.offsetWidth;
if (scrollbarWidth > 0) { - const doc = document.documentElement; - doc.style.setProperty(LOADINGBAR_END_OFFSET_VAR, `${scrollbarWidth}px`); + docStyle.setProperty("--progressBar-end-offset", `${scrollbarWidth}px`); } }
hide() { - if (!this.visible) { + if (!this.#visible) { return; }
- this.visible = false; - this.bar.classList.add("hidden"); + this.#visible = false; + this.#classList.add("hidden"); }
show() { - if (this.visible) { + if (this.#visible) { return; }
- this.visible = true; - this.bar.classList.remove("hidden"); + this.#visible = true; + this.#classList.remove("hidden"); }
} @@ -3402,6 +3403,22 @@ function apiPageModeToSidebarView(mode) {
/***/ }), /* 4 */ +/***/ ((module) => { + + + +let pdfjsLib; + +if (typeof window !== "undefined" && window["pdfjs-dist/build/pdf"]) { + pdfjsLib = window["pdfjs-dist/build/pdf"]; +} else { + pdfjsLib = require("../build/pdf.js"); +} + +module.exports = pdfjsLib; + +/***/ }), +/* 5 */ /***/ ((__unused_webpack_module, exports) => {
@@ -3566,22 +3583,6 @@ class AutomationEventBus extends EventBus {
exports.AutomationEventBus = AutomationEventBus;
-/***/ }), -/* 5 */ -/***/ ((module) => { - - - -let pdfjsLib; - -if (typeof window !== "undefined" && window["pdfjs-dist/build/pdf"]) { - pdfjsLib = window["pdfjs-dist/build/pdf"]; -} else { - pdfjsLib = require("../build/pdf.js"); -} - -module.exports = pdfjsLib; - /***/ }), /* 6 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { @@ -3826,7 +3827,7 @@ class GrabToPan { }
if (!this.overlay.parentNode) { - document.body.appendChild(this.overlay); + document.body.append(this.overlay); } }
@@ -4376,6 +4377,87 @@ exports.SimpleLinkService = SimpleLinkService;
/***/ }), /* 9 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.AnnotationEditorParams = void 0; + +var _pdfjsLib = __webpack_require__(4); + +class AnnotationEditorParams { + constructor(options, eventBus) { + this.eventBus = eventBus; + this.#bindListeners(options); + } + + #bindListeners({ + editorFreeTextFontSize, + editorFreeTextColor, + editorInkColor, + editorInkThickness + }) { + editorFreeTextFontSize.addEventListener("input", evt => { + this.eventBus.dispatch("switchannotationeditorparams", { + source: this, + type: _pdfjsLib.AnnotationEditorParamsType.FREETEXT_SIZE, + value: editorFreeTextFontSize.valueAsNumber + }); + }); + editorFreeTextColor.addEventListener("input", evt => { + this.eventBus.dispatch("switchannotationeditorparams", { + source: this, + type: _pdfjsLib.AnnotationEditorParamsType.FREETEXT_COLOR, + value: editorFreeTextColor.value + }); + }); + editorInkColor.addEventListener("input", evt => { + this.eventBus.dispatch("switchannotationeditorparams", { + source: this, + type: _pdfjsLib.AnnotationEditorParamsType.INK_COLOR, + value: editorInkColor.value + }); + }); + editorInkThickness.addEventListener("input", evt => { + this.eventBus.dispatch("switchannotationeditorparams", { + source: this, + type: _pdfjsLib.AnnotationEditorParamsType.INK_THICKNESS, + value: editorInkThickness.valueAsNumber + }); + }); + + this.eventBus._on("annotationeditorparamschanged", evt => { + for (const [type, value] of evt.details) { + switch (type) { + case _pdfjsLib.AnnotationEditorParamsType.FREETEXT_SIZE: + editorFreeTextFontSize.value = value; + break; + + case _pdfjsLib.AnnotationEditorParamsType.FREETEXT_COLOR: + editorFreeTextColor.value = value; + break; + + case _pdfjsLib.AnnotationEditorParamsType.INK_COLOR: + editorInkColor.value = value; + break; + + case _pdfjsLib.AnnotationEditorParamsType.INK_THICKNESS: + editorInkThickness.value = value; + break; + } + } + }); + } + +} + +exports.AnnotationEditorParams = AnnotationEditorParams; + +/***/ }), +/* 10 */ /***/ ((__unused_webpack_module, exports) => {
@@ -4453,7 +4535,7 @@ class OverlayManager { exports.OverlayManager = OverlayManager;
/***/ }), -/* 10 */ +/* 11 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -4463,7 +4545,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.PasswordPrompt = void 0;
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
class PasswordPrompt { #updateCallback = null; @@ -4539,7 +4621,7 @@ class PasswordPrompt { exports.PasswordPrompt = PasswordPrompt;
/***/ }), -/* 11 */ +/* 12 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -4549,11 +4631,11 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.PDFAttachmentViewer = void 0;
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
-var _base_tree_viewer = __webpack_require__(12); +var _base_tree_viewer = __webpack_require__(13);
-var _event_utils = __webpack_require__(4); +var _event_utils = __webpack_require__(5);
class PDFAttachmentViewer extends _base_tree_viewer.BaseTreeViewer { constructor(options) { @@ -4643,8 +4725,8 @@ class PDFAttachmentViewer extends _base_tree_viewer.BaseTreeViewer { });
element.textContent = this._normalizeTextContent(filename); - div.appendChild(element); - fragment.appendChild(div); + div.append(element); + fragment.append(div); attachmentsCount++; }
@@ -4685,7 +4767,7 @@ class PDFAttachmentViewer extends _base_tree_viewer.BaseTreeViewer { exports.PDFAttachmentViewer = PDFAttachmentViewer;
/***/ }), -/* 12 */ +/* 13 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -4750,7 +4832,7 @@ class BaseTreeViewer { } };
- div.insertBefore(toggler, div.firstChild); + div.prepend(toggler); }
_toggleTreeItem(root, show = false) { @@ -4771,7 +4853,7 @@ class BaseTreeViewer { this._lastToggleIsShow = !fragment.querySelector(".treeItemsHidden"); }
- this.container.appendChild(fragment); + this.container.append(fragment);
this._dispatchEvent(count); } @@ -4819,7 +4901,7 @@ class BaseTreeViewer { exports.BaseTreeViewer = BaseTreeViewer;
/***/ }), -/* 13 */ +/* 14 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -4829,7 +4911,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.PDFDocumentProperties = void 0;
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
var _ui_utils = __webpack_require__(3);
@@ -4857,11 +4939,12 @@ class PDFDocumentProperties { dialog, fields, closeButton - }, overlayManager, eventBus, l10n) { + }, overlayManager, eventBus, l10n, fileNameLookup) { this.dialog = dialog; this.fields = fields; this.overlayManager = overlayManager; this.l10n = l10n; + this._fileNameLookup = fileNameLookup; this.#reset(); closeButton.addEventListener("click", this.close.bind(this)); this.overlayManager.register(this.dialog); @@ -4892,10 +4975,9 @@ class PDFDocumentProperties {
const { info, - contentDispositionFilename, contentLength } = await this.pdfDocument.getMetadata(); - const [fileName, fileSize, creationDate, modificationDate, pageSize, isLinearized] = await Promise.all([contentDispositionFilename || (0, _pdfjsLib.getPdfFilenameFromUrl)(this.url), this.#parseFileSize(contentLength), this.#parseDate(info.CreationDate), this.#parseDate(info.ModDate), this.pdfDocument.getPage(currentPageNumber).then(pdfPage => { + const [fileName, fileSize, creationDate, modificationDate, pageSize, isLinearized] = await Promise.all([this._fileNameLookup(), this.#parseFileSize(contentLength), this.#parseDate(info.CreationDate), this.#parseDate(info.ModDate), this.pdfDocument.getPage(currentPageNumber).then(pdfPage => { return this.#parsePageSize((0, _ui_utils.getPageSizeInches)(pdfPage), pagesRotation); }), this.#parseLinearization(info.IsLinearized)]); this.#fieldData = Object.freeze({ @@ -4935,7 +5017,7 @@ class PDFDocumentProperties { this.overlayManager.close(this.dialog); }
- setDocument(pdfDocument, url = null) { + setDocument(pdfDocument) { if (this.pdfDocument) { this.#reset(); this.#updateUI(true); @@ -4946,14 +5028,12 @@ class PDFDocumentProperties { }
this.pdfDocument = pdfDocument; - this.url = url;
this._dataAvailableCapability.resolve(); }
#reset() { this.pdfDocument = null; - this.url = null; this.#fieldData = null; this._dataAvailableCapability = (0, _pdfjsLib.createPromiseCapability)(); this._currentPageNumber = 1; @@ -5075,7 +5155,7 @@ class PDFDocumentProperties { exports.PDFDocumentProperties = PDFDocumentProperties;
/***/ }), -/* 14 */ +/* 15 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -5085,7 +5165,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.PDFFindBar = void 0;
-var _pdf_find_controller = __webpack_require__(15); +var _pdf_find_controller = __webpack_require__(16);
const MATCHES_COUNT_LIMIT = 1000;
@@ -5280,7 +5360,7 @@ class PDFFindBar { exports.PDFFindBar = PDFFindBar;
/***/ }), -/* 15 */ +/* 16 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -5290,11 +5370,11 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.PDFFindController = exports.FindState = void 0;
-var _ui_utils = __webpack_require__(3); +var _pdfjsLib = __webpack_require__(4);
-var _pdfjsLib = __webpack_require__(5); +var _pdf_find_utils = __webpack_require__(17);
-var _pdf_find_utils = __webpack_require__(16); +var _ui_utils = __webpack_require__(3);
const FindState = { FOUND: 0, @@ -5326,16 +5406,51 @@ const DIACRITICS_REG_EXP = /\p{M}+/gu; const SPECIAL_CHARS_REG_EXP = /([.*+?^${}()|[]\])|(\p{P})|(\s+)|(\p{M})|(\p{L})/gu; const NOT_DIACRITIC_FROM_END_REG_EXP = /([^\p{M}])\p{M}*$/u; const NOT_DIACRITIC_FROM_START_REG_EXP = /^\p{M}*([^\p{M}])/u; -let normalizationRegex = null; +const SYLLABLES_REG_EXP = /[\uAC00-\uD7AF\uFA6C\uFACF-\uFAD1\uFAD5-\uFAD7]+/g; +const SYLLABLES_LENGTHS = new Map(); +const FIRST_CHAR_SYLLABLES_REG_EXP = "[\u1100-\u1112\ud7a4-\ud7af\ud84a\ud84c\ud850\ud854\ud857\ud85f]"; +let noSyllablesRegExp = null; +let withSyllablesRegExp = null;
function normalize(text) { - if (!normalizationRegex) { + const syllablePositions = []; + let m; + + while ((m = SYLLABLES_REG_EXP.exec(text)) !== null) { + let { + index + } = m; + + for (const char of m[0]) { + let len = SYLLABLES_LENGTHS.get(char); + + if (!len) { + len = char.normalize("NFD").length; + SYLLABLES_LENGTHS.set(char, len); + } + + syllablePositions.push([len, index++]); + } + } + + let normalizationRegex; + + if (syllablePositions.length === 0 && noSyllablesRegExp) { + normalizationRegex = noSyllablesRegExp; + } else if (syllablePositions.length > 0 && withSyllablesRegExp) { + normalizationRegex = withSyllablesRegExp; + } else { const replace = Object.keys(CHARACTERS_TO_NORMALIZE).join(""); - normalizationRegex = new RegExp(`([${replace}])|(\p{M}+(?:-\n)?)|(\S-\n)|(\n)`, "gum"); + const regexp = `([${replace}])|(\p{M}+(?:-\n)?)|(\S-\n)|(\n)`; + + if (syllablePositions.length === 0) { + normalizationRegex = noSyllablesRegExp = new RegExp(regexp + "|(\u0000)", "gum"); + } else { + normalizationRegex = withSyllablesRegExp = new RegExp(regexp + `|(${FIRST_CHAR_SYLLABLES_REG_EXP})`, "gum"); + } }
const rawDiacriticsPositions = []; - let m;
while ((m = DIACRITICS_REG_EXP.exec(text)) !== null) { rawDiacriticsPositions.push([m[0].length, m.index]); @@ -5343,12 +5458,13 @@ function normalize(text) {
let normalized = text.normalize("NFD"); const positions = [[0, 0]]; - let k = 0; + let rawDiacriticsIndex = 0; + let syllableIndex = 0; let shift = 0; let shiftOrigin = 0; let eol = 0; let hasDiacritics = false; - normalized = normalized.replace(normalizationRegex, (match, p1, p2, p3, p4, i) => { + normalized = normalized.replace(normalizationRegex, (match, p1, p2, p3, p4, p5, i) => { i -= shiftOrigin;
if (p1) { @@ -5369,12 +5485,12 @@ function normalize(text) { hasDiacritics = true; let jj = len;
- if (i + eol === rawDiacriticsPositions[k]?.[1]) { - jj -= rawDiacriticsPositions[k][0]; - ++k; + if (i + eol === rawDiacriticsPositions[rawDiacriticsIndex]?.[1]) { + jj -= rawDiacriticsPositions[rawDiacriticsIndex][0]; + ++rawDiacriticsIndex; }
- for (let j = 1; j < jj + 1; j++) { + for (let j = 1; j <= jj; j++) { positions.push([i - 1 - shift + j, shift - j]); }
@@ -5401,11 +5517,27 @@ function normalize(text) { return p3.charAt(0); }
- positions.push([i - shift + 1, shift - 1]); - shift -= 1; - shiftOrigin += 1; - eol += 1; - return " "; + if (p4) { + positions.push([i - shift + 1, shift - 1]); + shift -= 1; + shiftOrigin += 1; + eol += 1; + return " "; + } + + if (i + eol === syllablePositions[syllableIndex]?.[1]) { + const newCharLen = syllablePositions[syllableIndex][0] - 1; + ++syllableIndex; + + for (let j = 1; j <= newCharLen; j++) { + positions.push([i - (shift - j), shift - j]); + } + + shift -= newCharLen; + shiftOrigin += newCharLen; + } + + return p5; }); positions.push([normalized.length, shift]); return [normalized, positions, hasDiacritics]; @@ -5418,13 +5550,13 @@ function getOriginalIndex(diffs, pos, len) {
const start = pos; const end = pos + len; - let i = (0, _ui_utils.binarySearchFirstItem)(diffs, x => x[0] >= start); + let i = (0, _pdfjsLib.binarySearchFirstItem)(diffs, x => x[0] >= start);
if (diffs[i][0] > start) { --i; }
- let j = (0, _ui_utils.binarySearchFirstItem)(diffs, x => x[0] >= end, i); + let j = (0, _pdfjsLib.binarySearchFirstItem)(diffs, x => x[0] >= end, i);
if (diffs[j][0] > end) { --j; @@ -6042,7 +6174,7 @@ class PDFFindController { exports.PDFFindController = PDFFindController;
/***/ }), -/* 16 */ +/* 17 */ /***/ ((__unused_webpack_module, exports) => {
@@ -6137,7 +6269,7 @@ function getCharacterType(charCode) { }
/***/ }), -/* 17 */ +/* 18 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -6151,7 +6283,7 @@ exports.isDestHashesEqual = isDestHashesEqual;
var _ui_utils = __webpack_require__(3);
-var _event_utils = __webpack_require__(4); +var _event_utils = __webpack_require__(5);
const HASH_CHANGE_TIMEOUT = 1000; const POSITION_UPDATED_THRESHOLD = 50; @@ -6746,7 +6878,7 @@ function isDestArraysEqual(firstDest, secondDest) { }
/***/ }), -/* 18 */ +/* 19 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -6756,7 +6888,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.PDFLayerViewer = void 0;
-var _base_tree_viewer = __webpack_require__(12); +var _base_tree_viewer = __webpack_require__(13);
class PDFLayerViewer extends _base_tree_viewer.BaseTreeViewer { constructor(options) { @@ -6866,7 +6998,7 @@ class PDFLayerViewer extends _base_tree_viewer.BaseTreeViewer { const div = document.createElement("div"); div.className = "treeItem"; const element = document.createElement("a"); - div.appendChild(element); + div.append(element);
if (typeof groupId === "object") { hasAnyNesting = true; @@ -6877,7 +7009,7 @@ class PDFLayerViewer extends _base_tree_viewer.BaseTreeViewer {
const itemsDiv = document.createElement("div"); itemsDiv.className = "treeItems"; - div.appendChild(itemsDiv); + div.append(itemsDiv); queue.push({ parent: itemsDiv, groups: groupId.order @@ -6892,17 +7024,15 @@ class PDFLayerViewer extends _base_tree_viewer.BaseTreeViewer { });
input.type = "checkbox"; - input.id = groupId; input.checked = group.visible; const label = document.createElement("label"); - label.setAttribute("for", groupId); label.textContent = this._normalizeTextContent(group.name); - element.appendChild(input); - element.appendChild(label); + label.append(input); + element.append(label); layersCount++; }
- levelData.parent.appendChild(div); + levelData.parent.append(div); } }
@@ -6930,7 +7060,7 @@ class PDFLayerViewer extends _base_tree_viewer.BaseTreeViewer { exports.PDFLayerViewer = PDFLayerViewer;
/***/ }), -/* 19 */ +/* 20 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -6940,9 +7070,9 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.PDFOutlineViewer = void 0;
-var _base_tree_viewer = __webpack_require__(12); +var _base_tree_viewer = __webpack_require__(13);
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
var _ui_utils = __webpack_require__(3);
@@ -7121,7 +7251,7 @@ class PDFOutlineViewer extends _base_tree_viewer.BaseTreeViewer { this._setStyles(element, item);
element.textContent = this._normalizeTextContent(item.title); - div.appendChild(element); + div.append(element);
if (item.items.length > 0) { hasAnyNesting = true; @@ -7130,14 +7260,14 @@ class PDFOutlineViewer extends _base_tree_viewer.BaseTreeViewer {
const itemsDiv = document.createElement("div"); itemsDiv.className = "treeItems"; - div.appendChild(itemsDiv); + div.append(itemsDiv); queue.push({ parent: itemsDiv, items: item.items }); }
- levelData.parent.appendChild(div); + levelData.parent.append(div); outlineCount++; } } @@ -7265,7 +7395,7 @@ class PDFOutlineViewer extends _base_tree_viewer.BaseTreeViewer { exports.PDFOutlineViewer = PDFOutlineViewer;
/***/ }), -/* 20 */ +/* 21 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -7277,6 +7407,8 @@ exports.PDFPresentationMode = void 0;
var _ui_utils = __webpack_require__(3);
+var _pdfjsLib = __webpack_require__(4); + const DELAY_BEFORE_HIDING_CONTROLS = 3000; const ACTIVE_SELECTOR = "pdfPresentationMode"; const CONTROLS_SELECTOR = "pdfPresentationModeControls"; @@ -7320,7 +7452,8 @@ class PDFPresentationMode { pageNumber: pdfViewer.currentPageNumber, scaleValue: pdfViewer.currentScaleValue, scrollMode: pdfViewer.scrollMode, - spreadMode: null + spreadMode: null, + annotationEditorMode: null };
if (pdfViewer.spreadMode !== _ui_utils.SpreadMode.NONE && !(pdfViewer.pageViewsReady && pdfViewer.hasEqualPageSizes)) { @@ -7328,6 +7461,10 @@ class PDFPresentationMode { this.#args.spreadMode = pdfViewer.spreadMode; }
+ if (pdfViewer.annotationEditorMode !== _pdfjsLib.AnnotationEditorType.DISABLE) { + this.#args.annotationEditorMode = pdfViewer.annotationEditorMode; + } + try { await promise; return true; @@ -7394,6 +7531,10 @@ class PDFPresentationMode {
this.pdfViewer.currentPageNumber = this.#args.pageNumber; this.pdfViewer.currentScaleValue = "page-fit"; + + if (this.#args.annotationEditorMode !== null) { + this.pdfViewer.annotationEditorMode = _pdfjsLib.AnnotationEditorType.NONE; + } }, 0); this.#addWindowListeners(); this.#showControls(); @@ -7415,6 +7556,11 @@ class PDFPresentationMode {
this.pdfViewer.currentScaleValue = this.#args.scaleValue; this.pdfViewer.currentPageNumber = pageNumber; + + if (this.#args.annotationEditorMode !== null) { + this.pdfViewer.annotationEditorMode = this.#args.annotationEditorMode; + } + this.#args = null; }, 0); this.#removeWindowListeners(); @@ -7594,7 +7740,7 @@ class PDFPresentationMode { exports.PDFPresentationMode = PDFPresentationMode;
/***/ }), -/* 21 */ +/* 22 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -7604,7 +7750,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.PDFRenderingQueue = void 0;
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
var _ui_utils = __webpack_require__(3);
@@ -7756,7 +7902,7 @@ class PDFRenderingQueue { exports.PDFRenderingQueue = PDFRenderingQueue;
/***/ }), -/* 22 */ +/* 23 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -7768,7 +7914,7 @@ exports.PDFScriptingManager = void 0;
var _ui_utils = __webpack_require__(3);
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
class PDFScriptingManager { constructor({ @@ -8038,7 +8184,7 @@ class PDFScriptingManager { break;
case "SaveAs": - this._eventBus.dispatch("save", { + this._eventBus.dispatch("download", { source: this });
@@ -8095,7 +8241,7 @@ class PDFScriptingManager { const ids = siblings ? [id, ...siblings] : [id];
for (const elementId of ids) { - const element = document.getElementById(elementId); + const element = document.querySelector(`[data-element-id="${elementId}"]`);
if (element) { element.dispatchEvent(new CustomEvent("updatefromsandbox", { @@ -8250,7 +8396,7 @@ class PDFScriptingManager { exports.PDFScriptingManager = PDFScriptingManager;
/***/ }), -/* 23 */ +/* 24 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -8275,6 +8421,7 @@ class PDFSidebar { this.isOpen = false; this.active = _ui_utils.SidebarView.THUMBS; this.isInitialViewSet = false; + this.isInitialEventDispatched = false; this.onToggled = null; this.pdfViewer = pdfViewer; this.pdfThumbnailViewer = pdfThumbnailViewer; @@ -8293,15 +8440,13 @@ class PDFSidebar { this._currentOutlineItemButton = elements.currentOutlineItemButton; this.eventBus = eventBus; this.l10n = l10n; - - this._addEventListeners(); + this.#addEventListeners(); }
reset() { this.isInitialViewSet = false; - - this._hideUINotification(true); - + this.isInitialEventDispatched = false; + this.#hideUINotification(true); this.switchView(_ui_utils.SidebarView.THUMBS); this.outlineButton.disabled = false; this.attachmentsButton.disabled = false; @@ -8313,22 +8458,6 @@ class PDFSidebar { return this.isOpen ? this.active : _ui_utils.SidebarView.NONE; }
- get isThumbnailViewVisible() { - return this.isOpen && this.active === _ui_utils.SidebarView.THUMBS; - } - - get isOutlineViewVisible() { - return this.isOpen && this.active === _ui_utils.SidebarView.OUTLINE; - } - - get isAttachmentsViewVisible() { - return this.isOpen && this.active === _ui_utils.SidebarView.ATTACHMENTS; - } - - get isLayersViewVisible() { - return this.isOpen && this.active === _ui_utils.SidebarView.LAYERS; - } - setInitialView(view = _ui_utils.SidebarView.NONE) { if (this.isInitialViewSet) { return; @@ -8337,21 +8466,18 @@ class PDFSidebar { this.isInitialViewSet = true;
if (view === _ui_utils.SidebarView.NONE || view === _ui_utils.SidebarView.UNKNOWN) { - this._dispatchEvent(); - + this.#dispatchEvent(); return; }
- if (!this._switchView(view, true)) { - this._dispatchEvent(); + this.switchView(view, true); + + if (!this.isInitialEventDispatched) { + this.#dispatchEvent(); } }
switchView(view, forceOpen = false) { - this._switchView(view, forceOpen); - } - - _switchView(view, forceOpen = false) { const isViewChanged = view !== this.active; let shouldForceRendering = false;
@@ -8359,10 +8485,9 @@ class PDFSidebar { case _ui_utils.SidebarView.NONE: if (this.isOpen) { this.close(); - return true; }
- return false; + return;
case _ui_utils.SidebarView.THUMBS: if (this.isOpen && isViewChanged) { @@ -8373,28 +8498,28 @@ class PDFSidebar {
case _ui_utils.SidebarView.OUTLINE: if (this.outlineButton.disabled) { - return false; + return; }
break;
case _ui_utils.SidebarView.ATTACHMENTS: if (this.attachmentsButton.disabled) { - return false; + return; }
break;
case _ui_utils.SidebarView.LAYERS: if (this.layersButton.disabled) { - return false; + return; }
break;
default: - console.error(`PDFSidebar._switchView: "${view}" is not a valid view.`); - return false; + console.error(`PDFSidebar.switchView: "${view}" is not a valid view.`); + return; }
this.active = view; @@ -8419,20 +8544,17 @@ class PDFSidebar {
if (forceOpen && !this.isOpen) { this.open(); - return true; + return; }
if (shouldForceRendering) { - this._updateThumbnailViewer(); - - this._forceRendering(); + this.#updateThumbnailViewer(); + this.#forceRendering(); }
if (isViewChanged) { - this._dispatchEvent(); + this.#dispatchEvent(); } - - return isViewChanged; }
open() { @@ -8446,14 +8568,12 @@ class PDFSidebar { this.outerContainer.classList.add("sidebarMoving", "sidebarOpen");
if (this.active === _ui_utils.SidebarView.THUMBS) { - this._updateThumbnailViewer(); + this.#updateThumbnailViewer(); }
- this._forceRendering(); - - this._dispatchEvent(); - - this._hideUINotification(); + this.#forceRendering(); + this.#dispatchEvent(); + this.#hideUINotification(); }
close() { @@ -8466,10 +8586,8 @@ class PDFSidebar { this.toggleButton.setAttribute("aria-expanded", "false"); this.outerContainer.classList.add("sidebarMoving"); this.outerContainer.classList.remove("sidebarOpen"); - - this._forceRendering(); - - this._dispatchEvent(); + this.#forceRendering(); + this.#dispatchEvent(); }
toggle() { @@ -8480,14 +8598,18 @@ class PDFSidebar { } }
- _dispatchEvent() { + #dispatchEvent() { + if (this.isInitialViewSet && !this.isInitialEventDispatched) { + this.isInitialEventDispatched = true; + } + this.eventBus.dispatch("sidebarviewchanged", { source: this, view: this.visibleView }); }
- _forceRendering() { + #forceRendering() { if (this.onToggled) { this.onToggled(); } else { @@ -8496,7 +8618,7 @@ class PDFSidebar { } }
- _updateThumbnailViewer() { + #updateThumbnailViewer() { const { pdfViewer, pdfThumbnailViewer @@ -8515,7 +8637,7 @@ class PDFSidebar { pdfThumbnailViewer.scrollThumbnailIntoView(pdfViewer.currentPageNumber); }
- _showUINotification() { + #showUINotification() { this.l10n.get("toggle_sidebar_notification2.title").then(msg => { this.toggleButton.title = msg; }); @@ -8525,7 +8647,7 @@ class PDFSidebar { } }
- _hideUINotification(reset = false) { + #hideUINotification(reset = false) { if (this.isOpen || reset) { this.toggleButton.classList.remove(UI_NOTIFICATION_CLASS); } @@ -8537,7 +8659,7 @@ class PDFSidebar { } }
- _addEventListeners() { + #addEventListeners() { this.sidebarContainer.addEventListener("transitionend", evt => { if (evt.target === this.sidebarContainer) { this.outerContainer.classList.remove("sidebarMoving"); @@ -8579,7 +8701,7 @@ class PDFSidebar { button.disabled = !count;
if (count) { - this._showUINotification(); + this.#showUINotification(); } else if (this.active === view) { this.switchView(_ui_utils.SidebarView.THUMBS); } @@ -8605,8 +8727,8 @@ class PDFSidebar { });
this.eventBus._on("presentationmodechanged", evt => { - if (evt.state === _ui_utils.PresentationModeState.NORMAL && this.isThumbnailViewVisible) { - this._updateThumbnailViewer(); + if (evt.state === _ui_utils.PresentationModeState.NORMAL && this.visibleView === _ui_utils.SidebarView.THUMBS) { + this.#updateThumbnailViewer(); } }); } @@ -8616,8 +8738,8 @@ class PDFSidebar { exports.PDFSidebar = PDFSidebar;
/***/ }), -/* 24 */ -/***/ ((__unused_webpack_module, exports) => { +/* 25 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -8625,6 +8747,9 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); exports.PDFSidebarResizer = void 0; + +var _ui_utils = __webpack_require__(3); + const SIDEBAR_WIDTH_VAR = "--sidebar-width"; const SIDEBAR_MIN_WIDTH = 200; const SIDEBAR_RESIZING_CLASS = "sidebarResizing"; @@ -8633,7 +8758,6 @@ class PDFSidebarResizer { constructor(options, eventBus, l10n) { this.isRTL = false; this.sidebarOpen = false; - this.doc = document.documentElement; this._width = null; this._outerContainerWidth = null; this._boundEvents = Object.create(null); @@ -8667,7 +8791,9 @@ class PDFSidebarResizer { }
this._width = width; - this.doc.style.setProperty(SIDEBAR_WIDTH_VAR, `${width}px`); + + _ui_utils.docStyle.setProperty(SIDEBAR_WIDTH_VAR, `${width}px`); + return true; }
@@ -8747,7 +8873,7 @@ class PDFSidebarResizer { exports.PDFSidebarResizer = PDFSidebarResizer;
/***/ }), -/* 25 */ +/* 26 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -8759,7 +8885,7 @@ exports.PDFThumbnailViewer = void 0;
var _ui_utils = __webpack_require__(3);
-var _pdf_thumbnail_view = __webpack_require__(26); +var _pdf_thumbnail_view = __webpack_require__(27);
const THUMBNAIL_SCROLL_MARGIN = -19; const THUMBNAIL_SELECTED_CLASS = "selected"; @@ -8770,12 +8896,14 @@ class PDFThumbnailViewer { eventBus, linkService, renderingQueue, - l10n + l10n, + pageColors }) { this.container = container; this.linkService = linkService; this.renderingQueue = renderingQueue; this.l10n = l10n; + this.pageColors = pageColors || null; this.scroll = (0, _ui_utils.watchScroll)(this.container, this._scrollUpdated.bind(this));
this._resetView(); @@ -8935,7 +9063,8 @@ class PDFThumbnailViewer { linkService: this.linkService, renderingQueue: this.renderingQueue, checkSetImageDisabled, - l10n: this.l10n + l10n: this.l10n, + pageColors: this.pageColors });
this._thumbnails.push(thumbnail); @@ -9029,7 +9158,7 @@ class PDFThumbnailViewer { exports.PDFThumbnailViewer = PDFThumbnailViewer;
/***/ }), -/* 26 */ +/* 27 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -9041,7 +9170,7 @@ exports.TempImageFactory = exports.PDFThumbnailView = void 0;
var _ui_utils = __webpack_require__(3);
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
const DRAW_UPSCALE_FACTOR = 2; const MAX_NUM_SCALING_STEPS = 3; @@ -9055,7 +9184,6 @@ class TempImageFactory { const tempCanvas = this.#tempCanvas ||= document.createElement("canvas"); tempCanvas.width = width; tempCanvas.height = height; - tempCanvas.mozOpaque = true; const ctx = tempCanvas.getContext("2d", { alpha: false }); @@ -9090,7 +9218,8 @@ class PDFThumbnailView { linkService, renderingQueue, checkSetImageDisabled, - l10n + l10n, + pageColors }) { this.id = id; this.renderingId = "thumbnail" + id; @@ -9100,6 +9229,7 @@ class PDFThumbnailView { this.viewport = defaultViewport; this.pdfPageRotate = defaultViewport.rotation; this._optionalContentConfigPromise = optionalContentConfigPromise || null; + this.pageColors = pageColors || null; this.linkService = linkService; this.renderingQueue = renderingQueue; this.renderTask = null; @@ -9140,9 +9270,9 @@ class PDFThumbnailView { ring.style.width = this.canvasWidth + borderAdjustment + "px"; ring.style.height = this.canvasHeight + borderAdjustment + "px"; this.ring = ring; - div.appendChild(ring); - anchor.appendChild(div); - container.appendChild(anchor); + div.append(ring); + anchor.append(div); + container.append(anchor); }
setPdfPage(pdfPage) { @@ -9209,7 +9339,6 @@ class PDFThumbnailView {
_getPageDrawContext(upscaleFactor = 1) { const canvas = document.createElement("canvas"); - canvas.mozOpaque = true; const ctx = canvas.getContext("2d", { alpha: false }); @@ -9243,7 +9372,7 @@ class PDFThumbnailView { image.src = reducedCanvas.toDataURL(); this.image = image; this.div.setAttribute("data-loaded", true); - this.ring.appendChild(image); + this.ring.append(image); reducedCanvas.width = 0; reducedCanvas.height = 0; } @@ -9312,7 +9441,8 @@ class PDFThumbnailView { canvasContext: ctx, transform, viewport: drawViewport, - optionalContentConfigPromise: this._optionalContentConfigPromise + optionalContentConfigPromise: this._optionalContentConfigPromise, + pageColors: this.pageColors }; const renderTask = this.renderTask = pdfPage.render(renderContext); renderTask.onContinue = renderContinueCallback; @@ -9425,7 +9555,7 @@ class PDFThumbnailView { exports.PDFThumbnailView = PDFThumbnailView;
/***/ }), -/* 27 */ +/* 28 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -9437,7 +9567,7 @@ exports.PDFViewer = exports.PDFSinglePageViewer = void 0;
var _ui_utils = __webpack_require__(3);
-var _base_viewer = __webpack_require__(28); +var _base_viewer = __webpack_require__(29);
class PDFViewer extends _base_viewer.BaseViewer {}
@@ -9464,7 +9594,7 @@ class PDFSinglePageViewer extends _base_viewer.BaseViewer { exports.PDFSinglePageViewer = PDFSinglePageViewer;
/***/ }), -/* 28 */ +/* 29 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -9474,27 +9604,31 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.PagesCountLimit = exports.PDFPageViewBuffer = exports.BaseViewer = void 0;
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
var _ui_utils = __webpack_require__(3);
-var _annotation_layer_builder = __webpack_require__(29); +var _annotation_editor_layer_builder = __webpack_require__(30);
-var _l10n_utils = __webpack_require__(30); +var _annotation_layer_builder = __webpack_require__(32); + +var _app_options = __webpack_require__(1);
-var _pdf_page_view = __webpack_require__(31); +var _l10n_utils = __webpack_require__(31);
-var _pdf_rendering_queue = __webpack_require__(21); +var _pdf_page_view = __webpack_require__(33); + +var _pdf_rendering_queue = __webpack_require__(22);
var _pdf_link_service = __webpack_require__(8);
-var _struct_tree_layer_builder = __webpack_require__(32); +var _struct_tree_layer_builder = __webpack_require__(34);
-var _text_highlighter = __webpack_require__(33); +var _text_highlighter = __webpack_require__(35);
-var _text_layer_builder = __webpack_require__(34); +var _text_layer_builder = __webpack_require__(36);
-var _xfa_layer_builder = __webpack_require__(35); +var _xfa_layer_builder = __webpack_require__(37);
const DEFAULT_CACHE_SIZE = 10; const ENABLE_PERMISSIONS_CLASS = "enablePermissions"; @@ -9504,6 +9638,11 @@ const PagesCountLimit = { PAUSE_EAGER_PAGE_INIT: 250 }; exports.PagesCountLimit = PagesCountLimit; +const ANNOTATION_EDITOR_MODE = _app_options.compatibilityParams.annotationEditorMode ?? _pdfjsLib.AnnotationEditorType.DISABLE; + +function isValidAnnotationEditorMode(mode) { + return Object.values(_pdfjsLib.AnnotationEditorType).includes(mode) && mode !== _pdfjsLib.AnnotationEditorType.DISABLE; +}
class PDFPageViewBuffer { #buf = new Set(); @@ -9572,8 +9711,9 @@ exports.PDFPageViewBuffer = PDFPageViewBuffer;
class BaseViewer { #buffer = null; + #annotationEditorMode = _pdfjsLib.AnnotationEditorType.DISABLE; + #annotationEditorUIManager = null; #annotationMode = _pdfjsLib.AnnotationMode.ENABLE_FORMS; - #previousAnnotationMode = null; #enablePermissions = false; #previousContainerHeight = 0; #scrollModePageState = null; @@ -9584,7 +9724,7 @@ class BaseViewer { throw new Error("Cannot initialize BaseViewer."); }
- const viewerVersion = '2.14.290'; + const viewerVersion = '2.15.305';
if (_pdfjsLib.version !== viewerVersion) { throw new Error(`The API version "${_pdfjsLib.version}" does not match the Viewer version "${viewerVersion}".`); @@ -9600,9 +9740,9 @@ class BaseViewer { this.removePageBorders = options.removePageBorders || false; this.textLayerMode = options.textLayerMode ?? _ui_utils.TextLayerMode.ENABLE; this.#annotationMode = options.annotationMode ?? _pdfjsLib.AnnotationMode.ENABLE_FORMS; + this.#annotationEditorMode = options.annotationEditorMode ?? ANNOTATION_EDITOR_MODE; this.imageResourcesPath = options.imageResourcesPath || ""; this.enablePrintAutoRotate = options.enablePrintAutoRotate || false; - this.renderer = options.renderer || _ui_utils.RendererType.CANVAS; this.useOnlyCssZoom = options.useOnlyCssZoom || false; this.maxCanvasPixels = options.maxCanvasPixels; this.l10n = options.l10n || _l10n_utils.NullL10n; @@ -9617,7 +9757,6 @@ class BaseViewer { this.renderingQueue = options.renderingQueue; }
- this._doc = document.documentElement; this.scroll = (0, _ui_utils.watchScroll)(this.container, this._scrollUpdate.bind(this)); this.presentationModeState = _ui_utils.PresentationModeState.UNKNOWN; this._onBeforeDraw = this._onAfterDraw = null; @@ -9629,11 +9768,6 @@ class BaseViewer { }
this.updateContainerHeightCss(); - Promise.resolve().then(() => { - this.eventBus.dispatch("baseviewerinit", { - source: this - }); - }); }
get pagesCount() { @@ -9822,20 +9956,29 @@ class BaseViewer { }
#initializePermissions(permissions) { + const params = { + annotationEditorMode: this.#annotationEditorMode, + annotationMode: this.#annotationMode, + textLayerMode: this.textLayerMode + }; + if (!permissions) { - return; + return params; }
if (!permissions.includes(_pdfjsLib.PermissionFlag.COPY)) { this.viewer.classList.add(ENABLE_PERMISSIONS_CLASS); }
- if (!permissions.includes(_pdfjsLib.PermissionFlag.MODIFY_ANNOTATIONS) && !permissions.includes(_pdfjsLib.PermissionFlag.FILL_INTERACTIVE_FORMS)) { - if (this.#annotationMode === _pdfjsLib.AnnotationMode.ENABLE_FORMS) { - this.#previousAnnotationMode = this.#annotationMode; - this.#annotationMode = _pdfjsLib.AnnotationMode.ENABLE; - } + if (!permissions.includes(_pdfjsLib.PermissionFlag.MODIFY_CONTENTS)) { + params.annotationEditorMode = _pdfjsLib.AnnotationEditorType.DISABLE; + } + + if (!permissions.includes(_pdfjsLib.PermissionFlag.MODIFY_ANNOTATIONS) && !permissions.includes(_pdfjsLib.PermissionFlag.FILL_INTERACTIVE_FORMS) && this.#annotationMode === _pdfjsLib.AnnotationMode.ENABLE_FORMS) { + params.annotationMode = _pdfjsLib.AnnotationMode.ENABLE; } + + return params; }
#onePageRenderedOrForceFetch() { @@ -9876,6 +10019,11 @@ class BaseViewer { if (this._scriptingManager) { this._scriptingManager.setDocument(null); } + + if (this.#annotationEditorUIManager) { + this.#annotationEditorUIManager.destroy(); + this.#annotationEditorUIManager = null; + } }
this.pdfDocument = pdfDocument; @@ -9947,15 +10095,41 @@ class BaseViewer { this._firstPageCapability.resolve(firstPdfPage);
this._optionalContentConfigPromise = optionalContentConfigPromise; - this.#initializePermissions(permissions); + const { + annotationEditorMode, + annotationMode, + textLayerMode + } = this.#initializePermissions(permissions); + + if (annotationEditorMode !== _pdfjsLib.AnnotationEditorType.DISABLE) { + const mode = annotationEditorMode; + + if (isPureXfa) { + console.warn("Warning: XFA-editing is not implemented."); + } else if (isValidAnnotationEditorMode(mode)) { + this.eventBus.dispatch("annotationeditormodechanged", { + source: this, + mode + }); + this.#annotationEditorUIManager = new _pdfjsLib.AnnotationEditorUIManager(this.container, this.eventBus); + + if (mode !== _pdfjsLib.AnnotationEditorType.NONE) { + this.#annotationEditorUIManager.updateMode(mode); + } + } else { + console.error(`Invalid AnnotationEditor mode: ${mode}`); + } + } + const viewerElement = this._scrollMode === _ui_utils.ScrollMode.PAGE ? null : this.viewer; const scale = this.currentScale; const viewport = firstPdfPage.getViewport({ scale: scale * _pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS }); - const textLayerFactory = this.textLayerMode !== _ui_utils.TextLayerMode.DISABLE && !isPureXfa ? this : null; - const annotationLayerFactory = this.#annotationMode !== _pdfjsLib.AnnotationMode.DISABLE ? this : null; + const textLayerFactory = textLayerMode !== _ui_utils.TextLayerMode.DISABLE && !isPureXfa ? this : null; + const annotationLayerFactory = annotationMode !== _pdfjsLib.AnnotationMode.DISABLE ? this : null; const xfaLayerFactory = isPureXfa ? this : null; + const annotationEditorLayerFactory = this.#annotationEditorUIManager ? this : null;
for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) { const pageView = new _pdf_page_view.PDFPageView({ @@ -9967,14 +10141,15 @@ class BaseViewer { optionalContentConfigPromise, renderingQueue: this.renderingQueue, textLayerFactory, - textLayerMode: this.textLayerMode, + textLayerMode, annotationLayerFactory, - annotationMode: this.#annotationMode, + annotationMode, xfaLayerFactory, + annotationEditorLayerFactory, textHighlighterFactory: this, structTreeLayerFactory: this, imageResourcesPath: this.imageResourcesPath, - renderer: this.renderer, + renderer: null, useOnlyCssZoom: this.useOnlyCssZoom, maxCanvasPixels: this.maxCanvasPixels, pageColors: this.pageColors, @@ -10135,11 +10310,6 @@ class BaseViewer {
this.viewer.removeAttribute("lang"); this.viewer.classList.remove(ENABLE_PERMISSIONS_CLASS); - - if (this.#previousAnnotationMode !== null) { - this.#annotationMode = this.#previousAnnotationMode; - this.#previousAnnotationMode = null; - } }
#ensurePageViewVisible() { @@ -10155,7 +10325,7 @@ class BaseViewer {
if (this._spreadMode === _ui_utils.SpreadMode.NONE && !this.isInPresentationMode) { const pageView = this._pages[pageNumber - 1]; - viewer.appendChild(pageView.div); + viewer.append(pageView.div); state.pages.push(pageView); } else { const pageIndexSet = new Set(), @@ -10177,7 +10347,7 @@ class BaseViewer { if (this.isInPresentationMode) { const dummyPage = document.createElement("div"); dummyPage.className = "dummyPage"; - spread.appendChild(dummyPage); + spread.append(dummyPage); }
for (const i of pageIndexSet) { @@ -10187,11 +10357,11 @@ class BaseViewer { continue; }
- spread.appendChild(pageView.div); + spread.append(pageView.div); state.pages.push(pageView); }
- viewer.appendChild(spread); + viewer.append(spread); }
state.scrollDown = pageNumber >= state.previousPageNumber; @@ -10257,7 +10427,7 @@ class BaseViewer { return; }
- this._doc.style.setProperty("--zoom-factor", newScale); + _ui_utils.docStyle.setProperty("--scale-factor", newScale * _pdfjsLib.PixelsPerInch.PDF_TO_CSS_UNITS);
const updateArgs = { scale: newScale @@ -10761,6 +10931,16 @@ class BaseViewer { }); }
+ createAnnotationEditorLayerBuilder(pageDiv, pdfPage, l10n, annotationStorage = null) { + return new _annotation_editor_layer_builder.AnnotationEditorLayerBuilder({ + uiManager: this.#annotationEditorUIManager, + pageDiv, + pdfPage, + annotationStorage: annotationStorage || this.pdfDocument?.annotationStorage, + l10n + }); + } + createXfaLayerBuilder(pageDiv, pdfPage, annotationStorage = null) { return new _xfa_layer_builder.XfaLayerBuilder({ pageDiv, @@ -10942,7 +11122,7 @@ class BaseViewer {
if (this._spreadMode === _ui_utils.SpreadMode.NONE) { for (const pageView of this._pages) { - viewer.appendChild(pageView.div); + viewer.append(pageView.div); } } else { const parity = this._spreadMode - 1; @@ -10952,13 +11132,13 @@ class BaseViewer { if (spread === null) { spread = document.createElement("div"); spread.className = "spread"; - viewer.appendChild(spread); + viewer.append(spread); } else if (i % 2 === parity) { spread = spread.cloneNode(false); - viewer.appendChild(spread); + viewer.append(spread); }
- spread.appendChild(pages[i].div); + spread.append(pages[i].div); } } } @@ -11160,8 +11340,48 @@ class BaseViewer { if (height !== this.#previousContainerHeight) { this.#previousContainerHeight = height;
- this._doc.style.setProperty("--viewer-container-height", `${height}px`); + _ui_utils.docStyle.setProperty("--viewer-container-height", `${height}px`); + } + } + + get annotationEditorMode() { + return this.#annotationEditorUIManager ? this.#annotationEditorMode : _pdfjsLib.AnnotationEditorType.DISABLE; + } + + set annotationEditorMode(mode) { + if (!this.#annotationEditorUIManager) { + throw new Error(`The AnnotationEditor is not enabled.`); + } + + if (this.#annotationEditorMode === mode) { + return; + } + + if (!isValidAnnotationEditorMode(mode)) { + throw new Error(`Invalid AnnotationEditor mode: ${mode}`); } + + if (!this.pdfDocument) { + return; + } + + this.#annotationEditorMode = mode; + this.eventBus.dispatch("annotationeditormodechanged", { + source: this, + mode + }); + this.#annotationEditorUIManager.updateMode(mode); + } + + set annotationEditorParams({ + type, + value + }) { + if (!this.#annotationEditorUIManager) { + throw new Error(`The AnnotationEditor is not enabled.`); + } + + this.#annotationEditorUIManager.updateParams(type, value); }
} @@ -11169,7 +11389,7 @@ class BaseViewer { exports.BaseViewer = BaseViewer;
/***/ }), -/* 29 */ +/* 30 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -11177,89 +11397,71 @@ exports.BaseViewer = BaseViewer; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.AnnotationLayerBuilder = void 0; +exports.AnnotationEditorLayerBuilder = void 0;
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
-var _l10n_utils = __webpack_require__(30); +var _l10n_utils = __webpack_require__(31);
-class AnnotationLayerBuilder { - constructor({ - pageDiv, - pdfPage, - linkService, - downloadManager, - annotationStorage = null, - imageResourcesPath = "", - renderForms = true, - l10n = _l10n_utils.NullL10n, - enableScripting = false, - hasJSActionsPromise = null, - fieldObjectsPromise = null, - mouseState = null, - annotationCanvasMap = null - }) { - this.pageDiv = pageDiv; - this.pdfPage = pdfPage; - this.linkService = linkService; - this.downloadManager = downloadManager; - this.imageResourcesPath = imageResourcesPath; - this.renderForms = renderForms; - this.l10n = l10n; - this.annotationStorage = annotationStorage; - this.enableScripting = enableScripting; - this._hasJSActionsPromise = hasJSActionsPromise; - this._fieldObjectsPromise = fieldObjectsPromise; - this._mouseState = mouseState; - this._annotationCanvasMap = annotationCanvasMap; +class AnnotationEditorLayerBuilder { + #uiManager; + + constructor(options) { + this.pageDiv = options.pageDiv; + this.pdfPage = options.pdfPage; + this.annotationStorage = options.annotationStorage || null; + this.l10n = options.l10n || _l10n_utils.NullL10n; + this.annotationEditorLayer = null; this.div = null; this._cancelled = false; + this.#uiManager = options.uiManager; }
async render(viewport, intent = "display") { - const [annotations, hasJSActions = false, fieldObjects = null] = await Promise.all([this.pdfPage.getAnnotations({ - intent - }), this._hasJSActionsPromise, this._fieldObjectsPromise]); + if (intent !== "display") { + return; + }
- if (this._cancelled || annotations.length === 0) { + if (this._cancelled) { return; }
- const parameters = { - viewport: viewport.clone({ - dontFlip: true - }), - div: this.div, - annotations, - page: this.pdfPage, - imageResourcesPath: this.imageResourcesPath, - renderForms: this.renderForms, - linkService: this.linkService, - downloadManager: this.downloadManager, - annotationStorage: this.annotationStorage, - enableScripting: this.enableScripting, - hasJSActions, - fieldObjects, - mouseState: this._mouseState, - annotationCanvasMap: this._annotationCanvasMap - }; + const clonedViewport = viewport.clone({ + dontFlip: true + });
if (this.div) { - _pdfjsLib.AnnotationLayer.update(parameters); - } else { - this.div = document.createElement("div"); - this.div.className = "annotationLayer"; - this.pageDiv.appendChild(this.div); - parameters.div = this.div; - - _pdfjsLib.AnnotationLayer.render(parameters); - - this.l10n.translate(this.div); + this.annotationEditorLayer.update({ + viewport: clonedViewport + }); + this.show(); + return; } + + this.div = document.createElement("div"); + this.div.className = "annotationEditorLayer"; + this.div.tabIndex = 0; + this.pageDiv.append(this.div); + this.annotationEditorLayer = new _pdfjsLib.AnnotationEditorLayer({ + uiManager: this.#uiManager, + div: this.div, + annotationStorage: this.annotationStorage, + pageIndex: this.pdfPage._pageIndex, + l10n: this.l10n, + viewport: clonedViewport + }); + const parameters = { + viewport: clonedViewport, + div: this.div, + annotations: null, + intent + }; + this.annotationEditorLayer.render(parameters); }
cancel() { this._cancelled = true; + this.destroy(); }
hide() { @@ -11270,12 +11472,30 @@ class AnnotationLayerBuilder { this.div.hidden = true; }
+ show() { + if (!this.div) { + return; + } + + this.div.hidden = false; + } + + destroy() { + if (!this.div) { + return; + } + + this.pageDiv = null; + this.annotationEditorLayer.destroy(); + this.div.remove(); + } + }
-exports.AnnotationLayerBuilder = AnnotationLayerBuilder; +exports.AnnotationEditorLayerBuilder = AnnotationEditorLayerBuilder;
/***/ }), -/* 30 */ +/* 31 */ /***/ ((__unused_webpack_module, exports) => {
@@ -11336,7 +11556,11 @@ const DEFAULT_L10N_STRINGS = { unexpected_response_error: "Unexpected server response.", printing_not_supported: "Warning: Printing is not fully supported by this browser.", printing_not_ready: "Warning: The PDF is not fully loaded for printing.", - web_fonts_disabled: "Web fonts are disabled: unable to use embedded PDF fonts." + web_fonts_disabled: "Web fonts are disabled: unable to use embedded PDF fonts.", + free_text_default_content: "Enter text…", + editor_free_text_aria_label: "FreeText Editor", + editor_ink_aria_label: "Ink Editor", + editor_ink_canvas_aria_label: "User-created image" };
function getL10nFallback(key, args) { @@ -11403,7 +11627,113 @@ const NullL10n = { exports.NullL10n = NullL10n;
/***/ }), -/* 31 */ +/* 32 */ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.AnnotationLayerBuilder = void 0; + +var _pdfjsLib = __webpack_require__(4); + +var _l10n_utils = __webpack_require__(31); + +class AnnotationLayerBuilder { + constructor({ + pageDiv, + pdfPage, + linkService, + downloadManager, + annotationStorage = null, + imageResourcesPath = "", + renderForms = true, + l10n = _l10n_utils.NullL10n, + enableScripting = false, + hasJSActionsPromise = null, + fieldObjectsPromise = null, + mouseState = null, + annotationCanvasMap = null + }) { + this.pageDiv = pageDiv; + this.pdfPage = pdfPage; + this.linkService = linkService; + this.downloadManager = downloadManager; + this.imageResourcesPath = imageResourcesPath; + this.renderForms = renderForms; + this.l10n = l10n; + this.annotationStorage = annotationStorage; + this.enableScripting = enableScripting; + this._hasJSActionsPromise = hasJSActionsPromise; + this._fieldObjectsPromise = fieldObjectsPromise; + this._mouseState = mouseState; + this._annotationCanvasMap = annotationCanvasMap; + this.div = null; + this._cancelled = false; + } + + async render(viewport, intent = "display") { + const [annotations, hasJSActions = false, fieldObjects = null] = await Promise.all([this.pdfPage.getAnnotations({ + intent + }), this._hasJSActionsPromise, this._fieldObjectsPromise]); + + if (this._cancelled || annotations.length === 0) { + return; + } + + const parameters = { + viewport: viewport.clone({ + dontFlip: true + }), + div: this.div, + annotations, + page: this.pdfPage, + imageResourcesPath: this.imageResourcesPath, + renderForms: this.renderForms, + linkService: this.linkService, + downloadManager: this.downloadManager, + annotationStorage: this.annotationStorage, + enableScripting: this.enableScripting, + hasJSActions, + fieldObjects, + mouseState: this._mouseState, + annotationCanvasMap: this._annotationCanvasMap + }; + + if (this.div) { + _pdfjsLib.AnnotationLayer.update(parameters); + } else { + this.div = document.createElement("div"); + this.div.className = "annotationLayer"; + this.pageDiv.append(this.div); + parameters.div = this.div; + + _pdfjsLib.AnnotationLayer.render(parameters); + + this.l10n.translate(this.div); + } + } + + cancel() { + this._cancelled = true; + } + + hide() { + if (!this.div) { + return; + } + + this.div.hidden = true; + } + +} + +exports.AnnotationLayerBuilder = AnnotationLayerBuilder; + +/***/ }), +/* 33 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -11413,13 +11743,13 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.PDFPageView = void 0;
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
var _ui_utils = __webpack_require__(3);
var _app_options = __webpack_require__(1);
-var _l10n_utils = __webpack_require__(30); +var _l10n_utils = __webpack_require__(31);
const MAX_CANVAS_PIXELS = _app_options.compatibilityParams.maxCanvasPixels || 16777216;
@@ -11449,10 +11779,10 @@ class PDFPageView { this.renderingQueue = options.renderingQueue; this.textLayerFactory = options.textLayerFactory; this.annotationLayerFactory = options.annotationLayerFactory; + this.annotationEditorLayerFactory = options.annotationEditorLayerFactory; this.xfaLayerFactory = options.xfaLayerFactory; this.textHighlighter = options.textHighlighterFactory?.createTextHighlighter(this.id - 1, this.eventBus); this.structTreeLayerFactory = options.structTreeLayerFactory; - this.renderer = options.renderer || _ui_utils.RendererType.CANVAS; this.l10n = options.l10n || _l10n_utils.NullL10n; this.paintTask = null; this.paintedViewportMap = new WeakMap(); @@ -11462,6 +11792,7 @@ class PDFPageView { this._isStandalone = !this.renderingQueue?.hasViewer(); this._annotationCanvasMap = null; this.annotationLayer = null; + this.annotationEditorLayer = null; this.textLayer = null; this.zoomLayer = null; this.xfaLayer = null; @@ -11478,7 +11809,7 @@ class PDFPageView { div.setAttribute("aria-label", msg); }); this.div = div; - container?.appendChild(div); + container?.append(div); }
setPdfPage(pdfPage) { @@ -11516,6 +11847,22 @@ class PDFPageView { } }
+ async _renderAnnotationEditorLayer() { + let error = null; + + try { + await this.annotationEditorLayer.render(this.viewport, "display"); + } catch (ex) { + error = ex; + } finally { + this.eventBus.dispatch("annotationeditorlayerrendered", { + source: this, + pageNumber: this.id, + error + }); + } + } + async _renderXfaLayer() { let error = null;
@@ -11568,10 +11915,12 @@ class PDFPageView { reset({ keepZoomLayer = false, keepAnnotationLayer = false, + keepAnnotationEditorLayer = false, keepXfaLayer = false } = {}) { this.cancelRendering({ keepAnnotationLayer, + keepAnnotationEditorLayer, keepXfaLayer }); this.renderingState = _ui_utils.RenderingStates.INITIAL; @@ -11581,6 +11930,7 @@ class PDFPageView { const childNodes = div.childNodes, zoomLayerNode = keepZoomLayer && this.zoomLayer || null, annotationLayerNode = keepAnnotationLayer && this.annotationLayer?.div || null, + annotationEditorLayerNode = keepAnnotationEditorLayer && this.annotationEditorLayer?.div || null, xfaLayerNode = keepXfaLayer && this.xfaLayer?.div || null;
for (let i = childNodes.length - 1; i >= 0; i--) { @@ -11589,6 +11939,7 @@ class PDFPageView { switch (node) { case zoomLayerNode: case annotationLayerNode: + case annotationEditorLayerNode: case xfaLayerNode: continue; } @@ -11602,6 +11953,12 @@ class PDFPageView { this.annotationLayer.hide(); }
+ if (annotationEditorLayerNode) { + this.annotationEditorLayer.hide(); + } else { + this.annotationEditorLayer?.destroy(); + } + if (xfaLayerNode) { this.xfaLayer.hide(); } @@ -11617,11 +11974,6 @@ class PDFPageView { this._resetZoomLayer(); }
- if (this.svg) { - this.paintedViewportMap.delete(this.svg); - delete this.svg; - } - this.loadingIconDiv = document.createElement("div"); this.loadingIconDiv.className = "loadingIcon notVisible";
@@ -11633,7 +11985,7 @@ class PDFPageView { this.l10n.get("loading").then(msg => { this.loadingIconDiv?.setAttribute("aria-label", msg); }); - div.appendChild(this.loadingIconDiv); + div.append(this.loadingIconDiv); }
update({ @@ -11658,26 +12010,7 @@ class PDFPageView { });
if (this._isStandalone) { - const { - style - } = document.documentElement; - style.setProperty("--zoom-factor", this.scale); - } - - if (this.svg) { - this.cssTransform({ - target: this.svg, - redrawAnnotationLayer: true, - redrawXfaLayer: true - }); - this.eventBus.dispatch("pagerendered", { - source: this, - pageNumber: this.id, - cssTransform: true, - timestamp: performance.now(), - error: this._renderError - }); - return; + _ui_utils.docStyle.setProperty("--scale-factor", this.viewport.scale); }
let isScalingRestricted = false; @@ -11695,6 +12028,7 @@ class PDFPageView { this.cssTransform({ target: this.canvas, redrawAnnotationLayer: true, + redrawAnnotationEditorLayer: true, redrawXfaLayer: true }); this.eventBus.dispatch("pagerendered", { @@ -11722,12 +12056,14 @@ class PDFPageView { this.reset({ keepZoomLayer: true, keepAnnotationLayer: true, + keepAnnotationEditorLayer: true, keepXfaLayer: true }); }
cancelRendering({ keepAnnotationLayer = false, + keepAnnotationEditorLayer = false, keepXfaLayer = false } = {}) { if (this.paintTask) { @@ -11748,6 +12084,11 @@ class PDFPageView { this._annotationCanvasMap = null; }
+ if (this.annotationEditorLayer && (!keepAnnotationEditorLayer || !this.annotationEditorLayer.div)) { + this.annotationEditorLayer.cancel(); + this.annotationEditorLayer = null; + } + if (this.xfaLayer && (!keepXfaLayer || !this.xfaLayer.div)) { this.xfaLayer.cancel(); this.xfaLayer = null; @@ -11764,6 +12105,7 @@ class PDFPageView { cssTransform({ target, redrawAnnotationLayer = false, + redrawAnnotationEditorLayer = false, redrawXfaLayer = false }) { const width = this.viewport.width; @@ -11829,6 +12171,10 @@ class PDFPageView { this._renderAnnotationLayer(); }
+ if (redrawAnnotationEditorLayer && this.annotationEditorLayer) { + this._renderAnnotationEditorLayer(); + } + if (redrawXfaLayer && this.xfaLayer) { this._renderXfaLayer(); } @@ -11877,11 +12223,12 @@ class PDFPageView { canvasWrapper.style.width = div.style.width; canvasWrapper.style.height = div.style.height; canvasWrapper.classList.add("canvasWrapper"); + const lastDivBeforeTextDiv = this.annotationLayer?.div || this.annotationEditorLayer?.div;
- if (this.annotationLayer?.div) { - div.insertBefore(canvasWrapper, this.annotationLayer.div); + if (lastDivBeforeTextDiv) { + lastDivBeforeTextDiv.before(canvasWrapper); } else { - div.appendChild(canvasWrapper); + div.append(canvasWrapper); }
let textLayer = null; @@ -11892,10 +12239,10 @@ class PDFPageView { textLayerDiv.style.width = canvasWrapper.style.width; textLayerDiv.style.height = canvasWrapper.style.height;
- if (this.annotationLayer?.div) { - div.insertBefore(textLayerDiv, this.annotationLayer.div); + if (lastDivBeforeTextDiv) { + lastDivBeforeTextDiv.before(textLayerDiv); } else { - div.appendChild(textLayerDiv); + div.append(textLayerDiv); }
textLayer = this.textLayerFactory.createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport, this.textLayerMode === _ui_utils.TextLayerMode.ENABLE_ENHANCE, this.eventBus, this.textHighlighter); @@ -11909,7 +12256,7 @@ class PDFPageView { }
if (this.xfaLayer?.div) { - div.appendChild(this.xfaLayer.div); + div.append(this.xfaLayer.div); }
let renderContinueCallback = null; @@ -11964,7 +12311,7 @@ class PDFPageView { } };
- const paintTask = this.renderer === _ui_utils.RendererType.SVG ? this.paintOnSvg(canvasWrapper) : this.paintOnCanvas(canvasWrapper); + const paintTask = this.paintOnCanvas(canvasWrapper); paintTask.onRenderContinue = renderContinueCallback; this.paintTask = paintTask; const resultPromise = paintTask.promise.then(() => { @@ -11978,7 +12325,13 @@ class PDFPageView { }
if (this.annotationLayer) { - this._renderAnnotationLayer(); + this._renderAnnotationLayer().then(() => { + if (this.annotationEditorLayerFactory) { + this.annotationEditorLayer ||= this.annotationEditorLayerFactory.createAnnotationEditorLayerBuilder(div, pdfPage, this.l10n, null); + + this._renderAnnotationEditorLayer(); + } + }); } }); }, function (reason) { @@ -12018,7 +12371,7 @@ class PDFPageView {
const treeDom = this.structTreeLayer.render(tree); treeDom.classList.add("structTree"); - this.canvas.appendChild(treeDom); + this.canvas.append(treeDom); }); };
@@ -12051,6 +12404,7 @@ class PDFPageView { }; const viewport = this.viewport; const canvas = document.createElement("canvas"); + canvas.setAttribute("role", "presentation"); canvas.hidden = true; let isCanvasHidden = true;
@@ -12061,9 +12415,8 @@ class PDFPageView { } };
- canvasWrapper.appendChild(canvas); + canvasWrapper.append(canvas); this.canvas = canvas; - canvas.mozOpaque = true; const ctx = canvas.getContext("2d", { alpha: false }); @@ -12130,14 +12483,7 @@ class PDFPageView { }
paintOnSvg(wrapper) { - return { - promise: Promise.reject(new Error("SVG rendering is not supported.")), - - onRenderContinue(cont) {}, - - cancel() {} - - }; + throw new Error("Not implemented: paintOnSvg"); }
setPageLabel(label) { @@ -12155,7 +12501,7 @@ class PDFPageView { exports.PDFPageView = PDFPageView;
/***/ }), -/* 32 */ +/* 34 */ /***/ ((__unused_webpack_module, exports) => {
@@ -12261,7 +12607,7 @@ class StructTreeLayerBuilder { this._setAttributes(node.children[0], element); } else { for (const kid of node.children) { - element.appendChild(this._walk(kid)); + element.append(this._walk(kid)); } } } @@ -12274,7 +12620,7 @@ class StructTreeLayerBuilder { exports.StructTreeLayerBuilder = StructTreeLayerBuilder;
/***/ }), -/* 33 */ +/* 35 */ /***/ ((__unused_webpack_module, exports) => {
@@ -12424,8 +12770,8 @@ class TextHighlighter {
if (div.nodeType === Node.TEXT_NODE) { const span = document.createElement("span"); - div.parentNode.insertBefore(span, div); - span.appendChild(div); + div.before(span); + span.append(div); textDivs[divIdx] = span; div = span; } @@ -12436,12 +12782,12 @@ class TextHighlighter { if (className) { const span = document.createElement("span"); span.className = `${className} appended`; - span.appendChild(node); - div.appendChild(span); + span.append(node); + div.append(span); return className.includes("selected") ? span.offsetLeft : 0; }
- div.appendChild(node); + div.append(node); return 0; }
@@ -12547,7 +12893,7 @@ class TextHighlighter { exports.TextHighlighter = TextHighlighter;
/***/ }), -/* 34 */ +/* 36 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -12557,7 +12903,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.TextLayerBuilder = void 0;
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
const EXPAND_DIVS_TIMEOUT = 300;
@@ -12592,7 +12938,7 @@ class TextLayerBuilder { if (!this.enhanceTextSelection) { const endOfContent = document.createElement("div"); endOfContent.className = "endOfContent"; - this.textLayerDiv.appendChild(endOfContent); + this.textLayerDiv.append(endOfContent); }
this.eventBus.dispatch("textlayerrendered", { @@ -12622,7 +12968,7 @@ class TextLayerBuilder { enhanceTextSelection: this.enhanceTextSelection }); this.textLayerRenderTask.promise.then(() => { - this.textLayerDiv.appendChild(textLayerFrag); + this.textLayerDiv.append(textLayerFrag);
this._finishRendering();
@@ -12687,7 +13033,7 @@ class TextLayerBuilder { exports.TextLayerBuilder = TextLayerBuilder;
/***/ }), -/* 35 */ +/* 37 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -12697,7 +13043,7 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.XfaLayerBuilder = void 0;
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
class XfaLayerBuilder { constructor({ @@ -12729,7 +13075,7 @@ class XfaLayerBuilder { intent }; const div = document.createElement("div"); - this.pageDiv.appendChild(div); + this.pageDiv.append(div); parameters.div = div;
const result = _pdfjsLib.XfaLayer.render(parameters); @@ -12760,7 +13106,7 @@ class XfaLayerBuilder { }
this.div = document.createElement("div"); - this.pageDiv.appendChild(this.div); + this.pageDiv.append(this.div); parameters.div = this.div; return _pdfjsLib.XfaLayer.render(parameters); }).catch(error => { @@ -12785,7 +13131,7 @@ class XfaLayerBuilder { exports.XfaLayerBuilder = XfaLayerBuilder;
/***/ }), -/* 36 */ +/* 38 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -12799,7 +13145,7 @@ var _ui_utils = __webpack_require__(3);
var _pdf_cursor_tools = __webpack_require__(6);
-var _base_viewer = __webpack_require__(28); +var _base_viewer = __webpack_require__(29);
class SecondaryToolbar { constructor(options, eventBus) { @@ -13105,7 +13451,7 @@ class SecondaryToolbar { exports.SecondaryToolbar = SecondaryToolbar;
/***/ }), -/* 37 */ +/* 39 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -13117,6 +13463,8 @@ exports.Toolbar = void 0;
var _ui_utils = __webpack_require__(3);
+var _pdfjsLib = __webpack_require__(4); + const PAGE_NUMBER_LOADING_INDICATOR = "visiblePageIsLoading";
class Toolbar { @@ -13148,6 +13496,24 @@ class Toolbar { }, { element: options.viewBookmark, eventName: null + }, { + element: options.editorNoneButton, + eventName: "switchannotationeditormode", + eventDetails: { + mode: _pdfjsLib.AnnotationEditorType.NONE + } + }, { + element: options.editorFreeTextButton, + eventName: "switchannotationeditormode", + eventDetails: { + mode: _pdfjsLib.AnnotationEditorType.FREETEXT + } + }, { + element: options.editorInkButton, + eventName: "switchannotationeditormode", + eventDetails: { + mode: _pdfjsLib.AnnotationEditorType.INK + } }]; this.items = { numPages: options.numPages, @@ -13157,12 +13523,17 @@ class Toolbar { previous: options.previous, next: options.next, zoomIn: options.zoomIn, - zoomOut: options.zoomOut + zoomOut: options.zoomOut, + editorNoneButton: options.editorNoneButton, + editorFreeTextButton: options.editorFreeTextButton, + editorFreeTextParamsToolbar: options.editorFreeTextParamsToolbar, + editorInkButton: options.editorInkButton, + editorInkParamsToolbar: options.editorInkParamsToolbar }; this._wasLocalized = false; this.reset();
- this._bindListeners(); + this._bindListeners(options); }
setPageNumber(pageNumber, pageLabel) { @@ -13197,9 +13568,12 @@ class Toolbar { this._updateUIState(true);
this.updateLoadingIndicatorState(); + this.eventBus.dispatch("toolbarreset", { + source: this + }); }
- _bindListeners() { + _bindListeners(options) { const { pageNumber, scaleSelect @@ -13208,13 +13582,22 @@ class Toolbar {
for (const { element, - eventName + eventName, + eventDetails } of this.buttons) { element.addEventListener("click", evt => { if (eventName !== null) { - this.eventBus.dispatch(eventName, { + const details = { source: this - }); + }; + + if (eventDetails) { + for (const property in eventDetails) { + details[property] = eventDetails[property]; + } + } + + this.eventBus.dispatch(eventName, details); } }); } @@ -13249,11 +13632,60 @@ class Toolbar {
this.eventBus._on("localized", () => { this._wasLocalized = true; - - this._adjustScaleWidth(); + this.#adjustScaleWidth();
this._updateUIState(true); }); + + this.#bindEditorToolsListener(options); + } + + #bindEditorToolsListener({ + editorNoneButton, + editorFreeTextButton, + editorFreeTextParamsToolbar, + editorInkButton, + editorInkParamsToolbar + }) { + const editorModeChanged = (evt, disableButtons = false) => { + const editorButtons = [{ + mode: _pdfjsLib.AnnotationEditorType.NONE, + button: editorNoneButton + }, { + mode: _pdfjsLib.AnnotationEditorType.FREETEXT, + button: editorFreeTextButton, + toolbar: editorFreeTextParamsToolbar + }, { + mode: _pdfjsLib.AnnotationEditorType.INK, + button: editorInkButton, + toolbar: editorInkParamsToolbar + }]; + + for (const { + mode, + button, + toolbar + } of editorButtons) { + const checked = mode === evt.mode; + button.classList.toggle("toggled", checked); + button.setAttribute("aria-checked", checked); + button.disabled = disableButtons; + + if (toolbar) { + toolbar.classList.toggle("hidden", !checked); + } + } + }; + + this.eventBus._on("annotationeditormodechanged", editorModeChanged); + + this.eventBus._on("toolbarreset", evt => { + if (evt.source === this) { + editorModeChanged({ + mode: _pdfjsLib.AnnotationEditorType.NONE + }, true); + } + }); }
_updateUIState(resetNumPages = false) { @@ -13323,25 +13755,26 @@ class Toolbar { }
updateLoadingIndicatorState(loading = false) { - const pageNumberInput = this.items.pageNumber; - pageNumberInput.classList.toggle(PAGE_NUMBER_LOADING_INDICATOR, loading); + const { + pageNumber + } = this.items; + pageNumber.classList.toggle(PAGE_NUMBER_LOADING_INDICATOR, loading); }
- async _adjustScaleWidth() { + async #adjustScaleWidth() { const { items, l10n } = this; const predefinedValuesPromise = Promise.all([l10n.get("page_scale_auto"), l10n.get("page_scale_actual"), l10n.get("page_scale_fit"), l10n.get("page_scale_width")]); + await _ui_utils.animationStarted; const style = getComputedStyle(items.scaleSelect), scaleSelectContainerWidth = parseInt(style.getPropertyValue("--scale-select-container-width"), 10), scaleSelectOverflow = parseInt(style.getPropertyValue("--scale-select-overflow"), 10); - let canvas = document.createElement("canvas"); - canvas.mozOpaque = true; - let ctx = canvas.getContext("2d", { + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d", { alpha: false }); - await _ui_utils.animationStarted; ctx.font = `${style.fontSize} ${style.fontFamily}`; let maxWidth = 0;
@@ -13358,13 +13791,11 @@ class Toolbar { maxWidth += 2 * scaleSelectOverflow;
if (maxWidth > scaleSelectContainerWidth) { - const doc = document.documentElement; - doc.style.setProperty("--scale-select-container-width", `${maxWidth}px`); + _ui_utils.docStyle.setProperty("--scale-select-container-width", `${maxWidth}px`); }
canvas.width = 0; canvas.height = 0; - canvas = ctx = null; }
} @@ -13372,7 +13803,7 @@ class Toolbar { exports.Toolbar = Toolbar;
/***/ }), -/* 38 */ +/* 40 */ /***/ ((__unused_webpack_module, exports) => {
@@ -13467,7 +13898,7 @@ class ViewHistory { exports.ViewHistory = ViewHistory;
/***/ }), -/* 39 */ +/* 41 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -13477,24 +13908,24 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.FirefoxCom = exports.DownloadManager = void 0;
-__webpack_require__(40); +__webpack_require__(42);
var _app = __webpack_require__(2);
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
-var _preferences = __webpack_require__(41); +var _preferences = __webpack_require__(43);
var _ui_utils = __webpack_require__(3);
-var _l10n_utils = __webpack_require__(30); +var _l10n_utils = __webpack_require__(31);
;
class FirefoxCom { static requestSync(action, data) { const request = document.createTextNode(""); - document.documentElement.appendChild(request); + document.documentElement.append(request); const sender = document.createEvent("CustomEvent"); sender.initCustomEvent("pdf.js.message", true, false, { action, @@ -13526,7 +13957,7 @@ class FirefoxCom { }); }
- document.documentElement.appendChild(request); + document.documentElement.append(request); const sender = document.createEvent("CustomEvent"); sender.initCustomEvent("pdf.js.message", true, false, { action, @@ -13557,13 +13988,11 @@ class DownloadManager { const blobUrl = URL.createObjectURL(new Blob([data], { type: contentType })); - FirefoxCom.requestAsync("download", { + FirefoxCom.request("download", { blobUrl, originalUrl: blobUrl, filename, isAttachment: true - }).then(error => { - URL.revokeObjectURL(blobUrl); }); }
@@ -13599,19 +14028,12 @@ class DownloadManager { return false; }
- download(blob, url, filename, sourceEventType = "download") { + download(blob, url, filename) { const blobUrl = URL.createObjectURL(blob); - FirefoxCom.requestAsync("download", { + FirefoxCom.request("download", { blobUrl, originalUrl: url, - filename, - sourceEventType - }).then(error => { - if (error) { - console.error("`ChromeActions.download` failed."); - } - - URL.revokeObjectURL(blobUrl); + filename }); }
@@ -13726,7 +14148,7 @@ class MozL10n { return; }
- _app.PDFViewerApplication.eventBus.dispatch(type, { + _app.PDFViewerApplication.eventBus.dispatch("download", { source: window }); }; @@ -13734,6 +14156,23 @@ class MozL10n { window.addEventListener("save", handleEvent); })();
+(function listenEditingEvent() { + const handleEvent = function ({ + detail + }) { + if (!_app.PDFViewerApplication.initialized) { + return; + } + + _app.PDFViewerApplication.eventBus.dispatch("editingaction", { + source: window, + name: detail.name + }); + }; + + window.addEventListener("editingaction", handleEvent); +})(); + class FirefoxComDataRangeTransport extends _pdfjsLib.PDFDataRangeTransport { requestDataRange(begin, end) { FirefoxCom.request("requestDataRange", { @@ -13847,6 +14286,10 @@ class FirefoxExternalServices extends _app.DefaultExternalServices { return new FirefoxPreferences(); }
+ static updateEditorStates(data) { + FirefoxCom.request("updateEditorStates", data); + } + static createL10n(options) { const mozL10n = document.mozL10n; return new MozL10n(mozL10n); @@ -13891,7 +14334,7 @@ document.mozL10n.setExternalLocalizerServices({ });
/***/ }), -/* 40 */ +/* 42 */ /***/ (() => {
@@ -14014,7 +14457,7 @@ document.mozL10n.setExternalLocalizerServices({ })(void 0);
/***/ }), -/* 41 */ +/* 43 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -14028,6 +14471,7 @@ var _app_options = __webpack_require__(1);
class BasePreferences { #defaults = Object.freeze({ + "annotationEditorMode": -1, "annotationMode": 2, "cursorToolOnLoad": 0, "defaultZoomValue": "", @@ -14038,6 +14482,7 @@ class BasePreferences { "externalLinkTarget": 0, "historyUpdateUrl": false, "ignoreDestinationZoom": false, + "forcePageColors": false, "pageColorsBackground": "Canvas", "pageColorsForeground": "CanvasText", "pdfBugEnabled": false, @@ -14151,7 +14596,7 @@ class BasePreferences { exports.BasePreferences = BasePreferences;
/***/ }), -/* 42 */ +/* 44 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -14161,21 +14606,21 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.FirefoxPrintService = FirefoxPrintService;
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
-var _print_utils = __webpack_require__(43); +var _print_utils = __webpack_require__(45);
var _app = __webpack_require__(2);
-function composePage(pdfDocument, pageNumber, size, printContainer, printResolution, optionalContentConfigPromise) { +function composePage(pdfDocument, pageNumber, size, printContainer, printResolution, optionalContentConfigPromise, printAnnotationStoragePromise) { const canvas = document.createElement("canvas"); const PRINT_UNITS = printResolution / _pdfjsLib.PixelsPerInch.PDF; canvas.width = Math.floor(size.width * PRINT_UNITS); canvas.height = Math.floor(size.height * PRINT_UNITS); const canvasWrapper = document.createElement("div"); canvasWrapper.className = "printedPage"; - canvasWrapper.appendChild(canvas); - printContainer.appendChild(canvasWrapper); + canvasWrapper.append(canvas); + printContainer.append(canvasWrapper); let currentRenderTask = null;
canvas.mozPrintCallback = function (obj) { @@ -14185,7 +14630,7 @@ function composePage(pdfDocument, pageNumber, size, printContainer, printResolut ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.restore(); let thisRenderTask = null; - pdfDocument.getPage(pageNumber).then(function (pdfPage) { + Promise.all([pdfDocument.getPage(pageNumber), printAnnotationStoragePromise]).then(function ([pdfPage, printAnnotationStorage]) { if (currentRenderTask) { currentRenderTask.cancel(); currentRenderTask = null; @@ -14200,7 +14645,8 @@ function composePage(pdfDocument, pageNumber, size, printContainer, printResolut }), intent: "print", annotationMode: _pdfjsLib.AnnotationMode.ENABLE_STORAGE, - optionalContentConfigPromise + optionalContentConfigPromise, + printAnnotationStorage }; currentRenderTask = thisRenderTask = pdfPage.render(renderContext); return thisRenderTask.promise; @@ -14229,12 +14675,13 @@ function composePage(pdfDocument, pageNumber, size, printContainer, printResolut }; }
-function FirefoxPrintService(pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise = null) { +function FirefoxPrintService(pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise = null, printAnnotationStoragePromise = null) { this.pdfDocument = pdfDocument; this.pagesOverview = pagesOverview; this.printContainer = printContainer; this._printResolution = printResolution || 150; this._optionalContentConfigPromise = optionalContentConfigPromise || pdfDocument.getOptionalContentConfig(); + this._printAnnotationStoragePromise = printAnnotationStoragePromise || Promise.resolve(); }
FirefoxPrintService.prototype = { @@ -14244,7 +14691,8 @@ FirefoxPrintService.prototype = { pagesOverview, printContainer, _printResolution, - _optionalContentConfigPromise + _optionalContentConfigPromise, + _printAnnotationStoragePromise } = this; const body = document.querySelector("body"); body.setAttribute("data-pdfjsprinting", true); @@ -14255,7 +14703,7 @@ FirefoxPrintService.prototype = { }
for (let i = 0, ii = pagesOverview.length; i < ii; ++i) { - composePage(pdfDocument, i + 1, pagesOverview[i], printContainer, _printResolution, _optionalContentConfigPromise); + composePage(pdfDocument, i + 1, pagesOverview[i], printContainer, _printResolution, _optionalContentConfigPromise, _printAnnotationStoragePromise); } },
@@ -14273,14 +14721,14 @@ _app.PDFPrintServiceFactory.instance = { return (0, _pdfjsLib.shadow)(this, "supportsPrinting", value); },
- createPrintService(pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise) { - return new FirefoxPrintService(pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise); + createPrintService(pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise, printAnnotationStoragePromise) { + return new FirefoxPrintService(pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise, printAnnotationStoragePromise); }
};
/***/ }), -/* 43 */ +/* 45 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
@@ -14290,11 +14738,11 @@ Object.defineProperty(exports, "__esModule", ({ })); exports.getXfaHtmlForPrinting = getXfaHtmlForPrinting;
-var _pdfjsLib = __webpack_require__(5); +var _pdfjsLib = __webpack_require__(4);
var _pdf_link_service = __webpack_require__(8);
-var _xfa_layer_builder = __webpack_require__(35); +var _xfa_layer_builder = __webpack_require__(37);
function getXfaHtmlForPrinting(printContainer, pdfDocument) { const xfaHtml = pdfDocument.allXfaHtml; @@ -14304,7 +14752,7 @@ function getXfaHtmlForPrinting(printContainer, pdfDocument) { for (const xfaPage of xfaHtml.children) { const page = document.createElement("div"); page.className = "xfaPrintedPage"; - printContainer.appendChild(page); + printContainer.append(page); const builder = new _xfa_layer_builder.XfaLayerBuilder({ pageDiv: page, pdfPage: null, @@ -14373,15 +14821,15 @@ var _app_options = __webpack_require__(1);
var _app = __webpack_require__(2);
-const pdfjsVersion = '2.14.290'; -const pdfjsBuild = '38c82357b'; +const pdfjsVersion = '2.15.305'; +const pdfjsBuild = '2a386eff9'; window.PDFViewerApplication = _app.PDFViewerApplication; window.PDFViewerApplicationOptions = _app_options.AppOptions; ; { - __webpack_require__(39); + __webpack_require__(41);
- __webpack_require__(42); + __webpack_require__(44); } ; ; @@ -14406,6 +14854,11 @@ function getViewerConfiguration() { viewFind: document.getElementById("viewFind"), openFile: null, print: document.getElementById("print"), + editorNoneButton: document.getElementById("editorNone"), + editorFreeTextButton: document.getElementById("editorFreeText"), + editorFreeTextParamsToolbar: document.getElementById("editorFreeTextParamsToolbar"), + editorInkButton: document.getElementById("editorInk"), + editorInkParamsToolbar: document.getElementById("editorInkParamsToolbar"), presentationModeButton: document.getElementById("presentationMode"), download: document.getElementById("download"), viewBookmark: document.getElementById("viewBookmark") @@ -14492,6 +14945,12 @@ function getViewerConfiguration() { linearized: document.getElementById("linearizedField") } }, + annotationEditorParams: { + editorFreeTextFontSize: document.getElementById("editorFreeTextFontSize"), + editorFreeTextColor: document.getElementById("editorFreeTextColor"), + editorInkColor: document.getElementById("editorInkColor"), + editorInkThickness: document.getElementById("editorInkThickness") + }, errorWrapper, printContainer: document.getElementById("printContainer"), openFileInput: null, diff --git a/toolkit/components/pdfjs/moz.yaml b/toolkit/components/pdfjs/moz.yaml index 0adf830d2dad3..9742816da0b0f 100644 --- a/toolkit/components/pdfjs/moz.yaml +++ b/toolkit/components/pdfjs/moz.yaml @@ -20,8 +20,8 @@ origin:
# Human-readable identifier for this version/release # Generally "version NNN", "tag SSS", "bookmark SSS" - release: commit 38c82357b247199b11fb573d0a3d4201347a47fc - revision: 38c82357b247199b11fb573d0a3d4201347a47fc + release: commit bf000687313b08924186f9f35a604f8cce27bd1d + revision: bf000687313b08924186f9f35a604f8cce27bd1d
# The package's license, where possible using the mnemonic from # https://spdx.org/licenses/ diff --git a/toolkit/components/pdfjs/test/browser_pdfjs_js.js b/toolkit/components/pdfjs/test/browser_pdfjs_js.js index 9e260a2560a41..19500a5b1f38a 100644 --- a/toolkit/components/pdfjs/test/browser_pdfjs_js.js +++ b/toolkit/components/pdfjs/test/browser_pdfjs_js.js @@ -36,7 +36,7 @@ add_task(async function test_js_sandbox() { const button = document.querySelector("[data-annotation-id='16R'] a"); button.dispatchEvent(new content.Event("click"));
- const text = document.querySelector("#\31 5R"); + const text = document.querySelector(`[data-element-id="15R"]`);
is(text.value, "test", "Text field must containt 'test' string");