@pixerate/editor 0.266.1 → 0.267.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/agent/index.cjs +8 -4
- package/dist/agent/index.js +6 -2
- package/dist/animation-editor/controller.d.cts +8 -0
- package/dist/animation-editor/controller.d.ts +8 -0
- package/dist/animation-editor/effect-tools.d.cts +1 -1
- package/dist/animation-editor/effect-tools.d.ts +1 -1
- package/dist/animation-editor/index.cjs +172 -105
- package/dist/animation-editor/index.js +91 -24
- package/dist/brushes/index.cjs +59 -59
- package/dist/brushes/index.js +5 -5
- package/dist/brushes/profiles.d.cts +6 -1
- package/dist/brushes/profiles.d.ts +6 -1
- package/dist/{brushstrokeRender-FSUWXUZY.cjs → brushstrokeRender-L7JYRR2R.cjs} +16 -16
- package/dist/{brushstrokeRender-KD453OBX.js → brushstrokeRender-NLFPEBGI.js} +4 -4
- package/dist/canvas/brushTypes.d.cts +12 -0
- package/dist/canvas/brushTypes.d.ts +12 -0
- package/dist/canvas/brushstroke.d.cts +1 -1
- package/dist/canvas/brushstroke.d.ts +1 -1
- package/dist/canvas/drawController.d.cts +19 -4
- package/dist/canvas/drawController.d.ts +19 -4
- package/dist/canvas/index.cjs +144 -105
- package/dist/canvas/index.js +46 -7
- package/dist/{chunk-XORJ7UZO.cjs → chunk-3VHH6V67.cjs} +13 -12
- package/dist/{chunk-T2LDTEXK.js → chunk-4IDUYB45.js} +2217 -56
- package/dist/chunk-7UKFXXWL.js +802 -0
- package/dist/chunk-ADMRNWR7.js +340 -0
- package/dist/{chunk-CIJBSUM5.js → chunk-AGNUD5BI.js} +2 -2
- package/dist/{chunk-WLUVZKVD.cjs → chunk-DT4YQUGT.cjs} +32 -32
- package/dist/{chunk-DXYHQ2VN.js → chunk-EF7LZAXQ.js} +1 -1
- package/dist/chunk-EXB2EGBE.cjs +802 -0
- package/dist/{chunk-4ODRXQRW.js → chunk-EYSHTYLG.js} +1 -1
- package/dist/{chunk-R44Y3EFS.js → chunk-FGJHJIMN.js} +8 -336
- package/dist/{chunk-AQZQWXEU.cjs → chunk-G7NHE2VD.cjs} +35 -35
- package/dist/{chunk-XC6DPRYI.js → chunk-GSTSZPSR.js} +154 -949
- package/dist/{chunk-VRK322ZC.cjs → chunk-HIO6E7LC.cjs} +2 -2
- package/dist/{chunk-TOID45I2.cjs → chunk-J2TNIZ55.cjs} +1 -1
- package/dist/{chunk-YHDHFJUC.cjs → chunk-J5VQYK7T.cjs} +217 -1012
- package/dist/{chunk-3C33YTNN.js → chunk-JGWVZPT6.js} +2 -2
- package/dist/{chunk-ACFSFUQH.js → chunk-JL6YH5WD.js} +4 -0
- package/dist/{chunk-3SBLVGOM.cjs → chunk-LA5Y4ETA.cjs} +23 -23
- package/dist/{chunk-MVUQSK5J.cjs → chunk-LHPEG5AU.cjs} +107 -435
- package/dist/{chunk-DOZ6F2K2.js → chunk-NSETJI74.js} +3 -2
- package/dist/{chunk-XRXFVRGY.cjs → chunk-OKHKA43L.cjs} +2364 -203
- package/dist/{chunk-LK4SXL3V.js → chunk-OSEXT7JL.js} +1 -1
- package/dist/{chunk-PE6YJMQT.cjs → chunk-PFHJS4HE.cjs} +20 -19
- package/dist/{chunk-ZQI3WUPP.js → chunk-QCLY5SFS.js} +12 -0
- package/dist/{chunk-7KNW3WXZ.cjs → chunk-QEVLRLUN.cjs} +63 -0
- package/dist/{chunk-OTN6VB5S.cjs → chunk-RDFHWAHL.cjs} +5 -1
- package/dist/{chunk-6JL2D5SG.js → chunk-VE6UKYQ2.js} +3 -2
- package/dist/{chunk-RFJZGTHA.cjs → chunk-XVOP3CGQ.cjs} +9 -9
- package/dist/{chunk-EZOJBP4D.js → chunk-YIC6MAJ2.js} +1 -1
- package/dist/chunk-YZWM6ZIP.cjs +340 -0
- package/dist/{chunk-472INMWH.js → chunk-ZA7L5YJB.js} +63 -0
- package/dist/{chunk-YBC3RKT2.cjs → chunk-ZGXJ7BTR.cjs} +13 -1
- package/dist/commands/builtins.d.cts +12 -1
- package/dist/commands/builtins.d.ts +12 -1
- package/dist/commands/index.cjs +2 -2
- package/dist/commands/index.js +1 -1
- package/dist/image-editor/controller.d.cts +1 -1
- package/dist/image-editor/controller.d.ts +1 -1
- package/dist/image-editor/index.cjs +837 -833
- package/dist/image-editor/index.js +105 -101
- package/dist/paint/index.cjs +5 -3
- package/dist/paint/index.js +46 -44
- package/dist/paint-editor/controller.d.cts +5 -3
- package/dist/paint-editor/controller.d.ts +5 -3
- package/dist/paint-editor/index.cjs +832 -2295
- package/dist/paint-editor/index.js +285 -1748
- package/dist/paint-editor/path-samples.d.cts +2 -0
- package/dist/paint-editor/path-samples.d.ts +2 -0
- package/dist/paint-editor/presence.d.cts +20 -1
- package/dist/paint-editor/presence.d.ts +20 -1
- package/dist/stickers/helpers.d.cts +2 -0
- package/dist/stickers/helpers.d.ts +2 -0
- package/dist/stickers/index.cjs +41 -35
- package/dist/stickers/index.js +22 -16
- package/dist/stickers/types.d.cts +4 -2
- package/dist/stickers/types.d.ts +4 -2
- package/dist/tools/conformance.d.cts +8 -0
- package/dist/tools/conformance.d.ts +8 -0
- package/dist/tools/index.cjs +6 -2
- package/dist/tools/index.js +5 -1
- package/dist/vector/backdrop.d.cts +13 -0
- package/dist/vector/backdrop.d.ts +13 -0
- package/dist/vector/brushstroke.d.cts +54 -7
- package/dist/vector/brushstroke.d.ts +54 -7
- package/dist/vector/brushstrokeMedia.d.cts +96 -0
- package/dist/vector/brushstrokeMedia.d.ts +96 -0
- package/dist/vector/controller.d.cts +17 -3
- package/dist/vector/controller.d.ts +17 -3
- package/dist/vector/index.cjs +1846 -1386
- package/dist/vector/index.d.cts +2 -0
- package/dist/vector/index.d.ts +2 -0
- package/dist/vector/index.js +517 -57
- package/dist/vector/render.d.cts +6 -0
- package/dist/vector/render.d.ts +6 -0
- package/dist/vector/types.d.cts +14 -0
- package/dist/vector/types.d.ts +14 -0
- package/package.json +1 -1
- package/skills/pixerate-animation-editor/SKILL.md +1 -0
- package/skills/pixerate-brushes/SKILL.md +2 -2
- package/skills/pixerate-brushes-design/SKILL.md +7 -4
- package/skills/pixerate-brushes-design/evals/port-to-vector.json +8 -8
- package/skills/pixerate-canvas/SKILL.md +11 -1
- package/skills/pixerate-image-editor/SKILL.md +19 -64
- package/skills/pixerate-image-editor/references/color-management.md +2 -1
- package/skills/pixerate-image-editor/references/free-transform.md +12 -0
- package/skills/pixerate-image-editor/references/layer-effects.md +10 -0
- package/skills/pixerate-image-editor/references/painting.md +17 -0
- package/skills/pixerate-image-editor/references/photoshop-files.md +1 -1
- package/skills/pixerate-image-editor/references/shapes-and-type.md +14 -0
- package/skills/pixerate-image-editor/references/smart-objects.md +10 -0
- package/skills/pixerate-paint-editor/SKILL.md +8 -4
- package/skills/pixerate-paint-editor/references/wet-media.md +9 -0
- package/skills/pixerate-vector/SKILL.md +16 -6
- package/skills/pixerate-vector/references/best-practices.md +1 -0
- package/skills/pixerate-vector/references/commands.md +19 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/image-editor/layers/vector-raster.ts
|
|
2
|
+
var FLATNESS = 0.01;
|
|
3
|
+
function flattenPath(path, tolerance = FLATNESS) {
|
|
4
|
+
const out = [];
|
|
5
|
+
let pts = [];
|
|
6
|
+
let cx = 0;
|
|
7
|
+
let cy = 0;
|
|
8
|
+
let sx = 0;
|
|
9
|
+
let sy = 0;
|
|
10
|
+
const flush = () => {
|
|
11
|
+
if (pts.length >= 6) out.push(Float64Array.from(pts));
|
|
12
|
+
pts = [];
|
|
13
|
+
};
|
|
14
|
+
const steps = (dd, degree) => Math.max(1, Math.min(1024, Math.ceil(Math.sqrt(degree * (degree - 1) * dd / (8 * tolerance)))));
|
|
15
|
+
for (const c of path) {
|
|
16
|
+
switch (c.type) {
|
|
17
|
+
case "M":
|
|
18
|
+
flush();
|
|
19
|
+
cx = sx = c.x;
|
|
20
|
+
cy = sy = c.y;
|
|
21
|
+
pts.push(cx, cy);
|
|
22
|
+
break;
|
|
23
|
+
case "L":
|
|
24
|
+
if (!pts.length) pts.push(cx, cy);
|
|
25
|
+
cx = c.x;
|
|
26
|
+
cy = c.y;
|
|
27
|
+
pts.push(cx, cy);
|
|
28
|
+
break;
|
|
29
|
+
case "Q": {
|
|
30
|
+
if (!pts.length) pts.push(cx, cy);
|
|
31
|
+
const n = steps(Math.hypot(cx - 2 * c.x1 + c.x, cy - 2 * c.y1 + c.y), 2);
|
|
32
|
+
for (let k = 1; k <= n; k++) {
|
|
33
|
+
const t = k / n;
|
|
34
|
+
const u = 1 - t;
|
|
35
|
+
pts.push(u * u * cx + 2 * u * t * c.x1 + t * t * c.x, u * u * cy + 2 * u * t * c.y1 + t * t * c.y);
|
|
36
|
+
}
|
|
37
|
+
cx = c.x;
|
|
38
|
+
cy = c.y;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case "C": {
|
|
42
|
+
if (!pts.length) pts.push(cx, cy);
|
|
43
|
+
const dd = Math.max(Math.hypot(cx - 2 * c.x1 + c.x2, cy - 2 * c.y1 + c.y2), Math.hypot(c.x1 - 2 * c.x2 + c.x, c.y1 - 2 * c.y2 + c.y));
|
|
44
|
+
const n = steps(dd, 3);
|
|
45
|
+
for (let k = 1; k <= n; k++) {
|
|
46
|
+
const t = k / n;
|
|
47
|
+
const u = 1 - t;
|
|
48
|
+
const a = u * u * u;
|
|
49
|
+
const b = 3 * u * u * t;
|
|
50
|
+
const d = 3 * u * t * t;
|
|
51
|
+
const e = t * t * t;
|
|
52
|
+
pts.push(a * cx + b * c.x1 + d * c.x2 + e * c.x, a * cy + b * c.y1 + d * c.y2 + e * c.y);
|
|
53
|
+
}
|
|
54
|
+
cx = c.x;
|
|
55
|
+
cy = c.y;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
case "Z":
|
|
59
|
+
flush();
|
|
60
|
+
cx = sx;
|
|
61
|
+
cy = sy;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
flush();
|
|
66
|
+
return out.filter((p) => p.every(Number.isFinite));
|
|
67
|
+
}
|
|
68
|
+
function flatBounds(flat) {
|
|
69
|
+
let x0 = Infinity;
|
|
70
|
+
let y0 = Infinity;
|
|
71
|
+
let x1 = -Infinity;
|
|
72
|
+
let y1 = -Infinity;
|
|
73
|
+
for (const p of flat) {
|
|
74
|
+
for (let i = 0; i < p.length; i += 2) {
|
|
75
|
+
if (p[i] < x0) x0 = p[i];
|
|
76
|
+
if (p[i] > x1) x1 = p[i];
|
|
77
|
+
if (p[i + 1] < y0) y0 = p[i + 1];
|
|
78
|
+
if (p[i + 1] > y1) y1 = p[i + 1];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (x0 === Infinity) return null;
|
|
82
|
+
const x = Math.floor(x0);
|
|
83
|
+
const y = Math.floor(y0);
|
|
84
|
+
return { x, y, width: Math.ceil(x1) - x, height: Math.ceil(y1) - y };
|
|
85
|
+
}
|
|
86
|
+
function drawLine(a, w, h, x0, y0, x1, y1) {
|
|
87
|
+
if (y0 === y1) return;
|
|
88
|
+
let dir = 1;
|
|
89
|
+
if (y0 > y1) {
|
|
90
|
+
dir = -1;
|
|
91
|
+
let t = x0;
|
|
92
|
+
x0 = x1;
|
|
93
|
+
x1 = t;
|
|
94
|
+
t = y0;
|
|
95
|
+
y0 = y1;
|
|
96
|
+
y1 = t;
|
|
97
|
+
}
|
|
98
|
+
if (y1 <= 0 || y0 >= h) return;
|
|
99
|
+
const dxdy = (x1 - x0) / (y1 - y0);
|
|
100
|
+
let x = x0;
|
|
101
|
+
if (y0 < 0) x -= y0 * dxdy;
|
|
102
|
+
const rowStart = Math.max(0, Math.floor(y0));
|
|
103
|
+
const rowEnd = Math.min(h, Math.ceil(y1));
|
|
104
|
+
for (let y = rowStart; y < rowEnd; y++) {
|
|
105
|
+
const line = y * w;
|
|
106
|
+
const dy = Math.min(y + 1, y1) - Math.max(y, y0);
|
|
107
|
+
const xnext = x + dxdy * dy;
|
|
108
|
+
const d = dy * dir;
|
|
109
|
+
const xa = x < xnext ? x : xnext;
|
|
110
|
+
const xb = x < xnext ? xnext : x;
|
|
111
|
+
const xaFloor = Math.floor(xa);
|
|
112
|
+
const xai = xaFloor;
|
|
113
|
+
const xbCeil = Math.ceil(xb);
|
|
114
|
+
const xbi = xbCeil;
|
|
115
|
+
if (xbi <= xai + 1) {
|
|
116
|
+
const xmf = 0.5 * (x + xnext) - xaFloor;
|
|
117
|
+
a[line + xai] += d - d * xmf;
|
|
118
|
+
a[line + xai + 1] += d * xmf;
|
|
119
|
+
} else {
|
|
120
|
+
const s = 1 / (xb - xa);
|
|
121
|
+
const xaf = xa - xaFloor;
|
|
122
|
+
const a0 = 0.5 * s * (1 - xaf) * (1 - xaf);
|
|
123
|
+
const xbf = xb - xbCeil + 1;
|
|
124
|
+
const am = 0.5 * s * xbf * xbf;
|
|
125
|
+
a[line + xai] += d * a0;
|
|
126
|
+
if (xbi === xai + 2) a[line + xai + 1] += d * (1 - a0 - am);
|
|
127
|
+
else {
|
|
128
|
+
const a1 = s * (1.5 - xaf);
|
|
129
|
+
a[line + xai + 1] += d * (a1 - a0);
|
|
130
|
+
for (let xi = xai + 2; xi < xbi - 1; xi++) a[line + xi] += d * s;
|
|
131
|
+
const a2 = a1 + (xbi - xai - 3) * s;
|
|
132
|
+
a[line + xbi - 1] += d * (1 - a2 - am);
|
|
133
|
+
}
|
|
134
|
+
a[line + xbi] += d * am;
|
|
135
|
+
}
|
|
136
|
+
x = xnext;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function drawClippedLine(a, w, h, x0, y0, x1, y1) {
|
|
140
|
+
if (y0 === y1) return;
|
|
141
|
+
if (y0 <= 0 && y1 <= 0 || y0 >= h && y1 >= h) return;
|
|
142
|
+
if (x0 >= 0 && x0 <= w && x1 >= 0 && x1 <= w) return drawLine(a, w, h, x0, y0, x1, y1);
|
|
143
|
+
const ts = [0, 1];
|
|
144
|
+
const dx = x1 - x0;
|
|
145
|
+
if (dx !== 0) {
|
|
146
|
+
for (const edge of [0, w]) {
|
|
147
|
+
const t = (edge - x0) / dx;
|
|
148
|
+
if (t > 0 && t < 1) ts.push(t);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
ts.sort((p, q) => p - q);
|
|
152
|
+
const clamp = (v) => v < 0 ? 0 : v > w ? w : v;
|
|
153
|
+
for (let i = 0; i + 1 < ts.length; i++) {
|
|
154
|
+
const ta = ts[i];
|
|
155
|
+
const tb = ts[i + 1];
|
|
156
|
+
drawLine(a, w, h, clamp(x0 + dx * ta), y0 + (y1 - y0) * ta, clamp(x0 + dx * tb), y0 + (y1 - y0) * tb);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function ruleCoverage(v, rule) {
|
|
160
|
+
const m = v < 0 ? -v : v;
|
|
161
|
+
if (rule === "nonzero") return m >= 1 ? 1 : m;
|
|
162
|
+
const f = m % 2;
|
|
163
|
+
return f > 1 ? 2 - f : f;
|
|
164
|
+
}
|
|
165
|
+
function rasterizeCoverage(flat, rect, rule = "nonzero") {
|
|
166
|
+
const w = rect.width;
|
|
167
|
+
const h = rect.height;
|
|
168
|
+
if (w <= 0 || h <= 0 || !flat.length) return null;
|
|
169
|
+
const a = new Float64Array(w * h + w + 4);
|
|
170
|
+
const ox = rect.x;
|
|
171
|
+
const oy = rect.y;
|
|
172
|
+
let touched = false;
|
|
173
|
+
for (const p of flat) {
|
|
174
|
+
const n = p.length;
|
|
175
|
+
for (let i = 0; i < n; i += 2) {
|
|
176
|
+
const j = i + 2 < n ? i + 2 : 0;
|
|
177
|
+
const ya = p[i + 1] - oy;
|
|
178
|
+
const yb = p[j + 1] - oy;
|
|
179
|
+
if (ya <= 0 && yb <= 0 || ya >= h && yb >= h || ya === yb) continue;
|
|
180
|
+
drawClippedLine(a, w, h, p[i] - ox, ya, p[j] - ox, yb);
|
|
181
|
+
touched = true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (!touched) return null;
|
|
185
|
+
const out = new Float32Array(w * h);
|
|
186
|
+
let acc = 0;
|
|
187
|
+
let any = false;
|
|
188
|
+
for (let i = 0; i < out.length; i++) {
|
|
189
|
+
acc += a[i];
|
|
190
|
+
const c = ruleCoverage(acc, rule);
|
|
191
|
+
if (c > 1e-6) {
|
|
192
|
+
out[i] = c;
|
|
193
|
+
any = true;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return any ? out : null;
|
|
197
|
+
}
|
|
198
|
+
var SUB_ROWS = 16;
|
|
199
|
+
function rasterizeCoverageSampled(flat, rect, rule = "nonzero") {
|
|
200
|
+
const w = rect.width;
|
|
201
|
+
const h = rect.height;
|
|
202
|
+
if (w <= 0 || h <= 0 || !flat.length) return null;
|
|
203
|
+
let n = 0;
|
|
204
|
+
for (const p of flat) n += p.length >> 1;
|
|
205
|
+
const ey0 = new Float64Array(n);
|
|
206
|
+
const ey1 = new Float64Array(n);
|
|
207
|
+
const ex0 = new Float64Array(n);
|
|
208
|
+
const eslope = new Float64Array(n);
|
|
209
|
+
const edir = new Int8Array(n);
|
|
210
|
+
let count = 0;
|
|
211
|
+
for (const p of flat) {
|
|
212
|
+
const len = p.length;
|
|
213
|
+
for (let i = 0; i < len; i += 2) {
|
|
214
|
+
const j = i + 2 < len ? i + 2 : 0;
|
|
215
|
+
let xa = p[i] - rect.x;
|
|
216
|
+
let ya = p[i + 1] - rect.y;
|
|
217
|
+
let xb = p[j] - rect.x;
|
|
218
|
+
let yb = p[j + 1] - rect.y;
|
|
219
|
+
if (ya === yb) continue;
|
|
220
|
+
let dir = 1;
|
|
221
|
+
if (ya > yb) {
|
|
222
|
+
dir = -1;
|
|
223
|
+
let t = xa;
|
|
224
|
+
xa = xb;
|
|
225
|
+
xb = t;
|
|
226
|
+
t = ya;
|
|
227
|
+
ya = yb;
|
|
228
|
+
yb = t;
|
|
229
|
+
}
|
|
230
|
+
if (yb <= 0 || ya >= h) continue;
|
|
231
|
+
ey0[count] = ya;
|
|
232
|
+
ey1[count] = yb;
|
|
233
|
+
ex0[count] = xa;
|
|
234
|
+
eslope[count] = (xb - xa) / (yb - ya);
|
|
235
|
+
edir[count] = dir;
|
|
236
|
+
count++;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (!count) return null;
|
|
240
|
+
const order = Array.from({ length: count }, (_, i) => i).sort((a, b) => ey0[a] - ey0[b]);
|
|
241
|
+
const out = new Float32Array(w * h);
|
|
242
|
+
const diff = new Float32Array(w + 1);
|
|
243
|
+
let active = [];
|
|
244
|
+
let next = 0;
|
|
245
|
+
const xs = [];
|
|
246
|
+
const ds = [];
|
|
247
|
+
const idx = [];
|
|
248
|
+
const f = 1 / SUB_ROWS;
|
|
249
|
+
let any = false;
|
|
250
|
+
const firstRow = Math.max(0, Math.floor(ey0[order[0]]));
|
|
251
|
+
for (let y = firstRow; y < h; y++) {
|
|
252
|
+
if (next >= count && !active.length) break;
|
|
253
|
+
const row = y * w;
|
|
254
|
+
let rowTouched = false;
|
|
255
|
+
for (let s = 0; s < SUB_ROWS; s++) {
|
|
256
|
+
const sy = y + (s + 0.5) * f;
|
|
257
|
+
while (next < count && ey0[order[next]] <= sy) active.push(order[next++]);
|
|
258
|
+
if (!active.length) continue;
|
|
259
|
+
active = active.filter((e) => ey1[e] > sy);
|
|
260
|
+
xs.length = 0;
|
|
261
|
+
ds.length = 0;
|
|
262
|
+
idx.length = 0;
|
|
263
|
+
for (const e of active) {
|
|
264
|
+
if (ey0[e] > sy) continue;
|
|
265
|
+
idx.push(xs.length);
|
|
266
|
+
xs.push(ex0[e] + (sy - ey0[e]) * eslope[e]);
|
|
267
|
+
ds.push(edir[e]);
|
|
268
|
+
}
|
|
269
|
+
if (xs.length < 2) continue;
|
|
270
|
+
idx.sort((a, b) => xs[a] - xs[b]);
|
|
271
|
+
let wind = 0;
|
|
272
|
+
for (let k = 0; k + 1 < idx.length; k++) {
|
|
273
|
+
wind += ds[idx[k]];
|
|
274
|
+
const inside = rule === "nonzero" ? wind !== 0 : (wind & 1) !== 0;
|
|
275
|
+
if (!inside) continue;
|
|
276
|
+
let xa = xs[idx[k]];
|
|
277
|
+
let xb = xs[idx[k + 1]];
|
|
278
|
+
if (xb <= 0 || xa >= w || xb <= xa) continue;
|
|
279
|
+
if (xa < 0) xa = 0;
|
|
280
|
+
if (xb > w) xb = w;
|
|
281
|
+
const ia = Math.floor(xa);
|
|
282
|
+
const ib = Math.floor(xb);
|
|
283
|
+
rowTouched = true;
|
|
284
|
+
if (ia === ib) {
|
|
285
|
+
out[row + ia] += (xb - xa) * f;
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
out[row + ia] += (ia + 1 - xa) * f;
|
|
289
|
+
diff[ia + 1] += f;
|
|
290
|
+
diff[ib] -= f;
|
|
291
|
+
if (ib < w) out[row + ib] += (xb - ib) * f;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (!rowTouched) continue;
|
|
295
|
+
let run = 0;
|
|
296
|
+
for (let x = 0; x < w; x++) {
|
|
297
|
+
run += diff[x];
|
|
298
|
+
diff[x] = 0;
|
|
299
|
+
const v = out[row + x] + run;
|
|
300
|
+
out[row + x] = v > 1 ? 1 : v < 1e-6 ? 0 : v;
|
|
301
|
+
if (out[row + x] > 0) any = true;
|
|
302
|
+
}
|
|
303
|
+
diff[w] = 0;
|
|
304
|
+
}
|
|
305
|
+
return any ? out : null;
|
|
306
|
+
}
|
|
307
|
+
function combineCoverage(a, b, op, n) {
|
|
308
|
+
if (op === "combine") {
|
|
309
|
+
if (!a) return b;
|
|
310
|
+
if (!b) return a;
|
|
311
|
+
const out2 = new Float32Array(n);
|
|
312
|
+
for (let i = 0; i < n; i++) out2[i] = a[i] + b[i] - a[i] * b[i];
|
|
313
|
+
return out2;
|
|
314
|
+
}
|
|
315
|
+
if (op === "subtract") {
|
|
316
|
+
if (!a || !b) return a;
|
|
317
|
+
const out2 = new Float32Array(n);
|
|
318
|
+
for (let i = 0; i < n; i++) out2[i] = a[i] * (1 - b[i]);
|
|
319
|
+
return out2;
|
|
320
|
+
}
|
|
321
|
+
if (op === "intersect") {
|
|
322
|
+
if (!a || !b) return null;
|
|
323
|
+
const out2 = new Float32Array(n);
|
|
324
|
+
for (let i = 0; i < n; i++) out2[i] = a[i] * b[i];
|
|
325
|
+
return out2;
|
|
326
|
+
}
|
|
327
|
+
if (!a) return b;
|
|
328
|
+
if (!b) return a;
|
|
329
|
+
const out = new Float32Array(n);
|
|
330
|
+
for (let i = 0; i < n; i++) out[i] = a[i] + b[i] - 2 * a[i] * b[i];
|
|
331
|
+
return out;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
exports.flattenPath = flattenPath; exports.flatBounds = flatBounds; exports.rasterizeCoverage = rasterizeCoverage; exports.rasterizeCoverageSampled = rasterizeCoverageSampled; exports.combineCoverage = combineCoverage;
|
|
@@ -382,9 +382,72 @@ function createDrawCommands(target, options = {}) {
|
|
|
382
382
|
readOnly: true,
|
|
383
383
|
run: async () => ({ brushes: await target.listBrushes() })
|
|
384
384
|
},
|
|
385
|
+
...createBrushChoiceCommands(target, base, prefix),
|
|
385
386
|
...createGestureCommands(target, base, prefix, options)
|
|
386
387
|
];
|
|
387
388
|
}
|
|
389
|
+
function createBrushChoiceCommands(target, base, prefix) {
|
|
390
|
+
const { brushSettings, selectBrush, setColorLocked, setColorScheme } = target;
|
|
391
|
+
if (!brushSettings || !selectBrush || !setColorLocked || !setColorScheme) return [];
|
|
392
|
+
const settings = () => brushSettings();
|
|
393
|
+
const RESULT = "Returns { brush, color, colorScheme, colorLocked, colorFollowsScheme } (colorFollowsScheme: the colour is a brush's light / dark default and changes with the scheme).";
|
|
394
|
+
return [
|
|
395
|
+
{
|
|
396
|
+
...base,
|
|
397
|
+
id: `${prefix}selectBrush`,
|
|
398
|
+
label: "Choose Pen Brush",
|
|
399
|
+
keywords: ["brush", "pen", "pick brush", "chalk", "pencil", "ink"],
|
|
400
|
+
description: `Chooses the brush the pen and highlighter draw with by hand (brushId from canvas.listBrushes, or null for a plain vector stroke), at the brush's own size. A brush with a default colour (the ballpoint's blue, the chalk's light / dark pair) makes it the stroke colour unless keepColour or the colour is locked (canvas.setColorLocked). Does not draw; canvas.drawFreehand takes its own brush. ${RESULT}`,
|
|
401
|
+
params: {
|
|
402
|
+
type: "object",
|
|
403
|
+
additionalProperties: false,
|
|
404
|
+
required: ["brushId"],
|
|
405
|
+
properties: {
|
|
406
|
+
brushId: { type: ["string", "null"], minLength: 1, description: "A brush id from canvas.listBrushes, or null for a plain vector stroke." },
|
|
407
|
+
keepColour: { type: "boolean", description: "Keep the current stroke colour this once instead of taking the brush's default colour (default false)." }
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
run: async (_ctx, params) => {
|
|
411
|
+
await selectBrush(params.brushId, params.keepColour ? { keepColour: true } : {});
|
|
412
|
+
return settings();
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
...base,
|
|
417
|
+
id: `${prefix}setColorLocked`,
|
|
418
|
+
label: "Keep My Colour",
|
|
419
|
+
keywords: ["lock colour", "keep colour", "brush colour", "color lock"],
|
|
420
|
+
description: `Locks or unlocks the stroke colour ("Keep my colour"): while locked, canvas.selectBrush keeps the current colour instead of taking a brush's default colour. ${RESULT}`,
|
|
421
|
+
params: {
|
|
422
|
+
type: "object",
|
|
423
|
+
additionalProperties: false,
|
|
424
|
+
required: ["locked"],
|
|
425
|
+
properties: { locked: { type: "boolean", description: "true locks the colour, false unlocks it (the canvas starts unlocked)." } }
|
|
426
|
+
},
|
|
427
|
+
run: (_ctx, params) => {
|
|
428
|
+
setColorLocked(params.locked);
|
|
429
|
+
return settings();
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
...base,
|
|
434
|
+
id: `${prefix}setColorScheme`,
|
|
435
|
+
label: "Brush Colours for Light / Dark",
|
|
436
|
+
keywords: ["colour scheme", "dark mode", "light mode", "theme", "brush colour"],
|
|
437
|
+
description: `Sets the colour scheme that picks the side of a brush's light / dark default colour (white chalk in dark, dark chalk in light). A stroke colour that came from such a default follows; strokes already drawn keep theirs, and canvas.drawFreehand resolves brush defaults for this scheme. The host usually sets it to match its theme. ${RESULT}`,
|
|
438
|
+
params: {
|
|
439
|
+
type: "object",
|
|
440
|
+
additionalProperties: false,
|
|
441
|
+
required: ["scheme"],
|
|
442
|
+
properties: { scheme: { type: "string", enum: ["light", "dark"], description: "light (dark chalk on a light background) or dark (light chalk on a dark one)." } }
|
|
443
|
+
},
|
|
444
|
+
run: (_ctx, params) => {
|
|
445
|
+
setColorScheme(params.scheme);
|
|
446
|
+
return settings();
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
];
|
|
450
|
+
}
|
|
388
451
|
var GESTURE_RECT_PARAM = {
|
|
389
452
|
type: "object",
|
|
390
453
|
additionalProperties: false,
|
|
@@ -727,6 +727,16 @@ function resultText(result) {
|
|
|
727
727
|
}
|
|
728
728
|
return void 0;
|
|
729
729
|
}
|
|
730
|
+
var CONFORMANCE_NUMBER_TOLERANCE = 1e-9;
|
|
731
|
+
function conformanceValuesMatch(a, b) {
|
|
732
|
+
if (typeof a === "number" && typeof b === "number") return a === b || Math.abs(a - b) <= CONFORMANCE_NUMBER_TOLERANCE * Math.max(1, Math.abs(a), Math.abs(b));
|
|
733
|
+
if (Array.isArray(a) || Array.isArray(b)) return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((x, i) => conformanceValuesMatch(x, b[i]));
|
|
734
|
+
if (a && b && typeof a === "object" && typeof b === "object") {
|
|
735
|
+
const ka = Object.keys(a), kb = Object.keys(b);
|
|
736
|
+
return ka.length === kb.length && ka.every((k) => k in b && conformanceValuesMatch(a[k], b[k]));
|
|
737
|
+
}
|
|
738
|
+
return a === b;
|
|
739
|
+
}
|
|
730
740
|
async function runConformanceScenario(scenario, host) {
|
|
731
741
|
const ids = new ConformanceIds();
|
|
732
742
|
const isId = _optionalChain([host, 'access', _41 => _41.isGeneratedId, 'optionalAccess', _42 => _42.bind, 'call', _43 => _43(host)]);
|
|
@@ -773,4 +783,6 @@ async function runConformanceScenario(scenario, host) {
|
|
|
773
783
|
|
|
774
784
|
|
|
775
785
|
|
|
776
|
-
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
exports.listSkillEvals = listSkillEvals; exports.imageEvalFixturePixels = imageEvalFixturePixels; exports.callEvalTool = callEvalTool; exports.matchesEvalExpectation = matchesEvalExpectation; exports.failedEvalChecks = failedEvalChecks; exports.toolResultValue = toolResultValue; exports.toolResultError = toolResultError; exports.runToolScript = runToolScript; exports.parseStyleDomains = parseStyleDomains; exports.memoryStyleStore = memoryStyleStore; exports.createStyleResolver = createStyleResolver; exports.runStyleChecks = runStyleChecks; exports.renderStyle = renderStyle; exports.createStyleToolProvider = createStyleToolProvider; exports.createOriginMiddleware = createOriginMiddleware; exports.ConformanceIds = ConformanceIds; exports.CONFORMANCE_BINARY_MIN_LENGTH = CONFORMANCE_BINARY_MIN_LENGTH; exports.normalizeConformanceValue = normalizeConformanceValue; exports.omitConformancePaths = omitConformancePaths; exports.resolveConformanceArguments = resolveConformanceArguments; exports.conformanceResult = conformanceResult; exports.CONFORMANCE_NUMBER_TOLERANCE = CONFORMANCE_NUMBER_TOLERANCE; exports.conformanceValuesMatch = conformanceValuesMatch; exports.runConformanceScenario = runConformanceScenario;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HistoryState } from '../history/types.cjs';
|
|
2
2
|
import type { CanvasArrangeAction } from '../canvas/arrangeShortcuts.cjs';
|
|
3
3
|
import type { AlignEdge, DistributeAxis, DistributeMode, ZOrderOperation } from '../canvas/arrange.cjs';
|
|
4
|
-
import type { CanvasBrush, CanvasBrushPaint, CanvasBrushPreset } from '../canvas/brushTypes.cjs';
|
|
4
|
+
import type { CanvasBrush, CanvasBrushPaint, CanvasBrushPreset, CanvasBrushChoice } from '../canvas/brushTypes.cjs';
|
|
5
5
|
import type { CommandSpec } from './registry.cjs';
|
|
6
6
|
import type { PlaybackStep } from '../tools/playback.cjs';
|
|
7
7
|
import { type ShortcutBinding } from './shortcuts.cjs';
|
|
@@ -133,6 +133,17 @@ export interface DrawCommandTarget {
|
|
|
133
133
|
width: number;
|
|
134
134
|
height: number;
|
|
135
135
|
} | undefined;
|
|
136
|
+
/**
|
|
137
|
+
* The brush picker's state, for `canvas.selectBrush`, `canvas.setColorLocked` and
|
|
138
|
+
* `canvas.setColorScheme` (registered only when the target has all of these; the draw
|
|
139
|
+
* controller does).
|
|
140
|
+
*/
|
|
141
|
+
brushSettings?(): CanvasBrushChoice;
|
|
142
|
+
selectBrush?(id: string | null, choice?: {
|
|
143
|
+
keepColour?: boolean;
|
|
144
|
+
}): Promise<CanvasBrushPreset | null>;
|
|
145
|
+
setColorLocked?(locked: boolean): void;
|
|
146
|
+
setColorScheme?(scheme: 'light' | 'dark'): void;
|
|
136
147
|
}
|
|
137
148
|
export interface DrawCommandOptions {
|
|
138
149
|
/** Id prefix (default `canvas.`). */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HistoryState } from '../history/types.js';
|
|
2
2
|
import type { CanvasArrangeAction } from '../canvas/arrangeShortcuts.js';
|
|
3
3
|
import type { AlignEdge, DistributeAxis, DistributeMode, ZOrderOperation } from '../canvas/arrange.js';
|
|
4
|
-
import type { CanvasBrush, CanvasBrushPaint, CanvasBrushPreset } from '../canvas/brushTypes.js';
|
|
4
|
+
import type { CanvasBrush, CanvasBrushPaint, CanvasBrushPreset, CanvasBrushChoice } from '../canvas/brushTypes.js';
|
|
5
5
|
import type { CommandSpec } from './registry.js';
|
|
6
6
|
import type { PlaybackStep } from '../tools/playback.js';
|
|
7
7
|
import { type ShortcutBinding } from './shortcuts.js';
|
|
@@ -133,6 +133,17 @@ export interface DrawCommandTarget {
|
|
|
133
133
|
width: number;
|
|
134
134
|
height: number;
|
|
135
135
|
} | undefined;
|
|
136
|
+
/**
|
|
137
|
+
* The brush picker's state, for `canvas.selectBrush`, `canvas.setColorLocked` and
|
|
138
|
+
* `canvas.setColorScheme` (registered only when the target has all of these; the draw
|
|
139
|
+
* controller does).
|
|
140
|
+
*/
|
|
141
|
+
brushSettings?(): CanvasBrushChoice;
|
|
142
|
+
selectBrush?(id: string | null, choice?: {
|
|
143
|
+
keepColour?: boolean;
|
|
144
|
+
}): Promise<CanvasBrushPreset | null>;
|
|
145
|
+
setColorLocked?(locked: boolean): void;
|
|
146
|
+
setColorScheme?(scheme: 'light' | 'dark'): void;
|
|
136
147
|
}
|
|
137
148
|
export interface DrawCommandOptions {
|
|
138
149
|
/** Id prefix (default `canvas.`). */
|
package/dist/commands/index.cjs
CHANGED
|
@@ -22,7 +22,7 @@ var _chunkKIJIONZFcjs = require('../chunk-KIJIONZF.cjs');
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
var
|
|
25
|
+
var _chunkQEVLRLUNcjs = require('../chunk-QEVLRLUN.cjs');
|
|
26
26
|
require('../chunk-E2Z4UARJ.cjs');
|
|
27
27
|
|
|
28
28
|
|
|
@@ -413,4 +413,4 @@ function createCanvasAnimationCommands(controller, options = {}) {
|
|
|
413
413
|
|
|
414
414
|
|
|
415
415
|
|
|
416
|
-
exports.CommandRegistry = _chunkKIJIONZFcjs.CommandRegistry; exports.CommandRegistryError = _chunkKIJIONZFcjs.CommandRegistryError; exports.DEFAULT_HISTORY_SHORTCUTS =
|
|
416
|
+
exports.CommandRegistry = _chunkKIJIONZFcjs.CommandRegistry; exports.CommandRegistryError = _chunkKIJIONZFcjs.CommandRegistryError; exports.DEFAULT_HISTORY_SHORTCUTS = _chunkQEVLRLUNcjs.DEFAULT_HISTORY_SHORTCUTS; exports.DEFAULT_RECENT_LIMIT = _chunkKIJIONZFcjs.DEFAULT_RECENT_LIMIT; exports.PLATFORMS = _chunkQJVOJUTDcjs.PLATFORMS; exports.ShortcutMap = _chunkQJVOJUTDcjs.ShortcutMap; exports.chordToString = _chunkQJVOJUTDcjs.chordToString; exports.codeFromKey = _chunkQJVOJUTDcjs.codeFromKey; exports.codeToKeyText = _chunkQJVOJUTDcjs.codeToKeyText; exports.createArrangeCommands = _chunkQEVLRLUNcjs.createArrangeCommands; exports.createCanvasAnimationCommands = createCanvasAnimationCommands; exports.createCommandPaletteController = createCommandPaletteController; exports.createCommandRegistry = _chunkKIJIONZFcjs.createCommandRegistry; exports.createCommandToolProvider = _chunkKIJIONZFcjs.createCommandToolProvider; exports.createComponentCommands = _chunkQEVLRLUNcjs.createComponentCommands; exports.createDrawCommands = _chunkQEVLRLUNcjs.createDrawCommands; exports.createFormatCommands = _chunkVCL7CB56cjs.createFormatCommands; exports.createHistoryCommands = _chunkQEVLRLUNcjs.createHistoryCommands; exports.createShapeCommands = _chunkQEVLRLUNcjs.createShapeCommands; exports.createSpreadsheetCommands = _chunkQEVLRLUNcjs.createSpreadsheetCommands; exports.defineCommand = _chunkKIJIONZFcjs.defineCommand; exports.detectPlatform = _chunkQJVOJUTDcjs.detectPlatform; exports.effectiveChord = _chunkQJVOJUTDcjs.effectiveChord; exports.effectiveChordKey = _chunkQJVOJUTDcjs.effectiveChordKey; exports.eventCode = _chunkQJVOJUTDcjs.eventCode; exports.exactBonus = _chunkKIJIONZFcjs.exactBonus; exports.formatCommandsFor = _chunkVCL7CB56cjs.formatCommandsFor; exports.formatShortcut = _chunkQJVOJUTDcjs.formatShortcut; exports.fuzzyMatch = _chunkKIJIONZFcjs.fuzzyMatch; exports.fuzzyScore = _chunkKIJIONZFcjs.fuzzyScore; exports.hasVariantCommands = _chunkQEVLRLUNcjs.hasVariantCommands; exports.isEditableEventTarget = _chunkQJVOJUTDcjs.isEditableEventTarget; exports.keyToCode = _chunkQJVOJUTDcjs.keyToCode; exports.matchHistoryShortcut = _chunkQEVLRLUNcjs.matchHistoryShortcut; exports.matchPaletteHotkey = matchPaletteHotkey; exports.normalizeChord = _chunkQJVOJUTDcjs.normalizeChord; exports.parseChord = _chunkQJVOJUTDcjs.parseChord; exports.planFreehandPlayback = _chunkQEVLRLUNcjs.planFreehandPlayback; exports.pushRecent = _chunkKIJIONZFcjs.pushRecent; exports.rankCommands = _chunkKIJIONZFcjs.rankCommands; exports.shortcutCode = _chunkQJVOJUTDcjs.shortcutCode; exports.toShortcutBindings = _chunkQJVOJUTDcjs.toShortcutBindings;
|
package/dist/commands/index.js
CHANGED
|
@@ -2583,7 +2583,7 @@ export declare class ImageEditorController {
|
|
|
2583
2583
|
*/
|
|
2584
2584
|
private checkPsdFonts;
|
|
2585
2585
|
/**
|
|
2586
|
-
* The document as
|
|
2586
|
+
* The document as a PSD in its colour mode (RGB, CMYK or Lab) at its bit depth (PSB above 30 000 px) with real layers, groups, adjustment
|
|
2587
2587
|
* layers and masks, in the source frame. Layer filters and parametric (depth) masks are baked
|
|
2588
2588
|
* into pixels and masks, annotation layers are rasterized (in a browser; elsewhere they are left
|
|
2589
2589
|
* out), and the merged image is our composite. `warnings` lists every such change.
|
|
@@ -2583,7 +2583,7 @@ export declare class ImageEditorController {
|
|
|
2583
2583
|
*/
|
|
2584
2584
|
private checkPsdFonts;
|
|
2585
2585
|
/**
|
|
2586
|
-
* The document as
|
|
2586
|
+
* The document as a PSD in its colour mode (RGB, CMYK or Lab) at its bit depth (PSB above 30 000 px) with real layers, groups, adjustment
|
|
2587
2587
|
* layers and masks, in the source frame. Layer filters and parametric (depth) masks are baked
|
|
2588
2588
|
* into pixels and masks, annotation layers are rasterized (in a browser; elsewhere they are left
|
|
2589
2589
|
* out), and the merged image is our composite. `warnings` lists every such change.
|