@leafer-ui/worker 1.7.0 → 1.9.0

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