@leafer-ui/node 1.0.0-beta.9 → 1.0.0-rc.11

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,2448 @@
1
+ import { LeaferCanvasBase, Platform, canvasPatch, Creator, LeaferImage, FileHelper, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, AnimateEvent, ResizeEvent, BoundsHelper, Answer, MatrixHelper, ImageEvent, PointHelper, Direction4, TwoPointBoundsHelper, TaskProcessor, Matrix } from '@leafer/core';
2
+ export * from '@leafer/core';
3
+ export { LeaferImage } from '@leafer/core';
4
+ import { writeFileSync } from 'fs';
5
+ import { InteractionBase, HitCanvasManager } from '@leafer-ui/core';
6
+ export * from '@leafer-ui/core';
7
+ import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, Effect } from '@leafer-ui/draw';
8
+
9
+ /******************************************************************************
10
+ Copyright (c) Microsoft Corporation.
11
+
12
+ Permission to use, copy, modify, and/or distribute this software for any
13
+ purpose with or without fee is hereby granted.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
16
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
17
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
18
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
19
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
20
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21
+ PERFORMANCE OF THIS SOFTWARE.
22
+ ***************************************************************************** */
23
+ /* global Reflect, Promise, SuppressedError, Symbol */
24
+
25
+
26
+ function __awaiter(thisArg, _arguments, P, generator) {
27
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
28
+ return new (P || (P = Promise))(function (resolve, reject) {
29
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
30
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
31
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
32
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
33
+ });
34
+ }
35
+
36
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
37
+ var e = new Error(message);
38
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
39
+ };
40
+
41
+ class LeaferCanvas extends LeaferCanvasBase {
42
+ get allowBackgroundColor() { return true; }
43
+ init() {
44
+ this.__createView();
45
+ this.__createContext();
46
+ this.resize(this.config);
47
+ if (Platform.roundRectPatch) {
48
+ this.context.__proto__.roundRect = null;
49
+ canvasPatch(this.context.__proto__);
50
+ }
51
+ }
52
+ __createView() {
53
+ this.view = Platform.origin.createCanvas(1, 1);
54
+ }
55
+ updateViewSize() {
56
+ const { width, height, pixelRatio } = this;
57
+ this.view.width = Math.ceil(width * pixelRatio);
58
+ this.view.height = Math.ceil(height * pixelRatio);
59
+ this.clientBounds = this.bounds;
60
+ }
61
+ }
62
+
63
+ const { mineType, fileType } = FileHelper;
64
+ Object.assign(Creator, {
65
+ canvas: (options, manager) => new LeaferCanvas(options, manager),
66
+ image: (options) => new LeaferImage(options)
67
+ });
68
+ function useCanvas(canvasType, power) {
69
+ Platform.canvasType = canvasType;
70
+ if (!Platform.origin) {
71
+ if (canvasType === 'skia') {
72
+ const { Canvas, loadImage } = power;
73
+ Platform.origin = {
74
+ createCanvas: (width, height, format) => new Canvas(width, height, format),
75
+ canvasToDataURL: (canvas, type, quality) => canvas.toDataURLSync(type, { quality }),
76
+ canvasToBolb: (canvas, type, quality) => canvas.toBuffer(type, { quality }),
77
+ canvasSaveAs: (canvas, filename, quality) => canvas.saveAs(filename, { quality }),
78
+ loadImage
79
+ };
80
+ Platform.roundRectPatch = true;
81
+ }
82
+ else if (canvasType === 'napi') {
83
+ const { Canvas, loadImage } = power;
84
+ Platform.origin = {
85
+ createCanvas: (width, height, format) => new Canvas(width, height, format),
86
+ canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
87
+ canvasToBolb: (canvas, type, quality) => __awaiter(this, void 0, void 0, function* () { return canvas.toBuffer(mineType(type), quality); }),
88
+ canvasSaveAs: (canvas, filename, quality) => __awaiter(this, void 0, void 0, function* () { return writeFileSync(filename, canvas.toBuffer(mineType(fileType(filename)), quality)); }),
89
+ loadImage
90
+ };
91
+ }
92
+ Platform.ellipseToCurve = true;
93
+ Platform.event = {
94
+ stopDefault(_origin) { },
95
+ stopNow(_origin) { },
96
+ stop(_origin) { }
97
+ };
98
+ Platform.canvas = Creator.canvas();
99
+ }
100
+ }
101
+ Platform.name = 'node';
102
+ Platform.requestRender = function (render) { setTimeout(render); };
103
+ Platform.devicePixelRatio = 1;
104
+ Platform.conicGradientSupport = true;
105
+
106
+ class Watcher {
107
+ get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
108
+ get updatedList() {
109
+ if (this.hasRemove) {
110
+ const updatedList = new LeafList();
111
+ this.__updatedList.list.forEach(item => { if (item.leafer)
112
+ updatedList.add(item); });
113
+ return updatedList;
114
+ }
115
+ else {
116
+ return this.__updatedList;
117
+ }
118
+ }
119
+ constructor(target, userConfig) {
120
+ this.totalTimes = 0;
121
+ this.config = {};
122
+ this.__updatedList = new LeafList();
123
+ this.target = target;
124
+ if (userConfig)
125
+ this.config = DataHelper.default(userConfig, this.config);
126
+ this.__listenEvents();
127
+ }
128
+ start() {
129
+ if (this.disabled)
130
+ return;
131
+ this.running = true;
132
+ }
133
+ stop() {
134
+ this.running = false;
135
+ }
136
+ disable() {
137
+ this.stop();
138
+ this.__removeListenEvents();
139
+ this.disabled = true;
140
+ }
141
+ update() {
142
+ this.changed = true;
143
+ if (this.running)
144
+ this.target.emit(RenderEvent.REQUEST);
145
+ }
146
+ __onAttrChange(event) {
147
+ this.__updatedList.add(event.target);
148
+ this.update();
149
+ }
150
+ __onChildEvent(event) {
151
+ if (event.type === ChildEvent.ADD) {
152
+ this.hasAdd = true;
153
+ this.__pushChild(event.child);
154
+ }
155
+ else {
156
+ this.hasRemove = true;
157
+ this.__updatedList.add(event.parent);
158
+ }
159
+ this.update();
160
+ }
161
+ __pushChild(child) {
162
+ this.__updatedList.add(child);
163
+ if (child.isBranch)
164
+ this.__loopChildren(child);
165
+ }
166
+ __loopChildren(parent) {
167
+ const { children } = parent;
168
+ for (let i = 0, len = children.length; i < len; i++)
169
+ this.__pushChild(children[i]);
170
+ }
171
+ __onRquestData() {
172
+ this.target.emitEvent(new WatchEvent(WatchEvent.DATA, { updatedList: this.updatedList }));
173
+ this.__updatedList = new LeafList();
174
+ this.totalTimes++;
175
+ this.changed = false;
176
+ this.hasVisible = false;
177
+ this.hasRemove = false;
178
+ this.hasAdd = false;
179
+ }
180
+ __listenEvents() {
181
+ const { target } = this;
182
+ this.__eventIds = [
183
+ target.on_(PropertyEvent.CHANGE, this.__onAttrChange, this),
184
+ target.on_([ChildEvent.ADD, ChildEvent.REMOVE], this.__onChildEvent, this),
185
+ target.on_(WatchEvent.REQUEST, this.__onRquestData, this)
186
+ ];
187
+ }
188
+ __removeListenEvents() {
189
+ this.target.off_(this.__eventIds);
190
+ }
191
+ destroy() {
192
+ if (this.target) {
193
+ this.stop();
194
+ this.__removeListenEvents();
195
+ this.target = null;
196
+ this.__updatedList = null;
197
+ }
198
+ }
199
+ }
200
+
201
+ const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateAllWorldOpacity } = LeafHelper;
202
+ const { pushAllChildBranch, pushAllParent } = BranchHelper;
203
+ function updateMatrix(updateList, levelList) {
204
+ let layout;
205
+ updateList.list.forEach(leaf => {
206
+ layout = leaf.__layout;
207
+ if (levelList.without(leaf) && !layout.proxyZoom) {
208
+ if (layout.matrixChanged) {
209
+ updateAllMatrix$1(leaf, true);
210
+ levelList.add(leaf);
211
+ if (leaf.isBranch)
212
+ pushAllChildBranch(leaf, levelList);
213
+ pushAllParent(leaf, levelList);
214
+ }
215
+ else if (layout.boundsChanged) {
216
+ levelList.add(leaf);
217
+ if (leaf.isBranch)
218
+ leaf.__tempNumber = 0;
219
+ pushAllParent(leaf, levelList);
220
+ }
221
+ }
222
+ });
223
+ }
224
+ function updateBounds(boundsList) {
225
+ let list, branch, children;
226
+ boundsList.sort(true);
227
+ boundsList.levels.forEach(level => {
228
+ list = boundsList.levelMap[level];
229
+ for (let i = 0, len = list.length; i < len; i++) {
230
+ branch = list[i];
231
+ if (branch.isBranch && branch.__tempNumber) {
232
+ children = branch.children;
233
+ for (let j = 0, jLen = children.length; j < jLen; j++) {
234
+ if (!children[j].isBranch) {
235
+ updateOneBounds(children[j]);
236
+ }
237
+ }
238
+ }
239
+ updateOneBounds(branch);
240
+ }
241
+ });
242
+ }
243
+ function updateChange(updateList) {
244
+ updateList.list.forEach(leaf => {
245
+ if (leaf.__layout.opacityChanged)
246
+ updateAllWorldOpacity(leaf);
247
+ leaf.__updateChange();
248
+ });
249
+ }
250
+
251
+ const { worldBounds } = LeafBoundsHelper;
252
+ const bigBounds = { x: 0, y: 0, width: 100000, height: 100000 };
253
+ class LayoutBlockData {
254
+ constructor(list) {
255
+ this.updatedBounds = new Bounds();
256
+ this.beforeBounds = new Bounds();
257
+ this.afterBounds = new Bounds();
258
+ if (list instanceof Array)
259
+ list = new LeafList(list);
260
+ this.updatedList = list;
261
+ }
262
+ setBefore() {
263
+ this.beforeBounds.setListWithFn(this.updatedList.list, worldBounds);
264
+ }
265
+ setAfter() {
266
+ const { list } = this.updatedList;
267
+ if (list.some(leaf => leaf.noBounds)) {
268
+ this.afterBounds.set(bigBounds);
269
+ }
270
+ else {
271
+ this.afterBounds.setListWithFn(list, worldBounds);
272
+ }
273
+ this.updatedBounds.setList([this.beforeBounds, this.afterBounds]);
274
+ }
275
+ merge(data) {
276
+ this.updatedList.addList(data.updatedList.list);
277
+ this.beforeBounds.add(data.beforeBounds);
278
+ this.afterBounds.add(data.afterBounds);
279
+ this.updatedBounds.add(data.updatedBounds);
280
+ }
281
+ destroy() {
282
+ this.updatedList = null;
283
+ }
284
+ }
285
+
286
+ const { updateAllMatrix, updateAllChange } = LeafHelper;
287
+ const debug$1 = Debug.get('Layouter');
288
+ class Layouter {
289
+ constructor(target, userConfig) {
290
+ this.totalTimes = 0;
291
+ this.config = {};
292
+ this.__levelList = new LeafLevelList();
293
+ this.target = target;
294
+ if (userConfig)
295
+ this.config = DataHelper.default(userConfig, this.config);
296
+ this.__listenEvents();
297
+ }
298
+ start() {
299
+ if (this.disabled)
300
+ return;
301
+ this.running = true;
302
+ }
303
+ stop() {
304
+ this.running = false;
305
+ }
306
+ disable() {
307
+ this.stop();
308
+ this.__removeListenEvents();
309
+ this.disabled = true;
310
+ }
311
+ layout() {
312
+ if (!this.running)
313
+ return;
314
+ const { target } = this;
315
+ this.times = 0;
316
+ try {
317
+ target.emit(LayoutEvent.START);
318
+ this.layoutOnce();
319
+ target.emitEvent(new LayoutEvent(LayoutEvent.END, this.layoutedBlocks, this.times));
320
+ }
321
+ catch (e) {
322
+ debug$1.error(e);
323
+ }
324
+ this.layoutedBlocks = null;
325
+ }
326
+ layoutAgain() {
327
+ if (this.layouting) {
328
+ this.waitAgain = true;
329
+ }
330
+ else {
331
+ this.layoutOnce();
332
+ }
333
+ }
334
+ layoutOnce() {
335
+ if (this.layouting)
336
+ return debug$1.warn('layouting');
337
+ if (this.times > 3)
338
+ return debug$1.warn('layout max times');
339
+ this.times++;
340
+ this.totalTimes++;
341
+ this.layouting = true;
342
+ this.target.emit(WatchEvent.REQUEST);
343
+ if (this.totalTimes > 1) {
344
+ this.partLayout();
345
+ }
346
+ else {
347
+ this.fullLayout();
348
+ }
349
+ this.layouting = false;
350
+ if (this.waitAgain) {
351
+ this.waitAgain = false;
352
+ this.layoutOnce();
353
+ }
354
+ }
355
+ partLayout() {
356
+ var _a;
357
+ if (!((_a = this.__updatedList) === null || _a === void 0 ? void 0 : _a.length))
358
+ return;
359
+ const t = Run.start('PartLayout');
360
+ const { target, __updatedList: updateList } = this;
361
+ const { BEFORE, LAYOUT, AFTER } = LayoutEvent;
362
+ const blocks = this.getBlocks(updateList);
363
+ blocks.forEach(item => item.setBefore());
364
+ target.emitEvent(new LayoutEvent(BEFORE, blocks, this.times));
365
+ this.extraBlock = null;
366
+ updateList.sort();
367
+ updateMatrix(updateList, this.__levelList);
368
+ updateBounds(this.__levelList);
369
+ updateChange(updateList);
370
+ if (this.extraBlock)
371
+ blocks.push(this.extraBlock);
372
+ blocks.forEach(item => item.setAfter());
373
+ target.emitEvent(new LayoutEvent(LAYOUT, blocks, this.times));
374
+ target.emitEvent(new LayoutEvent(AFTER, blocks, this.times));
375
+ this.addBlocks(blocks);
376
+ this.__levelList.reset();
377
+ this.__updatedList = null;
378
+ Run.end(t);
379
+ }
380
+ fullLayout() {
381
+ const t = Run.start('FullLayout');
382
+ const { target } = this;
383
+ const { BEFORE, LAYOUT, AFTER } = LayoutEvent;
384
+ const blocks = this.getBlocks(new LeafList(target));
385
+ target.emitEvent(new LayoutEvent(BEFORE, blocks, this.times));
386
+ Layouter.fullLayout(target);
387
+ blocks.forEach(item => { item.setAfter(); });
388
+ target.emitEvent(new LayoutEvent(LAYOUT, blocks, this.times));
389
+ target.emitEvent(new LayoutEvent(AFTER, blocks, this.times));
390
+ this.addBlocks(blocks);
391
+ Run.end(t);
392
+ }
393
+ static fullLayout(target) {
394
+ updateAllMatrix(target, true);
395
+ if (target.isBranch) {
396
+ BranchHelper.updateBounds(target);
397
+ }
398
+ else {
399
+ LeafHelper.updateBounds(target);
400
+ }
401
+ updateAllChange(target);
402
+ }
403
+ addExtra(leaf) {
404
+ const block = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
405
+ block.updatedList.add(leaf);
406
+ block.beforeBounds.add(leaf.__world);
407
+ }
408
+ createBlock(data) {
409
+ return new LayoutBlockData(data);
410
+ }
411
+ getBlocks(list) {
412
+ return [this.createBlock(list)];
413
+ }
414
+ addBlocks(current) {
415
+ this.layoutedBlocks ? this.layoutedBlocks.push(...current) : this.layoutedBlocks = current;
416
+ }
417
+ __onReceiveWatchData(event) {
418
+ this.__updatedList = event.data.updatedList;
419
+ }
420
+ __listenEvents() {
421
+ const { target } = this;
422
+ this.__eventIds = [
423
+ target.on_(LayoutEvent.REQUEST, this.layout, this),
424
+ target.on_(LayoutEvent.AGAIN, this.layoutAgain, this),
425
+ target.on_(WatchEvent.DATA, this.__onReceiveWatchData, this)
426
+ ];
427
+ }
428
+ __removeListenEvents() {
429
+ this.target.off_(this.__eventIds);
430
+ }
431
+ destroy() {
432
+ if (this.target) {
433
+ this.stop();
434
+ this.__removeListenEvents();
435
+ this.target = this.config = null;
436
+ }
437
+ }
438
+ }
439
+
440
+ const debug = Debug.get('Renderer');
441
+ class Renderer {
442
+ get needFill() { return !!(!this.canvas.allowBackgroundColor && this.config.fill); }
443
+ constructor(target, canvas, userConfig) {
444
+ this.FPS = 60;
445
+ this.totalTimes = 0;
446
+ this.times = 0;
447
+ this.config = {
448
+ usePartRender: true,
449
+ maxFPS: 60
450
+ };
451
+ this.target = target;
452
+ this.canvas = canvas;
453
+ if (userConfig)
454
+ this.config = DataHelper.default(userConfig, this.config);
455
+ this.__listenEvents();
456
+ this.__requestRender();
457
+ }
458
+ start() {
459
+ this.running = true;
460
+ }
461
+ stop() {
462
+ this.running = false;
463
+ }
464
+ update() {
465
+ this.changed = true;
466
+ }
467
+ requestLayout() {
468
+ this.target.emit(LayoutEvent.REQUEST);
469
+ }
470
+ render(callback) {
471
+ if (!(this.running && this.canvas.view)) {
472
+ this.changed = true;
473
+ return;
474
+ }
475
+ const { target } = this;
476
+ this.times = 0;
477
+ this.totalBounds = new Bounds();
478
+ debug.log(target.innerName, '--->');
479
+ try {
480
+ this.emitRender(RenderEvent.START);
481
+ this.renderOnce(callback);
482
+ this.emitRender(RenderEvent.END, this.totalBounds);
483
+ ImageManager.clearRecycled();
484
+ }
485
+ catch (e) {
486
+ this.rendering = false;
487
+ debug.error(e);
488
+ }
489
+ debug.log('-------------|');
490
+ }
491
+ renderAgain() {
492
+ if (this.rendering) {
493
+ this.waitAgain = true;
494
+ }
495
+ else {
496
+ this.renderOnce();
497
+ }
498
+ }
499
+ renderOnce(callback) {
500
+ if (this.rendering)
501
+ return debug.warn('rendering');
502
+ if (this.times > 3)
503
+ return debug.warn('render max times');
504
+ this.times++;
505
+ this.totalTimes++;
506
+ this.rendering = true;
507
+ this.changed = false;
508
+ this.renderBounds = new Bounds();
509
+ this.renderOptions = {};
510
+ if (callback) {
511
+ this.emitRender(RenderEvent.BEFORE);
512
+ callback();
513
+ }
514
+ else {
515
+ this.requestLayout();
516
+ this.emitRender(RenderEvent.BEFORE);
517
+ if (this.config.usePartRender && this.totalTimes > 1) {
518
+ this.partRender();
519
+ }
520
+ else {
521
+ this.fullRender();
522
+ }
523
+ }
524
+ this.emitRender(RenderEvent.RENDER, this.renderBounds, this.renderOptions);
525
+ this.emitRender(RenderEvent.AFTER, this.renderBounds, this.renderOptions);
526
+ this.updateBlocks = null;
527
+ this.rendering = false;
528
+ if (this.waitAgain) {
529
+ this.waitAgain = false;
530
+ this.renderOnce();
531
+ }
532
+ }
533
+ partRender() {
534
+ const { canvas, updateBlocks: list } = this;
535
+ if (!list)
536
+ return debug.warn('PartRender: need update attr');
537
+ this.mergeBlocks();
538
+ list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
539
+ this.clipRender(block); });
540
+ }
541
+ clipRender(block) {
542
+ const t = Run.start('PartRender');
543
+ const { canvas } = this;
544
+ const bounds = block.getIntersect(canvas.bounds);
545
+ const includes = block.includes(this.target.__world);
546
+ const realBounds = new Bounds(bounds);
547
+ canvas.save();
548
+ if (includes && !Debug.showRepaint) {
549
+ canvas.clear();
550
+ }
551
+ else {
552
+ bounds.spread(1 + 1 / this.canvas.pixelRatio).ceil();
553
+ canvas.clearWorld(bounds, true);
554
+ canvas.clipWorld(bounds, true);
555
+ }
556
+ this.__render(bounds, includes, realBounds);
557
+ canvas.restore();
558
+ Run.end(t);
559
+ }
560
+ fullRender() {
561
+ const t = Run.start('FullRender');
562
+ const { canvas } = this;
563
+ canvas.save();
564
+ canvas.clear();
565
+ this.__render(canvas.bounds, true);
566
+ canvas.restore();
567
+ Run.end(t);
568
+ }
569
+ __render(bounds, includes, realBounds) {
570
+ const options = bounds.includes(this.target.__world) ? { includes } : { bounds, includes };
571
+ if (this.needFill)
572
+ this.canvas.fillWorld(bounds, this.config.fill);
573
+ if (Debug.showRepaint)
574
+ this.canvas.strokeWorld(bounds, 'red');
575
+ this.target.__render(this.canvas, options);
576
+ this.renderBounds = realBounds || bounds;
577
+ this.renderOptions = options;
578
+ this.totalBounds.isEmpty() ? this.totalBounds = this.renderBounds : this.totalBounds.add(this.renderBounds);
579
+ if (Debug.showHitView)
580
+ this.renderHitView(options);
581
+ if (Debug.showBoundsView)
582
+ this.renderBoundsView(options);
583
+ this.canvas.updateRender();
584
+ }
585
+ renderHitView(_options) { }
586
+ renderBoundsView(_options) { }
587
+ addBlock(block) {
588
+ if (!this.updateBlocks)
589
+ this.updateBlocks = [];
590
+ this.updateBlocks.push(block);
591
+ }
592
+ mergeBlocks() {
593
+ const { updateBlocks: list } = this;
594
+ if (list) {
595
+ const bounds = new Bounds();
596
+ bounds.setList(list);
597
+ list.length = 0;
598
+ list.push(bounds);
599
+ }
600
+ }
601
+ __requestRender() {
602
+ const startTime = Date.now();
603
+ Platform.requestRender(() => {
604
+ this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - startTime)));
605
+ if (this.running) {
606
+ this.target.emit(AnimateEvent.FRAME);
607
+ if (this.changed && this.canvas.view)
608
+ this.render();
609
+ this.target.emit(RenderEvent.NEXT);
610
+ }
611
+ if (this.target)
612
+ this.__requestRender();
613
+ });
614
+ }
615
+ __onResize(e) {
616
+ if (this.canvas.unreal)
617
+ return;
618
+ if (e.bigger || !e.samePixelRatio) {
619
+ const { width, height } = e.old;
620
+ const bounds = new Bounds(0, 0, width, height);
621
+ if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
622
+ this.addBlock(this.canvas.bounds);
623
+ this.target.forceUpdate('surface');
624
+ }
625
+ }
626
+ }
627
+ __onLayoutEnd(event) {
628
+ if (event.data)
629
+ event.data.map(item => {
630
+ let empty;
631
+ if (item.updatedList)
632
+ item.updatedList.list.some(leaf => {
633
+ empty = (!leaf.__world.width || !leaf.__world.height);
634
+ if (empty) {
635
+ if (!leaf.isLeafer)
636
+ debug.tip(leaf.innerName, ': empty');
637
+ empty = (!leaf.isBranch || leaf.isBranchLeaf);
638
+ }
639
+ return empty;
640
+ });
641
+ this.addBlock(empty ? this.canvas.bounds : item.updatedBounds);
642
+ });
643
+ }
644
+ emitRender(type, bounds, options) {
645
+ this.target.emitEvent(new RenderEvent(type, this.times, bounds, options));
646
+ }
647
+ __listenEvents() {
648
+ const { target } = this;
649
+ this.__eventIds = [
650
+ target.on_(RenderEvent.REQUEST, this.update, this),
651
+ target.on_(LayoutEvent.END, this.__onLayoutEnd, this),
652
+ target.on_(RenderEvent.AGAIN, this.renderAgain, this),
653
+ target.on_(ResizeEvent.RESIZE, this.__onResize, this)
654
+ ];
655
+ }
656
+ __removeListenEvents() {
657
+ this.target.off_(this.__eventIds);
658
+ }
659
+ destroy() {
660
+ if (this.target) {
661
+ this.stop();
662
+ this.__removeListenEvents();
663
+ this.target = null;
664
+ this.canvas = null;
665
+ this.config = null;
666
+ }
667
+ }
668
+ }
669
+
670
+ const { hitRadiusPoint } = BoundsHelper;
671
+ class Picker {
672
+ constructor(target, selector) {
673
+ this.target = target;
674
+ this.selector = selector;
675
+ }
676
+ getByPoint(hitPoint, hitRadius, options) {
677
+ if (!hitRadius)
678
+ hitRadius = 0;
679
+ if (!options)
680
+ options = {};
681
+ const through = options.through || false;
682
+ const ignoreHittable = options.ignoreHittable || false;
683
+ const target = options.target || this.target;
684
+ this.exclude = options.exclude || null;
685
+ this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius };
686
+ this.findList = options.findList || [];
687
+ if (!options.findList)
688
+ this.eachFind(target.children, target.__onlyHitMask);
689
+ const list = this.findList;
690
+ const leaf = this.getBestMatchLeaf();
691
+ const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf);
692
+ this.clear();
693
+ return through ? { path, target: leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, target: leaf };
694
+ }
695
+ getBestMatchLeaf() {
696
+ const { findList: targets } = this;
697
+ if (targets.length > 1) {
698
+ let find;
699
+ this.findList = [];
700
+ const { x, y } = this.point;
701
+ const point = { x, y, radiusX: 0, radiusY: 0 };
702
+ for (let i = 0, len = targets.length; i < len; i++) {
703
+ find = targets[i];
704
+ if (LeafHelper.worldHittable(find)) {
705
+ this.hitChild(find, point);
706
+ if (this.findList.length)
707
+ return this.findList[0];
708
+ }
709
+ }
710
+ }
711
+ return targets[0];
712
+ }
713
+ getPath(leaf) {
714
+ const path = new LeafList();
715
+ while (leaf) {
716
+ path.add(leaf);
717
+ leaf = leaf.parent;
718
+ }
719
+ path.add(this.target);
720
+ return path;
721
+ }
722
+ getHitablePath(leaf) {
723
+ const path = this.getPath(leaf);
724
+ let item, hittablePath = new LeafList();
725
+ for (let i = path.list.length - 1; i > -1; i--) {
726
+ item = path.list[i];
727
+ if (!item.__.hittable)
728
+ break;
729
+ hittablePath.addAt(item, 0);
730
+ if (!item.__.hitChildren)
731
+ break;
732
+ }
733
+ return hittablePath;
734
+ }
735
+ getThroughPath(list) {
736
+ const throughPath = new LeafList();
737
+ const pathList = [];
738
+ for (let i = list.length - 1; i > -1; i--) {
739
+ pathList.push(this.getPath(list[i]));
740
+ }
741
+ let path, nextPath, leaf;
742
+ for (let i = 0, len = pathList.length; i < len; i++) {
743
+ path = pathList[i], nextPath = pathList[i + 1];
744
+ for (let j = 0, jLen = path.length; j < jLen; j++) {
745
+ leaf = path.list[j];
746
+ if (nextPath && nextPath.has(leaf))
747
+ break;
748
+ throughPath.add(leaf);
749
+ }
750
+ }
751
+ return throughPath;
752
+ }
753
+ eachFind(children, hitMask) {
754
+ let child, hit;
755
+ const { point } = this, len = children.length;
756
+ for (let i = len - 1; i > -1; i--) {
757
+ child = children[i];
758
+ if (!child.__.visible || (hitMask && !child.__.mask))
759
+ continue;
760
+ hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
761
+ if (child.isBranch) {
762
+ if (hit || child.__ignoreHitWorld) {
763
+ this.eachFind(child.children, child.__onlyHitMask);
764
+ if (child.isBranchLeaf && !this.findList.length)
765
+ this.hitChild(child, point);
766
+ }
767
+ }
768
+ else {
769
+ if (hit)
770
+ this.hitChild(child, point);
771
+ }
772
+ }
773
+ }
774
+ hitChild(child, point) {
775
+ if (this.exclude && this.exclude.has(child))
776
+ return;
777
+ if (child.__hitWorld(point))
778
+ this.findList.push(child);
779
+ }
780
+ clear() {
781
+ this.point = null;
782
+ this.findList = null;
783
+ this.exclude = null;
784
+ }
785
+ destroy() {
786
+ this.clear();
787
+ }
788
+ }
789
+
790
+ const { Yes, NoAndSkip, YesAndSkip } = Answer;
791
+ class Selector {
792
+ constructor(target, userConfig) {
793
+ this.config = {};
794
+ this.innerIdMap = {};
795
+ this.idMap = {};
796
+ this.methods = {
797
+ id: (leaf, name) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
798
+ innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
799
+ className: (leaf, name) => leaf.className === name ? 1 : 0,
800
+ tag: (leaf, name) => leaf.__tag === name ? 1 : 0
801
+ };
802
+ this.target = target;
803
+ if (userConfig)
804
+ this.config = DataHelper.default(userConfig, this.config);
805
+ this.picker = new Picker(target, this);
806
+ this.__listenEvents();
807
+ }
808
+ getBy(condition, branch, one, options) {
809
+ switch (typeof condition) {
810
+ case 'number':
811
+ const leaf = this.getByInnerId(condition, branch);
812
+ return one ? leaf : (leaf ? [leaf] : []);
813
+ case 'string':
814
+ switch (condition[0]) {
815
+ case '#':
816
+ const leaf = this.getById(condition.substring(1), branch);
817
+ return one ? leaf : (leaf ? [leaf] : []);
818
+ case '.':
819
+ return this.getByMethod(this.methods.className, branch, one, condition.substring(1));
820
+ default:
821
+ return this.getByMethod(this.methods.tag, branch, one, condition);
822
+ }
823
+ case 'function':
824
+ return this.getByMethod(condition, branch, one, options);
825
+ }
826
+ }
827
+ getByPoint(hitPoint, hitRadius, options) {
828
+ if (Platform.name === 'node')
829
+ this.target.emit(LayoutEvent.CHECK_UPDATE);
830
+ return this.picker.getByPoint(hitPoint, hitRadius, options);
831
+ }
832
+ getByInnerId(innerId, branch) {
833
+ const cache = this.innerIdMap[innerId];
834
+ if (cache)
835
+ return cache;
836
+ this.eachFind(this.toChildren(branch), this.methods.innerId, null, innerId);
837
+ return this.findLeaf;
838
+ }
839
+ getById(id, branch) {
840
+ const cache = this.idMap[id];
841
+ if (cache && LeafHelper.hasParent(cache, branch || this.target))
842
+ return cache;
843
+ this.eachFind(this.toChildren(branch), this.methods.id, null, id);
844
+ return this.findLeaf;
845
+ }
846
+ getByClassName(className, branch) {
847
+ return this.getByMethod(this.methods.className, branch, false, className);
848
+ }
849
+ getByTag(tag, branch) {
850
+ return this.getByMethod(this.methods.tag, branch, false, tag);
851
+ }
852
+ getByMethod(method, branch, one, options) {
853
+ const list = one ? null : [];
854
+ this.eachFind(this.toChildren(branch), method, list, options);
855
+ return list || this.findLeaf;
856
+ }
857
+ eachFind(children, method, list, options) {
858
+ let child, result;
859
+ for (let i = 0, len = children.length; i < len; i++) {
860
+ child = children[i];
861
+ result = method(child, options);
862
+ if (result === Yes || result === YesAndSkip) {
863
+ if (list) {
864
+ list.push(child);
865
+ }
866
+ else {
867
+ this.findLeaf = child;
868
+ return;
869
+ }
870
+ }
871
+ if (child.isBranch && result < NoAndSkip)
872
+ this.eachFind(child.children, method, list, options);
873
+ }
874
+ }
875
+ toChildren(branch) {
876
+ this.findLeaf = null;
877
+ return [branch || this.target];
878
+ }
879
+ __onRemoveChild(event) {
880
+ const { id, innerId } = event.child;
881
+ if (this.idMap[id])
882
+ delete this.idMap[id];
883
+ if (this.innerIdMap[innerId])
884
+ delete this.innerIdMap[innerId];
885
+ }
886
+ __checkIdChange(event) {
887
+ if (event.attrName === 'id') {
888
+ const id = event.oldValue;
889
+ if (this.idMap[id])
890
+ delete this.idMap[id];
891
+ }
892
+ }
893
+ __listenEvents() {
894
+ this.__eventIds = [
895
+ this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this),
896
+ this.target.on_(PropertyEvent.CHANGE, this.__checkIdChange, this)
897
+ ];
898
+ }
899
+ __removeListenEvents() {
900
+ this.target.off_(this.__eventIds);
901
+ this.__eventIds.length = 0;
902
+ }
903
+ destroy() {
904
+ if (this.__eventIds.length) {
905
+ this.__removeListenEvents();
906
+ this.picker.destroy();
907
+ this.findLeaf = null;
908
+ this.innerIdMap = {};
909
+ this.idMap = {};
910
+ }
911
+ }
912
+ }
913
+
914
+ Object.assign(Creator, {
915
+ watcher: (target, options) => new Watcher(target, options),
916
+ layouter: (target, options) => new Layouter(target, options),
917
+ renderer: (target, canvas, options) => new Renderer(target, canvas, options),
918
+ selector: (target, options) => new Selector(target, options)
919
+ });
920
+ Platform.layout = Layouter.fullLayout;
921
+
922
+ function fillText(ui, canvas) {
923
+ let row;
924
+ const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
925
+ for (let i = 0, len = rows.length; i < len; i++) {
926
+ row = rows[i];
927
+ if (row.text) {
928
+ canvas.fillText(row.text, row.x, row.y);
929
+ }
930
+ else if (row.data) {
931
+ row.data.forEach(charData => {
932
+ canvas.fillText(charData.char, charData.x, row.y);
933
+ });
934
+ }
935
+ if (decorationY)
936
+ canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
937
+ }
938
+ }
939
+
940
+ function fill(fill, ui, canvas) {
941
+ canvas.fillStyle = fill;
942
+ ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
943
+ }
944
+ function fills(fills, ui, canvas) {
945
+ let item;
946
+ const { windingRule, __font } = ui.__;
947
+ for (let i = 0, len = fills.length; i < len; i++) {
948
+ item = fills[i];
949
+ if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
950
+ continue;
951
+ if (item.style) {
952
+ canvas.fillStyle = item.style;
953
+ if (item.transform) {
954
+ canvas.save();
955
+ canvas.transform(item.transform);
956
+ if (item.blendMode)
957
+ canvas.blendMode = item.blendMode;
958
+ __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
959
+ canvas.restore();
960
+ }
961
+ else {
962
+ if (item.blendMode) {
963
+ canvas.saveBlendMode(item.blendMode);
964
+ __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
965
+ canvas.restoreBlendMode();
966
+ }
967
+ else {
968
+ __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
969
+ }
970
+ }
971
+ }
972
+ }
973
+ }
974
+
975
+ function strokeText(stroke, ui, canvas) {
976
+ const { strokeAlign } = ui.__;
977
+ const isStrokes = typeof stroke !== 'string';
978
+ switch (strokeAlign) {
979
+ case 'center':
980
+ canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
981
+ isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
982
+ break;
983
+ case 'inside':
984
+ drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
985
+ break;
986
+ case 'outside':
987
+ drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
988
+ break;
989
+ }
990
+ }
991
+ function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
992
+ const { __strokeWidth, __font } = ui.__;
993
+ const out = canvas.getSameCanvas(true, true);
994
+ out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
995
+ out.font = __font;
996
+ isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
997
+ out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
998
+ fillText(ui, out);
999
+ out.blendMode = 'normal';
1000
+ if (ui.__worldFlipped) {
1001
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1002
+ }
1003
+ else {
1004
+ canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
1005
+ }
1006
+ out.recycle(ui.__nowWorld);
1007
+ }
1008
+ function drawTextStroke(ui, canvas) {
1009
+ let row;
1010
+ const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1011
+ for (let i = 0, len = rows.length; i < len; i++) {
1012
+ row = rows[i];
1013
+ if (row.text) {
1014
+ canvas.strokeText(row.text, row.x, row.y);
1015
+ }
1016
+ else if (row.data) {
1017
+ row.data.forEach(charData => {
1018
+ canvas.strokeText(charData.char, charData.x, row.y);
1019
+ });
1020
+ }
1021
+ if (decorationY)
1022
+ canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
1023
+ }
1024
+ }
1025
+ function drawStrokesStyle(strokes, isText, ui, canvas) {
1026
+ let item;
1027
+ for (let i = 0, len = strokes.length; i < len; i++) {
1028
+ item = strokes[i];
1029
+ if (item.image && PaintImage.checkImage(ui, canvas, item, false))
1030
+ continue;
1031
+ if (item.style) {
1032
+ canvas.strokeStyle = item.style;
1033
+ if (item.blendMode) {
1034
+ canvas.saveBlendMode(item.blendMode);
1035
+ isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1036
+ canvas.restoreBlendMode();
1037
+ }
1038
+ else {
1039
+ isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1040
+ }
1041
+ }
1042
+ }
1043
+ }
1044
+
1045
+ function stroke(stroke, ui, canvas) {
1046
+ const options = ui.__;
1047
+ const { __strokeWidth, strokeAlign, __font } = options;
1048
+ if (!__strokeWidth)
1049
+ return;
1050
+ if (__font) {
1051
+ strokeText(stroke, ui, canvas);
1052
+ }
1053
+ else {
1054
+ switch (strokeAlign) {
1055
+ case 'center':
1056
+ canvas.setStroke(stroke, __strokeWidth, options);
1057
+ canvas.stroke();
1058
+ break;
1059
+ case 'inside':
1060
+ canvas.save();
1061
+ canvas.setStroke(stroke, __strokeWidth * 2, options);
1062
+ options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1063
+ canvas.stroke();
1064
+ canvas.restore();
1065
+ break;
1066
+ case 'outside':
1067
+ const out = canvas.getSameCanvas(true, true);
1068
+ out.setStroke(stroke, __strokeWidth * 2, options);
1069
+ ui.__drawRenderPath(out);
1070
+ out.stroke();
1071
+ options.windingRule ? out.clip(options.windingRule) : out.clip();
1072
+ out.clearWorld(ui.__layout.renderBounds);
1073
+ if (ui.__worldFlipped) {
1074
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1075
+ }
1076
+ else {
1077
+ canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
1078
+ }
1079
+ out.recycle(ui.__nowWorld);
1080
+ break;
1081
+ }
1082
+ }
1083
+ }
1084
+ function strokes(strokes, ui, canvas) {
1085
+ const options = ui.__;
1086
+ const { __strokeWidth, strokeAlign, __font } = options;
1087
+ if (!__strokeWidth)
1088
+ return;
1089
+ if (__font) {
1090
+ strokeText(strokes, ui, canvas);
1091
+ }
1092
+ else {
1093
+ switch (strokeAlign) {
1094
+ case 'center':
1095
+ canvas.setStroke(undefined, __strokeWidth, options);
1096
+ drawStrokesStyle(strokes, false, ui, canvas);
1097
+ break;
1098
+ case 'inside':
1099
+ canvas.save();
1100
+ canvas.setStroke(undefined, __strokeWidth * 2, options);
1101
+ options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1102
+ drawStrokesStyle(strokes, false, ui, canvas);
1103
+ canvas.restore();
1104
+ break;
1105
+ case 'outside':
1106
+ const { renderBounds } = ui.__layout;
1107
+ const out = canvas.getSameCanvas(true, true);
1108
+ ui.__drawRenderPath(out);
1109
+ out.setStroke(undefined, __strokeWidth * 2, options);
1110
+ drawStrokesStyle(strokes, false, ui, out);
1111
+ options.windingRule ? out.clip(options.windingRule) : out.clip();
1112
+ out.clearWorld(renderBounds);
1113
+ if (ui.__worldFlipped) {
1114
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1115
+ }
1116
+ else {
1117
+ canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1118
+ }
1119
+ out.recycle(ui.__nowWorld);
1120
+ break;
1121
+ }
1122
+ }
1123
+ }
1124
+
1125
+ const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
1126
+ function shape(ui, current, options) {
1127
+ const canvas = current.getSameCanvas();
1128
+ const nowWorld = ui.__nowWorld;
1129
+ let bounds, fitMatrix, shapeBounds, worldCanvas;
1130
+ let { scaleX, scaleY } = nowWorld;
1131
+ if (scaleX < 0)
1132
+ scaleX = -scaleX;
1133
+ if (scaleY < 0)
1134
+ scaleY = -scaleY;
1135
+ if (current.bounds.includes(nowWorld)) {
1136
+ worldCanvas = canvas;
1137
+ bounds = shapeBounds = nowWorld;
1138
+ }
1139
+ else {
1140
+ const { renderShapeSpread: spread } = ui.__layout;
1141
+ const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, nowWorld);
1142
+ fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
1143
+ let { a: fitScaleX, d: fitScaleY } = fitMatrix;
1144
+ if (fitMatrix.a < 1) {
1145
+ worldCanvas = current.getSameCanvas();
1146
+ ui.__renderShape(worldCanvas, options);
1147
+ scaleX *= fitScaleX;
1148
+ scaleY *= fitScaleY;
1149
+ }
1150
+ shapeBounds = getOuterOf(nowWorld, fitMatrix);
1151
+ bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
1152
+ if (options.matrix) {
1153
+ const { matrix } = options;
1154
+ fitMatrix.multiply(matrix);
1155
+ fitScaleX *= matrix.scaleX;
1156
+ fitScaleY *= matrix.scaleY;
1157
+ }
1158
+ options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
1159
+ }
1160
+ ui.__renderShape(canvas, options);
1161
+ return {
1162
+ canvas, matrix: fitMatrix, bounds,
1163
+ worldCanvas, shapeBounds, scaleX, scaleY
1164
+ };
1165
+ }
1166
+
1167
+ let recycleMap;
1168
+ function compute(attrName, ui) {
1169
+ const data = ui.__, leafPaints = [];
1170
+ let paints = data.__input[attrName], hasOpacityPixel;
1171
+ if (!(paints instanceof Array))
1172
+ paints = [paints];
1173
+ recycleMap = PaintImage.recycleImage(attrName, data);
1174
+ for (let i = 0, len = paints.length, item; i < len; i++) {
1175
+ item = getLeafPaint(attrName, paints[i], ui);
1176
+ if (item)
1177
+ leafPaints.push(item);
1178
+ }
1179
+ data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
1180
+ if (leafPaints.length && leafPaints[0].image)
1181
+ hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
1182
+ if (attrName === 'fill') {
1183
+ data.__pixelFill = hasOpacityPixel;
1184
+ }
1185
+ else {
1186
+ data.__pixelStroke = hasOpacityPixel;
1187
+ }
1188
+ }
1189
+ function getLeafPaint(attrName, paint, ui) {
1190
+ if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
1191
+ return undefined;
1192
+ const { boxBounds } = ui.__layout;
1193
+ switch (paint.type) {
1194
+ case 'solid':
1195
+ let { type, blendMode, color, opacity } = paint;
1196
+ return { type, blendMode, style: ColorConvert.string(color, opacity) };
1197
+ case 'image':
1198
+ return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1199
+ case 'linear':
1200
+ return PaintGradient.linearGradient(paint, boxBounds);
1201
+ case 'radial':
1202
+ return PaintGradient.radialGradient(paint, boxBounds);
1203
+ case 'angular':
1204
+ return PaintGradient.conicGradient(paint, boxBounds);
1205
+ default:
1206
+ return paint.r ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
1207
+ }
1208
+ }
1209
+
1210
+ const PaintModule = {
1211
+ compute,
1212
+ fill,
1213
+ fills,
1214
+ fillText,
1215
+ stroke,
1216
+ strokes,
1217
+ strokeText,
1218
+ drawTextStroke,
1219
+ shape
1220
+ };
1221
+
1222
+ let origin = {};
1223
+ const { get: get$4, rotateOfOuter: rotateOfOuter$2, translate: translate$1, scaleOfOuter: scaleOfOuter$2, scale: scaleHelper, rotate } = MatrixHelper;
1224
+ function fillOrFitMode(data, mode, box, width, height, rotation) {
1225
+ const transform = get$4();
1226
+ const swap = rotation && rotation !== 180;
1227
+ const sw = box.width / (swap ? height : width);
1228
+ const sh = box.height / (swap ? width : height);
1229
+ const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1230
+ const x = box.x + (box.width - width * scale) / 2;
1231
+ const y = box.y + (box.height - height * scale) / 2;
1232
+ translate$1(transform, x, y);
1233
+ scaleHelper(transform, scale);
1234
+ if (rotation)
1235
+ rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
1236
+ data.scaleX = data.scaleY = scale;
1237
+ data.transform = transform;
1238
+ }
1239
+ function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
1240
+ const transform = get$4();
1241
+ translate$1(transform, box.x, box.y);
1242
+ if (x || y)
1243
+ translate$1(transform, x, y);
1244
+ if (scaleX) {
1245
+ scaleHelper(transform, scaleX, scaleY);
1246
+ data.scaleX = transform.a;
1247
+ data.scaleY = transform.d;
1248
+ }
1249
+ if (rotation)
1250
+ rotate(transform, rotation);
1251
+ data.transform = transform;
1252
+ }
1253
+ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation) {
1254
+ const transform = get$4();
1255
+ if (rotation) {
1256
+ rotate(transform, rotation);
1257
+ switch (rotation) {
1258
+ case 90:
1259
+ translate$1(transform, height, 0);
1260
+ break;
1261
+ case 180:
1262
+ translate$1(transform, width, height);
1263
+ break;
1264
+ case 270:
1265
+ translate$1(transform, 0, width);
1266
+ break;
1267
+ }
1268
+ }
1269
+ origin.x = box.x;
1270
+ origin.y = box.y;
1271
+ if (x || y)
1272
+ origin.x += x, origin.y += y;
1273
+ translate$1(transform, origin.x, origin.y);
1274
+ if (scaleX) {
1275
+ scaleOfOuter$2(transform, origin, scaleX, scaleY);
1276
+ data.scaleX = scaleX;
1277
+ data.scaleY = scaleY;
1278
+ }
1279
+ data.transform = transform;
1280
+ }
1281
+
1282
+ const { get: get$3, translate } = MatrixHelper;
1283
+ function createData(leafPaint, image, paint, box) {
1284
+ let { width, height } = image;
1285
+ const { opacity, mode, offset, scale, size, rotation, blendMode, repeat } = paint;
1286
+ const sameBox = box.width === width && box.height === height;
1287
+ if (blendMode)
1288
+ leafPaint.blendMode = blendMode;
1289
+ const data = leafPaint.data = { mode };
1290
+ let x, y, scaleX, scaleY;
1291
+ if (offset)
1292
+ x = offset.x, y = offset.y;
1293
+ if (size) {
1294
+ scaleX = (typeof size === 'number' ? size : size.width) / width;
1295
+ scaleY = (typeof size === 'number' ? size : size.height) / height;
1296
+ }
1297
+ else if (scale) {
1298
+ scaleX = typeof scale === 'number' ? scale : scale.x;
1299
+ scaleY = typeof scale === 'number' ? scale : scale.y;
1300
+ }
1301
+ switch (mode) {
1302
+ case 'strench':
1303
+ if (!sameBox)
1304
+ width = box.width, height = box.height;
1305
+ if (box.x || box.y) {
1306
+ data.transform = get$3();
1307
+ translate(data.transform, box.x, box.y);
1308
+ }
1309
+ break;
1310
+ case 'clip':
1311
+ if (offset || scaleX || rotation)
1312
+ clipMode(data, box, x, y, scaleX, scaleY, rotation);
1313
+ break;
1314
+ case 'repeat':
1315
+ if (!sameBox || scaleX || rotation)
1316
+ repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation);
1317
+ if (!repeat)
1318
+ data.repeat = 'repeat';
1319
+ break;
1320
+ case 'fit':
1321
+ case 'cover':
1322
+ default:
1323
+ if (!sameBox || rotation)
1324
+ fillOrFitMode(data, mode, box, width, height, rotation);
1325
+ }
1326
+ data.width = width;
1327
+ data.height = height;
1328
+ if (opacity)
1329
+ data.opacity = opacity;
1330
+ if (repeat)
1331
+ data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
1332
+ }
1333
+
1334
+ let cache, box = new Bounds();
1335
+ const { isSame } = BoundsHelper;
1336
+ function image(ui, attrName, paint, boxBounds, firstUse) {
1337
+ let leafPaint, event;
1338
+ const image = ImageManager.get(paint);
1339
+ if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1340
+ leafPaint = cache.leafPaint;
1341
+ }
1342
+ else {
1343
+ leafPaint = { type: paint.type };
1344
+ leafPaint.image = image;
1345
+ cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
1346
+ }
1347
+ if (firstUse || image.loading)
1348
+ event = { image, attrName, attrValue: paint };
1349
+ if (image.ready) {
1350
+ checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1351
+ if (firstUse) {
1352
+ onLoad(ui, event);
1353
+ onLoadSuccess(ui, event);
1354
+ }
1355
+ }
1356
+ else if (image.error) {
1357
+ if (firstUse)
1358
+ onLoadError(ui, event, image.error);
1359
+ }
1360
+ else {
1361
+ if (firstUse)
1362
+ onLoad(ui, event);
1363
+ leafPaint.loadId = image.load(() => {
1364
+ if (!ui.destroyed) {
1365
+ if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds))
1366
+ ui.forceUpdate('surface');
1367
+ onLoadSuccess(ui, event);
1368
+ }
1369
+ leafPaint.loadId = null;
1370
+ }, (error) => {
1371
+ onLoadError(ui, event, error);
1372
+ leafPaint.loadId = null;
1373
+ });
1374
+ }
1375
+ return leafPaint;
1376
+ }
1377
+ function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1378
+ if (attrName === 'fill' && !ui.__.__naturalWidth) {
1379
+ const data = ui.__;
1380
+ data.__naturalWidth = image.width;
1381
+ data.__naturalHeight = image.height;
1382
+ if (data.__autoWidth || data.__autoHeight) {
1383
+ ui.forceUpdate('width');
1384
+ if (ui.__proxyData) {
1385
+ ui.setProxyAttr('width', data.width);
1386
+ ui.setProxyAttr('height', data.height);
1387
+ }
1388
+ return false;
1389
+ }
1390
+ }
1391
+ if (!leafPaint.data)
1392
+ createData(leafPaint, image, paint, boxBounds);
1393
+ return true;
1394
+ }
1395
+ function onLoad(ui, event) {
1396
+ emit(ui, ImageEvent.LOAD, event);
1397
+ }
1398
+ function onLoadSuccess(ui, event) {
1399
+ emit(ui, ImageEvent.LOADED, event);
1400
+ }
1401
+ function onLoadError(ui, event, error) {
1402
+ event.error = error;
1403
+ ui.forceUpdate('surface');
1404
+ emit(ui, ImageEvent.ERROR, event);
1405
+ }
1406
+ function emit(ui, type, data) {
1407
+ if (ui.hasEvent(type))
1408
+ ui.emitEvent(new ImageEvent(type, data));
1409
+ }
1410
+
1411
+ const { get: get$2, scale, copy: copy$1 } = MatrixHelper;
1412
+ const { round, abs: abs$1 } = Math;
1413
+ function createPattern(ui, paint, pixelRatio) {
1414
+ let { scaleX, scaleY } = ui.__world;
1415
+ const id = scaleX + '-' + scaleY;
1416
+ if (paint.patternId !== id && !ui.destroyed) {
1417
+ scaleX = abs$1(scaleX);
1418
+ scaleY = abs$1(scaleY);
1419
+ const { image, data } = paint;
1420
+ let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
1421
+ if (sx) {
1422
+ imageMatrix = get$2();
1423
+ copy$1(imageMatrix, transform);
1424
+ scale(imageMatrix, 1 / sx, 1 / sy);
1425
+ scaleX *= sx;
1426
+ scaleY *= sy;
1427
+ }
1428
+ scaleX *= pixelRatio;
1429
+ scaleY *= pixelRatio;
1430
+ width *= scaleX;
1431
+ height *= scaleY;
1432
+ const size = width * height;
1433
+ if (!repeat) {
1434
+ if (size > Platform.image.maxCacheSize)
1435
+ return false;
1436
+ }
1437
+ let maxSize = Platform.image.maxPatternSize;
1438
+ if (!image.isSVG) {
1439
+ const imageSize = image.width * image.height;
1440
+ if (maxSize > imageSize)
1441
+ maxSize = imageSize;
1442
+ }
1443
+ if (size > maxSize)
1444
+ imageScale = Math.sqrt(size / maxSize);
1445
+ if (imageScale) {
1446
+ scaleX /= imageScale;
1447
+ scaleY /= imageScale;
1448
+ width /= imageScale;
1449
+ height /= imageScale;
1450
+ }
1451
+ if (sx) {
1452
+ scaleX /= sx;
1453
+ scaleY /= sy;
1454
+ }
1455
+ if (transform || scaleX !== 1 || scaleY !== 1) {
1456
+ if (!imageMatrix) {
1457
+ imageMatrix = get$2();
1458
+ if (transform)
1459
+ copy$1(imageMatrix, transform);
1460
+ }
1461
+ scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1462
+ }
1463
+ const canvas = image.getCanvas(width < 1 ? 1 : round(width), height < 1 ? 1 : round(height), opacity);
1464
+ const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
1465
+ paint.style = pattern;
1466
+ paint.patternId = id;
1467
+ return true;
1468
+ }
1469
+ else {
1470
+ return false;
1471
+ }
1472
+ }
1473
+
1474
+ const { abs } = Math;
1475
+ function checkImage(ui, canvas, paint, allowPaint) {
1476
+ const { scaleX, scaleY } = ui.__world;
1477
+ if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
1478
+ return false;
1479
+ }
1480
+ else {
1481
+ const { data } = paint;
1482
+ if (allowPaint) {
1483
+ if (!data.repeat) {
1484
+ let { width, height } = data;
1485
+ width *= abs(scaleX) * canvas.pixelRatio;
1486
+ height *= abs(scaleY) * canvas.pixelRatio;
1487
+ if (data.scaleX) {
1488
+ width *= data.scaleX;
1489
+ height *= data.scaleY;
1490
+ }
1491
+ allowPaint = width * height > Platform.image.maxCacheSize;
1492
+ }
1493
+ else {
1494
+ allowPaint = false;
1495
+ }
1496
+ }
1497
+ if (allowPaint) {
1498
+ canvas.save();
1499
+ canvas.clip();
1500
+ if (paint.blendMode)
1501
+ canvas.blendMode = paint.blendMode;
1502
+ if (data.opacity)
1503
+ canvas.opacity *= data.opacity;
1504
+ if (data.transform)
1505
+ canvas.transform(data.transform);
1506
+ canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
1507
+ canvas.restore();
1508
+ return true;
1509
+ }
1510
+ else {
1511
+ if (!paint.style || Export.running) {
1512
+ createPattern(ui, paint, canvas.pixelRatio);
1513
+ }
1514
+ else {
1515
+ if (!paint.patternTask) {
1516
+ paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1517
+ paint.patternTask = null;
1518
+ if (canvas.bounds.hit(ui.__world))
1519
+ createPattern(ui, paint, canvas.pixelRatio);
1520
+ ui.forceUpdate('surface');
1521
+ }), 300);
1522
+ }
1523
+ }
1524
+ return false;
1525
+ }
1526
+ }
1527
+ }
1528
+
1529
+ function recycleImage(attrName, data) {
1530
+ const paints = data['_' + attrName];
1531
+ if (paints instanceof Array) {
1532
+ let image, recycleMap, input, url;
1533
+ for (let i = 0, len = paints.length; i < len; i++) {
1534
+ image = paints[i].image;
1535
+ url = image && image.url;
1536
+ if (url) {
1537
+ if (!recycleMap)
1538
+ recycleMap = {};
1539
+ recycleMap[url] = true;
1540
+ ImageManager.recycle(image);
1541
+ if (image.loading) {
1542
+ if (!input) {
1543
+ input = (data.__input && data.__input[attrName]) || [];
1544
+ if (!(input instanceof Array))
1545
+ input = [input];
1546
+ }
1547
+ image.unload(paints[i].loadId, !input.some((item) => item.url === url));
1548
+ }
1549
+ }
1550
+ }
1551
+ return recycleMap;
1552
+ }
1553
+ return null;
1554
+ }
1555
+
1556
+ const PaintImageModule = {
1557
+ image,
1558
+ createData,
1559
+ fillOrFitMode,
1560
+ clipMode,
1561
+ repeatMode,
1562
+ createPattern,
1563
+ checkImage,
1564
+ recycleImage
1565
+ };
1566
+
1567
+ const defaultFrom$2 = { x: 0.5, y: 0 };
1568
+ const defaultTo$2 = { x: 0.5, y: 1 };
1569
+ function linearGradient(paint, box) {
1570
+ let { from, to, type, blendMode, opacity } = paint;
1571
+ from || (from = defaultFrom$2);
1572
+ to || (to = defaultTo$2);
1573
+ const style = Platform.canvas.createLinearGradient(box.x + from.x * box.width, box.y + from.y * box.height, box.x + to.x * box.width, box.y + to.y * box.height);
1574
+ applyStops(style, paint.stops, opacity);
1575
+ const data = { type, style };
1576
+ if (blendMode)
1577
+ data.blendMode = blendMode;
1578
+ return data;
1579
+ }
1580
+ function applyStops(gradient, stops, opacity) {
1581
+ let stop;
1582
+ for (let i = 0, len = stops.length; i < len; i++) {
1583
+ stop = stops[i];
1584
+ gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
1585
+ }
1586
+ }
1587
+
1588
+ const { set: set$1, getAngle: getAngle$1, getDistance: getDistance$1 } = PointHelper;
1589
+ const { get: get$1, rotateOfOuter: rotateOfOuter$1, scaleOfOuter: scaleOfOuter$1 } = MatrixHelper;
1590
+ const defaultFrom$1 = { x: 0.5, y: 0.5 };
1591
+ const defaultTo$1 = { x: 0.5, y: 1 };
1592
+ const realFrom$1 = {};
1593
+ const realTo$1 = {};
1594
+ function radialGradient(paint, box) {
1595
+ let { from, to, type, opacity, blendMode, stretch } = paint;
1596
+ from || (from = defaultFrom$1);
1597
+ to || (to = defaultTo$1);
1598
+ const { x, y, width, height } = box;
1599
+ set$1(realFrom$1, x + from.x * width, y + from.y * height);
1600
+ set$1(realTo$1, x + to.x * width, y + to.y * height);
1601
+ let transform;
1602
+ if (width !== height || stretch) {
1603
+ transform = get$1();
1604
+ scaleOfOuter$1(transform, realFrom$1, width / height * (stretch || 1), 1);
1605
+ rotateOfOuter$1(transform, realFrom$1, getAngle$1(realFrom$1, realTo$1) + 90);
1606
+ }
1607
+ const style = Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
1608
+ applyStops(style, paint.stops, opacity);
1609
+ const data = { type, style, transform };
1610
+ if (blendMode)
1611
+ data.blendMode = blendMode;
1612
+ return data;
1613
+ }
1614
+
1615
+ const { set, getAngle, getDistance } = PointHelper;
1616
+ const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
1617
+ const defaultFrom = { x: 0.5, y: 0.5 };
1618
+ const defaultTo = { x: 0.5, y: 1 };
1619
+ const realFrom = {};
1620
+ const realTo = {};
1621
+ function conicGradient(paint, box) {
1622
+ let { from, to, type, opacity, blendMode, stretch } = paint;
1623
+ from || (from = defaultFrom);
1624
+ to || (to = defaultTo);
1625
+ const { x, y, width, height } = box;
1626
+ set(realFrom, x + from.x * width, y + from.y * height);
1627
+ set(realTo, x + to.x * width, y + to.y * height);
1628
+ const transform = get();
1629
+ const angle = getAngle(realFrom, realTo);
1630
+ if (Platform.conicGradientRotate90) {
1631
+ scaleOfOuter(transform, realFrom, width / height * (stretch || 1), 1);
1632
+ rotateOfOuter(transform, realFrom, angle + 90);
1633
+ }
1634
+ else {
1635
+ scaleOfOuter(transform, realFrom, 1, width / height * (stretch || 1));
1636
+ rotateOfOuter(transform, realFrom, angle);
1637
+ }
1638
+ const style = Platform.conicGradientSupport ? Platform.canvas.createConicGradient(0, realFrom.x, realFrom.y) : Platform.canvas.createRadialGradient(realFrom.x, realFrom.y, 0, realFrom.x, realFrom.y, getDistance(realFrom, realTo));
1639
+ applyStops(style, paint.stops, opacity);
1640
+ const data = { type, style, transform };
1641
+ if (blendMode)
1642
+ data.blendMode = blendMode;
1643
+ return data;
1644
+ }
1645
+
1646
+ const PaintGradientModule = {
1647
+ linearGradient,
1648
+ radialGradient,
1649
+ conicGradient
1650
+ };
1651
+
1652
+ const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
1653
+ const tempBounds = {};
1654
+ const offsetOutBounds$1 = {};
1655
+ function shadow(ui, current, shape) {
1656
+ let copyBounds, spreadScale;
1657
+ const { __nowWorld: nowWorld, __layout } = ui;
1658
+ const { shadow } = ui.__;
1659
+ const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
1660
+ const other = current.getSameCanvas();
1661
+ const end = shadow.length - 1;
1662
+ toOffsetOutBounds$1(bounds, offsetOutBounds$1);
1663
+ shadow.forEach((item, index) => {
1664
+ other.setWorldShadow((offsetOutBounds$1.offsetX + item.x * scaleX), (offsetOutBounds$1.offsetY + item.y * scaleY), item.blur * scaleX, item.color);
1665
+ spreadScale = item.spread ? 1 + item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) : 0;
1666
+ drawWorldShadow(other, offsetOutBounds$1, spreadScale, shape);
1667
+ copyBounds = bounds;
1668
+ if (item.box) {
1669
+ other.restore();
1670
+ other.save();
1671
+ if (worldCanvas) {
1672
+ other.copyWorld(other, bounds, nowWorld, 'copy');
1673
+ copyBounds = nowWorld;
1674
+ }
1675
+ worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
1676
+ }
1677
+ if (ui.__worldFlipped) {
1678
+ current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
1679
+ }
1680
+ else {
1681
+ current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
1682
+ }
1683
+ if (end && index < end)
1684
+ other.clearWorld(copyBounds, true);
1685
+ });
1686
+ other.recycle(copyBounds);
1687
+ }
1688
+ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
1689
+ const { bounds, shapeBounds } = shape;
1690
+ if (Platform.fullImageShadow) {
1691
+ copy(tempBounds, canvas.bounds);
1692
+ tempBounds.x += (outBounds.x - shapeBounds.x);
1693
+ tempBounds.y += (outBounds.y - shapeBounds.y);
1694
+ if (spreadScale) {
1695
+ const { matrix } = shape;
1696
+ tempBounds.x -= (bounds.x + (matrix ? matrix.e : 0) + bounds.width / 2) * (spreadScale - 1);
1697
+ tempBounds.y -= (bounds.y + (matrix ? matrix.f : 0) + bounds.height / 2) * (spreadScale - 1);
1698
+ tempBounds.width *= spreadScale;
1699
+ tempBounds.height *= spreadScale;
1700
+ }
1701
+ canvas.copyWorld(shape.canvas, canvas.bounds, tempBounds);
1702
+ }
1703
+ else {
1704
+ if (spreadScale) {
1705
+ copy(tempBounds, outBounds);
1706
+ tempBounds.x -= (outBounds.width / 2) * (spreadScale - 1);
1707
+ tempBounds.y -= (outBounds.height / 2) * (spreadScale - 1);
1708
+ tempBounds.width *= spreadScale;
1709
+ tempBounds.height *= spreadScale;
1710
+ }
1711
+ canvas.copyWorld(shape.canvas, shapeBounds, spreadScale ? tempBounds : outBounds);
1712
+ }
1713
+ }
1714
+
1715
+ const { toOffsetOutBounds } = BoundsHelper;
1716
+ const offsetOutBounds = {};
1717
+ function innerShadow(ui, current, shape) {
1718
+ let copyBounds, spreadScale;
1719
+ const { __nowWorld: nowWorld, __layout: __layout } = ui;
1720
+ const { innerShadow } = ui.__;
1721
+ const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
1722
+ const other = current.getSameCanvas();
1723
+ const end = innerShadow.length - 1;
1724
+ toOffsetOutBounds(bounds, offsetOutBounds);
1725
+ innerShadow.forEach((item, index) => {
1726
+ other.save();
1727
+ other.setWorldShadow((offsetOutBounds.offsetX + item.x * scaleX), (offsetOutBounds.offsetY + item.y * scaleY), item.blur * scaleX);
1728
+ spreadScale = item.spread ? 1 - item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) : 0;
1729
+ drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
1730
+ other.restore();
1731
+ if (worldCanvas) {
1732
+ other.copyWorld(other, bounds, nowWorld, 'copy');
1733
+ other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
1734
+ copyBounds = nowWorld;
1735
+ }
1736
+ else {
1737
+ other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
1738
+ copyBounds = bounds;
1739
+ }
1740
+ other.fillWorld(copyBounds, item.color, 'source-in');
1741
+ if (ui.__worldFlipped) {
1742
+ current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
1743
+ }
1744
+ else {
1745
+ current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
1746
+ }
1747
+ if (end && index < end)
1748
+ other.clearWorld(copyBounds, true);
1749
+ });
1750
+ other.recycle(copyBounds);
1751
+ }
1752
+
1753
+ function blur(ui, current, origin) {
1754
+ const { blur } = ui.__;
1755
+ origin.setWorldBlur(blur * ui.__world.a);
1756
+ origin.copyWorldToInner(current, ui.__world, ui.__layout.renderBounds);
1757
+ origin.filter = 'none';
1758
+ }
1759
+
1760
+ function backgroundBlur(_ui, _current, _shape) {
1761
+ }
1762
+
1763
+ const EffectModule = {
1764
+ shadow,
1765
+ innerShadow,
1766
+ blur,
1767
+ backgroundBlur
1768
+ };
1769
+
1770
+ const { excludeRenderBounds } = LeafBoundsHelper;
1771
+ Group.prototype.__renderMask = function (canvas, options) {
1772
+ let child, maskCanvas, contentCanvas, maskOpacity, currentMask;
1773
+ const { children } = this;
1774
+ for (let i = 0, len = children.length; i < len; i++) {
1775
+ child = children[i];
1776
+ if (child.__.mask) {
1777
+ if (currentMask) {
1778
+ maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
1779
+ maskCanvas = contentCanvas = null;
1780
+ }
1781
+ if (child.__.maskType === 'path') {
1782
+ if (child.opacity < 1) {
1783
+ currentMask = 'opacity-path';
1784
+ maskOpacity = child.opacity;
1785
+ if (!contentCanvas)
1786
+ contentCanvas = getCanvas(canvas);
1787
+ }
1788
+ else {
1789
+ currentMask = 'path';
1790
+ canvas.save();
1791
+ }
1792
+ child.__clip(contentCanvas || canvas, options);
1793
+ }
1794
+ else {
1795
+ currentMask = 'alpha';
1796
+ if (!maskCanvas)
1797
+ maskCanvas = getCanvas(canvas);
1798
+ if (!contentCanvas)
1799
+ contentCanvas = getCanvas(canvas);
1800
+ child.__render(maskCanvas, options);
1801
+ }
1802
+ if (child.__.maskType !== 'clipping')
1803
+ continue;
1804
+ }
1805
+ if (excludeRenderBounds(child, options))
1806
+ continue;
1807
+ child.__render(contentCanvas || canvas, options);
1808
+ }
1809
+ maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
1810
+ };
1811
+ function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
1812
+ switch (maskMode) {
1813
+ case 'alpha':
1814
+ usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
1815
+ break;
1816
+ case 'opacity-path':
1817
+ copyContent(leaf, canvas, contentCanvas, maskOpacity);
1818
+ break;
1819
+ case 'path':
1820
+ canvas.restore();
1821
+ }
1822
+ }
1823
+ function getCanvas(canvas) {
1824
+ return canvas.getSameCanvas(false, true);
1825
+ }
1826
+ function usePixelMask(leaf, canvas, content, mask) {
1827
+ const realBounds = leaf.__nowWorld;
1828
+ content.resetTransform();
1829
+ content.opacity = 1;
1830
+ content.useMask(mask, realBounds);
1831
+ mask.recycle(realBounds);
1832
+ copyContent(leaf, canvas, content, 1);
1833
+ }
1834
+ function copyContent(leaf, canvas, content, maskOpacity) {
1835
+ const realBounds = leaf.__nowWorld;
1836
+ canvas.resetTransform();
1837
+ canvas.opacity = maskOpacity;
1838
+ canvas.copyWorld(content, realBounds);
1839
+ content.recycle(realBounds);
1840
+ }
1841
+
1842
+ const money = '¥¥$€££¢¢';
1843
+ const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
1844
+ const langBefore = '《(「〈『〖【〔{┌<‘“=' + money;
1845
+ const langAfter = '》)」〉』〗】〕}┐>’”!?,、。:;‰';
1846
+ const langSymbol = '≮≯≈≠=…';
1847
+ const langBreak$1 = '—/~|┆·';
1848
+ const beforeChar = '{[(<\'"' + langBefore;
1849
+ const afterChar = '>)]}%!?,.:;\'"' + langAfter;
1850
+ const symbolChar = afterChar + '_#~&*+\\=|' + langSymbol;
1851
+ const breakChar = '- ' + langBreak$1;
1852
+ const cjkRangeList = [
1853
+ [0x4E00, 0x9FFF],
1854
+ [0x3400, 0x4DBF],
1855
+ [0x20000, 0x2A6DF],
1856
+ [0x2A700, 0x2B73F],
1857
+ [0x2B740, 0x2B81F],
1858
+ [0x2B820, 0x2CEAF],
1859
+ [0x2CEB0, 0x2EBEF],
1860
+ [0x30000, 0x3134F],
1861
+ [0x31350, 0x323AF],
1862
+ [0x2E80, 0x2EFF],
1863
+ [0x2F00, 0x2FDF],
1864
+ [0x2FF0, 0x2FFF],
1865
+ [0x3000, 0x303F],
1866
+ [0x31C0, 0x31EF],
1867
+ [0x3200, 0x32FF],
1868
+ [0x3300, 0x33FF],
1869
+ [0xF900, 0xFAFF],
1870
+ [0xFE30, 0xFE4F],
1871
+ [0x1F200, 0x1F2FF],
1872
+ [0x2F800, 0x2FA1F],
1873
+ ];
1874
+ const cjkReg = new RegExp(cjkRangeList.map(([start, end]) => `[\\u${start.toString(16)}-\\u${end.toString(16)}]`).join('|'));
1875
+ function mapChar(str) {
1876
+ const map = {};
1877
+ str.split('').forEach(char => map[char] = true);
1878
+ return map;
1879
+ }
1880
+ const letterMap = mapChar(letter);
1881
+ const beforeMap = mapChar(beforeChar);
1882
+ const afterMap = mapChar(afterChar);
1883
+ const symbolMap = mapChar(symbolChar);
1884
+ const breakMap = mapChar(breakChar);
1885
+ var CharType;
1886
+ (function (CharType) {
1887
+ CharType[CharType["Letter"] = 0] = "Letter";
1888
+ CharType[CharType["Single"] = 1] = "Single";
1889
+ CharType[CharType["Before"] = 2] = "Before";
1890
+ CharType[CharType["After"] = 3] = "After";
1891
+ CharType[CharType["Symbol"] = 4] = "Symbol";
1892
+ CharType[CharType["Break"] = 5] = "Break";
1893
+ })(CharType || (CharType = {}));
1894
+ const { Letter: Letter$1, Single: Single$1, Before: Before$1, After: After$1, Symbol: Symbol$1, Break: Break$1 } = CharType;
1895
+ function getCharType(char) {
1896
+ if (letterMap[char]) {
1897
+ return Letter$1;
1898
+ }
1899
+ else if (breakMap[char]) {
1900
+ return Break$1;
1901
+ }
1902
+ else if (beforeMap[char]) {
1903
+ return Before$1;
1904
+ }
1905
+ else if (afterMap[char]) {
1906
+ return After$1;
1907
+ }
1908
+ else if (symbolMap[char]) {
1909
+ return Symbol$1;
1910
+ }
1911
+ else if (cjkReg.test(char)) {
1912
+ return Single$1;
1913
+ }
1914
+ else {
1915
+ return Letter$1;
1916
+ }
1917
+ }
1918
+
1919
+ const TextRowHelper = {
1920
+ trimRight(row) {
1921
+ const { words } = row;
1922
+ let trimRight = 0, len = words.length, char;
1923
+ for (let i = len - 1; i > -1; i--) {
1924
+ char = words[i].data[0];
1925
+ if (char.char === ' ') {
1926
+ trimRight++;
1927
+ row.width -= char.width;
1928
+ }
1929
+ else {
1930
+ break;
1931
+ }
1932
+ }
1933
+ if (trimRight)
1934
+ words.splice(len - trimRight, trimRight);
1935
+ }
1936
+ };
1937
+
1938
+ function getTextCase(char, textCase, firstChar) {
1939
+ switch (textCase) {
1940
+ case 'title':
1941
+ return firstChar ? char.toUpperCase() : char;
1942
+ case 'upper':
1943
+ return char.toUpperCase();
1944
+ case 'lower':
1945
+ return char.toLowerCase();
1946
+ default:
1947
+ return char;
1948
+ }
1949
+ }
1950
+
1951
+ const { trimRight } = TextRowHelper;
1952
+ const { Letter, Single, Before, After, Symbol, Break } = CharType;
1953
+ let word, row, wordWidth, rowWidth, realWidth;
1954
+ let char, charWidth, startCharSize, charSize, charType, lastCharType, langBreak, afterBreak, paraStart;
1955
+ let textDrawData, rows = [], bounds;
1956
+ function createRows(drawData, content, style) {
1957
+ textDrawData = drawData;
1958
+ rows = drawData.rows;
1959
+ bounds = drawData.bounds;
1960
+ const { __letterSpacing, paraIndent, textCase } = style;
1961
+ const { canvas } = Platform;
1962
+ const { width, height } = bounds;
1963
+ const charMode = width || height || __letterSpacing || (textCase !== 'none');
1964
+ if (charMode) {
1965
+ const wrap = style.textWrap !== 'none';
1966
+ const breakAll = style.textWrap === 'break';
1967
+ paraStart = true;
1968
+ lastCharType = null;
1969
+ startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
1970
+ word = { data: [] }, row = { words: [] };
1971
+ for (let i = 0, len = content.length; i < len; i++) {
1972
+ char = content[i];
1973
+ if (char === '\n') {
1974
+ if (wordWidth)
1975
+ addWord();
1976
+ row.paraEnd = true;
1977
+ addRow();
1978
+ paraStart = true;
1979
+ }
1980
+ else {
1981
+ charType = getCharType(char);
1982
+ if (charType === Letter && textCase !== 'none')
1983
+ char = getTextCase(char, textCase, !wordWidth);
1984
+ charWidth = canvas.measureText(char).width;
1985
+ if (__letterSpacing) {
1986
+ if (__letterSpacing < 0)
1987
+ charSize = charWidth;
1988
+ charWidth += __letterSpacing;
1989
+ }
1990
+ langBreak = (charType === Single && (lastCharType === Single || lastCharType === Letter)) || (lastCharType === Single && charType !== After);
1991
+ afterBreak = ((charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After));
1992
+ realWidth = paraStart && paraIndent ? width - paraIndent : width;
1993
+ if (wrap && (width && rowWidth + wordWidth + charWidth > realWidth)) {
1994
+ if (breakAll) {
1995
+ if (wordWidth)
1996
+ addWord();
1997
+ addRow();
1998
+ }
1999
+ else {
2000
+ if (!afterBreak)
2001
+ afterBreak = charType === Letter && lastCharType == After;
2002
+ if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
2003
+ if (wordWidth)
2004
+ addWord();
2005
+ addRow();
2006
+ }
2007
+ else {
2008
+ addRow();
2009
+ }
2010
+ }
2011
+ }
2012
+ if (char === ' ' && paraStart !== true && (rowWidth + wordWidth) === 0) ;
2013
+ else {
2014
+ if (charType === Break) {
2015
+ if (char === ' ' && wordWidth)
2016
+ addWord();
2017
+ addChar(char, charWidth);
2018
+ addWord();
2019
+ }
2020
+ else if (langBreak || afterBreak) {
2021
+ if (wordWidth)
2022
+ addWord();
2023
+ addChar(char, charWidth);
2024
+ }
2025
+ else {
2026
+ addChar(char, charWidth);
2027
+ }
2028
+ }
2029
+ lastCharType = charType;
2030
+ }
2031
+ }
2032
+ if (wordWidth)
2033
+ addWord();
2034
+ if (rowWidth)
2035
+ addRow();
2036
+ rows.length > 0 && (rows[rows.length - 1].paraEnd = true);
2037
+ }
2038
+ else {
2039
+ content.split('\n').forEach(content => {
2040
+ textDrawData.paraNumber++;
2041
+ rows.push({ x: paraIndent || 0, text: content, width: canvas.measureText(content).width, paraStart: true });
2042
+ });
2043
+ }
2044
+ }
2045
+ function addChar(char, width) {
2046
+ if (charSize && !startCharSize)
2047
+ startCharSize = charSize;
2048
+ word.data.push({ char, width });
2049
+ wordWidth += width;
2050
+ }
2051
+ function addWord() {
2052
+ rowWidth += wordWidth;
2053
+ word.width = wordWidth;
2054
+ row.words.push(word);
2055
+ word = { data: [] };
2056
+ wordWidth = 0;
2057
+ }
2058
+ function addRow() {
2059
+ if (paraStart) {
2060
+ textDrawData.paraNumber++;
2061
+ row.paraStart = true;
2062
+ paraStart = false;
2063
+ }
2064
+ if (charSize) {
2065
+ row.startCharSize = startCharSize;
2066
+ row.endCharSize = charSize;
2067
+ startCharSize = 0;
2068
+ }
2069
+ row.width = rowWidth;
2070
+ if (bounds.width)
2071
+ trimRight(row);
2072
+ rows.push(row);
2073
+ row = { words: [] };
2074
+ rowWidth = 0;
2075
+ }
2076
+
2077
+ const CharMode = 0;
2078
+ const WordMode = 1;
2079
+ const TextMode = 2;
2080
+ function layoutChar(drawData, style, width, _height) {
2081
+ const { rows } = drawData;
2082
+ const { textAlign, paraIndent, letterSpacing } = style;
2083
+ let charX, addWordWidth, indentWidth, mode, wordChar;
2084
+ rows.forEach(row => {
2085
+ if (row.words) {
2086
+ indentWidth = paraIndent && row.paraStart ? paraIndent : 0;
2087
+ addWordWidth = (width && textAlign === 'justify' && row.words.length > 1) ? (width - row.width - indentWidth) / (row.words.length - 1) : 0;
2088
+ mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : TextMode);
2089
+ if (row.isOverflow && !letterSpacing)
2090
+ row.textMode = true;
2091
+ if (mode === TextMode) {
2092
+ row.x += indentWidth;
2093
+ toTextChar$1(row);
2094
+ }
2095
+ else {
2096
+ row.x += indentWidth;
2097
+ charX = row.x;
2098
+ row.data = [];
2099
+ row.words.forEach(word => {
2100
+ if (mode === WordMode) {
2101
+ wordChar = { char: '', x: charX };
2102
+ charX = toWordChar(word.data, charX, wordChar);
2103
+ if (wordChar.char !== ' ')
2104
+ row.data.push(wordChar);
2105
+ }
2106
+ else {
2107
+ charX = toChar(word.data, charX, row.data);
2108
+ }
2109
+ if (!row.paraEnd && addWordWidth) {
2110
+ charX += addWordWidth;
2111
+ row.width += addWordWidth;
2112
+ }
2113
+ });
2114
+ }
2115
+ row.words = null;
2116
+ }
2117
+ });
2118
+ }
2119
+ function toTextChar$1(row) {
2120
+ row.text = '';
2121
+ row.words.forEach(word => {
2122
+ word.data.forEach(char => {
2123
+ row.text += char.char;
2124
+ });
2125
+ });
2126
+ }
2127
+ function toWordChar(data, charX, wordChar) {
2128
+ data.forEach(char => {
2129
+ wordChar.char += char.char;
2130
+ charX += char.width;
2131
+ });
2132
+ return charX;
2133
+ }
2134
+ function toChar(data, charX, rowData) {
2135
+ data.forEach(char => {
2136
+ if (char.char !== ' ') {
2137
+ char.x = charX;
2138
+ rowData.push(char);
2139
+ }
2140
+ charX += char.width;
2141
+ });
2142
+ return charX;
2143
+ }
2144
+
2145
+ function layoutText(drawData, style) {
2146
+ const { rows, bounds } = drawData;
2147
+ const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing } = style;
2148
+ let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
2149
+ let starY = __baseLine;
2150
+ if (__clipText && realHeight > height) {
2151
+ realHeight = Math.max(height, __lineHeight);
2152
+ drawData.overflow = rows.length;
2153
+ }
2154
+ else {
2155
+ switch (verticalAlign) {
2156
+ case 'middle':
2157
+ y += (height - realHeight) / 2;
2158
+ break;
2159
+ case 'bottom':
2160
+ y += (height - realHeight);
2161
+ }
2162
+ }
2163
+ starY += y;
2164
+ let row, rowX, rowWidth;
2165
+ for (let i = 0, len = rows.length; i < len; i++) {
2166
+ row = rows[i];
2167
+ row.x = x;
2168
+ switch (textAlign) {
2169
+ case 'center':
2170
+ row.x += (width - row.width) / 2;
2171
+ break;
2172
+ case 'right':
2173
+ row.x += width - row.width;
2174
+ }
2175
+ if (row.paraStart && paraSpacing && i > 0)
2176
+ starY += paraSpacing;
2177
+ row.y = starY;
2178
+ starY += __lineHeight;
2179
+ if (drawData.overflow > i && starY > realHeight) {
2180
+ row.isOverflow = true;
2181
+ drawData.overflow = i + 1;
2182
+ }
2183
+ rowX = row.x;
2184
+ rowWidth = row.width;
2185
+ if (__letterSpacing < 0) {
2186
+ if (row.width < 0) {
2187
+ rowWidth = -row.width + style.fontSize + __letterSpacing;
2188
+ rowX -= rowWidth;
2189
+ rowWidth += style.fontSize;
2190
+ }
2191
+ else {
2192
+ rowWidth -= __letterSpacing;
2193
+ }
2194
+ }
2195
+ if (rowX < bounds.x)
2196
+ bounds.x = rowX;
2197
+ if (rowWidth > bounds.width)
2198
+ bounds.width = rowWidth;
2199
+ if (__clipText && width && width < rowWidth) {
2200
+ row.isOverflow = true;
2201
+ if (!drawData.overflow)
2202
+ drawData.overflow = rows.length;
2203
+ }
2204
+ }
2205
+ bounds.y = y;
2206
+ bounds.height = realHeight;
2207
+ }
2208
+
2209
+ function clipText(drawData, style) {
2210
+ const { rows, overflow } = drawData;
2211
+ let { textOverflow } = style;
2212
+ rows.splice(overflow);
2213
+ if (textOverflow !== 'hide') {
2214
+ if (textOverflow === 'ellipsis')
2215
+ textOverflow = '...';
2216
+ let char, charRight;
2217
+ const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
2218
+ const right = style.x + style.width - ellipsisWidth;
2219
+ const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
2220
+ list.forEach(row => {
2221
+ if (row.isOverflow && row.data) {
2222
+ let end = row.data.length - 1;
2223
+ for (let i = end; i > -1; i--) {
2224
+ char = row.data[i];
2225
+ charRight = char.x + char.width;
2226
+ if (i === end && charRight < right) {
2227
+ break;
2228
+ }
2229
+ else if (charRight < right && char.char !== ' ') {
2230
+ row.data.splice(i + 1);
2231
+ row.width -= char.width;
2232
+ break;
2233
+ }
2234
+ row.width -= char.width;
2235
+ }
2236
+ row.width += ellipsisWidth;
2237
+ row.data.push({ char: textOverflow, x: charRight });
2238
+ if (row.textMode)
2239
+ toTextChar(row);
2240
+ }
2241
+ });
2242
+ }
2243
+ }
2244
+ function toTextChar(row) {
2245
+ row.text = '';
2246
+ row.data.forEach(char => {
2247
+ row.text += char.char;
2248
+ });
2249
+ row.data = null;
2250
+ }
2251
+
2252
+ function decorationText(drawData, style) {
2253
+ const { fontSize } = style;
2254
+ drawData.decorationHeight = fontSize / 11;
2255
+ switch (style.textDecoration) {
2256
+ case 'under':
2257
+ drawData.decorationY = fontSize * 0.15;
2258
+ break;
2259
+ case 'delete':
2260
+ drawData.decorationY = -fontSize * 0.35;
2261
+ }
2262
+ }
2263
+
2264
+ const { top, right, bottom, left } = Direction4;
2265
+ function getDrawData(content, style) {
2266
+ if (typeof content !== 'string')
2267
+ content = String(content);
2268
+ let x = 0, y = 0;
2269
+ let width = style.__getInput('width') || 0;
2270
+ let height = style.__getInput('height') || 0;
2271
+ const { textDecoration, __font, __padding: padding } = style;
2272
+ if (padding) {
2273
+ if (width) {
2274
+ x = padding[left];
2275
+ width -= (padding[right] + padding[left]);
2276
+ }
2277
+ if (height) {
2278
+ y = padding[top];
2279
+ height -= (padding[top] + padding[bottom]);
2280
+ }
2281
+ }
2282
+ const drawData = {
2283
+ bounds: { x, y, width, height },
2284
+ rows: [],
2285
+ paraNumber: 0,
2286
+ font: Platform.canvas.font = __font
2287
+ };
2288
+ createRows(drawData, content, style);
2289
+ if (padding)
2290
+ padAutoText(padding, drawData, style, width, height);
2291
+ layoutText(drawData, style);
2292
+ layoutChar(drawData, style, width);
2293
+ if (drawData.overflow)
2294
+ clipText(drawData, style);
2295
+ if (textDecoration !== 'none')
2296
+ decorationText(drawData, style);
2297
+ return drawData;
2298
+ }
2299
+ function padAutoText(padding, drawData, style, width, height) {
2300
+ if (!width) {
2301
+ switch (style.textAlign) {
2302
+ case 'left':
2303
+ offsetText(drawData, 'x', padding[left]);
2304
+ break;
2305
+ case 'right':
2306
+ offsetText(drawData, 'x', -padding[right]);
2307
+ }
2308
+ }
2309
+ if (!height) {
2310
+ switch (style.verticalAlign) {
2311
+ case 'top':
2312
+ offsetText(drawData, 'y', padding[top]);
2313
+ break;
2314
+ case 'bottom':
2315
+ offsetText(drawData, 'y', -padding[bottom]);
2316
+ }
2317
+ }
2318
+ }
2319
+ function offsetText(drawData, attrName, value) {
2320
+ const { bounds, rows } = drawData;
2321
+ bounds[attrName] += value;
2322
+ for (let i = 0; i < rows.length; i++)
2323
+ rows[i][attrName] += value;
2324
+ }
2325
+
2326
+ const TextConvertModule = {
2327
+ getDrawData
2328
+ };
2329
+
2330
+ function string(color, opacity) {
2331
+ if (typeof color === 'string')
2332
+ return color;
2333
+ let a = color.a === undefined ? 1 : color.a;
2334
+ if (opacity)
2335
+ a *= opacity;
2336
+ const rgb = color.r + ',' + color.g + ',' + color.b;
2337
+ return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
2338
+ }
2339
+
2340
+ const ColorConvertModule = {
2341
+ string
2342
+ };
2343
+
2344
+ const { setPoint, addPoint, toBounds } = TwoPointBoundsHelper;
2345
+ function getTrimBounds(canvas) {
2346
+ const { width, height } = canvas.view;
2347
+ const { data } = canvas.context.getImageData(0, 0, width, height);
2348
+ let x, y, pointBounds, index = 0;
2349
+ for (let i = 0; i < data.length; i += 4) {
2350
+ if (data[i + 3] !== 0) {
2351
+ x = index % width;
2352
+ y = (index - x) / width;
2353
+ pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
2354
+ }
2355
+ index++;
2356
+ }
2357
+ const bounds = new Bounds();
2358
+ toBounds(pointBounds, bounds);
2359
+ return bounds.scale(1 / canvas.pixelRatio).ceil();
2360
+ }
2361
+
2362
+ const ExportModule = {
2363
+ export(leaf, filename, options) {
2364
+ this.running = true;
2365
+ return addTask((success) => new Promise((resolve) => {
2366
+ const over = (result) => {
2367
+ success(result);
2368
+ resolve();
2369
+ this.running = false;
2370
+ };
2371
+ const { leafer } = leaf;
2372
+ if (leafer) {
2373
+ leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
2374
+ let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
2375
+ options = FileHelper.getExportOptions(options);
2376
+ const { scale, slice, trim } = options;
2377
+ const pixelRatio = options.pixelRatio || 1;
2378
+ const screenshot = options.screenshot || leaf.isApp;
2379
+ const fill = options.fill === undefined ? ((leaf.isLeafer && screenshot) ? leaf.fill : '') : options.fill;
2380
+ const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
2381
+ if (screenshot) {
2382
+ renderBounds = screenshot === true ? (leaf.isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
2383
+ }
2384
+ else {
2385
+ const { localTransform, __world: world } = leaf;
2386
+ matrix.set(world).divide(localTransform).invert();
2387
+ scaleX = 1 / (world.scaleX / leaf.scaleX);
2388
+ scaleY = 1 / (world.scaleY / leaf.scaleY);
2389
+ renderBounds = leaf.getBounds('render', 'local');
2390
+ }
2391
+ let { x, y, width, height } = renderBounds;
2392
+ if (scale) {
2393
+ matrix.scale(scale);
2394
+ width *= scale, height *= scale;
2395
+ scaleX *= scale, scaleY *= scale;
2396
+ }
2397
+ let canvas = Creator.canvas({ width: Math.ceil(width), height: Math.ceil(width), pixelRatio });
2398
+ const renderOptions = { matrix: matrix.translate(-x, -y).withScale(scaleX, scaleY) };
2399
+ if (slice) {
2400
+ leaf = leafer;
2401
+ renderOptions.bounds = canvas.bounds;
2402
+ }
2403
+ canvas.save();
2404
+ leaf.__render(canvas, renderOptions);
2405
+ canvas.restore();
2406
+ if (trim) {
2407
+ trimBounds = getTrimBounds(canvas);
2408
+ const old = canvas, { width, height } = trimBounds;
2409
+ const config = { x: 0, y: 0, width, height, pixelRatio };
2410
+ canvas = Creator.canvas(config);
2411
+ canvas.copyWorld(old, trimBounds, config);
2412
+ }
2413
+ if (needFill)
2414
+ canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
2415
+ const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
2416
+ over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
2417
+ }));
2418
+ }
2419
+ else {
2420
+ over({ data: false });
2421
+ }
2422
+ }));
2423
+ }
2424
+ };
2425
+ let tasker;
2426
+ function addTask(task) {
2427
+ if (!tasker)
2428
+ tasker = new TaskProcessor();
2429
+ return new Promise((resolve) => {
2430
+ tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
2431
+ });
2432
+ }
2433
+
2434
+ Object.assign(TextConvert, TextConvertModule);
2435
+ Object.assign(ColorConvert, ColorConvertModule);
2436
+ Object.assign(Paint, PaintModule);
2437
+ Object.assign(PaintImage, PaintImageModule);
2438
+ Object.assign(PaintGradient, PaintGradientModule);
2439
+ Object.assign(Effect, EffectModule);
2440
+ Object.assign(Export, ExportModule);
2441
+
2442
+ Object.assign(Creator, {
2443
+ interaction: (target, canvas, selector, options) => { return new InteractionBase(target, canvas, selector, options); },
2444
+ hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
2445
+ hitCanvasManager: () => new HitCanvasManager()
2446
+ });
2447
+
2448
+ export { Layouter, LeaferCanvas, Renderer, Selector, Watcher, useCanvas };