@pixerate/editor 0.102.0 → 0.104.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/THIRD_PARTY_NOTICES.md +3 -0
- package/dist/agent/index.cjs +7 -7
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.js +7 -7
- package/dist/canvas/index.cjs +3 -3
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.js +4 -4
- package/dist/chunk-6BU5WU4R.cjs +1 -0
- package/dist/chunk-6BU5WU4R.cjs.map +1 -0
- package/dist/{chunk-IB53LVGV.js → chunk-DS7KDKPX.js} +1 -1
- package/dist/chunk-NQLQ2JOI.js +7176 -0
- package/dist/chunk-NQLQ2JOI.js.map +1 -0
- package/dist/{chunk-ZZOTHJ4K.cjs → chunk-PV42JITT.cjs} +1 -1
- package/dist/{chunk-ZZOTHJ4K.cjs.map → chunk-PV42JITT.cjs.map} +1 -1
- package/dist/chunk-VSMM7B3P.cjs +7176 -0
- package/dist/chunk-VSMM7B3P.cjs.map +1 -0
- package/dist/chunk-XYBJKUAU.js +1 -0
- package/dist/chunk-XYBJKUAU.js.map +1 -0
- package/dist/compositor-B1ZrKR89.d.ts +835 -0
- package/dist/compositor-CTMU-B1t.d.cts +835 -0
- package/dist/export-BLpMyCYg.d.ts +3139 -0
- package/dist/export-X9rY79p0.d.cts +3139 -0
- package/dist/homography-CZ-tFjay.d.cts +50 -0
- package/dist/homography-Ctfjoc1b.d.ts +50 -0
- package/dist/image-editor/index.cjs +2846 -9407
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +24 -3151
- package/dist/image-editor/index.d.ts +24 -3151
- package/dist/image-editor/index.js +2508 -9069
- package/dist/image-editor/index.js.map +1 -1
- package/dist/mixer-DG_9Yu2W.d.ts +282 -0
- package/dist/mixer-DGcH6HLu.d.cts +282 -0
- package/dist/paint/index.cjs +4 -3
- package/dist/paint/index.cjs.map +1 -1
- package/dist/paint/index.d.cts +3 -281
- package/dist/paint/index.d.ts +3 -281
- package/dist/paint/index.js +2 -1
- package/dist/paint-editor/index.cjs +4417 -0
- package/dist/paint-editor/index.cjs.map +1 -0
- package/dist/paint-editor/index.d.cts +1539 -0
- package/dist/paint-editor/index.d.ts +1539 -0
- package/dist/paint-editor/index.js +4417 -0
- package/dist/paint-editor/index.js.map +1 -0
- package/dist/raster/index.d.cts +6 -835
- package/dist/raster/index.d.ts +6 -835
- package/dist/{surface-DIA-XatS.d.cts → surface-AfHCH7BR.d.cts} +1 -1
- package/dist/{surface-DIA-XatS.d.ts → surface-AfHCH7BR.d.ts} +1 -1
- package/dist/tools/index.cjs +3 -3
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.js +3 -3
- package/dist/vector/index.d.cts +2 -1
- package/dist/vector/index.d.ts +2 -1
- package/dist/{warp-B8rAguzs.d.ts → warp-CWHZzE3x.d.ts} +2 -49
- package/dist/{warp-nYs2DPrx.d.cts → warp-D5jz_tN7.d.cts} +2 -49
- package/package.json +6 -1
- package/skills/README.md +1 -0
- package/skills/pixerate-image-editor/SKILL.md +14 -5
- package/skills/pixerate-paint-editor/SKILL.md +203 -0
- /package/dist/{chunk-IB53LVGV.js.map → chunk-DS7KDKPX.js.map} +0 -0
|
@@ -0,0 +1,835 @@
|
|
|
1
|
+
import { B as BlendMode, R as RasterRect, a as TiledSurface, M as MaskSurface, P as PixelSurface, T as TileKey } from './surface-AfHCH7BR.js';
|
|
2
|
+
import { H as Homography, V as Vec2 } from './types-CwMPoRMU.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Layer effects (Photoshop's layer styles) as data: drop and inner shadows, outer and inner
|
|
6
|
+
* glows, bevel & emboss, satin, colour / gradient / pattern overlays and strokes. Rendering lives
|
|
7
|
+
* in `./render`, PSD mapping in the image editor's PSD module.
|
|
8
|
+
*
|
|
9
|
+
* Angles are in degrees, counter-clockwise from 3 o'clock, and give the direction the light
|
|
10
|
+
* comes *from* (Photoshop's convention). Sizes and distances are in pixels, opacities and
|
|
11
|
+
* percentages in 0..1, colours are `#rrggbb`.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** One point of a contour curve (input → output, both 0..1). */
|
|
15
|
+
interface ContourPoint {
|
|
16
|
+
input: number;
|
|
17
|
+
output: number;
|
|
18
|
+
/** The curve bends sharply here instead of passing smoothly through (Photoshop's corner point). */
|
|
19
|
+
corner?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** A transfer curve applied to an effect's coverage. Missing on an effect = linear. */
|
|
22
|
+
interface EffectContour {
|
|
23
|
+
name: string;
|
|
24
|
+
points: ContourPoint[];
|
|
25
|
+
}
|
|
26
|
+
type GradientStyle = 'linear' | 'radial' | 'angle' | 'reflected' | 'diamond';
|
|
27
|
+
interface GradientColorStop {
|
|
28
|
+
/** 0..1 along the gradient. */
|
|
29
|
+
position: number;
|
|
30
|
+
color: string;
|
|
31
|
+
}
|
|
32
|
+
interface GradientOpacityStop {
|
|
33
|
+
position: number;
|
|
34
|
+
/** 0..1 */
|
|
35
|
+
opacity: number;
|
|
36
|
+
}
|
|
37
|
+
/** A gradient as overlays, gradient strokes and gradient glows paint it. */
|
|
38
|
+
interface EffectGradient {
|
|
39
|
+
stops: GradientColorStop[];
|
|
40
|
+
/** Missing or empty: opaque. */
|
|
41
|
+
opacityStops?: GradientOpacityStop[];
|
|
42
|
+
style: GradientStyle;
|
|
43
|
+
/** Degrees (90 = bottom to top). */
|
|
44
|
+
angle: number;
|
|
45
|
+
/** 1 = 100 %. */
|
|
46
|
+
scale: number;
|
|
47
|
+
reverse: boolean;
|
|
48
|
+
/** Align with the layer's bounds (else the canvas). */
|
|
49
|
+
align: boolean;
|
|
50
|
+
/** Centre offset as a fraction of the bounds. */
|
|
51
|
+
offset: {
|
|
52
|
+
x: number;
|
|
53
|
+
y: number;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** A pattern reference: the id of a document or built-in pattern (see `builtinPatternIds`). */
|
|
57
|
+
interface EffectPatternRef {
|
|
58
|
+
patternId: string;
|
|
59
|
+
/** Display name (PSD keeps it beside the id). */
|
|
60
|
+
name?: string;
|
|
61
|
+
/** 1 = 100 %. */
|
|
62
|
+
scale: number;
|
|
63
|
+
/** Rotation in degrees (counter-clockwise). */
|
|
64
|
+
angle?: number;
|
|
65
|
+
/** Tile from the layer's top-left ("Link with Layer", default) instead of the canvas origin. */
|
|
66
|
+
link?: boolean;
|
|
67
|
+
/** Origin offset in pixels. */
|
|
68
|
+
phase?: {
|
|
69
|
+
x: number;
|
|
70
|
+
y: number;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/** What a stroke or glow paints with. */
|
|
74
|
+
type EffectFill = {
|
|
75
|
+
type: 'color';
|
|
76
|
+
color: string;
|
|
77
|
+
} | {
|
|
78
|
+
type: 'gradient';
|
|
79
|
+
gradient: EffectGradient;
|
|
80
|
+
} | ({
|
|
81
|
+
type: 'pattern';
|
|
82
|
+
} & EffectPatternRef);
|
|
83
|
+
interface EffectBase {
|
|
84
|
+
/** Unique within the layer. */
|
|
85
|
+
id: string;
|
|
86
|
+
enabled: boolean;
|
|
87
|
+
}
|
|
88
|
+
interface Blended {
|
|
89
|
+
blend: BlendMode;
|
|
90
|
+
/** 0..1 */
|
|
91
|
+
opacity: number;
|
|
92
|
+
}
|
|
93
|
+
interface DropShadowEffect extends EffectBase, Blended {
|
|
94
|
+
kind: 'drop-shadow';
|
|
95
|
+
color: string;
|
|
96
|
+
angle: number;
|
|
97
|
+
useGlobalLight: boolean;
|
|
98
|
+
distance: number;
|
|
99
|
+
/** 0..1 of the size grown solid before the blur. */
|
|
100
|
+
spread: number;
|
|
101
|
+
size: number;
|
|
102
|
+
contour?: EffectContour;
|
|
103
|
+
antiAlias: boolean;
|
|
104
|
+
/** 0..1 */
|
|
105
|
+
noise: number;
|
|
106
|
+
/** The layer hides the shadow beneath its see-through fill ("Layer Knocks Out Drop Shadow"). */
|
|
107
|
+
knocksOut: boolean;
|
|
108
|
+
}
|
|
109
|
+
interface InnerShadowEffect extends EffectBase, Blended {
|
|
110
|
+
kind: 'inner-shadow';
|
|
111
|
+
color: string;
|
|
112
|
+
angle: number;
|
|
113
|
+
useGlobalLight: boolean;
|
|
114
|
+
distance: number;
|
|
115
|
+
/** 0..1 of the size shrunk solid before the blur. */
|
|
116
|
+
choke: number;
|
|
117
|
+
size: number;
|
|
118
|
+
contour?: EffectContour;
|
|
119
|
+
antiAlias: boolean;
|
|
120
|
+
noise: number;
|
|
121
|
+
}
|
|
122
|
+
type GlowTechnique = 'softer' | 'precise';
|
|
123
|
+
interface OuterGlowEffect extends EffectBase, Blended {
|
|
124
|
+
kind: 'outer-glow';
|
|
125
|
+
/** Colour or gradient. */
|
|
126
|
+
fill: Extract<EffectFill, {
|
|
127
|
+
type: 'color' | 'gradient';
|
|
128
|
+
}>;
|
|
129
|
+
technique: GlowTechnique;
|
|
130
|
+
spread: number;
|
|
131
|
+
size: number;
|
|
132
|
+
contour?: EffectContour;
|
|
133
|
+
antiAlias: boolean;
|
|
134
|
+
/** 0..1 (default 0.5): the part of the glow the contour spans. */
|
|
135
|
+
range: number;
|
|
136
|
+
/** 0..1, varies a gradient glow's colours. Stored only (not rendered). */
|
|
137
|
+
jitter: number;
|
|
138
|
+
noise: number;
|
|
139
|
+
}
|
|
140
|
+
interface InnerGlowEffect extends EffectBase, Blended {
|
|
141
|
+
kind: 'inner-glow';
|
|
142
|
+
fill: Extract<EffectFill, {
|
|
143
|
+
type: 'color' | 'gradient';
|
|
144
|
+
}>;
|
|
145
|
+
technique: GlowTechnique;
|
|
146
|
+
choke: number;
|
|
147
|
+
size: number;
|
|
148
|
+
contour?: EffectContour;
|
|
149
|
+
antiAlias: boolean;
|
|
150
|
+
range: number;
|
|
151
|
+
jitter: number;
|
|
152
|
+
noise: number;
|
|
153
|
+
/** Glow from the edge inwards (default) or from the centre outwards. */
|
|
154
|
+
source: 'edge' | 'center';
|
|
155
|
+
}
|
|
156
|
+
type BevelStyle = 'inner-bevel' | 'outer-bevel' | 'emboss' | 'pillow-emboss' | 'stroke-emboss';
|
|
157
|
+
type BevelTechnique = 'smooth' | 'chisel-hard' | 'chisel-soft';
|
|
158
|
+
/** The Contour element of Bevel & Emboss: shapes the bevel's height profile. */
|
|
159
|
+
interface BevelContour {
|
|
160
|
+
contour: EffectContour;
|
|
161
|
+
/** 0..1 (default 0.5). Stored only. */
|
|
162
|
+
range: number;
|
|
163
|
+
antiAlias: boolean;
|
|
164
|
+
}
|
|
165
|
+
/** The Texture element of Bevel & Emboss: a pattern's luminance added to the height. */
|
|
166
|
+
interface BevelTexture extends EffectPatternRef {
|
|
167
|
+
/** -10..10 (1 = +100 %); negative carves the pattern in. */
|
|
168
|
+
depth: number;
|
|
169
|
+
invert: boolean;
|
|
170
|
+
}
|
|
171
|
+
interface BevelEmbossEffect extends EffectBase {
|
|
172
|
+
kind: 'bevel-emboss';
|
|
173
|
+
style: BevelStyle;
|
|
174
|
+
technique: BevelTechnique;
|
|
175
|
+
/** 0..10 (1 = 100 %). */
|
|
176
|
+
depth: number;
|
|
177
|
+
direction: 'up' | 'down';
|
|
178
|
+
size: number;
|
|
179
|
+
soften: number;
|
|
180
|
+
angle: number;
|
|
181
|
+
/** Light altitude in degrees (0..90). */
|
|
182
|
+
altitude: number;
|
|
183
|
+
useGlobalLight: boolean;
|
|
184
|
+
glossContour?: EffectContour;
|
|
185
|
+
highlightColor: string;
|
|
186
|
+
highlightBlend: BlendMode;
|
|
187
|
+
highlightOpacity: number;
|
|
188
|
+
shadowColor: string;
|
|
189
|
+
shadowBlend: BlendMode;
|
|
190
|
+
shadowOpacity: number;
|
|
191
|
+
/** Contour element (shapes the bevel's height profile), or missing when off. */
|
|
192
|
+
contourElement?: BevelContour;
|
|
193
|
+
/** Texture element, or missing when off. */
|
|
194
|
+
texture?: BevelTexture;
|
|
195
|
+
}
|
|
196
|
+
interface SatinEffect extends EffectBase, Blended {
|
|
197
|
+
kind: 'satin';
|
|
198
|
+
color: string;
|
|
199
|
+
angle: number;
|
|
200
|
+
distance: number;
|
|
201
|
+
size: number;
|
|
202
|
+
contour?: EffectContour;
|
|
203
|
+
antiAlias: boolean;
|
|
204
|
+
invert: boolean;
|
|
205
|
+
}
|
|
206
|
+
interface ColorOverlayEffect extends EffectBase, Blended {
|
|
207
|
+
kind: 'color-overlay';
|
|
208
|
+
color: string;
|
|
209
|
+
}
|
|
210
|
+
interface GradientOverlayEffect extends EffectBase, Blended {
|
|
211
|
+
kind: 'gradient-overlay';
|
|
212
|
+
gradient: EffectGradient;
|
|
213
|
+
dither: boolean;
|
|
214
|
+
}
|
|
215
|
+
interface PatternOverlayEffect extends EffectBase, Blended, EffectPatternRef {
|
|
216
|
+
kind: 'pattern-overlay';
|
|
217
|
+
}
|
|
218
|
+
type StrokePosition = 'outside' | 'inside' | 'center';
|
|
219
|
+
interface StrokeEffect extends EffectBase, Blended {
|
|
220
|
+
kind: 'stroke';
|
|
221
|
+
size: number;
|
|
222
|
+
position: StrokePosition;
|
|
223
|
+
fill: EffectFill;
|
|
224
|
+
}
|
|
225
|
+
/** One layer effect. Several of the same kind are allowed; the first listed of a kind is on top. */
|
|
226
|
+
type LayerEffect = DropShadowEffect | InnerShadowEffect | OuterGlowEffect | InnerGlowEffect | BevelEmbossEffect | SatinEffect | ColorOverlayEffect | GradientOverlayEffect | PatternOverlayEffect | StrokeEffect;
|
|
227
|
+
type LayerEffectKind = LayerEffect['kind'];
|
|
228
|
+
/** A layer's effects: the master switch, Layer Style › Scale Effects and the effect list. */
|
|
229
|
+
interface LayerEffects {
|
|
230
|
+
/** The master switch ("effects on"); `false` keeps the effects but renders none. */
|
|
231
|
+
enabled: boolean;
|
|
232
|
+
/** Scale Effects: multiplies every size, distance and pattern scale (1 = 100 %; missing = 1). */
|
|
233
|
+
scale?: number;
|
|
234
|
+
items: LayerEffect[];
|
|
235
|
+
/**
|
|
236
|
+
* The PSD block the effects were read from (`lfx2`, `lfxs` or `lmfx`), kept so export writes it
|
|
237
|
+
* back verbatim while the effects still map to the same values. Export regenerates it otherwise.
|
|
238
|
+
*/
|
|
239
|
+
psd?: {
|
|
240
|
+
key: string;
|
|
241
|
+
data: Uint8Array;
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/** The document-wide light that effects with `useGlobalLight` use. */
|
|
245
|
+
interface GlobalLight {
|
|
246
|
+
/** Degrees. */
|
|
247
|
+
angle: number;
|
|
248
|
+
/** Degrees. */
|
|
249
|
+
altitude: number;
|
|
250
|
+
}
|
|
251
|
+
declare const DEFAULT_GLOBAL_LIGHT: GlobalLight;
|
|
252
|
+
/** Every effect kind, in the order the Layer Style dialog lists them. */
|
|
253
|
+
declare const LAYER_EFFECT_KINDS: readonly LayerEffectKind[];
|
|
254
|
+
declare function layerEffectLabel(kind: LayerEffectKind): string;
|
|
255
|
+
declare function isLayerEffectKind(value: unknown): value is LayerEffectKind;
|
|
256
|
+
/** Photoshop's default black-to-white linear gradient. */
|
|
257
|
+
declare function defaultEffectGradient(): EffectGradient;
|
|
258
|
+
/** A fresh effect id. */
|
|
259
|
+
declare function newEffectId(): string;
|
|
260
|
+
/** An effect of `kind` with Photoshop's default settings. */
|
|
261
|
+
declare function defaultLayerEffect(kind: LayerEffectKind, id?: string): LayerEffect;
|
|
262
|
+
/** True when the master switch is on and at least one effect is enabled. */
|
|
263
|
+
declare function hasActiveEffects(effects: LayerEffects | undefined | null): effects is LayerEffects;
|
|
264
|
+
/** Maximum distance (px) an effect is rendered from the layer's shape. */
|
|
265
|
+
declare const MAX_EFFECT_REACH = 512;
|
|
266
|
+
/** How far (px, before Scale Effects) one effect paints beyond or into the layer's shape. */
|
|
267
|
+
declare function effectReach(e: LayerEffect): number;
|
|
268
|
+
/**
|
|
269
|
+
* Pixels an effect stack can reach beyond the layer's shape (its enabled effects, scaled), plus
|
|
270
|
+
* a little slack. 0 when no effect is active. Dirty areas and tile signatures grow by this.
|
|
271
|
+
*/
|
|
272
|
+
declare function effectsMargin(effects: LayerEffects | undefined | null): number;
|
|
273
|
+
/** Scale Effects as a usable factor (missing or invalid = 1). */
|
|
274
|
+
declare function effectsScale(effects: Pick<LayerEffects, 'scale'>): number;
|
|
275
|
+
/** `effect` with its sizes, distances and pattern scales multiplied by `s` (Scale Effects). */
|
|
276
|
+
declare function scaleLayerEffect<E extends LayerEffect>(e: E, s: number): E;
|
|
277
|
+
/** `#rrggbb` (or `#rgb`, `rrggbb`) as 0..1 RGB, or `null`. */
|
|
278
|
+
declare function parseEffectColor(value: unknown): [number, number, number] | null;
|
|
279
|
+
/** 0..1 RGB as `#rrggbb`. */
|
|
280
|
+
declare function effectColorHex(rgb: readonly number[]): string;
|
|
281
|
+
declare class LayerEffectError extends Error {
|
|
282
|
+
constructor(message: string);
|
|
283
|
+
}
|
|
284
|
+
declare function validateEffectGradient(v: unknown, path: string): void;
|
|
285
|
+
/** Every field an effect of `kind` has (required and optional), including `id` and `kind`. */
|
|
286
|
+
declare function layerEffectFields(kind: LayerEffectKind): string[];
|
|
287
|
+
/**
|
|
288
|
+
* Checks a complete effect (every field of its kind present and in range). Throws a
|
|
289
|
+
* {@link LayerEffectError} naming the first wrong field and how to fix it.
|
|
290
|
+
*/
|
|
291
|
+
declare function validateLayerEffect(v: unknown, path?: string): asserts v is LayerEffect;
|
|
292
|
+
/**
|
|
293
|
+
* Applies `changes` to `effect` and validates the result. `kind` and `id` cannot change. Nested
|
|
294
|
+
* objects (`fill`, `gradient`, `contour`, `texture`, `phase`, `offset`) are replaced whole; `null`
|
|
295
|
+
* removes an optional one (`contour`, `glossContour`, bevel `contour` / `texture`).
|
|
296
|
+
*/
|
|
297
|
+
declare function mergeLayerEffect(effect: LayerEffect, changes: Record<string, unknown>): LayerEffect;
|
|
298
|
+
/** A layer's effects with `items` validated; throws on the first bad effect. */
|
|
299
|
+
declare function validateLayerEffects(v: unknown): asserts v is LayerEffects;
|
|
300
|
+
/**
|
|
301
|
+
* Reads effects from JSON leniently: invalid effects are dropped (so one bad entry does not lose
|
|
302
|
+
* a document), and missing optional fields take their defaults. `null` when nothing usable.
|
|
303
|
+
*/
|
|
304
|
+
declare function normalizeLayerEffects(raw: unknown): LayerEffects | undefined;
|
|
305
|
+
/** Effects without ids or the PSD block, for comparing what two effect stacks render. */
|
|
306
|
+
declare function effectsFingerprint(effects: LayerEffects | undefined | null): string;
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Pattern paint for pattern overlays, pattern strokes and bevel textures: a tile repeated over
|
|
310
|
+
* the plane from an origin (the layer's top-left when linked, else the canvas origin, plus the
|
|
311
|
+
* phase), scaled and rotated about it. Samples are bilinear and wrap around, on premultiplied
|
|
312
|
+
* colour, so whole-pixel placements at 100 % reproduce the tile exactly.
|
|
313
|
+
*
|
|
314
|
+
* Patterns come from the document (PSD pattern resources) or from the built-in set below, so a
|
|
315
|
+
* pattern effect always has something to paint even in a document without patterns.
|
|
316
|
+
*/
|
|
317
|
+
/** A pattern tile: straight-alpha RGBA. */
|
|
318
|
+
interface EffectPattern {
|
|
319
|
+
id: string;
|
|
320
|
+
name: string;
|
|
321
|
+
width: number;
|
|
322
|
+
height: number;
|
|
323
|
+
data: Uint8ClampedArray;
|
|
324
|
+
}
|
|
325
|
+
/** A pattern converted once for sampling (premultiplied 0..1). */
|
|
326
|
+
declare class PatternTile {
|
|
327
|
+
readonly w: number;
|
|
328
|
+
readonly h: number;
|
|
329
|
+
private readonly px;
|
|
330
|
+
constructor(p: Pick<EffectPattern, 'width' | 'height' | 'data'>);
|
|
331
|
+
/** Bilinear wrapping sample at tile coordinates (pixel centres at `i + 0.5`), straight alpha into `out`. */
|
|
332
|
+
sample(u: number, v: number, out: Float32Array | number[]): void;
|
|
333
|
+
}
|
|
334
|
+
/** Where a pattern sits: maps a document point to tile coordinates. */
|
|
335
|
+
declare class PatternPlacement {
|
|
336
|
+
private readonly ox;
|
|
337
|
+
private readonly oy;
|
|
338
|
+
private readonly c;
|
|
339
|
+
private readonly s;
|
|
340
|
+
private readonly inv;
|
|
341
|
+
/** `anchor`: the layer's top-left (used when `link`); `phase` in px; `scale` a fraction; `angle` degrees counter-clockwise. */
|
|
342
|
+
constructor(anchor: {
|
|
343
|
+
x: number;
|
|
344
|
+
y: number;
|
|
345
|
+
}, link: boolean, phase: {
|
|
346
|
+
x: number;
|
|
347
|
+
y: number;
|
|
348
|
+
}, scale: number, angle: number);
|
|
349
|
+
/** Tile coordinates of the document point `(x, y)` into `out[0..1]`. */
|
|
350
|
+
map(x: number, y: number, out: number[]): void;
|
|
351
|
+
}
|
|
352
|
+
/** Ids of the built-in patterns (`checker`, `stripes`, `dots`, `grid`, `noise`). */
|
|
353
|
+
declare function builtinPatternIds(): string[];
|
|
354
|
+
/** A built-in pattern by id, or `null`. */
|
|
355
|
+
declare function builtinPattern(id: string): EffectPattern | null;
|
|
356
|
+
/**
|
|
357
|
+
* Deterministic per-pixel value in 0..1 hashed from document coordinates, so effect noise is
|
|
358
|
+
* stable across renders and tiles (photocraft's `hash_noise`).
|
|
359
|
+
*/
|
|
360
|
+
declare function hashNoise(x: number, y: number): number;
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Resampling tiled surfaces through geometric maps: Free Transform (scale, rotate, skew, distort,
|
|
364
|
+
* perspective: one projective map) and Warp (any forward map, such as a Bézier mesh).
|
|
365
|
+
*
|
|
366
|
+
* - Inverse mapping per destination tile: each destination tile reads only the source window its
|
|
367
|
+
* pixels map into, so memory stays bounded by one tile's footprint, and the result is a new
|
|
368
|
+
* copy-on-write surface (an identity or a whole-pixel move returns the source, or shares its
|
|
369
|
+
* tiles).
|
|
370
|
+
* - Nearest, bilinear and Photoshop's Bicubic (the Keys cubic at a = −0.75). Colour is sampled
|
|
371
|
+
* premultiplied by alpha, so partially transparent edges don't pick up the colour of the
|
|
372
|
+
* transparent pixels around them; outside the source everything is transparent.
|
|
373
|
+
* - Large reductions with Bicubic are pre-filtered: the source is box-averaged by whole factors
|
|
374
|
+
* first and the cubic widened by the rest, so shrinking a layer doesn't alias. Bilinear and
|
|
375
|
+
* nearest sample the source directly, as Photoshop's do.
|
|
376
|
+
* - Masks (one channel) are warped as "value + inside": outside the source and outside the warped
|
|
377
|
+
* area they read as the surface's default value, so a reveal-all mask stays white around a
|
|
378
|
+
* transformed hole.
|
|
379
|
+
* - A Distort dragged past the horizon draws only the side of the horizon most of the source maps
|
|
380
|
+
* to (no mirrored copy wrapped round infinity).
|
|
381
|
+
*
|
|
382
|
+
* No DOM: runs in Node, tests and workers.
|
|
383
|
+
*/
|
|
384
|
+
|
|
385
|
+
/** Resampling of a transform (Photoshop's interpolation menu). */
|
|
386
|
+
type Interpolation = 'nearest' | 'bilinear' | 'bicubic';
|
|
387
|
+
declare const INTERPOLATIONS: readonly Interpolation[];
|
|
388
|
+
declare function isInterpolation(value: unknown): value is Interpolation;
|
|
389
|
+
/**
|
|
390
|
+
* The largest result (pixels) one resample may build: about 11 600 × 11 600. Only the size of the
|
|
391
|
+
* result counts, not where it lands. A scale past it is refused rather than clipped.
|
|
392
|
+
*/
|
|
393
|
+
declare const MAX_TRANSFORM_PIXELS: number;
|
|
394
|
+
/** A transform whose result would be too large; the message gives the size and the limit. */
|
|
395
|
+
declare class TransformTooLargeError extends Error {
|
|
396
|
+
constructor(message: string);
|
|
397
|
+
}
|
|
398
|
+
interface ResampleOptions {
|
|
399
|
+
/** Default `bicubic`. */
|
|
400
|
+
interpolation?: Interpolation;
|
|
401
|
+
/** The source region to transform (default: the surface's content bounds). Pixels outside it are not moved. */
|
|
402
|
+
source?: RasterRect;
|
|
403
|
+
/** Keep only destination pixels inside this rectangle (a preview of the visible area). */
|
|
404
|
+
clip?: RasterRect;
|
|
405
|
+
/**
|
|
406
|
+
* Preview speed-up: sample once per `step × step` block of destination pixels and fill the
|
|
407
|
+
* block (a power of two, 1..64; default 1, every pixel).
|
|
408
|
+
*/
|
|
409
|
+
step?: number;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Photoshop's Bicubic: the Keys cubic at a = −0.75 (Catmull-Rom is −0.5). Measured on Photoshop
|
|
413
|
+
* 27.11's Free Transform by photocraft: a 200 % step edge matches within 0.5 levels.
|
|
414
|
+
*/
|
|
415
|
+
declare function keysWeight(x: number): number;
|
|
416
|
+
/**
|
|
417
|
+
* The surface box-averaged by `factor` (a whole number ≥ 1) in both directions: reduced pixel
|
|
418
|
+
* (i, j) covers pixels [i·factor, (i+1)·factor) of each axis. For previews: transform the reduced
|
|
419
|
+
* surface through the map composed with a scale by `factor`, so a preview at a low zoom reads a
|
|
420
|
+
* fraction of the pixels.
|
|
421
|
+
*/
|
|
422
|
+
declare function reduceSurface(src: TiledSurface, factor: number): TiledSurface;
|
|
423
|
+
/** The destination rectangle `transformSurface` fills for `source` under `h`, or `null` when it is empty or unbounded. */
|
|
424
|
+
declare function transformedBounds(source: RasterRect, h: Homography): RasterRect | null;
|
|
425
|
+
/**
|
|
426
|
+
* The surface's content inside `options.source` (default: all of it) warped by `h` (source →
|
|
427
|
+
* destination, both in the surface's pixel space). Pixels outside the warped area are the default
|
|
428
|
+
* (transparent for layers). Throws `TransformTooLargeError` past `MAX_TRANSFORM_PIXELS`.
|
|
429
|
+
*/
|
|
430
|
+
declare function transformSurface(src: TiledSurface, h: Homography, options?: ResampleOptions): TiledSurface;
|
|
431
|
+
/**
|
|
432
|
+
* The surface's content inside `options.source` (default: all of it) warped through the forward
|
|
433
|
+
* map `f` (source → destination pixel space; `null` where it is undefined).
|
|
434
|
+
*
|
|
435
|
+
* The source rectangle is subdivided into a fine grid whose vertices are mapped forward; each
|
|
436
|
+
* cell's two triangles are rasterized in destination space with the source position interpolated
|
|
437
|
+
* barycentrically, then the source is sampled there. Cells are a few source pixels across, so the
|
|
438
|
+
* piecewise-affine inverse is within a small fraction of a pixel of the true one; affine maps (the
|
|
439
|
+
* identity included) are reproduced exactly. Where the warp shrinks the source, each pixel instead
|
|
440
|
+
* averages a grid of bilinear subsamples over its source footprint, so thin lines don't alias.
|
|
441
|
+
* Where the warp folds over itself the later (lower-right) cell wins.
|
|
442
|
+
*/
|
|
443
|
+
declare function warpSurface(src: TiledSurface, f: (p: Vec2) => Vec2 | null, options?: ResampleOptions): TiledSurface;
|
|
444
|
+
/**
|
|
445
|
+
* `top` (RGBA, straight alpha) composited over `base` with the Normal blend. A one-channel `base`
|
|
446
|
+
* (a mask) takes `top`'s red channel as the value, weighted by its alpha: that is how a moved part
|
|
447
|
+
* of a mask travels (value and coverage) and lands. Only tiles `top` stores are touched, so every
|
|
448
|
+
* other tile of `base` stays shared.
|
|
449
|
+
*/
|
|
450
|
+
declare function compositeSurfaceOver(base: TiledSurface, top: TiledSurface): TiledSurface;
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* A layer stack that is not specific to any editor: pixel layers on tiled surfaces, groups (with
|
|
454
|
+
* pass-through), raster masks with density and feather, clipping, locks, opacity, fill and blend
|
|
455
|
+
* modes, plus pure tree helpers. Editors extend these types with their own layer kinds (the image
|
|
456
|
+
* editor adds adjustment and annotation layers, filters and parametric masks).
|
|
457
|
+
*
|
|
458
|
+
* Layer objects are immutable: every change builds new objects along the path from the root to
|
|
459
|
+
* the changed layer and shares everything else.
|
|
460
|
+
*/
|
|
461
|
+
|
|
462
|
+
/** Blend modes of a layer; groups also accept `pass-through`. */
|
|
463
|
+
type GroupBlendMode = BlendMode | 'pass-through';
|
|
464
|
+
interface LayerLocks {
|
|
465
|
+
/** Painting and filling are refused. */
|
|
466
|
+
pixels?: boolean;
|
|
467
|
+
/** Painting keeps each pixel's alpha. */
|
|
468
|
+
transparency?: boolean;
|
|
469
|
+
/** Moving (offset) is refused. */
|
|
470
|
+
position?: boolean;
|
|
471
|
+
/** Everything above, plus property changes and deletion. */
|
|
472
|
+
all?: boolean;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* A layer mask: 8-bit coverage (255 reveals, 0 hides) on a tiled surface, plus non-destructive
|
|
476
|
+
* density and feather. `source` is an editor-defined parametric mask (generated instead of
|
|
477
|
+
* painted; the compositor asks its profile for the coverage, and the surface is unused).
|
|
478
|
+
*/
|
|
479
|
+
interface RasterMask<Source = unknown> {
|
|
480
|
+
surface: MaskSurface;
|
|
481
|
+
/** Value outside the painted tiles (PSD's default colour); equals `surface.defaultValue`. */
|
|
482
|
+
defaultValue: 0 | 255;
|
|
483
|
+
/** 0..1 (missing = 1): at 0.5 hidden areas still show half. */
|
|
484
|
+
density?: number;
|
|
485
|
+
/** Gaussian σ in pixels (missing = 0). */
|
|
486
|
+
feather?: number;
|
|
487
|
+
/** `false` keeps the mask but ignores it. */
|
|
488
|
+
enabled?: boolean;
|
|
489
|
+
/**
|
|
490
|
+
* `false` unlinks the mask from its layer (Photoshop's chain icon): moving or transforming the
|
|
491
|
+
* layer's pixels leaves the mask where it is. Missing = linked.
|
|
492
|
+
*/
|
|
493
|
+
linked?: boolean;
|
|
494
|
+
source?: Source;
|
|
495
|
+
}
|
|
496
|
+
interface RasterLayerBase {
|
|
497
|
+
id: string;
|
|
498
|
+
name: string;
|
|
499
|
+
visible: boolean;
|
|
500
|
+
/** 0..1 */
|
|
501
|
+
opacity: number;
|
|
502
|
+
blend: BlendMode;
|
|
503
|
+
/** Clip to the nearest unclipped layer below (Photoshop's clipping mask). */
|
|
504
|
+
clipped?: boolean;
|
|
505
|
+
mask?: RasterMask;
|
|
506
|
+
locks?: LayerLocks;
|
|
507
|
+
/** Live layer effects (drop shadow, stroke, …), rendered between the content and its blend. */
|
|
508
|
+
effects?: LayerEffects;
|
|
509
|
+
}
|
|
510
|
+
interface RasterPixelLayer extends RasterLayerBase {
|
|
511
|
+
type: 'pixel';
|
|
512
|
+
/** Pixels in layer space; document position = layer position + `offset`. A linked mask moves with it. */
|
|
513
|
+
surface: PixelSurface;
|
|
514
|
+
/** Integer move without re-tiling. */
|
|
515
|
+
offset: {
|
|
516
|
+
x: number;
|
|
517
|
+
y: number;
|
|
518
|
+
};
|
|
519
|
+
/** 0..1, PSD "Fill" (missing = 1). */
|
|
520
|
+
fillOpacity?: number;
|
|
521
|
+
}
|
|
522
|
+
interface RasterGroupLayer<L = RasterLayer> extends Omit<RasterLayerBase, 'blend'> {
|
|
523
|
+
type: 'group';
|
|
524
|
+
blend: GroupBlendMode;
|
|
525
|
+
/** Bottom to top. */
|
|
526
|
+
children: L[];
|
|
527
|
+
/** UI only. */
|
|
528
|
+
collapsed?: boolean;
|
|
529
|
+
}
|
|
530
|
+
/** The plain stack: pixel layers and groups. */
|
|
531
|
+
type RasterLayer = RasterPixelLayer | RasterGroupLayer<RasterLayer>;
|
|
532
|
+
/** What the tree helpers need of a layer: an id, a type, and `children` on groups. */
|
|
533
|
+
interface RasterNode {
|
|
534
|
+
id: string;
|
|
535
|
+
type: string;
|
|
536
|
+
}
|
|
537
|
+
/** The group members of a layer union. */
|
|
538
|
+
type GroupIn<T> = Extract<T, {
|
|
539
|
+
type: 'group';
|
|
540
|
+
}>;
|
|
541
|
+
interface LayerLocation<T extends RasterNode = RasterLayer> {
|
|
542
|
+
layer: T;
|
|
543
|
+
/** The containing group, or `null` at the top level. */
|
|
544
|
+
parent: GroupIn<T> | null;
|
|
545
|
+
/** Index within the parent's children (or the top-level list). */
|
|
546
|
+
index: number;
|
|
547
|
+
/** Ancestors from the top level down to the parent. */
|
|
548
|
+
path: GroupIn<T>[];
|
|
549
|
+
}
|
|
550
|
+
/** Every layer, depth first, bottom to top (a group comes before its children). */
|
|
551
|
+
declare function flattenLayers<T extends RasterNode>(layers: readonly T[]): T[];
|
|
552
|
+
declare function findLayer<T extends RasterNode>(layers: readonly T[], id: string): LayerLocation<T> | null;
|
|
553
|
+
/** Replaces the layer with `id` by `fn(layer)` (or removes it when `fn` returns `null`). */
|
|
554
|
+
declare function mapLayer<T extends RasterNode>(layers: readonly T[], id: string, fn: (layer: T) => T | null): T[];
|
|
555
|
+
/** Inserts `layer` into `parentId`'s children (or the top level) at `index` (default: top). */
|
|
556
|
+
declare function insertLayer<T extends RasterNode>(layers: readonly T[], layer: T, parentId: string | null, index?: number): T[];
|
|
557
|
+
declare function isLayerLocked(layer: {
|
|
558
|
+
locks?: LayerLocks;
|
|
559
|
+
}, what: keyof LayerLocks): boolean;
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* The per-tile layer compositor engine. Composites a layer stack (pixel layers and groups with
|
|
563
|
+
* masks, clipping, blend modes, opacity, fill and pass-through) tile by tile in document space,
|
|
564
|
+
* in pure TypeScript, so results are deterministic and testable in Node and Workers.
|
|
565
|
+
*
|
|
566
|
+
* Editors add their own layer kinds through a {@link CompositorProfile}: layers that filter
|
|
567
|
+
* what is below them (adjustment layers), content layers drawn by the editor (annotations),
|
|
568
|
+
* per-layer pixel filters, and parametric mask sources.
|
|
569
|
+
*
|
|
570
|
+
* Caches:
|
|
571
|
+
* - Each top-level *step* (a content layer and the layers clipped to it, a run of filter layers,
|
|
572
|
+
* a group) has a per-tile *signature*: its properties plus the identity of every surface tile
|
|
573
|
+
* it reads. A tile whose signatures are unchanged returns the cached result (same buffer
|
|
574
|
+
* object, so callers can skip uploading it).
|
|
575
|
+
* - A prefix cache keeps the accumulator *before* the step that changed last time (and, when the
|
|
576
|
+
* caller names it, before the active layer). Dragging a slider on layer k, or a stroke on layer
|
|
577
|
+
* k, recomposites from step k upwards only; `dirty` rectangles limit that to where it changed.
|
|
578
|
+
* - Spatial filters and feathered or parametric masks are computed once over the canvas and
|
|
579
|
+
* cached by the identity of their inputs.
|
|
580
|
+
* - Layer effects: a layer's effect maps (shadow, glow, bevel, stroke distance fields) are built
|
|
581
|
+
* once over the layer's region (its bounds grown by the effects' margin, within the canvas grown
|
|
582
|
+
* the same) and cached by the identity of every surface tile the shape reads; tiles crop them.
|
|
583
|
+
* When only some of those tiles changed and every effect is local, the maps are rebuilt only
|
|
584
|
+
* within the margin of the change (narrowed by `dirty` when it covers the change) and patched in.
|
|
585
|
+
* A tile's signature then reads the layer within the margin around it (or the whole region when
|
|
586
|
+
* an effect is laid out over the layer's bounds), and `dirty` rectangles grow by the margin.
|
|
587
|
+
*/
|
|
588
|
+
|
|
589
|
+
/** What the compositor needs from its host besides the layers. */
|
|
590
|
+
interface RasterSources {
|
|
591
|
+
/** Canvas (document) size: spatial filters and mask feathering clamp at this rect. */
|
|
592
|
+
width: number;
|
|
593
|
+
height: number;
|
|
594
|
+
/** The pixels of a pixel layer (lets a host resolve layers whose pixels live elsewhere). */
|
|
595
|
+
surfaceOf?(layer: CompositorLayer): PixelSurface;
|
|
596
|
+
/** Changes whenever one of the host's callbacks would return something new for the same layers. */
|
|
597
|
+
version?: number | string;
|
|
598
|
+
/** The document's global light for effects that use it (default angle 120°, altitude 30°). */
|
|
599
|
+
globalLight?: GlobalLight;
|
|
600
|
+
/** A document pattern by id for pattern effects (built-in patterns are found without it). */
|
|
601
|
+
pattern?(id: string): EffectPattern | null;
|
|
602
|
+
}
|
|
603
|
+
/** The fields the engine reads; editor layer types are wider. */
|
|
604
|
+
interface CompositorLayer extends RasterNode {
|
|
605
|
+
visible: boolean;
|
|
606
|
+
opacity: number;
|
|
607
|
+
blend: string;
|
|
608
|
+
clipped?: boolean;
|
|
609
|
+
mask?: RasterMask;
|
|
610
|
+
/** Pixel layers. */
|
|
611
|
+
surface?: PixelSurface;
|
|
612
|
+
offset?: {
|
|
613
|
+
x: number;
|
|
614
|
+
y: number;
|
|
615
|
+
};
|
|
616
|
+
fillOpacity?: number;
|
|
617
|
+
/** Layer effects. */
|
|
618
|
+
effects?: LayerEffects;
|
|
619
|
+
/** Groups. */
|
|
620
|
+
children?: readonly CompositorLayer[];
|
|
621
|
+
}
|
|
622
|
+
/** A pixel layer's filters as the engine runs them. */
|
|
623
|
+
interface PixelFilterSpec {
|
|
624
|
+
/** Identifies the settings (part of the cache key). */
|
|
625
|
+
key: string;
|
|
626
|
+
/** Needs neighbouring pixels: runs once over the canvas instead of per tile. */
|
|
627
|
+
spatial: boolean;
|
|
628
|
+
/** Filters RGBA `data` (`width × height`) in place. */
|
|
629
|
+
apply(data: Uint8ClampedArray, width: number, height: number): void;
|
|
630
|
+
}
|
|
631
|
+
/** How an editor's own layer kinds composite. Every hook is optional. */
|
|
632
|
+
interface CompositorProfile<L extends CompositorLayer, S extends RasterSources> {
|
|
633
|
+
/** Layers that change what is below them; adjacent ones run as one step. */
|
|
634
|
+
isFilterLayer?(layer: L): boolean;
|
|
635
|
+
/** Applies a run of visible filter layers to `acc` (RGBA over `r`); `coverage` holds masked ones by id. */
|
|
636
|
+
applyFilterRun?(layers: L[], acc: Uint8ClampedArray, r: RasterRect, coverage: Map<string, Float32Array> | undefined, sources: S): void;
|
|
637
|
+
/** RGBA of a content layer that is neither a pixel layer nor a group, over `r`, or `null`. */
|
|
638
|
+
contentTile?(layer: L, r: RasterRect, sources: S): Uint8ClampedArray | null;
|
|
639
|
+
/** The blend mode a content layer draws with (default `layer.blend`). */
|
|
640
|
+
contentBlend?(layer: L): BlendMode;
|
|
641
|
+
/** Properties of a layer beyond the generic ones that change its pixels (part of its signature). */
|
|
642
|
+
layerKey?(layer: L): unknown;
|
|
643
|
+
/** Active filters of a pixel layer, or `null`. */
|
|
644
|
+
pixelFilters?(layer: L): PixelFilterSpec | null;
|
|
645
|
+
/** Canvas coverage (0..1, `width × height`) of a parametric mask source, or `null` to reveal all. */
|
|
646
|
+
maskSourcePlane?(source: unknown, width: number, height: number, sources: S): Float32Array | null;
|
|
647
|
+
/**
|
|
648
|
+
* Layer kinds besides `pixel` that composite exactly like pixel layers, from their `surface`,
|
|
649
|
+
* `offset` and `fillOpacity` (a smart object's rendered pixels). Their tile signatures, effect
|
|
650
|
+
* regions and `dirty` handling are a pixel layer's.
|
|
651
|
+
*/
|
|
652
|
+
isPixelLike?(layer: L): boolean;
|
|
653
|
+
}
|
|
654
|
+
interface CompositorOptions {
|
|
655
|
+
/** Upper bound for cached tile buffers (default 256 MiB). */
|
|
656
|
+
maxCacheBytes?: number;
|
|
657
|
+
}
|
|
658
|
+
interface CompositeCallOptions {
|
|
659
|
+
/**
|
|
660
|
+
* The layer about to be edited (the active layer): every tile composited in this call keeps a
|
|
661
|
+
* checkpoint below its step, so strokes and slider drags on it start there.
|
|
662
|
+
*/
|
|
663
|
+
checkpointLayerId?: string | null;
|
|
664
|
+
/**
|
|
665
|
+
* Where the layers changed since the previous call, when the caller knows (a stroke's dabs).
|
|
666
|
+
* Changed tiles are then recomposited only inside these rectangles (grown by the effects' reach),
|
|
667
|
+
* tiles they miss keep their pixels, and effect maps are rebuilt only around them. Changes outside
|
|
668
|
+
* them would be missed, so pass nothing when unsure.
|
|
669
|
+
*/
|
|
670
|
+
dirty?: RasterRect[];
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Blends straight-alpha `src` over `dst` (both RGBA) in place with `mode`, scaling the source
|
|
674
|
+
* alpha by `alpha` and, per pixel, by `coverage`. Same maths as `blendPixel` (including the
|
|
675
|
+
* `pigment` paint mix, which caches each 8-bit colour's spectrum).
|
|
676
|
+
*/
|
|
677
|
+
declare function blendTile(dst: Uint8ClampedArray, src: ArrayLike<number>, mode: BlendMode, alpha: number, coverage: ArrayLike<number> | null): void;
|
|
678
|
+
/** Statistics of the last `composite` call (for benchmarks and tests). */
|
|
679
|
+
interface CompositeStats {
|
|
680
|
+
tiles: number;
|
|
681
|
+
/** Tiles returned straight from the cache. */
|
|
682
|
+
cached: number;
|
|
683
|
+
/** Steps actually run, summed over tiles. */
|
|
684
|
+
stepsRun: number;
|
|
685
|
+
/** Layers whose effect maps were built over their whole region. */
|
|
686
|
+
effectsBuilt: number;
|
|
687
|
+
/** Layers whose effect maps were rebuilt only around a change and patched in. */
|
|
688
|
+
effectsPatched: number;
|
|
689
|
+
}
|
|
690
|
+
declare class RasterCompositor<L extends CompositorLayer = CompositorLayer, S extends RasterSources = RasterSources> {
|
|
691
|
+
private readonly profile;
|
|
692
|
+
private readonly tiles;
|
|
693
|
+
private readonly maxCacheBytes;
|
|
694
|
+
private cacheBytes;
|
|
695
|
+
private stamp;
|
|
696
|
+
private sources;
|
|
697
|
+
private sourcesVersion;
|
|
698
|
+
private filteredCache;
|
|
699
|
+
private planeCache;
|
|
700
|
+
private planeIds;
|
|
701
|
+
private nextPlaneId;
|
|
702
|
+
private contentCache;
|
|
703
|
+
private readonly stepsCache;
|
|
704
|
+
private readonly propsKeyCache;
|
|
705
|
+
/** Effect maps by layer id (see the module comment), least recently used first. */
|
|
706
|
+
private effectCache;
|
|
707
|
+
/** Effect maps already validated in this call, by layer object. */
|
|
708
|
+
private effectMemo;
|
|
709
|
+
private readonly patternTiles;
|
|
710
|
+
private readonly reachCache;
|
|
711
|
+
private fxContext;
|
|
712
|
+
lastStats: CompositeStats;
|
|
713
|
+
private hint;
|
|
714
|
+
/** The `dirty` rectangles of the current call, as passed. */
|
|
715
|
+
private callDirty;
|
|
716
|
+
private callStats;
|
|
717
|
+
constructor(profile?: CompositorProfile<L, S>, options?: CompositorOptions);
|
|
718
|
+
/** Drops every cached tile and plane. */
|
|
719
|
+
clear(): void;
|
|
720
|
+
private setSources;
|
|
721
|
+
/** The composite of `layers` over `rect` as `rect.width × rect.height` RGBA (straight alpha). */
|
|
722
|
+
composite(layers: readonly L[], rect: RasterRect, sources: S, options?: CompositeCallOptions): Uint8ClampedArray;
|
|
723
|
+
/**
|
|
724
|
+
* Composites every tile intersecting `rect` and calls `onTile` with each tile's RGBA buffer
|
|
725
|
+
* (TILE × TILE). A tile whose inputs did not change since the last call returns the same buffer
|
|
726
|
+
* object; never mutate it.
|
|
727
|
+
*/
|
|
728
|
+
compositeTiles(layers: readonly L[], rect: RasterRect, sources: S, onTile: (tx: number, ty: number, data: Uint8ClampedArray, changed: boolean) => void, options?: CompositeCallOptions): void;
|
|
729
|
+
/** The composite of one tile (cached; do not mutate the result). */
|
|
730
|
+
tile(layers: readonly L[], tx: number, ty: number, sources: S): Uint8ClampedArray;
|
|
731
|
+
/**
|
|
732
|
+
* A layer's effective mask coverage (0..1, after density, feather or parametric evaluation)
|
|
733
|
+
* over `r` in document space, or `null` when it reveals all of `r`.
|
|
734
|
+
*/
|
|
735
|
+
maskCoverage(layer: L, r: RasterRect, sources: S): Float32Array | null;
|
|
736
|
+
/** Pixel layers, and the layer kinds the profile composites like them. */
|
|
737
|
+
private isPixel;
|
|
738
|
+
private isFilter;
|
|
739
|
+
/**
|
|
740
|
+
* Groups a layer list into compositing steps: clipped layers join the nearest unclipped
|
|
741
|
+
* content or group layer below; consecutive unclipped filter layers form one run.
|
|
742
|
+
*/
|
|
743
|
+
private buildSteps;
|
|
744
|
+
/** The index of the top-level step that holds layer `id` (searching groups and clipped layers), or -1. */
|
|
745
|
+
private stepIndexOf;
|
|
746
|
+
/** Properties of a layer that change pixels, minus its surfaces (memoised per object). */
|
|
747
|
+
private propsKey;
|
|
748
|
+
private compositeTile;
|
|
749
|
+
/**
|
|
750
|
+
* Whether a tile with no part in this call's (grown) `dirty` rectangles changed only in what local
|
|
751
|
+
* effects read beyond it: every changed step is a pixel layer with local effects whose changes stay
|
|
752
|
+
* inside `dirty` (and so are farther than its margin), which leaves the tile's pixels as they were.
|
|
753
|
+
*/
|
|
754
|
+
private changedOnlyNearby;
|
|
755
|
+
private entryBytes;
|
|
756
|
+
private evict;
|
|
757
|
+
private stepSig;
|
|
758
|
+
private layerSig;
|
|
759
|
+
private groupSig;
|
|
760
|
+
private plainGroupSig;
|
|
761
|
+
private contentSig;
|
|
762
|
+
private plainContentSig;
|
|
763
|
+
private hasEffects;
|
|
764
|
+
/** The largest effects margin of any visible layer in the stack (memoised per root). */
|
|
765
|
+
private effectsReach;
|
|
766
|
+
private effectContext;
|
|
767
|
+
/**
|
|
768
|
+
* Where a layer's effect maps are built: its bounds (pixel layers; the canvas otherwise) grown by
|
|
769
|
+
* the effects' margin, within the canvas grown the same.
|
|
770
|
+
*/
|
|
771
|
+
private effectRegion;
|
|
772
|
+
/** The signature of a layer's shape (its surface tiles and mask refs) per tile of `region`. */
|
|
773
|
+
private shapeSigs;
|
|
774
|
+
/** The surface tiles (and mask refs) a layer's shape reads over `region`. */
|
|
775
|
+
private shapeRefs;
|
|
776
|
+
private lightKey;
|
|
777
|
+
/**
|
|
778
|
+
* The signature of a layer with effects for tile (tx, ty): its properties and the tiles its shape
|
|
779
|
+
* reads within the effects' margin around the tile, or over its whole region when an effect is
|
|
780
|
+
* laid out over the layer's bounds.
|
|
781
|
+
*/
|
|
782
|
+
private effectSig;
|
|
783
|
+
/** A layer's effect maps over its region (cached; see the module comment). */
|
|
784
|
+
private effectMapsOf;
|
|
785
|
+
/**
|
|
786
|
+
* Where a layer's shape may differ from the one `prev` was built from: the tiles whose signature
|
|
787
|
+
* changed (a tile new to the region that reads nothing did not), narrowed to this call's `dirty`
|
|
788
|
+
* rectangles when `prev` is from the previous call and they cover every change of the shape.
|
|
789
|
+
*/
|
|
790
|
+
private shapeChanges;
|
|
791
|
+
/**
|
|
792
|
+
* Whether a change to a layer stays inside the `dirty` rectangles that name it: a pixel layer
|
|
793
|
+
* without filters or a feathered or parametric mask (those spread a change beyond it).
|
|
794
|
+
*/
|
|
795
|
+
private dirtyCoversShape;
|
|
796
|
+
/** A layer's alpha over `r` after its mask (0..1, quantised to bytes as tiles see it). */
|
|
797
|
+
private layerShape;
|
|
798
|
+
/** A content or group layer's own pixels over `r` with its mask applied to alpha, or `null` when empty. */
|
|
799
|
+
private ownPixels;
|
|
800
|
+
/**
|
|
801
|
+
* The part of `r` a layer with effects can change: its shape's bounds grown by the effects'
|
|
802
|
+
* margin. Beyond it the layer and every effect are transparent, so the backdrop stays as it is.
|
|
803
|
+
*/
|
|
804
|
+
private effectArea;
|
|
805
|
+
/**
|
|
806
|
+
* Composites `layer`'s pixels (with `clipped` applied) and its effects onto `acc` (RGBA over `r`),
|
|
807
|
+
* only where they can reach. `keepAlpha`: clipped layers keep the base's alpha.
|
|
808
|
+
*/
|
|
809
|
+
private compositeEffects;
|
|
810
|
+
/** Composites a layer with active effects onto `acc` over `r`; returns whether `acc` is still empty. */
|
|
811
|
+
private runEffectStep;
|
|
812
|
+
private maskRefs;
|
|
813
|
+
/**
|
|
814
|
+
* A pixel layer's pixels after spatial filters: the surface and the offset to apply. Layers
|
|
815
|
+
* with a spatial filter are filtered once over the canvas (in document space, offset 0).
|
|
816
|
+
*/
|
|
817
|
+
private layerPixels;
|
|
818
|
+
/** RGBA of a content layer over `r` (document space, inside one tile), or `null` when it has nothing there. */
|
|
819
|
+
private contentTile;
|
|
820
|
+
private planeKey;
|
|
821
|
+
/** Canvas-sized coverage of a feathered or parametric mask (cached). */
|
|
822
|
+
private planeFor;
|
|
823
|
+
private maskTile;
|
|
824
|
+
/** Runs one step onto `acc`; returns whether `acc` is still empty. */
|
|
825
|
+
private runStep;
|
|
826
|
+
private runSteps;
|
|
827
|
+
private contentBlend;
|
|
828
|
+
private blendOnto;
|
|
829
|
+
private applyClipped;
|
|
830
|
+
private applyFilterRun;
|
|
831
|
+
}
|
|
832
|
+
/** Tiles that differ between two surfaces (by tile identity), as tile keys. */
|
|
833
|
+
declare function changedTiles(a: TiledSurface, b: TiledSurface): TileKey[];
|
|
834
|
+
|
|
835
|
+
export { TransformTooLargeError as $, type GradientColorStop as A, type BevelContour as B, type CompositorLayer as C, DEFAULT_GLOBAL_LIGHT as D, type EffectPattern as E, type GradientOpacityStop as F, type GroupBlendMode as G, type GradientOverlayEffect as H, type Interpolation as I, type GradientStyle as J, INTERPOLATIONS as K, type LayerLocks as L, type InnerGlowEffect as M, type InnerShadowEffect as N, LAYER_EFFECT_KINDS as O, LayerEffectError as P, MAX_EFFECT_REACH as Q, type RasterLayer as R, MAX_TRANSFORM_PIXELS as S, type OuterGlowEffect as T, type PatternOverlayEffect as U, PatternPlacement as V, PatternTile as W, type ResampleOptions as X, type SatinEffect as Y, type StrokeEffect as Z, type StrokePosition as _, type RasterGroupLayer as a, blendTile as a0, builtinPattern as a1, builtinPatternIds as a2, changedTiles as a3, compositeSurfaceOver as a4, defaultEffectGradient as a5, defaultLayerEffect as a6, effectColorHex as a7, effectReach as a8, effectsFingerprint as a9, type CompositorProfile as aA, type GroupIn as aB, type PixelFilterSpec as aC, type RasterNode as aD, effectsMargin as aa, effectsScale as ab, findLayer as ac, flattenLayers as ad, hasActiveEffects as ae, hashNoise as af, insertLayer as ag, isInterpolation as ah, isLayerEffectKind as ai, isLayerLocked as aj, keysWeight as ak, layerEffectFields as al, layerEffectLabel as am, mapLayer as an, mergeLayerEffect as ao, newEffectId as ap, normalizeLayerEffects as aq, parseEffectColor as ar, reduceSurface as as, scaleLayerEffect as at, transformSurface as au, transformedBounds as av, validateEffectGradient as aw, validateLayerEffect as ax, validateLayerEffects as ay, warpSurface as az, type RasterPixelLayer as b, RasterCompositor as c, type RasterSources as d, type RasterLayerBase as e, type RasterMask as f, type GlobalLight as g, type LayerLocation as h, type LayerEffect as i, type LayerEffects as j, type CompositorOptions as k, type LayerEffectKind as l, type BevelEmbossEffect as m, type BevelStyle as n, type BevelTechnique as o, type BevelTexture as p, type ColorOverlayEffect as q, type CompositeCallOptions as r, type CompositeStats as s, type ContourPoint as t, type DropShadowEffect as u, type EffectContour as v, type EffectFill as w, type EffectGradient as x, type EffectPatternRef as y, type GlowTechnique as z };
|