From bf0aca86d72d2b7a6b8d24333a11fdaf187b7ac8 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Thu, 28 Jun 2018 22:38:09 +0200 Subject: [PATCH] Fix re-rendering, using the same canvas, when rendering was previously cancelled (PR 8519 follow-up) Currently if `RenderTask.cancel` is called *immediately* after rendering was started, then by the time that `InternalRenderTask.initializeGraphics` is called rendering will already have been cancelled. However, we're still inserting the canvas into the `canvasInRendering` map, thus breaking any future attempts at re-rendering using the same canvas. Considering that `InternalRenderTask.cancel` always removes the canvas from the map, I cannot imagine that we'd ever want to re-add it *after* rendering was cancelled (it was likely just a simple oversight in PR 8519). Fixes 9456. --- src/display/api.js | 10 ++++------ test/unit/api_spec.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/display/api.js b/src/display/api.js index ede847f9e..92b418b10 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -2380,9 +2380,10 @@ var InternalRenderTask = (function InternalRenderTaskClosure() { InternalRenderTask.prototype = { - initializeGraphics: - function InternalRenderTask_initializeGraphics(transparency) { - + initializeGraphics(transparency) { + if (this.cancelled) { + return; + } if (this._canvas) { if (canvasInRendering.has(this._canvas)) { throw new Error( @@ -2393,9 +2394,6 @@ var InternalRenderTask = (function InternalRenderTaskClosure() { canvasInRendering.set(this._canvas, this); } - if (this.cancelled) { - return; - } if (this._pdfBug && globalScope.StepperManager && globalScope.StepperManager.enabled) { this.stepper = globalScope.StepperManager.create(this.pageNumber - 1); diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index fcb1558be..ec23a6fae 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -1253,6 +1253,37 @@ describe('api', function() { done(); }); }); + + it('re-render page, using the same canvas, after cancelling rendering', + function(done) { + if (isNodeJS()) { + pending('TODO: Support Canvas testing in Node.js.'); + } + let viewport = page.getViewport(1); + let canvasAndCtx = CanvasFactory.create(viewport.width, viewport.height); + + let renderTask = page.render({ + canvasContext: canvasAndCtx.context, + viewport, + }); + renderTask.cancel(); + + renderTask.promise.then(() => { + throw new Error('shall cancel rendering'); + }, (reason) => { + expect(reason instanceof RenderingCancelledException).toEqual(true); + }).then(() => { + let reRenderTask = page.render({ + canvasContext: canvasAndCtx.context, + viewport, + }); + return reRenderTask.promise; + }).then(() => { + CanvasFactory.destroy(canvasAndCtx); + done(); + }, done.fail); + }); + it('multiple render() on the same canvas', function(done) { if (isNodeJS()) { pending('TODO: Support Canvas testing in Node.js.');