Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow FontFaceObject.getPathGenerator to ignore non-embedded fonts during rendering #9809

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 33 additions & 25 deletions src/display/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -1884,6 +1884,8 @@ var WorkerTransport = (function WorkerTransportClosure() {
var font = new FontFaceObject(exportedData, {
isEvalSupported: params.isEvalSupported,
disableFontFace: params.disableFontFace,
ignoreErrors: params.ignoreErrors,
onUnsupportedFeature: this._onUnsupportedFeature.bind(this),
fontRegistry,
});
var fontReady = (fontObjs) => {
Expand Down Expand Up @@ -1986,15 +1988,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
}
}, this);

messageHandler.on('UnsupportedFeature', function(data) {
if (this.destroyed) {
return; // Ignore any pending requests if the worker was terminated.
}
let loadingTask = this.loadingTask;
if (loadingTask.onUnsupportedFeature) {
loadingTask.onUnsupportedFeature(data.featureId);
}
}, this);
messageHandler.on('UnsupportedFeature', this._onUnsupportedFeature, this);

messageHandler.on('JpegDecode', function(data) {
if (this.destroyed) {
Expand Down Expand Up @@ -2060,6 +2054,16 @@ var WorkerTransport = (function WorkerTransportClosure() {
}, this);
},

_onUnsupportedFeature({ featureId, }) {
if (this.destroyed) {
return; // Ignore any pending requests if the worker was terminated.
}
let loadingTask = this.loadingTask;
if (loadingTask.onUnsupportedFeature) {
loadingTask.onUnsupportedFeature(featureId);
}
},

getData: function WorkerTransport_getData() {
return this.messageHandler.sendWithPromise('GetData', null);
},
Expand Down Expand Up @@ -2455,30 +2459,34 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {

_scheduleNext: function InternalRenderTask__scheduleNext() {
if (this.useRequestAnimationFrame && typeof window !== 'undefined') {
window.requestAnimationFrame(this._nextBound);
window.requestAnimationFrame(() => {
this._nextBound().catch(this.callback);
});
} else {
Promise.resolve().then(this._nextBound).catch(this.callback);
}
},

_next: function InternalRenderTask__next() {
if (this.cancelled) {
return;
}
this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList,
this.operatorListIdx,
this._continueBound,
this.stepper);
if (this.operatorListIdx === this.operatorList.argsArray.length) {
this.running = false;
if (this.operatorList.lastChunk) {
this.gfx.endDrawing();
if (this._canvas) {
canvasInRendering.delete(this._canvas);
return new Promise(() => {
if (this.cancelled) {
return;
}
this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList,
this.operatorListIdx,
this._continueBound,
this.stepper);
if (this.operatorListIdx === this.operatorList.argsArray.length) {
this.running = false;
if (this.operatorList.lastChunk) {
this.gfx.endDrawing();
if (this._canvas) {
canvasInRendering.delete(this._canvas);
}
this.callback();
}
this.callback();
}
}
});
},

};
Expand Down
90 changes: 53 additions & 37 deletions src/display/font_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
*/

import {
assert, bytesToString, isEvalSupported, shadow, string32, warn
assert, bytesToString, isEvalSupported, shadow, string32,
UNSUPPORTED_FEATURES, warn
} from '../shared/util';

function FontLoader(docId) {
Expand Down Expand Up @@ -338,6 +339,8 @@ var IsEvalSupportedCached = {
var FontFaceObject = (function FontFaceObjectClosure() {
function FontFaceObject(translatedData, { isEvalSupported = true,
disableFontFace = false,
ignoreErrors = false,
onUnsupportedFeature = null,
fontRegistry = null, }) {
this.compiledGlyphs = Object.create(null);
// importing translated data
Expand All @@ -346,6 +349,8 @@ var FontFaceObject = (function FontFaceObjectClosure() {
}
this.isEvalSupported = isEvalSupported !== false;
this.disableFontFace = disableFontFace === true;
this.ignoreErrors = ignoreErrors === true;
this._onUnsupportedFeature = onUnsupportedFeature;
this.fontRegistry = fontRegistry;
}
FontFaceObject.prototype = {
Expand Down Expand Up @@ -385,45 +390,56 @@ var FontFaceObject = (function FontFaceObjectClosure() {
return rule;
},

getPathGenerator:
function FontFaceObject_getPathGenerator(objs, character) {
if (!(character in this.compiledGlyphs)) {
var cmds = objs.get(this.loadedName + '_path_' + character);
var current, i, len;

// If we can, compile cmds into JS for MAXIMUM SPEED
if (this.isEvalSupported && IsEvalSupportedCached.value) {
var args, js = '';
for (i = 0, len = cmds.length; i < len; i++) {
current = cmds[i];

if (current.args !== undefined) {
args = current.args.join(',');
} else {
args = '';
}

js += 'c.' + current.cmd + '(' + args + ');\n';
getPathGenerator(objs, character) {
if (this.compiledGlyphs[character] !== undefined) {
return this.compiledGlyphs[character];
}

let cmds, current;
try {
cmds = objs.get(this.loadedName + '_path_' + character);
} catch (ex) {
if (!this.ignoreErrors) {
throw ex;
}
if (this._onUnsupportedFeature) {
this._onUnsupportedFeature({ featureId: UNSUPPORTED_FEATURES.font, });
}
warn(`getPathGenerator - ignoring character: "${ex}".`);

return this.compiledGlyphs[character] = function(c, size) {
// No-op function, to allow rendering to continue.
};
}

// If we can, compile cmds into JS for MAXIMUM SPEED...
if (this.isEvalSupported && IsEvalSupportedCached.value) {
let args, js = '';
for (let i = 0, ii = cmds.length; i < ii; i++) {
current = cmds[i];

if (current.args !== undefined) {
args = current.args.join(',');
} else {
args = '';
}
// eslint-disable-next-line no-new-func
this.compiledGlyphs[character] = new Function('c', 'size', js);
} else {
// But fall back on using Function.prototype.apply() if we're
// blocked from using eval() for whatever reason (like CSP policies)
this.compiledGlyphs[character] = function(c, size) {
for (i = 0, len = cmds.length; i < len; i++) {
current = cmds[i];

if (current.cmd === 'scale') {
current.args = [size, -size];
}

c[current.cmd].apply(c, current.args);
}
};
js += 'c.' + current.cmd + '(' + args + ');\n';
}
// eslint-disable-next-line no-new-func
return this.compiledGlyphs[character] = new Function('c', 'size', js);
}
return this.compiledGlyphs[character];
// ... but fall back on using Function.prototype.apply() if we're
// blocked from using eval() for whatever reason (like CSP policies).
return this.compiledGlyphs[character] = function(c, size) {
for (let i = 0, ii = cmds.length; i < ii; i++) {
current = cmds[i];

if (current.cmd === 'scale') {
current.args = [size, -size];
}
c[current.cmd].apply(c, current.args);
}
};
},
};

Expand Down
1 change: 1 addition & 0 deletions test/pdfs/issue4244.pdf.link
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://web.archive.org/web/20180613082417/https://tcpdf.org/files/examples/example_026.pdf
7 changes: 7 additions & 0 deletions test/test_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2267,6 +2267,13 @@
"rounds": 1,
"type": "eq"
},
{ "id": "issue4244",
"file": "pdfs/issue4244.pdf",
"md5": "26845274a32a537182ced1fd693a38b2",
"rounds": 1,
"link": true,
"type": "eq"
},
{ "id": "preistabelle",
"file": "pdfs/preistabelle.pdf",
"md5": "d2f0b2086160d4f3d325c79a5dc1fb4d",
Expand Down