@pixerate/editor 0.189.0 → 0.191.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-ED4L4UD6.cjs → chunk-2UR4OX3B.cjs} +1002 -787
- package/dist/{chunk-M7XIC2FC.js → chunk-RQ2EM5TY.js} +333 -0
- package/dist/{chunk-ZEHTUR7Z.js → chunk-TXYXF32N.js} +968 -753
- package/dist/{chunk-5UEFNX24.cjs → chunk-ZQGZWFPU.cjs} +344 -11
- package/dist/image-editor/controller.d.cts +73 -1
- package/dist/image-editor/controller.d.ts +73 -1
- package/dist/image-editor/free-transform.d.cts +3 -6
- package/dist/image-editor/free-transform.d.ts +3 -6
- package/dist/image-editor/index.cjs +1382 -904
- package/dist/image-editor/index.d.cts +1 -0
- package/dist/image-editor/index.d.ts +1 -0
- package/dist/image-editor/index.js +485 -7
- package/dist/image-editor/layer-tools.d.cts +1 -1
- package/dist/image-editor/layer-tools.d.ts +1 -1
- package/dist/image-editor/layers/compositor.d.cts +3 -0
- package/dist/image-editor/layers/compositor.d.ts +3 -0
- package/dist/image-editor/layers/model.d.cts +23 -0
- package/dist/image-editor/layers/model.d.ts +23 -0
- package/dist/image-editor/layers/panel.d.cts +11 -1
- package/dist/image-editor/layers/panel.d.ts +11 -1
- package/dist/image-editor/layers/serialize.d.cts +11 -0
- package/dist/image-editor/layers/serialize.d.ts +11 -0
- package/dist/image-editor/layers/shape.d.cts +5 -0
- package/dist/image-editor/layers/shape.d.ts +5 -0
- package/dist/image-editor/layers/vector-mask.d.cts +51 -0
- package/dist/image-editor/layers/vector-mask.d.ts +51 -0
- package/dist/image-editor/psd/import.d.cts +0 -7
- package/dist/image-editor/psd/import.d.ts +0 -7
- package/dist/image-editor/selection/index.d.cts +1 -0
- package/dist/image-editor/selection/index.d.ts +1 -0
- package/dist/image-editor/selection/path.d.cts +37 -0
- package/dist/image-editor/selection/path.d.ts +37 -0
- package/dist/paint-editor/index.cjs +6 -6
- package/dist/paint-editor/index.js +1 -1
- package/dist/vector/index.cjs +21 -303
- package/dist/vector/index.js +15 -297
- package/dist/vector/trace.d.cts +8 -1
- package/dist/vector/trace.d.ts +8 -1
- package/package.json +1 -1
- package/skills/pixerate-image-editor/SKILL.md +8 -0
- package/skills/pixerate-image-selection-masking/SKILL.md +10 -2
|
@@ -1,4 +1,332 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkNM3G4VQTcjs = require('./chunk-NM3G4VQT.cjs');
|
|
5
|
+
|
|
6
|
+
// src/vector/trace.ts
|
|
7
|
+
var VECTOR_TRACE_MAX_PIXELS = 4e6;
|
|
8
|
+
function signedArea(p) {
|
|
9
|
+
let a = 0;
|
|
10
|
+
for (let i = 0; i < p.length; i++) {
|
|
11
|
+
const [x0, y0] = p[i];
|
|
12
|
+
const [x1, y1] = p[(i + 1) % p.length];
|
|
13
|
+
a += x0 * y1 - x1 * y0;
|
|
14
|
+
}
|
|
15
|
+
return a / 2;
|
|
16
|
+
}
|
|
17
|
+
function pointInPoly(p, poly) {
|
|
18
|
+
let inside = false;
|
|
19
|
+
for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {
|
|
20
|
+
const [xi, yi] = poly[i];
|
|
21
|
+
const [xj, yj] = poly[j];
|
|
22
|
+
if (yi > p[1] !== yj > p[1] && p[0] < (xj - xi) * (p[1] - yi) / (yj - yi) + xi) inside = !inside;
|
|
23
|
+
}
|
|
24
|
+
return inside;
|
|
25
|
+
}
|
|
26
|
+
function vectorTraceContours(field, w, h, threshold) {
|
|
27
|
+
const gw = w + 2;
|
|
28
|
+
const gh = h + 2;
|
|
29
|
+
const val = (i, j) => i === 0 || j === 0 || i > w || j > h ? -Infinity : field[(j - 1) * w + (i - 1)];
|
|
30
|
+
const inside = (i, j) => val(i, j) >= threshold;
|
|
31
|
+
const pos = (i, j) => [i - 0.5, j - 0.5];
|
|
32
|
+
const cross = (a, b) => {
|
|
33
|
+
const va = val(a[0], a[1]);
|
|
34
|
+
const vb = val(b[0], b[1]);
|
|
35
|
+
let t;
|
|
36
|
+
if (Number.isFinite(va) && Number.isFinite(vb) && Math.abs(vb - va) > 1e-12) t = Math.min(1, Math.max(0, (threshold - va) / (vb - va)));
|
|
37
|
+
else if (Number.isFinite(va)) t = va >= threshold ? 0.5 : 0;
|
|
38
|
+
else t = vb >= threshold ? 0.5 : 1;
|
|
39
|
+
const pa = pos(a[0], a[1]);
|
|
40
|
+
const pb = pos(b[0], b[1]);
|
|
41
|
+
return [pa[0] + (pb[0] - pa[0]) * t, pa[1] + (pb[1] - pa[1]) * t];
|
|
42
|
+
};
|
|
43
|
+
const hid = (i, j) => 2 * (j * gw + i);
|
|
44
|
+
const vid = (i, j) => 2 * (j * gw + i) + 1;
|
|
45
|
+
const next = /* @__PURE__ */ new Map();
|
|
46
|
+
const point = /* @__PURE__ */ new Map();
|
|
47
|
+
for (let j = 0; j < gh - 1; j++) {
|
|
48
|
+
for (let i = 0; i < gw - 1; i++) {
|
|
49
|
+
const tl = inside(i, j);
|
|
50
|
+
const tr = inside(i + 1, j);
|
|
51
|
+
const br = inside(i + 1, j + 1);
|
|
52
|
+
const bl = inside(i, j + 1);
|
|
53
|
+
const code = +tl << 3 | +tr << 2 | +br << 1 | +bl;
|
|
54
|
+
if (code === 0 || code === 15) continue;
|
|
55
|
+
const top = hid(i, j);
|
|
56
|
+
const bottom = hid(i, j + 1);
|
|
57
|
+
const left = vid(i, j);
|
|
58
|
+
const right = vid(i + 1, j);
|
|
59
|
+
const seg = (a, b) => next.set(a, b);
|
|
60
|
+
const mean = () => (val(i, j) + val(i + 1, j) + val(i + 1, j + 1) + val(i, j + 1)) / 4;
|
|
61
|
+
switch (code) {
|
|
62
|
+
case 1:
|
|
63
|
+
seg(left, bottom);
|
|
64
|
+
break;
|
|
65
|
+
case 2:
|
|
66
|
+
seg(bottom, right);
|
|
67
|
+
break;
|
|
68
|
+
case 3:
|
|
69
|
+
seg(left, right);
|
|
70
|
+
break;
|
|
71
|
+
case 4:
|
|
72
|
+
seg(right, top);
|
|
73
|
+
break;
|
|
74
|
+
case 5:
|
|
75
|
+
if (mean() >= threshold) {
|
|
76
|
+
seg(left, top);
|
|
77
|
+
seg(right, bottom);
|
|
78
|
+
} else {
|
|
79
|
+
seg(left, bottom);
|
|
80
|
+
seg(right, top);
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
case 6:
|
|
84
|
+
seg(bottom, top);
|
|
85
|
+
break;
|
|
86
|
+
case 7:
|
|
87
|
+
seg(left, top);
|
|
88
|
+
break;
|
|
89
|
+
case 8:
|
|
90
|
+
seg(top, left);
|
|
91
|
+
break;
|
|
92
|
+
case 9:
|
|
93
|
+
seg(top, bottom);
|
|
94
|
+
break;
|
|
95
|
+
case 10:
|
|
96
|
+
if (mean() >= threshold) {
|
|
97
|
+
seg(top, right);
|
|
98
|
+
seg(bottom, left);
|
|
99
|
+
} else {
|
|
100
|
+
seg(top, left);
|
|
101
|
+
seg(bottom, right);
|
|
102
|
+
}
|
|
103
|
+
break;
|
|
104
|
+
case 11:
|
|
105
|
+
seg(top, right);
|
|
106
|
+
break;
|
|
107
|
+
case 12:
|
|
108
|
+
seg(right, left);
|
|
109
|
+
break;
|
|
110
|
+
case 13:
|
|
111
|
+
seg(right, bottom);
|
|
112
|
+
break;
|
|
113
|
+
case 14:
|
|
114
|
+
seg(bottom, left);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
const edges = [
|
|
118
|
+
[top, [i, j], [i + 1, j]],
|
|
119
|
+
[bottom, [i, j + 1], [i + 1, j + 1]],
|
|
120
|
+
[left, [i, j], [i, j + 1]],
|
|
121
|
+
[right, [i + 1, j], [i + 1, j + 1]]
|
|
122
|
+
];
|
|
123
|
+
for (const [e, a, b] of edges) if (inside(a[0], a[1]) !== inside(b[0], b[1]) && !point.has(e)) point.set(e, cross(a, b));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const out = [];
|
|
127
|
+
for (const start of [...next.keys()].sort((a, b) => a - b)) {
|
|
128
|
+
if (!next.has(start)) continue;
|
|
129
|
+
const poly = [];
|
|
130
|
+
let e = start;
|
|
131
|
+
for (; ; ) {
|
|
132
|
+
const n = next.get(e);
|
|
133
|
+
if (n === void 0) break;
|
|
134
|
+
next.delete(e);
|
|
135
|
+
const p = point.get(e);
|
|
136
|
+
if (p) poly.push(p);
|
|
137
|
+
e = n;
|
|
138
|
+
if (e === start) break;
|
|
139
|
+
}
|
|
140
|
+
if (poly.length >= 3) out.push(poly);
|
|
141
|
+
}
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
function squareContourCorners(ring) {
|
|
145
|
+
const n = ring.length;
|
|
146
|
+
if (n < 4) return ring;
|
|
147
|
+
const eq = (u, v) => Math.abs(u - v) < 1e-9;
|
|
148
|
+
const out = [];
|
|
149
|
+
for (let i = 0; i < n; i++) {
|
|
150
|
+
const a = ring[i];
|
|
151
|
+
const b = ring[(i + 1) % n];
|
|
152
|
+
const p = ring[(i - 1 + n) % n];
|
|
153
|
+
const q = ring[(i + 2) % n];
|
|
154
|
+
const diagonal = Math.abs(Math.abs(b[0] - a[0]) - 0.5) < 0.02 && Math.abs(Math.abs(b[1] - a[1]) - 0.5) < 0.02;
|
|
155
|
+
const wraps = i === n - 1;
|
|
156
|
+
let corner = null;
|
|
157
|
+
if (diagonal && (!wraps || out[0] === ring[0])) {
|
|
158
|
+
if (eq(p[1], a[1]) && !eq(p[0], a[0]) && eq(q[0], b[0]) && !eq(q[1], b[1])) corner = [b[0], a[1]];
|
|
159
|
+
else if (eq(p[0], a[0]) && !eq(p[1], a[1]) && eq(q[1], b[1]) && !eq(q[0], b[0])) corner = [a[0], b[1]];
|
|
160
|
+
}
|
|
161
|
+
if (!corner) {
|
|
162
|
+
out.push(a);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
out.push(corner);
|
|
166
|
+
if (wraps) out.shift();
|
|
167
|
+
else i++;
|
|
168
|
+
}
|
|
169
|
+
if (out.length < 3) return ring;
|
|
170
|
+
const m = out.length;
|
|
171
|
+
for (let k = 0; k < m; k++) {
|
|
172
|
+
const p = out[(k - 1 + m) % m];
|
|
173
|
+
const a = out[k];
|
|
174
|
+
const q = out[(k + 1) % m];
|
|
175
|
+
if (Math.abs((a[0] - p[0]) * (q[1] - a[1]) - (a[1] - p[1]) * (q[0] - a[0])) > 1e-6) return k ? [...out.slice(k), ...out.slice(0, k)] : out;
|
|
176
|
+
}
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
function loopsOf(field, w, h, threshold, tolerance, minArea, square = false) {
|
|
180
|
+
const loops = [];
|
|
181
|
+
for (const contour of vectorTraceContours(field, w, h, threshold)) {
|
|
182
|
+
const raw = square ? squareContourCorners(contour) : contour;
|
|
183
|
+
const area = signedArea(raw);
|
|
184
|
+
if (Math.abs(area) < Math.max(0, minArea)) continue;
|
|
185
|
+
const simple = _chunkNM3G4VQTcjs.simplifyRing.call(void 0, raw, Math.max(0.01, tolerance));
|
|
186
|
+
if (simple.length < 3) continue;
|
|
187
|
+
loops.push({ raw, simple, area, depth: 0 });
|
|
188
|
+
}
|
|
189
|
+
for (const l of loops) l.depth = loops.filter((o) => o !== l && Math.abs(o.area) > Math.abs(l.area) && pointInPoly(l.simple[0], o.simple)).length;
|
|
190
|
+
return loops.sort((a, b) => a.depth - b.depth || Math.abs(b.area) - Math.abs(a.area));
|
|
191
|
+
}
|
|
192
|
+
function loopSubpath(l, tolerance, roundness) {
|
|
193
|
+
if (roundness <= 0) return { closed: true, anchors: l.simple.map(([x, y]) => ({ x, y })) };
|
|
194
|
+
const cornerAngleDeg = 25 + roundness * 125;
|
|
195
|
+
const cubics = _chunkNM3G4VQTcjs.fitCubics.call(void 0, l.raw, Math.max(0.05, tolerance), {
|
|
196
|
+
closed: true,
|
|
197
|
+
cornerAngleDeg
|
|
198
|
+
});
|
|
199
|
+
if (!cubics.length) return { closed: true, anchors: l.simple.map(([x, y]) => ({ x, y })) };
|
|
200
|
+
const anchors = cubics.map((c, k) => {
|
|
201
|
+
const prev = cubics[(k - 1 + cubics.length) % cubics.length];
|
|
202
|
+
return {
|
|
203
|
+
x: c.p0[0],
|
|
204
|
+
y: c.p0[1],
|
|
205
|
+
in: { x: prev.p2[0], y: prev.p2[1] },
|
|
206
|
+
out: { x: c.p1[0], y: c.p1[1] }
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
return { closed: true, anchors };
|
|
210
|
+
}
|
|
211
|
+
function traceField(field, w, h, threshold, o) {
|
|
212
|
+
const tolerance = _nullishCoalesce(o.tolerance, () => ( 1));
|
|
213
|
+
const roundness = Math.min(1, Math.max(0, _nullishCoalesce(o.cornerRoundness, () => ( 0.5))));
|
|
214
|
+
return loopsOf(field, w, h, threshold, tolerance, _nullishCoalesce(o.minArea, () => ( 10)), o.squareCorners === true).map((l) => loopSubpath(l, tolerance, roundness));
|
|
215
|
+
}
|
|
216
|
+
function quantizeVectorTraceColors(pixels, count) {
|
|
217
|
+
const n = pixels.width * pixels.height;
|
|
218
|
+
const d = pixels.data;
|
|
219
|
+
const opaque = [];
|
|
220
|
+
for (let i = 0; i < n; i++) if (d[i * 4 + 3] >= 128) opaque.push(i);
|
|
221
|
+
const boxes = opaque.length ? [opaque] : [];
|
|
222
|
+
const range = (box, c) => {
|
|
223
|
+
let lo = 255;
|
|
224
|
+
let hi = 0;
|
|
225
|
+
for (const i of box) {
|
|
226
|
+
const v = d[i * 4 + c];
|
|
227
|
+
if (v < lo) lo = v;
|
|
228
|
+
if (v > hi) hi = v;
|
|
229
|
+
}
|
|
230
|
+
return hi - lo;
|
|
231
|
+
};
|
|
232
|
+
while (boxes.length < count) {
|
|
233
|
+
let best = -1;
|
|
234
|
+
let bestRange = 0;
|
|
235
|
+
let bestC = 0;
|
|
236
|
+
boxes.forEach((b, k) => {
|
|
237
|
+
if (b.length < 2) return;
|
|
238
|
+
for (let c = 0; c < 3; c++) {
|
|
239
|
+
const r = range(b, c);
|
|
240
|
+
if (r > bestRange) {
|
|
241
|
+
bestRange = r;
|
|
242
|
+
best = k;
|
|
243
|
+
bestC = c;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
if (best < 0) break;
|
|
248
|
+
const box = boxes[best].slice().sort((a, b) => d[a * 4 + bestC] - d[b * 4 + bestC]);
|
|
249
|
+
const key = (k) => d[box[k] * 4 + bestC];
|
|
250
|
+
const v = key(box.length >> 1);
|
|
251
|
+
let mid = box.findIndex((_, k) => key(k) >= v);
|
|
252
|
+
if (mid <= 0) mid = box.findIndex((_, k) => key(k) > v);
|
|
253
|
+
boxes.splice(best, 1, box.slice(0, mid), box.slice(mid));
|
|
254
|
+
}
|
|
255
|
+
const palette = boxes.map((b) => {
|
|
256
|
+
const s = [0, 0, 0];
|
|
257
|
+
for (const i of b) for (let c = 0; c < 3; c++) s[c] += d[i * 4 + c];
|
|
258
|
+
return [Math.round(s[0] / b.length), Math.round(s[1] / b.length), Math.round(s[2] / b.length)];
|
|
259
|
+
});
|
|
260
|
+
const index = new Int16Array(n).fill(-1);
|
|
261
|
+
const counts = palette.map(() => 0);
|
|
262
|
+
for (const i of opaque) {
|
|
263
|
+
let best = 0;
|
|
264
|
+
let bestD = Infinity;
|
|
265
|
+
palette.forEach((p, k) => {
|
|
266
|
+
const dd = (d[i * 4] - p[0]) ** 2 + (d[i * 4 + 1] - p[1]) ** 2 + (d[i * 4 + 2] - p[2]) ** 2;
|
|
267
|
+
if (dd < bestD) {
|
|
268
|
+
bestD = dd;
|
|
269
|
+
best = k;
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
index[i] = best;
|
|
273
|
+
counts[best]++;
|
|
274
|
+
}
|
|
275
|
+
return { palette, index, counts };
|
|
276
|
+
}
|
|
277
|
+
var hex = (c) => `#${c.map((v) => Math.round(v).toString(16).padStart(2, "0")).join("")}`;
|
|
278
|
+
function traceVectorImage(pixels, options = {}) {
|
|
279
|
+
const { width: w, height: h, data } = pixels;
|
|
280
|
+
if (!(w > 0 && h > 0) || data.length < w * h * 4) throw new Error("The image has no pixels (or fewer than width \xD7 height \xD7 4 values).");
|
|
281
|
+
if (w * h > VECTOR_TRACE_MAX_PIXELS) throw new Error(`The image has ${w * h} pixels; scale it down to at most ${VECTOR_TRACE_MAX_PIXELS} to trace it.`);
|
|
282
|
+
const n = w * h;
|
|
283
|
+
if ((_nullishCoalesce(options.mode, () => ( "threshold"))) === "threshold") {
|
|
284
|
+
const field = new Float32Array(n);
|
|
285
|
+
const byAlpha = options.channel === "alpha";
|
|
286
|
+
for (let i = 0; i < n; i++) {
|
|
287
|
+
const a = data[i * 4 + 3] / 255;
|
|
288
|
+
field[i] = byAlpha ? a : a * (1 - (0.2126 * data[i * 4] + 0.7152 * data[i * 4 + 1] + 0.0722 * data[i * 4 + 2]) / 255);
|
|
289
|
+
}
|
|
290
|
+
const subpaths = traceField(field, w, h, Math.min(1, Math.max(0, _nullishCoalesce(options.threshold, () => ( 0.5)))), options);
|
|
291
|
+
return subpaths.length ? [
|
|
292
|
+
{
|
|
293
|
+
id: "trace-1",
|
|
294
|
+
type: "path",
|
|
295
|
+
name: "Trace",
|
|
296
|
+
fill: _nullishCoalesce(options.color, () => ( "#000000")),
|
|
297
|
+
stroke: null,
|
|
298
|
+
fillRule: "evenodd",
|
|
299
|
+
subpaths
|
|
300
|
+
}
|
|
301
|
+
] : [];
|
|
302
|
+
}
|
|
303
|
+
const count = Math.min(32, Math.max(2, Math.round(_nullishCoalesce(options.colors, () => ( 6)))));
|
|
304
|
+
const q = quantizeVectorTraceColors(pixels, count);
|
|
305
|
+
const order = q.palette.map((_, k) => k).filter((k) => q.counts[k] > 0).sort((a, b) => q.counts[b] - q.counts[a]);
|
|
306
|
+
const rank = new Map(order.map((k, r) => [k, r]));
|
|
307
|
+
const out = [];
|
|
308
|
+
order.forEach((k, r) => {
|
|
309
|
+
const field = new Uint8Array(n);
|
|
310
|
+
for (let i = 0; i < n; i++) {
|
|
311
|
+
const ix = q.index[i];
|
|
312
|
+
field[i] = ix >= 0 && rank.get(ix) >= r ? 1 : 0;
|
|
313
|
+
}
|
|
314
|
+
const subpaths = traceField(field, w, h, 0.5, options);
|
|
315
|
+
if (subpaths.length)
|
|
316
|
+
out.push({
|
|
317
|
+
id: `trace-${out.length + 1}`,
|
|
318
|
+
type: "path",
|
|
319
|
+
name: hex(q.palette[k]),
|
|
320
|
+
fill: hex(q.palette[k]),
|
|
321
|
+
stroke: null,
|
|
322
|
+
fillRule: "evenodd",
|
|
323
|
+
subpaths
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
return out;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// src/text/opentype.ts
|
|
2
330
|
var fail = (message) => {
|
|
3
331
|
throw new Error(message);
|
|
4
332
|
};
|
|
@@ -310,22 +638,22 @@ function cffOutlines(view, t, numGlyphs) {
|
|
|
310
638
|
const gsubrs = cffIndex(view, strings.end).items;
|
|
311
639
|
if (!tops.items.length) fail("The font's CFF table has no Top DICT.");
|
|
312
640
|
const top = cffDict(view, tops.items[0][0], tops.items[0][1]);
|
|
313
|
-
const charStrings = cffIndex(view, base + (_nullishCoalesce(_optionalChain([top, 'access',
|
|
641
|
+
const charStrings = cffIndex(view, base + (_nullishCoalesce(_optionalChain([top, 'access', _2 => _2.get, 'call', _3 => _3(17), 'optionalAccess', _4 => _4[0]]), () => ( fail("The font's CFF table has no CharStrings."))))).items;
|
|
314
642
|
const privateOf = (dict) => {
|
|
315
643
|
const pv = dict.get(18);
|
|
316
644
|
if (!pv || pv.length < 2) return { subrs: [], defaultWidth: 0, nominalWidth: 0 };
|
|
317
645
|
const [size, off] = pv;
|
|
318
646
|
const priv = cffDict(view, base + off, base + off + size);
|
|
319
|
-
const subrsOff = _optionalChain([priv, 'access',
|
|
647
|
+
const subrsOff = _optionalChain([priv, 'access', _5 => _5.get, 'call', _6 => _6(19), 'optionalAccess', _7 => _7[0]]);
|
|
320
648
|
return {
|
|
321
649
|
subrs: subrsOff !== void 0 ? cffIndex(view, base + off + subrsOff).items : [],
|
|
322
|
-
defaultWidth: _nullishCoalesce(_optionalChain([priv, 'access',
|
|
323
|
-
nominalWidth: _nullishCoalesce(_optionalChain([priv, 'access',
|
|
650
|
+
defaultWidth: _nullishCoalesce(_optionalChain([priv, 'access', _8 => _8.get, 'call', _9 => _9(20), 'optionalAccess', _10 => _10[0]]), () => ( 0)),
|
|
651
|
+
nominalWidth: _nullishCoalesce(_optionalChain([priv, 'access', _11 => _11.get, 'call', _12 => _12(21), 'optionalAccess', _13 => _13[0]]), () => ( 0))
|
|
324
652
|
};
|
|
325
653
|
};
|
|
326
654
|
let fdFor;
|
|
327
|
-
const fdArrayOff = _optionalChain([top, 'access',
|
|
328
|
-
const fdSelectOff = _optionalChain([top, 'access',
|
|
655
|
+
const fdArrayOff = _optionalChain([top, 'access', _14 => _14.get, 'call', _15 => _15(1236), 'optionalAccess', _16 => _16[0]]);
|
|
656
|
+
const fdSelectOff = _optionalChain([top, 'access', _17 => _17.get, 'call', _18 => _18(1237), 'optionalAccess', _19 => _19[0]]);
|
|
329
657
|
if (fdArrayOff !== void 0 && fdSelectOff !== void 0) {
|
|
330
658
|
const fds = cffIndex(view, base + fdArrayOff).items.map(([a, b]) => privateOf(cffDict(view, a, b)));
|
|
331
659
|
const sel = base + fdSelectOff;
|
|
@@ -795,7 +1123,7 @@ function parseOpenTypeFont(data, options = {}) {
|
|
|
795
1123
|
if (g < 0 || g >= numGlyphs) return 0;
|
|
796
1124
|
const i = Math.min(g, numHMetrics - 1);
|
|
797
1125
|
if (i >= 0 && hmtx.offset + i * 4 + 2 <= hmtx.offset + hmtx.length) return view.getUint16(hmtx.offset + i * 4);
|
|
798
|
-
return _nullishCoalesce(_optionalChain([cffWidth, 'optionalCall',
|
|
1126
|
+
return _nullishCoalesce(_optionalChain([cffWidth, 'optionalCall', _20 => _20(g)]), () => ( 0));
|
|
799
1127
|
};
|
|
800
1128
|
const kernPairs = readKern(view, tables.get("kern"));
|
|
801
1129
|
const gpos = gposKerning(view, tables.get("GPOS"));
|
|
@@ -849,11 +1177,11 @@ function parseOpenTypeFont(data, options = {}) {
|
|
|
849
1177
|
kerning,
|
|
850
1178
|
glyphPath,
|
|
851
1179
|
getAdvanceWidth(text, fontSize, opts) {
|
|
852
|
-
return layout(text, _optionalChain([opts, 'optionalAccess',
|
|
1180
|
+
return layout(text, _optionalChain([opts, 'optionalAccess', _21 => _21.kerning]) !== false).width * fontSize / unitsPerEm;
|
|
853
1181
|
},
|
|
854
1182
|
getPath(text, x, y, fontSize, opts) {
|
|
855
1183
|
const k = fontSize / unitsPerEm;
|
|
856
|
-
const { gs, xs } = layout(text, _optionalChain([opts, 'optionalAccess',
|
|
1184
|
+
const { gs, xs } = layout(text, _optionalChain([opts, 'optionalAccess', _22 => _22.kerning]) !== false);
|
|
857
1185
|
const commands = [];
|
|
858
1186
|
gs.forEach((g, i) => {
|
|
859
1187
|
const ox = x + xs[i] * k;
|
|
@@ -925,4 +1253,9 @@ async function unwoff(view) {
|
|
|
925
1253
|
|
|
926
1254
|
|
|
927
1255
|
|
|
928
|
-
|
|
1256
|
+
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
exports.VECTOR_TRACE_MAX_PIXELS = VECTOR_TRACE_MAX_PIXELS; exports.vectorTraceContours = vectorTraceContours; exports.traceField = traceField; exports.quantizeVectorTraceColors = quantizeVectorTraceColors; exports.traceVectorImage = traceVectorImage; exports.parseOpenTypeFont = parseOpenTypeFont; exports.loadOpenTypeFont = loadOpenTypeFont;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AdjustmentKind, AdjustmentLayer, AdjustmentParamsMap, Annotation, CreateAnnotationPayload, AspectRatio, CropBox, DepthMaskOptions, ExportOptions, ImageAdjustments, ImageDimensions, ImageEditorFit, ImageEditorOptions, ImageEditorState, ImageEditorTool, ImageTransform, ImagePoint, SerializedImageEditorState } from './types.cjs';
|
|
2
|
+
import { type PathToSelectionOptions, type SelectionToPathOptions } from './selection/path.cjs';
|
|
2
3
|
import { RenderOptions } from './renderer.cjs';
|
|
3
4
|
import { type BlendMode } from './blend.cjs';
|
|
4
5
|
import type { ImageHistogram } from './histogram.cjs';
|
|
@@ -11,7 +12,7 @@ import { type RefineEdgeParams } from './selection/refine.cjs';
|
|
|
11
12
|
import { type LayerMaskProps } from './selection/layer-mask.cjs';
|
|
12
13
|
import { type AlphaChannel } from './selection/channels.cjs';
|
|
13
14
|
import type { AdjustmentLayerMask } from './types.cjs';
|
|
14
|
-
import { type LayerBlendMode, type ImageLayer, type LayerFilter, type LayerTarget, type PixelLayer, type RasterMask, type SmartContents, type SmartFilter, type SmartPlacement, type LiveShape, type ShapeFillRule, type ShapeOperation, type ShapePaint, type ShapeStroke, type ParagraphStyle, type TextStyle, type TypeLayer, type ImageEffectAnimation } from './layers/model.cjs';
|
|
15
|
+
import { type LayerBlendMode, type ImageLayer, type LayerFilter, type LayerTarget, type PixelLayer, type RasterMask, type SmartContents, type SmartFilter, type SmartPlacement, type LiveShape, type ShapeFillRule, type VectorMask, type ShapeOperation, type ShapePaint, type ShapeStroke, type ParagraphStyle, type TextStyle, type TypeLayer, type ImageEffectAnimation } from './layers/model.cjs';
|
|
15
16
|
import { type TextLayout, type TextShaper } from './layers/text.cjs';
|
|
16
17
|
import type { VectorSubpath } from '../vector/types.cjs';
|
|
17
18
|
import { EffectsSlot } from '../effects/helpers.cjs';
|
|
@@ -209,6 +210,29 @@ export interface CloneSource {
|
|
|
209
210
|
* 'star' | 'line', … }`, see `LiveShape`) or subpaths (`[{ anchors: [{ x, y, in?, out? }],
|
|
210
211
|
* closed }]` or SVG path data), and how it combines with the components below it.
|
|
211
212
|
*/
|
|
213
|
+
/** A vector mask's path: several `components`, or one `shape` / `subpaths` (with `op`). */
|
|
214
|
+
export interface VectorMaskPathInput extends ShapeGeometryInput {
|
|
215
|
+
components?: ShapeGeometryInput[];
|
|
216
|
+
fillRule?: ShapeFillRule;
|
|
217
|
+
}
|
|
218
|
+
/** A vector mask as `getVectorMask` describes it. */
|
|
219
|
+
export interface VectorMaskInfo {
|
|
220
|
+
layerId: string;
|
|
221
|
+
enabled: boolean;
|
|
222
|
+
linked: boolean;
|
|
223
|
+
inverted: boolean;
|
|
224
|
+
fillRule: ShapeFillRule;
|
|
225
|
+
density: number;
|
|
226
|
+
feather: number;
|
|
227
|
+
/** Bounds of the path's anchors and handles (document px), or `null` for an empty path. */
|
|
228
|
+
bounds: CropBox | null;
|
|
229
|
+
components: Array<{
|
|
230
|
+
index: number;
|
|
231
|
+
op: ShapeOperation;
|
|
232
|
+
live: LiveShape | null;
|
|
233
|
+
subpaths: VectorSubpath[];
|
|
234
|
+
}>;
|
|
235
|
+
}
|
|
212
236
|
export interface ShapeGeometryInput {
|
|
213
237
|
shape?: LiveShape | Record<string, unknown>;
|
|
214
238
|
subpaths?: VectorSubpath[] | string;
|
|
@@ -888,6 +912,54 @@ export declare class ImageEditorController {
|
|
|
888
912
|
addLayerMask(id: string, from?: 'reveal-all' | 'hide-all' | 'selection' | 'hide-selection' | 'transparency', props?: LayerMaskProps): RasterMask;
|
|
889
913
|
/** Removes a layer's mask (one undo step). */
|
|
890
914
|
removeLayerMask(id: string): void;
|
|
915
|
+
/** The layer for a vector mask command: not a shape layer (its path is its vector mask), not a depth-masked one. */
|
|
916
|
+
private vectorMaskLayer;
|
|
917
|
+
private requireVectorMask;
|
|
918
|
+
/** Components from a path spec: `components`, or one `shape` / `subpaths`. */
|
|
919
|
+
private vectorMaskComponents;
|
|
920
|
+
/**
|
|
921
|
+
* Layer › Vector Mask: `reveal-all` (an empty path showing everything), `hide-all` (an empty path
|
|
922
|
+
* hiding everything) or `path` (reveals inside the path given). Replaces an existing vector mask;
|
|
923
|
+
* the raster mask is kept and both apply. One undo step. Returns the vector mask.
|
|
924
|
+
*/
|
|
925
|
+
addVectorMask(id: string, from?: 'reveal-all' | 'hide-all' | 'path' | 'selection', path?: VectorMaskPathInput, trace?: SelectionToPathOptions): VectorMask;
|
|
926
|
+
/** The selection's outline as subpaths; throws when nothing is selected or nothing is left to trace. */
|
|
927
|
+
private traceSelection;
|
|
928
|
+
/**
|
|
929
|
+
* Make Work Path: the selection's outline as closed Bézier subpaths in document pixels, holes
|
|
930
|
+
* included (fill them even-odd), within `tolerance` px. Changes nothing. Throws without a selection.
|
|
931
|
+
*/
|
|
932
|
+
selectionToPath(options?: SelectionToPathOptions): {
|
|
933
|
+
subpaths: VectorSubpath[];
|
|
934
|
+
svg: string;
|
|
935
|
+
fillRule: 'evenodd';
|
|
936
|
+
bounds: CropBox | null;
|
|
937
|
+
anchors: number;
|
|
938
|
+
};
|
|
939
|
+
/**
|
|
940
|
+
* Make Selection: fills a path (`shape`, `subpaths` or `components`, document pixels) into a
|
|
941
|
+
* selection combined with the current one by `mode`, with `feather` px and `antiAlias`. One
|
|
942
|
+
* undo step. Returns whether anything is selected.
|
|
943
|
+
*/
|
|
944
|
+
pathToSelection(path: VectorMaskPathInput, options?: PathToSelectionOptions & {
|
|
945
|
+
mode?: SelectionMode;
|
|
946
|
+
}): boolean;
|
|
947
|
+
/** Replaces a vector mask's path (its properties are kept). One undo step. Returns the vector mask. */
|
|
948
|
+
setVectorMaskPath(id: string, path: VectorMaskPathInput): VectorMask;
|
|
949
|
+
/** Changes a vector mask's enabled, linked, inverted, density or feather (the path is kept). One undo step. */
|
|
950
|
+
setVectorMaskProps(id: string, props: Partial<Pick<VectorMask, 'enabled' | 'linked' | 'inverted' | 'density' | 'feather'>>): VectorMask;
|
|
951
|
+
/** Deletes a layer's vector mask (one undo step). */
|
|
952
|
+
removeVectorMask(id: string): void;
|
|
953
|
+
/**
|
|
954
|
+
* Layer › Rasterize › Vector Mask: multiplies the path (with its density and feather) into the
|
|
955
|
+
* layer's raster mask, adding one when there is none, and removes the vector mask. The raster
|
|
956
|
+
* mask keeps its own properties. One undo step. Returns the raster mask.
|
|
957
|
+
*/
|
|
958
|
+
rasterizeVectorMask(id: string): RasterMask;
|
|
959
|
+
/** Load Selection from a vector mask's path (density and feather are not applied), inverted with `invert`. */
|
|
960
|
+
selectionFromVectorMask(id: string, mode?: SelectionMode, invert?: boolean): boolean;
|
|
961
|
+
/** A layer's vector mask with its paths (rounded), or `null` without one. */
|
|
962
|
+
getVectorMask(id: string): VectorMaskInfo | null;
|
|
891
963
|
/** Changes any layer mask's density, feather, enabled or linked flag (pixels kept). Returns the mask. */
|
|
892
964
|
setLayerMaskProps(id: string, props: LayerMaskProps, commitToHistory?: boolean): RasterMask;
|
|
893
965
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AdjustmentKind, AdjustmentLayer, AdjustmentParamsMap, Annotation, CreateAnnotationPayload, AspectRatio, CropBox, DepthMaskOptions, ExportOptions, ImageAdjustments, ImageDimensions, ImageEditorFit, ImageEditorOptions, ImageEditorState, ImageEditorTool, ImageTransform, ImagePoint, SerializedImageEditorState } from './types.js';
|
|
2
|
+
import { type PathToSelectionOptions, type SelectionToPathOptions } from './selection/path.js';
|
|
2
3
|
import { RenderOptions } from './renderer.js';
|
|
3
4
|
import { type BlendMode } from './blend.js';
|
|
4
5
|
import type { ImageHistogram } from './histogram.js';
|
|
@@ -11,7 +12,7 @@ import { type RefineEdgeParams } from './selection/refine.js';
|
|
|
11
12
|
import { type LayerMaskProps } from './selection/layer-mask.js';
|
|
12
13
|
import { type AlphaChannel } from './selection/channels.js';
|
|
13
14
|
import type { AdjustmentLayerMask } from './types.js';
|
|
14
|
-
import { type LayerBlendMode, type ImageLayer, type LayerFilter, type LayerTarget, type PixelLayer, type RasterMask, type SmartContents, type SmartFilter, type SmartPlacement, type LiveShape, type ShapeFillRule, type ShapeOperation, type ShapePaint, type ShapeStroke, type ParagraphStyle, type TextStyle, type TypeLayer, type ImageEffectAnimation } from './layers/model.js';
|
|
15
|
+
import { type LayerBlendMode, type ImageLayer, type LayerFilter, type LayerTarget, type PixelLayer, type RasterMask, type SmartContents, type SmartFilter, type SmartPlacement, type LiveShape, type ShapeFillRule, type VectorMask, type ShapeOperation, type ShapePaint, type ShapeStroke, type ParagraphStyle, type TextStyle, type TypeLayer, type ImageEffectAnimation } from './layers/model.js';
|
|
15
16
|
import { type TextLayout, type TextShaper } from './layers/text.js';
|
|
16
17
|
import type { VectorSubpath } from '../vector/types.js';
|
|
17
18
|
import { EffectsSlot } from '../effects/helpers.js';
|
|
@@ -209,6 +210,29 @@ export interface CloneSource {
|
|
|
209
210
|
* 'star' | 'line', … }`, see `LiveShape`) or subpaths (`[{ anchors: [{ x, y, in?, out? }],
|
|
210
211
|
* closed }]` or SVG path data), and how it combines with the components below it.
|
|
211
212
|
*/
|
|
213
|
+
/** A vector mask's path: several `components`, or one `shape` / `subpaths` (with `op`). */
|
|
214
|
+
export interface VectorMaskPathInput extends ShapeGeometryInput {
|
|
215
|
+
components?: ShapeGeometryInput[];
|
|
216
|
+
fillRule?: ShapeFillRule;
|
|
217
|
+
}
|
|
218
|
+
/** A vector mask as `getVectorMask` describes it. */
|
|
219
|
+
export interface VectorMaskInfo {
|
|
220
|
+
layerId: string;
|
|
221
|
+
enabled: boolean;
|
|
222
|
+
linked: boolean;
|
|
223
|
+
inverted: boolean;
|
|
224
|
+
fillRule: ShapeFillRule;
|
|
225
|
+
density: number;
|
|
226
|
+
feather: number;
|
|
227
|
+
/** Bounds of the path's anchors and handles (document px), or `null` for an empty path. */
|
|
228
|
+
bounds: CropBox | null;
|
|
229
|
+
components: Array<{
|
|
230
|
+
index: number;
|
|
231
|
+
op: ShapeOperation;
|
|
232
|
+
live: LiveShape | null;
|
|
233
|
+
subpaths: VectorSubpath[];
|
|
234
|
+
}>;
|
|
235
|
+
}
|
|
212
236
|
export interface ShapeGeometryInput {
|
|
213
237
|
shape?: LiveShape | Record<string, unknown>;
|
|
214
238
|
subpaths?: VectorSubpath[] | string;
|
|
@@ -888,6 +912,54 @@ export declare class ImageEditorController {
|
|
|
888
912
|
addLayerMask(id: string, from?: 'reveal-all' | 'hide-all' | 'selection' | 'hide-selection' | 'transparency', props?: LayerMaskProps): RasterMask;
|
|
889
913
|
/** Removes a layer's mask (one undo step). */
|
|
890
914
|
removeLayerMask(id: string): void;
|
|
915
|
+
/** The layer for a vector mask command: not a shape layer (its path is its vector mask), not a depth-masked one. */
|
|
916
|
+
private vectorMaskLayer;
|
|
917
|
+
private requireVectorMask;
|
|
918
|
+
/** Components from a path spec: `components`, or one `shape` / `subpaths`. */
|
|
919
|
+
private vectorMaskComponents;
|
|
920
|
+
/**
|
|
921
|
+
* Layer › Vector Mask: `reveal-all` (an empty path showing everything), `hide-all` (an empty path
|
|
922
|
+
* hiding everything) or `path` (reveals inside the path given). Replaces an existing vector mask;
|
|
923
|
+
* the raster mask is kept and both apply. One undo step. Returns the vector mask.
|
|
924
|
+
*/
|
|
925
|
+
addVectorMask(id: string, from?: 'reveal-all' | 'hide-all' | 'path' | 'selection', path?: VectorMaskPathInput, trace?: SelectionToPathOptions): VectorMask;
|
|
926
|
+
/** The selection's outline as subpaths; throws when nothing is selected or nothing is left to trace. */
|
|
927
|
+
private traceSelection;
|
|
928
|
+
/**
|
|
929
|
+
* Make Work Path: the selection's outline as closed Bézier subpaths in document pixels, holes
|
|
930
|
+
* included (fill them even-odd), within `tolerance` px. Changes nothing. Throws without a selection.
|
|
931
|
+
*/
|
|
932
|
+
selectionToPath(options?: SelectionToPathOptions): {
|
|
933
|
+
subpaths: VectorSubpath[];
|
|
934
|
+
svg: string;
|
|
935
|
+
fillRule: 'evenodd';
|
|
936
|
+
bounds: CropBox | null;
|
|
937
|
+
anchors: number;
|
|
938
|
+
};
|
|
939
|
+
/**
|
|
940
|
+
* Make Selection: fills a path (`shape`, `subpaths` or `components`, document pixels) into a
|
|
941
|
+
* selection combined with the current one by `mode`, with `feather` px and `antiAlias`. One
|
|
942
|
+
* undo step. Returns whether anything is selected.
|
|
943
|
+
*/
|
|
944
|
+
pathToSelection(path: VectorMaskPathInput, options?: PathToSelectionOptions & {
|
|
945
|
+
mode?: SelectionMode;
|
|
946
|
+
}): boolean;
|
|
947
|
+
/** Replaces a vector mask's path (its properties are kept). One undo step. Returns the vector mask. */
|
|
948
|
+
setVectorMaskPath(id: string, path: VectorMaskPathInput): VectorMask;
|
|
949
|
+
/** Changes a vector mask's enabled, linked, inverted, density or feather (the path is kept). One undo step. */
|
|
950
|
+
setVectorMaskProps(id: string, props: Partial<Pick<VectorMask, 'enabled' | 'linked' | 'inverted' | 'density' | 'feather'>>): VectorMask;
|
|
951
|
+
/** Deletes a layer's vector mask (one undo step). */
|
|
952
|
+
removeVectorMask(id: string): void;
|
|
953
|
+
/**
|
|
954
|
+
* Layer › Rasterize › Vector Mask: multiplies the path (with its density and feather) into the
|
|
955
|
+
* layer's raster mask, adding one when there is none, and removes the vector mask. The raster
|
|
956
|
+
* mask keeps its own properties. One undo step. Returns the raster mask.
|
|
957
|
+
*/
|
|
958
|
+
rasterizeVectorMask(id: string): RasterMask;
|
|
959
|
+
/** Load Selection from a vector mask's path (density and feather are not applied), inverted with `invert`. */
|
|
960
|
+
selectionFromVectorMask(id: string, mode?: SelectionMode, invert?: boolean): boolean;
|
|
961
|
+
/** A layer's vector mask with its paths (rounded), or `null` without one. */
|
|
962
|
+
getVectorMask(id: string): VectorMaskInfo | null;
|
|
891
963
|
/** Changes any layer mask's density, feather, enabled or linked flag (pixels kept). Returns the mask. */
|
|
892
964
|
setLayerMaskProps(id: string, props: LayerMaskProps, commitToHistory?: boolean): RasterMask;
|
|
893
965
|
/**
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Free Transform sessions: what a transform moves (a layer's pixels with its linked mask, a lone
|
|
3
|
-
* unlinked mask, the selected pixels as a floating piece, a copy of them on a new layer, or just
|
|
4
|
-
* the selection outline), a live preview while the geometry changes, and one undo step when it is
|
|
5
|
-
* committed with full-quality resampling.
|
|
6
|
-
*/
|
|
7
1
|
import { TiledSurface } from '../raster/surface.cjs';
|
|
8
2
|
import { type Interpolation } from '../raster/transform.cjs';
|
|
9
3
|
import { type ImageLayer, type LayerTarget, type PixelLayer, type SmartObjectLayer } from './layers/model.cjs';
|
|
@@ -147,6 +141,9 @@ export declare class FreeTransformSession {
|
|
|
147
141
|
}, preview?: FreeTransformPreview | false): FreeTransformGeometry;
|
|
148
142
|
/** Resamples every part for the current geometry and shows it (or returns it, for commit). */
|
|
149
143
|
private resample;
|
|
144
|
+
/** A linked vector mask follows the layer's content through the same document-space map. */
|
|
145
|
+
private moveVectorMask;
|
|
146
|
+
private resampleContent;
|
|
150
147
|
/**
|
|
151
148
|
* A shape with its paths mapped through the current geometry and rendered again (live shapes
|
|
152
149
|
* stay live under an affine map; perspective and warps turn them into plain paths). Previews
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Free Transform sessions: what a transform moves (a layer's pixels with its linked mask, a lone
|
|
3
|
-
* unlinked mask, the selected pixels as a floating piece, a copy of them on a new layer, or just
|
|
4
|
-
* the selection outline), a live preview while the geometry changes, and one undo step when it is
|
|
5
|
-
* committed with full-quality resampling.
|
|
6
|
-
*/
|
|
7
1
|
import { TiledSurface } from '../raster/surface.js';
|
|
8
2
|
import { type Interpolation } from '../raster/transform.js';
|
|
9
3
|
import { type ImageLayer, type LayerTarget, type PixelLayer, type SmartObjectLayer } from './layers/model.js';
|
|
@@ -147,6 +141,9 @@ export declare class FreeTransformSession {
|
|
|
147
141
|
}, preview?: FreeTransformPreview | false): FreeTransformGeometry;
|
|
148
142
|
/** Resamples every part for the current geometry and shows it (or returns it, for commit). */
|
|
149
143
|
private resample;
|
|
144
|
+
/** A linked vector mask follows the layer's content through the same document-space map. */
|
|
145
|
+
private moveVectorMask;
|
|
146
|
+
private resampleContent;
|
|
150
147
|
/**
|
|
151
148
|
* A shape with its paths mapped through the current geometry and rendered again (live shapes
|
|
152
149
|
* stay live under an affine map; perspective and warps turn them into plain paths). Previews
|