@overtone-art/canvas-editor-core 0.6.4 → 0.7.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/chunk-XNGPX7FG.mjs +641 -0
- package/dist/chunk-XNGPX7FG.mjs.map +1 -0
- package/dist/index.d.mts +99 -3
- package/dist/index.d.ts +99 -3
- package/dist/index.global.js +55 -54
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +426 -127
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +87 -138
- package/dist/index.mjs.map +1 -1
- package/dist/node.d.mts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +146 -0
- package/dist/node.js.map +1 -1
- package/dist/node.mjs +3 -1
- package/dist/node.mjs.map +1 -1
- package/dist/{types-DSu2jbiV.d.mts → types-DLrbzRj1.d.mts} +20 -1
- package/dist/{types-DSu2jbiV.d.ts → types-DLrbzRj1.d.ts} +20 -1
- package/package.json +1 -1
- package/dist/chunk-MCBRZQ4M.mjs +0 -261
- package/dist/chunk-MCBRZQ4M.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
+
TEXT_FIT_SLACK,
|
|
3
|
+
TextWrapManager,
|
|
4
|
+
applyMatrix,
|
|
5
|
+
applyRelativeMatrix,
|
|
6
|
+
applyTextWrapToObject,
|
|
7
|
+
asObject,
|
|
8
|
+
asText,
|
|
2
9
|
computeCoverPlacement,
|
|
3
10
|
computePrintAreaClip,
|
|
4
11
|
displaceRgba,
|
|
@@ -7,8 +14,19 @@ import {
|
|
|
7
14
|
exportMockup,
|
|
8
15
|
exportPNG,
|
|
9
16
|
exportPrintArea,
|
|
10
|
-
exportSVG
|
|
11
|
-
|
|
17
|
+
exportSVG,
|
|
18
|
+
fitTextWidth,
|
|
19
|
+
fitToBox,
|
|
20
|
+
matrixOf,
|
|
21
|
+
preWrapWordSplit,
|
|
22
|
+
readTextWrap,
|
|
23
|
+
relativeMatrix,
|
|
24
|
+
textInk,
|
|
25
|
+
toCanvasSpace,
|
|
26
|
+
toHostSpace,
|
|
27
|
+
toMatrix,
|
|
28
|
+
unwrapGroup
|
|
29
|
+
} from "./chunk-XNGPX7FG.mjs";
|
|
12
30
|
|
|
13
31
|
// src/editor.ts
|
|
14
32
|
import { Canvas, FabricImage as FabricImage3, Group as Group7, Textbox as Textbox2, filters } from "fabric";
|
|
@@ -1143,60 +1161,7 @@ var STROKE2 = "#22c55e";
|
|
|
1143
1161
|
import { util } from "fabric";
|
|
1144
1162
|
|
|
1145
1163
|
// src/pattern/tiled-pattern-object.ts
|
|
1146
|
-
import { FabricObject, Point
|
|
1147
|
-
|
|
1148
|
-
// src/text-fit.ts
|
|
1149
|
-
import { Point } from "fabric";
|
|
1150
|
-
var TEXT_FIT_SLACK = 0.5;
|
|
1151
|
-
var MEASURE_WIDTH = 1e5;
|
|
1152
|
-
function unwrappedWidth(text) {
|
|
1153
|
-
const authored = text.width;
|
|
1154
|
-
try {
|
|
1155
|
-
text.set({ width: MEASURE_WIDTH });
|
|
1156
|
-
text.initDimensions?.();
|
|
1157
|
-
const measured = text.calcTextWidth?.() ?? authored;
|
|
1158
|
-
return Number.isFinite(measured) && measured > 0 ? measured : authored;
|
|
1159
|
-
} finally {
|
|
1160
|
-
text.set({ width: authored });
|
|
1161
|
-
text.initDimensions?.();
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
function asText(object) {
|
|
1165
|
-
if (!object) return null;
|
|
1166
|
-
const text = object;
|
|
1167
|
-
return typeof text.text === "string" && typeof text.calcTextWidth === "function" ? text : null;
|
|
1168
|
-
}
|
|
1169
|
-
function textInk(text) {
|
|
1170
|
-
const boxWidth = Math.max(0, text.width ?? 0);
|
|
1171
|
-
const measured = text.calcTextWidth?.() ?? boxWidth;
|
|
1172
|
-
const width = Math.max(1, Math.min(boxWidth, Number.isFinite(measured) ? measured : boxWidth));
|
|
1173
|
-
const slack = (boxWidth - width) / 2;
|
|
1174
|
-
const align = text.textAlign ?? "left";
|
|
1175
|
-
if (align.includes("center")) return { width, dx: 0 };
|
|
1176
|
-
const flip = text.flipX ? -1 : 1;
|
|
1177
|
-
return { width, dx: flip * (align.includes("right") ? slack : -slack) };
|
|
1178
|
-
}
|
|
1179
|
-
function fitTextWidth(object) {
|
|
1180
|
-
const text = asText(object);
|
|
1181
|
-
if (!text || text.path) return false;
|
|
1182
|
-
const before = textInk(text);
|
|
1183
|
-
const fitted = unwrappedWidth(text) + TEXT_FIT_SLACK;
|
|
1184
|
-
if (Math.abs(fitted - text.width) < TEXT_FIT_SLACK) return false;
|
|
1185
|
-
const centre = text.getCenterPoint();
|
|
1186
|
-
text.set({ width: fitted });
|
|
1187
|
-
text.initDimensions?.();
|
|
1188
|
-
const after = textInk(text);
|
|
1189
|
-
const shift = (before.dx - after.dx) * (text.scaleX ?? 1);
|
|
1190
|
-
const radians = (text.angle ?? 0) * Math.PI / 180;
|
|
1191
|
-
const moved = new Point(
|
|
1192
|
-
centre.x + shift * Math.cos(radians),
|
|
1193
|
-
centre.y + shift * Math.sin(radians)
|
|
1194
|
-
);
|
|
1195
|
-
text.setPositionByOrigin(moved, "center", "center");
|
|
1196
|
-
text.setCoords();
|
|
1197
|
-
text.dirty = true;
|
|
1198
|
-
return true;
|
|
1199
|
-
}
|
|
1164
|
+
import { FabricObject, Point } from "fabric";
|
|
1200
1165
|
|
|
1201
1166
|
// src/pattern/tile-geometry.ts
|
|
1202
1167
|
var MAX_TILES_PER_AXIS = 200;
|
|
@@ -1353,7 +1318,7 @@ var TiledPatternObject = class _TiledPatternObject extends FabricObject {
|
|
|
1353
1318
|
const centre = this.getCenterPoint();
|
|
1354
1319
|
const shift = this.shiftVector(tileW, tileH, this.liveAngle());
|
|
1355
1320
|
const ink = this.inkOffset();
|
|
1356
|
-
return new
|
|
1321
|
+
return new Point(centre.x - shift.x - ink.x, centre.y - shift.y - ink.y);
|
|
1357
1322
|
}
|
|
1358
1323
|
_render(ctx) {
|
|
1359
1324
|
const { width, height } = this.area;
|
|
@@ -1485,12 +1450,12 @@ var TiledPatternObject = class _TiledPatternObject extends FabricObject {
|
|
|
1485
1450
|
*/
|
|
1486
1451
|
inkOffset() {
|
|
1487
1452
|
const text = asText(this.source);
|
|
1488
|
-
if (!text) return new
|
|
1453
|
+
if (!text) return new Point(0, 0);
|
|
1489
1454
|
const { dx } = textInk(text);
|
|
1490
|
-
if (!dx) return new
|
|
1455
|
+
if (!dx) return new Point(0, 0);
|
|
1491
1456
|
const scaled = dx * (this.source.scaleX ?? 1);
|
|
1492
1457
|
const radians = (this.source.angle ?? 0) * Math.PI / 180;
|
|
1493
|
-
return new
|
|
1458
|
+
return new Point(scaled * Math.cos(radians), scaled * Math.sin(radians));
|
|
1494
1459
|
}
|
|
1495
1460
|
/** The source's on-canvas width, before the tile scale. */
|
|
1496
1461
|
baseW() {
|
|
@@ -1551,11 +1516,11 @@ var TiledPatternObject = class _TiledPatternObject extends FabricObject {
|
|
|
1551
1516
|
const radians = angle * Math.PI / 180;
|
|
1552
1517
|
const cos = Math.cos(radians);
|
|
1553
1518
|
const sin = Math.sin(radians);
|
|
1554
|
-
return new
|
|
1519
|
+
return new Point(dx * cos - dy * sin, dx * sin + dy * cos);
|
|
1555
1520
|
}
|
|
1556
1521
|
anchorFromOrigin(origin, tileW, tileH, angle) {
|
|
1557
1522
|
const shift = this.shiftVector(tileW, tileH, angle);
|
|
1558
|
-
return new
|
|
1523
|
+
return new Point(origin.x + shift.x, origin.y + shift.y);
|
|
1559
1524
|
}
|
|
1560
1525
|
/**
|
|
1561
1526
|
* Snapshot the source at (at least) `scale`, reusing the cached one while it
|
|
@@ -1969,7 +1934,7 @@ function buildCurvePathData(config, width, fontSize) {
|
|
|
1969
1934
|
}
|
|
1970
1935
|
|
|
1971
1936
|
// src/text-curve.ts
|
|
1972
|
-
var
|
|
1937
|
+
var MEASURE_WIDTH = 1e5;
|
|
1973
1938
|
var PATH_SLACK = 0.06;
|
|
1974
1939
|
var FALLBACK_LINE_HEIGHT = 1.16;
|
|
1975
1940
|
var patches = /* @__PURE__ */ new WeakMap();
|
|
@@ -2017,7 +1982,7 @@ function isCurvable(object) {
|
|
|
2017
1982
|
function measureText(text) {
|
|
2018
1983
|
const authored = text.width;
|
|
2019
1984
|
try {
|
|
2020
|
-
text.set({ width:
|
|
1985
|
+
text.set({ width: MEASURE_WIDTH });
|
|
2021
1986
|
text.initDimensions?.();
|
|
2022
1987
|
return Math.max(1, text.calcTextWidth?.() ?? text.width ?? 1);
|
|
2023
1988
|
} finally {
|
|
@@ -2487,6 +2452,7 @@ var MaskPresetManager = class {
|
|
|
2487
2452
|
object.dirty = true;
|
|
2488
2453
|
object.setCoords();
|
|
2489
2454
|
this.canvas.requestRenderAll();
|
|
2455
|
+
this.events.emit("masks:changed", { target: layerId });
|
|
2490
2456
|
this.events.emit("layer:modified", { layerId });
|
|
2491
2457
|
if (save) this.history.save();
|
|
2492
2458
|
return true;
|
|
@@ -2761,6 +2727,7 @@ async function deserializeEditor(editor, state) {
|
|
|
2761
2727
|
for (const item of staged) {
|
|
2762
2728
|
restoreLayer(editor, item.serialized, item.fabricObject);
|
|
2763
2729
|
}
|
|
2730
|
+
editor.wrap.refreshAll();
|
|
2764
2731
|
editor.canvas.requestRenderAll();
|
|
2765
2732
|
}
|
|
2766
2733
|
function restoreLayer(editor, serialized, fabricObject) {
|
|
@@ -3412,76 +3379,7 @@ function needsAbsoluteSpace(entries) {
|
|
|
3412
3379
|
}
|
|
3413
3380
|
|
|
3414
3381
|
// src/masks/edit.ts
|
|
3415
|
-
import { util as util4 } from "fabric";
|
|
3416
|
-
|
|
3417
|
-
// src/masks/space.ts
|
|
3418
3382
|
import { util as util3 } from "fabric";
|
|
3419
|
-
function matrixOf(object) {
|
|
3420
|
-
return object.calcTransformMatrix();
|
|
3421
|
-
}
|
|
3422
|
-
function applyMatrix(object, matrix) {
|
|
3423
|
-
const decomposed = util3.qrDecompose(matrix);
|
|
3424
|
-
object.set({
|
|
3425
|
-
flipX: false,
|
|
3426
|
-
flipY: false,
|
|
3427
|
-
originX: "center",
|
|
3428
|
-
originY: "center",
|
|
3429
|
-
left: decomposed.translateX,
|
|
3430
|
-
top: decomposed.translateY,
|
|
3431
|
-
scaleX: decomposed.scaleX,
|
|
3432
|
-
scaleY: decomposed.scaleY,
|
|
3433
|
-
angle: decomposed.angle,
|
|
3434
|
-
skewX: decomposed.skewX,
|
|
3435
|
-
skewY: 0
|
|
3436
|
-
});
|
|
3437
|
-
object.setCoords();
|
|
3438
|
-
}
|
|
3439
|
-
function toCanvasSpace(object, host) {
|
|
3440
|
-
applyMatrix(object, util3.multiplyTransformMatrices(matrixOf(host), matrixOf(object)));
|
|
3441
|
-
}
|
|
3442
|
-
function toHostSpace(object, host) {
|
|
3443
|
-
applyMatrix(
|
|
3444
|
-
object,
|
|
3445
|
-
util3.multiplyTransformMatrices(util3.invertTransform(matrixOf(host)), matrixOf(object))
|
|
3446
|
-
);
|
|
3447
|
-
}
|
|
3448
|
-
function relativeMatrix(object, host) {
|
|
3449
|
-
return util3.multiplyTransformMatrices(util3.invertTransform(matrixOf(host)), matrixOf(object));
|
|
3450
|
-
}
|
|
3451
|
-
function applyRelativeMatrix(object, host, rel) {
|
|
3452
|
-
applyMatrix(object, util3.multiplyTransformMatrices(matrixOf(host), rel));
|
|
3453
|
-
}
|
|
3454
|
-
function asObject(clip) {
|
|
3455
|
-
return clip;
|
|
3456
|
-
}
|
|
3457
|
-
function toMatrix(values) {
|
|
3458
|
-
if (!values || values.length !== 6 || values.some((value) => !Number.isFinite(value)))
|
|
3459
|
-
return null;
|
|
3460
|
-
return [values[0], values[1], values[2], values[3], values[4], values[5]];
|
|
3461
|
-
}
|
|
3462
|
-
function fitToBox(object, box, zoom = 1) {
|
|
3463
|
-
const width = Math.max(1, box.width) * zoom;
|
|
3464
|
-
const height = Math.max(1, box.height) * zoom;
|
|
3465
|
-
object.set({
|
|
3466
|
-
originX: "center",
|
|
3467
|
-
originY: "center",
|
|
3468
|
-
angle: 0,
|
|
3469
|
-
skewX: 0,
|
|
3470
|
-
skewY: 0,
|
|
3471
|
-
left: box.left + box.width / 2,
|
|
3472
|
-
top: box.top + box.height / 2,
|
|
3473
|
-
scaleX: width / Math.max(1, object.width ?? 1),
|
|
3474
|
-
scaleY: height / Math.max(1, object.height ?? 1)
|
|
3475
|
-
});
|
|
3476
|
-
object.setCoords();
|
|
3477
|
-
}
|
|
3478
|
-
function unwrapGroup(group) {
|
|
3479
|
-
const children = group.removeAll();
|
|
3480
|
-
for (const child of children) child.setCoords();
|
|
3481
|
-
return children;
|
|
3482
|
-
}
|
|
3483
|
-
|
|
3484
|
-
// src/masks/edit.ts
|
|
3485
3383
|
var MaskEditController = class {
|
|
3486
3384
|
constructor(canvas, onCommit) {
|
|
3487
3385
|
this.canvas = canvas;
|
|
@@ -3562,8 +3460,8 @@ var MaskEditController = class {
|
|
|
3562
3460
|
if (!this.handle || !this.child || !this.group) return;
|
|
3563
3461
|
applyMatrix(
|
|
3564
3462
|
this.child,
|
|
3565
|
-
|
|
3566
|
-
|
|
3463
|
+
util3.multiplyTransformMatrices(
|
|
3464
|
+
util3.invertTransform(matrixOf(this.group)),
|
|
3567
3465
|
matrixOf(this.handle)
|
|
3568
3466
|
)
|
|
3569
3467
|
);
|
|
@@ -3713,6 +3611,24 @@ var MaskStackStore = class {
|
|
|
3713
3611
|
this.pinning = false;
|
|
3714
3612
|
}
|
|
3715
3613
|
}
|
|
3614
|
+
/**
|
|
3615
|
+
* Is the host's own `clipPath` the wrap manager's box clip rather than a mask?
|
|
3616
|
+
*
|
|
3617
|
+
* Adoption rescues a clip whose provenance is UNKNOWN — a mask preset, or a
|
|
3618
|
+
* hand-set `clipPath` from before stacks existed — so the first add() cannot
|
|
3619
|
+
* silently throw it away. A text layer's box clip is the opposite case: its
|
|
3620
|
+
* provenance is known exactly (the wrap manager derives it from
|
|
3621
|
+
* `meta.overflow` on every pass and re-installs it under whatever owns the
|
|
3622
|
+
* property next), and it is not a mask. Adopted, it becomes a stack row the
|
|
3623
|
+
* user never made whose 'add' union covers the whole box — swallowing the mask
|
|
3624
|
+
* they actually added.
|
|
3625
|
+
*
|
|
3626
|
+
* Only meaningful with an empty stack: once there are entries the top-level
|
|
3627
|
+
* clip is the composed group and the box clip is nested underneath it.
|
|
3628
|
+
*/
|
|
3629
|
+
holdsBoxClip(meta) {
|
|
3630
|
+
return meta?.overflow === "hidden" && !meta.maskPreset;
|
|
3631
|
+
}
|
|
3716
3632
|
/**
|
|
3717
3633
|
* Take the current geometry back out of the composed clip, entry-aligned.
|
|
3718
3634
|
*
|
|
@@ -3725,7 +3641,13 @@ var MaskStackStore = class {
|
|
|
3725
3641
|
const clip = host.clipPath;
|
|
3726
3642
|
if (!clip) return [];
|
|
3727
3643
|
const entries = this.list(target);
|
|
3728
|
-
|
|
3644
|
+
const meta = this.hostLayer(target)?.meta;
|
|
3645
|
+
if (entries.length === 0 && this.holdsBoxClip(meta)) return [];
|
|
3646
|
+
if (entries.length === 0 || !(clip instanceof Group5)) {
|
|
3647
|
+
const source = asObject(clip);
|
|
3648
|
+
if (meta?.overflow === "hidden") source.clipPath = void 0;
|
|
3649
|
+
return [source];
|
|
3650
|
+
}
|
|
3729
3651
|
const children = unwrapGroup(clip);
|
|
3730
3652
|
const extra = children.length - entries.length;
|
|
3731
3653
|
return extra > 0 ? children.slice(extra) : children;
|
|
@@ -4056,6 +3978,7 @@ var LayerMaskManager = class extends MaskStackStore {
|
|
|
4056
3978
|
const clip = layer?.fabricObject.clipPath;
|
|
4057
3979
|
if (!layer || !clip || layer.meta.pattern) return null;
|
|
4058
3980
|
if ((layer.meta.maskStack ?? []).length > 0) return null;
|
|
3981
|
+
if (this.holdsBoxClip(layer.meta)) return null;
|
|
4059
3982
|
const entry = {
|
|
4060
3983
|
...DEFAULT_ENTRY,
|
|
4061
3984
|
id: generateId(),
|
|
@@ -4108,6 +4031,7 @@ var CanvasEditor = class {
|
|
|
4108
4031
|
crop;
|
|
4109
4032
|
patterns;
|
|
4110
4033
|
curves;
|
|
4034
|
+
wrap;
|
|
4111
4035
|
maskPresets;
|
|
4112
4036
|
/** Stacked boolean masks, per layer and for the design as a whole. */
|
|
4113
4037
|
layerMasks;
|
|
@@ -4158,6 +4082,7 @@ var CanvasEditor = class {
|
|
|
4158
4082
|
this.crop = new CropController(this.canvas, this.history, this.events);
|
|
4159
4083
|
this.patterns = new PatternManager(this.canvas, this.layers, this.history, this.events);
|
|
4160
4084
|
this.curves = new TextCurveManager(this.canvas, this.layers, this.history, this.events);
|
|
4085
|
+
this.wrap = new TextWrapManager(this.canvas, this.layers, this.history, this.events);
|
|
4161
4086
|
this.maskPresets = new MaskPresetManager(this.canvas, this.layers, this.history, this.events);
|
|
4162
4087
|
this.layerMasks = new LayerMaskManager(this.canvas, this.layers, this.history, this.events);
|
|
4163
4088
|
this.setupCanvasEvents();
|
|
@@ -4914,15 +4839,34 @@ var CanvasEditor = class {
|
|
|
4914
4839
|
}
|
|
4915
4840
|
// ─── Text curve ─────────────────────────────────────
|
|
4916
4841
|
applyTextCurve(layerId, config) {
|
|
4917
|
-
|
|
4842
|
+
const applied = this.curves.apply(layerId, config);
|
|
4843
|
+
if (applied) this.wrap.refresh(layerId);
|
|
4844
|
+
return applied;
|
|
4918
4845
|
}
|
|
4919
4846
|
clearTextCurve(layerId) {
|
|
4920
|
-
|
|
4847
|
+
const cleared = this.curves.clear(layerId);
|
|
4848
|
+
if (cleared) this.wrap.refresh(layerId);
|
|
4849
|
+
return cleared;
|
|
4921
4850
|
}
|
|
4922
4851
|
getTextCurve(layerId) {
|
|
4923
4852
|
return this.curves.get(layerId);
|
|
4924
4853
|
}
|
|
4854
|
+
// ─── Text wrap ──────────────────────────────────────
|
|
4855
|
+
applyTextWrap(layerId, wrap) {
|
|
4856
|
+
return this.wrap.apply(layerId, wrap);
|
|
4857
|
+
}
|
|
4858
|
+
setTextOverflow(layerId, overflow) {
|
|
4859
|
+
return this.wrap.setOverflow(layerId, overflow);
|
|
4860
|
+
}
|
|
4861
|
+
getTextWrap(layerId) {
|
|
4862
|
+
return this.wrap.get(layerId);
|
|
4863
|
+
}
|
|
4925
4864
|
// ─── Mask presets ───────────────────────────────────
|
|
4865
|
+
// A preset assigns `clipPath` wholesale, so a text layer clipping to its box
|
|
4866
|
+
// loses that clip the moment a mask lands on it. Putting it back is NOT wired
|
|
4867
|
+
// here: the preset manager announces `masks:changed` and the wrap manager
|
|
4868
|
+
// re-derives from that, which covers this facade, the manager called directly,
|
|
4869
|
+
// and `refreshAll()` on a restore — all with one mechanism.
|
|
4926
4870
|
applyMaskPreset(layerId, id) {
|
|
4927
4871
|
return this.maskPresets.apply(layerId, id);
|
|
4928
4872
|
}
|
|
@@ -5011,6 +4955,7 @@ var CanvasEditor = class {
|
|
|
5011
4955
|
this.history.dispose();
|
|
5012
4956
|
this.patterns.dispose();
|
|
5013
4957
|
this.curves.dispose();
|
|
4958
|
+
this.wrap.dispose();
|
|
5014
4959
|
this.events.removeAllListeners();
|
|
5015
4960
|
this.canvas.dispose();
|
|
5016
4961
|
}
|
|
@@ -5159,12 +5104,14 @@ export {
|
|
|
5159
5104
|
TEXTURE_MASK_IDS,
|
|
5160
5105
|
TEXTURE_MASK_SIZE,
|
|
5161
5106
|
TextCurveManager,
|
|
5107
|
+
TextWrapManager,
|
|
5162
5108
|
TiledPatternObject,
|
|
5163
5109
|
UnitConverter,
|
|
5164
5110
|
applyAspectLock,
|
|
5165
5111
|
applyLayerShadow,
|
|
5166
5112
|
applyObjectSelectionStyle,
|
|
5167
5113
|
applySelectionStyle,
|
|
5114
|
+
applyTextWrapToObject,
|
|
5168
5115
|
buildCurveLinePaths,
|
|
5169
5116
|
buildCurvePathData,
|
|
5170
5117
|
clamp,
|
|
@@ -5192,7 +5139,9 @@ export {
|
|
|
5192
5139
|
isTextureMaskId,
|
|
5193
5140
|
needsAbsoluteSpace,
|
|
5194
5141
|
normalizeTextCurve,
|
|
5142
|
+
preWrapWordSplit,
|
|
5195
5143
|
readLayerShadow,
|
|
5144
|
+
readTextWrap,
|
|
5196
5145
|
renderTextureMask,
|
|
5197
5146
|
resetTransform,
|
|
5198
5147
|
restoreLocks,
|