@leafer-draw/miniapp 1.0.0-rc.10

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