@leafer-draw/miniapp 1.0.1 → 1.0.3

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