Merge pull request #9809 from Snuffleupagus/getPathGenerator-ignoreErrors
Allow `FontFaceObject.getPathGenerator` to ignore non-embedded fonts during rendering
This commit is contained in:
commit
280f20bf3c
@ -1884,6 +1884,8 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
|||||||
var font = new FontFaceObject(exportedData, {
|
var font = new FontFaceObject(exportedData, {
|
||||||
isEvalSupported: params.isEvalSupported,
|
isEvalSupported: params.isEvalSupported,
|
||||||
disableFontFace: params.disableFontFace,
|
disableFontFace: params.disableFontFace,
|
||||||
|
ignoreErrors: params.ignoreErrors,
|
||||||
|
onUnsupportedFeature: this._onUnsupportedFeature.bind(this),
|
||||||
fontRegistry,
|
fontRegistry,
|
||||||
});
|
});
|
||||||
var fontReady = (fontObjs) => {
|
var fontReady = (fontObjs) => {
|
||||||
@ -1986,15 +1988,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
|||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
messageHandler.on('UnsupportedFeature', function(data) {
|
messageHandler.on('UnsupportedFeature', this._onUnsupportedFeature, this);
|
||||||
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('JpegDecode', function(data) {
|
messageHandler.on('JpegDecode', function(data) {
|
||||||
if (this.destroyed) {
|
if (this.destroyed) {
|
||||||
@ -2060,6 +2054,16 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
|||||||
}, this);
|
}, 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() {
|
getData: function WorkerTransport_getData() {
|
||||||
return this.messageHandler.sendWithPromise('GetData', null);
|
return this.messageHandler.sendWithPromise('GetData', null);
|
||||||
},
|
},
|
||||||
@ -2455,30 +2459,34 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
|
|||||||
|
|
||||||
_scheduleNext: function InternalRenderTask__scheduleNext() {
|
_scheduleNext: function InternalRenderTask__scheduleNext() {
|
||||||
if (this.useRequestAnimationFrame && typeof window !== 'undefined') {
|
if (this.useRequestAnimationFrame && typeof window !== 'undefined') {
|
||||||
window.requestAnimationFrame(this._nextBound);
|
window.requestAnimationFrame(() => {
|
||||||
|
this._nextBound().catch(this.callback);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
Promise.resolve().then(this._nextBound).catch(this.callback);
|
Promise.resolve().then(this._nextBound).catch(this.callback);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_next: function InternalRenderTask__next() {
|
_next: function InternalRenderTask__next() {
|
||||||
if (this.cancelled) {
|
return new Promise(() => {
|
||||||
return;
|
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.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -14,7 +14,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
assert, bytesToString, isEvalSupported, shadow, string32, warn
|
assert, bytesToString, isEvalSupported, shadow, string32,
|
||||||
|
UNSUPPORTED_FEATURES, warn
|
||||||
} from '../shared/util';
|
} from '../shared/util';
|
||||||
|
|
||||||
function FontLoader(docId) {
|
function FontLoader(docId) {
|
||||||
@ -338,6 +339,8 @@ var IsEvalSupportedCached = {
|
|||||||
var FontFaceObject = (function FontFaceObjectClosure() {
|
var FontFaceObject = (function FontFaceObjectClosure() {
|
||||||
function FontFaceObject(translatedData, { isEvalSupported = true,
|
function FontFaceObject(translatedData, { isEvalSupported = true,
|
||||||
disableFontFace = false,
|
disableFontFace = false,
|
||||||
|
ignoreErrors = false,
|
||||||
|
onUnsupportedFeature = null,
|
||||||
fontRegistry = null, }) {
|
fontRegistry = null, }) {
|
||||||
this.compiledGlyphs = Object.create(null);
|
this.compiledGlyphs = Object.create(null);
|
||||||
// importing translated data
|
// importing translated data
|
||||||
@ -346,6 +349,8 @@ var FontFaceObject = (function FontFaceObjectClosure() {
|
|||||||
}
|
}
|
||||||
this.isEvalSupported = isEvalSupported !== false;
|
this.isEvalSupported = isEvalSupported !== false;
|
||||||
this.disableFontFace = disableFontFace === true;
|
this.disableFontFace = disableFontFace === true;
|
||||||
|
this.ignoreErrors = ignoreErrors === true;
|
||||||
|
this._onUnsupportedFeature = onUnsupportedFeature;
|
||||||
this.fontRegistry = fontRegistry;
|
this.fontRegistry = fontRegistry;
|
||||||
}
|
}
|
||||||
FontFaceObject.prototype = {
|
FontFaceObject.prototype = {
|
||||||
@ -385,45 +390,56 @@ var FontFaceObject = (function FontFaceObjectClosure() {
|
|||||||
return rule;
|
return rule;
|
||||||
},
|
},
|
||||||
|
|
||||||
getPathGenerator:
|
getPathGenerator(objs, character) {
|
||||||
function FontFaceObject_getPathGenerator(objs, character) {
|
if (this.compiledGlyphs[character] !== undefined) {
|
||||||
if (!(character in this.compiledGlyphs)) {
|
return this.compiledGlyphs[character];
|
||||||
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';
|
|
||||||
}
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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 = '';
|
||||||
|
}
|
||||||
|
js += 'c.' + current.cmd + '(' + args + ');\n';
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line no-new-func
|
||||||
|
return this.compiledGlyphs[character] = new Function('c', 'size', js);
|
||||||
|
}
|
||||||
|
// ... 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
1
test/pdfs/issue4244.pdf.link
Normal file
1
test/pdfs/issue4244.pdf.link
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://web.archive.org/web/20180613082417/https://tcpdf.org/files/examples/example_026.pdf
|
@ -2267,6 +2267,13 @@
|
|||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "issue4244",
|
||||||
|
"file": "pdfs/issue4244.pdf",
|
||||||
|
"md5": "26845274a32a537182ced1fd693a38b2",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": true,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "preistabelle",
|
{ "id": "preistabelle",
|
||||||
"file": "pdfs/preistabelle.pdf",
|
"file": "pdfs/preistabelle.pdf",
|
||||||
"md5": "d2f0b2086160d4f3d325c79a5dc1fb4d",
|
"md5": "d2f0b2086160d4f3d325c79a5dc1fb4d",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user