From f42a2e845110c110111c5e40a7f7e156990bbbf5 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Wed, 1 Mar 2023 09:07:16 +0100 Subject: [PATCH] [api-minor] Move the `canvasFactory` option into `getDocument` Rather than repeatedly initializing a `canvasFactory`-instance for every page, move it to the document-level instead. *Please note:* This patch is written using the GitHub UI, since I'm currently without a dev machine, so hopefully it works correctly. --- examples/node/pdf2png/pdf2png.js | 5 ++-- src/display/api.js | 51 +++++++++++++++++++------------- test/unit/api_spec.js | 10 ------- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/examples/node/pdf2png/pdf2png.js b/examples/node/pdf2png/pdf2png.js index cc66cfcf1..f0d0608ed 100644 --- a/examples/node/pdf2png/pdf2png.js +++ b/examples/node/pdf2png/pdf2png.js @@ -58,6 +58,8 @@ const CMAP_PACKED = true; const STANDARD_FONT_DATA_URL = "../../../node_modules/pdfjs-dist/standard_fonts/"; +const canvasFactory = new NodeCanvasFactory(); + // Loading file from file system into typed array. const pdfPath = process.argv[2] || "../../../web/compressed.tracemonkey-pldi-09.pdf"; @@ -69,6 +71,7 @@ const loadingTask = pdfjsLib.getDocument({ cMapUrl: CMAP_URL, cMapPacked: CMAP_PACKED, standardFontDataUrl: STANDARD_FONT_DATA_URL, + canvasFactory, }); (async function () { @@ -79,7 +82,6 @@ const loadingTask = pdfjsLib.getDocument({ const page = await pdfDocument.getPage(1); // Render the page on a Node canvas with 100% scale. const viewport = page.getViewport({ scale: 1.0 }); - const canvasFactory = new NodeCanvasFactory(); const canvasAndContext = canvasFactory.create( viewport.width, viewport.height @@ -87,7 +89,6 @@ const loadingTask = pdfjsLib.getDocument({ const renderContext = { canvasContext: canvasAndContext.context, viewport, - canvasFactory, }; const renderTask = page.render(renderContext); diff --git a/src/display/api.js b/src/display/api.js index 4d07cb27f..a13d9d63b 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -230,6 +230,8 @@ if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")) { * disabling of pre-fetching to work correctly. * @property {boolean} [pdfBug] - Enables special hooks for debugging PDF.js * (see `web/debugger.js`). The default value is `false`. + * @property {Object} [canvasFactory] - The factory instance that will be used + * when creating canvases. The default value is {new DOMCanvasFactory()}. */ /** @@ -337,6 +339,8 @@ function getDocument(src) { StandardFontDataFactory === DOMStandardFontDataFactory && isValidFetchUrl(cMapUrl, document.baseURI) && isValidFetchUrl(standardFontDataUrl, document.baseURI)); + const canvasFactory = + src.canvasFactory || new DefaultCanvasFactory({ ownerDocument }); // Parameters only intended for development/testing purposes. const styleElement = @@ -349,17 +353,18 @@ function getDocument(src) { // Ensure that the various factories can be initialized, when necessary, // since the user may provide *custom* ones. - const transportFactory = useWorkerFetch - ? null - : { - cMapReaderFactory: new CMapReaderFactory({ - baseUrl: cMapUrl, - isCompressed: cMapPacked, - }), - standardFontDataFactory: new StandardFontDataFactory({ - baseUrl: standardFontDataUrl, - }), - }; + const transportFactory = { + canvasFactory, + }; + if (!useWorkerFetch) { + transportFactory.cMapReaderFactory = new CMapReaderFactory({ + baseUrl: cMapUrl, + isCompressed: cMapPacked, + }); + transportFactory.standardFontDataFactory = new StandardFontDataFactory({ + baseUrl: standardFontDataUrl, + }); + } if (!worker) { const workerParams = { @@ -1280,10 +1285,9 @@ class PDFDocumentProxy { * Proxy to a `PDFPage` in the worker thread. */ class PDFPageProxy { - constructor(pageIndex, pageInfo, transport, ownerDocument, pdfBug = false) { + constructor(pageIndex, pageInfo, transport, pdfBug = false) { this._pageIndex = pageIndex; this._pageInfo = pageInfo; - this._ownerDocument = ownerDocument; this._transport = transport; this._stats = pdfBug ? new StatTimer() : null; this._pdfBug = pdfBug; @@ -1414,6 +1418,16 @@ class PDFPageProxy { pageColors = null, printAnnotationStorage = null, }) { + if ( + (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) && + canvasFactory + ) { + deprecated( + "render no longer accepts the `canvasFactory`-option, " + + "please pass it to the `getDocument`-function instead." + ); + } + this._stats?.time("Overall"); const intentArgs = this._transport.getRenderingIntent( @@ -1441,9 +1455,6 @@ class PDFPageProxy { intentState.streamReaderCancelTimeout = null; } - const canvasFactoryInstance = - canvasFactory || - new DefaultCanvasFactory({ ownerDocument: this._ownerDocument }); const intentPrint = !!( intentArgs.renderingIntent & RenderingIntentFlag.PRINT ); @@ -1502,7 +1513,7 @@ class PDFPageProxy { annotationCanvasMap, operatorList: intentState.operatorList, pageIndex: this._pageIndex, - canvasFactory: canvasFactoryInstance, + canvasFactory: canvasFactory || this._transport.canvasFactory, useRequestAnimationFrame: !intentPrint, pdfBug: this._pdfBug, pageColors, @@ -2345,8 +2356,9 @@ class WorkerTransport { }); this._params = params; - this.cMapReaderFactory = factory?.cMapReaderFactory; - this.standardFontDataFactory = factory?.standardFontDataFactory; + this.canvasFactory = factory.canvasFactory; + this.cMapReaderFactory = factory.cMapReaderFactory; + this.standardFontDataFactory = factory.standardFontDataFactory; this.destroyed = false; this.destroyCapability = null; @@ -2905,7 +2917,6 @@ class WorkerTransport { pageIndex, pageInfo, this, - this._params.ownerDocument, this._params.pdfBug ); this.#pageCache.set(pageIndex, page); diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index 00d428749..52ae70450 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -2880,7 +2880,6 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`) ); const renderTask = pdfPage.render({ canvasContext: canvasAndCtx.context, - canvasFactory: CanvasFactory, viewport, }); expect(renderTask instanceof RenderTask).toEqual(true); @@ -2916,7 +2915,6 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`) ); const renderTask = page.render({ canvasContext: canvasAndCtx.context, - canvasFactory: CanvasFactory, viewport, }); expect(renderTask instanceof RenderTask).toEqual(true); @@ -2948,7 +2946,6 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`) ); const renderTask = page.render({ canvasContext: canvasAndCtx.context, - canvasFactory: CanvasFactory, viewport, }); expect(renderTask instanceof RenderTask).toEqual(true); @@ -2966,7 +2963,6 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`) const reRenderTask = page.render({ canvasContext: canvasAndCtx.context, - canvasFactory: CanvasFactory, viewport, }); expect(reRenderTask instanceof RenderTask).toEqual(true); @@ -2990,7 +2986,6 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`) ); const renderTask1 = page.render({ canvasContext: canvasAndCtx.context, - canvasFactory: CanvasFactory, viewport, optionalContentConfigPromise, }); @@ -2998,7 +2993,6 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`) const renderTask2 = page.render({ canvasContext: canvasAndCtx.context, - canvasFactory: CanvasFactory, viewport, optionalContentConfigPromise, }); @@ -3033,7 +3027,6 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`) ); const renderTask = pdfPage.render({ canvasContext: canvasAndCtx.context, - canvasFactory: CanvasFactory, viewport, }); expect(renderTask instanceof RenderTask).toEqual(true); @@ -3064,7 +3057,6 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`) ); const renderTask = pdfPage.render({ canvasContext: canvasAndCtx.context, - canvasFactory: CanvasFactory, viewport, }); expect(renderTask instanceof RenderTask).toEqual(true); @@ -3166,7 +3158,6 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`) ); const renderTask = pdfPage.render({ canvasContext: canvasAndCtx.context, - canvasFactory: CanvasFactory, viewport, intent: "print", annotationMode: AnnotationMode.ENABLE_STORAGE, @@ -3256,7 +3247,6 @@ Caron Broadcasting, Inc., an Ohio corporation (“Lessee”).`) ); const renderTask = page.render({ canvasContext: canvasAndCtx.context, - canvasFactory: CanvasFactory, viewport, }); await renderTask.promise;