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