@leafer-ui/node 1.0.0-beta.11 → 1.0.0-beta.15

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