@ohos-ports/vi-canvas-mock 1.0.0-beta.0

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.
@@ -0,0 +1,1246 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _DOMMatrix = _interopRequireDefault(require("./DOMMatrix"));
8
+ var _CanvasPattern = _interopRequireDefault(require("./CanvasPattern"));
9
+ var _cssfontparser = _interopRequireDefault(require("cssfontparser"));
10
+ var _TextMetrics = _interopRequireDefault(require("./TextMetrics"));
11
+ var _createCanvasEvent = _interopRequireDefault(require("../mock/createCanvasEvent"));
12
+ var _Path2D = _interopRequireDefault(require("./Path2D"));
13
+ var _mooColor = require("moo-color");
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
16
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
17
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
18
+ const testFuncs = ['setLineDash', 'getLineDash', 'setTransform', 'getTransform', 'getImageData', 'save', 'restore', 'createPattern', 'createRadialGradient', 'addHitRegion', 'arc', 'arcTo', 'beginPath', 'clip', 'closePath', 'scale', 'stroke', 'clearHitRegions', 'clearRect', 'fillRect', 'strokeRect', 'rect', 'resetTransform', 'translate', 'moveTo', 'lineTo', 'bezierCurveTo', 'createLinearGradient', 'ellipse', 'measureText', 'rotate', 'drawImage', 'drawFocusIfNeeded', 'isPointInPath', 'isPointInStroke', 'putImageData', 'strokeText', 'fillText', 'quadraticCurveTo', 'removeHitRegion', 'fill', 'transform', 'scrollPathIntoView', 'createImageData'];
19
+ const compositeOperations = ['source-over', 'source-in', 'source-out', 'source-atop', 'destination-over', 'destination-in', 'destination-out', 'destination-atop', 'lighter', 'copy', 'xor', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'];
20
+ function getTransformSlice(ctx) {
21
+ return ctx._transformStack[ctx._stackIndex].slice();
22
+ }
23
+
24
+ /**
25
+ * Returns the string serialization of a CSS color, according to https://www.w3.org/TR/2dcontext/#serialization-of-a-color
26
+ */
27
+ function serializeColor(value) {
28
+ return value.getAlpha() === 1 ? value.toHex() : value.toRgb();
29
+ }
30
+ class CanvasRenderingContext2D {
31
+ /**
32
+ * Every time a function call would result in a drawing operation, it should be added to this array.
33
+ * This goes for only draw call functions.
34
+ */
35
+
36
+ __getDrawCalls() {
37
+ return this._drawCalls.slice();
38
+ }
39
+
40
+ /**
41
+ * Clear the list of draw calls
42
+ */
43
+ __clearDrawCalls() {
44
+ this._drawCalls = [];
45
+ }
46
+
47
+ /**
48
+ * Every time a function call results in something that would have modified the state of the context,
49
+ * an event is added to this array. This goes for every property set, and draw call.
50
+ */
51
+
52
+ __getEvents() {
53
+ return this._events.slice();
54
+ }
55
+
56
+ /**
57
+ * Clear the list of events
58
+ */
59
+ __clearEvents() {
60
+ this._events = [];
61
+ }
62
+
63
+ /**
64
+ * This array keeps track of the current path, so that fill and stroke operations can store the
65
+ * path.
66
+ */
67
+
68
+ __getPath() {
69
+ return this._path.slice();
70
+ }
71
+
72
+ /**
73
+ * Clear the path and reset it to a single beginPath event.
74
+ */
75
+ __clearPath() {
76
+ const event = (0, _createCanvasEvent.default)('beginPath', getTransformSlice(this), {});
77
+ // The clipping path should start after the initial beginPath instruction
78
+ this._clipIndex = 1;
79
+ this._path = [event];
80
+ }
81
+
82
+ /**
83
+ * Get the current clipping region.
84
+ */
85
+ __getClippingRegion() {
86
+ return this._clipStack[this._stackIndex];
87
+ }
88
+ constructor(canvas) {
89
+ _defineProperty(this, "_drawCalls", []);
90
+ _defineProperty(this, "_events", []);
91
+ _defineProperty(this, "_path", [(0, _createCanvasEvent.default)('beginPath', [1, 0, 0, 1, 0, 0], {})]);
92
+ _defineProperty(this, "_directionStack", ['inherit']);
93
+ _defineProperty(this, "_fillStyleStack", ['#000000']);
94
+ _defineProperty(this, "_filterStack", ['none']);
95
+ _defineProperty(this, "_fontStack", ['10px sans-serif']);
96
+ _defineProperty(this, "_globalAlphaStack", [1.0]);
97
+ _defineProperty(this, "_globalCompositeOperationStack", ['source-over']);
98
+ _defineProperty(this, "_imageSmoothingEnabledStack", [true]);
99
+ _defineProperty(this, "_imageSmoothingQualityStack", ['low']);
100
+ _defineProperty(this, "_lineCapStack", ['butt']);
101
+ _defineProperty(this, "_lineDashOffsetStack", [0]);
102
+ _defineProperty(this, "_lineDashStack", [[]]);
103
+ _defineProperty(this, "_lineJoinStack", ['miter']);
104
+ _defineProperty(this, "_lineWidthStack", [1]);
105
+ _defineProperty(this, "_miterLimitStack", [10]);
106
+ _defineProperty(this, "_shadowBlurStack", [0]);
107
+ _defineProperty(this, "_shadowColorStack", ['rgba(0, 0, 0, 0)']);
108
+ _defineProperty(this, "_shadowOffsetXStack", [0]);
109
+ _defineProperty(this, "_shadowOffsetYStack", [0]);
110
+ _defineProperty(this, "_stackIndex", 0);
111
+ _defineProperty(this, "_strokeStyleStack", ['#000000']);
112
+ _defineProperty(this, "_textAlignStack", ['start']);
113
+ _defineProperty(this, "_textBaselineStack", ['alphabetic']);
114
+ _defineProperty(this, "_transformStack", [[1, 0, 0, 1, 0, 0]]);
115
+ _defineProperty(this, "_clipStack", [[]]);
116
+ /**
117
+ * This index points to the next path item that should be written to the clipStack
118
+ * when ctx.clip() is called.
119
+ */
120
+ _defineProperty(this, "_clipIndex", 1);
121
+ testFuncs.forEach(key => {
122
+ this[key] = vi.fn(CanvasRenderingContext2D.prototype[key].bind(this));
123
+ });
124
+ this._canvas = canvas;
125
+ }
126
+ addHitRegion(options = {}) {
127
+ const {
128
+ path,
129
+ fillRule,
130
+ id,
131
+ parentID,
132
+ cursor,
133
+ control,
134
+ label,
135
+ role
136
+ } = options;
137
+ if (!path && !id) throw new DOMException('ConstraintError', "Failed to execute 'addHitRegion' on '" + this.constructor.name + "': Both id and control are null.");
138
+ if (fillRule && fillRule !== 'evenodd' && fillRule !== 'nonzero') throw new TypeError("Failed to execute 'addHitRegion' on '" + this.constructor.name + "': The provided value '" + fillRule + "' is not a valid enum value of type CanvasFillRule.");
139
+ this._events.push((0, _createCanvasEvent.default)('addHitRegion', getTransformSlice(this), {
140
+ path,
141
+ fillRule,
142
+ id,
143
+ parentID,
144
+ cursor,
145
+ control,
146
+ label,
147
+ role
148
+ }));
149
+ }
150
+ arc(x, y, radius, startAngle, endAngle, anticlockwise = false) {
151
+ if (arguments.length < 5) throw new TypeError("Failed to execute 'arc' on '" + this.constructor.name + "': 5 arguments required, but only " + arguments.length + ' present.');
152
+ const xResult = Number(x);
153
+ const yResult = Number(y);
154
+ const radiusResult = Number(radius);
155
+ const startAngleResult = Number(startAngle);
156
+ const endAngleResult = Number(endAngle);
157
+ const anticlockwiseResult = Boolean(anticlockwise);
158
+
159
+ // quick is finite check
160
+ if (!Number.isFinite(xResult + yResult + radiusResult + startAngleResult + endAngleResult)) return;
161
+ if (Number(radius) < 0) throw new DOMException('IndexSizeError', "Failed to execute 'arc' on '" + this.constructor.name + "': The radius provided (" + radius + ') is negative.');
162
+ const event = (0, _createCanvasEvent.default)('arc', getTransformSlice(this), {
163
+ x: xResult,
164
+ y: yResult,
165
+ radius: radiusResult,
166
+ startAngle: startAngleResult,
167
+ endAngle: endAngleResult,
168
+ anticlockwise: anticlockwiseResult
169
+ });
170
+ this._path.push(event);
171
+ this._events.push(event);
172
+ }
173
+ arcTo(cpx1, cpy1, cpx2, cpy2, radius) {
174
+ if (arguments.length < 5) throw new DOMException('IndexSizeError', "Failed to execute 'arcTo' on '" + this.constructor.name + "': 5 arguments required, but only " + arguments.length + ' present.');
175
+ const cpx1Result = Number(cpx1);
176
+ const cpy1Result = Number(cpy1);
177
+ const cpx2Result = Number(cpx2);
178
+ const cpy2Result = Number(cpy2);
179
+ const radiusResult = Number(radius);
180
+ if (!Number.isFinite(cpx1Result + cpx2Result + cpy1Result + cpy2Result + radiusResult)) return;
181
+ if (radiusResult < 0) throw new TypeError("Failed to execute 'arcTo' on '" + this.constructor.name + "': The radius provided (" + radius + ') is negative.');
182
+ const event = (0, _createCanvasEvent.default)('arcTo', getTransformSlice(this), {
183
+ cpx1: cpx1Result,
184
+ cpy1: cpy1Result,
185
+ cpx2: cpx2Result,
186
+ cpy2: cpy2Result,
187
+ radius: radiusResult
188
+ });
189
+ this._path.push(event);
190
+ this._events.push(event);
191
+ }
192
+ beginPath() {
193
+ this.__clearPath();
194
+ // push the generated beginPath to the event list
195
+ this._events.push(this._path[0]);
196
+ }
197
+ bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y) {
198
+ if (arguments.length < 6) throw new TypeError("Failed to execute 'bezierCurveTo' on '" + this.constructor.name + "': 6 arguments required, but only " + arguments.length + ' present.');
199
+ const cpx1Result = Number(cpx1);
200
+ const cpy1Result = Number(cpy1);
201
+ const cpx2Result = Number(cpx2);
202
+ const cpy2Result = Number(cpy2);
203
+ const xResult = Number(x);
204
+ const yResult = Number(y);
205
+ if (!Number.isFinite(cpx1Result + cpy1Result + cpx2Result + cpy2Result + xResult + yResult)) return;
206
+ const event = (0, _createCanvasEvent.default)('bezierCurveTo', getTransformSlice(this), {
207
+ cpx1,
208
+ cpy1,
209
+ cpx2,
210
+ cpy2,
211
+ x,
212
+ y
213
+ });
214
+ this._path.push(event);
215
+ this._events.push(event);
216
+ }
217
+ get canvas() {
218
+ return this._canvas;
219
+ }
220
+ clearHitRegions() {
221
+ const event = (0, _createCanvasEvent.default)('clearHitRegions', getTransformSlice(this), {});
222
+ this._events.push(event);
223
+ }
224
+ clearRect(x, y, width, height) {
225
+ if (arguments.length < 4) throw new TypeError("Failed to execute 'clearRect' on '" + this.constructor.name + "': 4 arguments required, but only " + arguments.length + ' present.');
226
+ const xResult = Number(x);
227
+ const yResult = Number(y);
228
+ const widthResult = Number(width);
229
+ const heightResult = Number(height);
230
+ if (!Number.isFinite(x + y + width + height)) return;
231
+ const event = (0, _createCanvasEvent.default)('clearRect', getTransformSlice(this), {
232
+ x: xResult,
233
+ y: yResult,
234
+ width: widthResult,
235
+ height: heightResult
236
+ });
237
+ this._events.push(event);
238
+ this._drawCalls.push(event);
239
+ }
240
+ clip(path, fillRule) {
241
+ let clipPath;
242
+ if (arguments.length === 0) {
243
+ fillRule = 'nonzero';
244
+ path = this._path.slice();
245
+ clipPath = path.slice(this._clipIndex);
246
+ this._clipIndex = path.length;
247
+ } else {
248
+ if (arguments.length === 1) fillRule = 'nonzero';
249
+ if (path instanceof _Path2D.default) {
250
+ fillRule = String(fillRule);
251
+ if (fillRule !== 'nonzero' && fillRule !== 'evenodd') throw new TypeError("Failed to execute 'clip' on '" + this.constructor.name + "': The provided value '" + fillRule + "' is not a valid enum value of type CanvasFillRule.");
252
+ path = path._path.slice();
253
+ clipPath = path;
254
+ } else {
255
+ fillRule = String(path);
256
+ if (fillRule !== 'nonzero' && fillRule !== 'evenodd') throw new TypeError("Failed to execute 'clip' on '" + this.constructor.name + "': The provided value '" + fillRule + "' is not a valid enum value of type CanvasFillRule.");
257
+ path = this._path.slice();
258
+ clipPath = path.slice(this._clipIndex);
259
+ this._clipIndex = path.length;
260
+ }
261
+ }
262
+ const event = (0, _createCanvasEvent.default)('clip', getTransformSlice(this), {
263
+ path,
264
+ fillRule
265
+ });
266
+ this._path.push(event);
267
+ this._events.push(event);
268
+ const currentClip = this._clipStack[this._stackIndex];
269
+ this._clipStack[this._stackIndex] = currentClip.concat(clipPath);
270
+ }
271
+ closePath() {
272
+ const event = (0, _createCanvasEvent.default)('closePath', getTransformSlice(this), {});
273
+ this._events.push(event);
274
+ this._path.push(event);
275
+ }
276
+ createImageData(width, height) {
277
+ if (arguments.length < 1) throw new TypeError("Failed to execute 'createImageData' on '" + this.constructor.name + "': 1 argument required, but only 0 present.");else if (arguments.length === 1) {
278
+ if (!(width instanceof ImageData)) throw new TypeError("Failed to execute 'createImageData' on '" + this.constructor.name + "': parameter 1 is not of type 'ImageData'.");
279
+ let result = new ImageData(width.width, width.height);
280
+ result.data.set(width.data);
281
+ const event = (0, _createCanvasEvent.default)('createImageData', getTransformSlice(this), {
282
+ width: width.width,
283
+ height: width.height
284
+ });
285
+ this._events.push(event);
286
+ return result;
287
+ } else {
288
+ width = Math.abs(Number(width));
289
+ height = Math.abs(Number(height));
290
+ if (!Number.isFinite(width) || width === 0) throw new TypeError("Failed to execute 'createImageData' on '" + this.constructor.name + "': The source width is 0.");
291
+ if (!Number.isFinite(height) || height === 0) throw new TypeError("Failed to execute 'createImageData' on '" + this.constructor.name + "': The source height is 0.");
292
+ const event = (0, _createCanvasEvent.default)('createImageData', getTransformSlice(this), {
293
+ width,
294
+ height
295
+ });
296
+ this._events.push(event);
297
+ return new ImageData(width, height);
298
+ }
299
+ }
300
+ createLinearGradient(x0, y0, x1, y1) {
301
+ if (arguments.length < 4) throw new TypeError("Failed to execute 'createLinearGradient' on '" + this.constructor.name + "': 4 arguments required, but only " + arguments.length + ' present.');
302
+ const x0Result = Number(x0);
303
+ const y0Result = Number(y0);
304
+ const x1Result = Number(x1);
305
+ const y1Result = Number(y1);
306
+ if (!Number.isFinite(x0Result + y0Result + x1Result + y1Result)) throw new TypeError("Failed to execute 'createLinearGradient' on '" + this.constructor.name + "': The provided double value is non-finite.");
307
+ const event = (0, _createCanvasEvent.default)('createLinearGradient', getTransformSlice(this), {
308
+ x0: x0Result,
309
+ y0: y0Result,
310
+ x1: x1Result,
311
+ y1: y1Result
312
+ });
313
+ this._events.push(event);
314
+ return new CanvasGradient();
315
+ }
316
+ createPattern(image, type) {
317
+ if (arguments.length === 1) throw new TypeError("Failed to execute 'createPattern' on '" + this.constructor.name + "': 2 arguments required, but only 1 present.");
318
+ if (type === null) type = 'repeat';
319
+ if (type === '') type = 'repeat';
320
+ if (type === 'repeat' || type === 'repeat-x' || type === 'repeat-y' || type === 'no-repeat') {
321
+ const event = (0, _createCanvasEvent.default)('createPattern', getTransformSlice(this), {
322
+ image,
323
+ type
324
+ });
325
+ if (image instanceof ImageBitmap) {
326
+ if (image._closed) throw new DOMException('InvalidStateError', "Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The image source is detached.");
327
+ this._events.push(event);
328
+ return new _CanvasPattern.default();
329
+ }
330
+ if (image instanceof HTMLImageElement) {
331
+ this._events.push(event);
332
+ return new _CanvasPattern.default();
333
+ }
334
+ if (image instanceof HTMLVideoElement) {
335
+ this._events.push(event);
336
+ return new _CanvasPattern.default();
337
+ }
338
+ if (image instanceof HTMLCanvasElement) {
339
+ this._events.push(event);
340
+ return new _CanvasPattern.default();
341
+ }
342
+ } else {
343
+ throw new TypeError("Failed to execute 'createPattern' on '" + this.constructor.name + "': The provided type ('" + type + "') is not one of 'repeat', 'no-repeat', 'repeat-x', or 'repeat-y'.");
344
+ }
345
+ throw new TypeError("Failed to execute 'createPattern' on '" + this.constructor.name + "': The provided value is not of type '(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)'");
346
+ }
347
+ createRadialGradient(x0, y0, r0, x1, y1, r1) {
348
+ if (arguments.length < 6) throw new TypeError("Failed to execute 'createRadialGradient' on '" + this.constructor.name + "': 6 arguments required, but only " + arguments.length + ' present.');
349
+ const x0Result = Number(x0);
350
+ const y0Result = Number(y0);
351
+ const r0Result = Number(r0);
352
+ const x1Result = Number(x1);
353
+ const y1Result = Number(y1);
354
+ const r1Result = Number(r1);
355
+ if (!Number.isFinite(x0Result + y0Result + r0Result + x1Result + y1Result + r1Result)) throw new TypeError("Failed to execute 'createRadialGradient' on '" + this.constructor.name + "': The provided double value is non-finite.");
356
+ if (r0Result < 0) throw new DOMException('IndexSizeError', "Failed to execute 'createRadialGradient' on '" + this.constructor.name + "': The r0 provided is less than 0.");
357
+ if (r1Result < 0) throw new DOMException('IndexSizeError', "Failed to execute 'createRadialGradient' on '" + this.constructor.name + "': The r1 provided is less than 0.");
358
+ const event = (0, _createCanvasEvent.default)('createRadialGradient', getTransformSlice(this), {
359
+ x0: x0Result,
360
+ y0: y0Result,
361
+ r0: r0Result,
362
+ x1: x1Result,
363
+ y1: y1Result,
364
+ r1: r1Result
365
+ });
366
+ this._events.push(event);
367
+ return new CanvasGradient();
368
+ }
369
+ set currentTransform(value) {
370
+ if (value instanceof _DOMMatrix.default) {
371
+ this._transformStack[this._stackIndex][0] = value.a;
372
+ this._transformStack[this._stackIndex][1] = value.b;
373
+ this._transformStack[this._stackIndex][2] = value.c;
374
+ this._transformStack[this._stackIndex][3] = value.d;
375
+ this._transformStack[this._stackIndex][4] = value.e;
376
+ this._transformStack[this._stackIndex][5] = value.f;
377
+ const event = (0, _createCanvasEvent.default)('currentTransform', getTransformSlice(this), {
378
+ a: value.a,
379
+ b: value.b,
380
+ c: value.c,
381
+ d: value.d,
382
+ e: value.e,
383
+ f: value.f
384
+ });
385
+ this._events.push(event);
386
+ }
387
+ }
388
+ get currentTransform() {
389
+ return new _DOMMatrix.default(this._transformStack[this._stackIndex]);
390
+ }
391
+ set direction(value) {
392
+ if (value === 'rtl' || value === 'ltr' || value === 'inherit') {
393
+ this._directionStack[this._stackIndex] = value;
394
+ const event = (0, _createCanvasEvent.default)('direction', getTransformSlice(this), {
395
+ value
396
+ });
397
+ this._events.push(event);
398
+ }
399
+ }
400
+ get direction() {
401
+ return this._directionStack[this._stackIndex];
402
+ }
403
+ drawFocusIfNeeded(path, element) {
404
+ if (arguments.length === 0) throw new TypeError("Failed to execute 'drawFocusIfNeeded' on '" + this.constructor.name + "': 1 argument required, but only 0 present.");
405
+ if (arguments.length === 2 && !(path instanceof _Path2D.default)) throw new TypeError("Failed to execute 'drawFocusIfNeeded' on '" + this.constructor.name + "': parameter 1 is not of type 'Path2D'.");
406
+ if (arguments.length === 1) {
407
+ element = path;
408
+ path = null;
409
+ }
410
+ if (!(element instanceof Element)) throw new TypeError("Failed to execute 'drawFocusIfNeeded' on '" + this.constructor.name + "': parameter " + arguments.length + " is not of type 'Element'.");
411
+ const event = (0, _createCanvasEvent.default)('drawFocusIfNeeded', getTransformSlice(this), {
412
+ path: path ? path._path : null,
413
+ element
414
+ });
415
+ this._events.push(event);
416
+ }
417
+ drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) {
418
+ if (arguments.length < 3) throw new TypeError("Failed to execute 'drawImage' on '" + this.constructor.name + "': 3 arguments required, but only " + arguments.length + ' present.');
419
+ if (arguments.length === 4 || arguments.length > 5 && arguments.length < 9) throw new TypeError("Failed to execute 'drawImage' on '" + this.constructor.name + "': Valid arities are: [3, 5, 9], but 4 arguments provided.");
420
+ let valid = false;
421
+ if (img instanceof HTMLImageElement) valid = true;
422
+ if (img instanceof ImageBitmap) {
423
+ if (img._closed) throw new DOMException('InvalidStateError', "DOMException: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The image source is detached.");
424
+ valid = true;
425
+ }
426
+ if (img instanceof HTMLVideoElement) valid = true;
427
+ if (img instanceof HTMLCanvasElement) valid = true;
428
+ if (!valid) throw new TypeError("Failed to execute 'drawImage' on '" + this.constructor.name + "': The provided value is not of type '(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)'");
429
+ const sxResult = Number(sx);
430
+ const syResult = Number(sy);
431
+ const sWidthResult = Number(sWidth);
432
+ const sHeightResult = Number(sHeight);
433
+ const dxResult = Number(dx);
434
+ const dyResult = Number(dy);
435
+ const dWidthResult = Number(dWidth);
436
+ const dHeightResult = Number(dHeight);
437
+ if (arguments.length === 3) {
438
+ if (!Number.isFinite(sxResult + syResult)) return;
439
+ sx = 0;
440
+ sy = 0;
441
+ sWidth = img.width;
442
+ sHeight = img.height;
443
+ dx = sxResult;
444
+ dy = syResult;
445
+ dWidth = img.width;
446
+ dHeight = img.height;
447
+ } else if (arguments.length === 5) {
448
+ if (!Number.isFinite(sxResult + syResult + sWidthResult + sHeightResult)) return;
449
+ sx = 0;
450
+ sy = 0;
451
+ sWidth = img.width;
452
+ sHeight = img.height;
453
+ dx = sxResult;
454
+ dy = syResult;
455
+ dWidth = sWidth;
456
+ dHeight = sHeight;
457
+ } else {
458
+ if (!Number.isFinite(sx + sy + sWidth + sHeight + dx + dy + dWidth + dHeight)) return;
459
+ sx = sxResult;
460
+ sy = syResult;
461
+ sWidth = sWidthResult;
462
+ sHeight = sHeightResult;
463
+ dx = dxResult;
464
+ dy = dyResult;
465
+ dWidth = dWidthResult;
466
+ dHeight = dHeightResult;
467
+ }
468
+ const event = (0, _createCanvasEvent.default)('drawImage', getTransformSlice(this), {
469
+ img,
470
+ sx,
471
+ sy,
472
+ sWidth,
473
+ sHeight,
474
+ dx,
475
+ dy,
476
+ dWidth,
477
+ dHeight
478
+ });
479
+ this._events.push(event);
480
+ this._drawCalls.push(event);
481
+ }
482
+ ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise = false) {
483
+ if (arguments.length < 7) throw new TypeError("Failed to execute 'ellipse' on '" + this.constructor.name + "': 6 arguments required, but only " + arguments.length + ' present.');
484
+ const xResult = Number(x);
485
+ const yResult = Number(y);
486
+ const radiusXResult = Number(radiusX);
487
+ const radiusYResult = Number(radiusY);
488
+ const rotationResult = Number(rotation);
489
+ const startAngleResult = Number(startAngle);
490
+ const endAngleResult = Number(endAngle);
491
+ const anticlockwiseResult = Boolean(anticlockwise);
492
+ if (!Number.isFinite(xResult + yResult + radiusXResult + radiusYResult + rotationResult + startAngleResult + endAngleResult)) return;
493
+ if (Number(radiusX) < 0) throw new DOMException('IndexSizeError', "Failed to execute 'ellipse' on '" + this.constructor.name + "': The major-axis radius provided (" + radiusX + ') is negative.');
494
+ if (Number(radiusY) < 0) throw new DOMException('IndexSizeError', "Failed to execute 'ellipse' on '" + this.constructor.name + "': The minor-axis radius provided (" + radiusY + ') is negative.');
495
+ const event = (0, _createCanvasEvent.default)('ellipse', getTransformSlice(this), {
496
+ x: xResult,
497
+ y: yResult,
498
+ radiusX: radiusXResult,
499
+ radiusY: radiusYResult,
500
+ rotation: rotationResult,
501
+ startAngle: startAngleResult,
502
+ endAngle: endAngleResult,
503
+ anticlockwise: anticlockwiseResult
504
+ });
505
+ this._path.push(event);
506
+ this._events.push(event);
507
+ }
508
+ fill(path, fillRule) {
509
+ if (arguments.length === 0) {
510
+ fillRule = 'nonzero';
511
+ path = this._path.slice();
512
+ } else {
513
+ if (arguments.length === 1) fillRule = 'nonzero';
514
+ if (path instanceof _Path2D.default) {
515
+ fillRule = String(fillRule);
516
+ if (fillRule !== 'nonzero' && fillRule !== 'evenodd') throw new TypeError("Failed to execute 'clip' on '" + this.constructor.name + "': The provided value '" + fillRule + "' is not a valid enum value of type CanvasFillRule.");
517
+ path = path._path.slice();
518
+ } else {
519
+ fillRule = String(path);
520
+ if (fillRule !== 'nonzero' && fillRule !== 'evenodd') throw new TypeError("Failed to execute 'clip' on '" + this.constructor.name + "': The provided value '" + fillRule + "' is not a valid enum value of type CanvasFillRule.");
521
+ path = this._path.slice();
522
+ }
523
+ }
524
+ const event = (0, _createCanvasEvent.default)('fill', getTransformSlice(this), {
525
+ path,
526
+ fillRule
527
+ });
528
+ this._events.push(event);
529
+ this._drawCalls.push(event);
530
+ }
531
+ fillRect(x, y, width, height) {
532
+ if (arguments.length < 4) throw new TypeError("Failed to execute 'fillRect' on '" + this.constructor.name + "': 4 arguments required, but only " + arguments.length + ' present.');
533
+ const xResult = Number(x);
534
+ const yResult = Number(y);
535
+ const widthResult = Number(width);
536
+ const heightResult = Number(height);
537
+ if (!Number.isFinite(x + y + width + height)) return;
538
+ const event = (0, _createCanvasEvent.default)('fillRect', getTransformSlice(this), {
539
+ x: xResult,
540
+ y: yResult,
541
+ width: widthResult,
542
+ height: heightResult
543
+ });
544
+ this._events.push(event);
545
+ this._drawCalls.push(event);
546
+ }
547
+ set fillStyle(value) {
548
+ let valid = false;
549
+ if (typeof value === 'string') {
550
+ try {
551
+ const result = new _mooColor.MooColor(value);
552
+ valid = true;
553
+ value = this._fillStyleStack[this._stackIndex] = serializeColor(result);
554
+ } catch (e) {
555
+ return;
556
+ }
557
+ } else if (value instanceof CanvasGradient || value instanceof _CanvasPattern.default) {
558
+ valid = true;
559
+ this._fillStyleStack[this._stackIndex] = value;
560
+ }
561
+ if (valid) {
562
+ const event = (0, _createCanvasEvent.default)('fillStyle', getTransformSlice(this), {
563
+ value
564
+ });
565
+ this._events.push(event);
566
+ }
567
+ }
568
+ get fillStyle() {
569
+ return this._fillStyleStack[this._stackIndex];
570
+ }
571
+ fillText(text, x, y, maxWidth) {
572
+ if (arguments.length < 3) throw new TypeError("Failed to execute 'fillText' on '" + this.constructor.name + "': 3 arguments required, but only " + arguments.length + ' present.');
573
+ const textResult = String(text);
574
+ const xResult = Number(x);
575
+ const yResult = Number(y);
576
+ const maxWidthResult = Number(maxWidth);
577
+ if (arguments.length === 3 && !Number.isFinite(xResult + yResult)) return;
578
+ if (arguments.length > 3 && !Number.isFinite(xResult + yResult + maxWidthResult)) return;
579
+ const event = (0, _createCanvasEvent.default)('fillText', getTransformSlice(this), {
580
+ text: textResult,
581
+ x: xResult,
582
+ y: yResult,
583
+ maxWidth: arguments.length === 3 ? null : maxWidthResult
584
+ });
585
+ this._events.push(event);
586
+ this._drawCalls.push(event);
587
+ }
588
+ set filter(value) {
589
+ if (value === '') value = 'none';
590
+ value = this._filterStack[this._stackIndex] = typeof value === 'string' ? value : 'none';
591
+ const event = (0, _createCanvasEvent.default)('filter', getTransformSlice(this), {
592
+ value
593
+ });
594
+ this._events.push(event);
595
+ }
596
+ get filter() {
597
+ return this._filterStack[this._stackIndex];
598
+ }
599
+ set font(value) {
600
+ let ex;
601
+ try {
602
+ const result = (0, _cssfontparser.default)(value);
603
+ value = this._fontStack[this._stackIndex] = result.toString();
604
+ const event = (0, _createCanvasEvent.default)('font', getTransformSlice(this), {
605
+ value
606
+ });
607
+ this._events.push(event);
608
+ } catch (ex) {}
609
+ }
610
+ get font() {
611
+ return this._fontStack[this._stackIndex];
612
+ }
613
+ getImageData() {
614
+ return new ImageData(this._canvas.width, this._canvas.height);
615
+ }
616
+ getLineDash() {
617
+ return this._lineDashStack[this._stackIndex];
618
+ }
619
+ getTransform() {
620
+ return new _DOMMatrix.default(this._transformStack[this._stackIndex]);
621
+ }
622
+ set globalAlpha(value) {
623
+ value = Number(value);
624
+ if (!Number.isFinite(value)) return;
625
+ if (value < 0) return;
626
+ if (value > 1) return;
627
+ this._globalAlphaStack[this._stackIndex] = value;
628
+ const event = (0, _createCanvasEvent.default)('globalAlpha', getTransformSlice(this), {
629
+ value
630
+ });
631
+ this._events.push(event);
632
+ }
633
+ get globalAlpha() {
634
+ return this._globalAlphaStack[this._stackIndex];
635
+ }
636
+ set globalCompositeOperation(value) {
637
+ if (compositeOperations.indexOf(value) !== -1) {
638
+ this._globalCompositeOperationStack[this._stackIndex] = value;
639
+ const event = (0, _createCanvasEvent.default)('globalCompositeOperation', getTransformSlice(this), {
640
+ value
641
+ });
642
+ this._events.push(event);
643
+ }
644
+ }
645
+ get globalCompositeOperation() {
646
+ return this._globalCompositeOperationStack[this._stackIndex];
647
+ }
648
+ set imageSmoothingEnabled(value) {
649
+ value = this._imageSmoothingEnabledStack[this._stackIndex] = Boolean(value);
650
+ const event = (0, _createCanvasEvent.default)('imageSmoothingEnabled', getTransformSlice(this), {
651
+ value
652
+ });
653
+ this._events.push(event);
654
+ }
655
+ get imageSmoothingEnabled() {
656
+ return this._imageSmoothingEnabledStack[this._stackIndex];
657
+ }
658
+ set imageSmoothingQuality(value) {
659
+ if (value === 'high' || value === 'medium' || value === 'low') {
660
+ this._imageSmoothingQualityStack[this._stackIndex] = value;
661
+ const event = (0, _createCanvasEvent.default)('imageSmoothingQuality', getTransformSlice(this), {
662
+ value
663
+ });
664
+ this._events.push(event);
665
+ }
666
+ }
667
+ get imageSmoothingQuality() {
668
+ return this._imageSmoothingQualityStack[this._stackIndex];
669
+ }
670
+ isPointInPath(path, x, y, fillRule = 'nonzero') {
671
+ if (arguments.length < 2) throw new TypeError("Failed to execute 'isPointInPath' on '" + this.constructor.name + "': 2 arguments required, but only " + arguments.length + ' present.');
672
+ if (!(path instanceof _Path2D.default)) {
673
+ if (arguments.length > 2) {
674
+ fillRule = y;
675
+ }
676
+ y = x;
677
+ x = path;
678
+ }
679
+ if (fillRule !== 'nonzero' && fillRule !== 'evenodd') throw new TypeError("Failed to execute 'isPointInPath' on '" + this.constructor.name + "': The provided value '" + fillRule + "' is not a valid enum value of type CanvasFillRule.");
680
+ const event = (0, _createCanvasEvent.default)('isPointInPath', getTransformSlice(this), {
681
+ x: Number(x),
682
+ y: Number(y),
683
+ fillRule,
684
+ path: path instanceof _Path2D.default ? path._path.slice() : this._path.slice()
685
+ });
686
+ this._events.push(event);
687
+ return false; // return false in a mocking environment, unless I can verify a point is actually within the path
688
+ }
689
+
690
+ isPointInStroke(path, x, y) {
691
+ if (arguments.length < 2) throw new TypeError("Failed to execute 'isPointInStroke' on '" + this.constructor.name + "': 2 arguments required, but only " + arguments.length + ' present.');
692
+ if (!(path instanceof _Path2D.default)) {
693
+ y = x;
694
+ x = path;
695
+ }
696
+ const event = (0, _createCanvasEvent.default)('isPointInPath', getTransformSlice(this), {
697
+ x: Number(x),
698
+ y: Number(y),
699
+ path: path instanceof _Path2D.default ? path._path.slice() : this._path.slice()
700
+ });
701
+ this._events.push(event);
702
+ return false; // return false in a mocking environment, unless I can verify a point is actually within the path
703
+ }
704
+
705
+ set lineCap(value) {
706
+ if (value === 'butt' || value === 'round' || value === 'square') {
707
+ this._lineCapStack[this._stackIndex] = value;
708
+ const event = (0, _createCanvasEvent.default)('lineCap', getTransformSlice(this), {
709
+ value
710
+ });
711
+ this._events.push(event);
712
+ }
713
+ }
714
+ get lineCap() {
715
+ return this._lineCapStack[this._stackIndex];
716
+ }
717
+ set lineDashOffset(value) {
718
+ const result = Number(value);
719
+ if (Number.isFinite(result)) {
720
+ this._lineDashOffsetStack[this._stackIndex] = result;
721
+ const event = (0, _createCanvasEvent.default)('lineDashOffset', getTransformSlice(this), {
722
+ value
723
+ });
724
+ this._events.push(event);
725
+ }
726
+ }
727
+ get lineDashOffset() {
728
+ return this._lineDashOffsetStack[this._stackIndex];
729
+ }
730
+ set lineJoin(value) {
731
+ if (value === 'round' || value === 'bevel' || value === 'miter') {
732
+ this._lineJoinStack[this._stackIndex] = value;
733
+ const event = (0, _createCanvasEvent.default)('lineJoin', getTransformSlice(this), {
734
+ value
735
+ });
736
+ this._events.push(event);
737
+ }
738
+ }
739
+ get lineJoin() {
740
+ return this._lineJoinStack[this._stackIndex];
741
+ }
742
+ lineTo(x, y) {
743
+ if (arguments.length < 2) throw new TypeError("Failed to execute 'lineTo' on '" + this.constructor.name + "': 2 arguments required, but only " + arguments.length + ' present.');
744
+ const xResult = Number(x);
745
+ const yResult = Number(y);
746
+ if (!Number.isFinite(xResult + yResult)) return;
747
+ const event = (0, _createCanvasEvent.default)('lineTo', getTransformSlice(this), {
748
+ x: xResult,
749
+ y: yResult
750
+ });
751
+ this._events.push(event);
752
+ this._path.push(event);
753
+ }
754
+ set lineWidth(value) {
755
+ const result = Number(value);
756
+ if (Number.isFinite(result) && result > 0) {
757
+ this._lineWidthStack[this._stackIndex] = result;
758
+ const event = (0, _createCanvasEvent.default)('lineWidth', getTransformSlice(this), {
759
+ value: result
760
+ });
761
+ this._events.push(event);
762
+ }
763
+ }
764
+ get lineWidth() {
765
+ return this._lineWidthStack[this._stackIndex];
766
+ }
767
+ measureText(text) {
768
+ if (arguments.length < 1) throw new TypeError("Failed to execute 'measureText' on '" + this.constructor.name + "': 1 argument required, but only 0 present.");
769
+ text = text == null ? '' : text;
770
+ text = text.toString();
771
+ const event = (0, _createCanvasEvent.default)('measureText', getTransformSlice(this), {
772
+ text
773
+ });
774
+ this._events.push(event);
775
+ return new _TextMetrics.default(text);
776
+ }
777
+ set miterLimit(value) {
778
+ const result = Number(value);
779
+ if (Number.isFinite(result) && result > 0) {
780
+ this._miterLimitStack[this._stackIndex] = result;
781
+ const event = (0, _createCanvasEvent.default)('lineWidth', getTransformSlice(this), {
782
+ value: result
783
+ });
784
+ this._events.push(event);
785
+ }
786
+ }
787
+ get miterLimit() {
788
+ return this._miterLimitStack[this._stackIndex];
789
+ }
790
+ moveTo(x, y) {
791
+ if (arguments.length < 2) throw new TypeError("Failed to execute 'moveTo' on '" + this.constructor.name + "': 2 arguments required, but only " + arguments.length + ' present.');
792
+ const xResult = Number(x);
793
+ const yResult = Number(y);
794
+ if (!Number.isFinite(x + y)) return;
795
+ const event = (0, _createCanvasEvent.default)('moveTo', getTransformSlice(this), {
796
+ x: xResult,
797
+ y: yResult
798
+ });
799
+ this._events.push(event);
800
+ this._path.push(event);
801
+ }
802
+ putImageData(data, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight) {
803
+ if (arguments.length < 3) throw new TypeError("Failed to execute 'putImageData' on '" + this.constructor.name + "': 3 arguments required, but only " + arguments.length + ' present.');
804
+ if (arguments.length > 3 && arguments.length < 7) throw new TypeError("Failed to execute 'putImageData' on '" + this.constructor.name + "': Valid arities are: [3, 7], but " + arguments.length + ' arguments provided.');
805
+ if (!(data instanceof ImageData)) throw new TypeError("Failed to execute 'putImageData' on '" + this.constructor.name + "': parameter 1 is not of type 'ImageData'.");
806
+ const xResult = Number(x);
807
+ const yResult = Number(y);
808
+ const dirtyXResult = Number(dirtyX);
809
+ const dirtyYResult = Number(dirtyY);
810
+ const dirtyWidthResult = Number(dirtyWidth);
811
+ const dirtyHeightResult = Number(dirtyHeight);
812
+ if (arguments.length === 3) {
813
+ if (!Number.isFinite(xResult + yResult)) return;
814
+ } else {
815
+ if (!Number.isFinite(xResult + yResult + dirtyXResult + dirtyYResult + dirtyWidthResult + dirtyHeightResult)) return;
816
+ }
817
+ const event = (0, _createCanvasEvent.default)('putImageData', getTransformSlice(this), {
818
+ x: xResult,
819
+ y: yResult,
820
+ dirtyX: dirtyXResult,
821
+ dirtyY: dirtyYResult,
822
+ dirtyWidth: dirtyWidthResult,
823
+ dirtyHeight: dirtyHeightResult
824
+ });
825
+ this._events.push(event);
826
+ }
827
+ quadraticCurveTo(cpx, cpy, x, y) {
828
+ if (arguments.length < 4) throw new TypeError("Failed to execute 'quadraticCurveTo' on '" + this.constructor.name + "': 4 arguments required, but only " + arguments.length + ' present.');
829
+ const cpxResult = Number(cpx);
830
+ const cpyResult = Number(cpy);
831
+ const xResult = Number(x);
832
+ const yResult = Number(y);
833
+ if (!Number.isFinite(cpxResult + cpyResult + xResult + yResult)) return;
834
+ const event = (0, _createCanvasEvent.default)('quadraticCurveTo', getTransformSlice(this), {
835
+ cpx: cpxResult,
836
+ cpy: cpyResult,
837
+ x: xResult,
838
+ y: yResult
839
+ });
840
+ this._events.push(event);
841
+ }
842
+ rect(x, y, width, height) {
843
+ if (arguments.length < 4) throw new TypeError("Failed to execute 'rect' on '" + this.constructor.name + "': 4 arguments required, but only " + arguments.length + ' present.');
844
+ if (!Number.isFinite(x + y + width + height)) return;
845
+ const xResult = Number(x);
846
+ const yResult = Number(y);
847
+ const widthResult = Number(width);
848
+ const heightResult = Number(height);
849
+ const event = (0, _createCanvasEvent.default)('rect', getTransformSlice(this), {
850
+ x: xResult,
851
+ y: yResult,
852
+ width: widthResult,
853
+ height: heightResult
854
+ });
855
+ this._events.push(event);
856
+ this._path.push(event);
857
+ }
858
+ removeHitRegion(id) {
859
+ if (arguments.length < 1) throw new TypeError("Failed to execute 'removeHitRegion' on '" + this.constructor.name + "': 1 argument required, but only " + arguments.length + ' present.');
860
+ const event = (0, _createCanvasEvent.default)('removeHitRegion', getTransformSlice(this), {
861
+ id
862
+ });
863
+ this._events.push(event);
864
+ }
865
+ resetTransform() {
866
+ this._transformStack[this._stackIndex][0] = 1;
867
+ this._transformStack[this._stackIndex][1] = 0;
868
+ this._transformStack[this._stackIndex][2] = 0;
869
+ this._transformStack[this._stackIndex][3] = 1;
870
+ this._transformStack[this._stackIndex][4] = 0;
871
+ this._transformStack[this._stackIndex][5] = 0;
872
+ const event = (0, _createCanvasEvent.default)('resetTransform', getTransformSlice(this), {
873
+ a: 1,
874
+ b: 0,
875
+ c: 0,
876
+ d: 1,
877
+ e: 0,
878
+ f: 0
879
+ });
880
+ this._events.push(event);
881
+ }
882
+ restore() {
883
+ if (this._stackIndex <= 0) return;
884
+ this._transformStack.pop();
885
+ this._clipStack.pop();
886
+ this._directionStack.pop();
887
+ this._fillStyleStack.pop();
888
+ this._filterStack.pop();
889
+ this._fontStack.pop();
890
+ this._globalAlphaStack.pop();
891
+ this._globalCompositeOperationStack.pop();
892
+ this._imageSmoothingEnabledStack.pop();
893
+ this._imageSmoothingQualityStack.pop();
894
+ this._lineCapStack.pop();
895
+ this._lineDashStack.pop();
896
+ this._lineDashOffsetStack.pop();
897
+ this._lineJoinStack.pop();
898
+ this._lineWidthStack.pop();
899
+ this._miterLimitStack.pop();
900
+ this._shadowBlurStack.pop();
901
+ this._shadowColorStack.pop();
902
+ this._shadowOffsetXStack.pop();
903
+ this._shadowOffsetYStack.pop();
904
+ this._strokeStyleStack.pop();
905
+ this._textAlignStack.pop();
906
+ this._textBaselineStack.pop();
907
+ this._stackIndex -= 1;
908
+ const event = (0, _createCanvasEvent.default)('restore', getTransformSlice(this), {});
909
+ this._events.push(event);
910
+ }
911
+ rotate(angle) {
912
+ if (arguments.length < 1) throw new TypeError("Failed to execute 'rotate' on '" + this.constructor.name + "': 1 argument required, but only 0 present.");
913
+ angle = Number(angle);
914
+ if (!Number.isFinite(angle)) return;
915
+ const a = this._transformStack[this._stackIndex][0];
916
+ const b = this._transformStack[this._stackIndex][1];
917
+ const c = this._transformStack[this._stackIndex][2];
918
+ const d = this._transformStack[this._stackIndex][3];
919
+ const cos = Math.cos(angle);
920
+ const sin = Math.sin(angle);
921
+ this._transformStack[this._stackIndex][0] = a * cos + c * sin;
922
+ this._transformStack[this._stackIndex][1] = b * cos + d * sin;
923
+ this._transformStack[this._stackIndex][2] = c * cos - a * sin;
924
+ this._transformStack[this._stackIndex][3] = d * cos - b * sin;
925
+ const event = (0, _createCanvasEvent.default)('rotate', getTransformSlice(this), {
926
+ angle
927
+ });
928
+ this._events.push(event);
929
+ }
930
+ save() {
931
+ const stackIndex = this._stackIndex;
932
+ this._transformStack.push(this._transformStack[stackIndex].slice());
933
+ this._directionStack.push(this._directionStack[stackIndex]);
934
+ this._fillStyleStack.push(this._fillStyleStack[stackIndex]);
935
+ this._filterStack.push(this._filterStack[stackIndex]);
936
+ this._fontStack.push(this._fontStack[stackIndex]);
937
+ this._globalAlphaStack.push(this._globalAlphaStack[stackIndex]);
938
+ this._globalCompositeOperationStack.push(this._globalCompositeOperationStack[stackIndex]);
939
+ this._imageSmoothingEnabledStack.push(this._imageSmoothingEnabledStack[stackIndex]);
940
+ this._imageSmoothingQualityStack.push(this._imageSmoothingQualityStack[stackIndex]);
941
+ this._lineCapStack.push(this._lineCapStack[stackIndex]);
942
+ this._lineDashStack.push(this._lineDashStack[stackIndex]);
943
+ this._lineDashOffsetStack.push(this._lineDashOffsetStack[stackIndex]);
944
+ this._lineJoinStack.push(this._lineJoinStack[stackIndex]);
945
+ this._lineWidthStack.push(this._lineWidthStack[stackIndex]);
946
+ this._miterLimitStack.push(this._miterLimitStack[stackIndex]);
947
+ this._shadowBlurStack.push(this._shadowBlurStack[stackIndex]);
948
+ this._shadowColorStack.push(this._shadowColorStack[stackIndex]);
949
+ this._shadowOffsetXStack.push(this._shadowOffsetXStack[stackIndex]);
950
+ this._shadowOffsetYStack.push(this._shadowOffsetYStack[stackIndex]);
951
+ this._strokeStyleStack.push(this._strokeStyleStack[stackIndex]);
952
+ this._textAlignStack.push(this._textAlignStack[stackIndex]);
953
+ this._textBaselineStack.push(this._textBaselineStack[stackIndex]);
954
+ this._clipStack.push(this._clipStack[stackIndex].slice());
955
+ this._stackIndex = stackIndex + 1;
956
+ const event = (0, _createCanvasEvent.default)('save', getTransformSlice(this), {});
957
+ this._events.push(event);
958
+ }
959
+ scale(x, y) {
960
+ if (arguments.length < 2) throw new TypeError("Failed to execute 'scale' on '" + this.constructor.name + "': 2 arguments required, but only " + arguments.length + ' present.');
961
+ const xResult = Number(x);
962
+ const yResult = Number(y);
963
+ if (Number.isFinite(xResult) && Number.isFinite(yResult)) {
964
+ this._transformStack[this._stackIndex][0] *= xResult;
965
+ this._transformStack[this._stackIndex][1] *= xResult;
966
+ this._transformStack[this._stackIndex][2] *= yResult;
967
+ this._transformStack[this._stackIndex][3] *= yResult;
968
+ const event = (0, _createCanvasEvent.default)('scale', getTransformSlice(this), {
969
+ x: xResult,
970
+ y: yResult
971
+ });
972
+ this._events.push(event);
973
+ }
974
+ }
975
+ scrollPathIntoView(path) {
976
+ if (arguments.length > 0 && path instanceof _Path2D.default) path = path._path.slice();else path = this._path.slice();
977
+ const event = (0, _createCanvasEvent.default)('scrollPathIntoView', getTransformSlice(this), {
978
+ path
979
+ });
980
+ this._events.push(event);
981
+ }
982
+ setLineDash(lineDash) {
983
+ const isSequence = [Array, Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array].reduce((left, right) => left || lineDash instanceof right, false);
984
+ if (!isSequence) throw new TypeError("Failed to execute 'setLineDash' on '" + this.constructor.name + "': The provided value cannot be converted to a sequence.");
985
+ let result = [];
986
+ for (let i = 0; i < lineDash.length; i++) {
987
+ const value = Number(lineDash[i]);
988
+ if (Number.isFinite(value) && value >= 0) {
989
+ result.push(value);
990
+ } else {
991
+ return;
992
+ }
993
+ }
994
+ result = this._lineDashStack[this._stackIndex] = result.length % 2 === 1 ? result.concat(result) : result;
995
+ const event = (0, _createCanvasEvent.default)('setLineDash', getTransformSlice(this), {
996
+ segments: result.slice()
997
+ });
998
+ this._events.push(event);
999
+ }
1000
+ setTransform(a, b, c, d, e, f) {
1001
+ if (arguments.length === 0) {
1002
+ a = 1;
1003
+ b = 0;
1004
+ c = 0;
1005
+ d = 1;
1006
+ e = 0;
1007
+ f = 0;
1008
+ } else if (arguments.length === 1) {
1009
+ if (a instanceof _DOMMatrix.default) {
1010
+ let transform = a;
1011
+ a = transform.a;
1012
+ b = transform.b;
1013
+ c = transform.c;
1014
+ d = transform.d;
1015
+ e = transform.e;
1016
+ f = transform.f;
1017
+ } else {
1018
+ throw new TypeError("Failed to execute 'setTransform' on '" + this.constructor.name + "': parameter " + a + " ('transform') is not an object.");
1019
+ }
1020
+ } else if (arguments.length < 6) {
1021
+ throw new TypeError("Failed to execute 'setTransform' on '" + this.constructor.name + "': Valid arities are: [0, 1, 6], but " + arguments.length + ' arguments provided.');
1022
+ }
1023
+ a = Number(a);
1024
+ b = Number(b);
1025
+ c = Number(c);
1026
+ d = Number(d);
1027
+ e = Number(e);
1028
+ f = Number(f);
1029
+ if (!Number.isFinite(a + b + c + d + e + f)) return;
1030
+ this._transformStack[this._stackIndex][0] = a;
1031
+ this._transformStack[this._stackIndex][1] = b;
1032
+ this._transformStack[this._stackIndex][2] = c;
1033
+ this._transformStack[this._stackIndex][3] = d;
1034
+ this._transformStack[this._stackIndex][4] = e;
1035
+ this._transformStack[this._stackIndex][5] = f;
1036
+ const event = (0, _createCanvasEvent.default)('setTransform', getTransformSlice(this), {
1037
+ a,
1038
+ b,
1039
+ c,
1040
+ d,
1041
+ e,
1042
+ f
1043
+ });
1044
+ this._events.push(event);
1045
+ }
1046
+ set shadowBlur(value) {
1047
+ const result = Number(value);
1048
+ if (Number.isFinite(result) && result > 0) {
1049
+ this._shadowBlurStack[this._stackIndex] = result;
1050
+ const event = (0, _createCanvasEvent.default)('shadowBlur', getTransformSlice(this), {
1051
+ value: result
1052
+ });
1053
+ this._events.push(event);
1054
+ }
1055
+ }
1056
+ get shadowBlur() {
1057
+ return this._shadowBlurStack[this._stackIndex];
1058
+ }
1059
+ set shadowColor(value) {
1060
+ if (typeof value === 'string') {
1061
+ try {
1062
+ const result = new _mooColor.MooColor(value);
1063
+ value = this._shadowColorStack[this._stackIndex] = serializeColor(result);
1064
+ } catch (e) {
1065
+ return;
1066
+ }
1067
+ const event = (0, _createCanvasEvent.default)('shadowColor', getTransformSlice(this), {
1068
+ value
1069
+ });
1070
+ this._events.push(event);
1071
+ }
1072
+ }
1073
+ get shadowColor() {
1074
+ return this._shadowColorStack[this._stackIndex];
1075
+ }
1076
+ set shadowOffsetX(value) {
1077
+ const result = Number(value);
1078
+ if (Number.isFinite(result)) {
1079
+ this._shadowOffsetXStack[this._stackIndex] = result;
1080
+ const event = (0, _createCanvasEvent.default)('shadowOffsetX', getTransformSlice(this), {
1081
+ value: result
1082
+ });
1083
+ this._events.push(event);
1084
+ }
1085
+ }
1086
+ get shadowOffsetX() {
1087
+ return this._shadowOffsetXStack[this._stackIndex];
1088
+ }
1089
+ set shadowOffsetY(value) {
1090
+ const result = Number(value);
1091
+ if (Number.isFinite(result)) {
1092
+ this._shadowOffsetXStack[this._stackIndex] = result;
1093
+ const event = (0, _createCanvasEvent.default)('shadowOffsetY', getTransformSlice(this), {
1094
+ value: result
1095
+ });
1096
+ this._events.push(event);
1097
+ }
1098
+ }
1099
+ get shadowOffsetY() {
1100
+ return this._shadowOffsetXStack[this._stackIndex];
1101
+ }
1102
+ stroke(path) {
1103
+ if (arguments.length === 0) {
1104
+ path = this._path.slice();
1105
+ } else {
1106
+ if (!(path instanceof _Path2D.default)) throw new TypeError("Failed to execute 'stroke' on '" + this.constructor.name + "': parameter 1 is not of type 'Path2D'.");
1107
+ path = path._path.slice();
1108
+ }
1109
+ const event = (0, _createCanvasEvent.default)('stroke', getTransformSlice(this), {
1110
+ path
1111
+ });
1112
+ this._events.push(event);
1113
+ this._drawCalls.push(event);
1114
+ }
1115
+ strokeRect(x, y, width, height) {
1116
+ if (arguments.length < 4) throw new TypeError("Failed to execute 'strokeRect' on '" + this.constructor.name + "': 4 arguments required, but only " + arguments.length + ' present.');
1117
+ x = Number(x);
1118
+ y = Number(y);
1119
+ width = Number(width);
1120
+ height = Number(height);
1121
+ if (!Number.isFinite(x + y + width + height)) return;
1122
+ const event = (0, _createCanvasEvent.default)('strokeRect', getTransformSlice(this), {
1123
+ x,
1124
+ y,
1125
+ width,
1126
+ height
1127
+ });
1128
+ this._events.push(event);
1129
+ this._drawCalls.push(event);
1130
+ }
1131
+ set strokeStyle(value) {
1132
+ let valid = false;
1133
+ if (typeof value === 'string') {
1134
+ try {
1135
+ const result = new _mooColor.MooColor(value);
1136
+ valid = true;
1137
+ value = this._strokeStyleStack[this._stackIndex] = serializeColor(result);
1138
+ } catch (e) {
1139
+ return;
1140
+ }
1141
+ } else if (value instanceof CanvasGradient || value instanceof _CanvasPattern.default) {
1142
+ valid = true;
1143
+ this._strokeStyleStack[this._stackIndex] = value;
1144
+ }
1145
+ if (valid) {
1146
+ const event = (0, _createCanvasEvent.default)('strokeStyle', getTransformSlice(this), {
1147
+ value
1148
+ });
1149
+ this._events.push(event);
1150
+ }
1151
+ }
1152
+ get strokeStyle() {
1153
+ return this._strokeStyleStack[this._stackIndex];
1154
+ }
1155
+ strokeText(text, x, y, maxWidth) {
1156
+ if (arguments.length < 3) throw new TypeError("Failed to execute 'strokeText' on '" + this.constructor.name + "': 3 arguments required, but only " + arguments.length + ' present.');
1157
+ const textResult = String(text);
1158
+ const xResult = Number(x);
1159
+ const yResult = Number(y);
1160
+ const maxWidthResult = Number(maxWidth);
1161
+ if (arguments.length === 3 && !Number.isFinite(xResult + yResult)) return;
1162
+ if (arguments.length > 3 && !Number.isFinite(xResult + yResult + maxWidthResult)) return;
1163
+ const event = (0, _createCanvasEvent.default)('strokeText', getTransformSlice(this), {
1164
+ text: textResult,
1165
+ x: xResult,
1166
+ y: yResult,
1167
+ maxWidth: arguments.length === 3 ? null : maxWidthResult
1168
+ });
1169
+ this._events.push(event);
1170
+ this._drawCalls.push(event);
1171
+ }
1172
+ set textAlign(value) {
1173
+ if (value === 'left' || value === 'right' || value === 'center' || value === 'start' || value === 'end') {
1174
+ this._textAlignStack[this._stackIndex] = value;
1175
+ const event = (0, _createCanvasEvent.default)('textAlign', getTransformSlice(this), {
1176
+ value
1177
+ });
1178
+ this._events.push(event);
1179
+ }
1180
+ }
1181
+ get textAlign() {
1182
+ return this._textAlignStack[this._stackIndex];
1183
+ }
1184
+ set textBaseline(value) {
1185
+ if (value === 'top' || value === 'hanging' || value === 'middle' || value === 'alphabetic' || value === 'ideographic' || value === 'bottom') {
1186
+ this._textBaselineStack[this._stackIndex] = value;
1187
+ const event = (0, _createCanvasEvent.default)('textBaseline', getTransformSlice(this), {
1188
+ value
1189
+ });
1190
+ this._events.push(event);
1191
+ }
1192
+ }
1193
+ get textBaseline() {
1194
+ return this._textBaselineStack[this._stackIndex];
1195
+ }
1196
+ transform(a, b, c, d, e, f) {
1197
+ if (arguments.length < 6) throw new TypeError("Failed to execute 'transform' on '" + this.constructor.name + "': 6 arguments required, but only " + arguments.length + ' present.');
1198
+ a = Number(a);
1199
+ b = Number(b);
1200
+ c = Number(c);
1201
+ d = Number(d);
1202
+ e = Number(e);
1203
+ f = Number(f);
1204
+ if (!Number.isFinite(a + b + c + d + e + f)) return;
1205
+ const sa = this._transformStack[this._stackIndex][0];
1206
+ const sb = this._transformStack[this._stackIndex][1];
1207
+ const sc = this._transformStack[this._stackIndex][2];
1208
+ const sd = this._transformStack[this._stackIndex][3];
1209
+ const se = this._transformStack[this._stackIndex][4];
1210
+ const sf = this._transformStack[this._stackIndex][5];
1211
+ this._transformStack[this._stackIndex][0] = sa * a + sc * b;
1212
+ this._transformStack[this._stackIndex][1] = sb * a + sd * b;
1213
+ this._transformStack[this._stackIndex][2] = sa * c + sc * d;
1214
+ this._transformStack[this._stackIndex][3] = sb * c + sd * d;
1215
+ this._transformStack[this._stackIndex][4] = sa * e + sc * f + se;
1216
+ this._transformStack[this._stackIndex][5] = sb * e + sd * f + sf;
1217
+ const event = (0, _createCanvasEvent.default)('transform', getTransformSlice(this), {
1218
+ a,
1219
+ b,
1220
+ c,
1221
+ d,
1222
+ e,
1223
+ f
1224
+ });
1225
+ this._events.push(event);
1226
+ }
1227
+ translate(x, y) {
1228
+ if (arguments.length < 2) throw new TypeError("Failed to execute 'translate' on '" + this.constructor.name + "': 2 arguments required, but only " + arguments.length + ' present.');
1229
+ const xResult = Number(x);
1230
+ const yResult = Number(y);
1231
+ const a = this._transformStack[this._stackIndex][0];
1232
+ const b = this._transformStack[this._stackIndex][1];
1233
+ const c = this._transformStack[this._stackIndex][2];
1234
+ const d = this._transformStack[this._stackIndex][3];
1235
+ if (Number.isFinite(xResult + yResult)) {
1236
+ this._transformStack[this._stackIndex][4] += a * xResult + c * yResult;
1237
+ this._transformStack[this._stackIndex][5] += b * xResult + d * yResult;
1238
+ const event = (0, _createCanvasEvent.default)('translate', getTransformSlice(this), {
1239
+ x: xResult,
1240
+ y: yResult
1241
+ });
1242
+ this._events.push(event);
1243
+ }
1244
+ }
1245
+ }
1246
+ exports.default = CanvasRenderingContext2D;