diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 3178b0f11..53c8282a3 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -84,6 +84,7 @@ const DefaultPartialEvaluatorOptions = Object.freeze({ disableFontFace: false, ignoreErrors: false, isEvalSupported: true, + isOffscreenCanvasSupported: true, fontExtraProperties: false, useSystemFonts: true, cMapUrl: null, @@ -652,6 +653,7 @@ class PartialEvaluator { imageIsFromDecodeStream: image instanceof DecodeStream, inverseDecode: !!decode && decode[0] > 0, interpolate, + isOffscreenCanvasSupported: this.options.isOffscreenCanvasSupported, }); if (imgData.isSingleOpaquePixel) { diff --git a/src/core/image.js b/src/core/image.js index f16f189de..14f9699a2 100644 --- a/src/core/image.js +++ b/src/core/image.js @@ -356,6 +356,7 @@ class PDFImage { imageIsFromDecodeStream, inverseDecode, interpolate, + isOffscreenCanvasSupported = true, }) { const isSingleOpaquePixel = width === 1 && @@ -366,7 +367,7 @@ class PDFImage { return { isSingleOpaquePixel }; } - if (FeatureTest.isOffscreenCanvasSupported) { + if (isOffscreenCanvasSupported && FeatureTest.isOffscreenCanvasSupported) { const canvas = new OffscreenCanvas(width, height); const ctx = canvas.getContext("2d"); const imgData = ctx.createImageData(width, height); diff --git a/src/core/worker.js b/src/core/worker.js index ae5221f06..0749e1541 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -410,6 +410,7 @@ class WorkerMessageHandler { disableFontFace: data.disableFontFace, ignoreErrors: data.ignoreErrors, isEvalSupported: data.isEvalSupported, + isOffscreenCanvasSupported: data.isOffscreenCanvasSupported, fontExtraProperties: data.fontExtraProperties, useSystemFonts: data.useSystemFonts, cMapUrl: data.cMapUrl, diff --git a/src/display/api.js b/src/display/api.js index a0b2156c9..b7914fe10 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -189,6 +189,10 @@ function setPDFNetworkStreamFactory(pdfNetworkStreamFactory) { * @property {boolean} [isEvalSupported] - Determines if we can evaluate strings * as JavaScript. Primarily used to improve performance of font rendering, and * when parsing PDF functions. The default value is `true`. + * @property {boolean} [isOffscreenCanvasSupported] - Determines if we can use + * `OffscreenCanvas` in the worker. Primarily used to improve performance of + * image conversion/rendering. + * The default value is `true` in web environments and `false` in Node.js. * @property {boolean} [disableFontFace] - By default fonts are converted to * OpenType fonts and loaded via the Font Loading API or `@font-face` rules. * If disabled, fonts will be rendered using a built-in font renderer that @@ -365,6 +369,9 @@ function getDocument(src) { if (typeof params.isEvalSupported !== "boolean") { params.isEvalSupported = true; } + if (typeof params.isOffscreenCanvasSupported !== "boolean") { + params.isOffscreenCanvasSupported = !isNodeJS; + } if (typeof params.disableFontFace !== "boolean") { params.disableFontFace = isNodeJS; } @@ -516,6 +523,7 @@ async function _fetchDocument(worker, source, pdfDataRangeTransport, docId) { docBaseUrl: source.docBaseUrl, ignoreErrors: source.ignoreErrors, isEvalSupported: source.isEvalSupported, + isOffscreenCanvasSupported: source.isOffscreenCanvasSupported, fontExtraProperties: source.fontExtraProperties, enableXfa: source.enableXfa, useSystemFonts: source.useSystemFonts, diff --git a/src/display/svg.js b/src/display/svg.js index 8cd2e04a6..0373c7263 100644 --- a/src/display/svg.js +++ b/src/display/svg.js @@ -495,6 +495,15 @@ if ( } } + getObject(data, fallback = null) { + if (typeof data === "string") { + return data.startsWith("g_") + ? this.commonObjs.get(data) + : this.objs.get(data); + } + return fallback; + } + save() { this.transformStack.push(this.transformMatrix); const old = this.current; @@ -1586,9 +1595,7 @@ if ( } paintImageXObject(objId) { - const imgData = objId.startsWith("g_") - ? this.commonObjs.get(objId) - : this.objs.get(objId); + const imgData = this.getObject(objId); if (!imgData) { warn(`Dependent image with object ID ${objId} is not ready yet`); return; @@ -1627,7 +1634,15 @@ if ( } } - paintImageMaskXObject(imgData) { + paintImageMaskXObject(img) { + const imgData = this.getObject(img.data, img); + if (imgData.bitmap) { + warn( + "paintImageMaskXObject: ImageBitmap support is not implemented, " + + "ensure that the `isOffscreenCanvasSupported` API parameter is disabled." + ); + return; + } const current = this.current; const width = imgData.width; const height = imgData.height; diff --git a/web/app_options.js b/web/app_options.js index 0f09c490b..de96674a2 100644 --- a/web/app_options.js +++ b/web/app_options.js @@ -242,6 +242,11 @@ const defaultOptions = { value: true, kind: OptionKind.API, }, + isOffscreenCanvasSupported: { + /** @type {boolean} */ + value: true, + kind: OptionKind.API, + }, maxImageSize: { /** @type {number} */ value: -1,