Comparing version 2.8.0 to 2.9.0
14
index.js
const Canvas = require('./lib/canvas') | ||
const Image = require('./lib/image') | ||
const CanvasRenderingContext2D = require('./lib/context2d') | ||
const CanvasPattern = require('./lib/pattern') | ||
const parseFont = require('./lib/parse-font') | ||
@@ -11,4 +12,3 @@ const packageJson = require('./package.json') | ||
const JPEGStream = require('./lib/jpegstream') | ||
const DOMMatrix = require('./lib/DOMMatrix').DOMMatrix | ||
const DOMPoint = require('./lib/DOMMatrix').DOMPoint | ||
const { DOMPoint, DOMMatrix } = require('./lib/DOMMatrix') | ||
@@ -52,2 +52,9 @@ function createCanvas (width, height, type) { | ||
/** | ||
* Unload all fonts from pango to free up memory | ||
*/ | ||
function deregisterAllFonts () { | ||
return Canvas._deregisterAllFonts() | ||
} | ||
module.exports = { | ||
@@ -58,3 +65,3 @@ Canvas, | ||
CanvasGradient: bindings.CanvasGradient, | ||
CanvasPattern: bindings.CanvasPattern, | ||
CanvasPattern, | ||
Image, | ||
@@ -69,2 +76,3 @@ ImageData: bindings.ImageData, | ||
registerFont, | ||
deregisterAllFonts, | ||
parseFont, | ||
@@ -71,0 +79,0 @@ |
@@ -1,3 +0,3 @@ | ||
'use strict'; | ||
'use strict' | ||
module.exports = require('../build/Release/canvas.node'); | ||
module.exports = require('../build/Release/canvas.node') |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
'use strict' | ||
@@ -24,26 +24,26 @@ /*! | ||
Canvas.prototype.getContext = function (contextType, contextAttributes) { | ||
if ('2d' == contextType) { | ||
var ctx = this._context2d || (this._context2d = new Context2d(this, contextAttributes)); | ||
this.context = ctx; | ||
ctx.canvas = this; | ||
return ctx; | ||
if (contextType == '2d') { | ||
const ctx = this._context2d || (this._context2d = new Context2d(this, contextAttributes)) | ||
this.context = ctx | ||
ctx.canvas = this | ||
return ctx | ||
} | ||
}; | ||
} | ||
Canvas.prototype.pngStream = | ||
Canvas.prototype.createPNGStream = function(options){ | ||
return new PNGStream(this, options); | ||
}; | ||
Canvas.prototype.createPNGStream = function (options) { | ||
return new PNGStream(this, options) | ||
} | ||
Canvas.prototype.pdfStream = | ||
Canvas.prototype.createPDFStream = function(options){ | ||
return new PDFStream(this, options); | ||
}; | ||
Canvas.prototype.createPDFStream = function (options) { | ||
return new PDFStream(this, options) | ||
} | ||
Canvas.prototype.jpegStream = | ||
Canvas.prototype.createJPEGStream = function(options){ | ||
return new JPEGStream(this, options); | ||
}; | ||
Canvas.prototype.createJPEGStream = function (options) { | ||
return new JPEGStream(this, options) | ||
} | ||
Canvas.prototype.toDataURL = function(a1, a2, a3){ | ||
Canvas.prototype.toDataURL = function (a1, a2, a3) { | ||
// valid arg patterns (args -> [type, opts, fn]): | ||
@@ -67,26 +67,26 @@ // [] -> ['image/png', null, null] | ||
var type = 'image/png'; | ||
var opts = {}; | ||
var fn; | ||
let type = 'image/png' | ||
let opts = {} | ||
let fn | ||
if ('function' === typeof a1) { | ||
fn = a1; | ||
if (typeof a1 === 'function') { | ||
fn = a1 | ||
} else { | ||
if ('string' === typeof a1 && FORMATS.includes(a1.toLowerCase())) { | ||
type = a1.toLowerCase(); | ||
if (typeof a1 === 'string' && FORMATS.includes(a1.toLowerCase())) { | ||
type = a1.toLowerCase() | ||
} | ||
if ('function' === typeof a2) { | ||
fn = a2; | ||
if (typeof a2 === 'function') { | ||
fn = a2 | ||
} else { | ||
if ('object' === typeof a2) { | ||
opts = a2; | ||
} else if ('number' === typeof a2) { | ||
opts = {quality: Math.max(0, Math.min(1, a2))}; | ||
if (typeof a2 === 'object') { | ||
opts = a2 | ||
} else if (typeof a2 === 'number') { | ||
opts = { quality: Math.max(0, Math.min(1, a2)) } | ||
} | ||
if ('function' === typeof a3) { | ||
fn = a3; | ||
if (typeof a3 === 'function') { | ||
fn = a3 | ||
} else if (undefined !== a3) { | ||
throw new TypeError(typeof a3 + ' is not a function'); | ||
throw new TypeError(`${typeof a3} is not a function`) | ||
} | ||
@@ -98,8 +98,8 @@ } | ||
// Per spec, if the bitmap has no pixels, return this string: | ||
var str = "data:,"; | ||
const str = 'data:,' | ||
if (fn) { | ||
setTimeout(() => fn(null, str)); | ||
return; | ||
setTimeout(() => fn(null, str)) | ||
return | ||
} else { | ||
return str; | ||
return str | ||
} | ||
@@ -110,4 +110,4 @@ } | ||
this.toBuffer((err, buf) => { | ||
if (err) return fn(err); | ||
fn(null, `data:${type};base64,${buf.toString('base64')}`); | ||
if (err) return fn(err) | ||
fn(null, `data:${type};base64,${buf.toString('base64')}`) | ||
}, type, opts) | ||
@@ -117,2 +117,2 @@ } else { | ||
} | ||
}; | ||
} |
1023
lib/DOMMatrix.js
@@ -7,24 +7,22 @@ 'use strict' | ||
function DOMPoint(x, y, z, w) { | ||
if (!(this instanceof DOMPoint)) { | ||
throw new TypeError("Class constructors cannot be invoked without 'new'") | ||
class DOMPoint { | ||
constructor (x, y, z, w) { | ||
if (typeof x === 'object' && x !== null) { | ||
w = x.w | ||
z = x.z | ||
y = x.y | ||
x = x.x | ||
} | ||
this.x = typeof x === 'number' ? x : 0 | ||
this.y = typeof y === 'number' ? y : 0 | ||
this.z = typeof z === 'number' ? z : 0 | ||
this.w = typeof w === 'number' ? w : 1 | ||
} | ||
if (typeof x === 'object') { | ||
w = x.w | ||
z = x.z | ||
y = x.y | ||
x = x.x | ||
} | ||
this.x = typeof x === 'number' ? x : 0 | ||
this.y = typeof y === 'number' ? y : 0 | ||
this.z = typeof z === 'number' ? z : 0 | ||
this.w = typeof w === 'number' ? w : 1 | ||
} | ||
// Constants to index into _values (col-major) | ||
const M11 = 0, M12 = 1, M13 = 2, M14 = 3 | ||
const M21 = 4, M22 = 5, M23 = 6, M24 = 7 | ||
const M31 = 8, M32 = 9, M33 = 10, M34 = 11 | ||
const M41 = 12, M42 = 13, M43 = 14, M44 = 15 | ||
const M11 = 0; const M12 = 1; const M13 = 2; const M14 = 3 | ||
const M21 = 4; const M22 = 5; const M23 = 6; const M24 = 7 | ||
const M31 = 8; const M32 = 9; const M33 = 10; const M34 = 11 | ||
const M41 = 12; const M42 = 13; const M43 = 14; const M44 = 15 | ||
@@ -34,5 +32,5 @@ const DEGREE_PER_RAD = 180 / Math.PI | ||
function parseMatrix(init) { | ||
var parsed = init.replace(/matrix\(/, '') | ||
parsed = parsed.split(/,/, 7) // 6 + 1 to handle too many params | ||
function parseMatrix (init) { | ||
let parsed = init.replace('matrix(', '') | ||
parsed = parsed.split(',', 7) // 6 + 1 to handle too many params | ||
if (parsed.length !== 6) throw new Error(`Failed to parse ${init}`) | ||
@@ -48,5 +46,5 @@ parsed = parsed.map(parseFloat) | ||
function parseMatrix3d(init) { | ||
var parsed = init.replace(/matrix3d\(/, '') | ||
parsed = parsed.split(/,/, 17) // 16 + 1 to handle too many params | ||
function parseMatrix3d (init) { | ||
let parsed = init.replace('matrix3d(', '') | ||
parsed = parsed.split(',', 17) // 16 + 1 to handle too many params | ||
if (parsed.length !== 16) throw new Error(`Failed to parse ${init}`) | ||
@@ -56,4 +54,4 @@ return parsed.map(parseFloat) | ||
function parseTransform(tform) { | ||
var type = tform.split(/\(/, 1)[0] | ||
function parseTransform (tform) { | ||
const type = tform.split('(', 1)[0] | ||
switch (type) { | ||
@@ -70,545 +68,558 @@ case 'matrix': | ||
function DOMMatrix (init) { | ||
if (!(this instanceof DOMMatrix)) { | ||
throw new TypeError("Class constructors cannot be invoked without 'new'") | ||
class DOMMatrix { | ||
constructor (init) { | ||
this._is2D = true | ||
this._values = new Float64Array([ | ||
1, 0, 0, 0, | ||
0, 1, 0, 0, | ||
0, 0, 1, 0, | ||
0, 0, 0, 1 | ||
]) | ||
let i | ||
if (typeof init === 'string') { // parse CSS transformList | ||
if (init === '') return // default identity matrix | ||
const tforms = init.split(/\)\s+/, 20).map(parseTransform) | ||
if (tforms.length === 0) return | ||
init = tforms[0] | ||
for (i = 1; i < tforms.length; i++) init = multiply(tforms[i], init) | ||
} | ||
i = 0 | ||
if (init && init.length === 6) { | ||
setNumber2D(this, M11, init[i++]) | ||
setNumber2D(this, M12, init[i++]) | ||
setNumber2D(this, M21, init[i++]) | ||
setNumber2D(this, M22, init[i++]) | ||
setNumber2D(this, M41, init[i++]) | ||
setNumber2D(this, M42, init[i++]) | ||
} else if (init && init.length === 16) { | ||
setNumber2D(this, M11, init[i++]) | ||
setNumber2D(this, M12, init[i++]) | ||
setNumber3D(this, M13, init[i++]) | ||
setNumber3D(this, M14, init[i++]) | ||
setNumber2D(this, M21, init[i++]) | ||
setNumber2D(this, M22, init[i++]) | ||
setNumber3D(this, M23, init[i++]) | ||
setNumber3D(this, M24, init[i++]) | ||
setNumber3D(this, M31, init[i++]) | ||
setNumber3D(this, M32, init[i++]) | ||
setNumber3D(this, M33, init[i++]) | ||
setNumber3D(this, M34, init[i++]) | ||
setNumber2D(this, M41, init[i++]) | ||
setNumber2D(this, M42, init[i++]) | ||
setNumber3D(this, M43, init[i++]) | ||
setNumber3D(this, M44, init[i]) | ||
} else if (init !== undefined) { | ||
throw new TypeError('Expected string or array.') | ||
} | ||
} | ||
this._is2D = true | ||
this._values = new Float64Array([ | ||
1, 0, 0, 0, | ||
0, 1, 0, 0, | ||
0, 0, 1, 0, | ||
0, 0, 0, 1 | ||
]) | ||
toString () { | ||
return this.is2D | ||
? `matrix(${this.a}, ${this.b}, ${this.c}, ${this.d}, ${this.e}, ${this.f})` | ||
: `matrix3d(${this._values.join(', ')})` | ||
} | ||
var i | ||
multiply (other) { | ||
return newInstance(this._values).multiplySelf(other) | ||
} | ||
if (typeof init === 'string') { // parse CSS transformList | ||
if (init === '') return // default identity matrix | ||
var tforms = init.split(/\)\s+/, 20).map(parseTransform) | ||
if (tforms.length === 0) return | ||
init = tforms[0] | ||
for (i = 1; i < tforms.length; i++) init = multiply(tforms[i], init) | ||
multiplySelf (other) { | ||
this._values = multiply(other._values, this._values) | ||
if (!other.is2D) this._is2D = false | ||
return this | ||
} | ||
i = 0 | ||
if (init && init.length === 6) { | ||
setNumber2D(this, M11, init[i++]) | ||
setNumber2D(this, M12, init[i++]) | ||
setNumber2D(this, M21, init[i++]) | ||
setNumber2D(this, M22, init[i++]) | ||
setNumber2D(this, M41, init[i++]) | ||
setNumber2D(this, M42, init[i++]) | ||
} else if (init && init.length === 16) { | ||
setNumber2D(this, M11, init[i++]) | ||
setNumber2D(this, M12, init[i++]) | ||
setNumber3D(this, M13, init[i++]) | ||
setNumber3D(this, M14, init[i++]) | ||
setNumber2D(this, M21, init[i++]) | ||
setNumber2D(this, M22, init[i++]) | ||
setNumber3D(this, M23, init[i++]) | ||
setNumber3D(this, M24, init[i++]) | ||
setNumber3D(this, M31, init[i++]) | ||
setNumber3D(this, M32, init[i++]) | ||
setNumber3D(this, M33, init[i++]) | ||
setNumber3D(this, M34, init[i++]) | ||
setNumber2D(this, M41, init[i++]) | ||
setNumber2D(this, M42, init[i++]) | ||
setNumber3D(this, M43, init[i++]) | ||
setNumber3D(this, M44, init[i]) | ||
} else if (init !== undefined) { | ||
throw new TypeError('Expected string or array.') | ||
preMultiplySelf (other) { | ||
this._values = multiply(this._values, other._values) | ||
if (!other.is2D) this._is2D = false | ||
return this | ||
} | ||
} | ||
DOMMatrix.fromMatrix = function (init) { | ||
if (!(init instanceof DOMMatrix)) throw new TypeError('Expected DOMMatrix') | ||
return new DOMMatrix(init._values) | ||
} | ||
DOMMatrix.fromFloat32Array = function (init) { | ||
if (!(init instanceof Float32Array)) throw new TypeError('Expected Float32Array') | ||
return new DOMMatrix(init) | ||
} | ||
DOMMatrix.fromFloat64Array = function (init) { | ||
if (!(init instanceof Float64Array)) throw new TypeError('Expected Float64Array') | ||
return new DOMMatrix(init) | ||
} | ||
translate (tx, ty, tz) { | ||
return newInstance(this._values).translateSelf(tx, ty, tz) | ||
} | ||
// TODO || is for Node.js pre-v6.6.0 | ||
DOMMatrix.prototype[util.inspect.custom || 'inspect'] = function (depth, options) { | ||
if (depth < 0) return '[DOMMatrix]' | ||
translateSelf (tx, ty, tz) { | ||
if (typeof tx !== 'number') tx = 0 | ||
if (typeof ty !== 'number') ty = 0 | ||
if (typeof tz !== 'number') tz = 0 | ||
this._values = multiply([ | ||
1, 0, 0, 0, | ||
0, 1, 0, 0, | ||
0, 0, 1, 0, | ||
tx, ty, tz, 1 | ||
], this._values) | ||
if (tz !== 0) this._is2D = false | ||
return this | ||
} | ||
return `DOMMatrix [ | ||
a: ${this.a} | ||
b: ${this.b} | ||
c: ${this.c} | ||
d: ${this.d} | ||
e: ${this.e} | ||
f: ${this.f} | ||
m11: ${this.m11} | ||
m12: ${this.m12} | ||
m13: ${this.m13} | ||
m14: ${this.m14} | ||
m21: ${this.m21} | ||
m22: ${this.m22} | ||
m23: ${this.m23} | ||
m23: ${this.m23} | ||
m31: ${this.m31} | ||
m32: ${this.m32} | ||
m33: ${this.m33} | ||
m34: ${this.m34} | ||
m41: ${this.m41} | ||
m42: ${this.m42} | ||
m43: ${this.m43} | ||
m44: ${this.m44} | ||
is2D: ${this.is2D} | ||
isIdentity: ${this.isIdentity} ]` | ||
} | ||
scale (scaleX, scaleY, scaleZ, originX, originY, originZ) { | ||
return newInstance(this._values).scaleSelf(scaleX, scaleY, scaleZ, originX, originY, originZ) | ||
} | ||
DOMMatrix.prototype.toString = function () { | ||
return this.is2D ? | ||
`matrix(${this.a}, ${this.b}, ${this.c}, ${this.d}, ${this.e}, ${this.f})` : | ||
`matrix3d(${this._values.join(', ')})` | ||
} | ||
scale3d (scale, originX, originY, originZ) { | ||
return newInstance(this._values).scale3dSelf(scale, originX, originY, originZ) | ||
} | ||
/** | ||
* Checks that `value` is a number and sets the value. | ||
*/ | ||
function setNumber2D(receiver, index, value) { | ||
if (typeof value !== 'number') throw new TypeError('Expected number') | ||
return receiver._values[index] = value | ||
} | ||
scale3dSelf (scale, originX, originY, originZ) { | ||
return this.scaleSelf(scale, scale, scale, originX, originY, originZ) | ||
} | ||
/** | ||
* Checks that `value` is a number, sets `_is2D = false` if necessary and sets | ||
* the value. | ||
*/ | ||
function setNumber3D(receiver, index, value) { | ||
if (typeof value !== 'number') throw new TypeError('Expected number') | ||
if (index === M33 || index === M44) { | ||
if (value !== 1) receiver._is2D = false | ||
} else if (value !== 0) receiver._is2D = false | ||
return receiver._values[index] = value | ||
} | ||
scaleSelf (scaleX, scaleY, scaleZ, originX, originY, originZ) { | ||
// Not redundant with translate's checks because we need to negate the values later. | ||
if (typeof originX !== 'number') originX = 0 | ||
if (typeof originY !== 'number') originY = 0 | ||
if (typeof originZ !== 'number') originZ = 0 | ||
this.translateSelf(originX, originY, originZ) | ||
if (typeof scaleX !== 'number') scaleX = 1 | ||
if (typeof scaleY !== 'number') scaleY = scaleX | ||
if (typeof scaleZ !== 'number') scaleZ = 1 | ||
this._values = multiply([ | ||
scaleX, 0, 0, 0, | ||
0, scaleY, 0, 0, | ||
0, 0, scaleZ, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
this.translateSelf(-originX, -originY, -originZ) | ||
if (scaleZ !== 1 || originZ !== 0) this._is2D = false | ||
return this | ||
} | ||
Object.defineProperties(DOMMatrix.prototype, { | ||
m11: {get: function () { return this._values[M11] }, set: function (v) { return setNumber2D(this, M11, v) }}, | ||
m12: {get: function () { return this._values[M12] }, set: function (v) { return setNumber2D(this, M12, v) }}, | ||
m13: {get: function () { return this._values[M13] }, set: function (v) { return setNumber3D(this, M13, v) }}, | ||
m14: {get: function () { return this._values[M14] }, set: function (v) { return setNumber3D(this, M14, v) }}, | ||
m21: {get: function () { return this._values[M21] }, set: function (v) { return setNumber2D(this, M21, v) }}, | ||
m22: {get: function () { return this._values[M22] }, set: function (v) { return setNumber2D(this, M22, v) }}, | ||
m23: {get: function () { return this._values[M23] }, set: function (v) { return setNumber3D(this, M23, v) }}, | ||
m24: {get: function () { return this._values[M24] }, set: function (v) { return setNumber3D(this, M24, v) }}, | ||
m31: {get: function () { return this._values[M31] }, set: function (v) { return setNumber3D(this, M31, v) }}, | ||
m32: {get: function () { return this._values[M32] }, set: function (v) { return setNumber3D(this, M32, v) }}, | ||
m33: {get: function () { return this._values[M33] }, set: function (v) { return setNumber3D(this, M33, v) }}, | ||
m34: {get: function () { return this._values[M34] }, set: function (v) { return setNumber3D(this, M34, v) }}, | ||
m41: {get: function () { return this._values[M41] }, set: function (v) { return setNumber2D(this, M41, v) }}, | ||
m42: {get: function () { return this._values[M42] }, set: function (v) { return setNumber2D(this, M42, v) }}, | ||
m43: {get: function () { return this._values[M43] }, set: function (v) { return setNumber3D(this, M43, v) }}, | ||
m44: {get: function () { return this._values[M44] }, set: function (v) { return setNumber3D(this, M44, v) }}, | ||
rotateFromVector (x, y) { | ||
return newInstance(this._values).rotateFromVectorSelf(x, y) | ||
} | ||
a: {get: function () { return this.m11 }, set: function (v) { return this.m11 = v }}, | ||
b: {get: function () { return this.m12 }, set: function (v) { return this.m12 = v }}, | ||
c: {get: function () { return this.m21 }, set: function (v) { return this.m21 = v }}, | ||
d: {get: function () { return this.m22 }, set: function (v) { return this.m22 = v }}, | ||
e: {get: function () { return this.m41 }, set: function (v) { return this.m41 = v }}, | ||
f: {get: function () { return this.m42 }, set: function (v) { return this.m42 = v }}, | ||
rotateFromVectorSelf (x, y) { | ||
if (typeof x !== 'number') x = 0 | ||
if (typeof y !== 'number') y = 0 | ||
const theta = (x === 0 && y === 0) ? 0 : Math.atan2(y, x) * DEGREE_PER_RAD | ||
return this.rotateSelf(theta) | ||
} | ||
is2D: {get: function () { return this._is2D }}, // read-only | ||
rotate (rotX, rotY, rotZ) { | ||
return newInstance(this._values).rotateSelf(rotX, rotY, rotZ) | ||
} | ||
isIdentity: { | ||
get: function () { | ||
var values = this._values | ||
return values[M11] === 1 && values[M12] === 0 && values[M13] === 0 && values[M14] === 0 && | ||
values[M21] === 0 && values[M22] === 1 && values[M23] === 0 && values[M24] === 0 && | ||
values[M31] === 0 && values[M32] === 0 && values[M33] === 1 && values[M34] === 0 && | ||
values[M41] === 0 && values[M42] === 0 && values[M43] === 0 && values[M44] === 1 | ||
rotateSelf (rotX, rotY, rotZ) { | ||
if (rotY === undefined && rotZ === undefined) { | ||
rotZ = rotX | ||
rotX = rotY = 0 | ||
} | ||
if (typeof rotY !== 'number') rotY = 0 | ||
if (typeof rotZ !== 'number') rotZ = 0 | ||
if (rotX !== 0 || rotY !== 0) this._is2D = false | ||
rotX *= RAD_PER_DEGREE | ||
rotY *= RAD_PER_DEGREE | ||
rotZ *= RAD_PER_DEGREE | ||
let c, s | ||
c = Math.cos(rotZ) | ||
s = Math.sin(rotZ) | ||
this._values = multiply([ | ||
c, s, 0, 0, | ||
-s, c, 0, 0, | ||
0, 0, 1, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
c = Math.cos(rotY) | ||
s = Math.sin(rotY) | ||
this._values = multiply([ | ||
c, 0, -s, 0, | ||
0, 1, 0, 0, | ||
s, 0, c, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
c = Math.cos(rotX) | ||
s = Math.sin(rotX) | ||
this._values = multiply([ | ||
1, 0, 0, 0, | ||
0, c, s, 0, | ||
0, -s, c, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
return this | ||
} | ||
}) | ||
/** | ||
* Instantiates a DOMMatrix, bypassing the constructor. | ||
* @param {Float64Array} values Value to assign to `_values`. This is assigned | ||
* without copying (okay because all usages are followed by a multiply). | ||
*/ | ||
function newInstance(values) { | ||
var instance = Object.create(DOMMatrix.prototype) | ||
instance.constructor = DOMMatrix | ||
instance._is2D = true | ||
instance._values = values | ||
return instance | ||
} | ||
rotateAxisAngle (x, y, z, angle) { | ||
return newInstance(this._values).rotateAxisAngleSelf(x, y, z, angle) | ||
} | ||
function multiply(A, B) { | ||
var dest = new Float64Array(16) | ||
for (var i = 0; i < 4; i++) { | ||
for (var j = 0; j < 4; j++) { | ||
var sum = 0 | ||
for (var k = 0; k < 4; k++) { | ||
sum += A[i * 4 + k] * B[k * 4 + j] | ||
} | ||
dest[i * 4 + j] = sum | ||
rotateAxisAngleSelf (x, y, z, angle) { | ||
if (typeof x !== 'number') x = 0 | ||
if (typeof y !== 'number') y = 0 | ||
if (typeof z !== 'number') z = 0 | ||
// Normalize axis | ||
const length = Math.sqrt(x * x + y * y + z * z) | ||
if (length === 0) return this | ||
if (length !== 1) { | ||
x /= length | ||
y /= length | ||
z /= length | ||
} | ||
angle *= RAD_PER_DEGREE | ||
const c = Math.cos(angle) | ||
const s = Math.sin(angle) | ||
const t = 1 - c | ||
const tx = t * x | ||
const ty = t * y | ||
// NB: This is the generic transform. If the axis is a major axis, there are | ||
// faster transforms. | ||
this._values = multiply([ | ||
tx * x + c, tx * y + s * z, tx * z - s * y, 0, | ||
tx * y - s * z, ty * y + c, ty * z + s * x, 0, | ||
tx * z + s * y, ty * z - s * x, t * z * z + c, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
if (x !== 0 || y !== 0) this._is2D = false | ||
return this | ||
} | ||
return dest | ||
} | ||
DOMMatrix.prototype.multiply = function (other) { | ||
return newInstance(this._values).multiplySelf(other) | ||
} | ||
DOMMatrix.prototype.multiplySelf = function (other) { | ||
this._values = multiply(other._values, this._values) | ||
if (!other.is2D) this._is2D = false | ||
return this | ||
} | ||
DOMMatrix.prototype.preMultiplySelf = function (other) { | ||
this._values = multiply(this._values, other._values) | ||
if (!other.is2D) this._is2D = false | ||
return this | ||
} | ||
skewX (sx) { | ||
return newInstance(this._values).skewXSelf(sx) | ||
} | ||
DOMMatrix.prototype.translate = function (tx, ty, tz) { | ||
return newInstance(this._values).translateSelf(tx, ty, tz) | ||
} | ||
DOMMatrix.prototype.translateSelf = function (tx, ty, tz) { | ||
if (typeof tx !== 'number') tx = 0 | ||
if (typeof ty !== 'number') ty = 0 | ||
if (typeof tz !== 'number') tz = 0 | ||
this._values = multiply([ | ||
1, 0, 0, 0, | ||
0, 1, 0, 0, | ||
0, 0, 1, 0, | ||
tx, ty, tz, 1 | ||
], this._values) | ||
if (tz !== 0) this._is2D = false | ||
return this | ||
} | ||
skewXSelf (sx) { | ||
if (typeof sx !== 'number') return this | ||
const t = Math.tan(sx * RAD_PER_DEGREE) | ||
this._values = multiply([ | ||
1, 0, 0, 0, | ||
t, 1, 0, 0, | ||
0, 0, 1, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
return this | ||
} | ||
DOMMatrix.prototype.scale = function (scaleX, scaleY, scaleZ, originX, originY, originZ) { | ||
return newInstance(this._values).scaleSelf(scaleX, scaleY, scaleZ, originX, originY, originZ) | ||
} | ||
DOMMatrix.prototype.scale3d = function (scale, originX, originY, originZ) { | ||
return newInstance(this._values).scale3dSelf(scale, originX, originY, originZ) | ||
} | ||
DOMMatrix.prototype.scale3dSelf = function (scale, originX, originY, originZ) { | ||
return this.scaleSelf(scale, scale, scale, originX, originY, originZ) | ||
} | ||
DOMMatrix.prototype.scaleSelf = function (scaleX, scaleY, scaleZ, originX, originY, originZ) { | ||
// Not redundant with translate's checks because we need to negate the values later. | ||
if (typeof originX !== 'number') originX = 0 | ||
if (typeof originY !== 'number') originY = 0 | ||
if (typeof originZ !== 'number') originZ = 0 | ||
this.translateSelf(originX, originY, originZ) | ||
if (typeof scaleX !== 'number') scaleX = 1 | ||
if (typeof scaleY !== 'number') scaleY = scaleX | ||
if (typeof scaleZ !== 'number') scaleZ = 1 | ||
this._values = multiply([ | ||
scaleX, 0, 0, 0, | ||
0, scaleY, 0, 0, | ||
0, 0, scaleZ, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
this.translateSelf(-originX, -originY, -originZ) | ||
if (scaleZ !== 1 || originZ !== 0) this._is2D = false | ||
return this | ||
} | ||
skewY (sy) { | ||
return newInstance(this._values).skewYSelf(sy) | ||
} | ||
DOMMatrix.prototype.rotateFromVector = function (x, y) { | ||
return newInstance(this._values).rotateFromVectorSelf(x, y) | ||
} | ||
DOMMatrix.prototype.rotateFromVectorSelf = function (x, y) { | ||
if (typeof x !== 'number') x = 0 | ||
if (typeof y !== 'number') y = 0 | ||
var theta = (x === 0 && y === 0) ? 0 : Math.atan2(y, x) * DEGREE_PER_RAD | ||
return this.rotateSelf(theta) | ||
} | ||
DOMMatrix.prototype.rotate = function (rotX, rotY, rotZ) { | ||
return newInstance(this._values).rotateSelf(rotX, rotY, rotZ) | ||
} | ||
DOMMatrix.prototype.rotateSelf = function (rotX, rotY, rotZ) { | ||
if (rotY === undefined && rotZ === undefined) { | ||
rotZ = rotX | ||
rotX = rotY = 0 | ||
skewYSelf (sy) { | ||
if (typeof sy !== 'number') return this | ||
const t = Math.tan(sy * RAD_PER_DEGREE) | ||
this._values = multiply([ | ||
1, t, 0, 0, | ||
0, 1, 0, 0, | ||
0, 0, 1, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
return this | ||
} | ||
if (typeof rotY !== 'number') rotY = 0 | ||
if (typeof rotZ !== 'number') rotZ = 0 | ||
if (rotX !== 0 || rotY !== 0) this._is2D = false | ||
rotX *= RAD_PER_DEGREE | ||
rotY *= RAD_PER_DEGREE | ||
rotZ *= RAD_PER_DEGREE | ||
var c, s | ||
c = Math.cos(rotZ) | ||
s = Math.sin(rotZ) | ||
this._values = multiply([ | ||
c, s, 0, 0, | ||
-s, c, 0, 0, | ||
0, 0, 1, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
c = Math.cos(rotY) | ||
s = Math.sin(rotY) | ||
this._values = multiply([ | ||
c, 0, -s, 0, | ||
0, 1, 0, 0, | ||
s, 0, c, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
c = Math.cos(rotX) | ||
s = Math.sin(rotX) | ||
this._values = multiply([ | ||
1, 0, 0, 0, | ||
0, c, s, 0, | ||
0, -s, c, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
return this | ||
} | ||
DOMMatrix.prototype.rotateAxisAngle = function (x, y, z, angle) { | ||
return newInstance(this._values).rotateAxisAngleSelf(x, y, z, angle) | ||
} | ||
DOMMatrix.prototype.rotateAxisAngleSelf = function (x, y, z, angle) { | ||
if (typeof x !== 'number') x = 0 | ||
if (typeof y !== 'number') y = 0 | ||
if (typeof z !== 'number') z = 0 | ||
// Normalize axis | ||
var length = Math.sqrt(x * x + y * y + z * z) | ||
if (length === 0) return this | ||
if (length !== 1) { | ||
x /= length | ||
y /= length | ||
z /= length | ||
flipX () { | ||
return newInstance(multiply([ | ||
-1, 0, 0, 0, | ||
0, 1, 0, 0, | ||
0, 0, 1, 0, | ||
0, 0, 0, 1 | ||
], this._values)) | ||
} | ||
angle *= RAD_PER_DEGREE | ||
var c = Math.cos(angle) | ||
var s = Math.sin(angle) | ||
var t = 1 - c | ||
var tx = t * x | ||
var ty = t * y | ||
// NB: This is the generic transform. If the axis is a major axis, there are | ||
// faster transforms. | ||
this._values = multiply([ | ||
tx * x + c, tx * y + s * z, tx * z - s * y, 0, | ||
tx * y - s * z, ty * y + c, ty * z + s * x, 0, | ||
tx * z + s * y, ty * z - s * x, t * z * z + c, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
if (x !== 0 || y !== 0) this._is2D = false | ||
return this | ||
} | ||
DOMMatrix.prototype.skewX = function (sx) { | ||
return newInstance(this._values).skewXSelf(sx) | ||
} | ||
DOMMatrix.prototype.skewXSelf = function (sx) { | ||
if (typeof sx !== 'number') return this | ||
var t = Math.tan(sx * RAD_PER_DEGREE) | ||
this._values = multiply([ | ||
1, 0, 0, 0, | ||
t, 1, 0, 0, | ||
0, 0, 1, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
return this | ||
} | ||
flipY () { | ||
return newInstance(multiply([ | ||
1, 0, 0, 0, | ||
0, -1, 0, 0, | ||
0, 0, 1, 0, | ||
0, 0, 0, 1 | ||
], this._values)) | ||
} | ||
DOMMatrix.prototype.skewY = function (sy) { | ||
return newInstance(this._values).skewYSelf(sy) | ||
} | ||
DOMMatrix.prototype.skewYSelf = function (sy) { | ||
if (typeof sy !== 'number') return this | ||
var t = Math.tan(sy * RAD_PER_DEGREE) | ||
this._values = multiply([ | ||
1, t, 0, 0, | ||
0, 1, 0, 0, | ||
0, 0, 1, 0, | ||
0, 0, 0, 1 | ||
], this._values) | ||
return this | ||
} | ||
inverse () { | ||
return newInstance(this._values).invertSelf() | ||
} | ||
DOMMatrix.prototype.flipX = function () { | ||
return newInstance(multiply([ | ||
-1, 0, 0, 0, | ||
0, 1, 0, 0, | ||
0, 0, 1, 0, | ||
0, 0, 0, 1 | ||
], this._values)) | ||
} | ||
DOMMatrix.prototype.flipY = function () { | ||
return newInstance(multiply([ | ||
1, 0, 0, 0, | ||
0, -1, 0, 0, | ||
0, 0, 1, 0, | ||
0, 0, 0, 1 | ||
], this._values)) | ||
} | ||
invertSelf () { | ||
const m = this._values | ||
const inv = m.map(v => 0) | ||
DOMMatrix.prototype.inverse = function () { | ||
return newInstance(this._values).invertSelf() | ||
} | ||
DOMMatrix.prototype.invertSelf = function () { | ||
var m = this._values; | ||
var inv = m.map(v => 0); | ||
inv[0] = m[5] * m[10] * m[15] - | ||
m[5] * m[11] * m[14] - | ||
m[9] * m[6] * m[15] + | ||
m[9] * m[7] * m[14] + | ||
m[13] * m[6] * m[11] - | ||
m[13] * m[7] * m[10] | ||
inv[0] = m[5] * m[10] * m[15] - | ||
m[5] * m[11] * m[14] - | ||
m[9] * m[6] * m[15] + | ||
m[9] * m[7] * m[14] + | ||
m[13] * m[6] * m[11] - | ||
m[13] * m[7] * m[10]; | ||
inv[4] = -m[4] * m[10] * m[15] + | ||
m[4] * m[11] * m[14] + | ||
m[8] * m[6] * m[15] - | ||
m[8] * m[7] * m[14] - | ||
m[12] * m[6] * m[11] + | ||
m[12] * m[7] * m[10] | ||
inv[4] = -m[4] * m[10] * m[15] + | ||
m[4] * m[11] * m[14] + | ||
m[8] * m[6] * m[15] - | ||
m[8] * m[7] * m[14] - | ||
m[12] * m[6] * m[11] + | ||
m[12] * m[7] * m[10]; | ||
inv[8] = m[4] * m[9] * m[15] - | ||
m[4] * m[11] * m[13] - | ||
m[8] * m[5] * m[15] + | ||
m[8] * m[7] * m[13] + | ||
m[12] * m[5] * m[11] - | ||
m[12] * m[7] * m[9] | ||
inv[8] = m[4] * m[9] * m[15] - | ||
m[4] * m[11] * m[13] - | ||
m[8] * m[5] * m[15] + | ||
m[8] * m[7] * m[13] + | ||
m[12] * m[5] * m[11] - | ||
m[12] * m[7] * m[9]; | ||
inv[12] = -m[4] * m[9] * m[14] + | ||
m[4] * m[10] * m[13] + | ||
m[8] * m[5] * m[14] - | ||
m[8] * m[6] * m[13] - | ||
m[12] * m[5] * m[10] + | ||
m[12] * m[6] * m[9] | ||
inv[12] = -m[4] * m[9] * m[14] + | ||
m[4] * m[10] * m[13] + | ||
m[8] * m[5] * m[14] - | ||
m[8] * m[6] * m[13] - | ||
m[12] * m[5] * m[10] + | ||
m[12] * m[6] * m[9]; | ||
// If the determinant is zero, this matrix cannot be inverted, and all | ||
// values should be set to NaN, with the is2D flag set to false. | ||
// If the determinant is zero, this matrix cannot be inverted, and all | ||
// values should be set to NaN, with the is2D flag set to false. | ||
const det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12] | ||
var det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12]; | ||
if (det === 0) { | ||
this._values = m.map(v => NaN) | ||
this._is2D = false | ||
return this | ||
} | ||
if (det === 0) { | ||
this._values = m.map(v => NaN); | ||
this._is2D = false; | ||
return this; | ||
} | ||
inv[1] = -m[1] * m[10] * m[15] + | ||
m[1] * m[11] * m[14] + | ||
m[9] * m[2] * m[15] - | ||
m[9] * m[3] * m[14] - | ||
m[13] * m[2] * m[11] + | ||
m[13] * m[3] * m[10] | ||
inv[1] = -m[1] * m[10] * m[15] + | ||
m[1] * m[11] * m[14] + | ||
m[9] * m[2] * m[15] - | ||
m[9] * m[3] * m[14] - | ||
m[13] * m[2] * m[11] + | ||
m[13] * m[3] * m[10]; | ||
inv[5] = m[0] * m[10] * m[15] - | ||
m[0] * m[11] * m[14] - | ||
m[8] * m[2] * m[15] + | ||
m[8] * m[3] * m[14] + | ||
m[12] * m[2] * m[11] - | ||
m[12] * m[3] * m[10] | ||
inv[5] = m[0] * m[10] * m[15] - | ||
m[0] * m[11] * m[14] - | ||
m[8] * m[2] * m[15] + | ||
m[8] * m[3] * m[14] + | ||
m[12] * m[2] * m[11] - | ||
m[12] * m[3] * m[10]; | ||
inv[9] = -m[0] * m[9] * m[15] + | ||
m[0] * m[11] * m[13] + | ||
m[8] * m[1] * m[15] - | ||
m[8] * m[3] * m[13] - | ||
m[12] * m[1] * m[11] + | ||
m[12] * m[3] * m[9] | ||
inv[9] = -m[0] * m[9] * m[15] + | ||
m[0] * m[11] * m[13] + | ||
m[8] * m[1] * m[15] - | ||
m[8] * m[3] * m[13] - | ||
m[12] * m[1] * m[11] + | ||
m[12] * m[3] * m[9]; | ||
inv[13] = m[0] * m[9] * m[14] - | ||
m[0] * m[10] * m[13] - | ||
m[8] * m[1] * m[14] + | ||
m[8] * m[2] * m[13] + | ||
m[12] * m[1] * m[10] - | ||
m[12] * m[2] * m[9] | ||
inv[13] = m[0] * m[9] * m[14] - | ||
m[0] * m[10] * m[13] - | ||
m[8] * m[1] * m[14] + | ||
m[8] * m[2] * m[13] + | ||
m[12] * m[1] * m[10] - | ||
m[12] * m[2] * m[9]; | ||
inv[2] = m[1] * m[6] * m[15] - | ||
m[1] * m[7] * m[14] - | ||
m[5] * m[2] * m[15] + | ||
m[5] * m[3] * m[14] + | ||
m[13] * m[2] * m[7] - | ||
m[13] * m[3] * m[6] | ||
inv[2] = m[1] * m[6] * m[15] - | ||
m[1] * m[7] * m[14] - | ||
m[5] * m[2] * m[15] + | ||
m[5] * m[3] * m[14] + | ||
m[13] * m[2] * m[7] - | ||
m[13] * m[3] * m[6]; | ||
inv[6] = -m[0] * m[6] * m[15] + | ||
m[0] * m[7] * m[14] + | ||
m[4] * m[2] * m[15] - | ||
m[4] * m[3] * m[14] - | ||
m[12] * m[2] * m[7] + | ||
m[12] * m[3] * m[6] | ||
inv[6] = -m[0] * m[6] * m[15] + | ||
m[0] * m[7] * m[14] + | ||
m[4] * m[2] * m[15] - | ||
m[4] * m[3] * m[14] - | ||
m[12] * m[2] * m[7] + | ||
m[12] * m[3] * m[6]; | ||
inv[10] = m[0] * m[5] * m[15] - | ||
m[0] * m[7] * m[13] - | ||
m[4] * m[1] * m[15] + | ||
m[4] * m[3] * m[13] + | ||
m[12] * m[1] * m[7] - | ||
m[12] * m[3] * m[5] | ||
inv[10] = m[0] * m[5] * m[15] - | ||
m[0] * m[7] * m[13] - | ||
m[4] * m[1] * m[15] + | ||
m[4] * m[3] * m[13] + | ||
m[12] * m[1] * m[7] - | ||
m[12] * m[3] * m[5]; | ||
inv[14] = -m[0] * m[5] * m[14] + | ||
m[0] * m[6] * m[13] + | ||
m[4] * m[1] * m[14] - | ||
m[4] * m[2] * m[13] - | ||
m[12] * m[1] * m[6] + | ||
m[12] * m[2] * m[5] | ||
inv[14] = -m[0] * m[5] * m[14] + | ||
m[0] * m[6] * m[13] + | ||
m[4] * m[1] * m[14] - | ||
m[4] * m[2] * m[13] - | ||
m[12] * m[1] * m[6] + | ||
m[12] * m[2] * m[5]; | ||
inv[3] = -m[1] * m[6] * m[11] + | ||
m[1] * m[7] * m[10] + | ||
m[5] * m[2] * m[11] - | ||
m[5] * m[3] * m[10] - | ||
m[9] * m[2] * m[7] + | ||
m[9] * m[3] * m[6] | ||
inv[3] = -m[1] * m[6] * m[11] + | ||
m[1] * m[7] * m[10] + | ||
m[5] * m[2] * m[11] - | ||
m[5] * m[3] * m[10] - | ||
m[9] * m[2] * m[7] + | ||
m[9] * m[3] * m[6]; | ||
inv[7] = m[0] * m[6] * m[11] - | ||
m[0] * m[7] * m[10] - | ||
m[4] * m[2] * m[11] + | ||
m[4] * m[3] * m[10] + | ||
m[8] * m[2] * m[7] - | ||
m[8] * m[3] * m[6] | ||
inv[7] = m[0] * m[6] * m[11] - | ||
m[0] * m[7] * m[10] - | ||
m[4] * m[2] * m[11] + | ||
m[4] * m[3] * m[10] + | ||
m[8] * m[2] * m[7] - | ||
m[8] * m[3] * m[6]; | ||
inv[11] = -m[0] * m[5] * m[11] + | ||
m[0] * m[7] * m[9] + | ||
m[4] * m[1] * m[11] - | ||
m[4] * m[3] * m[9] - | ||
m[8] * m[1] * m[7] + | ||
m[8] * m[3] * m[5] | ||
inv[11] = -m[0] * m[5] * m[11] + | ||
m[0] * m[7] * m[9] + | ||
m[4] * m[1] * m[11] - | ||
m[4] * m[3] * m[9] - | ||
m[8] * m[1] * m[7] + | ||
m[8] * m[3] * m[5]; | ||
inv[15] = m[0] * m[5] * m[10] - | ||
m[0] * m[6] * m[9] - | ||
m[4] * m[1] * m[10] + | ||
m[4] * m[2] * m[9] + | ||
m[8] * m[1] * m[6] - | ||
m[8] * m[2] * m[5] | ||
inv[15] = m[0] * m[5] * m[10] - | ||
m[0] * m[6] * m[9] - | ||
m[4] * m[1] * m[10] + | ||
m[4] * m[2] * m[9] + | ||
m[8] * m[1] * m[6] - | ||
m[8] * m[2] * m[5]; | ||
inv.forEach((v, i) => { inv[i] = v / det }) | ||
this._values = inv | ||
return this | ||
} | ||
inv.forEach((v,i) => inv[i] = v/det); | ||
this._values = inv; | ||
return this | ||
setMatrixValue (transformList) { | ||
const temp = new DOMMatrix(transformList) | ||
this._values = temp._values | ||
this._is2D = temp._is2D | ||
return this | ||
} | ||
transformPoint (point) { | ||
point = new DOMPoint(point) | ||
const x = point.x | ||
const y = point.y | ||
const z = point.z | ||
const w = point.w | ||
const values = this._values | ||
const nx = values[M11] * x + values[M21] * y + values[M31] * z + values[M41] * w | ||
const ny = values[M12] * x + values[M22] * y + values[M32] * z + values[M42] * w | ||
const nz = values[M13] * x + values[M23] * y + values[M33] * z + values[M43] * w | ||
const nw = values[M14] * x + values[M24] * y + values[M34] * z + values[M44] * w | ||
return new DOMPoint(nx, ny, nz, nw) | ||
} | ||
toFloat32Array () { | ||
return Float32Array.from(this._values) | ||
} | ||
toFloat64Array () { | ||
return this._values.slice(0) | ||
} | ||
static fromMatrix (init) { | ||
if (!(init instanceof DOMMatrix)) throw new TypeError('Expected DOMMatrix') | ||
return new DOMMatrix(init._values) | ||
} | ||
static fromFloat32Array (init) { | ||
if (!(init instanceof Float32Array)) throw new TypeError('Expected Float32Array') | ||
return new DOMMatrix(init) | ||
} | ||
static fromFloat64Array (init) { | ||
if (!(init instanceof Float64Array)) throw new TypeError('Expected Float64Array') | ||
return new DOMMatrix(init) | ||
} | ||
[util.inspect.custom || 'inspect'] (depth, options) { | ||
if (depth < 0) return '[DOMMatrix]' | ||
return `DOMMatrix [ | ||
a: ${this.a} | ||
b: ${this.b} | ||
c: ${this.c} | ||
d: ${this.d} | ||
e: ${this.e} | ||
f: ${this.f} | ||
m11: ${this.m11} | ||
m12: ${this.m12} | ||
m13: ${this.m13} | ||
m14: ${this.m14} | ||
m21: ${this.m21} | ||
m22: ${this.m22} | ||
m23: ${this.m23} | ||
m23: ${this.m23} | ||
m31: ${this.m31} | ||
m32: ${this.m32} | ||
m33: ${this.m33} | ||
m34: ${this.m34} | ||
m41: ${this.m41} | ||
m42: ${this.m42} | ||
m43: ${this.m43} | ||
m44: ${this.m44} | ||
is2D: ${this.is2D} | ||
isIdentity: ${this.isIdentity} ]` | ||
} | ||
} | ||
DOMMatrix.prototype.setMatrixValue = function (transformList) { | ||
var temp = new DOMMatrix(transformList) | ||
this._values = temp._values | ||
this._is2D = temp._is2D | ||
return this | ||
/** | ||
* Checks that `value` is a number and sets the value. | ||
*/ | ||
function setNumber2D (receiver, index, value) { | ||
if (typeof value !== 'number') throw new TypeError('Expected number') | ||
return (receiver._values[index] = value) | ||
} | ||
DOMMatrix.prototype.transformPoint = function (point) { | ||
point = new DOMPoint(point) | ||
var x = point.x | ||
var y = point.y | ||
var z = point.z | ||
var w = point.w | ||
var values = this._values | ||
var nx = values[M11] * x + values[M21] * y + values[M31] * z + values[M41] * w | ||
var ny = values[M12] * x + values[M22] * y + values[M32] * z + values[M42] * w | ||
var nz = values[M13] * x + values[M23] * y + values[M33] * z + values[M43] * w | ||
var nw = values[M14] * x + values[M24] * y + values[M34] * z + values[M44] * w | ||
return new DOMPoint(nx, ny, nz, nw) | ||
/** | ||
* Checks that `value` is a number, sets `_is2D = false` if necessary and sets | ||
* the value. | ||
*/ | ||
function setNumber3D (receiver, index, value) { | ||
if (typeof value !== 'number') throw new TypeError('Expected number') | ||
if (index === M33 || index === M44) { | ||
if (value !== 1) receiver._is2D = false | ||
} else if (value !== 0) receiver._is2D = false | ||
return (receiver._values[index] = value) | ||
} | ||
DOMMatrix.prototype.toFloat32Array = function () { | ||
return Float32Array.from(this._values) | ||
Object.defineProperties(DOMMatrix.prototype, { | ||
m11: { get () { return this._values[M11] }, set (v) { return setNumber2D(this, M11, v) } }, | ||
m12: { get () { return this._values[M12] }, set (v) { return setNumber2D(this, M12, v) } }, | ||
m13: { get () { return this._values[M13] }, set (v) { return setNumber3D(this, M13, v) } }, | ||
m14: { get () { return this._values[M14] }, set (v) { return setNumber3D(this, M14, v) } }, | ||
m21: { get () { return this._values[M21] }, set (v) { return setNumber2D(this, M21, v) } }, | ||
m22: { get () { return this._values[M22] }, set (v) { return setNumber2D(this, M22, v) } }, | ||
m23: { get () { return this._values[M23] }, set (v) { return setNumber3D(this, M23, v) } }, | ||
m24: { get () { return this._values[M24] }, set (v) { return setNumber3D(this, M24, v) } }, | ||
m31: { get () { return this._values[M31] }, set (v) { return setNumber3D(this, M31, v) } }, | ||
m32: { get () { return this._values[M32] }, set (v) { return setNumber3D(this, M32, v) } }, | ||
m33: { get () { return this._values[M33] }, set (v) { return setNumber3D(this, M33, v) } }, | ||
m34: { get () { return this._values[M34] }, set (v) { return setNumber3D(this, M34, v) } }, | ||
m41: { get () { return this._values[M41] }, set (v) { return setNumber2D(this, M41, v) } }, | ||
m42: { get () { return this._values[M42] }, set (v) { return setNumber2D(this, M42, v) } }, | ||
m43: { get () { return this._values[M43] }, set (v) { return setNumber3D(this, M43, v) } }, | ||
m44: { get () { return this._values[M44] }, set (v) { return setNumber3D(this, M44, v) } }, | ||
a: { get () { return this.m11 }, set (v) { return (this.m11 = v) } }, | ||
b: { get () { return this.m12 }, set (v) { return (this.m12 = v) } }, | ||
c: { get () { return this.m21 }, set (v) { return (this.m21 = v) } }, | ||
d: { get () { return this.m22 }, set (v) { return (this.m22 = v) } }, | ||
e: { get () { return this.m41 }, set (v) { return (this.m41 = v) } }, | ||
f: { get () { return this.m42 }, set (v) { return (this.m42 = v) } }, | ||
is2D: { get () { return this._is2D } }, // read-only | ||
isIdentity: { | ||
get () { | ||
const values = this._values | ||
return (values[M11] === 1 && values[M12] === 0 && values[M13] === 0 && values[M14] === 0 && | ||
values[M21] === 0 && values[M22] === 1 && values[M23] === 0 && values[M24] === 0 && | ||
values[M31] === 0 && values[M32] === 0 && values[M33] === 1 && values[M34] === 0 && | ||
values[M41] === 0 && values[M42] === 0 && values[M43] === 0 && values[M44] === 1) | ||
} | ||
} | ||
}) | ||
/** | ||
* Instantiates a DOMMatrix, bypassing the constructor. | ||
* @param {Float64Array} values Value to assign to `_values`. This is assigned | ||
* without copying (okay because all usages are followed by a multiply). | ||
*/ | ||
function newInstance (values) { | ||
const instance = Object.create(DOMMatrix.prototype) | ||
instance.constructor = DOMMatrix | ||
instance._is2D = true | ||
instance._values = values | ||
return instance | ||
} | ||
DOMMatrix.prototype.toFloat64Array = function () { | ||
return this._values.slice(0) | ||
function multiply (A, B) { | ||
const dest = new Float64Array(16) | ||
for (let i = 0; i < 4; i++) { | ||
for (let j = 0; j < 4; j++) { | ||
let sum = 0 | ||
for (let k = 0; k < 4; k++) { | ||
sum += A[i * 4 + k] * B[k * 4 + j] | ||
} | ||
dest[i * 4 + j] = sum | ||
} | ||
} | ||
return dest | ||
} | ||
module.exports = {DOMMatrix, DOMPoint} | ||
module.exports = { DOMMatrix, DOMPoint } |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
'use strict' | ||
@@ -18,5 +18,5 @@ /*! | ||
// Lazily loaded simple-get | ||
let get; | ||
let get | ||
const {GetSource, SetSource} = bindings; | ||
const { GetSource, SetSource } = bindings | ||
@@ -34,3 +34,3 @@ Object.defineProperty(Image.prototype, 'src', { | ||
*/ | ||
set(val) { | ||
set (val) { | ||
if (typeof val === 'string') { | ||
@@ -42,3 +42,3 @@ if (/^\s*data:/.test(val)) { // data: URI | ||
const content = val.slice(commaI + 1) | ||
setSource(this, Buffer.from(content, isBase64 ? 'base64' : 'utf8'), val); | ||
setSource(this, Buffer.from(content, isBase64 ? 'base64' : 'utf8'), val) | ||
} else if (/^\s*https?:\/\//.test(val)) { // remote URL | ||
@@ -53,3 +53,3 @@ const onerror = err => { | ||
if (!get) get = require('simple-get'); | ||
if (!get) get = require('simple-get') | ||
@@ -66,33 +66,33 @@ get.concat(val, (err, res, data) => { | ||
} else { // local file path assumed | ||
setSource(this, val); | ||
setSource(this, val) | ||
} | ||
} else if (Buffer.isBuffer(val)) { | ||
setSource(this, val); | ||
setSource(this, val) | ||
} | ||
}, | ||
get() { | ||
get () { | ||
// TODO https://github.com/Automattic/node-canvas/issues/118 | ||
return getSource(this); | ||
return getSource(this) | ||
}, | ||
configurable: true | ||
}); | ||
}) | ||
// TODO || is for Node.js pre-v6.6.0 | ||
Image.prototype[util.inspect.custom || 'inspect'] = function(){ | ||
return '[Image' | ||
+ (this.complete ? ':' + this.width + 'x' + this.height : '') | ||
+ (this.src ? ' ' + this.src : '') | ||
+ (this.complete ? ' complete' : '') | ||
+ ']'; | ||
}; | ||
Image.prototype[util.inspect.custom || 'inspect'] = function () { | ||
return '[Image' + | ||
(this.complete ? ':' + this.width + 'x' + this.height : '') + | ||
(this.src ? ' ' + this.src : '') + | ||
(this.complete ? ' complete' : '') + | ||
']' | ||
} | ||
function getSource(img){ | ||
return img._originalSource || GetSource.call(img); | ||
function getSource (img) { | ||
return img._originalSource || GetSource.call(img) | ||
} | ||
function setSource(img, src, origSrc){ | ||
SetSource.call(img, src); | ||
img._originalSource = origSrc; | ||
function setSource (img, src, origSrc) { | ||
SetSource.call(img, src) | ||
img._originalSource = origSrc | ||
} |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
'use strict' | ||
@@ -9,38 +9,34 @@ /*! | ||
var Readable = require('stream').Readable; | ||
var util = require('util'); | ||
const { Readable } = require('stream') | ||
function noop () {} | ||
var JPEGStream = module.exports = function JPEGStream(canvas, options) { | ||
if (!(this instanceof JPEGStream)) { | ||
throw new TypeError("Class constructors cannot be invoked without 'new'"); | ||
} | ||
class JPEGStream extends Readable { | ||
constructor (canvas, options) { | ||
super() | ||
if (canvas.streamJPEGSync === undefined) { | ||
throw new Error("node-canvas was built without JPEG support."); | ||
if (canvas.streamJPEGSync === undefined) { | ||
throw new Error('node-canvas was built without JPEG support.') | ||
} | ||
this.options = options | ||
this.canvas = canvas | ||
} | ||
Readable.call(this); | ||
_read () { | ||
// For now we're not controlling the c++ code's data emission, so we only | ||
// call canvas.streamJPEGSync once and let it emit data at will. | ||
this._read = noop | ||
this.options = options; | ||
this.canvas = canvas; | ||
this.canvas.streamJPEGSync(this.options, (err, chunk) => { | ||
if (err) { | ||
this.emit('error', err) | ||
} else if (chunk) { | ||
this.push(chunk) | ||
} else { | ||
this.push(null) | ||
} | ||
}) | ||
} | ||
}; | ||
util.inherits(JPEGStream, Readable); | ||
function noop() {} | ||
JPEGStream.prototype._read = function _read() { | ||
// For now we're not controlling the c++ code's data emission, so we only | ||
// call canvas.streamJPEGSync once and let it emit data at will. | ||
this._read = noop; | ||
var self = this; | ||
self.canvas.streamJPEGSync(this.options, function(err, chunk){ | ||
if (err) { | ||
self.emit('error', err); | ||
} else if (chunk) { | ||
self.push(chunk); | ||
} else { | ||
self.push(null); | ||
} | ||
}); | ||
}; | ||
module.exports = JPEGStream |
@@ -8,7 +8,7 @@ 'use strict' | ||
const weights = 'bold|bolder|lighter|[1-9]00' | ||
, styles = 'italic|oblique' | ||
, variants = 'small-caps' | ||
, stretches = 'ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded' | ||
, units = 'px|pt|pc|in|cm|mm|%|em|ex|ch|rem|q' | ||
, string = '\'([^\']+)\'|"([^"]+)"|[\\w\\s-]+' | ||
const styles = 'italic|oblique' | ||
const variants = 'small-caps' | ||
const stretches = 'ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded' | ||
const units = 'px|pt|pc|in|cm|mm|%|em|ex|ch|rem|q' | ||
const string = '\'([^\']+)\'|"([^"]+)"|[\\w\\s-]+' | ||
@@ -18,9 +18,8 @@ // [ [ <‘font-style’> || <font-variant-css21> || <‘font-weight’> || <‘font-stretch’> ]? | ||
// https://drafts.csswg.org/css-fonts-3/#font-prop | ||
const weightRe = new RegExp('(' + weights + ') +', 'i') | ||
const styleRe = new RegExp('(' + styles + ') +', 'i') | ||
const variantRe = new RegExp('(' + variants + ') +', 'i') | ||
const stretchRe = new RegExp('(' + stretches + ') +', 'i') | ||
const weightRe = new RegExp(`(${weights}) +`, 'i') | ||
const styleRe = new RegExp(`(${styles}) +`, 'i') | ||
const variantRe = new RegExp(`(${variants}) +`, 'i') | ||
const stretchRe = new RegExp(`(${stretches}) +`, 'i') | ||
const sizeFamilyRe = new RegExp( | ||
'([\\d\\.]+)(' + units + ') *' | ||
+ '((?:' + string + ')( *, *(?:' + string + '))*)') | ||
`([\\d\\.]+)(${units}) *((?:${string})( *, *(?:${string}))*)`) | ||
@@ -44,3 +43,3 @@ /** | ||
module.exports = function (str) { | ||
module.exports = str => { | ||
// Cached | ||
@@ -67,3 +66,3 @@ if (cache[str]) return cache[str] | ||
// Stop search at `sizeFamily.index` | ||
let substr = str.substring(0, sizeFamily.index) | ||
const substr = str.substring(0, sizeFamily.index) | ||
if ((weight = weightRe.exec(substr))) font.weight = weight[1] | ||
@@ -70,0 +69,0 @@ if ((style = styleRe.exec(substr))) font.style = style[1] |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
'use strict' | ||
@@ -7,34 +7,30 @@ /*! | ||
var Readable = require('stream').Readable; | ||
var util = require('util'); | ||
const { Readable } = require('stream') | ||
function noop () {} | ||
var PDFStream = module.exports = function PDFStream(canvas, options) { | ||
if (!(this instanceof PDFStream)) { | ||
throw new TypeError("Class constructors cannot be invoked without 'new'"); | ||
class PDFStream extends Readable { | ||
constructor (canvas, options) { | ||
super() | ||
this.canvas = canvas | ||
this.options = options | ||
} | ||
Readable.call(this); | ||
_read () { | ||
// For now we're not controlling the c++ code's data emission, so we only | ||
// call canvas.streamPDFSync once and let it emit data at will. | ||
this._read = noop | ||
this.canvas = canvas; | ||
this.options = options; | ||
}; | ||
this.canvas.streamPDFSync((err, chunk, len) => { | ||
if (err) { | ||
this.emit('error', err) | ||
} else if (len) { | ||
this.push(chunk) | ||
} else { | ||
this.push(null) | ||
} | ||
}, this.options) | ||
} | ||
} | ||
util.inherits(PDFStream, Readable); | ||
function noop() {} | ||
PDFStream.prototype._read = function _read() { | ||
// For now we're not controlling the c++ code's data emission, so we only | ||
// call canvas.streamPDFSync once and let it emit data at will. | ||
this._read = noop; | ||
var self = this; | ||
self.canvas.streamPDFSync(function(err, chunk, len){ | ||
if (err) { | ||
self.emit('error', err); | ||
} else if (len) { | ||
self.push(chunk); | ||
} else { | ||
self.push(null); | ||
} | ||
}, this.options); | ||
}; | ||
module.exports = PDFStream |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
'use strict' | ||
@@ -9,39 +9,35 @@ /*! | ||
var Readable = require('stream').Readable; | ||
var util = require('util'); | ||
const { Readable } = require('stream') | ||
function noop () {} | ||
var PNGStream = module.exports = function PNGStream(canvas, options) { | ||
if (!(this instanceof PNGStream)) { | ||
throw new TypeError("Class constructors cannot be invoked without 'new'"); | ||
class PNGStream extends Readable { | ||
constructor (canvas, options) { | ||
super() | ||
if (options && | ||
options.palette instanceof Uint8ClampedArray && | ||
options.palette.length % 4 !== 0) { | ||
throw new Error('Palette length must be a multiple of 4.') | ||
} | ||
this.canvas = canvas | ||
this.options = options || {} | ||
} | ||
Readable.call(this); | ||
_read () { | ||
// For now we're not controlling the c++ code's data emission, so we only | ||
// call canvas.streamPNGSync once and let it emit data at will. | ||
this._read = noop | ||
if (options && | ||
options.palette instanceof Uint8ClampedArray && | ||
options.palette.length % 4 !== 0) { | ||
throw new Error("Palette length must be a multiple of 4."); | ||
this.canvas.streamPNGSync((err, chunk, len) => { | ||
if (err) { | ||
this.emit('error', err) | ||
} else if (len) { | ||
this.push(chunk) | ||
} else { | ||
this.push(null) | ||
} | ||
}, this.options) | ||
} | ||
this.canvas = canvas; | ||
this.options = options || {}; | ||
}; | ||
} | ||
util.inherits(PNGStream, Readable); | ||
function noop() {} | ||
PNGStream.prototype._read = function _read() { | ||
// For now we're not controlling the c++ code's data emission, so we only | ||
// call canvas.streamPNGSync once and let it emit data at will. | ||
this._read = noop; | ||
var self = this; | ||
self.canvas.streamPNGSync(function(err, chunk, len){ | ||
if (err) { | ||
self.emit('error', err); | ||
} else if (len) { | ||
self.push(chunk); | ||
} else { | ||
self.push(null); | ||
} | ||
}, self.options); | ||
}; | ||
module.exports = PNGStream |
{ | ||
"name": "canvas", | ||
"description": "Canvas graphics API backed by Cairo", | ||
"version": "2.8.0", | ||
"version": "2.9.0", | ||
"author": "TJ Holowaychuk <tj@learnboost.com>", | ||
@@ -51,4 +51,4 @@ "main": "index.js", | ||
"dependencies": { | ||
"nan": "^2.14.0", | ||
"@mapbox/node-pre-gyp": "^1.0.0", | ||
"nan": "^2.15.0", | ||
"simple-get": "^3.0.3" | ||
@@ -55,0 +55,0 @@ }, |
@@ -131,3 +131,3 @@ // TypeScript Version: 3.0 | ||
export class NodeCanvasRenderingContext2D extends CanvasRenderingContext2D { | ||
declare class NodeCanvasRenderingContext2D extends CanvasRenderingContext2D { | ||
/** | ||
@@ -134,0 +134,0 @@ * _Non-standard_. Defaults to 'good'. Affects pattern (gradient, image, |
@@ -1,6 +0,6 @@ | ||
var query = process.argv[2] | ||
var fs = require('fs') | ||
var childProcess = require('child_process') | ||
const query = process.argv[2] | ||
const fs = require('fs') | ||
const childProcess = require('child_process') | ||
var SYSTEM_PATHS = [ | ||
const SYSTEM_PATHS = [ | ||
'/lib', | ||
@@ -11,2 +11,3 @@ '/usr/lib', | ||
'/opt/local/lib', | ||
'/opt/homebrew/lib', | ||
'/usr/lib/x86_64-linux-gnu', | ||
@@ -26,4 +27,4 @@ '/usr/lib/i386-linux-gnu', | ||
function hasSystemLib (lib) { | ||
var libName = 'lib' + lib + '.+(so|dylib)' | ||
var libNameRegex = new RegExp(libName) | ||
const libName = 'lib' + lib + '.+(so|dylib)' | ||
const libNameRegex = new RegExp(libName) | ||
@@ -44,3 +45,3 @@ // Try using ldconfig on linux systems | ||
try { | ||
var dirListing = fs.readdirSync(systemPath) | ||
const dirListing = fs.readdirSync(systemPath) | ||
return dirListing.some(function (file) { | ||
@@ -106,3 +107,2 @@ return libNameRegex.test(file) | ||
case 'gif': | ||
case 'jpeg': | ||
case 'cairo': | ||
@@ -114,2 +114,4 @@ return hasSystemLib(query) | ||
return hasFreetype() | ||
case 'jpeg': | ||
return hasPkgconfigLib('libjpeg') | ||
case 'rsvg': | ||
@@ -116,0 +118,0 @@ return hasPkgconfigLib('librsvg-2.0') |
@@ -1,3 +0,3 @@ | ||
var fs = require('fs') | ||
var paths = ['C:/libjpeg-turbo'] | ||
const fs = require('fs') | ||
const paths = ['C:/libjpeg-turbo'] | ||
@@ -8,3 +8,3 @@ if (process.arch === 'x64') { | ||
paths.forEach(function(path){ | ||
paths.forEach(function (path) { | ||
if (exists(path)) { | ||
@@ -16,8 +16,8 @@ process.stdout.write(path) | ||
function exists(path) { | ||
function exists (path) { | ||
try { | ||
return fs.lstatSync(path).isDirectory() | ||
} catch(e) { | ||
} catch (e) { | ||
return false | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1466
344122
Updatednan@^2.15.0