Skip to content

[api-minor] Fix #7798: Refactor scratch canvas usage. #8002

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

Merged
merged 1 commit into from
Feb 6, 2017

Conversation

mukulmishra18
Copy link
Contributor

Fixes #7798, Refactoring scratch canvas usage to use both DOM canvas and npm canvas.

@@ -33,6 +33,44 @@ var createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;

var DEFAULT_LINK_REL = 'noopener noreferrer nofollow';

if (typeof require === 'function') {
var Canvas = require('canvas');
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this require() call -- Canvas is not used anywhere

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it is used in the else block of create method, line 48.

@@ -83,7 +84,8 @@ var WebGLUtils = (function WebGLUtilsClosure() {
if (currentGL) {
return;
}
currentCanvas = document.createElement('canvas');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert the change here -- it is used in the webgl context, you can add a comment that CanvasRactory is not needed here

package.json Outdated
@@ -2,6 +2,7 @@
"name": "pdf.js",
"version": "0.8.0",
"devDependencies": {
"canvas": "^1.6.2",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this package - we are not ready to use node.js canvas just yet

@@ -186,7 +187,8 @@ var renderTextLayer = (function renderTextLayerClosure() {
return;
}

var canvas = document.createElement('canvas');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert the change here -- it is used to measure text length in the DOM, you can add a comment that CanvasRactory is not needed here

@@ -216,7 +218,8 @@ if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) {

var i, ii;

var canvas = document.createElement('canvas');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert the change here -- it is used for hack to determine if font is loaded, you can add a comment that CanvasRactory is not needed here

@@ -1454,7 +1449,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
get isFontSubpixelAAEnabled() {
// Checks if anti-aliasing is enabled when scaled text is painted.
// On Windows GDI scaled fonts looks bad.
var ctx = document.createElement('canvas').getContext('2d');
var canvasFactory = new CanvasFactory();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CanvasFactory must be created once per render() call and stored at CanvasGraphics.

Copy link
Collaborator

@Snuffleupagus Snuffleupagus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a couple of review comments based on cursory looking at/testing the code.
Having briefly tested this locally, using the default tracemonkey.pdf file with gulp server, it seems that the current version of this patch unfortunately doesn't work as is.

Again, please remember to run tests (and use the viewer locally), since that helps catch errors as described below; see e.g. https://github.com/mozilla/pdf.js/wiki/Contributing#4-run-lint-and-testing.

@@ -50,6 +50,7 @@ var TilingPattern = displayPatternHelper.TilingPattern;
var getShadingPatternFromIR = displayPatternHelper.getShadingPatternFromIR;
var WebGLUtils = displayWebGL.WebGLUtils;
var hasCanvasTypedArrays = displayDOMUtils.hasCanvasTypedArrays;
var DOMcanvasFactory = displayDOMUtils.DOMCanvasFactory;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change the capitalization to var DOMCanvasFactory = ... to be consistent with the actual factory name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, thanks.

}
}(this, function (exports, sharedUtil) {
}(this, function (exports, sharedUtil, displayDOMUtils) {
Copy link
Collaborator

@Snuffleupagus Snuffleupagus Jan 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're not actually using displayDOMUtils anywhere in this file, please don't import it.

var Metadata = displayMetadata.Metadata;
var getDefaultSetting = displayDOMUtils.getDefaultSetting;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Please don't delete this new line, since the imports should be separated from the definition of the constant just below.

return this.canvas;
},

destroy: function DOMCanvasFactory_destroy() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also remember to set the width/height of the canvas to 0 before removing it, since that will cause (at least) Firefox to free graphics resources quicker; refer to e.g.

// Zeroing the width and height causes Firefox to release graphics
.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also remember to set the width/height of the canvas to 0 before removing it, since that will cause (at least) Firefox to free graphics resources quicker

That is a good point, i didn't think about that. Thanks for pointing.

@@ -83,6 +83,8 @@ var WebGLUtils = (function WebGLUtilsClosure() {
if (currentGL) {
return;
}

// CanvasFactory is not needed here, as it is used in the webgl context.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: let's capitalize this corrently, i.e. please use WebGL instead.

@@ -478,6 +472,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
this.smaskCounter = 0;
this.tempSMask = null;
this.cachedCanvases = new CachedCanvases();
this.DOMcanvasFactory = new DOMcanvasFactory();
Copy link
Collaborator

@Snuffleupagus Snuffleupagus Jan 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be better to call it this.canvasFactory, since I believe that one of the points of issue #7798 is to allow an API consumer to provide their own canvas factory (e.g. using Node canvas), and then a using the this.DOMCanvasFactory name here would be confusing.

Copy link
Collaborator

@Snuffleupagus Snuffleupagus Jan 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Furthermore, I think that you also need to initialize the DOMCanvasFactory before CachedCanvases, since you'll need to do this.cachedCanvases = new CachedCanvases(this.canvasFactory);.
Please refer to https://github.com/mozilla/pdf.js/pull/8002/files#r98327854.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be better to call it this.canvasFactory, since I believe that one of the points of issue #7798 is to allow an API consumer to provide their own canvas factory (e.g. using Node canvas), and then a using the this.DOMCanvasFactory name here would be confusing.

Should i have to change this.DOMcanvasFactory with this.canvasFactory in the whole canvas.js file or just the specified place?

Copy link
Collaborator

@Snuffleupagus Snuffleupagus Jan 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that I really understand what you're asking here, but you should (obviously) be consistent within the file. I.e. the above ought to look like the below instead (see also the code snippet in #8002 (comment)).

this.canvasFactory = new DOMCanvasFactory();
this.cachedCanvases = new CachedCanvases(this.canvasFactory);

@@ -218,7 +212,7 @@ var CachedCanvases = (function CachedCanvasesClosure() {
// reset canvas transform for emulated mozCurrentTransform, if needed
canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0);
} else {
var canvas = createScratchCanvas(width, height);
var canvas = CanvasGraphics.DOMcanvasFactory.create(width, height);
Copy link
Collaborator

@Snuffleupagus Snuffleupagus Jan 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to prevent errors, such as TypeError: CanvasGraphics.DOMcanvasFactory is undefined[Learn More] canvas.js:215:13, you'll need to pass in a canvasFactory instance when initializing CachedCanvases, i.e. change the "constructor" to

function CachedCanvases(canvasFactory) {
     this.canvasFactory = canvasFactory;
     this.cache = Object.create(null);
   }
}

and then use this.canvasFactory.create(width, height) here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only ran gulp unittest and lint, but forgot to test the viewer. Thanks for pointing out, i will take care of that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't forget to also run the entire test-suite, using gulp test, to ensure that there's no rendering regressions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, thanks.

@@ -33,6 +33,36 @@ var createValidAbsoluteUrl = sharedUtil.createValidAbsoluteUrl;

var DEFAULT_LINK_REL = 'noopener noreferrer nofollow';

function DOMCanvasFactory() {}
Copy link
Collaborator

@Snuffleupagus Snuffleupagus Jan 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if using this the way that you do here below actually makes sense in the context of a factory!? I'd think that you may need to do something like this instead:

function DOMCanvasFactory() {}
DOMCanvasFactory.prototype = {
  create: function DOMCanvasFactory_create(width, height) {
    var canvas = document.createElement('canvas');
    canvas.width = width || 0;
    canvas.height = height || 0;

    return canvas;
  },

  reset: function DOMCanvasFactory_reset(canvas, width, height) {
    if (!canvas) {
      throw new Error('Canvas not found');
    }
    canvas.width = width;
    canvas.height = height;
  },

  destroy: function DOMCanvasFactory_destroy(canvas) {
    if (!canvas) {
      throw new Error('Canvas not found');
    }
    // Zeroing the width and height causes Firefox to release graphics
    // resources immediately, which can greatly reduce memory consumption.
    canvas.width = 0;
    canvas.height = 0;

    canvas = null;
  }
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, i think i was little messed up with constructor function pattern. I will change it.

Copy link
Collaborator

@Snuffleupagus Snuffleupagus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking much better now!
Edit: It seems that this patch causes a lot of movement/failures in some of the tests, and I think I understand why. Please see the inline comment below.

However, I still think that there's one crucial thing left to do here. The way that I interpret issue #7798 is that we need to make it possible for users of the API to provide their own custom CanvasFactory, for example one using Node.js, for this refactoring to be truly useful.
I obviously don't know what @yurydelendik had in mind, but I'd think you probably want something along the lines of the following diff (created on top of this patch): Edit: Based on comments below, this isn't exactly what we want here; hence I'll remove the diff to not cause unnecessary confusion.

@@ -1742,7 +1742,8 @@ var WorkerTransport = (function WorkerTransportClosure() {
var size = width * height;
var rgbaLength = size * 4;
var buf = new Uint8Array(size * components);
var tmpCanvas = createScratchCanvas(width, height);
var canvasFactory = new DOMCanvasFactory();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that a new DOMCanvasFactory gets created for every JPEG image a document contains, which seem like the opposite of how you'd actually want a factory to be used.
See the general review comments for more regarding this subject.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the conversation with @yurydelendik, when i am trying to solve this issue. I think i got confused of passing canvasFactory via CanvasGraphics. I will fix it. Thanks for clearing.

Copy link
Contributor

@yurydelendik yurydelendik Jan 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to keep this part without change as well and add assert(typeof document !== 'undefined').

I'm thinking the canvasFactory must be a property of the render parameters. To protect core from calling browser decoding (which will fail anyway at setting image src), we need to pass a flag to evaluator that shows that browser decoding is disabled. I thought we do/did it, since pdf2svg example worked, but I cannot find this code now, so we need to pass this flag with getOperatorList requests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still will be passed to the CanvasGraphics, but it will be specified at the RenderParameters. And if it is not specified, created at the render().

@@ -216,6 +216,8 @@ if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) {

var i, ii;

// CanvasFactory is not needed here, as it is used to determine if fonts
// is loaded.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think are loaded. is better here, since the word "fonts" on the previous line is plural.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, thanks for catch. I will fix it.

create: function DOMCanvasFactory_create(width, height) {
var canvas = document.createElement('canvas');
canvas.width = width || 0;
canvas.height = height || 0;
Copy link
Collaborator

@Snuffleupagus Snuffleupagus Jan 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Letting the width/height default to zero is breaking the get isFontSubpixelAAEnabled() method, with lots of test failures as a result. I think that you need to do e.g. this instead:

if (typeof width !== 'undefined') {
  canvas.width = width;
}
if (typeof height !== 'undefined') {
  canvas.height = height;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, Thanks. I will do it this way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, the code at isFontSubpixelAAEnabled was just creating canvas with default size, we just need to remove || 0 or typeof width !== 'undefined' and specify needed canvas size at the caller (isFontSubpixelAAEnabled) e.g. 200x100 or 50x10

Copy link
Contributor Author

@mukulmishra18 mukulmishra18 Jan 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then i think we should remove typeof width !== 'undefined', as || 0 is little bit more clean.

Edit: @yurydelendik, or we can remove both as we are adding assert for width and height parameters.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, meant to say need to remove || 0 and typeof width !== 'undefined'

@@ -1454,7 +1450,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
get isFontSubpixelAAEnabled() {
// Checks if anti-aliasing is enabled when scaled text is painted.
// On Windows GDI scaled fonts looks bad.
var ctx = document.createElement('canvas').getContext('2d');
var ctx = this.canvasFactory.create().getContext('2d');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create canvas is size (10, 10) here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it, thanks

},

reset: function DOMCanvasFactory_reset(canvas, width, height) {
if (!canvas) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use assert(canvas, 'canvas is not specifed') here (and below)

add asserts (here and above) for the width and height parameters: assert(width > 0 && height > 0, 'invalid canvas size')

Copy link
Contributor

@timvandermeij timvandermeij left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This patch looks good to me after addressing these comments, but I'll leave the final review for others that know this particular code a bit better than me.

@@ -1742,7 +1751,10 @@ var WorkerTransport = (function WorkerTransportClosure() {
var size = width * height;
var rgbaLength = size * 4;
var buf = new Uint8Array(size * components);
var tmpCanvas = createScratchCanvas(width, height);
// make sure that this code is not executing in node.js.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this comment a bit more specific, i.e., why is it bad if this runs with Node.js?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, thanks. I will do it.

var tmpCanvas = createScratchCanvas(width, height);
// make sure that this code is not executing in node.js.
assert(typeof document !== 'undefined');
var canvasFactory = new DOMCanvasFactory();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we use this.canvasFactory (as set above) here? If so, we can remove this line and use var tmpCanvas = this.canvasFactory.create(width, height); in the line below.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probable need to make it var tmpCanvas = document.createElement('canvas'); tmpCanvas.width =...

@@ -477,7 +473,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
this.smaskStack = [];
this.smaskCounter = 0;
this.tempSMask = null;
this.cachedCanvases = new CachedCanvases();
this.canvasFactory = canvasFactory || new DOMCanvasFactory();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

canvasFactory parameter must be always specified (starting at render() method). can you also move canvasFactory before imageLayer in the parameters list.

canvas.width = 0;
canvas.height = 0;

canvas = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove canvas = null;

Also, this method must be used in the CachedCanvases.clear

DOMCanvasFactory.prototype = {
create: function DOMCanvasFactory_create(width, height) {
var canvas = document.createElement('canvas');
assert(width > 0 && height > 0, 'invalid canvas size');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move assert as a first line of the function

@@ -132,6 +133,8 @@ if (typeof PDFJSDev !== 'undefined' &&
* @property {string} docBaseUrl - (optional) The base URL of the document,
* used when attempting to recover valid absolute URLs for annotations, and
* outline items, that (incorrectly) only specify relative URLs.
* @property {Object} canvasFactory - (optional) The factory that will be used
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move canvasFactory from here and add to the RenderParameters below. We don't need to store canvas factory on the transport but rather than on a rendering task.

var tmpCanvas = createScratchCanvas(width, height);
// make sure that this code is not executing in node.js.
assert(typeof document !== 'undefined');
var canvasFactory = new DOMCanvasFactory();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probable need to make it var tmpCanvas = document.createElement('canvas'); tmpCanvas.width =...

Copy link
Collaborator

@Snuffleupagus Snuffleupagus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about bad advice previously!
Looking through the latest patch, it seems that a couple of things should probably be reverted/changed based on #8002 (comment) and #8002 (comment), so I've added inline comments where applicable.

@@ -245,6 +246,7 @@ function getDocument(src, pdfDataRangeTransport,
}

params.rangeChunkSize = params.rangeChunkSize || DEFAULT_RANGE_CHUNK_SIZE;
var canvasFactory = params.canvasFactory || new DOMCanvasFactory();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on #8002 (comment), this line should be removed.

@@ -262,7 +264,8 @@ function getDocument(src, pdfDataRangeTransport,
throw new Error('Loading aborted');
}
var messageHandler = new MessageHandler(docId, workerId, worker.port);
var transport = new WorkerTransport(messageHandler, task, rangeTransport);
var transport = new WorkerTransport(messageHandler, task, rangeTransport,
canvasFactory);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on #8002 (comment), this parameter should be removed.

@@ -720,6 +726,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
this.transport = transport;
this.stats = new StatTimer();
this.stats.enabled = getDefaultSetting('enableStats');
this.canvasFactory = transport.canvasFactory;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on #8002 (comment). this line should be removed.

@@ -1410,10 +1418,12 @@ var PDFWorker = (function PDFWorkerClosure() {
* @ignore
*/
var WorkerTransport = (function WorkerTransportClosure() {
function WorkerTransport(messageHandler, loadingTask, pdfDataRangeTransport) {
function WorkerTransport(messageHandler, loadingTask, pdfDataRangeTransport,
canvasFactory) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on #8002 (comment), this parameter should be removed.

this.messageHandler = messageHandler;
this.loadingTask = loadingTask;
this.pdfDataRangeTransport = pdfDataRangeTransport;
this.canvasFactory = canvasFactory;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on #8002 (comment), this line should be removed.

@@ -834,7 +841,8 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
this.objs,
this.commonObjs,
intentState.operatorList,
this.pageNumber);
this.pageNumber,
this.canvasFactory);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on #8002 (comment), this line should be replaced by canvasFactory, with

var canvasFactory = params.canvasFactory || new DOMCanvasFactory();

defined at line https://github.com/mozilla/pdf.js/pull/8002/files#diff-0ecad279ed2252e3eb47a4d96ec1463cR815 above.

@@ -466,6 +459,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
this.xobjs = null;
this.commonObjs = commonObjs;
this.objs = objs;
this.canvasFactory = canvasFactory || new DOMCanvasFactory();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on #8002 (comment), this line should simply read

this.canvasFactory = canvasFactory;

@@ -456,7 +448,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
// Defines the number of steps before checking the execution time
var EXECUTION_STEPS = 10;

function CanvasGraphics(canvasCtx, commonObjs, objs, imageLayer) {
function CanvasGraphics(canvasCtx, commonObjs, objs, imageLayer,
canvasFactory) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on #8002 (comment), please change the order of imageLayer and canvasFactory here.

@@ -2068,7 +2084,8 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {

var params = this.params;
this.gfx = new CanvasGraphics(params.canvasContext, this.commonObjs,
this.objs, params.imageLayer);
this.objs, params.imageLayer,
this.canvasFactory);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on #8002 (comment), please change the order of params.imageLayer and this.canvasFactory here.

var tmpCanvas = createScratchCanvas(width, height);
// make sure that this code is not executing in node.js, as
// it's using DOM image, and there is no library to support that.
assert(typeof document !== 'undefined');
Copy link
Collaborator

@Snuffleupagus Snuffleupagus Feb 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the entire JpegDecode code here, please see https://github.com/mozilla/pdf.js/blob/master/src/display/api.js#L1724-L1769, the use of assert seems slightly out of place here.

@yurydelendik I'd think it'd be more in line with the rest of this code-block if we did

if (typeof document === 'undefined') {
  // Make sure that this code is not executed in Node.js, as
  // it's using DOM image, and there is no library to support that.
  return Promise.reject(new Error('"document" is not defined.'));
}

placed at line https://github.com/mozilla/pdf.js/blob/master/src/display/api.js#L1728 instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either way works for me - it's just to make it easier to catch a problem. We can even move assert/reject at the top of the function.

var Metadata = displayMetadata.Metadata;
var getDefaultSetting = displayDOMUtils.getDefaultSetting;
var DOMCanvasFactory = displayDOMUtils.DOMCanvasFactory;
var assert = sharedUtil.assert;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this line, since assert is now unused (which is also why linting failed).

@@ -1727,6 +1733,12 @@ var WorkerTransport = (function WorkerTransportClosure() {
return Promise.reject(new Error('Worker was destroyed'));
}

if (typeof document === 'undefined') {
// make sure that this code is not executing in node.js, as
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Please remember to use uppercase letters at the beginning of sentences in comments, i.e. // Make sure ... instead.

Copy link
Contributor

@yurydelendik yurydelendik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me with comments below addressed and tests are passing.

var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we can remove a empty line here.

return canvas;
},

reset: function DOMCanvasFactory_reset(canvas, width, height) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function must be used from CachedCanvases

@@ -216,6 +216,8 @@ if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('MOZCENTRAL')) {

var i, ii;

// CanvasFactory is not needed here, as it is used to determine if fonts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and below, replace "CanvasFractory is not needed here, as it is" to something like "The temporary canvas is"

@yurydelendik yurydelendik dismissed their stale review February 4, 2017 14:34

previous concerns are addressed

@Snuffleupagus Snuffleupagus dismissed their stale review February 4, 2017 14:49

Earlier comments have now been addressed.

@Snuffleupagus Snuffleupagus changed the title Fix #7798: Refactor scratch canvas usage. [api-minor] Fix #7798: Refactor scratch canvas usage. Feb 4, 2017
@@ -213,12 +207,11 @@ var CachedCanvases = (function CachedCanvasesClosure() {
var canvasEntry;
if (this.cache[id] !== undefined) {
canvasEntry = this.cache[id];
canvasEntry.canvas.width = width;
canvasEntry.canvas.height = height;
this.canvasFactory.reset(canvasEntry, width, height);
Copy link
Collaborator

@Snuffleupagus Snuffleupagus Feb 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure that this actually works, since I believe that you need to use canvasEntry.canvas instead (compare with e.g. the destroy(...) call below).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, okay. I missed something. Sorry

Fixes extra canvas create calls.
Fixes unnecessary call of `new DOMCanvasFactory`.
Fixes undefined error of DOMCanvasFactory.
Fixes failures in some of the tests.
Fixes expected behaviour.
Remove unused vars.
@pdfjsbot
Copy link

pdfjsbot commented Feb 6, 2017

From: Bot.io (Linux)


Received

Command cmd_test from @Snuffleupagus received. Current queue size: 0

Live output at: http://107.21.233.14:8877/cc716af9f1aef5e/output.txt

@pdfjsbot
Copy link

pdfjsbot commented Feb 6, 2017

From: Bot.io (Windows)


Received

Command cmd_test from @Snuffleupagus received. Current queue size: 0

Live output at: http://54.215.176.217:8877/2eac7c0ccb9ad21/output.txt

@pdfjsbot
Copy link

pdfjsbot commented Feb 6, 2017

From: Bot.io (Windows)


Success

Full output at http://54.215.176.217:8877/2eac7c0ccb9ad21/output.txt

Total script time: 22.33 mins

  • Font tests: Passed
  • Unit tests: Passed
  • Regression tests: Passed

@pdfjsbot
Copy link

pdfjsbot commented Feb 6, 2017

From: Bot.io (Linux)


Success

Full output at http://107.21.233.14:8877/cc716af9f1aef5e/output.txt

Total script time: 25.96 mins

  • Font tests: Passed
  • Unit tests: Passed
  • Regression tests: Passed

@yurydelendik yurydelendik merged commit d842c9c into mozilla:master Feb 6, 2017
@yurydelendik
Copy link
Contributor

Thank you for the patch.

It's very good step, but I think to make it work we need to change a factory to return {canvas, context} pair instead to make it work for node's canvas. @mukulmishra18, would you like to follow up?

@mukulmishra18
Copy link
Contributor Author

@yurydelendik, @Snuffleupagus, @timvandermeij thanks for your reviews and help. You all are very supportive and cooperative, i learned a lot from all of you. I definitely wants to continue, please guide me what i have to do.

@yurydelendik
Copy link
Contributor

I definitely wants to continue, please guide me what i have to do.

Looking the the way node-canvas is create, we will need to create a new canvas and content on reset/resize. Let's just return create CanvasAndContextPair "structure" from create method and accept it in reset and destroy calls. CachedCanvases will/do store this structure. Notice that every time we create canvas we always create 2d-context after that, so we may do that in the factory.

@mukulmishra18 mukulmishra18 deleted the refactor-canvas branch September 19, 2017 08:21
movsb pushed a commit to movsb/pdf.js that referenced this pull request Jul 14, 2018
[api-minor] Fix mozilla#7798: Refactor scratch canvas usage.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants