From bb302dd99337ed4705f2b5d4000091d844366b78 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Mon, 23 Sep 2024 10:22:39 +0200 Subject: [PATCH] [api-minor] Pass `CanvasFactory`/`FilterFactory`, rather than instances, to `getDocument` This unifies the various factory-options, since it's consistent with `CMapReaderFactory`/`StandardFontDataFactory`, and ensures that any needed parameters will always be consistently provided when creating `CanvasFactory`/`FilterFactory`-instances. As shown in the modified example this may simplify some custom implementations, since we now provide the ability to access the `CanvasFactory`-instance used with a particular `getDocument`-invocation. --- examples/node/pdf2png/pdf2png.mjs | 36 +--------------------------- src/display/api.js | 40 +++++++++++++++++++++++-------- src/display/base_factory.js | 2 +- src/display/display_utils.js | 4 ++-- test/unit/api_spec.js | 2 +- test/unit/custom_spec.js | 2 +- test/unit/display_utils_spec.js | 2 +- 7 files changed, 37 insertions(+), 51 deletions(-) diff --git a/examples/node/pdf2png/pdf2png.mjs b/examples/node/pdf2png/pdf2png.mjs index 3dfd9b089aa40..359fc807bea97 100644 --- a/examples/node/pdf2png/pdf2png.mjs +++ b/examples/node/pdf2png/pdf2png.mjs @@ -13,41 +13,9 @@ * limitations under the License. */ -import { strict as assert } from "assert"; -import Canvas from "canvas"; import fs from "fs"; import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs"; -class NodeCanvasFactory { - create(width, height) { - assert(width > 0 && height > 0, "Invalid canvas size"); - const canvas = Canvas.createCanvas(width, height); - const context = canvas.getContext("2d"); - return { - canvas, - context, - }; - } - - reset(canvasAndContext, width, height) { - assert(canvasAndContext.canvas, "Canvas is not specified"); - assert(width > 0 && height > 0, "Invalid canvas size"); - canvasAndContext.canvas.width = width; - canvasAndContext.canvas.height = height; - } - - destroy(canvasAndContext) { - assert(canvasAndContext.canvas, "Canvas is not specified"); - - // Zeroing the width and height cause Firefox to release graphics - // resources immediately, which can greatly reduce memory consumption. - canvasAndContext.canvas.width = 0; - canvasAndContext.canvas.height = 0; - canvasAndContext.canvas = null; - canvasAndContext.context = null; - } -} - // Some PDFs need external cmaps. const CMAP_URL = "../../../node_modules/pdfjs-dist/cmaps/"; const CMAP_PACKED = true; @@ -56,8 +24,6 @@ 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,7 +35,6 @@ const loadingTask = getDocument({ cMapUrl: CMAP_URL, cMapPacked: CMAP_PACKED, standardFontDataUrl: STANDARD_FONT_DATA_URL, - canvasFactory, }); try { @@ -78,6 +43,7 @@ try { // Get the first page. const page = await pdfDocument.getPage(1); // Render the page on a Node canvas with 100% scale. + const canvasFactory = pdfDocument.canvasFactory; const viewport = page.getViewport({ scale: 1.0 }); const canvasAndContext = canvasFactory.create( viewport.width, diff --git a/src/display/api.js b/src/display/api.js index 5b65e50d663df..8e7a3c4b79040 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -43,6 +43,7 @@ import { SerializableEmpty, } from "./annotation_storage.js"; import { + deprecated, DOMCanvasFactory, DOMCMapReaderFactory, DOMFilterFactory, @@ -209,10 +210,11 @@ const DefaultStandardFontDataFactory = * 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()}. - * @property {Object} [filterFactory] - A factory instance that will be used - * to create SVG filters when rendering some images on the main canvas. + * @property {Object} [CanvasFactory] - The factory that will be used when + * creating canvases. The default value is {DOMCanvasFactory}. + * @property {Object} [FilterFactory] - The factory that will be used to + * create SVG filters when rendering some images on the main canvas. + * The default value is {DOMFilterFactory}. * @property {boolean} [enableHWA] - Enables hardware acceleration for * rendering. The default value is `false`. */ @@ -291,6 +293,8 @@ function getDocument(src = {}) { const disableStream = src.disableStream === true; const disableAutoFetch = src.disableAutoFetch === true; const pdfBug = src.pdfBug === true; + const CanvasFactory = src.CanvasFactory || DefaultCanvasFactory; + const FilterFactory = src.FilterFactory || DefaultFilterFactory; const enableHWA = src.enableHWA === true; // Parameters whose default values depend on other parameters. @@ -309,10 +313,19 @@ function getDocument(src = {}) { standardFontDataUrl && isValidFetchUrl(cMapUrl, document.baseURI) && isValidFetchUrl(standardFontDataUrl, document.baseURI)); - const canvasFactory = - src.canvasFactory || new DefaultCanvasFactory({ ownerDocument, enableHWA }); - const filterFactory = - src.filterFactory || new DefaultFilterFactory({ docId, ownerDocument }); + + if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { + if (src.canvasFactory) { + deprecated( + "`canvasFactory`-instance option, please use `CanvasFactory` instead." + ); + } + if (src.filterFactory) { + deprecated( + "`filterFactory`-instance option, please use `FilterFactory` instead." + ); + } + } // Parameters only intended for development/testing purposes. const styleElement = @@ -326,8 +339,8 @@ function getDocument(src = {}) { // Ensure that the various factories can be initialized, when necessary, // since the user may provide *custom* ones. const transportFactory = { - canvasFactory, - filterFactory, + canvasFactory: new CanvasFactory({ ownerDocument, enableHWA }), + filterFactory: new FilterFactory({ docId, ownerDocument }), }; if (!useWorkerFetch) { transportFactory.cMapReaderFactory = new CMapReaderFactory({ @@ -781,6 +794,13 @@ class PDFDocumentProxy { return this._transport.annotationStorage; } + /** + * @type {Object} The canvas factory instance. + */ + get canvasFactory() { + return this._transport.canvasFactory; + } + /** * @type {Object} The filter factory instance. */ diff --git a/src/display/base_factory.js b/src/display/base_factory.js index 5f5b2b0e9d338..e6773daa90553 100644 --- a/src/display/base_factory.js +++ b/src/display/base_factory.js @@ -51,7 +51,7 @@ class BaseFilterFactory { class BaseCanvasFactory { #enableHWA = false; - constructor({ enableHWA = false } = {}) { + constructor({ enableHWA = false }) { if ( (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) && this.constructor === BaseCanvasFactory diff --git a/src/display/display_utils.js b/src/display/display_utils.js index f88dd3041baee..ae6172632ab80 100644 --- a/src/display/display_utils.js +++ b/src/display/display_utils.js @@ -63,7 +63,7 @@ class DOMFilterFactory extends BaseFilterFactory { #id = 0; - constructor({ docId, ownerDocument = globalThis.document } = {}) { + constructor({ docId, ownerDocument = globalThis.document }) { super(); this.#docId = docId; this.#document = ownerDocument; @@ -496,7 +496,7 @@ class DOMFilterFactory extends BaseFilterFactory { } class DOMCanvasFactory extends BaseCanvasFactory { - constructor({ ownerDocument = globalThis.document, enableHWA = false } = {}) { + constructor({ ownerDocument = globalThis.document, enableHWA = false }) { super({ enableHWA }); this._document = ownerDocument; } diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index dc5140fd1e692..3a792c7151d96 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -69,7 +69,7 @@ describe("api", function () { let tempServer = null; beforeAll(function () { - CanvasFactory = new DefaultCanvasFactory(); + CanvasFactory = new DefaultCanvasFactory({}); if (isNodeJS) { tempServer = createTemporaryNodeServer(); diff --git a/test/unit/custom_spec.js b/test/unit/custom_spec.js index ae33736ec911e..052c60d641c41 100644 --- a/test/unit/custom_spec.js +++ b/test/unit/custom_spec.js @@ -35,7 +35,7 @@ describe("custom canvas rendering", function () { let page; beforeAll(async function () { - CanvasFactory = new DefaultCanvasFactory(); + CanvasFactory = new DefaultCanvasFactory({}); loadingTask = getDocument(transparentGetDocumentParams); const doc = await loadingTask.promise; diff --git a/test/unit/display_utils_spec.js b/test/unit/display_utils_spec.js index 1d684bfd7b9de..e152d5d9c5677 100644 --- a/test/unit/display_utils_spec.js +++ b/test/unit/display_utils_spec.js @@ -28,7 +28,7 @@ describe("display_utils", function () { let canvasFactory; beforeAll(function () { - canvasFactory = new DOMCanvasFactory(); + canvasFactory = new DOMCanvasFactory({}); }); afterAll(function () {