@pixerate/editor 0.115.0 → 0.117.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/animation-editor/index.cjs +54 -54
- package/dist/animation-editor/index.d.cts +2 -2
- package/dist/animation-editor/index.d.ts +2 -2
- package/dist/animation-editor/index.js +2 -2
- package/dist/{chunk-I7FQBWMQ.cjs → chunk-2J3LS7JZ.cjs} +333 -333
- package/dist/{chunk-I7FQBWMQ.cjs.map → chunk-2J3LS7JZ.cjs.map} +1 -1
- package/dist/{chunk-TFOPHZ3U.cjs → chunk-7ISPWEJA.cjs} +302 -5
- package/dist/chunk-7ISPWEJA.cjs.map +1 -0
- package/dist/{chunk-VXR7XWMF.js → chunk-7LNZAWSJ.js} +437 -41
- package/dist/chunk-7LNZAWSJ.js.map +1 -0
- package/dist/{chunk-DFQEX3AM.cjs → chunk-BYAWOAST.cjs} +223 -30
- package/dist/chunk-BYAWOAST.cjs.map +1 -0
- package/dist/chunk-COAMRKVI.cjs +159 -0
- package/dist/chunk-COAMRKVI.cjs.map +1 -0
- package/dist/{chunk-ST7E3NEE.cjs → chunk-EBSYZRSW.cjs} +230 -732
- package/dist/chunk-EBSYZRSW.cjs.map +1 -0
- package/dist/chunk-EJVDBITD.cjs +501 -0
- package/dist/chunk-EJVDBITD.cjs.map +1 -0
- package/dist/{chunk-LPLCWZTM.cjs → chunk-FODKPD44.cjs} +555 -159
- package/dist/chunk-FODKPD44.cjs.map +1 -0
- package/dist/{chunk-XK5LZKBD.js → chunk-HKDTM6VC.js} +298 -1
- package/dist/chunk-HKDTM6VC.js.map +1 -0
- package/dist/chunk-IPFRWILU.js +1908 -0
- package/dist/chunk-IPFRWILU.js.map +1 -0
- package/dist/chunk-IVSNUXW7.js +3339 -0
- package/dist/chunk-IVSNUXW7.js.map +1 -0
- package/dist/{chunk-LKCYANMW.js → chunk-JHXMNOMF.js} +198 -5
- package/dist/chunk-JHXMNOMF.js.map +1 -0
- package/dist/{chunk-FV5AXTSF.cjs → chunk-JSSBHMMU.cjs} +36 -188
- package/dist/chunk-JSSBHMMU.cjs.map +1 -0
- package/dist/chunk-L2T6EJ5S.cjs +3339 -0
- package/dist/chunk-L2T6EJ5S.cjs.map +1 -0
- package/dist/chunk-LF4WOZXZ.js +159 -0
- package/dist/chunk-LF4WOZXZ.js.map +1 -0
- package/dist/{chunk-26PGXHY7.cjs → chunk-M7O4BJRH.cjs} +36 -36
- package/dist/{chunk-26PGXHY7.cjs.map → chunk-M7O4BJRH.cjs.map} +1 -1
- package/dist/chunk-N3467VD6.js +501 -0
- package/dist/chunk-N3467VD6.js.map +1 -0
- package/dist/{chunk-XICA4PVO.js → chunk-R2JE6SA7.js} +17 -17
- package/dist/chunk-SMJGE7HM.cjs +1908 -0
- package/dist/chunk-SMJGE7HM.cjs.map +1 -0
- package/dist/{chunk-MMVHBKMM.js → chunk-T2P5TIZ6.js} +2 -2
- package/dist/{chunk-C6C5PDKU.js → chunk-VD2UDVF7.js} +102 -604
- package/dist/chunk-VD2UDVF7.js.map +1 -0
- package/dist/{chunk-FGW5OWJ4.js → chunk-VJUML33I.js} +4 -156
- package/dist/chunk-VJUML33I.js.map +1 -0
- package/dist/export/index.cjs +4 -2
- package/dist/export/index.cjs.map +1 -1
- package/dist/export/index.js +5 -3
- package/dist/{export-BJE8T0YA.d.cts → export-DMOuzgZZ.d.cts} +9 -4
- package/dist/{export-Con3UKkm.d.ts → export-Dul1SbPv.d.ts} +9 -4
- package/dist/export-Dv0-ZVrV.d.cts +501 -0
- package/dist/export-Dv0-ZVrV.d.ts +501 -0
- package/dist/{retouch-Bxkuc0KH.d.cts → flow-4-OC-UkQ.d.cts} +582 -2
- package/dist/{retouch-Do6tBs2H.d.ts → flow-Cb7lkPm8.d.ts} +582 -2
- package/dist/image-editor/index.cjs +1345 -1095
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +8 -8
- package/dist/image-editor/index.d.ts +8 -8
- package/dist/image-editor/index.js +300 -50
- package/dist/image-editor/index.js.map +1 -1
- package/dist/index.cjs +4 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/kernel-wasm-WYCGNZR4.js +10 -0
- package/dist/kernel-wasm-WYCGNZR4.js.map +1 -0
- package/dist/kernel-wasm-YPVAEMVN.cjs +10 -0
- package/dist/kernel-wasm-YPVAEMVN.cjs.map +1 -0
- package/dist/paint/index.cjs +170 -4
- package/dist/paint/index.cjs.map +1 -1
- package/dist/paint/index.d.cts +225 -3
- package/dist/paint/index.d.ts +225 -3
- package/dist/paint/index.js +171 -5
- package/dist/paint-editor/index.cjs +4735 -890
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +1526 -278
- package/dist/paint-editor/index.d.ts +1526 -278
- package/dist/paint-editor/index.js +4561 -716
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/raster/index.cjs +7 -4
- package/dist/raster/index.cjs.map +1 -1
- package/dist/raster/index.d.cts +2 -2
- package/dist/raster/index.d.ts +2 -2
- package/dist/raster/index.js +36 -33
- package/dist/{render-CrmHOgpo.d.ts → render-B05K68_h.d.ts} +9 -1
- package/dist/{render-B1K_OoLy.d.cts → render-DnAbIKcs.d.cts} +9 -1
- package/dist/{svg-BnRj0q8i.d.cts → svg-CVdFc80-.d.cts} +2 -2
- package/dist/{svg-CmmBFfGT.d.ts → svg-DlEuhwoX.d.ts} +2 -2
- package/dist/{types-1SUQKDAw.d.ts → types-CDLGhAZp.d.ts} +40 -2
- package/dist/{types-yINF17Ta.d.cts → types-Tfly4Aya.d.cts} +40 -2
- package/dist/vector/index.cjs +6536 -4525
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +426 -32
- package/dist/vector/index.d.ts +426 -32
- package/dist/vector/index.js +11397 -9386
- package/dist/vector/index.js.map +1 -1
- package/dist/video-editor/index.cjs +502 -2165
- package/dist/video-editor/index.cjs.map +1 -1
- package/dist/video-editor/index.d.cts +3 -501
- package/dist/video-editor/index.d.ts +3 -501
- package/dist/video-editor/index.js +151 -1814
- package/dist/video-editor/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/pixerate-image-editor/references/photoshop-files.md +7 -3
- package/skills/pixerate-vector/SKILL.md +3 -0
- package/dist/chunk-C6C5PDKU.js.map +0 -1
- package/dist/chunk-DFQEX3AM.cjs.map +0 -1
- package/dist/chunk-FGW5OWJ4.js.map +0 -1
- package/dist/chunk-FV5AXTSF.cjs.map +0 -1
- package/dist/chunk-GX332W2C.js +0 -181
- package/dist/chunk-GX332W2C.js.map +0 -1
- package/dist/chunk-LKCYANMW.js.map +0 -1
- package/dist/chunk-LPLCWZTM.cjs.map +0 -1
- package/dist/chunk-MUUXNRU4.cjs +0 -181
- package/dist/chunk-MUUXNRU4.cjs.map +0 -1
- package/dist/chunk-ST7E3NEE.cjs.map +0 -1
- package/dist/chunk-TCKIXI46.cjs +0 -1136
- package/dist/chunk-TCKIXI46.cjs.map +0 -1
- package/dist/chunk-TFOPHZ3U.cjs.map +0 -1
- package/dist/chunk-UBIXVXPR.js +0 -1136
- package/dist/chunk-UBIXVXPR.js.map +0 -1
- package/dist/chunk-VXR7XWMF.js.map +0 -1
- package/dist/chunk-XK5LZKBD.js.map +0 -1
- /package/dist/{chunk-XICA4PVO.js.map → chunk-R2JE6SA7.js.map} +0 -0
- /package/dist/{chunk-MMVHBKMM.js.map → chunk-T2P5TIZ6.js.map} +0 -0
package/dist/paint/index.d.cts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
1
|
+
import { at as PaintMedium, W as WetWorld, au as PaintSample, n as RgbTriple, B as BrushSettings, C as CoverageMap, D as Dab } from '../flow-4-OC-UkQ.cjs';
|
|
2
|
+
export { F as BlenderScratch, i as BlenderSettings, G as DEFAULT_BLENDER, H as DEFAULT_BRUSH, s as DEFAULT_FLOW, I as DEFAULT_MIXER, J as DEFAULT_RETOUCH, K as DEFAULT_SMUDGE, L as DEFAULT_WET_PAPER, t as DEFAULT_WET_PARAMS, N as DRY_EPS, O as DabWalker, Q as EMPTY_MIXER_LOAD, U as EX, V as EY, X as ExchangeRates, Y as FLAG_ALIVE, Z as FLAG_BOTTOM, _ as FLAG_LEFT, $ as FLAG_RIGHT, a0 as FLAG_TOP, a1 as FLAG_WET, a2 as FLAT, a3 as FREE_INTERVAL, a4 as MAX_BATCH, u as MAX_BRUSH_SIZE, a5 as MAX_TILT_ACCEL, a6 as MAX_WET_LANES, a7 as MAX_WET_SLOTS, a8 as MIXER_DRAIN, a9 as MIXER_PICKUP_RATE, aa as MIXING_MODELS, a as MixerLoad, M as MixerSettings, c as MixerStroke, b as MixerTarget, h as MixingModel, ab as OPP, ac as PAPER_CAPACITY, ad as PARAM, ae as PARAM_FLOATS, af as PIGMENT_CHANNELS, ag as PLANE, ah as PLANE_BYTES, ai as P_D0, aj as P_EDGE, ak as P_FX, al as P_FY, am as P_H, an as P_P0, ao as P_RHO, ap as P_SW, aq as P_UX, ar as P_UY, as as PaintExchange, P as PaintTileTarget, av as PixelSource, aw as RETOUCH_SAMPLES, ax as RegionPixelSource, d as RetouchApply, ay as RetouchDabEffect, az as RetouchDabStroke, f as RetouchPaint, aA as RetouchSample, R as RetouchSettings, aB as SET_PLANES, aC as SLOT_BYTES, aD as SLOT_PLANES, aE as SLOT_SIDE, aF as SPOT_HEAL_TYPES, aG as STRIP, aH as SmudgeDab, j as SmudgeSettings, aI as SmudgeTip, aJ as SpotHealType, g as StrokeApply, S as StrokeCoverage, e as StrokePoint, aK as TONE_RANGES, T as TileMedium, aL as TileMediumOptions, aM as TilePixelSource, aN as ToneRange, aO as U_MAX, aP as W9, v as WET_FLOW_KINDS, w as WET_PARAM_KEYS, aQ as WET_TILE, p as WetBackendInfo, aR as WetFlowField, x as WetFlowKind, m as WetFlowSpec, aS as WetKernelKind, aT as WetLaneOptions, aU as WetLaneStats, aV as WetPaper, r as WetPaperInput, l as WetParams, q as WetSnapshot, y as WetSupport, k as WetTilt, aW as WetWorkerLayout, aX as WetWorkerPool, aY as WetWorldError, o as WetWorldOptions, aZ as applyRetouchToTile, a_ as applyStrokeToDeepTile, a$ as applyStrokeToTile, b0 as applyToneToDeepTile, b1 as blendRadius, b2 as blenderDab, b3 as canShareMemory, b4 as cleanMixer, b5 as coverageTileCoord, b6 as createBlenderScratch, b7 as dabCoverage, b8 as dabRect, b9 as dodgeBurn, ba as dodgeBurnCurve, bb as dsincos, bc as edgeBits, bd as exchangeRates, be as flowField, bf as healPixels, bg as latticeViscosity, bh as loadMixer, bi as loadWetKernel, bj as luma, bk as mixerRates, bl as normalizeBlender, bm as normalizeBrush, z as normalizeFlow, bn as normalizeMixer, bo as normalizeRetouch, bp as normalizeSmudge, bq as normalizeTilt, A as normalizeWetParams, br as packWetParams, bs as perDabStrength, bt as rasterizeDab, bu as readSourceRegion, bv as rgbaViewOfGrey, bw as saturationOf, bx as smoothPoints, by as smudgeEffect, bz as sponge, bA as spongeEffect, bB as spotHealPixels, bC as spotHealWindow, bD as tipFalloff, bE as tipReach, bF as tipShape, bG as toneOf, bH as walkDabs, bI as wetSimdSupported, E as wetSupport } from '../flow-4-OC-UkQ.cjs';
|
|
3
|
+
import { R as RasterRect, Y as Pigment, a as BlendMode, j as TiledSurface } from '../surface-Cn30xIV6.cjs';
|
|
4
|
+
export { Z as PIGMENT_BANDS, _ as PIGMENT_LAMBDA_MIN, $ as PIGMENT_LAMBDA_STEP, a0 as PIGMENT_WAVELENGTHS, a1 as PigmentOptions, a2 as PigmentRgb, a3 as createPigment, a4 as lerpPigment, a5 as lerpPigmentInto, a6 as mixPigments, a7 as reflectanceToRgb, a8 as rgbToReflectance, a9 as setPigmentColor } from '../surface-Cn30xIV6.cjs';
|
|
3
5
|
import { A as AgentTool } from '../registry-BqA1AZt0.cjs';
|
|
4
6
|
import '../schema-Di0CS6Pe.cjs';
|
|
5
7
|
|
|
@@ -36,4 +38,224 @@ declare function maskBounds(w: number, h: number, mask: ArrayLike<boolean | numb
|
|
|
36
38
|
*/
|
|
37
39
|
declare function bestOffset(w: number, h: number, ch: number, img: ArrayLike<number>, hole: ArrayLike<boolean | number>, ring: number, maxRadius: number): [number, number] | null;
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
/**
|
|
42
|
+
* How wet-layer pigment looks, and how it bakes into 8-bit pixels.
|
|
43
|
+
*
|
|
44
|
+
* A cell carries pigment as Kubelka-Munk absorption `K` per channel (linear R, G, B) and one
|
|
45
|
+
* scattering `S`, in mass units where `PIGMENT_UNIT` of a colour's pigment is a full-strength wash.
|
|
46
|
+
* Over what is below it (`below`, linear), the film reflects
|
|
47
|
+
*
|
|
48
|
+
* film = hide·R∞ + (1 − hide)·T·below, T = e^(−2K), hide = 1 − e^(−HIDE·S),
|
|
49
|
+
* R∞ = 1 + K/S − √((K/S)² + 2·K/S) (the shipped pigment model's two-flux formula)
|
|
50
|
+
*
|
|
51
|
+
* so transparent washes (S ≈ 0) multiply like glazes and opaque paint (gouache, oil) hides.
|
|
52
|
+
*
|
|
53
|
+
* The bake is a pure function of the f32 state and the 8-bit pixels, computed with deterministic
|
|
54
|
+
* maths only (`dexp`, `dlog`, `sqrt`, + − × ÷ in f64; never `Math.exp` / `Math.pow`, whose last
|
|
55
|
+
* bits differ between JavaScript engines), so "dry on save" gives the same pixels everywhere.
|
|
56
|
+
* The layer pixel is the film expressed as colour plus alpha over the paper colour (exact over the
|
|
57
|
+
* paper, a normal-blend approximation over other layers), with alpha never below the pixel's own.
|
|
58
|
+
*/
|
|
59
|
+
/** Pigment mass of a full-strength wash of a colour. */
|
|
60
|
+
declare const PIGMENT_UNIT = 0.25;
|
|
61
|
+
/** Hiding per unit of scattering. */
|
|
62
|
+
declare const HIDE = 1.5;
|
|
63
|
+
/** Scattering of fully opaque paint (`body` 1), per `PIGMENT_UNIT` of mass. */
|
|
64
|
+
declare const BODY_SCATTER = 3;
|
|
65
|
+
/**
|
|
66
|
+
* e^x with + − × ÷ only: x = k·ln2 + r with |r| ≤ ln2/2, then a degree-11 Taylor polynomial
|
|
67
|
+
* (error below 1e-15). The same bits in every JavaScript engine.
|
|
68
|
+
*/
|
|
69
|
+
declare function dexp(x: number): number;
|
|
70
|
+
/** ln x for x > 0 with + − × ÷ only: x = m·2^e, ln m by the atanh series. */
|
|
71
|
+
declare function dlog(x: number): number;
|
|
72
|
+
/** x^y for x ≥ 0, deterministically. */
|
|
73
|
+
declare function dpow(x: number, y: number): number;
|
|
74
|
+
/** sRGB byte → linear. */
|
|
75
|
+
declare const SRGB_TO_LINEAR: Float64Array<ArrayBuffer>;
|
|
76
|
+
/** sRGB value 0..255 (not necessarily whole) → linear, interpolating the byte table. */
|
|
77
|
+
declare function srgbByteToLinear(v: number): number;
|
|
78
|
+
/** Linear 0..1 → sRGB byte (16384-step table). */
|
|
79
|
+
declare function linearToSrgb8(v: number): number;
|
|
80
|
+
/**
|
|
81
|
+
* The pigment (K r, g, b, S per unit of mass) of an sRGB colour (0..1) at `body` 0 (a transparent
|
|
82
|
+
* watercolour: K = −ln R / 2 so a full wash over white shows the colour) .. 1 (opaque paint:
|
|
83
|
+
* `K/S = (1 − R)² / 2R` at `BODY_SCATTER`).
|
|
84
|
+
*/
|
|
85
|
+
declare function pigmentOf(rgb: readonly [number, number, number] | readonly number[], body: number, out?: Float64Array | number[]): Float64Array | number[];
|
|
86
|
+
/** e^(−x) for x ≥ 0 (deterministic: a table built with `dexp`, interpolated with + − ×). */
|
|
87
|
+
declare function expNeg(x: number): number;
|
|
88
|
+
/** Linear reflectance of a film of pigment `k` (3) and `s` over `below` (linear) into `out`. */
|
|
89
|
+
declare function filmReflectance(k0: number, k1: number, k2: number, s: number, b0: number, b1: number, b2: number, out: Float64Array | number[]): void;
|
|
90
|
+
/** The sRGB colour (0..1) of pigment `k`, `s` over white: what a brush picking it up sees. */
|
|
91
|
+
declare function pigmentColor(k0: number, k1: number, k2: number, s: number, out?: number[]): number[];
|
|
92
|
+
/**
|
|
93
|
+
* Bakes one pixel: pigment `k0..k2`, `s` laid over layer pixel `px[i..i+3]` (straight sRGB) on paper
|
|
94
|
+
* `paper` (sRGB bytes). `wet` (0..1) darkens wet paper slightly (display only; 0 for a bake).
|
|
95
|
+
* Writes the new layer pixel into `out[o..o+3]`.
|
|
96
|
+
*/
|
|
97
|
+
declare function filmPixel(k0: number, k1: number, k2: number, s: number, px: ArrayLike<number>, i: number, paper: ArrayLike<number>, wet: number, out: Uint8ClampedArray, o: number): void;
|
|
98
|
+
/**
|
|
99
|
+
* The pigment a layer pixel holds over the paper, as a transparent film (`K = −ln(below/paper)/2`,
|
|
100
|
+
* `S` 0): what re-wetting lifts back into the water. Writes K r, g, b, S into `out`.
|
|
101
|
+
*/
|
|
102
|
+
declare function pixelPigment(px: ArrayLike<number>, i: number, paper: ArrayLike<number>, out: Float64Array | number[]): void;
|
|
103
|
+
/**
|
|
104
|
+
* `filmPixel` over a whole tile, specialised for speed (same results, pixel for pixel). Reads the
|
|
105
|
+
* slot's planes from `f`: settled pigment at `d` (4 planes, `plane` floats apart), suspended pigment
|
|
106
|
+
* at `p` (or −1 to leave it out), surface and paper water at `rho` / `sw` (or −1: no wet darkening).
|
|
107
|
+
* Cell (x, y) of the tile is at offset `(y + 1)·side + x + 1` of each plane. `src` is the base tile
|
|
108
|
+
* (or `null` for transparent); writes `out` (a copy of `src` where nothing changes). Returns
|
|
109
|
+
* whether any pixel was shaded.
|
|
110
|
+
*/
|
|
111
|
+
declare function shadeTile(f: Float32Array, plane: number, side: number, d: number, p: number, rho: number, sw: number, src: Uint8ClampedArray | null, out: Uint8ClampedArray, w: number, h: number, paper: Uint8Array): boolean;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* One wet-media step for the 256 × 256 interior of a tile slot, in plain TypeScript: the
|
|
115
|
+
* specification of the model. Every intermediate is rounded to f32 (`F`) in the same order as the
|
|
116
|
+
* WebAssembly SIMD kernel (`assembly/wet.ts`), so the two give identical bits: computing an f32
|
|
117
|
+
* `+ − × ÷ √` in f64 and rounding once is exactly the f32 operation. Keep the two in step; the
|
|
118
|
+
* kernel test compares them bit for bit.
|
|
119
|
+
*
|
|
120
|
+
* A slot is `SLOT_PLANES` planes of 258 × 258 f32 (the tile plus a one-cell halo, filled from the
|
|
121
|
+
* neighbouring slots after each step). The step reads set `parity` (and the single planes) and
|
|
122
|
+
* writes the interior of the other set, the deposit planes in place, and returns the tile's flags.
|
|
123
|
+
*
|
|
124
|
+
* Per cell x:
|
|
125
|
+
* 1. Streaming with partial bounce-back: for each direction i, the source is n = x − eᵢ and the
|
|
126
|
+
* blocking is b = max(κ(x), κ(n)), κ = blockScale·h. b = 1 off the canvas (h < 0) and where the
|
|
127
|
+
* front is pinned: one side dry and the other shallower than the pin threshold
|
|
128
|
+
* (pinT + rough·h)·(1 − paperWater/capacity) of the dry side, so damp paper does not pin.
|
|
129
|
+
* Off-canvas cells (h < 0, in the halo or past a canvas edge inside a tile) only bounce back.
|
|
130
|
+
* Symmetric in x and n, so water is conserved: fᵢ(x) = (1 − b)·f*ᵢ(n) + b·f*ₒₚₚ₍ᵢ₎(x).
|
|
131
|
+
* 2. Depth and velocity; tilt plus the flow map shift the velocity (u += τ·g), capped at U_MAX.
|
|
132
|
+
* 3. Absorption into the paper until it holds its capacity, and evaporation (faster in the edge
|
|
133
|
+
* band); the collided populations are scaled by the depth ratio.
|
|
134
|
+
* 4. BGK collision towards the D2Q9 equilibrium.
|
|
135
|
+
* 5. Pigment (4 channels): upwind flux through the 4 faces with the previous step's velocities,
|
|
136
|
+
* plus bleed (diffusion) between wet cells; never below 0.
|
|
137
|
+
* 6. Deposition (more in valleys and in the edge band) and pickup (more where water arrives);
|
|
138
|
+
* where a cell dries, all its suspended pigment settles.
|
|
139
|
+
* 7. The edge field: max(dry neighbours / 4, 0.99 × the mean of the 4 neighbours' edge), at most
|
|
140
|
+
* 1, and 0 where the cell is dry.
|
|
141
|
+
*/
|
|
142
|
+
/**
|
|
143
|
+
* Steps one slot. `f` views the whole memory; `base` is the slot's first float; `prm` is the
|
|
144
|
+
* lane's packed parameters (`packWetParams`). Returns the tile's flag bits.
|
|
145
|
+
*/
|
|
146
|
+
declare function stepSlotTs(f: Float32Array, base: number, parity: number, prm: Float32Array): number;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The wet layer as a `PaintMedium`: the canvas side of the shared pick-up / mix exchange
|
|
150
|
+
* (`PaintExchange`), so wet brushes pick up and mix paint the same way the Mixer Brush and the
|
|
151
|
+
* phase 2 dab brushes do.
|
|
152
|
+
*
|
|
153
|
+
* - `sample` sees only wet paint (pigment still suspended in surface water): what a brush can
|
|
154
|
+
* lift. Its colour is the suspended pigment's hue at full strength; contact is how much of the
|
|
155
|
+
* footprint is wet with pigment in it.
|
|
156
|
+
* - `deposit` lays water and pigment: the colour becomes Kubelka-Munk pigment (`pigmentOf` at the
|
|
157
|
+
* brush's body), at `mass` per unit of coverage, with `water` depth.
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
interface WetMediumOptions {
|
|
161
|
+
/** Water depth laid per unit of coverage (at deposit weight 1). */
|
|
162
|
+
water: number;
|
|
163
|
+
/** Pigment mass laid per unit of coverage (at deposit weight 1). */
|
|
164
|
+
mass: number;
|
|
165
|
+
/** 0 transparent watercolour .. 1 opaque gouache. */
|
|
166
|
+
body: number;
|
|
167
|
+
}
|
|
168
|
+
declare class WetMedium implements PaintMedium {
|
|
169
|
+
readonly world: WetWorld;
|
|
170
|
+
readonly laneId: string;
|
|
171
|
+
options: WetMediumOptions;
|
|
172
|
+
private readonly pig;
|
|
173
|
+
constructor(world: WetWorld, laneId: string, options: WetMediumOptions);
|
|
174
|
+
sample(rect: RasterRect, cov: ArrayLike<number>): PaintSample | null;
|
|
175
|
+
deposit(rect: RasterRect, cov: ArrayLike<number>, dep: number, paint: Readonly<RgbTriple>, _pigment: Pigment | null, field?: Float32Array | null): void;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* A brush stroke along a path: polyline samples, each with an optional pressure and pen tilt, are
|
|
180
|
+
* walked at the brush's spacing (pressure and tilt interpolated between samples) into dabs, built
|
|
181
|
+
* up in a coverage map and composited onto a layer. This is what a vector editor calls to draw a
|
|
182
|
+
* path with a natural-media brush ("brushstrokes on vector paths"): the path is the data, the
|
|
183
|
+
* pixels are rendered from it.
|
|
184
|
+
*
|
|
185
|
+
* - Pressure scales size and / or opacity as the brush says.
|
|
186
|
+
* - Tilt (`tiltX` / `tiltY` in degrees, or `altitude` / `azimuth` in radians, as Pointer Events give
|
|
187
|
+
* them) widens the tip (`tilt.size`), flattens it along the lean (`tilt.roundness`), and with
|
|
188
|
+
* `tilt.followAzimuth` turns the tip to the lean, as a pen laid on its side does.
|
|
189
|
+
* - With `followPath` the tip turns with the path (a calligraphic nib along a curve).
|
|
190
|
+
*
|
|
191
|
+
* Deterministic and DOM-free: the same samples and brush give the same pixels everywhere.
|
|
192
|
+
*/
|
|
193
|
+
|
|
194
|
+
/** One sample of the path (document pixels). */
|
|
195
|
+
interface PathSample {
|
|
196
|
+
x: number;
|
|
197
|
+
y: number;
|
|
198
|
+
/** 0..1 (default 1). */
|
|
199
|
+
pressure?: number;
|
|
200
|
+
/** Pointer Events tilt in degrees (−90..90). */
|
|
201
|
+
tiltX?: number;
|
|
202
|
+
tiltY?: number;
|
|
203
|
+
/** Radians above the surface (π/2 upright); overrides tiltX / tiltY. */
|
|
204
|
+
altitude?: number;
|
|
205
|
+
/** Radians clockwise from +x: where the pen leans (with altitude). */
|
|
206
|
+
azimuth?: number;
|
|
207
|
+
}
|
|
208
|
+
interface PathStrokeOptions {
|
|
209
|
+
brush: Partial<BrushSettings>;
|
|
210
|
+
/** How tilt shapes the tip (each 0..1; default none). */
|
|
211
|
+
tilt?: {
|
|
212
|
+
size?: number;
|
|
213
|
+
roundness?: number;
|
|
214
|
+
followAzimuth?: boolean;
|
|
215
|
+
};
|
|
216
|
+
/** Turn the tip with the direction of the path (added to the brush angle). */
|
|
217
|
+
followPath?: boolean;
|
|
218
|
+
/** Size at zero pressure as a fraction of the full size, when pressure controls size (default 0). */
|
|
219
|
+
minSize?: number;
|
|
220
|
+
/** Join the last sample back to the first. */
|
|
221
|
+
closed?: boolean;
|
|
222
|
+
}
|
|
223
|
+
/** The dabs of a brush stroke along `samples`, with pressure and tilt interpolated between them. */
|
|
224
|
+
declare function pathStrokeDabs(samples: readonly PathSample[], options: PathStrokeOptions): Dab[];
|
|
225
|
+
/** The coverage of a brush stroke along `samples` (build-up towards each dab's opacity) and its bounds. */
|
|
226
|
+
declare function pathStrokeCoverage(samples: readonly PathSample[], options: PathStrokeOptions): {
|
|
227
|
+
coverage: CoverageMap;
|
|
228
|
+
bounds: RasterRect | null;
|
|
229
|
+
dabs: number;
|
|
230
|
+
};
|
|
231
|
+
interface PaintPathOptions extends PathStrokeOptions {
|
|
232
|
+
/** RGBA 0..255 of the paint. */
|
|
233
|
+
color: readonly [number, number, number, number];
|
|
234
|
+
/** `erase` removes paint instead (default `paint`). */
|
|
235
|
+
mode?: 'paint' | 'erase';
|
|
236
|
+
/** Blend mode (default the brush's). */
|
|
237
|
+
blend?: BlendMode;
|
|
238
|
+
/** Layer offset: layer pixel = document pixel − offset (default 0, 0). */
|
|
239
|
+
offset?: {
|
|
240
|
+
x: number;
|
|
241
|
+
y: number;
|
|
242
|
+
};
|
|
243
|
+
lockTransparency?: boolean;
|
|
244
|
+
/** Where paint may land (canvas-sized coverage 0..255), or none. */
|
|
245
|
+
selection?: {
|
|
246
|
+
width: number;
|
|
247
|
+
height: number;
|
|
248
|
+
data: ArrayLike<number>;
|
|
249
|
+
} | null;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Paints a brush stroke along `samples` onto an RGBA layer surface and returns the new surface
|
|
253
|
+
* (the input is not changed; untouched tiles are shared) with the bounds it touched.
|
|
254
|
+
*/
|
|
255
|
+
declare function paintPathStroke(surface: TiledSurface, samples: readonly PathSample[], options: PaintPathOptions): {
|
|
256
|
+
surface: TiledSurface;
|
|
257
|
+
bounds: RasterRect | null;
|
|
258
|
+
dabs: number;
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
export { BODY_SCATTER, BrushSettings, CoverageMap, Dab, HIDE, PIGMENT_UNIT, PaintMedium, type PaintPathOptions, PaintSample, type PathSample, type PathStrokeOptions, Pigment, RgbTriple, SRGB_TO_LINEAR, WetMedium, type WetMediumOptions, WetWorld, bestOffset, createPigmentTools, dexp, dilateMask, dlog, dpow, expNeg, filmPixel, filmReflectance, linearToSrgb8, maskBounds, membraneFill, paintPathStroke, pathStrokeCoverage, pathStrokeDabs, pigmentColor, pigmentOf, pixelPigment, seamlessClone, shadeTile, solveMembrane, srgbByteToLinear, stepSlotTs };
|
package/dist/paint/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
1
|
+
import { at as PaintMedium, W as WetWorld, au as PaintSample, n as RgbTriple, B as BrushSettings, C as CoverageMap, D as Dab } from '../flow-Cb7lkPm8.js';
|
|
2
|
+
export { F as BlenderScratch, i as BlenderSettings, G as DEFAULT_BLENDER, H as DEFAULT_BRUSH, s as DEFAULT_FLOW, I as DEFAULT_MIXER, J as DEFAULT_RETOUCH, K as DEFAULT_SMUDGE, L as DEFAULT_WET_PAPER, t as DEFAULT_WET_PARAMS, N as DRY_EPS, O as DabWalker, Q as EMPTY_MIXER_LOAD, U as EX, V as EY, X as ExchangeRates, Y as FLAG_ALIVE, Z as FLAG_BOTTOM, _ as FLAG_LEFT, $ as FLAG_RIGHT, a0 as FLAG_TOP, a1 as FLAG_WET, a2 as FLAT, a3 as FREE_INTERVAL, a4 as MAX_BATCH, u as MAX_BRUSH_SIZE, a5 as MAX_TILT_ACCEL, a6 as MAX_WET_LANES, a7 as MAX_WET_SLOTS, a8 as MIXER_DRAIN, a9 as MIXER_PICKUP_RATE, aa as MIXING_MODELS, a as MixerLoad, M as MixerSettings, c as MixerStroke, b as MixerTarget, h as MixingModel, ab as OPP, ac as PAPER_CAPACITY, ad as PARAM, ae as PARAM_FLOATS, af as PIGMENT_CHANNELS, ag as PLANE, ah as PLANE_BYTES, ai as P_D0, aj as P_EDGE, ak as P_FX, al as P_FY, am as P_H, an as P_P0, ao as P_RHO, ap as P_SW, aq as P_UX, ar as P_UY, as as PaintExchange, P as PaintTileTarget, av as PixelSource, aw as RETOUCH_SAMPLES, ax as RegionPixelSource, d as RetouchApply, ay as RetouchDabEffect, az as RetouchDabStroke, f as RetouchPaint, aA as RetouchSample, R as RetouchSettings, aB as SET_PLANES, aC as SLOT_BYTES, aD as SLOT_PLANES, aE as SLOT_SIDE, aF as SPOT_HEAL_TYPES, aG as STRIP, aH as SmudgeDab, j as SmudgeSettings, aI as SmudgeTip, aJ as SpotHealType, g as StrokeApply, S as StrokeCoverage, e as StrokePoint, aK as TONE_RANGES, T as TileMedium, aL as TileMediumOptions, aM as TilePixelSource, aN as ToneRange, aO as U_MAX, aP as W9, v as WET_FLOW_KINDS, w as WET_PARAM_KEYS, aQ as WET_TILE, p as WetBackendInfo, aR as WetFlowField, x as WetFlowKind, m as WetFlowSpec, aS as WetKernelKind, aT as WetLaneOptions, aU as WetLaneStats, aV as WetPaper, r as WetPaperInput, l as WetParams, q as WetSnapshot, y as WetSupport, k as WetTilt, aW as WetWorkerLayout, aX as WetWorkerPool, aY as WetWorldError, o as WetWorldOptions, aZ as applyRetouchToTile, a_ as applyStrokeToDeepTile, a$ as applyStrokeToTile, b0 as applyToneToDeepTile, b1 as blendRadius, b2 as blenderDab, b3 as canShareMemory, b4 as cleanMixer, b5 as coverageTileCoord, b6 as createBlenderScratch, b7 as dabCoverage, b8 as dabRect, b9 as dodgeBurn, ba as dodgeBurnCurve, bb as dsincos, bc as edgeBits, bd as exchangeRates, be as flowField, bf as healPixels, bg as latticeViscosity, bh as loadMixer, bi as loadWetKernel, bj as luma, bk as mixerRates, bl as normalizeBlender, bm as normalizeBrush, z as normalizeFlow, bn as normalizeMixer, bo as normalizeRetouch, bp as normalizeSmudge, bq as normalizeTilt, A as normalizeWetParams, br as packWetParams, bs as perDabStrength, bt as rasterizeDab, bu as readSourceRegion, bv as rgbaViewOfGrey, bw as saturationOf, bx as smoothPoints, by as smudgeEffect, bz as sponge, bA as spongeEffect, bB as spotHealPixels, bC as spotHealWindow, bD as tipFalloff, bE as tipReach, bF as tipShape, bG as toneOf, bH as walkDabs, bI as wetSimdSupported, E as wetSupport } from '../flow-Cb7lkPm8.js';
|
|
3
|
+
import { R as RasterRect, Y as Pigment, a as BlendMode, j as TiledSurface } from '../surface-Cn30xIV6.js';
|
|
4
|
+
export { Z as PIGMENT_BANDS, _ as PIGMENT_LAMBDA_MIN, $ as PIGMENT_LAMBDA_STEP, a0 as PIGMENT_WAVELENGTHS, a1 as PigmentOptions, a2 as PigmentRgb, a3 as createPigment, a4 as lerpPigment, a5 as lerpPigmentInto, a6 as mixPigments, a7 as reflectanceToRgb, a8 as rgbToReflectance, a9 as setPigmentColor } from '../surface-Cn30xIV6.js';
|
|
3
5
|
import { A as AgentTool } from '../registry-D-4fit9C.js';
|
|
4
6
|
import '../schema-Di0CS6Pe.js';
|
|
5
7
|
|
|
@@ -36,4 +38,224 @@ declare function maskBounds(w: number, h: number, mask: ArrayLike<boolean | numb
|
|
|
36
38
|
*/
|
|
37
39
|
declare function bestOffset(w: number, h: number, ch: number, img: ArrayLike<number>, hole: ArrayLike<boolean | number>, ring: number, maxRadius: number): [number, number] | null;
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
/**
|
|
42
|
+
* How wet-layer pigment looks, and how it bakes into 8-bit pixels.
|
|
43
|
+
*
|
|
44
|
+
* A cell carries pigment as Kubelka-Munk absorption `K` per channel (linear R, G, B) and one
|
|
45
|
+
* scattering `S`, in mass units where `PIGMENT_UNIT` of a colour's pigment is a full-strength wash.
|
|
46
|
+
* Over what is below it (`below`, linear), the film reflects
|
|
47
|
+
*
|
|
48
|
+
* film = hide·R∞ + (1 − hide)·T·below, T = e^(−2K), hide = 1 − e^(−HIDE·S),
|
|
49
|
+
* R∞ = 1 + K/S − √((K/S)² + 2·K/S) (the shipped pigment model's two-flux formula)
|
|
50
|
+
*
|
|
51
|
+
* so transparent washes (S ≈ 0) multiply like glazes and opaque paint (gouache, oil) hides.
|
|
52
|
+
*
|
|
53
|
+
* The bake is a pure function of the f32 state and the 8-bit pixels, computed with deterministic
|
|
54
|
+
* maths only (`dexp`, `dlog`, `sqrt`, + − × ÷ in f64; never `Math.exp` / `Math.pow`, whose last
|
|
55
|
+
* bits differ between JavaScript engines), so "dry on save" gives the same pixels everywhere.
|
|
56
|
+
* The layer pixel is the film expressed as colour plus alpha over the paper colour (exact over the
|
|
57
|
+
* paper, a normal-blend approximation over other layers), with alpha never below the pixel's own.
|
|
58
|
+
*/
|
|
59
|
+
/** Pigment mass of a full-strength wash of a colour. */
|
|
60
|
+
declare const PIGMENT_UNIT = 0.25;
|
|
61
|
+
/** Hiding per unit of scattering. */
|
|
62
|
+
declare const HIDE = 1.5;
|
|
63
|
+
/** Scattering of fully opaque paint (`body` 1), per `PIGMENT_UNIT` of mass. */
|
|
64
|
+
declare const BODY_SCATTER = 3;
|
|
65
|
+
/**
|
|
66
|
+
* e^x with + − × ÷ only: x = k·ln2 + r with |r| ≤ ln2/2, then a degree-11 Taylor polynomial
|
|
67
|
+
* (error below 1e-15). The same bits in every JavaScript engine.
|
|
68
|
+
*/
|
|
69
|
+
declare function dexp(x: number): number;
|
|
70
|
+
/** ln x for x > 0 with + − × ÷ only: x = m·2^e, ln m by the atanh series. */
|
|
71
|
+
declare function dlog(x: number): number;
|
|
72
|
+
/** x^y for x ≥ 0, deterministically. */
|
|
73
|
+
declare function dpow(x: number, y: number): number;
|
|
74
|
+
/** sRGB byte → linear. */
|
|
75
|
+
declare const SRGB_TO_LINEAR: Float64Array<ArrayBuffer>;
|
|
76
|
+
/** sRGB value 0..255 (not necessarily whole) → linear, interpolating the byte table. */
|
|
77
|
+
declare function srgbByteToLinear(v: number): number;
|
|
78
|
+
/** Linear 0..1 → sRGB byte (16384-step table). */
|
|
79
|
+
declare function linearToSrgb8(v: number): number;
|
|
80
|
+
/**
|
|
81
|
+
* The pigment (K r, g, b, S per unit of mass) of an sRGB colour (0..1) at `body` 0 (a transparent
|
|
82
|
+
* watercolour: K = −ln R / 2 so a full wash over white shows the colour) .. 1 (opaque paint:
|
|
83
|
+
* `K/S = (1 − R)² / 2R` at `BODY_SCATTER`).
|
|
84
|
+
*/
|
|
85
|
+
declare function pigmentOf(rgb: readonly [number, number, number] | readonly number[], body: number, out?: Float64Array | number[]): Float64Array | number[];
|
|
86
|
+
/** e^(−x) for x ≥ 0 (deterministic: a table built with `dexp`, interpolated with + − ×). */
|
|
87
|
+
declare function expNeg(x: number): number;
|
|
88
|
+
/** Linear reflectance of a film of pigment `k` (3) and `s` over `below` (linear) into `out`. */
|
|
89
|
+
declare function filmReflectance(k0: number, k1: number, k2: number, s: number, b0: number, b1: number, b2: number, out: Float64Array | number[]): void;
|
|
90
|
+
/** The sRGB colour (0..1) of pigment `k`, `s` over white: what a brush picking it up sees. */
|
|
91
|
+
declare function pigmentColor(k0: number, k1: number, k2: number, s: number, out?: number[]): number[];
|
|
92
|
+
/**
|
|
93
|
+
* Bakes one pixel: pigment `k0..k2`, `s` laid over layer pixel `px[i..i+3]` (straight sRGB) on paper
|
|
94
|
+
* `paper` (sRGB bytes). `wet` (0..1) darkens wet paper slightly (display only; 0 for a bake).
|
|
95
|
+
* Writes the new layer pixel into `out[o..o+3]`.
|
|
96
|
+
*/
|
|
97
|
+
declare function filmPixel(k0: number, k1: number, k2: number, s: number, px: ArrayLike<number>, i: number, paper: ArrayLike<number>, wet: number, out: Uint8ClampedArray, o: number): void;
|
|
98
|
+
/**
|
|
99
|
+
* The pigment a layer pixel holds over the paper, as a transparent film (`K = −ln(below/paper)/2`,
|
|
100
|
+
* `S` 0): what re-wetting lifts back into the water. Writes K r, g, b, S into `out`.
|
|
101
|
+
*/
|
|
102
|
+
declare function pixelPigment(px: ArrayLike<number>, i: number, paper: ArrayLike<number>, out: Float64Array | number[]): void;
|
|
103
|
+
/**
|
|
104
|
+
* `filmPixel` over a whole tile, specialised for speed (same results, pixel for pixel). Reads the
|
|
105
|
+
* slot's planes from `f`: settled pigment at `d` (4 planes, `plane` floats apart), suspended pigment
|
|
106
|
+
* at `p` (or −1 to leave it out), surface and paper water at `rho` / `sw` (or −1: no wet darkening).
|
|
107
|
+
* Cell (x, y) of the tile is at offset `(y + 1)·side + x + 1` of each plane. `src` is the base tile
|
|
108
|
+
* (or `null` for transparent); writes `out` (a copy of `src` where nothing changes). Returns
|
|
109
|
+
* whether any pixel was shaded.
|
|
110
|
+
*/
|
|
111
|
+
declare function shadeTile(f: Float32Array, plane: number, side: number, d: number, p: number, rho: number, sw: number, src: Uint8ClampedArray | null, out: Uint8ClampedArray, w: number, h: number, paper: Uint8Array): boolean;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* One wet-media step for the 256 × 256 interior of a tile slot, in plain TypeScript: the
|
|
115
|
+
* specification of the model. Every intermediate is rounded to f32 (`F`) in the same order as the
|
|
116
|
+
* WebAssembly SIMD kernel (`assembly/wet.ts`), so the two give identical bits: computing an f32
|
|
117
|
+
* `+ − × ÷ √` in f64 and rounding once is exactly the f32 operation. Keep the two in step; the
|
|
118
|
+
* kernel test compares them bit for bit.
|
|
119
|
+
*
|
|
120
|
+
* A slot is `SLOT_PLANES` planes of 258 × 258 f32 (the tile plus a one-cell halo, filled from the
|
|
121
|
+
* neighbouring slots after each step). The step reads set `parity` (and the single planes) and
|
|
122
|
+
* writes the interior of the other set, the deposit planes in place, and returns the tile's flags.
|
|
123
|
+
*
|
|
124
|
+
* Per cell x:
|
|
125
|
+
* 1. Streaming with partial bounce-back: for each direction i, the source is n = x − eᵢ and the
|
|
126
|
+
* blocking is b = max(κ(x), κ(n)), κ = blockScale·h. b = 1 off the canvas (h < 0) and where the
|
|
127
|
+
* front is pinned: one side dry and the other shallower than the pin threshold
|
|
128
|
+
* (pinT + rough·h)·(1 − paperWater/capacity) of the dry side, so damp paper does not pin.
|
|
129
|
+
* Off-canvas cells (h < 0, in the halo or past a canvas edge inside a tile) only bounce back.
|
|
130
|
+
* Symmetric in x and n, so water is conserved: fᵢ(x) = (1 − b)·f*ᵢ(n) + b·f*ₒₚₚ₍ᵢ₎(x).
|
|
131
|
+
* 2. Depth and velocity; tilt plus the flow map shift the velocity (u += τ·g), capped at U_MAX.
|
|
132
|
+
* 3. Absorption into the paper until it holds its capacity, and evaporation (faster in the edge
|
|
133
|
+
* band); the collided populations are scaled by the depth ratio.
|
|
134
|
+
* 4. BGK collision towards the D2Q9 equilibrium.
|
|
135
|
+
* 5. Pigment (4 channels): upwind flux through the 4 faces with the previous step's velocities,
|
|
136
|
+
* plus bleed (diffusion) between wet cells; never below 0.
|
|
137
|
+
* 6. Deposition (more in valleys and in the edge band) and pickup (more where water arrives);
|
|
138
|
+
* where a cell dries, all its suspended pigment settles.
|
|
139
|
+
* 7. The edge field: max(dry neighbours / 4, 0.99 × the mean of the 4 neighbours' edge), at most
|
|
140
|
+
* 1, and 0 where the cell is dry.
|
|
141
|
+
*/
|
|
142
|
+
/**
|
|
143
|
+
* Steps one slot. `f` views the whole memory; `base` is the slot's first float; `prm` is the
|
|
144
|
+
* lane's packed parameters (`packWetParams`). Returns the tile's flag bits.
|
|
145
|
+
*/
|
|
146
|
+
declare function stepSlotTs(f: Float32Array, base: number, parity: number, prm: Float32Array): number;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The wet layer as a `PaintMedium`: the canvas side of the shared pick-up / mix exchange
|
|
150
|
+
* (`PaintExchange`), so wet brushes pick up and mix paint the same way the Mixer Brush and the
|
|
151
|
+
* phase 2 dab brushes do.
|
|
152
|
+
*
|
|
153
|
+
* - `sample` sees only wet paint (pigment still suspended in surface water): what a brush can
|
|
154
|
+
* lift. Its colour is the suspended pigment's hue at full strength; contact is how much of the
|
|
155
|
+
* footprint is wet with pigment in it.
|
|
156
|
+
* - `deposit` lays water and pigment: the colour becomes Kubelka-Munk pigment (`pigmentOf` at the
|
|
157
|
+
* brush's body), at `mass` per unit of coverage, with `water` depth.
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
interface WetMediumOptions {
|
|
161
|
+
/** Water depth laid per unit of coverage (at deposit weight 1). */
|
|
162
|
+
water: number;
|
|
163
|
+
/** Pigment mass laid per unit of coverage (at deposit weight 1). */
|
|
164
|
+
mass: number;
|
|
165
|
+
/** 0 transparent watercolour .. 1 opaque gouache. */
|
|
166
|
+
body: number;
|
|
167
|
+
}
|
|
168
|
+
declare class WetMedium implements PaintMedium {
|
|
169
|
+
readonly world: WetWorld;
|
|
170
|
+
readonly laneId: string;
|
|
171
|
+
options: WetMediumOptions;
|
|
172
|
+
private readonly pig;
|
|
173
|
+
constructor(world: WetWorld, laneId: string, options: WetMediumOptions);
|
|
174
|
+
sample(rect: RasterRect, cov: ArrayLike<number>): PaintSample | null;
|
|
175
|
+
deposit(rect: RasterRect, cov: ArrayLike<number>, dep: number, paint: Readonly<RgbTriple>, _pigment: Pigment | null, field?: Float32Array | null): void;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* A brush stroke along a path: polyline samples, each with an optional pressure and pen tilt, are
|
|
180
|
+
* walked at the brush's spacing (pressure and tilt interpolated between samples) into dabs, built
|
|
181
|
+
* up in a coverage map and composited onto a layer. This is what a vector editor calls to draw a
|
|
182
|
+
* path with a natural-media brush ("brushstrokes on vector paths"): the path is the data, the
|
|
183
|
+
* pixels are rendered from it.
|
|
184
|
+
*
|
|
185
|
+
* - Pressure scales size and / or opacity as the brush says.
|
|
186
|
+
* - Tilt (`tiltX` / `tiltY` in degrees, or `altitude` / `azimuth` in radians, as Pointer Events give
|
|
187
|
+
* them) widens the tip (`tilt.size`), flattens it along the lean (`tilt.roundness`), and with
|
|
188
|
+
* `tilt.followAzimuth` turns the tip to the lean, as a pen laid on its side does.
|
|
189
|
+
* - With `followPath` the tip turns with the path (a calligraphic nib along a curve).
|
|
190
|
+
*
|
|
191
|
+
* Deterministic and DOM-free: the same samples and brush give the same pixels everywhere.
|
|
192
|
+
*/
|
|
193
|
+
|
|
194
|
+
/** One sample of the path (document pixels). */
|
|
195
|
+
interface PathSample {
|
|
196
|
+
x: number;
|
|
197
|
+
y: number;
|
|
198
|
+
/** 0..1 (default 1). */
|
|
199
|
+
pressure?: number;
|
|
200
|
+
/** Pointer Events tilt in degrees (−90..90). */
|
|
201
|
+
tiltX?: number;
|
|
202
|
+
tiltY?: number;
|
|
203
|
+
/** Radians above the surface (π/2 upright); overrides tiltX / tiltY. */
|
|
204
|
+
altitude?: number;
|
|
205
|
+
/** Radians clockwise from +x: where the pen leans (with altitude). */
|
|
206
|
+
azimuth?: number;
|
|
207
|
+
}
|
|
208
|
+
interface PathStrokeOptions {
|
|
209
|
+
brush: Partial<BrushSettings>;
|
|
210
|
+
/** How tilt shapes the tip (each 0..1; default none). */
|
|
211
|
+
tilt?: {
|
|
212
|
+
size?: number;
|
|
213
|
+
roundness?: number;
|
|
214
|
+
followAzimuth?: boolean;
|
|
215
|
+
};
|
|
216
|
+
/** Turn the tip with the direction of the path (added to the brush angle). */
|
|
217
|
+
followPath?: boolean;
|
|
218
|
+
/** Size at zero pressure as a fraction of the full size, when pressure controls size (default 0). */
|
|
219
|
+
minSize?: number;
|
|
220
|
+
/** Join the last sample back to the first. */
|
|
221
|
+
closed?: boolean;
|
|
222
|
+
}
|
|
223
|
+
/** The dabs of a brush stroke along `samples`, with pressure and tilt interpolated between them. */
|
|
224
|
+
declare function pathStrokeDabs(samples: readonly PathSample[], options: PathStrokeOptions): Dab[];
|
|
225
|
+
/** The coverage of a brush stroke along `samples` (build-up towards each dab's opacity) and its bounds. */
|
|
226
|
+
declare function pathStrokeCoverage(samples: readonly PathSample[], options: PathStrokeOptions): {
|
|
227
|
+
coverage: CoverageMap;
|
|
228
|
+
bounds: RasterRect | null;
|
|
229
|
+
dabs: number;
|
|
230
|
+
};
|
|
231
|
+
interface PaintPathOptions extends PathStrokeOptions {
|
|
232
|
+
/** RGBA 0..255 of the paint. */
|
|
233
|
+
color: readonly [number, number, number, number];
|
|
234
|
+
/** `erase` removes paint instead (default `paint`). */
|
|
235
|
+
mode?: 'paint' | 'erase';
|
|
236
|
+
/** Blend mode (default the brush's). */
|
|
237
|
+
blend?: BlendMode;
|
|
238
|
+
/** Layer offset: layer pixel = document pixel − offset (default 0, 0). */
|
|
239
|
+
offset?: {
|
|
240
|
+
x: number;
|
|
241
|
+
y: number;
|
|
242
|
+
};
|
|
243
|
+
lockTransparency?: boolean;
|
|
244
|
+
/** Where paint may land (canvas-sized coverage 0..255), or none. */
|
|
245
|
+
selection?: {
|
|
246
|
+
width: number;
|
|
247
|
+
height: number;
|
|
248
|
+
data: ArrayLike<number>;
|
|
249
|
+
} | null;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Paints a brush stroke along `samples` onto an RGBA layer surface and returns the new surface
|
|
253
|
+
* (the input is not changed; untouched tiles are shared) with the bounds it touched.
|
|
254
|
+
*/
|
|
255
|
+
declare function paintPathStroke(surface: TiledSurface, samples: readonly PathSample[], options: PaintPathOptions): {
|
|
256
|
+
surface: TiledSurface;
|
|
257
|
+
bounds: RasterRect | null;
|
|
258
|
+
dabs: number;
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
export { BODY_SCATTER, BrushSettings, CoverageMap, Dab, HIDE, PIGMENT_UNIT, PaintMedium, type PaintPathOptions, PaintSample, type PathSample, type PathStrokeOptions, Pigment, RgbTriple, SRGB_TO_LINEAR, WetMedium, type WetMediumOptions, WetWorld, bestOffset, createPigmentTools, dexp, dilateMask, dlog, dpow, expNeg, filmPixel, filmReflectance, linearToSrgb8, maskBounds, membraneFill, paintPathStroke, pathStrokeCoverage, pathStrokeDabs, pigmentColor, pigmentOf, pixelPigment, seamlessClone, shadeTile, solveMembrane, srgbByteToLinear, stepSlotTs };
|