Move BaseCanvasFactory, BaseCMapReaderFactory, and BaseStandardFontDataFactory to their own file

Given that these factories are being used in *different* files, for Browser respectively Node.js implementations, it seems reasonable to move them into their own file instead.
This commit is contained in:
Jonas Jenwald 2021-06-07 11:45:16 +02:00
parent 2a6111044e
commit 248113bbf0
3 changed files with 148 additions and 119 deletions

129
src/display/base_factory.js Normal file
View File

@ -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,
};

View File

@ -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,

View File

@ -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) {