@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.cjs +1235 -1087
- package/dist/node.esm.js +1219 -1081
- package/dist/node.esm.min.js +1 -1
- package/dist/node.esm.min.js.map +1 -1
- package/dist/node.min.cjs +1 -1
- package/dist/node.min.cjs.map +1 -1
- package/package.json +10 -10
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
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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() {
|
|
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:
|
|
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 ===
|
|
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, {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
|
|
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*
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
129
|
+
|
|
130
|
+
Platform.name = "node";
|
|
131
|
+
|
|
103
132
|
Platform.backgrounder = true;
|
|
104
|
-
|
|
105
|
-
|
|
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() {
|
|
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 => {
|
|
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
|
|
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, {
|
|
175
|
-
|
|
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 {
|
|
201
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
347
|
-
const
|
|
348
|
-
const {
|
|
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(
|
|
370
|
-
const { target
|
|
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 => {
|
|
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(
|
|
445
|
+
const debug$1 = Debug.get("Renderer");
|
|
446
|
+
|
|
430
447
|
class Renderer {
|
|
431
|
-
get needFill() {
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
544
|
-
if (!list)
|
|
545
|
-
return;
|
|
552
|
+
const {canvas: canvas, updateBlocks: list} = this;
|
|
553
|
+
if (!list) return;
|
|
546
554
|
this.mergeBlocks();
|
|
547
|
-
list.forEach(block => {
|
|
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(
|
|
552
|
-
const { canvas
|
|
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(
|
|
563
|
-
const { canvas
|
|
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
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
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 {
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
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(
|
|
685
|
-
|
|
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.
|
|
718
|
-
|
|
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) :
|
|
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
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
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
|
-
|
|
753
|
-
|
|
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 ===
|
|
764
|
+
out.blendMode = align === "outside" ? "destination-out" : "destination-in";
|
|
760
765
|
fillText(ui, out);
|
|
761
|
-
out.blendMode =
|
|
762
|
-
|
|
766
|
+
out.blendMode = "normal";
|
|
767
|
+
LeafHelper.copyCanvasByWorld(ui, canvas, out);
|
|
763
768
|
out.recycle(ui.__nowWorld);
|
|
764
769
|
}
|
|
765
|
-
|
|
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(
|
|
778
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
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
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
875
|
-
const
|
|
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 {
|
|
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
|
-
|
|
888
|
-
|
|
889
|
-
fitMatrix
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
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
|
|
898
|
-
|
|
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
|
-
|
|
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
|
|
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))
|
|
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[
|
|
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 ===
|
|
922
|
-
stintSet(data,
|
|
923
|
-
stintSet(data,
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
stintSet(data,
|
|
927
|
-
stintSet(data,
|
|
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 (
|
|
932
|
-
return undefined;
|
|
956
|
+
if (!isObject(paint) || paint.visible === false || paint.opacity === 0) return undefined;
|
|
933
957
|
let data;
|
|
934
|
-
const { boxBounds
|
|
958
|
+
const {boxBounds: boxBounds} = ui.__layout;
|
|
935
959
|
switch (paint.type) {
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
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 (
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
data.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1029
|
+
|
|
1030
|
+
function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipSize) {
|
|
989
1031
|
const transform = get$3();
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
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
|
-
|
|
1039
|
+
|
|
1040
|
+
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
|
|
1000
1041
|
const transform = get$3();
|
|
1001
|
-
if (
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
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
|
-
|
|
1057
|
+
|
|
1058
|
+
case 180:
|
|
1012
1059
|
translate$1(transform, width, height);
|
|
1013
1060
|
break;
|
|
1014
|
-
|
|
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
|
-
|
|
1029
|
-
|
|
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,
|
|
1034
|
-
if (changeful)
|
|
1035
|
-
|
|
1036
|
-
if (
|
|
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
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
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 = {
|
|
1051
|
-
|
|
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 ===
|
|
1111
|
+
if (!mode || mode === "cover" || mode === "fit") {
|
|
1055
1112
|
if (!sameBox || rotation) {
|
|
1056
|
-
scaleX = scaleY = BoundsHelper.getFitScale(box, tempImage, mode !==
|
|
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
|
-
|
|
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
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
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 !==
|
|
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
|
-
|
|
1111
|
-
if (
|
|
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
|
-
|
|
1119
|
-
|
|
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
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
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
|
-
|
|
1142
|
-
|
|
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
|
-
|
|
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
|
-
},
|
|
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.
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
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 ===
|
|
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(
|
|
1257
|
+
ui.forceUpdate("width");
|
|
1187
1258
|
if (ui.__proxyData) {
|
|
1188
|
-
ui.setProxyAttr(
|
|
1189
|
-
ui.setProxyAttr(
|
|
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(
|
|
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
|
|
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 {
|
|
1220
|
-
|
|
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 } =
|
|
1223
|
-
const id = scaleX +
|
|
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
|
-
|
|
1226
|
-
scaleY =
|
|
1227
|
-
|
|
1228
|
-
|
|
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
|
|
1231
|
-
sy = abs
|
|
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
|
-
|
|
1274
|
-
|
|
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 } =
|
|
1287
|
-
const { pixelRatio
|
|
1288
|
-
if (!data ||
|
|
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
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
1336
|
-
if (data.
|
|
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[
|
|
1346
|
-
if (paints
|
|
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 =
|
|
1360
|
-
if (!(input
|
|
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(
|
|
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 {
|
|
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 ||
|
|
1390
|
-
toPoint$2(to ||
|
|
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 = {
|
|
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 (
|
|
1402
|
-
|
|
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
|
|
1415
|
-
|
|
1416
|
-
const {
|
|
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 ||
|
|
1422
|
-
toPoint$1(to ||
|
|
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 = {
|
|
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
|
|
1450
|
-
|
|
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 ||
|
|
1456
|
-
toPoint(to ||
|
|
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 = {
|
|
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
|
|
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 {
|
|
1479
|
-
const { shadow
|
|
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
|
-
|
|
1486
|
-
|
|
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,
|
|
1585
|
+
other.copyWorld(other, bounds, nowWorld, "copy");
|
|
1494
1586
|
copyBounds = nowWorld;
|
|
1495
1587
|
}
|
|
1496
|
-
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld,
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1499
|
-
|
|
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 +=
|
|
1512
|
-
tempBounds.y +=
|
|
1600
|
+
tempBounds.x += outBounds.x - shapeBounds.x;
|
|
1601
|
+
tempBounds.y += outBounds.y - shapeBounds.y;
|
|
1513
1602
|
if (spreadScale) {
|
|
1514
|
-
const {
|
|
1515
|
-
tempBounds.x -= (bounds.x + (
|
|
1516
|
-
tempBounds.y -= (bounds.y + (
|
|
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 -=
|
|
1526
|
-
tempBounds.y -=
|
|
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
|
|
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 {
|
|
1539
|
-
const { innerShadow
|
|
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(
|
|
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,
|
|
1552
|
-
other.copyWorld(worldCanvas, nowWorld, nowWorld,
|
|
1646
|
+
other.copyWorld(other, bounds, nowWorld, "copy");
|
|
1647
|
+
other.copyWorld(worldCanvas, nowWorld, nowWorld, "source-out");
|
|
1553
1648
|
copyBounds = nowWorld;
|
|
1554
|
-
}
|
|
1555
|
-
|
|
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),
|
|
1560
|
-
|
|
1561
|
-
|
|
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
|
|
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 =
|
|
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
|
|
1588
|
-
|
|
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
|
|
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
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
}
|
|
1605
|
-
|
|
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
|
-
|
|
1612
|
-
|
|
1613
|
-
if (!
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
1717
|
+
|
|
1718
|
+
function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity, blendMode, recycle) {
|
|
1629
1719
|
switch (maskMode) {
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1663
|
-
const
|
|
1664
|
-
|
|
1665
|
-
const
|
|
1666
|
-
|
|
1667
|
-
const
|
|
1668
|
-
|
|
1669
|
-
const
|
|
1670
|
-
|
|
1671
|
-
const
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
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
|
|
1771
|
-
|
|
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
|
|
1782
|
-
const { width, height } = bounds;
|
|
1783
|
-
const charMode = width || height || __letterSpacing ||
|
|
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 !==
|
|
1786
|
-
const breakAll = style.textWrap ===
|
|
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 = {
|
|
1791
|
-
|
|
1792
|
-
|
|
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 ===
|
|
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 !==
|
|
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 =
|
|
1813
|
-
afterBreak = (
|
|
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
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
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 ===
|
|
1838
|
-
else {
|
|
1924
|
+
if (char === " " && paraStart !== true && rowWidth + wordWidth === 0) ; else {
|
|
1839
1925
|
if (charType === Break) {
|
|
1840
|
-
if (char ===
|
|
1841
|
-
addWord();
|
|
1926
|
+
if (char === " " && wordWidth) addWord();
|
|
1842
1927
|
addChar(char, charWidth);
|
|
1843
1928
|
addWord();
|
|
1844
|
-
}
|
|
1845
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
1868
|
-
|
|
1869
|
-
|
|
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
|
-
|
|
1876
|
-
|
|
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 = {
|
|
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 = {
|
|
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
|
|
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 =
|
|
1922
|
-
mode =
|
|
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 = {
|
|
2025
|
+
wordChar = {
|
|
2026
|
+
char: "",
|
|
2027
|
+
x: charX
|
|
2028
|
+
};
|
|
1936
2029
|
charX = toWordChar(word.data, charX, wordChar);
|
|
1937
|
-
if (row.isOverflow || wordChar.char !==
|
|
1938
|
-
|
|
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 ===
|
|
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
|
-
|
|
1988
|
-
}
|
|
1989
|
-
else if (height || autoSizeAlign) {
|
|
2080
|
+
if (countRows > 1) drawData.overflow = countRows;
|
|
2081
|
+
} else if (height || autoSizeAlign) {
|
|
1990
2082
|
switch (verticalAlign) {
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
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 =
|
|
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 ||
|
|
2096
|
+
if (row.width < width || row.width > width && !__clipText) {
|
|
2003
2097
|
switch (textAlign) {
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2047
|
-
|
|
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 !==
|
|
2051
|
-
if (textOverflow ===
|
|
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 ===
|
|
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({
|
|
2077
|
-
|
|
2078
|
-
|
|
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 (
|
|
2184
|
+
if (isObject(textDecoration)) {
|
|
2096
2185
|
type = textDecoration.type;
|
|
2097
|
-
if (textDecoration.color)
|
|
2098
|
-
|
|
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
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
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 (
|
|
2117
|
-
content = String(content);
|
|
2205
|
+
if (!isString(content)) content = String(content);
|
|
2118
2206
|
let x = 0, y = 0;
|
|
2119
|
-
let width = style.__getInput(
|
|
2120
|
-
let height = style.__getInput(
|
|
2121
|
-
const { textDecoration, __font, __padding: padding
|
|
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
|
-
|
|
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: {
|
|
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
|
-
|
|
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
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
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
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
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 =
|
|
2180
|
-
if (
|
|
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
|
|
2187
|
-
if (doOpacity)
|
|
2188
|
-
|
|
2189
|
-
|
|
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
|
|
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
|
-
|
|
2219
|
-
|
|
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
|
-
|
|
2318
|
+
Export.running = true;
|
|
2225
2319
|
let result;
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2360
|
+
|
|
2361
|
+
case "world":
|
|
2264
2362
|
scaleX = 1;
|
|
2265
2363
|
scaleY = 1;
|
|
2266
2364
|
break;
|
|
2267
|
-
|
|
2365
|
+
|
|
2366
|
+
case "page":
|
|
2268
2367
|
relative = leafer || leaf;
|
|
2269
|
-
|
|
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
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
x += clip.x, y += clip.y, width = clip.width, height = clip.height;
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
canvas.
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
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
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
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
|
-
|
|
2461
|
+
Export.running = false;
|
|
2326
2462
|
return result;
|
|
2327
2463
|
},
|
|
2328
2464
|
export(leaf, filename, options) {
|
|
2329
|
-
|
|
2330
|
-
return addTask(
|
|
2331
|
-
const getResult = () => __awaiter(this, void 0, void 0, function*
|
|
2332
|
-
if (!Resource.isComplete)
|
|
2333
|
-
|
|
2334
|
-
|
|
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
|
|
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
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
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
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
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(
|
|
2513
|
+
}).catch(e => {
|
|
2381
2514
|
debug.error(e);
|
|
2382
2515
|
resolve(null);
|
|
2383
2516
|
});
|
|
2384
2517
|
});
|
|
2385
2518
|
};
|
|
2386
|
-
|
|
2519
|
+
|
|
2520
|
+
canvas.toDataURL = function(type, quality) {
|
|
2387
2521
|
return Platform$1.origin.canvasToDataURL(this.view, type, quality);
|
|
2388
2522
|
};
|
|
2389
|
-
|
|
2390
|
-
|
|
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(
|
|
2528
|
+
}).catch(e => {
|
|
2394
2529
|
debug.error(e);
|
|
2395
2530
|
resolve(false);
|
|
2396
2531
|
});
|
|
2397
2532
|
});
|
|
2398
2533
|
};
|
|
2399
2534
|
|
|
2400
|
-
Plugin.add(
|
|
2535
|
+
Plugin.add("export");
|
|
2536
|
+
|
|
2401
2537
|
Object.assign(Export, ExportModule);
|
|
2402
|
-
|
|
2538
|
+
|
|
2539
|
+
UI.prototype.export = function(filename, options) {
|
|
2403
2540
|
return Export.export(this, filename, options);
|
|
2404
2541
|
};
|
|
2405
|
-
|
|
2542
|
+
|
|
2543
|
+
UI.prototype.syncExport = function(filename, options) {
|
|
2406
2544
|
return Export.syncExport(this, filename, options);
|
|
2407
2545
|
};
|
|
2408
2546
|
|