@leafer-ui/worker 1.0.1 → 1.0.3

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