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