Revert "[api-minor] Allow loading pdf fonts into another document."

This commit is contained in:
Jonas Jenwald 2020-08-01 12:52:39 +02:00 committed by GitHub
parent 173b92a873
commit 05baa4c89f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 19 additions and 158 deletions

View File

@ -152,9 +152,6 @@ function setPDFNetworkStreamFactory(pdfNetworkStreamFactory) {
* parsed font data from the worker-thread. This may be useful for debugging * parsed font data from the worker-thread. This may be useful for debugging
* purposes (and backwards compatibility), but note that it will lead to * purposes (and backwards compatibility), but note that it will lead to
* increased memory usage. The default value is `false`. * increased memory usage. The default value is `false`.
* @property {HTMLDocument} [ownerDocument] - Specify an explicit document
* context to create elements with and to load resources, such as fonts,
* into. Defaults to the current document.
* @property {boolean} [disableRange] - Disable range request loading * @property {boolean} [disableRange] - Disable range request loading
* of PDF files. When enabled, and if the server supports partial content * of PDF files. When enabled, and if the server supports partial content
* requests, then the PDF will be fetched in chunks. * requests, then the PDF will be fetched in chunks.
@ -271,9 +268,6 @@ function getDocument(src) {
if (typeof params.disableFontFace !== "boolean") { if (typeof params.disableFontFace !== "boolean") {
params.disableFontFace = apiCompatibilityParams.disableFontFace || false; params.disableFontFace = apiCompatibilityParams.disableFontFace || false;
} }
if (typeof params.ownerDocument === "undefined") {
params.ownerDocument = globalThis.document;
}
if (typeof params.disableRange !== "boolean") { if (typeof params.disableRange !== "boolean") {
params.disableRange = false; params.disableRange = false;
@ -913,10 +907,9 @@ class PDFDocumentProxy {
* @alias PDFPageProxy * @alias PDFPageProxy
*/ */
class PDFPageProxy { class PDFPageProxy {
constructor(pageIndex, pageInfo, transport, ownerDocument, pdfBug = false) { constructor(pageIndex, pageInfo, transport, pdfBug = false) {
this._pageIndex = pageIndex; this._pageIndex = pageIndex;
this._pageInfo = pageInfo; this._pageInfo = pageInfo;
this._ownerDocument = ownerDocument;
this._transport = transport; this._transport = transport;
this._stats = pdfBug ? new StatTimer() : null; this._stats = pdfBug ? new StatTimer() : null;
this._pdfBug = pdfBug; this._pdfBug = pdfBug;
@ -1043,9 +1036,7 @@ class PDFPageProxy {
intentState.streamReaderCancelTimeout = null; intentState.streamReaderCancelTimeout = null;
} }
const canvasFactoryInstance = const canvasFactoryInstance = canvasFactory || new DefaultCanvasFactory();
canvasFactory ||
new DefaultCanvasFactory({ ownerDocument: this._ownerDocument });
const webGLContext = new WebGLContext({ const webGLContext = new WebGLContext({
enable: enableWebGL, enable: enableWebGL,
}); });
@ -1953,7 +1944,6 @@ class WorkerTransport {
this.fontLoader = new FontLoader({ this.fontLoader = new FontLoader({
docId: loadingTask.docId, docId: loadingTask.docId,
onUnsupportedFeature: this._onUnsupportedFeature.bind(this), onUnsupportedFeature: this._onUnsupportedFeature.bind(this),
ownerDocument: params.ownerDocument,
}); });
this._params = params; this._params = params;
this.CMapReaderFactory = new params.CMapReaderFactory({ this.CMapReaderFactory = new params.CMapReaderFactory({
@ -2410,7 +2400,6 @@ class WorkerTransport {
pageIndex, pageIndex,
pageInfo, pageInfo,
this, this,
this._params.ownerDocument,
this._params.pdfBug this._params.pdfBug
); );
this.pageCache[pageIndex] = page; this.pageCache[pageIndex] = page;

View File

@ -65,16 +65,11 @@ class BaseCanvasFactory {
} }
class DOMCanvasFactory extends BaseCanvasFactory { class DOMCanvasFactory extends BaseCanvasFactory {
constructor({ ownerDocument = globalThis.document } = {}) {
super();
this._document = ownerDocument;
}
create(width, height) { create(width, height) {
if (width <= 0 || height <= 0) { if (width <= 0 || height <= 0) {
throw new Error("Invalid canvas size"); throw new Error("Invalid canvas size");
} }
const canvas = this._document.createElement("canvas"); const canvas = document.createElement("canvas");
const context = canvas.getContext("2d"); const context = canvas.getContext("2d");
canvas.width = width; canvas.width = width;
canvas.height = height; canvas.height = height;

View File

@ -25,17 +25,12 @@ import {
} from "../shared/util.js"; } from "../shared/util.js";
class BaseFontLoader { class BaseFontLoader {
constructor({ constructor({ docId, onUnsupportedFeature }) {
docId,
onUnsupportedFeature,
ownerDocument = globalThis.document,
}) {
if (this.constructor === BaseFontLoader) { if (this.constructor === BaseFontLoader) {
unreachable("Cannot initialize BaseFontLoader."); unreachable("Cannot initialize BaseFontLoader.");
} }
this.docId = docId; this.docId = docId;
this._onUnsupportedFeature = onUnsupportedFeature; this._onUnsupportedFeature = onUnsupportedFeature;
this._document = ownerDocument;
this.nativeFontFaces = []; this.nativeFontFaces = [];
this.styleElement = null; this.styleElement = null;
@ -43,15 +38,15 @@ class BaseFontLoader {
addNativeFontFace(nativeFontFace) { addNativeFontFace(nativeFontFace) {
this.nativeFontFaces.push(nativeFontFace); this.nativeFontFaces.push(nativeFontFace);
this._document.fonts.add(nativeFontFace); document.fonts.add(nativeFontFace);
} }
insertRule(rule) { insertRule(rule) {
let styleElement = this.styleElement; let styleElement = this.styleElement;
if (!styleElement) { if (!styleElement) {
styleElement = this.styleElement = this._document.createElement("style"); styleElement = this.styleElement = document.createElement("style");
styleElement.id = `PDFJS_FONT_STYLE_TAG_${this.docId}`; styleElement.id = `PDFJS_FONT_STYLE_TAG_${this.docId}`;
this._document.documentElement document.documentElement
.getElementsByTagName("head")[0] .getElementsByTagName("head")[0]
.appendChild(styleElement); .appendChild(styleElement);
} }
@ -61,8 +56,8 @@ class BaseFontLoader {
} }
clear() { clear() {
this.nativeFontFaces.forEach(nativeFontFace => { this.nativeFontFaces.forEach(function (nativeFontFace) {
this._document.fonts.delete(nativeFontFace); document.fonts.delete(nativeFontFace);
}); });
this.nativeFontFaces.length = 0; this.nativeFontFaces.length = 0;
@ -121,8 +116,7 @@ class BaseFontLoader {
} }
get isFontLoadingAPISupported() { get isFontLoadingAPISupported() {
const supported = const supported = typeof document !== "undefined" && !!document.fonts;
typeof this._document !== "undefined" && !!this._document.fonts;
return shadow(this, "isFontLoadingAPISupported", supported); return shadow(this, "isFontLoadingAPISupported", supported);
} }
@ -152,8 +146,8 @@ if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
// PDFJSDev.test('CHROME || GENERIC') // PDFJSDev.test('CHROME || GENERIC')
FontLoader = class GenericFontLoader extends BaseFontLoader { FontLoader = class GenericFontLoader extends BaseFontLoader {
constructor(params) { constructor(docId) {
super(params); super(docId);
this.loadingContext = { this.loadingContext = {
requests: [], requests: [],
nextRequestId: 0, nextRequestId: 0,
@ -260,7 +254,7 @@ if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
let i, ii; let i, ii;
// The temporary canvas is used to determine if fonts are loaded. // The temporary canvas is used to determine if fonts are loaded.
const canvas = this._document.createElement("canvas"); const canvas = document.createElement("canvas");
canvas.width = 1; canvas.width = 1;
canvas.height = 1; canvas.height = 1;
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
@ -322,22 +316,22 @@ if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
} }
names.push(loadTestFontId); names.push(loadTestFontId);
const div = this._document.createElement("div"); const div = document.createElement("div");
div.style.visibility = "hidden"; div.style.visibility = "hidden";
div.style.width = div.style.height = "10px"; div.style.width = div.style.height = "10px";
div.style.position = "absolute"; div.style.position = "absolute";
div.style.top = div.style.left = "0px"; div.style.top = div.style.left = "0px";
for (i = 0, ii = names.length; i < ii; ++i) { for (i = 0, ii = names.length; i < ii; ++i) {
const span = this._document.createElement("span"); const span = document.createElement("span");
span.textContent = "Hi"; span.textContent = "Hi";
span.style.fontFamily = names[i]; span.style.fontFamily = names[i];
div.appendChild(span); div.appendChild(span);
} }
this._document.body.appendChild(div); document.body.appendChild(div);
isFontReady(loadTestFontId, () => { isFontReady(loadTestFontId, function () {
this._document.body.removeChild(div); document.body.removeChild(div);
request.complete(); request.complete();
}); });
/** Hack end */ /** Hack end */

View File

@ -510,7 +510,6 @@ var renderTextLayer = (function renderTextLayerClosure() {
this._textContent = textContent; this._textContent = textContent;
this._textContentStream = textContentStream; this._textContentStream = textContentStream;
this._container = container; this._container = container;
this._document = container.ownerDocument;
this._viewport = viewport; this._viewport = viewport;
this._textDivs = textDivs || []; this._textDivs = textDivs || [];
this._textContentItemsStr = textContentItemsStr || []; this._textContentItemsStr = textContentItemsStr || [];
@ -615,7 +614,7 @@ var renderTextLayer = (function renderTextLayerClosure() {
let styleCache = Object.create(null); let styleCache = Object.create(null);
// The temporary canvas is used to measure text length in the DOM. // The temporary canvas is used to measure text length in the DOM.
const canvas = this._document.createElement("canvas"); const canvas = document.createElement("canvas");
if ( if (
typeof PDFJSDev === "undefined" || typeof PDFJSDev === "undefined" ||
PDFJSDev.test("MOZCENTRAL || GENERIC") PDFJSDev.test("MOZCENTRAL || GENERIC")

View File

@ -107,119 +107,3 @@ describe("custom canvas rendering", function () {
.catch(done.fail); .catch(done.fail);
}); });
}); });
describe("alternate document context", function () {
const FontFace = global.FontFace;
let altDocument;
let CanvasFactory;
let elements;
beforeEach(() => {
global.FontFace = function MockFontFace(name) {
this.family = name;
};
elements = [];
const createElement = name => {
const element = {
tagName: name,
remove() {
this.remove.called = true;
},
};
if (name === "style") {
element.sheet = {
cssRules: [],
insertRule(rule) {
this.cssRules.push(rule);
},
};
}
elements.push(element);
return element;
};
altDocument = {
fonts: new Set(),
createElement,
documentElement: {
getElementsByTagName: () => [{ appendChild: () => {} }],
},
};
CanvasFactory = isNodeJS
? new NodeCanvasFactory()
: new DOMCanvasFactory({ ownerDocument: altDocument });
});
afterEach(() => {
global.FontFace = FontFace;
CanvasFactory = null;
elements = null;
});
it("should use given document for loading fonts (with Font Loading API)", async function () {
const getDocumentParams = buildGetDocumentParams(
"TrueType_without_cmap.pdf",
{
disableFontFace: false,
ownerDocument: altDocument,
}
);
const loadingTask = getDocument(getDocumentParams);
const doc = await loadingTask.promise;
const page = await doc.getPage(1);
const viewport = page.getViewport({ scale: 1 });
const canvasAndCtx = CanvasFactory.create(viewport.width, viewport.height);
await page.render({
canvasContext: canvasAndCtx.context,
viewport,
}).promise;
expect(elements).toEqual([]);
expect(altDocument.fonts.size).toBe(1);
const [font] = Array.from(altDocument.fonts);
expect(font.family).toMatch(/g_d\d+_f1/);
await doc.destroy();
await loadingTask.destroy();
CanvasFactory.destroy(canvasAndCtx);
expect(altDocument.fonts.size).toBe(0);
});
it("should use given document for loading fonts (with CSS rules)", async function () {
altDocument.fonts = null;
const getDocumentParams = buildGetDocumentParams(
"TrueType_without_cmap.pdf",
{
disableFontFace: false,
ownerDocument: altDocument,
}
);
const loadingTask = getDocument(getDocumentParams);
const doc = await loadingTask.promise;
const page = await doc.getPage(1);
const viewport = page.getViewport({ scale: 1 });
const canvasAndCtx = CanvasFactory.create(viewport.width, viewport.height);
await page.render({
canvasContext: canvasAndCtx.context,
viewport,
}).promise;
const style = elements.find(element => element.tagName === "style");
expect(style.sheet.cssRules.length).toBe(1);
expect(style.sheet.cssRules[0]).toMatch(
/^@font-face {font-family:"g_d\d+_f1";src:/
);
await doc.destroy();
await loadingTask.destroy();
CanvasFactory.destroy(canvasAndCtx);
expect(style.remove.called).toBe(true);
});
});