diff --git a/examples/Node.js/JSONtoPDF.js b/examples/Node.js/JSONtoPDF.js index 468775d6..e93792db 100644 --- a/examples/Node.js/JSONtoPDF.js +++ b/examples/Node.js/JSONtoPDF.js @@ -4,16 +4,15 @@ var paper = require('paper'), var canvas = paper.createCanvas(612, 792, 'pdf'); paper.setup(canvas); -with (paper) { - fs.readFile('./in.json', { encoding: 'utf8' }, function (err, data) { +fs.readFile('./in.json', { encoding: 'utf8' }, function (err, data) { + if (err) + throw err; + paper.project.importJSON(data); + paper.view.update(); + fs.writeFile(path.resolve(__dirname, 'out.pdf'), canvas.toBuffer(), function (err) { if (err) throw err; - project.importJSON(data); - view.update(); - fs.writeFile(path.resolve(__dirname, 'out.pdf'), canvas.toBuffer(), function (err) { - if (err) - throw err; - console.log('Saved!'); - }); + console.log('Saved!'); + process.exit(); }); -} +}); diff --git a/src/core/PaperScope.js b/src/core/PaperScope.js index 04cc29d9..d005feb8 100644 --- a/src/core/PaperScope.js +++ b/src/core/PaperScope.js @@ -253,18 +253,10 @@ var PaperScope = Base.extend(/** @lends PaperScope# */{ return this; }, - createCanvas: function(width, height, type) { - if (type) { - // TODO: Support 'pdf' on node.js! - } + createCanvas: function(width, height) { return CanvasProvider.getCanvas(width, height); }, - /** - * @deprecated, use use {@link #createCanvas(width, height)} instead. - */ - Canvas: '#createCanvas', - /** * Activates this PaperScope, so all newly created items will be placed * in its active project. diff --git a/src/node/canvas.js b/src/node/canvas.js new file mode 100644 index 00000000..a94c4265 --- /dev/null +++ b/src/node/canvas.js @@ -0,0 +1,53 @@ +/* + * Paper.js - The Swiss Army Knife of Vector Graphics Scripting. + * http://paperjs.org/ + * + * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey + * http://scratchdisk.com/ & http://jonathanpuckey.com/ + * + * Distributed under the MIT license. See LICENSE file for details. + * + * All rights reserved. + */ + +var Canvas = require('canvas'), + idlUtils = require('jsdom/lib/jsdom/living/generated/utils'); + +// Add some useful extensions to HTMLCanvasElement: +// - HTMLCanvasElement#type, so we can switch to a PDF canvas +// - Various Node Canvas methods, routed through from HTMLCanvasElement: +// toBuffer, pngStream, createPNGStream, jpgStream, createJPGStream + +module.exports = function(window) { + var HTMLCanvasElement = window.HTMLCanvasElement; + + function getImplementation(obj) { + return obj._canvas ? obj : idlUtils.implForWrapper(obj); + } + + // Add fake HTMLCanvasElement#type property: + Object.defineProperty(HTMLCanvasElement.prototype, 'type', { + get: function() { + return getImplementation(this)._type; + }, + + set: function(type) { + // Allow replacement of internal node-canvas, so we can switch to a + // PDF canvas. + var impl = getImplementation(this), + size = impl._canvas || impl; + impl._canvas = new Canvas(size.width, size.height, type); + impl._context = null; + impl._type = type; + } + }); + + // Extend HTMLCanvasElement with useful methods from the underlying Canvas: + ['toBuffer', 'pngStream', 'createPNGStream', 'jpgStream', 'createJPGStream'] + .forEach(function(key) { + HTMLCanvasElement.prototype[key] = function() { + var canvas = getImplementation(this)._canvas; + return canvas[key].apply(canvas, arguments); + }; + }); +}; diff --git a/src/node/extend.js b/src/node/extend.js index e162c642..4583e43d 100644 --- a/src/node/extend.js +++ b/src/node/extend.js @@ -12,6 +12,7 @@ var fs = require('fs'), path = require('path'); + Canvas = require('canvas'); module.exports = function(paper) { var sourceMaps = {}, @@ -52,6 +53,24 @@ module.exports = function(paper) { }; }; + paper.PaperScope.inject({ + createCanvas: function(width, height, type) { + // Do not use CanvasProvider.getCanvas(), since we may be changing + // the underlying node-canvas and don't want to release it after + // back into the pool. + var canvas = paper.document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + canvas.type = type; + return canvas; + }, + + /** + * @deprecated, use use {@link #createCanvas(width, height)} instead. + */ + Canvas: '#createCanvas' + }); + // Node.js based image exporting code. paper.CanvasView.inject({ // DOCS: CanvasView#exportFrames(param); diff --git a/src/node/window.js b/src/node/window.js index 60a45079..e00e302a 100644 --- a/src/node/window.js +++ b/src/node/window.js @@ -13,8 +13,7 @@ // Node.js emulation layer of browser environment, based on jsdom with node- // canvas integration. -var jsdom = require('jsdom'), - idlUtils = require('jsdom/lib/jsdom/living/generated/utils'); +var jsdom = require('jsdom'); // Create our document and window objects through jsdom. /* global document:true, window:true */ @@ -25,18 +24,10 @@ var document = jsdom.jsdom('', { }), window = document.defaultView; -['pngStream', 'createPNGStream', 'jpgStream', 'createJPGStream'].forEach( - function(key) { - this[key] = function() { - var impl = this._canvas ? this : idlUtils.implForWrapper(this), - canvas = impl && impl._canvas; - return canvas[key].apply(canvas, arguments); - }; - }, - window.HTMLCanvasElement.prototype); +require('./canvas')(window); // Define XMLSerializer and DOMParser shims, to emulate browser behavior. -// TODO: Put this into a simple node module, with dependency on jsdom? +// Effort to bring this to jsdom: https://github.com/tmpvar/jsdom/issues/1368 function XMLSerializer() { } @@ -44,7 +35,7 @@ XMLSerializer.prototype.serializeToString = function(node) { var text = jsdom.serializeDocument(node); // Fix a jsdom issue where all SVG tagNames are lowercased: // https://github.com/tmpvar/jsdom/issues/620 - var tagNames = ['linearGradient', 'radialGradient', 'clipPath']; + var tagNames = ['linearGradient', 'radialGradient', 'clipPath', 'textPath']; for (var i = 0, l = tagNames.length; i < l; i++) { var tagName = tagNames[i]; text = text.replace(