@pixerate/editor 0.96.0 → 0.97.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-T422YCHR.cjs → chunk-4AB5BHYK.cjs} +237 -63
- package/dist/chunk-4AB5BHYK.cjs.map +1 -0
- package/dist/{chunk-KFTQ2PKP.js → chunk-OEVSVA6V.js} +214 -40
- package/dist/chunk-OEVSVA6V.js.map +1 -0
- package/dist/image-editor/index.cjs +413 -235
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +75 -1
- package/dist/image-editor/index.d.ts +75 -1
- package/dist/image-editor/index.js +254 -76
- package/dist/image-editor/index.js.map +1 -1
- package/dist/raster/index.cjs +4 -2
- package/dist/raster/index.cjs.map +1 -1
- package/dist/raster/index.d.cts +46 -3
- package/dist/raster/index.d.ts +46 -3
- package/dist/raster/index.js +3 -1
- package/package.json +1 -1
- package/dist/chunk-KFTQ2PKP.js.map +0 -1
- package/dist/chunk-T422YCHR.cjs.map +0 -1
|
@@ -1080,11 +1080,18 @@ function boxLine(src, x0, dst, bw) {
|
|
|
1080
1080
|
}
|
|
1081
1081
|
}
|
|
1082
1082
|
var BLUR_EPS = 1e-7;
|
|
1083
|
+
var BLUR_FIX = 2 ** 32;
|
|
1083
1084
|
function tentLine(src, dst, bw, mid) {
|
|
1084
1085
|
const [r] = boxGeom(bw);
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1086
|
+
const m = mid.subarray(0, src.length + 2 * r);
|
|
1087
|
+
for (let i = 0; i < src.length; i++) src[i] = Math.round(src[i] * BLUR_FIX);
|
|
1088
|
+
boxLine(src, -r, m, bw);
|
|
1089
|
+
for (let i = 0; i < m.length; i++) m[i] = Math.round(m[i]);
|
|
1090
|
+
boxLine(m, r, dst, bw);
|
|
1091
|
+
for (let i = 0; i < dst.length; i++) {
|
|
1092
|
+
const v = dst[i] / BLUR_FIX;
|
|
1093
|
+
dst[i] = Math.abs(v) < BLUR_EPS ? 0 : v;
|
|
1094
|
+
}
|
|
1088
1095
|
}
|
|
1089
1096
|
function tent(m, w) {
|
|
1090
1097
|
if (!Number.isFinite(w) || m.v.length === 0) return;
|
|
@@ -1386,25 +1393,41 @@ function effectsAreLocal(items) {
|
|
|
1386
1393
|
}
|
|
1387
1394
|
});
|
|
1388
1395
|
}
|
|
1396
|
+
function shapeBounds(shape, rect) {
|
|
1397
|
+
const { width: w, height: h } = rect;
|
|
1398
|
+
const rowHit = (y) => {
|
|
1399
|
+
for (let x = 0, i = y * w; x < w; x++, i++) if (shape[i] > INSIDE_EPS) return true;
|
|
1400
|
+
return false;
|
|
1401
|
+
};
|
|
1402
|
+
let y0 = 0;
|
|
1403
|
+
while (y0 < h && !rowHit(y0)) y0++;
|
|
1404
|
+
if (y0 === h) return null;
|
|
1405
|
+
let y1 = h - 1;
|
|
1406
|
+
while (!rowHit(y1)) y1--;
|
|
1407
|
+
let x0 = w;
|
|
1408
|
+
let x1 = -1;
|
|
1409
|
+
for (let y = y0; y <= y1; y++) {
|
|
1410
|
+
const o = y * w;
|
|
1411
|
+
for (let x = 0; x < x0; x++) {
|
|
1412
|
+
if (shape[o + x] > INSIDE_EPS) {
|
|
1413
|
+
x0 = x;
|
|
1414
|
+
break;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
for (let x = w - 1; x > x1; x--) {
|
|
1418
|
+
if (shape[o + x] > INSIDE_EPS) {
|
|
1419
|
+
x1 = x;
|
|
1420
|
+
break;
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
return { x: rect.x + x0, y: rect.y + y0, width: x1 - x0 + 1, height: y1 - y0 + 1 };
|
|
1425
|
+
}
|
|
1389
1426
|
function buildEffectMaps(items, shape, rect, ctx) {
|
|
1390
1427
|
const w = rect.width;
|
|
1391
1428
|
const h = rect.height;
|
|
1392
1429
|
const s = { w, h, v: shape };
|
|
1393
|
-
|
|
1394
|
-
let y0 = Infinity;
|
|
1395
|
-
let x1 = -Infinity;
|
|
1396
|
-
let y1 = -Infinity;
|
|
1397
|
-
for (let y = 0; y < h; y++) {
|
|
1398
|
-
for (let x = 0; x < w; x++) {
|
|
1399
|
-
if (shape[y * w + x] > INSIDE_EPS) {
|
|
1400
|
-
if (x < x0) x0 = x;
|
|
1401
|
-
if (x > x1) x1 = x;
|
|
1402
|
-
if (y < y0) y0 = y;
|
|
1403
|
-
if (y > y1) y1 = y;
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
const bounds = x0 === Infinity ? null : { x: rect.x + x0, y: rect.y + y0, width: x1 - x0 + 1, height: y1 - y0 + 1 };
|
|
1430
|
+
const bounds = shapeBounds(shape, rect);
|
|
1408
1431
|
const anchor = bounds ? { x: bounds.x, y: bounds.y } : { x: rect.x, y: rect.y };
|
|
1409
1432
|
const per = [];
|
|
1410
1433
|
const bevelPaint = [];
|
|
@@ -1452,6 +1475,81 @@ function buildEffectMaps(items, shape, rect, ctx) {
|
|
|
1452
1475
|
for (const d of [din, dout, doutExact]) if (d) bytes += d.byteLength;
|
|
1453
1476
|
return { rect, items, bounds, shape, per, bevelPaint, din, dout, doutExact, frames, bytes };
|
|
1454
1477
|
}
|
|
1478
|
+
var rectArea = (r) => r.width * r.height;
|
|
1479
|
+
function clipRect(a, b) {
|
|
1480
|
+
const x0 = Math.max(a.x, b.x);
|
|
1481
|
+
const y0 = Math.max(a.y, b.y);
|
|
1482
|
+
const x1 = Math.min(a.x + a.width, b.x + b.width);
|
|
1483
|
+
const y1 = Math.min(a.y + a.height, b.y + b.height);
|
|
1484
|
+
return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
|
|
1485
|
+
}
|
|
1486
|
+
var growRect = (r, m) => ({ x: r.x - m, y: r.y - m, width: r.width + 2 * m, height: r.height + 2 * m });
|
|
1487
|
+
function unionRect(a, b) {
|
|
1488
|
+
const x0 = Math.min(a.x, b.x);
|
|
1489
|
+
const y0 = Math.min(a.y, b.y);
|
|
1490
|
+
return { x: x0, y: y0, width: Math.max(a.x + a.width, b.x + b.width) - x0, height: Math.max(a.y + a.height, b.y + b.height) - y0 };
|
|
1491
|
+
}
|
|
1492
|
+
function rectMinus(r, cut) {
|
|
1493
|
+
const i = clipRect(r, cut);
|
|
1494
|
+
if (!i) return [r];
|
|
1495
|
+
const parts = [
|
|
1496
|
+
{ x: r.x, y: r.y, width: r.width, height: i.y - r.y },
|
|
1497
|
+
{ x: r.x, y: i.y + i.height, width: r.width, height: r.y + r.height - (i.y + i.height) },
|
|
1498
|
+
{ x: r.x, y: i.y, width: i.x - r.x, height: i.height },
|
|
1499
|
+
{ x: i.x + i.width, y: i.y, width: r.x + r.width - (i.x + i.width), height: i.height }
|
|
1500
|
+
];
|
|
1501
|
+
return parts.filter((p) => p.width > 0 && p.height > 0);
|
|
1502
|
+
}
|
|
1503
|
+
function pasteMap(dst, to, src, from, a) {
|
|
1504
|
+
for (let y = a.y; y < a.y + a.height; y++) {
|
|
1505
|
+
const s = (y - from.y) * from.width + (a.x - from.x);
|
|
1506
|
+
dst.set(src.subarray(s, s + a.width), (y - to.y) * to.width + (a.x - to.x));
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
function patchEffectMaps(prev, items, rect, changed, margin, shapeOver, ctx) {
|
|
1510
|
+
if (!effectsAreLocal(items) || rectArea(rect) <= 0) return null;
|
|
1511
|
+
let areas = [];
|
|
1512
|
+
for (const c of changed) {
|
|
1513
|
+
const a = clipRect(growRect(c, margin), rect);
|
|
1514
|
+
if (a) areas.push(a);
|
|
1515
|
+
}
|
|
1516
|
+
areas.push(...rectMinus(rect, prev.rect));
|
|
1517
|
+
for (let merged = true; merged; ) {
|
|
1518
|
+
merged = false;
|
|
1519
|
+
for (let i = 0; i < areas.length && !merged; i++) {
|
|
1520
|
+
for (let j = i + 1; j < areas.length; j++) {
|
|
1521
|
+
if (clipRect(growRect(areas[i], 2 * margin), areas[j])) {
|
|
1522
|
+
areas[i] = unionRect(areas[i], areas[j]);
|
|
1523
|
+
areas.splice(j, 1);
|
|
1524
|
+
merged = true;
|
|
1525
|
+
break;
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
const windows = areas.map((a) => clipRect(growRect(a, margin), rect));
|
|
1531
|
+
if (windows.reduce((n, w) => n + rectArea(w), 0) > rectArea(rect) / 2) return null;
|
|
1532
|
+
const same = rect.x === prev.rect.x && rect.y === prev.rect.y && rect.width === prev.rect.width && rect.height === prev.rect.height;
|
|
1533
|
+
const take = (v) => same ? v : crop(v, prev.rect, rect, 0);
|
|
1534
|
+
const shape = take(prev.shape);
|
|
1535
|
+
const per = prev.per.map((maps) => maps.map(take));
|
|
1536
|
+
const din = prev.din && take(prev.din);
|
|
1537
|
+
const dout = prev.dout && take(prev.dout);
|
|
1538
|
+
const doutExact = prev.doutExact && take(prev.doutExact);
|
|
1539
|
+
areas.forEach((a, k) => {
|
|
1540
|
+
const w = windows[k];
|
|
1541
|
+
const part = buildEffectMaps(items, shapeOver(w), w, ctx);
|
|
1542
|
+
pasteMap(shape, rect, part.shape, w, a);
|
|
1543
|
+
per.forEach((maps, i) => maps.forEach((m, j) => pasteMap(m, rect, part.per[i][j], w, a)));
|
|
1544
|
+
if (din) pasteMap(din, rect, part.din, w, a);
|
|
1545
|
+
if (dout) pasteMap(dout, rect, part.dout, w, a);
|
|
1546
|
+
if (doutExact) pasteMap(doutExact, rect, part.doutExact, w, a);
|
|
1547
|
+
});
|
|
1548
|
+
let bytes = shape.byteLength;
|
|
1549
|
+
for (const maps of per) for (const m of maps) bytes += m.byteLength;
|
|
1550
|
+
for (const d of [din, dout, doutExact]) if (d) bytes += d.byteLength;
|
|
1551
|
+
return { rect, items, bounds: shapeBounds(shape, rect), shape, per, bevelPaint: prev.bevelPaint, din, dout, doutExact, frames: /* @__PURE__ */ new Map(), bytes };
|
|
1552
|
+
}
|
|
1455
1553
|
var rgbScratchB = [0, 0, 0];
|
|
1456
1554
|
var rgbScratchS = [0, 0, 0];
|
|
1457
1555
|
var rgbScratchM = [0, 0, 0];
|
|
@@ -2059,7 +2157,7 @@ var ZERO_TILE = new Uint8ClampedArray(TILE_BYTES);
|
|
|
2059
2157
|
var isGroup = (l) => l.type === "group";
|
|
2060
2158
|
var isPixel = (l) => l.type === "pixel";
|
|
2061
2159
|
var RasterCompositor = (_class = class {
|
|
2062
|
-
constructor(profile = {}, options = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);_class.prototype.__init11.call(this);_class.prototype.__init12.call(this);_class.prototype.__init13.call(this);_class.prototype.__init14.call(this);_class.prototype.__init15.call(this);_class.prototype.__init16.call(this);_class.prototype.__init17.call(this);_class.prototype.__init18.call(this);_class.prototype.__init19.call(this);
|
|
2160
|
+
constructor(profile = {}, options = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);_class.prototype.__init11.call(this);_class.prototype.__init12.call(this);_class.prototype.__init13.call(this);_class.prototype.__init14.call(this);_class.prototype.__init15.call(this);_class.prototype.__init16.call(this);_class.prototype.__init17.call(this);_class.prototype.__init18.call(this);_class.prototype.__init19.call(this);_class.prototype.__init20.call(this);_class.prototype.__init21.call(this);
|
|
2063
2161
|
this.profile = profile;
|
|
2064
2162
|
this.maxCacheBytes = _nullishCoalesce(options.maxCacheBytes, () => ( 256 * 1024 * 1024));
|
|
2065
2163
|
}
|
|
@@ -2084,8 +2182,11 @@ var RasterCompositor = (_class = class {
|
|
|
2084
2182
|
__init15() {this.patternTiles = /* @__PURE__ */ new WeakMap()}
|
|
2085
2183
|
__init16() {this.reachCache = /* @__PURE__ */ new WeakMap()}
|
|
2086
2184
|
__init17() {this.fxContext = null}
|
|
2087
|
-
__init18() {this.lastStats = { tiles: 0, cached: 0, stepsRun: 0 }}
|
|
2185
|
+
__init18() {this.lastStats = { tiles: 0, cached: 0, stepsRun: 0, effectsBuilt: 0, effectsPatched: 0 }}
|
|
2088
2186
|
__init19() {this.hint = -1}
|
|
2187
|
+
/** The `dirty` rectangles of the current call, as passed. */
|
|
2188
|
+
__init20() {this.callDirty = null}
|
|
2189
|
+
__init21() {this.callStats = this.lastStats}
|
|
2089
2190
|
/** Drops every cached tile and plane. */
|
|
2090
2191
|
clear() {
|
|
2091
2192
|
this.tiles.clear();
|
|
@@ -2133,7 +2234,9 @@ var RasterCompositor = (_class = class {
|
|
|
2133
2234
|
const steps = this.buildSteps(layers);
|
|
2134
2235
|
this.hint = options.checkpointLayerId ? this.stepIndexOf(steps, options.checkpointLayerId) : -1;
|
|
2135
2236
|
this.stamp++;
|
|
2136
|
-
|
|
2237
|
+
this.callDirty = _nullishCoalesce(options.dirty, () => ( null));
|
|
2238
|
+
const stats = { tiles: 0, cached: 0, stepsRun: 0, effectsBuilt: 0, effectsPatched: 0 };
|
|
2239
|
+
this.callStats = stats;
|
|
2137
2240
|
const grow = options.dirty ? this.effectsReach(layers) : 0;
|
|
2138
2241
|
const dirty = grow > 0 ? options.dirty.map((d) => inflateRect(d, grow)) : options.dirty;
|
|
2139
2242
|
for (const { tx, ty } of _chunkCRMAXIUVcjs.tilesInRect.call(void 0, rect)) {
|
|
@@ -2149,8 +2252,10 @@ var RasterCompositor = (_class = class {
|
|
|
2149
2252
|
tile(layers, tx, ty, sources) {
|
|
2150
2253
|
this.setSources(sources);
|
|
2151
2254
|
this.stamp++;
|
|
2152
|
-
const stats = { tiles: 1, cached: 0, stepsRun: 0 };
|
|
2255
|
+
const stats = { tiles: 1, cached: 0, stepsRun: 0, effectsBuilt: 0, effectsPatched: 0 };
|
|
2256
|
+
this.callStats = stats;
|
|
2153
2257
|
this.hint = -1;
|
|
2258
|
+
this.callDirty = null;
|
|
2154
2259
|
const data = this.compositeTile(layers, this.buildSteps(layers), tx, ty, stats);
|
|
2155
2260
|
this.lastStats = stats;
|
|
2156
2261
|
this.evict();
|
|
@@ -2220,7 +2325,8 @@ var RasterCompositor = (_class = class {
|
|
|
2220
2325
|
let first = 0;
|
|
2221
2326
|
if (entry) {
|
|
2222
2327
|
while (first < sigs.length && first < entry.sigs.length && sameSig(entry.sigs[first], sigs[first])) first++;
|
|
2223
|
-
if (first === sigs.length && first === entry.sigs.length) {
|
|
2328
|
+
if (first === sigs.length && first === entry.sigs.length || this.changedOnlyNearby(steps, sigs, entry, dirty)) {
|
|
2329
|
+
entry.sigs = sigs;
|
|
2224
2330
|
entry.stamp = this.stamp;
|
|
2225
2331
|
stats.cached++;
|
|
2226
2332
|
return entry.result;
|
|
@@ -2285,6 +2391,20 @@ var RasterCompositor = (_class = class {
|
|
|
2285
2391
|
this.cacheBytes += this.entryBytes(next) - prevBytes;
|
|
2286
2392
|
return result;
|
|
2287
2393
|
}
|
|
2394
|
+
/**
|
|
2395
|
+
* Whether a tile with no part in this call's (grown) `dirty` rectangles changed only in what local
|
|
2396
|
+
* effects read beyond it: every changed step is a pixel layer with local effects whose changes stay
|
|
2397
|
+
* inside `dirty` (and so are farther than its margin), which leaves the tile's pixels as they were.
|
|
2398
|
+
*/
|
|
2399
|
+
changedOnlyNearby(steps, sigs, entry, dirty) {
|
|
2400
|
+
if (this.callDirty === null || dirty || entry.stamp !== this.stamp - 1 || sigs.length !== entry.sigs.length) return false;
|
|
2401
|
+
return steps.every((step, i) => {
|
|
2402
|
+
if (sameSig(entry.sigs[i], sigs[i])) return true;
|
|
2403
|
+
if (step.kind !== "content" || entry.sigs[i].key !== sigs[i].key) return false;
|
|
2404
|
+
const { layer, clipped } = step;
|
|
2405
|
+
return this.hasEffects(layer) && effectsAreLocal(activeEffectItems(layer.effects)) && this.dirtyCoversShape(layer) && clipped.every((c) => this.dirtyCoversShape(c));
|
|
2406
|
+
});
|
|
2407
|
+
}
|
|
2288
2408
|
entryBytes(e) {
|
|
2289
2409
|
let n = e.result === ZERO_TILE ? 0 : TILE_BYTES;
|
|
2290
2410
|
for (const cp of e.checkpoints.values()) n += cp.data.byteLength;
|
|
@@ -2415,14 +2535,20 @@ var RasterCompositor = (_class = class {
|
|
|
2415
2535
|
if (!b) return { x: 0, y: 0, width: 0, height: 0 };
|
|
2416
2536
|
return intersectRect({ x: b.x + dx - m, y: b.y + dy - m, width: b.width + 2 * m, height: b.height + 2 * m }, canvas);
|
|
2417
2537
|
}
|
|
2538
|
+
/** The signature of a layer's shape (its surface tiles and mask refs) per tile of `region`. */
|
|
2539
|
+
shapeSigs(layer, region) {
|
|
2540
|
+
const sigs = /* @__PURE__ */ new Map();
|
|
2541
|
+
if (region.width <= 0 || region.height <= 0) return sigs;
|
|
2542
|
+
const steps = isGroup(layer) ? this.buildSteps(_nullishCoalesce(layer.children, () => ( []))) : null;
|
|
2543
|
+
for (const t of _chunkCRMAXIUVcjs.tilesInRect.call(void 0, region)) {
|
|
2544
|
+
sigs.set(_chunkCRMAXIUVcjs.tileKey.call(void 0, t.tx, t.ty), steps ? this.plainGroupSig(layer, steps, t.tx, t.ty) : this.plainContentSig(layer, t.tx, t.ty));
|
|
2545
|
+
}
|
|
2546
|
+
return sigs;
|
|
2547
|
+
}
|
|
2418
2548
|
/** The surface tiles (and mask refs) a layer's shape reads over `region`. */
|
|
2419
2549
|
shapeRefs(layer, region) {
|
|
2420
2550
|
const refs = [];
|
|
2421
|
-
|
|
2422
|
-
for (const t of _chunkCRMAXIUVcjs.tilesInRect.call(void 0, region)) {
|
|
2423
|
-
const sig = isGroup(layer) ? this.plainGroupSig(layer, this.buildSteps(_nullishCoalesce(layer.children, () => ( []))), t.tx, t.ty) : this.plainContentSig(layer, t.tx, t.ty);
|
|
2424
|
-
for (const r of sig.refs) refs.push(r);
|
|
2425
|
-
}
|
|
2551
|
+
for (const sig of this.shapeSigs(layer, region).values()) for (const r of sig.refs) refs.push(r);
|
|
2426
2552
|
return refs;
|
|
2427
2553
|
}
|
|
2428
2554
|
lightKey() {
|
|
@@ -2448,18 +2574,28 @@ var RasterCompositor = (_class = class {
|
|
|
2448
2574
|
const memo = this.effectMemo.get(layer);
|
|
2449
2575
|
if (memo && memo.stamp === this.stamp) return memo.maps;
|
|
2450
2576
|
const region = this.effectRegion(layer);
|
|
2451
|
-
const key =
|
|
2452
|
-
const
|
|
2577
|
+
const key = this.propsKey(layer) + this.lightKey();
|
|
2578
|
+
const tiles = this.shapeSigs(layer, region);
|
|
2453
2579
|
const hit = this.effectCache.get(layer.id);
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
maps = hit.maps;
|
|
2580
|
+
this.effectCache.delete(layer.id);
|
|
2581
|
+
let entry;
|
|
2582
|
+
if (hit && hit.key === key && sameRect(hit.region, region) && [...tiles].every(([k, sig]) => sameSig(hit.tiles.get(k), sig))) {
|
|
2583
|
+
entry = hit;
|
|
2459
2584
|
} else {
|
|
2460
|
-
|
|
2461
|
-
this.
|
|
2462
|
-
|
|
2585
|
+
const items = activeEffectItems(layer.effects);
|
|
2586
|
+
const ctx = this.effectContext();
|
|
2587
|
+
let maps = null;
|
|
2588
|
+
if (hit && hit.key === key && items.every((e) => effectReach(e) <= MAX_EFFECT_REACH)) {
|
|
2589
|
+
const changed = this.shapeChanges(layer, hit, tiles, region);
|
|
2590
|
+
maps = patchEffectMaps(hit.maps, items, region, changed, effectsMargin(layer.effects), (r) => this.layerShape(layer, r), ctx);
|
|
2591
|
+
}
|
|
2592
|
+
if (maps) this.callStats.effectsPatched++;
|
|
2593
|
+
else this.callStats.effectsBuilt++;
|
|
2594
|
+
entry = { key, region, tiles, maps: _nullishCoalesce(maps, () => ( buildEffectMaps(items, this.layerShape(layer, region), region, ctx))), stamp: 0 };
|
|
2595
|
+
}
|
|
2596
|
+
entry.stamp = this.stamp;
|
|
2597
|
+
this.effectCache.set(layer.id, entry);
|
|
2598
|
+
if (entry !== hit) {
|
|
2463
2599
|
let bytes = 0;
|
|
2464
2600
|
for (const e of this.effectCache.values()) bytes += e.maps.bytes;
|
|
2465
2601
|
while (this.effectCache.size > 1 && (this.effectCache.size > 32 || bytes > this.maxCacheBytes / 2)) {
|
|
@@ -2468,8 +2604,42 @@ var RasterCompositor = (_class = class {
|
|
|
2468
2604
|
this.effectCache.delete(oldest);
|
|
2469
2605
|
}
|
|
2470
2606
|
}
|
|
2471
|
-
this.effectMemo.set(layer, { stamp: this.stamp, maps });
|
|
2472
|
-
return maps;
|
|
2607
|
+
this.effectMemo.set(layer, { stamp: this.stamp, maps: entry.maps });
|
|
2608
|
+
return entry.maps;
|
|
2609
|
+
}
|
|
2610
|
+
/**
|
|
2611
|
+
* Where a layer's shape may differ from the one `prev` was built from: the tiles whose signature
|
|
2612
|
+
* changed (a tile new to the region that reads nothing did not), narrowed to this call's `dirty`
|
|
2613
|
+
* rectangles when `prev` is from the previous call and they cover every change of the shape.
|
|
2614
|
+
*/
|
|
2615
|
+
shapeChanges(layer, prev, tiles, region) {
|
|
2616
|
+
const out = [];
|
|
2617
|
+
for (const { tx, ty } of _chunkCRMAXIUVcjs.tilesInRect.call(void 0, region)) {
|
|
2618
|
+
const sig = tiles.get(_chunkCRMAXIUVcjs.tileKey.call(void 0, tx, ty));
|
|
2619
|
+
const old = prev.tiles.get(_chunkCRMAXIUVcjs.tileKey.call(void 0, tx, ty));
|
|
2620
|
+
if (old ? sameSig(old, sig) : sig.refs.every((r2) => r2 === null || r2 === 0)) continue;
|
|
2621
|
+
const r = intersectRect({ x: tx * _chunkCRMAXIUVcjs.TILE, y: ty * _chunkCRMAXIUVcjs.TILE, width: _chunkCRMAXIUVcjs.TILE, height: _chunkCRMAXIUVcjs.TILE }, region);
|
|
2622
|
+
if (r.width > 0 && r.height > 0) out.push(r);
|
|
2623
|
+
}
|
|
2624
|
+
const dirty = this.callDirty;
|
|
2625
|
+
if (!dirty || prev.stamp !== this.stamp - 1 || !this.dirtyCoversShape(layer)) return out;
|
|
2626
|
+
const narrowed = [];
|
|
2627
|
+
for (const r of out) {
|
|
2628
|
+
for (const d of dirty) {
|
|
2629
|
+
const a = intersectRect(r, { x: Math.floor(d.x), y: Math.floor(d.y), width: Math.ceil(d.x + d.width) - Math.floor(d.x), height: Math.ceil(d.y + d.height) - Math.floor(d.y) });
|
|
2630
|
+
if (a.width > 0 && a.height > 0) narrowed.push(a);
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
return narrowed;
|
|
2634
|
+
}
|
|
2635
|
+
/**
|
|
2636
|
+
* Whether a change to a layer stays inside the `dirty` rectangles that name it: a pixel layer
|
|
2637
|
+
* without filters or a feathered or parametric mask (those spread a change beyond it).
|
|
2638
|
+
*/
|
|
2639
|
+
dirtyCoversShape(layer) {
|
|
2640
|
+
if (!isPixel(layer) || _optionalChain([this, 'access', _26 => _26.profile, 'access', _27 => _27.pixelFilters, 'optionalCall', _28 => _28(layer)])) return false;
|
|
2641
|
+
const mask = layer.mask;
|
|
2642
|
+
return !mask || mask.enabled === false || !mask.source && !((_nullishCoalesce(mask.feather, () => ( 0))) > 0);
|
|
2473
2643
|
}
|
|
2474
2644
|
/** A layer's alpha over `r` after its mask (0..1, quantised to bytes as tiles see it). */
|
|
2475
2645
|
layerShape(layer, r) {
|
|
@@ -2555,10 +2725,10 @@ var RasterCompositor = (_class = class {
|
|
|
2555
2725
|
*/
|
|
2556
2726
|
layerPixels(layer) {
|
|
2557
2727
|
const raw = this.sources.surfaceOf ? this.sources.surfaceOf(layer) : layer.surface;
|
|
2558
|
-
const ox = _nullishCoalesce(_optionalChain([layer, 'access',
|
|
2559
|
-
const oy = _nullishCoalesce(_optionalChain([layer, 'access',
|
|
2560
|
-
const filters = _nullishCoalesce(_optionalChain([this, 'access',
|
|
2561
|
-
if (!_optionalChain([filters, 'optionalAccess',
|
|
2728
|
+
const ox = _nullishCoalesce(_optionalChain([layer, 'access', _29 => _29.offset, 'optionalAccess', _30 => _30.x]), () => ( 0));
|
|
2729
|
+
const oy = _nullishCoalesce(_optionalChain([layer, 'access', _31 => _31.offset, 'optionalAccess', _32 => _32.y]), () => ( 0));
|
|
2730
|
+
const filters = _nullishCoalesce(_optionalChain([this, 'access', _33 => _33.profile, 'access', _34 => _34.pixelFilters, 'optionalCall', _35 => _35(layer)]), () => ( null));
|
|
2731
|
+
if (!_optionalChain([filters, 'optionalAccess', _36 => _36.spatial])) return { surface: raw, dx: ox, dy: oy, perPixel: filters };
|
|
2562
2732
|
const fkey = `${ox},${oy}:${filters.key}`;
|
|
2563
2733
|
let byKey = this.filteredCache.get(raw);
|
|
2564
2734
|
if (!byKey) {
|
|
@@ -2575,7 +2745,7 @@ var RasterCompositor = (_class = class {
|
|
|
2575
2745
|
}
|
|
2576
2746
|
/** RGBA of a content layer over `r` (document space, inside one tile), or `null` when it has nothing there. */
|
|
2577
2747
|
contentTile(layer, r) {
|
|
2578
|
-
if (!isPixel(layer)) return _nullishCoalesce(_optionalChain([this, 'access',
|
|
2748
|
+
if (!isPixel(layer)) return _nullishCoalesce(_optionalChain([this, 'access', _37 => _37.profile, 'access', _38 => _38.contentTile, 'optionalCall', _39 => _39(layer, r, this.sources)]), () => ( null));
|
|
2579
2749
|
const { surface, dx, dy, perPixel } = this.layerPixels(layer);
|
|
2580
2750
|
const src = { x: r.x - dx, y: r.y - dy, width: r.width, height: r.height };
|
|
2581
2751
|
const covered = _chunkCRMAXIUVcjs.tilesInRect.call(void 0, src).map((t) => surface.getTile(t.tx, t.ty));
|
|
@@ -2590,7 +2760,7 @@ var RasterCompositor = (_class = class {
|
|
|
2590
2760
|
let byKey = this.contentCache.get(anchor);
|
|
2591
2761
|
const refsKey = `${r.x},${r.y}:${fkey}`;
|
|
2592
2762
|
if (aligned) {
|
|
2593
|
-
const hit = _optionalChain([byKey, 'optionalAccess',
|
|
2763
|
+
const hit = _optionalChain([byKey, 'optionalAccess', _40 => _40.get, 'call', _41 => _41(refsKey)]);
|
|
2594
2764
|
if (hit) return hit;
|
|
2595
2765
|
}
|
|
2596
2766
|
const data = _chunkCRMAXIUVcjs.readRegion.call(void 0, surface, src);
|
|
@@ -2628,7 +2798,7 @@ var RasterCompositor = (_class = class {
|
|
|
2628
2798
|
const H = this.sources.height;
|
|
2629
2799
|
let v = new Float32Array(W * H);
|
|
2630
2800
|
if (mask.source) {
|
|
2631
|
-
const generated = _nullishCoalesce(_optionalChain([this, 'access',
|
|
2801
|
+
const generated = _nullishCoalesce(_optionalChain([this, 'access', _42 => _42.profile, 'access', _43 => _43.maskSourcePlane, 'optionalCall', _44 => _44(mask.source, W, H, this.sources)]), () => ( null));
|
|
2632
2802
|
if (!generated || generated.length !== W * H) v.fill(1);
|
|
2633
2803
|
else v.set(generated);
|
|
2634
2804
|
} else {
|
|
@@ -2647,8 +2817,8 @@ var RasterCompositor = (_class = class {
|
|
|
2647
2817
|
maskTile(layer, r) {
|
|
2648
2818
|
const mask = layer.mask;
|
|
2649
2819
|
if (!mask || mask.enabled === false) return null;
|
|
2650
|
-
const ox = isPixel(layer) ? _nullishCoalesce(_optionalChain([layer, 'access',
|
|
2651
|
-
const oy = isPixel(layer) ? _nullishCoalesce(_optionalChain([layer, 'access',
|
|
2820
|
+
const ox = isPixel(layer) ? _nullishCoalesce(_optionalChain([layer, 'access', _45 => _45.offset, 'optionalAccess', _46 => _46.x]), () => ( 0)) : 0;
|
|
2821
|
+
const oy = isPixel(layer) ? _nullishCoalesce(_optionalChain([layer, 'access', _47 => _47.offset, 'optionalAccess', _48 => _48.y]), () => ( 0)) : 0;
|
|
2652
2822
|
const n = r.width * r.height;
|
|
2653
2823
|
const out = new Float32Array(n);
|
|
2654
2824
|
const density = _nullishCoalesce(mask.density, () => ( 1));
|
|
@@ -2722,7 +2892,7 @@ var RasterCompositor = (_class = class {
|
|
|
2722
2892
|
return empty;
|
|
2723
2893
|
}
|
|
2724
2894
|
contentBlend(layer) {
|
|
2725
|
-
return _nullishCoalesce(_optionalChain([this, 'access',
|
|
2895
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _49 => _49.profile, 'access', _50 => _50.contentBlend, 'optionalCall', _51 => _51(layer)]), () => ( layer.blend));
|
|
2726
2896
|
}
|
|
2727
2897
|
blendOnto(acc, src, empty, mode, alpha, coverage) {
|
|
2728
2898
|
if (!(alpha > 0)) return empty;
|
|
@@ -2776,7 +2946,7 @@ var RasterCompositor = (_class = class {
|
|
|
2776
2946
|
}
|
|
2777
2947
|
visible.push(node);
|
|
2778
2948
|
}
|
|
2779
|
-
if (visible.length) _optionalChain([this, 'access',
|
|
2949
|
+
if (visible.length) _optionalChain([this, 'access', _52 => _52.profile, 'access', _53 => _53.applyFilterRun, 'optionalCall', _54 => _54(visible, acc, r, masks, this.sources)]);
|
|
2780
2950
|
}
|
|
2781
2951
|
}, _class);
|
|
2782
2952
|
function filterOverCanvas(surface, ox, oy, filters, width, height) {
|
|
@@ -2796,6 +2966,9 @@ function copyRect(data, r, a) {
|
|
|
2796
2966
|
function pasteRect(data, r, part, a) {
|
|
2797
2967
|
for (let y = 0; y < a.height; y++) data.set(part.subarray(y * a.width * 4, (y + 1) * a.width * 4), ((a.y - r.y + y) * r.width + (a.x - r.x)) * 4);
|
|
2798
2968
|
}
|
|
2969
|
+
function sameRect(a, b) {
|
|
2970
|
+
return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
|
|
2971
|
+
}
|
|
2799
2972
|
function inflateRect(r, m) {
|
|
2800
2973
|
return { x: r.x - m, y: r.y - m, width: r.width + 2 * m, height: r.height + 2 * m };
|
|
2801
2974
|
}
|
|
@@ -2851,13 +3024,13 @@ function fixedTables() {
|
|
|
2851
3024
|
return [fixedLit, fixedDist];
|
|
2852
3025
|
}
|
|
2853
3026
|
var BitReader = (_class2 = class {
|
|
2854
|
-
constructor(data) {;_class2.prototype.
|
|
3027
|
+
constructor(data) {;_class2.prototype.__init22.call(this);_class2.prototype.__init23.call(this);_class2.prototype.__init24.call(this);
|
|
2855
3028
|
this.data = data;
|
|
2856
3029
|
}
|
|
2857
3030
|
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
3031
|
+
__init22() {this.pos = 0}
|
|
3032
|
+
__init23() {this.bit = 0}
|
|
3033
|
+
__init24() {this.bits = 0}
|
|
2861
3034
|
need(n) {
|
|
2862
3035
|
while (this.bits < n) {
|
|
2863
3036
|
if (this.pos >= this.data.length) throw new ZlibError("Unexpected end of compressed data");
|
|
@@ -2890,13 +3063,13 @@ var BitReader = (_class2 = class {
|
|
|
2890
3063
|
}
|
|
2891
3064
|
}, _class2);
|
|
2892
3065
|
var Output = (_class3 = class {
|
|
2893
|
-
constructor(hint, max) {;_class3.prototype.
|
|
3066
|
+
constructor(hint, max) {;_class3.prototype.__init25.call(this);
|
|
2894
3067
|
this.max = max;
|
|
2895
3068
|
this.buf = new Uint8Array(Math.max(1024, Math.min(hint, max)));
|
|
2896
3069
|
}
|
|
2897
3070
|
|
|
2898
3071
|
|
|
2899
|
-
|
|
3072
|
+
__init25() {this.len = 0}
|
|
2900
3073
|
ensure(n) {
|
|
2901
3074
|
if (this.len + n > this.max) throw new ZlibError(`Decompressed data exceeds ${this.max} bytes`);
|
|
2902
3075
|
if (this.len + n <= this.buf.length) return;
|
|
@@ -3016,10 +3189,10 @@ function inflate(data, options = {}) {
|
|
|
3016
3189
|
}
|
|
3017
3190
|
var BitWriter = (_class4 = class {
|
|
3018
3191
|
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
constructor(hint) {;_class4.prototype.
|
|
3192
|
+
__init26() {this.len = 0}
|
|
3193
|
+
__init27() {this.bit = 0}
|
|
3194
|
+
__init28() {this.bits = 0}
|
|
3195
|
+
constructor(hint) {;_class4.prototype.__init26.call(this);_class4.prototype.__init27.call(this);_class4.prototype.__init28.call(this);
|
|
3023
3196
|
this.buf = new Uint8Array(Math.max(1024, hint));
|
|
3024
3197
|
}
|
|
3025
3198
|
grow() {
|
|
@@ -3708,5 +3881,6 @@ function pngDataUrl(width, height, data, channels = 4) {
|
|
|
3708
3881
|
|
|
3709
3882
|
|
|
3710
3883
|
|
|
3711
|
-
|
|
3712
|
-
|
|
3884
|
+
|
|
3885
|
+
exports.DIRECT_GAUSSIAN_MAX_SIGMA = DIRECT_GAUSSIAN_MAX_SIGMA; exports.gaussianBlur = gaussianBlur; exports.flattenLayers = flattenLayers; exports.findLayer = findLayer; exports.mapLayer = mapLayer; exports.insertLayer = insertLayer; exports.isLayerLocked = isLayerLocked; exports.DEFAULT_GLOBAL_LIGHT = DEFAULT_GLOBAL_LIGHT; exports.LAYER_EFFECT_KINDS = LAYER_EFFECT_KINDS; exports.layerEffectLabel = layerEffectLabel; exports.isLayerEffectKind = isLayerEffectKind; exports.defaultEffectGradient = defaultEffectGradient; exports.newEffectId = newEffectId; exports.defaultLayerEffect = defaultLayerEffect; exports.hasActiveEffects = hasActiveEffects; exports.MAX_EFFECT_REACH = MAX_EFFECT_REACH; exports.effectReach = effectReach; exports.effectsMargin = effectsMargin; exports.effectsScale = effectsScale; exports.scaleLayerEffect = scaleLayerEffect; exports.parseEffectColor = parseEffectColor; exports.effectColorHex = effectColorHex; exports.LayerEffectError = LayerEffectError; exports.validateEffectGradient = validateEffectGradient; exports.layerEffectFields = layerEffectFields; exports.validateLayerEffect = validateLayerEffect; exports.mergeLayerEffect = mergeLayerEffect; exports.validateLayerEffects = validateLayerEffects; exports.normalizeLayerEffects = normalizeLayerEffects; exports.effectsFingerprint = effectsFingerprint; exports.PatternTile = PatternTile; exports.PatternPlacement = PatternPlacement; exports.builtinPatternIds = builtinPatternIds; exports.builtinPattern = builtinPattern; exports.hashNoise = hashNoise; exports.CURVE_LUT_SIZE = CURVE_LUT_SIZE; exports.curveLut = curveLut; exports.STROKE_CHAMFER_MAX = STROKE_CHAMFER_MAX; exports.contourLut = contourLut; exports.activeEffectItems = activeEffectItems; exports.effectsAreLocal = effectsAreLocal; exports.buildEffectMaps = buildEffectMaps; exports.patchEffectMaps = patchEffectMaps; exports.gradientT = gradientT; exports.compositeLayerEffects = compositeLayerEffects; exports.renderLayerEffects = renderLayerEffects; exports.blendTile = blendTile; exports.RasterCompositor = RasterCompositor; exports.changedTiles = changedTiles; exports.ZlibError = ZlibError; exports.inflateRaw = inflateRaw; exports.adler32 = adler32; exports.inflate = inflate; exports.deflateRaw = deflateRaw; exports.deflate = deflate; exports.encodePng = encodePng; exports.isPng = isPng; exports.decodePng = decodePng; exports.bytesToBase64 = bytesToBase64; exports.base64ToBytes = base64ToBytes; exports.parseDataUrl = parseDataUrl; exports.pngDataUrl = pngDataUrl;
|
|
3886
|
+
//# sourceMappingURL=chunk-4AB5BHYK.cjs.map
|