diff --git a/src/display/base_factory.js b/src/display/base_factory.js new file mode 100644 index 000000000..fa880c155 --- /dev/null +++ b/src/display/base_factory.js @@ -0,0 +1,129 @@ +/* Copyright 2015 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CMapCompressionType, unreachable } from "../shared/util.js"; + +class BaseCanvasFactory { + constructor() { + if (this.constructor === BaseCanvasFactory) { + unreachable("Cannot initialize BaseCanvasFactory."); + } + } + + create(width, height) { + unreachable("Abstract method `create` called."); + } + + reset(canvasAndContext, width, height) { + if (!canvasAndContext.canvas) { + throw new Error("Canvas is not specified"); + } + if (width <= 0 || height <= 0) { + throw new Error("Invalid canvas size"); + } + canvasAndContext.canvas.width = width; + canvasAndContext.canvas.height = height; + } + + destroy(canvasAndContext) { + if (!canvasAndContext.canvas) { + throw new Error("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; + } +} + +class BaseCMapReaderFactory { + constructor({ baseUrl = null, isCompressed = false }) { + if (this.constructor === BaseCMapReaderFactory) { + unreachable("Cannot initialize BaseCMapReaderFactory."); + } + this.baseUrl = baseUrl; + this.isCompressed = isCompressed; + } + + 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 + ? CMapCompressionType.BINARY + : CMapCompressionType.NONE; + + return this._fetchData(url, compressionType).catch(reason => { + throw new Error( + `Unable to load ${this.isCompressed ? "binary " : ""}CMap at: ${url}` + ); + }); + } + + /** + * @private + */ + _fetchData(url, compressionType) { + unreachable("Abstract method `_fetchData` called."); + } +} + +class BaseStandardFontDataFactory { + constructor({ baseUrl = null }) { + if (this.constructor === BaseStandardFontDataFactory) { + unreachable("Cannot initialize BaseStandardFontDataFactory."); + } + this.baseUrl = baseUrl; + } + + 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.' + ); + } + if (!filename) { + throw new Error("Font filename must be specified."); + } + const url = this.baseUrl + filename + ".pfb"; + + return this._fetchData(url).catch(reason => { + throw new Error(`Unable to load font data at: ${url}`); + }); + } + + /** + * @private + */ + _fetchData(url) { + unreachable("Abstract method `_fetchData` called."); + } +} + +export { + BaseCanvasFactory, + BaseCMapReaderFactory, + BaseStandardFontDataFactory, +}; diff --git a/src/display/display_utils.js b/src/display/display_utils.js index 06b6f6e67..72f25810e 100644 --- a/src/display/display_utils.js +++ b/src/display/display_utils.js @@ -16,53 +16,21 @@ import { assert, BaseException, - CMapCompressionType, isString, removeNullCharacters, stringToBytes, - unreachable, Util, warn, } from "../shared/util.js"; +import { + BaseCanvasFactory, + BaseCMapReaderFactory, + BaseStandardFontDataFactory, +} from "./base_factory.js"; const DEFAULT_LINK_REL = "noopener noreferrer nofollow"; const SVG_NS = "http://www.w3.org/2000/svg"; -class BaseCanvasFactory { - constructor() { - if (this.constructor === BaseCanvasFactory) { - unreachable("Cannot initialize BaseCanvasFactory."); - } - } - - create(width, height) { - unreachable("Abstract method `create` called."); - } - - reset(canvasAndContext, width, height) { - if (!canvasAndContext.canvas) { - throw new Error("Canvas is not specified"); - } - if (width <= 0 || height <= 0) { - throw new Error("Invalid canvas size"); - } - canvasAndContext.canvas.width = width; - canvasAndContext.canvas.height = height; - } - - destroy(canvasAndContext) { - if (!canvasAndContext.canvas) { - throw new Error("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; - } -} - class DOMCanvasFactory extends BaseCanvasFactory { constructor({ ownerDocument = globalThis.document } = {}) { super(); @@ -134,45 +102,6 @@ function fetchData(url, asTypedArray) { }); } -class BaseCMapReaderFactory { - constructor({ baseUrl = null, isCompressed = false }) { - if (this.constructor === BaseCMapReaderFactory) { - unreachable("Cannot initialize BaseCMapReaderFactory."); - } - this.baseUrl = baseUrl; - this.isCompressed = isCompressed; - } - - 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 - ? CMapCompressionType.BINARY - : CMapCompressionType.NONE; - - return this._fetchData(url, compressionType).catch(reason => { - throw new Error( - `Unable to load ${this.isCompressed ? "binary " : ""}CMap at: ${url}` - ); - }); - } - - /** - * @private - */ - _fetchData(url, compressionType) { - unreachable("Abstract method `_fetchData` called."); - } -} - class DOMCMapReaderFactory extends BaseCMapReaderFactory { _fetchData(url, compressionType) { return fetchData(url, /* asTypedArray = */ this.isCompressed).then(data => { @@ -181,32 +110,6 @@ class DOMCMapReaderFactory extends BaseCMapReaderFactory { } } -class BaseStandardFontDataFactory { - constructor({ baseUrl = null }) { - if (this.constructor === BaseStandardFontDataFactory) { - unreachable("Cannot initialize BaseStandardFontDataFactory."); - } - this.baseUrl = baseUrl; - } - - 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.' - ); - } - if (!filename) { - throw new Error("Font filename must be specified."); - } - const url = this.baseUrl + filename + ".pfb"; - - return this._fetchData(url).catch(reason => { - throw new Error(`Unable to load font data at: ${url}`); - }); - } -} - class DOMStandardFontDataFactory extends BaseStandardFontDataFactory { _fetchData(url) { return fetchData(url, /* asTypedArray = */ true); @@ -740,9 +643,6 @@ class PDFDateString { export { addLinkAttributes, - BaseCanvasFactory, - BaseCMapReaderFactory, - BaseStandardFontDataFactory, DEFAULT_LINK_REL, deprecated, DOMCanvasFactory, diff --git a/src/display/node_utils.js b/src/display/node_utils.js index f40155b83..cf8a387c5 100644 --- a/src/display/node_utils.js +++ b/src/display/node_utils.js @@ -18,23 +18,10 @@ import { BaseCanvasFactory, BaseCMapReaderFactory, BaseStandardFontDataFactory, -} from "./display_utils.js"; +} from "./base_factory.js"; import { isNodeJS } from "../shared/is_node.js"; import { unreachable } from "../shared/util.js"; -function fetchData(url) { - return new Promise((resolve, reject) => { - const fs = __non_webpack_require__("fs"); - fs.readFile(url, (error, data) => { - if (error || !data) { - reject(new Error(error)); - return; - } - resolve(new Uint8Array(data)); - }); - }); -} - let NodeCanvasFactory = class { constructor() { unreachable("Not implemented: NodeCanvasFactory"); @@ -54,6 +41,19 @@ let NodeStandardFontDataFactory = class { }; if ((typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) && isNodeJS) { + const fetchData = function (url) { + return new Promise((resolve, reject) => { + const fs = __non_webpack_require__("fs"); + fs.readFile(url, (error, data) => { + if (error || !data) { + reject(new Error(error)); + return; + } + resolve(new Uint8Array(data)); + }); + }); + }; + NodeCanvasFactory = class extends BaseCanvasFactory { create(width, height) { if (width <= 0 || height <= 0) {