@shqld/canvas 3.2.2-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +654 -0
- package/binding.gyp +229 -0
- package/browser.js +31 -0
- package/index.d.ts +507 -0
- package/index.js +94 -0
- package/lib/DOMMatrix.js +678 -0
- package/lib/bindings.js +113 -0
- package/lib/canvas.js +113 -0
- package/lib/context2d.js +11 -0
- package/lib/image.js +97 -0
- package/lib/jpegstream.js +41 -0
- package/lib/pattern.js +15 -0
- package/lib/pdfstream.js +35 -0
- package/lib/pngstream.js +42 -0
- package/package.json +77 -0
- package/scripts/install.js +19 -0
- package/src/Backends.h +9 -0
- package/src/Canvas.cc +1026 -0
- package/src/Canvas.h +128 -0
- package/src/CanvasError.h +37 -0
- package/src/CanvasGradient.cc +113 -0
- package/src/CanvasGradient.h +20 -0
- package/src/CanvasPattern.cc +129 -0
- package/src/CanvasPattern.h +33 -0
- package/src/CanvasRenderingContext2d.cc +3527 -0
- package/src/CanvasRenderingContext2d.h +238 -0
- package/src/CharData.h +233 -0
- package/src/FontParser.cc +605 -0
- package/src/FontParser.h +115 -0
- package/src/Image.cc +1719 -0
- package/src/Image.h +146 -0
- package/src/ImageData.cc +138 -0
- package/src/ImageData.h +26 -0
- package/src/InstanceData.h +12 -0
- package/src/JPEGStream.h +157 -0
- package/src/PNG.h +292 -0
- package/src/Point.h +11 -0
- package/src/Util.h +9 -0
- package/src/bmp/BMPParser.cc +459 -0
- package/src/bmp/BMPParser.h +60 -0
- package/src/bmp/LICENSE.md +24 -0
- package/src/closure.cc +52 -0
- package/src/closure.h +98 -0
- package/src/color.cc +796 -0
- package/src/color.h +30 -0
- package/src/dll_visibility.h +20 -0
- package/src/init.cc +114 -0
- package/src/register_font.cc +352 -0
- package/src/register_font.h +7 -0
- package/util/has_lib.js +119 -0
- package/util/win_jpeg_lookup.js +21 -0
package/lib/DOMMatrix.js
ADDED
|
@@ -0,0 +1,678 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const util = require('util')
|
|
4
|
+
|
|
5
|
+
// DOMMatrix per https://drafts.fxtf.org/geometry/#DOMMatrix
|
|
6
|
+
|
|
7
|
+
class DOMPoint {
|
|
8
|
+
constructor (x, y, z, w) {
|
|
9
|
+
if (typeof x === 'object' && x !== null) {
|
|
10
|
+
w = x.w
|
|
11
|
+
z = x.z
|
|
12
|
+
y = x.y
|
|
13
|
+
x = x.x
|
|
14
|
+
}
|
|
15
|
+
this.x = typeof x === 'number' ? x : 0
|
|
16
|
+
this.y = typeof y === 'number' ? y : 0
|
|
17
|
+
this.z = typeof z === 'number' ? z : 0
|
|
18
|
+
this.w = typeof w === 'number' ? w : 1
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
matrixTransform(init) {
|
|
22
|
+
// TODO: this next line is wrong. matrixTransform is supposed to only take
|
|
23
|
+
// an object with the DOMMatrix properties called DOMMatrixInit
|
|
24
|
+
const m = init instanceof DOMMatrix ? init : new DOMMatrix(init)
|
|
25
|
+
return m.transformPoint(this)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
toJSON() {
|
|
29
|
+
return {
|
|
30
|
+
x: this.x,
|
|
31
|
+
y: this.y,
|
|
32
|
+
z: this.z,
|
|
33
|
+
w: this.w
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static fromPoint(other) {
|
|
38
|
+
return new this(other.x, other.y, other.z, other.w)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Constants to index into _values (col-major)
|
|
43
|
+
const M11 = 0; const M12 = 1; const M13 = 2; const M14 = 3
|
|
44
|
+
const M21 = 4; const M22 = 5; const M23 = 6; const M24 = 7
|
|
45
|
+
const M31 = 8; const M32 = 9; const M33 = 10; const M34 = 11
|
|
46
|
+
const M41 = 12; const M42 = 13; const M43 = 14; const M44 = 15
|
|
47
|
+
|
|
48
|
+
const DEGREE_PER_RAD = 180 / Math.PI
|
|
49
|
+
const RAD_PER_DEGREE = Math.PI / 180
|
|
50
|
+
|
|
51
|
+
function parseMatrix (init) {
|
|
52
|
+
let parsed = init.replace('matrix(', '')
|
|
53
|
+
parsed = parsed.split(',', 7) // 6 + 1 to handle too many params
|
|
54
|
+
if (parsed.length !== 6) throw new Error(`Failed to parse ${init}`)
|
|
55
|
+
parsed = parsed.map(parseFloat)
|
|
56
|
+
return [
|
|
57
|
+
parsed[0], parsed[1], 0, 0,
|
|
58
|
+
parsed[2], parsed[3], 0, 0,
|
|
59
|
+
0, 0, 1, 0,
|
|
60
|
+
parsed[4], parsed[5], 0, 1
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function parseMatrix3d (init) {
|
|
65
|
+
let parsed = init.replace('matrix3d(', '')
|
|
66
|
+
parsed = parsed.split(',', 17) // 16 + 1 to handle too many params
|
|
67
|
+
if (parsed.length !== 16) throw new Error(`Failed to parse ${init}`)
|
|
68
|
+
return parsed.map(parseFloat)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function parseTransform (tform) {
|
|
72
|
+
const type = tform.split('(', 1)[0]
|
|
73
|
+
switch (type) {
|
|
74
|
+
case 'matrix':
|
|
75
|
+
return parseMatrix(tform)
|
|
76
|
+
case 'matrix3d':
|
|
77
|
+
return parseMatrix3d(tform)
|
|
78
|
+
// TODO This is supposed to support any CSS transform value.
|
|
79
|
+
default:
|
|
80
|
+
throw new Error(`${type} parsing not implemented`)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
class DOMMatrix {
|
|
85
|
+
constructor (init) {
|
|
86
|
+
this._is2D = true
|
|
87
|
+
this._values = new Float64Array([
|
|
88
|
+
1, 0, 0, 0,
|
|
89
|
+
0, 1, 0, 0,
|
|
90
|
+
0, 0, 1, 0,
|
|
91
|
+
0, 0, 0, 1
|
|
92
|
+
])
|
|
93
|
+
|
|
94
|
+
let i
|
|
95
|
+
|
|
96
|
+
if (typeof init === 'string') { // parse CSS transformList
|
|
97
|
+
if (init === '') return // default identity matrix
|
|
98
|
+
const tforms = init.split(/\)\s+/, 20).map(parseTransform)
|
|
99
|
+
if (tforms.length === 0) return
|
|
100
|
+
init = tforms[0]
|
|
101
|
+
for (i = 1; i < tforms.length; i++) init = multiply(tforms[i], init)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
i = 0
|
|
105
|
+
if (init && init.length === 6) {
|
|
106
|
+
setNumber2D(this, M11, init[i++])
|
|
107
|
+
setNumber2D(this, M12, init[i++])
|
|
108
|
+
setNumber2D(this, M21, init[i++])
|
|
109
|
+
setNumber2D(this, M22, init[i++])
|
|
110
|
+
setNumber2D(this, M41, init[i++])
|
|
111
|
+
setNumber2D(this, M42, init[i++])
|
|
112
|
+
} else if (init && init.length === 16) {
|
|
113
|
+
setNumber2D(this, M11, init[i++])
|
|
114
|
+
setNumber2D(this, M12, init[i++])
|
|
115
|
+
setNumber3D(this, M13, init[i++])
|
|
116
|
+
setNumber3D(this, M14, init[i++])
|
|
117
|
+
setNumber2D(this, M21, init[i++])
|
|
118
|
+
setNumber2D(this, M22, init[i++])
|
|
119
|
+
setNumber3D(this, M23, init[i++])
|
|
120
|
+
setNumber3D(this, M24, init[i++])
|
|
121
|
+
setNumber3D(this, M31, init[i++])
|
|
122
|
+
setNumber3D(this, M32, init[i++])
|
|
123
|
+
setNumber3D(this, M33, init[i++])
|
|
124
|
+
setNumber3D(this, M34, init[i++])
|
|
125
|
+
setNumber2D(this, M41, init[i++])
|
|
126
|
+
setNumber2D(this, M42, init[i++])
|
|
127
|
+
setNumber3D(this, M43, init[i++])
|
|
128
|
+
setNumber3D(this, M44, init[i])
|
|
129
|
+
} else if (init !== undefined) {
|
|
130
|
+
throw new TypeError('Expected string or array.')
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
toString () {
|
|
135
|
+
return this.is2D
|
|
136
|
+
? `matrix(${this.a}, ${this.b}, ${this.c}, ${this.d}, ${this.e}, ${this.f})`
|
|
137
|
+
: `matrix3d(${this._values.join(', ')})`
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
multiply (other) {
|
|
141
|
+
return newInstance(this._values).multiplySelf(other)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
multiplySelf (other) {
|
|
145
|
+
this._values = multiply(other._values, this._values)
|
|
146
|
+
if (!other.is2D) this._is2D = false
|
|
147
|
+
return this
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
preMultiplySelf (other) {
|
|
151
|
+
this._values = multiply(this._values, other._values)
|
|
152
|
+
if (!other.is2D) this._is2D = false
|
|
153
|
+
return this
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
translate (tx, ty, tz) {
|
|
157
|
+
return newInstance(this._values).translateSelf(tx, ty, tz)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
translateSelf (tx, ty, tz) {
|
|
161
|
+
if (typeof tx !== 'number') tx = 0
|
|
162
|
+
if (typeof ty !== 'number') ty = 0
|
|
163
|
+
if (typeof tz !== 'number') tz = 0
|
|
164
|
+
this._values = multiply([
|
|
165
|
+
1, 0, 0, 0,
|
|
166
|
+
0, 1, 0, 0,
|
|
167
|
+
0, 0, 1, 0,
|
|
168
|
+
tx, ty, tz, 1
|
|
169
|
+
], this._values)
|
|
170
|
+
if (tz !== 0) this._is2D = false
|
|
171
|
+
return this
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
scale (scaleX, scaleY, scaleZ, originX, originY, originZ) {
|
|
175
|
+
return newInstance(this._values).scaleSelf(scaleX, scaleY, scaleZ, originX, originY, originZ)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
scale3d (scale, originX, originY, originZ) {
|
|
179
|
+
return newInstance(this._values).scale3dSelf(scale, originX, originY, originZ)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
scale3dSelf (scale, originX, originY, originZ) {
|
|
183
|
+
return this.scaleSelf(scale, scale, scale, originX, originY, originZ)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @deprecated
|
|
188
|
+
*/
|
|
189
|
+
scaleNonUniform(scaleX, scaleY) {
|
|
190
|
+
return this.scale(scaleX, scaleY)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
scaleSelf (scaleX, scaleY, scaleZ, originX, originY, originZ) {
|
|
194
|
+
// Not redundant with translate's checks because we need to negate the values later.
|
|
195
|
+
if (typeof originX !== 'number') originX = 0
|
|
196
|
+
if (typeof originY !== 'number') originY = 0
|
|
197
|
+
if (typeof originZ !== 'number') originZ = 0
|
|
198
|
+
this.translateSelf(originX, originY, originZ)
|
|
199
|
+
if (typeof scaleX !== 'number') scaleX = 1
|
|
200
|
+
if (typeof scaleY !== 'number') scaleY = scaleX
|
|
201
|
+
if (typeof scaleZ !== 'number') scaleZ = 1
|
|
202
|
+
this._values = multiply([
|
|
203
|
+
scaleX, 0, 0, 0,
|
|
204
|
+
0, scaleY, 0, 0,
|
|
205
|
+
0, 0, scaleZ, 0,
|
|
206
|
+
0, 0, 0, 1
|
|
207
|
+
], this._values)
|
|
208
|
+
this.translateSelf(-originX, -originY, -originZ)
|
|
209
|
+
if (scaleZ !== 1 || originZ !== 0) this._is2D = false
|
|
210
|
+
return this
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
rotateFromVector (x, y) {
|
|
214
|
+
return newInstance(this._values).rotateFromVectorSelf(x, y)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
rotateFromVectorSelf (x, y) {
|
|
218
|
+
if (typeof x !== 'number') x = 0
|
|
219
|
+
if (typeof y !== 'number') y = 0
|
|
220
|
+
const theta = (x === 0 && y === 0) ? 0 : Math.atan2(y, x) * DEGREE_PER_RAD
|
|
221
|
+
return this.rotateSelf(theta)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
rotate (rotX, rotY, rotZ) {
|
|
225
|
+
return newInstance(this._values).rotateSelf(rotX, rotY, rotZ)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
rotateSelf (rotX, rotY, rotZ) {
|
|
229
|
+
if (rotY === undefined && rotZ === undefined) {
|
|
230
|
+
rotZ = rotX
|
|
231
|
+
rotX = rotY = 0
|
|
232
|
+
}
|
|
233
|
+
if (typeof rotY !== 'number') rotY = 0
|
|
234
|
+
if (typeof rotZ !== 'number') rotZ = 0
|
|
235
|
+
if (rotX !== 0 || rotY !== 0) this._is2D = false
|
|
236
|
+
rotX *= RAD_PER_DEGREE
|
|
237
|
+
rotY *= RAD_PER_DEGREE
|
|
238
|
+
rotZ *= RAD_PER_DEGREE
|
|
239
|
+
let c, s
|
|
240
|
+
c = Math.cos(rotZ)
|
|
241
|
+
s = Math.sin(rotZ)
|
|
242
|
+
this._values = multiply([
|
|
243
|
+
c, s, 0, 0,
|
|
244
|
+
-s, c, 0, 0,
|
|
245
|
+
0, 0, 1, 0,
|
|
246
|
+
0, 0, 0, 1
|
|
247
|
+
], this._values)
|
|
248
|
+
c = Math.cos(rotY)
|
|
249
|
+
s = Math.sin(rotY)
|
|
250
|
+
this._values = multiply([
|
|
251
|
+
c, 0, -s, 0,
|
|
252
|
+
0, 1, 0, 0,
|
|
253
|
+
s, 0, c, 0,
|
|
254
|
+
0, 0, 0, 1
|
|
255
|
+
], this._values)
|
|
256
|
+
c = Math.cos(rotX)
|
|
257
|
+
s = Math.sin(rotX)
|
|
258
|
+
this._values = multiply([
|
|
259
|
+
1, 0, 0, 0,
|
|
260
|
+
0, c, s, 0,
|
|
261
|
+
0, -s, c, 0,
|
|
262
|
+
0, 0, 0, 1
|
|
263
|
+
], this._values)
|
|
264
|
+
return this
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
rotateAxisAngle (x, y, z, angle) {
|
|
268
|
+
return newInstance(this._values).rotateAxisAngleSelf(x, y, z, angle)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
rotateAxisAngleSelf (x, y, z, angle) {
|
|
272
|
+
if (typeof x !== 'number') x = 0
|
|
273
|
+
if (typeof y !== 'number') y = 0
|
|
274
|
+
if (typeof z !== 'number') z = 0
|
|
275
|
+
// Normalize axis
|
|
276
|
+
const length = Math.sqrt(x * x + y * y + z * z)
|
|
277
|
+
if (length === 0) return this
|
|
278
|
+
if (length !== 1) {
|
|
279
|
+
x /= length
|
|
280
|
+
y /= length
|
|
281
|
+
z /= length
|
|
282
|
+
}
|
|
283
|
+
angle *= RAD_PER_DEGREE
|
|
284
|
+
const c = Math.cos(angle)
|
|
285
|
+
const s = Math.sin(angle)
|
|
286
|
+
const t = 1 - c
|
|
287
|
+
const tx = t * x
|
|
288
|
+
const ty = t * y
|
|
289
|
+
// NB: This is the generic transform. If the axis is a major axis, there are
|
|
290
|
+
// faster transforms.
|
|
291
|
+
this._values = multiply([
|
|
292
|
+
tx * x + c, tx * y + s * z, tx * z - s * y, 0,
|
|
293
|
+
tx * y - s * z, ty * y + c, ty * z + s * x, 0,
|
|
294
|
+
tx * z + s * y, ty * z - s * x, t * z * z + c, 0,
|
|
295
|
+
0, 0, 0, 1
|
|
296
|
+
], this._values)
|
|
297
|
+
if (x !== 0 || y !== 0) this._is2D = false
|
|
298
|
+
return this
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
skewX (sx) {
|
|
302
|
+
return newInstance(this._values).skewXSelf(sx)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
skewXSelf (sx) {
|
|
306
|
+
if (typeof sx !== 'number') return this
|
|
307
|
+
const t = Math.tan(sx * RAD_PER_DEGREE)
|
|
308
|
+
this._values = multiply([
|
|
309
|
+
1, 0, 0, 0,
|
|
310
|
+
t, 1, 0, 0,
|
|
311
|
+
0, 0, 1, 0,
|
|
312
|
+
0, 0, 0, 1
|
|
313
|
+
], this._values)
|
|
314
|
+
return this
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
skewY (sy) {
|
|
318
|
+
return newInstance(this._values).skewYSelf(sy)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
skewYSelf (sy) {
|
|
322
|
+
if (typeof sy !== 'number') return this
|
|
323
|
+
const t = Math.tan(sy * RAD_PER_DEGREE)
|
|
324
|
+
this._values = multiply([
|
|
325
|
+
1, t, 0, 0,
|
|
326
|
+
0, 1, 0, 0,
|
|
327
|
+
0, 0, 1, 0,
|
|
328
|
+
0, 0, 0, 1
|
|
329
|
+
], this._values)
|
|
330
|
+
return this
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
flipX () {
|
|
334
|
+
return newInstance(multiply([
|
|
335
|
+
-1, 0, 0, 0,
|
|
336
|
+
0, 1, 0, 0,
|
|
337
|
+
0, 0, 1, 0,
|
|
338
|
+
0, 0, 0, 1
|
|
339
|
+
], this._values))
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
flipY () {
|
|
343
|
+
return newInstance(multiply([
|
|
344
|
+
1, 0, 0, 0,
|
|
345
|
+
0, -1, 0, 0,
|
|
346
|
+
0, 0, 1, 0,
|
|
347
|
+
0, 0, 0, 1
|
|
348
|
+
], this._values))
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
inverse () {
|
|
352
|
+
return newInstance(this._values).invertSelf()
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
invertSelf () {
|
|
356
|
+
const m = this._values
|
|
357
|
+
const inv = m.map(v => 0)
|
|
358
|
+
|
|
359
|
+
inv[0] = m[5] * m[10] * m[15] -
|
|
360
|
+
m[5] * m[11] * m[14] -
|
|
361
|
+
m[9] * m[6] * m[15] +
|
|
362
|
+
m[9] * m[7] * m[14] +
|
|
363
|
+
m[13] * m[6] * m[11] -
|
|
364
|
+
m[13] * m[7] * m[10]
|
|
365
|
+
|
|
366
|
+
inv[4] = -m[4] * m[10] * m[15] +
|
|
367
|
+
m[4] * m[11] * m[14] +
|
|
368
|
+
m[8] * m[6] * m[15] -
|
|
369
|
+
m[8] * m[7] * m[14] -
|
|
370
|
+
m[12] * m[6] * m[11] +
|
|
371
|
+
m[12] * m[7] * m[10]
|
|
372
|
+
|
|
373
|
+
inv[8] = m[4] * m[9] * m[15] -
|
|
374
|
+
m[4] * m[11] * m[13] -
|
|
375
|
+
m[8] * m[5] * m[15] +
|
|
376
|
+
m[8] * m[7] * m[13] +
|
|
377
|
+
m[12] * m[5] * m[11] -
|
|
378
|
+
m[12] * m[7] * m[9]
|
|
379
|
+
|
|
380
|
+
inv[12] = -m[4] * m[9] * m[14] +
|
|
381
|
+
m[4] * m[10] * m[13] +
|
|
382
|
+
m[8] * m[5] * m[14] -
|
|
383
|
+
m[8] * m[6] * m[13] -
|
|
384
|
+
m[12] * m[5] * m[10] +
|
|
385
|
+
m[12] * m[6] * m[9]
|
|
386
|
+
|
|
387
|
+
// If the determinant is zero, this matrix cannot be inverted, and all
|
|
388
|
+
// values should be set to NaN, with the is2D flag set to false.
|
|
389
|
+
|
|
390
|
+
const det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12]
|
|
391
|
+
|
|
392
|
+
if (det === 0) {
|
|
393
|
+
this._values = m.map(v => NaN)
|
|
394
|
+
this._is2D = false
|
|
395
|
+
return this
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
inv[1] = -m[1] * m[10] * m[15] +
|
|
399
|
+
m[1] * m[11] * m[14] +
|
|
400
|
+
m[9] * m[2] * m[15] -
|
|
401
|
+
m[9] * m[3] * m[14] -
|
|
402
|
+
m[13] * m[2] * m[11] +
|
|
403
|
+
m[13] * m[3] * m[10]
|
|
404
|
+
|
|
405
|
+
inv[5] = m[0] * m[10] * m[15] -
|
|
406
|
+
m[0] * m[11] * m[14] -
|
|
407
|
+
m[8] * m[2] * m[15] +
|
|
408
|
+
m[8] * m[3] * m[14] +
|
|
409
|
+
m[12] * m[2] * m[11] -
|
|
410
|
+
m[12] * m[3] * m[10]
|
|
411
|
+
|
|
412
|
+
inv[9] = -m[0] * m[9] * m[15] +
|
|
413
|
+
m[0] * m[11] * m[13] +
|
|
414
|
+
m[8] * m[1] * m[15] -
|
|
415
|
+
m[8] * m[3] * m[13] -
|
|
416
|
+
m[12] * m[1] * m[11] +
|
|
417
|
+
m[12] * m[3] * m[9]
|
|
418
|
+
|
|
419
|
+
inv[13] = m[0] * m[9] * m[14] -
|
|
420
|
+
m[0] * m[10] * m[13] -
|
|
421
|
+
m[8] * m[1] * m[14] +
|
|
422
|
+
m[8] * m[2] * m[13] +
|
|
423
|
+
m[12] * m[1] * m[10] -
|
|
424
|
+
m[12] * m[2] * m[9]
|
|
425
|
+
|
|
426
|
+
inv[2] = m[1] * m[6] * m[15] -
|
|
427
|
+
m[1] * m[7] * m[14] -
|
|
428
|
+
m[5] * m[2] * m[15] +
|
|
429
|
+
m[5] * m[3] * m[14] +
|
|
430
|
+
m[13] * m[2] * m[7] -
|
|
431
|
+
m[13] * m[3] * m[6]
|
|
432
|
+
|
|
433
|
+
inv[6] = -m[0] * m[6] * m[15] +
|
|
434
|
+
m[0] * m[7] * m[14] +
|
|
435
|
+
m[4] * m[2] * m[15] -
|
|
436
|
+
m[4] * m[3] * m[14] -
|
|
437
|
+
m[12] * m[2] * m[7] +
|
|
438
|
+
m[12] * m[3] * m[6]
|
|
439
|
+
|
|
440
|
+
inv[10] = m[0] * m[5] * m[15] -
|
|
441
|
+
m[0] * m[7] * m[13] -
|
|
442
|
+
m[4] * m[1] * m[15] +
|
|
443
|
+
m[4] * m[3] * m[13] +
|
|
444
|
+
m[12] * m[1] * m[7] -
|
|
445
|
+
m[12] * m[3] * m[5]
|
|
446
|
+
|
|
447
|
+
inv[14] = -m[0] * m[5] * m[14] +
|
|
448
|
+
m[0] * m[6] * m[13] +
|
|
449
|
+
m[4] * m[1] * m[14] -
|
|
450
|
+
m[4] * m[2] * m[13] -
|
|
451
|
+
m[12] * m[1] * m[6] +
|
|
452
|
+
m[12] * m[2] * m[5]
|
|
453
|
+
|
|
454
|
+
inv[3] = -m[1] * m[6] * m[11] +
|
|
455
|
+
m[1] * m[7] * m[10] +
|
|
456
|
+
m[5] * m[2] * m[11] -
|
|
457
|
+
m[5] * m[3] * m[10] -
|
|
458
|
+
m[9] * m[2] * m[7] +
|
|
459
|
+
m[9] * m[3] * m[6]
|
|
460
|
+
|
|
461
|
+
inv[7] = m[0] * m[6] * m[11] -
|
|
462
|
+
m[0] * m[7] * m[10] -
|
|
463
|
+
m[4] * m[2] * m[11] +
|
|
464
|
+
m[4] * m[3] * m[10] +
|
|
465
|
+
m[8] * m[2] * m[7] -
|
|
466
|
+
m[8] * m[3] * m[6]
|
|
467
|
+
|
|
468
|
+
inv[11] = -m[0] * m[5] * m[11] +
|
|
469
|
+
m[0] * m[7] * m[9] +
|
|
470
|
+
m[4] * m[1] * m[11] -
|
|
471
|
+
m[4] * m[3] * m[9] -
|
|
472
|
+
m[8] * m[1] * m[7] +
|
|
473
|
+
m[8] * m[3] * m[5]
|
|
474
|
+
|
|
475
|
+
inv[15] = m[0] * m[5] * m[10] -
|
|
476
|
+
m[0] * m[6] * m[9] -
|
|
477
|
+
m[4] * m[1] * m[10] +
|
|
478
|
+
m[4] * m[2] * m[9] +
|
|
479
|
+
m[8] * m[1] * m[6] -
|
|
480
|
+
m[8] * m[2] * m[5]
|
|
481
|
+
|
|
482
|
+
inv.forEach((v, i) => { inv[i] = v / det })
|
|
483
|
+
this._values = inv
|
|
484
|
+
return this
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
setMatrixValue (transformList) {
|
|
488
|
+
const temp = new DOMMatrix(transformList)
|
|
489
|
+
this._values = temp._values
|
|
490
|
+
this._is2D = temp._is2D
|
|
491
|
+
return this
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
transformPoint (point) {
|
|
495
|
+
point = new DOMPoint(point)
|
|
496
|
+
const x = point.x
|
|
497
|
+
const y = point.y
|
|
498
|
+
const z = point.z
|
|
499
|
+
const w = point.w
|
|
500
|
+
const values = this._values
|
|
501
|
+
const nx = values[M11] * x + values[M21] * y + values[M31] * z + values[M41] * w
|
|
502
|
+
const ny = values[M12] * x + values[M22] * y + values[M32] * z + values[M42] * w
|
|
503
|
+
const nz = values[M13] * x + values[M23] * y + values[M33] * z + values[M43] * w
|
|
504
|
+
const nw = values[M14] * x + values[M24] * y + values[M34] * z + values[M44] * w
|
|
505
|
+
return new DOMPoint(nx, ny, nz, nw)
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
toFloat32Array () {
|
|
509
|
+
return Float32Array.from(this._values)
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
toFloat64Array () {
|
|
513
|
+
return this._values.slice(0)
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
static fromMatrix (init) {
|
|
517
|
+
if (!(init instanceof DOMMatrix)) throw new TypeError('Expected DOMMatrix')
|
|
518
|
+
return new DOMMatrix(init._values)
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
static fromFloat32Array (init) {
|
|
522
|
+
if (!(init instanceof Float32Array)) throw new TypeError('Expected Float32Array')
|
|
523
|
+
return new DOMMatrix(init)
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
static fromFloat64Array (init) {
|
|
527
|
+
if (!(init instanceof Float64Array)) throw new TypeError('Expected Float64Array')
|
|
528
|
+
return new DOMMatrix(init)
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
[util.inspect.custom || 'inspect'] (depth, options) {
|
|
532
|
+
if (depth < 0) return '[DOMMatrix]'
|
|
533
|
+
|
|
534
|
+
return `DOMMatrix [
|
|
535
|
+
a: ${this.a}
|
|
536
|
+
b: ${this.b}
|
|
537
|
+
c: ${this.c}
|
|
538
|
+
d: ${this.d}
|
|
539
|
+
e: ${this.e}
|
|
540
|
+
f: ${this.f}
|
|
541
|
+
m11: ${this.m11}
|
|
542
|
+
m12: ${this.m12}
|
|
543
|
+
m13: ${this.m13}
|
|
544
|
+
m14: ${this.m14}
|
|
545
|
+
m21: ${this.m21}
|
|
546
|
+
m22: ${this.m22}
|
|
547
|
+
m23: ${this.m23}
|
|
548
|
+
m23: ${this.m23}
|
|
549
|
+
m31: ${this.m31}
|
|
550
|
+
m32: ${this.m32}
|
|
551
|
+
m33: ${this.m33}
|
|
552
|
+
m34: ${this.m34}
|
|
553
|
+
m41: ${this.m41}
|
|
554
|
+
m42: ${this.m42}
|
|
555
|
+
m43: ${this.m43}
|
|
556
|
+
m44: ${this.m44}
|
|
557
|
+
is2D: ${this.is2D}
|
|
558
|
+
isIdentity: ${this.isIdentity} ]`
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Checks that `value` is a number and sets the value.
|
|
564
|
+
*/
|
|
565
|
+
function setNumber2D (receiver, index, value) {
|
|
566
|
+
if (typeof value !== 'number') throw new TypeError('Expected number')
|
|
567
|
+
return (receiver._values[index] = value)
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Checks that `value` is a number, sets `_is2D = false` if necessary and sets
|
|
572
|
+
* the value.
|
|
573
|
+
*/
|
|
574
|
+
function setNumber3D (receiver, index, value) {
|
|
575
|
+
if (typeof value !== 'number') throw new TypeError('Expected number')
|
|
576
|
+
if (index === M33 || index === M44) {
|
|
577
|
+
if (value !== 1) receiver._is2D = false
|
|
578
|
+
} else if (value !== 0) receiver._is2D = false
|
|
579
|
+
return (receiver._values[index] = value)
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
Object.defineProperties(DOMMatrix.prototype, {
|
|
583
|
+
m11: { get () { return this._values[M11] }, set (v) { return setNumber2D(this, M11, v) } },
|
|
584
|
+
m12: { get () { return this._values[M12] }, set (v) { return setNumber2D(this, M12, v) } },
|
|
585
|
+
m13: { get () { return this._values[M13] }, set (v) { return setNumber3D(this, M13, v) } },
|
|
586
|
+
m14: { get () { return this._values[M14] }, set (v) { return setNumber3D(this, M14, v) } },
|
|
587
|
+
m21: { get () { return this._values[M21] }, set (v) { return setNumber2D(this, M21, v) } },
|
|
588
|
+
m22: { get () { return this._values[M22] }, set (v) { return setNumber2D(this, M22, v) } },
|
|
589
|
+
m23: { get () { return this._values[M23] }, set (v) { return setNumber3D(this, M23, v) } },
|
|
590
|
+
m24: { get () { return this._values[M24] }, set (v) { return setNumber3D(this, M24, v) } },
|
|
591
|
+
m31: { get () { return this._values[M31] }, set (v) { return setNumber3D(this, M31, v) } },
|
|
592
|
+
m32: { get () { return this._values[M32] }, set (v) { return setNumber3D(this, M32, v) } },
|
|
593
|
+
m33: { get () { return this._values[M33] }, set (v) { return setNumber3D(this, M33, v) } },
|
|
594
|
+
m34: { get () { return this._values[M34] }, set (v) { return setNumber3D(this, M34, v) } },
|
|
595
|
+
m41: { get () { return this._values[M41] }, set (v) { return setNumber2D(this, M41, v) } },
|
|
596
|
+
m42: { get () { return this._values[M42] }, set (v) { return setNumber2D(this, M42, v) } },
|
|
597
|
+
m43: { get () { return this._values[M43] }, set (v) { return setNumber3D(this, M43, v) } },
|
|
598
|
+
m44: { get () { return this._values[M44] }, set (v) { return setNumber3D(this, M44, v) } },
|
|
599
|
+
|
|
600
|
+
a: { get () { return this.m11 }, set (v) { return (this.m11 = v) } },
|
|
601
|
+
b: { get () { return this.m12 }, set (v) { return (this.m12 = v) } },
|
|
602
|
+
c: { get () { return this.m21 }, set (v) { return (this.m21 = v) } },
|
|
603
|
+
d: { get () { return this.m22 }, set (v) { return (this.m22 = v) } },
|
|
604
|
+
e: { get () { return this.m41 }, set (v) { return (this.m41 = v) } },
|
|
605
|
+
f: { get () { return this.m42 }, set (v) { return (this.m42 = v) } },
|
|
606
|
+
|
|
607
|
+
is2D: { get () { return this._is2D } }, // read-only
|
|
608
|
+
|
|
609
|
+
isIdentity: {
|
|
610
|
+
get () {
|
|
611
|
+
const values = this._values
|
|
612
|
+
return (values[M11] === 1 && values[M12] === 0 && values[M13] === 0 && values[M14] === 0 &&
|
|
613
|
+
values[M21] === 0 && values[M22] === 1 && values[M23] === 0 && values[M24] === 0 &&
|
|
614
|
+
values[M31] === 0 && values[M32] === 0 && values[M33] === 1 && values[M34] === 0 &&
|
|
615
|
+
values[M41] === 0 && values[M42] === 0 && values[M43] === 0 && values[M44] === 1)
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
|
|
619
|
+
toJSON: {
|
|
620
|
+
value() {
|
|
621
|
+
return {
|
|
622
|
+
a: this.a,
|
|
623
|
+
b: this.b,
|
|
624
|
+
c: this.c,
|
|
625
|
+
d: this.d,
|
|
626
|
+
e: this.e,
|
|
627
|
+
f: this.f,
|
|
628
|
+
m11: this.m11,
|
|
629
|
+
m12: this.m12,
|
|
630
|
+
m13: this.m13,
|
|
631
|
+
m14: this.m14,
|
|
632
|
+
m21: this.m21,
|
|
633
|
+
m22: this.m22,
|
|
634
|
+
m23: this.m23,
|
|
635
|
+
m23: this.m23,
|
|
636
|
+
m31: this.m31,
|
|
637
|
+
m32: this.m32,
|
|
638
|
+
m33: this.m33,
|
|
639
|
+
m34: this.m34,
|
|
640
|
+
m41: this.m41,
|
|
641
|
+
m42: this.m42,
|
|
642
|
+
m43: this.m43,
|
|
643
|
+
m44: this.m44,
|
|
644
|
+
is2D: this.is2D,
|
|
645
|
+
isIdentity: this.isIdentity,
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
})
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Instantiates a DOMMatrix, bypassing the constructor.
|
|
653
|
+
* @param {Float64Array} values Value to assign to `_values`. This is assigned
|
|
654
|
+
* without copying (okay because all usages are followed by a multiply).
|
|
655
|
+
*/
|
|
656
|
+
function newInstance (values) {
|
|
657
|
+
const instance = Object.create(DOMMatrix.prototype)
|
|
658
|
+
instance.constructor = DOMMatrix
|
|
659
|
+
instance._is2D = true
|
|
660
|
+
instance._values = values
|
|
661
|
+
return instance
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
function multiply (A, B) {
|
|
665
|
+
const dest = new Float64Array(16)
|
|
666
|
+
for (let i = 0; i < 4; i++) {
|
|
667
|
+
for (let j = 0; j < 4; j++) {
|
|
668
|
+
let sum = 0
|
|
669
|
+
for (let k = 0; k < 4; k++) {
|
|
670
|
+
sum += A[i * 4 + k] * B[k * 4 + j]
|
|
671
|
+
}
|
|
672
|
+
dest[i * 4 + j] = sum
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
return dest
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
module.exports = { DOMMatrix, DOMPoint }
|