Preventing from using the same canvas for multiple render()

This commit is contained in:
Yury Delendik 2017-06-12 16:04:35 -05:00
parent 0ca6132ad2
commit 24f14d44cb
2 changed files with 45 additions and 1 deletions

View File

@ -901,7 +901,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
stats.time('Rendering');
internalRenderTask.initializeGraphics(transparency);
internalRenderTask.operatorListChanged();
}, complete);
}).catch(complete);
return renderTask;
},
@ -2103,6 +2103,7 @@ var RenderTask = (function RenderTaskClosure() {
* @ignore
*/
var InternalRenderTask = (function InternalRenderTaskClosure() {
let canvasInRendering = new WeakMap();
function InternalRenderTask(callback, params, objs, commonObjs, operatorList,
pageNumber, canvasFactory) {
@ -2125,6 +2126,7 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
this._continueBound = this._continue.bind(this);
this._scheduleNextBound = this._scheduleNext.bind(this);
this._nextBound = this._next.bind(this);
this._canvas = params.canvasContext.canvas;
}
InternalRenderTask.prototype = {
@ -2132,6 +2134,16 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
initializeGraphics:
function InternalRenderTask_initializeGraphics(transparency) {
if (this._canvas) {
if (canvasInRendering.has(this._canvas)) {
throw new Error(
'Cannot use the same canvas during multiple render() operations. ' +
'Use different canvas or ensure previous operations were ' +
'cancelled or completed.');
}
canvasInRendering.set(this._canvas, this);
}
if (this.cancelled) {
return;
}
@ -2163,6 +2175,9 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
cancel: function InternalRenderTask_cancel() {
this.running = false;
this.cancelled = true;
if (this._canvas) {
canvasInRendering.delete(this._canvas);
}
if ((typeof PDFJSDev !== 'undefined' && PDFJSDev.test('PDFJS_NEXT')) ||
getDefaultSetting('pdfjsNext')) {
@ -2223,6 +2238,9 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
this.running = false;
if (this.operatorList.lastChunk) {
this.gfx.endDrawing();
if (this._canvas) {
canvasInRendering.delete(this._canvas);
}
this.callback();
}
}

View File

@ -1041,6 +1041,32 @@ describe('api', function() {
done();
});
});
it('multiple render() on the same canvas', function(done) {
if (isNodeJS()) {
pending('TODO: Support Canvas testing in Node.js.');
}
var viewport = page.getViewport(1);
var canvasAndCtx = CanvasFactory.create(viewport.width, viewport.height);
var renderTask1 = page.render({
canvasContext: canvasAndCtx.context,
viewport,
});
var renderTask2 = page.render({
canvasContext: canvasAndCtx.context,
viewport,
});
Promise.all([
renderTask1.promise,
renderTask2.promise.then(() => {
done.fail('shall fail rendering');
}, (reason) => {
/* it fails because we already using this canvas */
expect(/multiple render\(\)/.test(reason.message)).toEqual(true);
})
]).then(done);
});
});
describe('Multiple PDFJS instances', function() {
if (isNodeJS()) {