@pixerate/editor 0.36.0 → 0.38.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.
@@ -1,4 +1,4 @@
1
- import { C as CanvasGradientDef, A as AffineMatrix, B as BezierPathInput, a as BezierPath, S as SvgGradientDef } from '../bezier-D8bsO-L0.cjs';
1
+ import { C as CanvasGradientDef, A as AffineMatrix, B as BezierPathInput, a as BezierPath, S as SvgGradientDef, b as StrokeJoin, c as StrokeCap, d as BezierSegment, P as PlanarMap, e as PathfinderOperation, f as PathfinderShape } from '../pathfinder-Bd87_lsQ.cjs';
2
2
  import { P as Point } from '../types-BFkYA4eF.cjs';
3
3
  import { H as HistoryManager } from '../HistoryManager-DeQQMBCj.cjs';
4
4
  import { C as CommandSpec } from '../registry-D0GADKc7.cjs';
@@ -75,6 +75,17 @@ declare const VECTOR_ARROWHEADS: readonly VectorArrowhead[];
75
75
  * tip sits on the end point and the stroke is shortened under the head.
76
76
  */
77
77
  type VectorArrowAlign = 'extend' | 'tip';
78
+ /**
79
+ * One point of a variable-width stroke profile. `t` is the position along the subpath by
80
+ * length (0 at its start, 1 at its end); `left` and `right` are how far the stroke reaches on
81
+ * each side, as multiples of half the stroke width (looking along the path on screen, y down).
82
+ * A uniform stroke has 1 on both sides. Two points at the same `t` make a step.
83
+ */
84
+ interface VectorWidthPoint {
85
+ t: number;
86
+ left: number;
87
+ right: number;
88
+ }
78
89
  /** Paint and stroke settings of a path. */
79
90
  interface VectorStyle {
80
91
  fill?: VectorPaint;
@@ -98,6 +109,12 @@ interface VectorStyle {
98
109
  startArrowScale?: number;
99
110
  /** Size of the end head (default 1). */
100
111
  endArrowScale?: number;
112
+ /**
113
+ * Variable width: side scales along each subpath, interpolated with a monotone cubic (see
114
+ * `widthProfileAt`). Absent, empty or `null` strokes at a uniform width. A profiled stroke is
115
+ * drawn as its filled outline.
116
+ */
117
+ strokeWidthProfile?: VectorWidthPoint[] | null;
101
118
  }
102
119
  interface VectorNodeBase {
103
120
  id: string;
@@ -154,10 +171,12 @@ interface VectorHandleRef extends VectorAnchorRef {
154
171
  }
155
172
  /**
156
173
  * Canvas tools. `direct` edits anchors, handles and segments; the shape tools drag out a new
157
- * shape; `scissors` cuts a path at a point, `knife` cuts filled shapes along a freehand stroke
158
- * and `eraser` rubs out the area under one.
174
+ * shape; `scissors` cuts a path at a point, `knife` cuts filled shapes along a freehand stroke,
175
+ * `eraser` rubs out the area under one and `width` drags a stroke's width at a point.
176
+ * `shapeBuilder` merges (Alt: deletes) the faces the selected shapes make, and `paintBucket`
177
+ * fills the region the visible outlines enclose around a click with a new shape.
159
178
  */
160
- type VectorTool = 'select' | 'direct' | 'pen' | 'pencil' | 'rect' | 'ellipse' | 'polygon' | 'star' | 'line' | 'scissors' | 'knife' | 'eraser';
179
+ type VectorTool = 'select' | 'direct' | 'pen' | 'pencil' | 'rect' | 'ellipse' | 'polygon' | 'star' | 'line' | 'scissors' | 'knife' | 'eraser' | 'width' | 'shapeBuilder' | 'paintBucket';
161
180
  declare const VECTOR_TOOLS: readonly VectorTool[];
162
181
  /** Keyboard modifiers held during a pointer event. */
163
182
  interface VectorModifiers {
@@ -192,6 +211,14 @@ interface VectorDefaults extends VectorStyle {
192
211
  type VectorAlign = 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom';
193
212
  type VectorDistribute = 'horizontal' | 'vertical';
194
213
  type VectorBooleanOperation = 'union' | 'subtract' | 'intersect' | 'exclude';
214
+ /**
215
+ * Pathfinder operations: `divide` (every face its own shape), `trim` (hidden parts removed),
216
+ * `merge` (Trim, then touching parts of one fill joined), `crop` (the top shape crops the others),
217
+ * `outline` (outlines cut into open strokes where they meet) and `minusBack` (the top shape minus
218
+ * everything below it).
219
+ */
220
+ type VectorPathfinderOperation = 'divide' | 'trim' | 'merge' | 'crop' | 'outline' | 'minusBack';
221
+ declare const VECTOR_PATHFINDER_OPERATIONS: readonly VectorPathfinderOperation[];
195
222
  type VectorArrange = 'front' | 'forward' | 'backward' | 'back';
196
223
  /** Average: line anchors up on a horizontal line (same y), a vertical one (same x), or both. */
197
224
  type VectorAverageAxis = 'horizontal' | 'vertical' | 'both';
@@ -408,6 +435,11 @@ interface VectorRenderStrokeParts {
408
435
  d: string;
409
436
  /** Width to draw it with: twice the stroke width when aligned, half of it being clipped away. */
410
437
  width: number;
438
+ /**
439
+ * A variable-width stroke: the area to fill with `stroke` (nonzero) instead of stroking `d`,
440
+ * clipped or masked like the stroke would be.
441
+ */
442
+ outline?: string;
411
443
  /**
412
444
  * Inside: a `<clipPath id>` holding the shape (`d`, `clip-rule` = `fillRule`). Outside: a
413
445
  * `<mask id>` in user space over `bounds`, white with the shape (`d`) in black.
@@ -422,6 +454,10 @@ interface VectorRenderStrokeParts {
422
454
  }
423
455
  /** The stroke parts of a path whose stroke needs more than one element, in its own space (undefined otherwise). */
424
456
  declare function vectorStrokeSvgParts(node: VectorPathNode, clipId: string, precision?: number): VectorRenderStrokeParts | undefined;
457
+ /** A width profile as a data attribute: `t,left,right` points separated by `;`. */
458
+ declare function widthProfileToAttribute(points: readonly VectorWidthPoint[], precision?: number): string;
459
+ /** Reads `widthProfileToAttribute` output (invalid points are dropped). */
460
+ declare function widthProfileFromAttribute(value: string | undefined): VectorWidthPoint[];
425
461
  /** Serializes a vector document as a standalone SVG string. */
426
462
  declare function vectorDocumentToSvg(doc: VectorDocument, options?: VectorSvgExportOptions): string;
427
463
  interface VectorSvgImportOptions {
@@ -491,6 +527,136 @@ declare function nextVectorCornerKind(kind: VectorCornerKind | undefined): Vecto
491
527
  /** Every anchor of a subpath given the same live corner (radius 0 clears them). */
492
528
  declare function setSubpathCorners(sp: VectorSubpath, radius: number, kind?: VectorCornerKind): VectorSubpath;
493
529
 
530
+ /**
531
+ * Variable-width stroke profiles: stroke widths at positions along a path (each subpath on its
532
+ * own), interpolated smoothly and held flat before the first and after the last point. Each
533
+ * point has a left and a right side scale (looking along the path on screen, y down), so a
534
+ * stroke can grow on one side only.
535
+ *
536
+ * Ported from ArtCraft (MIT OR Apache-2.0, see THIRD_PARTY_NOTICES.md):
537
+ * - figcraft `crates/doc/src/props.rs` — `WidthProfile` / `WidthPoint`: sanitising, side
538
+ * scales, inserting and moving points, and the monotone cubic (Fritsch–Carlson) interpolation
539
+ * that never overshoots its neighbouring points.
540
+ * - vectorcraft `crates/doc/src/appearance.rs` — `WidthProfile` as `(t, left, right)` points,
541
+ * discontinuous points (two points at one `t` make a step) and the profile presets.
542
+ * - effectcraft `crates/path/src/varstroke.rs` — `width_factor`: the parametric Taper (lengths,
543
+ * end widths, ease) and Wave (amount, cycles, phase) shapes, used here as profile generators.
544
+ */
545
+
546
+ /** The most points a profile keeps. */
547
+ declare const VECTOR_WIDTH_PROFILE_MAX_POINTS = 64;
548
+ /** The widest a side can be, as a multiple of the stroke width. */
549
+ declare const VECTOR_WIDTH_PROFILE_MAX_SCALE = 1000;
550
+ /** Positions closer than this are the same place (the two sides of a discontinuous point). */
551
+ declare const VECTOR_WIDTH_SAME_T = 0.000001;
552
+ /** Built-in profiles. `uniform` is the plain stroke (no profile). */
553
+ type VectorWidthPreset = 'uniform' | 'taperStart' | 'taperEnd' | 'taperBoth' | 'bulge' | 'pinch' | 'teardrop' | 'wave' | 'pressure';
554
+ /** One preset as a menu shows it. */
555
+ interface VectorWidthPresetInfo {
556
+ id: VectorWidthPreset;
557
+ label: string;
558
+ points: readonly VectorWidthPoint[];
559
+ }
560
+ /** The built-in profiles, in menu order. */
561
+ declare const VECTOR_WIDTH_PRESETS: readonly VectorWidthPresetInfo[];
562
+ declare const VECTOR_WIDTH_PRESET_IDS: readonly VectorWidthPreset[];
563
+ /**
564
+ * A profile as the outline uses it: finite points only, `t` in 0–1, side scales in 0–1000,
565
+ * sorted by `t` (stable, so a step keeps its order), at most 64 points. Points missing a side
566
+ * take the other side's scale.
567
+ */
568
+ declare function sanitizeWidthProfile(points: readonly Partial<VectorWidthPoint>[] | null | undefined): VectorWidthPoint[];
569
+ /** True when the profile draws a plain stroke: no points, or every side at scale 1. */
570
+ declare function isUniformWidthProfile(points: readonly VectorWidthPoint[] | null | undefined): boolean;
571
+ /**
572
+ * The left and right side scales at `t` (0–1 along the subpath by length). Each side is
573
+ * interpolated on its own with a monotone cubic, so the width never overshoots its points;
574
+ * a profile without points is uniform (1, 1).
575
+ */
576
+ declare function widthProfileAt(points: readonly VectorWidthPoint[] | null | undefined, t: number): {
577
+ left: number;
578
+ right: number;
579
+ };
580
+ /** The largest side scale (the interpolation never exceeds its points); 1 without a profile. */
581
+ declare function widthProfileMaxScale(points: readonly VectorWidthPoint[] | null | undefined): number;
582
+ /** The points of a preset (empty for `uniform`), or null for an unknown id. */
583
+ declare function widthProfilePreset(id: string): VectorWidthPoint[] | null;
584
+ /** The preset a profile matches: `uniform` without one (or all at scale 1), `custom` when none matches. */
585
+ declare function widthProfilePresetId(points: readonly VectorWidthPoint[] | null | undefined): VectorWidthPreset | 'custom';
586
+ /** The profile of the reversed path: positions mirrored and the sides swapped. */
587
+ declare function reverseWidthProfile(points: readonly VectorWidthPoint[]): VectorWidthPoint[];
588
+ /** The profile of a mirrored path (it runs the same way, but its sides swap). */
589
+ declare function mirrorWidthProfile(points: readonly VectorWidthPoint[]): VectorWidthPoint[];
590
+ /**
591
+ * Adds a width point at `t` (side scales `left` / `right`, default: as wide as the stroke is
592
+ * there) and returns the new profile and the point's index. Inserting at the position of an
593
+ * existing point replaces it, unless `step` is set (which makes a discontinuous point).
594
+ */
595
+ declare function insertWidthPoint(points: readonly VectorWidthPoint[] | null | undefined, t: number, sides?: {
596
+ left?: number;
597
+ right?: number;
598
+ }, options?: {
599
+ step?: boolean;
600
+ }): {
601
+ points: VectorWidthPoint[];
602
+ index: number;
603
+ };
604
+ /**
605
+ * Changes point `index`: moves it to `t` (kept between its neighbours, so indices stay put)
606
+ * and / or sets its side scales. Out-of-range indices leave the profile as it is.
607
+ */
608
+ declare function setWidthPoint(points: readonly VectorWidthPoint[], index: number, patch: Partial<VectorWidthPoint>): VectorWidthPoint[];
609
+ /** Removes the points at `indices`. */
610
+ declare function removeWidthPoints(points: readonly VectorWidthPoint[], indices: readonly number[]): VectorWidthPoint[];
611
+ /** A parametric taper (effectcraft's Stroke Taper), lengths as fractions of the path. */
612
+ interface VectorTaperOptions {
613
+ /** Fraction of the path the start taper covers (default 0). */
614
+ startLength?: number;
615
+ /** Fraction the end taper covers (default 0). */
616
+ endLength?: number;
617
+ /** Width at the start as a fraction of the stroke width (default 0: a point). */
618
+ startWidth?: number;
619
+ endWidth?: number;
620
+ /** 0 linear, 1 a quarter circle bulging outwards (default 0). */
621
+ startEase?: number;
622
+ endEase?: number;
623
+ }
624
+ /** A width wave (effectcraft's Stroke Wave): the width swings between `1 − amount` and 1. */
625
+ interface VectorWaveOptions {
626
+ /** 0–1 (default 0.5). */
627
+ amount?: number;
628
+ /** Whole cycles along the path (default 4). */
629
+ cycles?: number;
630
+ /** Degrees (default 0). */
631
+ phase?: number;
632
+ }
633
+ /** The width factor at fraction `t` of a taper and / or a wave (effectcraft `width_factor`). */
634
+ declare function taperWaveFactor(t: number, taper?: VectorTaperOptions | null, wave?: VectorWaveOptions | null): number;
635
+ /**
636
+ * Samples a taper and / or wave into profile points (symmetric), simplified to within
637
+ * `tolerance` of the factor (default 0.01). The monotone interpolation draws them back smoothly.
638
+ */
639
+ declare function generateWidthProfile(options: {
640
+ taper?: VectorTaperOptions | null;
641
+ wave?: VectorWaveOptions | null;
642
+ samples?: number;
643
+ tolerance?: number;
644
+ }): VectorWidthPoint[];
645
+ /** Pen pressure that draws the stroke's own width (a mouse reports 0.5 while a button is down). */
646
+ declare const VECTOR_PRESSURE_NOMINAL = 0.5;
647
+ /**
648
+ * A profile from pen pressure recorded along a stroke: `(t, pressure 0–1)` samples in order.
649
+ * The width scale is pressure ÷ 0.5 (so half pressure draws the stroke's width, full pressure
650
+ * twice it), at least 0.05; the samples are simplified to within `tolerance` (default 0.02).
651
+ * Returns an empty (uniform) profile when every sample is the same.
652
+ */
653
+ declare function pressureWidthProfile(samples: readonly {
654
+ t: number;
655
+ pressure: number;
656
+ }[], options?: {
657
+ tolerance?: number;
658
+ }): VectorWidthPoint[];
659
+
494
660
  /**
495
661
  * What a guide line shows: `align` lines run from a target through the snapped point or box,
496
662
  * `construction` lines from where a drawn point leaves, `spacing` marks equal gaps and `size`
@@ -725,7 +891,19 @@ interface VectorPathEditOptions {
725
891
  recognizeShapes: boolean;
726
892
  /** Eraser diameter in document units (default 10). */
727
893
  eraserSize: number;
894
+ /**
895
+ * Record pointer pressure on pencil strokes as a width profile: `pen` (default) for pen input
896
+ * only, `all` for any pointer that reports pressure, `off` never.
897
+ */
898
+ pencilPressure: 'pen' | 'all' | 'off';
899
+ /**
900
+ * Paint bucket: gaps up to this distance (document units) between loose ends of outlines are
901
+ * closed when finding the region to fill (default 0, off).
902
+ */
903
+ fillGap: number;
728
904
  }
905
+ /** The gap the toolbars' "Close gaps" toggle sets (document units). */
906
+ declare const VECTOR_FILL_GAP = 6;
729
907
  /** Path-editing options new editors start with. */
730
908
  declare const DEFAULT_VECTOR_PATH_EDIT: Readonly<VectorPathEditOptions>;
731
909
  /** Longest pencil lazy-mouse string (at smoothing 1), in screen pixels. */
@@ -752,6 +930,27 @@ interface VectorEditorOptions {
752
930
  interface VectorPointerInput extends VectorModifiers {
753
931
  /** 0 = primary, 1 = middle (pans), 2 = secondary. Default 0. */
754
932
  button?: number;
933
+ /** `PointerEvent.pressure` (0–1), recorded on pencil strokes. */
934
+ pressure?: number;
935
+ /** `PointerEvent.pointerType` (`mouse`, `pen`, `touch`). */
936
+ pointerType?: string;
937
+ }
938
+ /** One width point of a path's stroke profile; `subpath` is the subpath it is shown on. */
939
+ interface VectorWidthPointRef {
940
+ nodeId: string;
941
+ index: number;
942
+ subpath: number;
943
+ }
944
+ /** A spot on a stroke (width tool): where a drag would add a width point. Positions in document units. */
945
+ interface VectorStrokeSpot {
946
+ nodeId: string;
947
+ subpath: number;
948
+ /** Position along the subpath by length, 0–1. */
949
+ t: number;
950
+ point: Vec2;
951
+ /** Ends of the stroke's width across the path there. */
952
+ left: Vec2;
953
+ right: Vec2;
755
954
  }
756
955
  /** A key press as the controller needs it. */
757
956
  interface VectorKeyInput extends VectorModifiers {
@@ -774,6 +973,12 @@ interface VectorHover {
774
973
  transformHandle?: VectorTransformHandle;
775
974
  /** A live corner widget (direct tool): the corner's anchor. */
776
975
  corner?: VectorAnchorRef;
976
+ /** A width point (width tool): its centre or the end of its left / right side. */
977
+ widthPoint?: VectorWidthPointRef & {
978
+ part: 'center' | 'left' | 'right';
979
+ };
980
+ /** A spot on a stroke away from its width points (width tool). */
981
+ strokeSpot?: VectorStrokeSpot;
777
982
  }
778
983
  /** The drag in progress, for overlays and status text. */
779
984
  type VectorInteraction = {
@@ -816,6 +1021,15 @@ type VectorInteraction = {
816
1021
  tool: 'knife' | 'eraser';
817
1022
  points: Vec2[];
818
1023
  width: number;
1024
+ } | {
1025
+ type: 'builder';
1026
+ mode: 'merge' | 'erase';
1027
+ points: Vec2[];
1028
+ } | {
1029
+ type: 'width';
1030
+ ref: VectorWidthPointRef;
1031
+ mode: 'width' | 'move';
1032
+ width: number;
819
1033
  } | {
820
1034
  type: 'pen';
821
1035
  nodeId: string;
@@ -830,6 +1044,8 @@ interface VectorEditorState {
830
1044
  selection: readonly string[];
831
1045
  /** Selected anchors (direct tool). */
832
1046
  selectedAnchors: readonly VectorAnchorRef[];
1047
+ /** The selected width point (width tool); Delete removes it. */
1048
+ selectedWidthPoint: VectorWidthPointRef | null;
833
1049
  /** The path whose anchors are being edited, if any. */
834
1050
  editingId: string | null;
835
1051
  /** Axis-aligned bounds of the selected nodes in document units. */
@@ -854,6 +1070,8 @@ interface VectorEditorState {
854
1070
  } | null;
855
1071
  /** Last pointer position in document units (for the pen preview), or null when outside. */
856
1072
  pointer: Vec2 | null;
1073
+ /** Shape Builder and paint bucket highlight: faces, line pieces and the gesture's trail. */
1074
+ builder: VectorBuilderPreview | null;
857
1075
  canUndo: boolean;
858
1076
  canRedo: boolean;
859
1077
  undoLabel: string;
@@ -867,6 +1085,37 @@ type VectorActionResult = {
867
1085
  ok: false;
868
1086
  message: string;
869
1087
  };
1088
+ /**
1089
+ * What the Shape Builder or paint bucket highlights, in document units: the faces (filled paths
1090
+ * as SVG path data) under the pointer or touched by the drag, the line pieces an erase would
1091
+ * delete, and the drag's trail. `mode` is `merge`, `erase` (Alt) or `fill` (paint bucket).
1092
+ */
1093
+ interface VectorBuilderPreview {
1094
+ mode: 'merge' | 'erase' | 'fill';
1095
+ faces: BezierPath[];
1096
+ lines: BezierPath[];
1097
+ trail: Vec2[] | null;
1098
+ }
1099
+ /** Result of a Shape Builder gesture. */
1100
+ interface VectorShapeBuilderResult {
1101
+ ok: boolean;
1102
+ message?: string;
1103
+ /** Id of the merged shape (none when erasing). */
1104
+ merged: string | null;
1105
+ faces: number;
1106
+ lines: number;
1107
+ }
1108
+ /** A face of the Shape Builder map (document units). */
1109
+ interface VectorShapeBuilderFace {
1110
+ index: number;
1111
+ /** SVG path data. */
1112
+ d: string;
1113
+ area: number;
1114
+ /** Ids of the paths whose fill covers it, bottom to top (empty for an area only outlines enclose). */
1115
+ sources: string[];
1116
+ /** A point inside it. */
1117
+ point: Vec2 | null;
1118
+ }
870
1119
  interface AddVectorNodeOptions {
871
1120
  /** Group to add into (default: the root). */
872
1121
  parentId?: string;
@@ -893,7 +1142,7 @@ interface VectorShapeInput extends VectorStyle {
893
1142
  name?: string;
894
1143
  }
895
1144
  /** Every field of `VectorStyle`, in the order style panels and commands list them. */
896
- declare const VECTOR_STYLE_KEYS: readonly ["fill", "stroke", "strokeWidth", "strokeLinecap", "strokeLinejoin", "strokeDasharray", "fillRule", "strokeAlign", "startArrow", "endArrow", "arrowAlign", "startArrowScale", "endArrowScale"];
1145
+ declare const VECTOR_STYLE_KEYS: readonly ["fill", "stroke", "strokeWidth", "strokeLinecap", "strokeLinejoin", "strokeDasharray", "fillRule", "strokeAlign", "startArrow", "endArrow", "arrowAlign", "startArrowScale", "endArrowScale", "strokeWidthProfile"];
897
1146
  /** Clipboard payload type written by `copy()`. */
898
1147
  declare const VECTOR_CLIPBOARD_TYPE = "pixerate/vector";
899
1148
  /** Screen distance of the rotation handle above the selection box. */
@@ -930,6 +1179,37 @@ interface VectorCornerWidget {
930
1179
  * THIRD_PARTY_NOTICES.md), as is the `corner` drag below.
931
1180
  */
932
1181
  declare function getVectorCornerWidgets(state: Pick<VectorEditorState, 'document' | 'selection' | 'editingId' | 'tool' | 'pen' | 'selectedAnchors' | 'viewport'>): VectorCornerWidget[];
1182
+ /**
1183
+ * The line a path's stroke follows (node space; shortened under `tip` arrowheads) and the
1184
+ * distance a side scale of 1 reaches from it (half the drawn width: twice the stroke width for
1185
+ * inside / outside strokes). Null for paths without a visible stroke.
1186
+ */
1187
+ declare function vectorStrokeWidthGeometry(node: VectorPathNode): {
1188
+ line: BezierPath;
1189
+ unit: number;
1190
+ } | null;
1191
+ /** A width point of the width tool, in document units. */
1192
+ interface VectorWidthHandle {
1193
+ ref: VectorWidthPointRef;
1194
+ /** The point on the path. */
1195
+ x: number;
1196
+ y: number;
1197
+ /** Ends of its left and right sides. */
1198
+ left: Vec2;
1199
+ right: Vec2;
1200
+ t: number;
1201
+ /** Side scales (multiples of half the stroke width). */
1202
+ leftScale: number;
1203
+ rightScale: number;
1204
+ selected: boolean;
1205
+ }
1206
+ /**
1207
+ * The width points the width tool shows: every profile point on every subpath of the stroke
1208
+ * under the pointer, the selected paths and the stroke being edited. Ported from ArtCraft
1209
+ * vectorcraft `crates/tools/src/distort/width.rs` (MIT OR Apache-2.0, see
1210
+ * THIRD_PARTY_NOTICES.md), as are the `width` drag and hover below.
1211
+ */
1212
+ declare function getVectorWidthHandles(state: Pick<VectorEditorState, 'document' | 'selection' | 'tool' | 'hover' | 'interaction' | 'selectedWidthPoint'>): VectorWidthHandle[];
933
1213
  /** Looks up an anchor (positions in its node's own space). */
934
1214
  declare function getAnchor(doc: VectorDocument, ref: VectorAnchorRef): VectorAnchor | undefined;
935
1215
  /** An anchor with its position and handles in document space (its node's transforms applied). */
@@ -986,6 +1266,8 @@ declare function vectorToolLabel(tool: VectorTool): string;
986
1266
  declare const VECTOR_TOOL_SHORTCUTS: Readonly<Record<VectorTool, string>>;
987
1267
  /** Short glyphs for tool buttons (pair them with `vectorToolLabel` for the accessible name). */
988
1268
  declare const VECTOR_TOOL_GLYPHS: Readonly<Record<VectorTool, string>>;
1269
+ /** Names of the Pathfinder operations (undo steps, groups and buttons). */
1270
+ declare const VECTOR_PATHFINDER_LABELS: Readonly<Record<VectorPathfinderOperation, string>>;
989
1271
  /**
990
1272
  * Headless state for a vector editor: a document of paths and groups, select / direct /
991
1273
  * pen / pencil / shape tools driven by pointer and key events, undo, transforms, boolean
@@ -998,6 +1280,7 @@ declare class VectorEditorController {
998
1280
  private doc;
999
1281
  private selection;
1000
1282
  private anchors;
1283
+ private widthPoint;
1001
1284
  private editingId;
1002
1285
  private pen;
1003
1286
  private tool;
@@ -1017,6 +1300,13 @@ declare class VectorEditorController {
1017
1300
  private hoverTargets;
1018
1301
  private spaceHeld;
1019
1302
  private clipboard;
1303
+ /** Shape Builder map of the selection, kept while the document and the selection stay the same. */
1304
+ private builderCache;
1305
+ /** Paint bucket map of the visible outlines. */
1306
+ private fillCache;
1307
+ private builderPreview;
1308
+ /** What the highlight shows, to skip notifying when the pointer stays over the same face. */
1309
+ private builderHoverKey;
1020
1310
  private readonly createId;
1021
1311
  private readonly onChange?;
1022
1312
  private readonly listeners;
@@ -1131,6 +1421,19 @@ declare class VectorEditorController {
1131
1421
  }, ids?: readonly string[], options?: {
1132
1422
  label?: string;
1133
1423
  }): VectorActionResult;
1424
+ /**
1425
+ * Sets the variable-width profile of the selected (or given) paths: a preset id
1426
+ * (`uniform` removes the profile), points, or a parametric taper / wave. Returns an error for
1427
+ * an unknown preset.
1428
+ */
1429
+ setWidthProfile(profile: VectorWidthPreset | readonly VectorWidthPoint[] | {
1430
+ taper?: VectorTaperOptions;
1431
+ wave?: VectorWaveOptions;
1432
+ } | null, options?: {
1433
+ ids?: readonly string[];
1434
+ }): VectorActionResult;
1435
+ /** Removes one width point of a path's profile (the width tool's Delete). */
1436
+ removeWidthPoint(ref: Pick<VectorWidthPointRef, 'nodeId' | 'index'>): VectorActionResult;
1134
1437
  /**
1135
1438
  * Sets the live corner radius (and optionally the kind) of anchors: `refs`, else the selected
1136
1439
  * anchors (direct tool), else every anchor of the `ids` / selected paths. Radius 0 makes the
@@ -1258,6 +1561,56 @@ declare class VectorEditorController {
1258
1561
  breakApart(options?: {
1259
1562
  ids?: readonly string[];
1260
1563
  }): VectorActionResult;
1564
+ /**
1565
+ * Pathfinder: Divide, Trim, Merge, Crop, Outline or Minus Back over the selected (or given)
1566
+ * paths, in document space (rotated nodes and groups included, live corners cut). Unfilled
1567
+ * stroked paths take part as the area their stroke paints (Divide: open ones cut instead).
1568
+ * The results replace the operands at the place of the top-most one, grouped when there are
1569
+ * several; each keeps the style of the operand whose area it is. Returns the new path ids,
1570
+ * or an empty list when nothing came out.
1571
+ */
1572
+ pathfinder(op: VectorPathfinderOperation, options?: {
1573
+ ids?: readonly string[];
1574
+ }): string[];
1575
+ /** The Shape Builder map of the selected (or given) paths, cached per document and selection. */
1576
+ private shapeBuilderMap;
1577
+ /** The faces the Shape Builder offers for the selected (or given) paths (document units). */
1578
+ getShapeBuilderFaces(options?: {
1579
+ ids?: readonly string[];
1580
+ }): VectorShapeBuilderFace[];
1581
+ /** Pick distance of the Shape Builder's erase for line pieces (document units). */
1582
+ private builderLineTolerance;
1583
+ /**
1584
+ * Shape Builder gesture along `points` (document units; one point is a click) over the faces
1585
+ * the selected (or given) paths make. Merges the faces touched into one shape styled like the
1586
+ * top-most shape over the first face (the current fill for a face only outlines enclose);
1587
+ * with `erase` deletes them, and the pieces of unfilled open paths within `tolerance`. Every
1588
+ * shape covering a touched face loses that area. One undo step.
1589
+ */
1590
+ shapeBuilder(points: readonly Vec2[], options?: {
1591
+ ids?: readonly string[];
1592
+ erase?: boolean;
1593
+ tolerance?: number;
1594
+ }): VectorShapeBuilderResult;
1595
+ private applyShapeBuilder;
1596
+ /** The paint bucket's map of the visible outlines, cached per document and gap. */
1597
+ private fillMap;
1598
+ /**
1599
+ * Paint bucket: the region the visible outlines enclose around `point` (document units),
1600
+ * crossings split and islands left as holes, becomes a new path filled with the current fill
1601
+ * default, placed just below the selection (or on top when nothing is selected). `gap`
1602
+ * (default `editing.fillGap`) closes gaps up to that size between loose ends. Returns the new
1603
+ * path's id, or null when nothing encloses the point.
1604
+ */
1605
+ fillRegion(point: Vec2, options?: {
1606
+ gap?: number;
1607
+ }): string | null;
1608
+ /** Updates the Shape Builder / paint bucket highlight for the pointer at `p`; true when it changed. */
1609
+ private hoverBuilder;
1610
+ private builderPreviewOf;
1611
+ private downBuilder;
1612
+ private moveBuilder;
1613
+ private upBuilder;
1261
1614
  private updateAnchors;
1262
1615
  /** Moves anchors by a document-space offset (converted into each node's own space). */
1263
1616
  private movedAnchors;
@@ -1403,6 +1756,12 @@ declare class VectorEditorController {
1403
1756
  /** Endpoints of open subpaths of unlocked visible paths (pen tool resumes from them). */
1404
1757
  private openEndpoints;
1405
1758
  private computeHover;
1759
+ private widthView;
1760
+ /** The width point centre or side end under `screen` (width tool). */
1761
+ private hitWidthHandle;
1762
+ /** The nearest stroked, unlocked visible path whose stroke is under document point `p` (width tool). */
1763
+ private strokeSpotAt;
1764
+ private downWidth;
1406
1765
  /** The nearest outline point of any visible, unlocked path within the pick distance of document point `p`. */
1407
1766
  private nearestOutline;
1408
1767
  private sameHover;
@@ -1517,6 +1876,22 @@ interface VectorRenderCornerWidget {
1517
1876
  /** Its corners are being dragged. */
1518
1877
  active: boolean;
1519
1878
  }
1879
+ /**
1880
+ * A width point of the width tool in screen pixels: a diamond at (`x`, `y`) on the path and a
1881
+ * line across the stroke from `left` to `right`, with a handle at each end.
1882
+ */
1883
+ interface VectorRenderWidthPoint {
1884
+ ref: VectorWidthPointRef;
1885
+ x: number;
1886
+ y: number;
1887
+ left: Vec2;
1888
+ right: Vec2;
1889
+ selected: boolean;
1890
+ /** The part under the pointer, if any. */
1891
+ hovered: 'center' | 'left' | 'right' | null;
1892
+ /** Being dragged. */
1893
+ active: boolean;
1894
+ }
1520
1895
  /** A smart guide line in screen pixels. */
1521
1896
  interface VectorRenderGuideLine {
1522
1897
  kind: VectorGuideKind;
@@ -1586,6 +1961,29 @@ interface VectorOverlayRenderData {
1586
1961
  * Alt-click to cycle round / inverted / chamfer, click to pick its corner alone.
1587
1962
  */
1588
1963
  cornerWidgets: VectorRenderCornerWidget[];
1964
+ /** Width points of the width tool (screen space). */
1965
+ widthPoints: VectorRenderWidthPoint[];
1966
+ /**
1967
+ * Where a width-tool drag would add a width point (screen space): draw a dashed line from
1968
+ * `left` to `right` and a hollow diamond at (`x`, `y`).
1969
+ */
1970
+ widthSpot: {
1971
+ x: number;
1972
+ y: number;
1973
+ left: Vec2;
1974
+ right: Vec2;
1975
+ } | null;
1976
+ /**
1977
+ * Shape Builder and paint bucket highlight (screen space): `faces` are filled paths (fill
1978
+ * them translucent and outline them), `lines` are line pieces an erase deletes, `trail` is
1979
+ * the drag's polyline. `mode` is `merge`, `erase` (Alt) or `fill` (paint bucket).
1980
+ */
1981
+ builder: {
1982
+ mode: 'merge' | 'erase' | 'fill';
1983
+ faces: string[];
1984
+ lines: string[];
1985
+ trail: string | null;
1986
+ } | null;
1589
1987
  /** A short status, e.g. "W 120 × H 80" or "45°". */
1590
1988
  status: string | null;
1591
1989
  }
@@ -1612,7 +2010,16 @@ declare const VECTOR_OVERLAY_THEME: {
1612
2010
  readonly handleRadius: 3.5;
1613
2011
  /** Radius of a live corner widget (a ring with a dot). */
1614
2012
  readonly cornerWidgetRadius: 4;
2013
+ /** Half the diagonal of a width point's diamond. */
2014
+ readonly widthPointSize: 5;
2015
+ /** Shape Builder faces to merge and paint bucket regions. */
2016
+ readonly builderFill: "rgba(14, 165, 233, 0.22)";
2017
+ /** Shape Builder faces and line pieces an Alt gesture deletes. */
2018
+ readonly builderErase: "#ef4444";
2019
+ readonly builderEraseFill: "rgba(239, 68, 68, 0.22)";
1615
2020
  };
2021
+ /** SVG path data of the diamond a width point is drawn with (screen pixels). */
2022
+ declare function vectorDiamondPath(x: number, y: number, r?: number): string;
1616
2023
  interface ModifierEventLike {
1617
2024
  shiftKey?: boolean;
1618
2025
  altKey?: boolean;
@@ -1625,10 +2032,17 @@ declare function toVectorModifiers(event: ModifierEventLike): {
1625
2032
  alt: boolean;
1626
2033
  mod: boolean;
1627
2034
  };
1628
- /** A pointer event as `VectorEditorController.pointerDown/Move/Up` input. */
2035
+ /**
2036
+ * A pointer event as `VectorEditorController.pointerDown/Move/Up` input: modifiers, button,
2037
+ * and the pressure and pointer type the pencil records as a width profile.
2038
+ */
1629
2039
  declare function toVectorPointerInput(event: ModifierEventLike & {
1630
2040
  button?: number;
2041
+ pressure?: number;
2042
+ pointerType?: string;
1631
2043
  }): {
2044
+ pointerType?: string | undefined;
2045
+ pressure?: number | undefined;
1632
2046
  button: number | undefined;
1633
2047
  shift: boolean;
1634
2048
  alt: boolean;
@@ -1657,6 +2071,9 @@ interface VectorSelectionStyle {
1657
2071
  arrowAlign: VectorArrowAlign;
1658
2072
  startArrowScale: number;
1659
2073
  endArrowScale: number;
2074
+ /** The first path's width profile (null when uniform) and the preset it matches. */
2075
+ strokeWidthProfile: VectorWidthPoint[] | null;
2076
+ widthProfile: VectorWidthPreset | 'custom';
1660
2077
  /**
1661
2078
  * Live corners of the selected anchors (direct tool) or of every corner of the selected
1662
2079
  * paths: the first one's radius and kind, and how many corners there are (0: none to round).
@@ -1677,6 +2094,7 @@ interface VectorSelectionStyle {
1677
2094
  arrowAlign: boolean;
1678
2095
  startArrowScale: boolean;
1679
2096
  endArrowScale: boolean;
2097
+ widthProfile: boolean;
1680
2098
  cornerRadius: boolean;
1681
2099
  cornerKind: boolean;
1682
2100
  };
@@ -1703,6 +2121,16 @@ interface VectorPathAction {
1703
2121
  }
1704
2122
  /** Join, Average, Cut at Points, Remove Redundant Points, Smooth and Outline Stroke, as the toolbars show them. */
1705
2123
  declare const VECTOR_PATH_ACTIONS: readonly VectorPathAction[];
2124
+ /** A Pathfinder button of the bundled toolbars. */
2125
+ interface VectorPathfinderAction {
2126
+ id: VectorPathfinderOperation;
2127
+ label: string;
2128
+ title: string;
2129
+ /** Paths (or groups) it needs selected. */
2130
+ min: number;
2131
+ }
2132
+ /** Divide, Trim, Merge, Crop, Outline and Minus Back, as the toolbars show them. */
2133
+ declare const VECTOR_PATHFINDER_ACTIONS: readonly VectorPathfinderAction[];
1706
2134
  /** The on / off path-editing settings the toolbars toggle. */
1707
2135
  declare const VECTOR_EDIT_TOGGLES: readonly {
1708
2136
  key: 'keepShapeOnDelete' | 'curvatureMoves' | 'recognizeShapes';
@@ -1954,8 +2382,15 @@ interface VectorStrokeParts {
1954
2382
  declare function isClosedBezierShape(path: BezierPath): boolean;
1955
2383
  /** The alignment a stroke is drawn with: the style's, or `center` for open shapes. */
1956
2384
  declare function effectiveStrokeAlign(style: Pick<VectorStyle, 'strokeAlign'>, closedShape: boolean): VectorStrokeAlign;
1957
- /** True when the style asks for more than a plain centred stroke (an alignment or arrowheads). */
2385
+ /** The style's width profile, sanitised, or null when the stroke is uniform. */
2386
+ declare function strokeWidthProfileOf(style: Pick<VectorStyle, 'strokeWidthProfile'>): VectorWidthPoint[] | null;
2387
+ /** True when the style asks for more than a plain centred stroke (an alignment, arrowheads or a width profile). */
1958
2388
  declare function hasStrokeExtras(style: VectorStyle): boolean;
2389
+ /**
2390
+ * The area of the stroke along `parts.line` before alignment clipping: SVG's stroke for a
2391
+ * uniform width, the variable-width outline (`variableStrokeOutline`) for a profiled one.
2392
+ */
2393
+ declare function vectorStrokeLineArea(parts: Pick<VectorStrokeParts, 'line' | 'drawWidth'>, style: VectorStyle, tolerance?: number): BezierPath;
1959
2394
  /** The weight of a head: the stroke width times its scale (at least 0.25). A head is 4 weights long and wide. */
1960
2395
  declare function arrowheadWeight(style: VectorStyle, end: 'start' | 'end'): number;
1961
2396
  /** Distance from the tip where the stroke ends, for a stroke whose cap reaches `cap` past its end. */
@@ -1983,4 +2418,181 @@ declare function hitTestVectorStroke(path: BezierPath, p: Vec2, style: VectorSty
1983
2418
  /** How far the stroke can reach past the outline (for padding bounds and masks). */
1984
2419
  declare function vectorStrokeReach(style: VectorStyle): number;
1985
2420
 
1986
- export { type AddVectorNodeOptions, AffineMatrix, DEFAULT_VECTOR_PATH_EDIT, DEFAULT_VECTOR_SNAP, IDENTITY_MATRIX, KAPPA, LazyMouse, type NearestSegment, type RecognizeInkOptions, SvgGradientDef, VECTOR_ARROWHEADS, VECTOR_ARROWHEAD_LABELS, VECTOR_CLIPBOARD_TYPE, VECTOR_CONSTRUCTION_ANGLES, VECTOR_CORNER_KINDS, VECTOR_CORNER_KIND_LABELS, VECTOR_CORNER_WIDGET_INSET, VECTOR_EDIT_TOGGLES, VECTOR_INK_MAX_CORNERS, VECTOR_OVERLAY_THEME, VECTOR_PATH_ACTIONS, VECTOR_PENCIL_STRING_PX, VECTOR_ROTATE_HANDLE_OFFSET, VECTOR_STROKE_ALIGN_LABELS, VECTOR_STYLE_KEYS, VECTOR_TOOLS, VECTOR_TOOL_GLYPHS, VECTOR_TOOL_SHORTCUTS, VECTOR_TRANSFORM_HANDLES, type Vec2, type VectorActionResult, type VectorAlign, type VectorAnchor, type VectorAnchorRef, type VectorAnchorType, type VectorArrange, type VectorArrowAlign, type VectorArrowhead, type VectorArrowheadShape, type VectorAverageAxis, type VectorBooleanOperation, type VectorBounds, type VectorCommandOptions, type VectorCorner, type VectorCornerInfo, type VectorCornerKind, type VectorCornerWidget, type VectorDefaults, type VectorDistribute, type VectorDocument, VectorEditorController, type VectorEditorOptions, type VectorEditorState, type VectorFillRule, type VectorGroupNode, type VectorGuideKind, type VectorGuideLabel, type VectorGuideLine, type VectorHandleRef, type VectorHover, type VectorInkShape, type VectorInteraction, type VectorKeyInput, type VectorLineCap, type VectorLineJoin, type VectorMatrix, type VectorModifiers, type VectorNode, type VectorNodeListing, type VectorOverlayRenderData, type VectorPaint, type VectorPathAction, type VectorPathEditOptions, type VectorPathNode, type VectorPointSnap, type VectorPointerInput, type VectorRectSnap, type VectorRenderAnchor, type VectorRenderCornerWidget, type VectorRenderGroup, type VectorRenderGuideLabel, type VectorRenderGuideLine, type VectorRenderHandle, type VectorRenderNode, type VectorRenderPath, type VectorRenderStrokeParts, type VectorScaleSnap, type VectorSceneRenderData, type VectorSegmentRef, type VectorSelectionBoxGeometry, type VectorSelectionFrame, type VectorSelectionStyle, type VectorShapeInput, type VectorSnapGuides, type VectorSnapKind, type VectorSnapLeave, type VectorSnapOptions, VectorSnapTargets, type VectorStrokeAlign, type VectorStrokeParts, type VectorStyle, type VectorSubpath, type VectorSvgExportOptions, type VectorSvgImportOptions, type VectorTool, type VectorTransformHandle, type VectorViewport, applyMatrix, applyMatrixLinear, applyVectorCornersAttribute, arrowheadInset, arrowheadPath, arrowheadWeight, bendSegment, bezierToSubpaths, boundsFromPoints, boundsIntersect, cloneAnchor, cloneSubpath, cloneVectorDocument, cloneVectorNode, collectPathNodes, constrainToLeave, convertAnchor, cornerBisectorPoint, cornerRadiusChange, cornerSetback, createVectorCommands, curvatureMoveAnchor, cutSubpathAt, decomposeRigid, effectiveStrokeAlign, ellipseSubpath, eraseFromFill, eraseFromOutline, eraserRegion, expandVectorCorners, expandVectorCornersOf, findVectorNode, fitCornerRadius, getAnchor, getAnchorWorld, getEditablePathIds, getTransformHandlePositions, getVectorCornerWidgets, getVectorOverlayRenderData, getVectorSceneRenderData, getVectorSelectionBoxGeometry, getVectorSelectionFrame, getVectorSelectionStyle, getVisibleAnchors, getVisibleHandles, hasPaint, hasStrokeExtras, hasVectorCorners, hitTestVectorNode, hitTestVectorNodes, hitTestVectorStroke, inferAnchorType, insertAnchor, invertMatrix, isClosedBezierShape, isIdentityMatrix, isVectorTextTarget, joinSubpaths, knifePath, lineSubpath, locateVectorNode, matrixRotation, moveAnchorHandle, multiplyMatrices, nearestSegment, nextVectorCornerKind, nodeMatrix, parseSvgTransform, parseVectorSvg, polygonSubpath, polylineBounds, recognizeInkShape, rectSubpath, removeAnchorKeepingShape, removeAnchors, removeAnchorsKeepingShape, removeRedundantPoints, reverseSubpath, rotateMatrix, roundSubpaths, scaleFor, scaleMatrix, setAnchorCorner, setSubpathCorners, simplifyPolyline, smoothSubpath, splitIntoFaces, splitSubpathAt, starSubpath, subpathPointAt, subpathSegment, subpathSegmentCount, subpathsToBezier, toVectorKeyInput, toVectorModifiers, toVectorPointerInput, transformVectorNode, translateAnchor, translateMatrix, unionBounds, vectorCornerAt, vectorCorners, vectorCornersAttribute, vectorDocumentToSvg, vectorInkShapeName, vectorNodeBounds, vectorNodeRotation, vectorNodeToBezier, vectorPaintToHex, vectorPaintToSvg, vectorParentMatrix, vectorPathData, vectorPathWorldBezier, vectorResizeCursor, vectorStrokeOutline, vectorStrokeOutlinePath, vectorStrokeParts, vectorStrokeReach, vectorStrokeSvgParts, vectorToolLabel, vectorWorldMatrix, walkVectorNodes };
2421
+ /**
2422
+ * The outline of a variable-width stroke, as a clean filled Bézier path.
2423
+ *
2424
+ * Each subpath is flattened (finely enough for the width to vary smoothly) and the stroke is
2425
+ * the union of positively wound pieces: one trapezoid per flattened segment (its ends at the
2426
+ * local side widths), a wedge on the outer side of every bend (the style's join at the path's
2427
+ * own corners, round inside curves) and the caps. Filled with the non-zero rule the union is
2428
+ * exact whatever the profile does; it is built as the boundary those pieces add up to (see
2429
+ * `variableStrokeRings`), normalised with the polygon boolean engine, and every ring is refitted
2430
+ * with cubics (`fitCubics`) to within the tolerance — a real Bézier outline, not a polyline.
2431
+ *
2432
+ * Ported from ArtCraft effectcraft `crates/path/src/varstroke.rs` (`outline`, `dash_intervals`)
2433
+ * (MIT OR Apache-2.0, see THIRD_PARTY_NOTICES.md), with one-sided widths after figcraft
2434
+ * `crates/pathops/src/width.rs` (`variable_outline`).
2435
+ */
2436
+
2437
+ interface VariableStrokeOptions {
2438
+ /** Stroke width: a side scale of 1 reaches half of it from the centre line. */
2439
+ width: number;
2440
+ profile: readonly VectorWidthPoint[];
2441
+ /** Joins at the path's own corners (default `miter`); bends inside curves are always round. */
2442
+ join?: StrokeJoin;
2443
+ /** Default `butt`. */
2444
+ cap?: StrokeCap;
2445
+ /** Default 4 (as SVG). */
2446
+ miterLimit?: number;
2447
+ /** Dash pattern (as SVG); the profile still runs along the whole subpath. */
2448
+ dash?: readonly number[];
2449
+ dashOffset?: number;
2450
+ /** Largest distance of the result from the exact outline (default 0.05). */
2451
+ tolerance?: number;
2452
+ }
2453
+ type Vec = [number, number];
2454
+ /** Arc-length intervals that are "on" for a dash pattern on a path `len` long (effectcraft `dash_intervals`). */
2455
+ declare function dashIntervals(pattern: readonly number[], offset: number, len: number): [number, number][];
2456
+ /**
2457
+ * The rings of a variable-width stroke in the path's own space; filled with the non-zero rule
2458
+ * they are the stroke.
2459
+ *
2460
+ * effectcraft builds the stroke as a union of positively wound pieces: a trapezoid per flattened
2461
+ * segment (its ends at the local side widths), a wedge on the outer side of every bend and the
2462
+ * caps. Unioning thousands of overlapping pieces is slow, so each run is emitted as the boundary
2463
+ * those pieces add up to instead (winding numbers add, so the non-zero fill is the same): the
2464
+ * offset sides with the outer join between them, and on the inner side of a bend either the point
2465
+ * where the two offsets cross (the region cut off is covered by both trapezoids) or, when they do
2466
+ * not cross, a detour through the centre point (which keeps the winding right when segments are
2467
+ * shorter than the width). A closed subpath gives two rings, an open run one.
2468
+ */
2469
+ declare function variableStrokeRings(path: BezierPath, options: VariableStrokeOptions): Point[][];
2470
+ /**
2471
+ * The outline of a variable-width stroke of `path` (side widths from `profile`), as a clean
2472
+ * Bézier path: overlaps removed, outer rings and holes, each refitted with cubics to within
2473
+ * `tolerance` of the exact outline. Fill it with the non-zero rule (either rule works).
2474
+ */
2475
+ declare function variableStrokeOutline(path: BezierPath, options: VariableStrokeOptions): BezierPath;
2476
+ /**
2477
+ * Where point `p` lies relative to the stroke's centre line: the nearest point's contour,
2478
+ * its position `t` by length (0–1), the distance, and the side (`left` looking along the
2479
+ * path on screen) — what hit-testing and the width tool need.
2480
+ */
2481
+ declare function nearestStrokePosition(path: BezierPath, p: Point,
2482
+ /** Only this contour (subpath) of the path. */
2483
+ only?: number): {
2484
+ contour: number;
2485
+ t: number;
2486
+ distance: number;
2487
+ side: 'left' | 'right';
2488
+ point: Point;
2489
+ tangent: Vec;
2490
+ length: number;
2491
+ } | null;
2492
+ /** The point and unit tangent at position `t` (0–1 by length) of contour `index` of `path`. */
2493
+ declare function strokePositionPoint(path: BezierPath, index: number, t: number): {
2494
+ point: Point;
2495
+ tangent: Vec;
2496
+ } | null;
2497
+
2498
+ /** A path node with the matrix of its parent space (parent → document). */
2499
+ interface VectorPathEntry {
2500
+ node: VectorPathNode;
2501
+ parent: AffineMatrix;
2502
+ }
2503
+ /**
2504
+ * The path nodes inside `roots` (or every node when `roots` is null), bottom to top, with their
2505
+ * parent matrices. Hidden nodes are skipped, and locked ones unless `locked` is true.
2506
+ */
2507
+ declare function vectorPathEntries(doc: VectorDocument, roots: readonly string[] | null, options?: {
2508
+ locked?: boolean;
2509
+ }): VectorPathEntry[];
2510
+ /** Whether a subpath, closed, encloses an area (rather than retracing itself). */
2511
+ declare function subpathEnclosesArea(sp: VectorSubpath): boolean;
2512
+ /** How an operand takes part in a Pathfinder operation: its fill, its stroke's area, a cutting line or its bare outline. */
2513
+ type VectorPathfinderPaint = 'fill' | 'stroke' | 'line' | 'outline';
2514
+ /** The Pathfinder shape of a path (document space), and what it stands for. */
2515
+ declare function vectorPathfinderShape(entry: VectorPathEntry, op: PathfinderOperation): PathfinderShape & {
2516
+ paint: VectorPathfinderPaint;
2517
+ };
2518
+ /**
2519
+ * Style of a Pathfinder or Shape Builder result taken from `node`: the node's own style for a
2520
+ * filled area, the stroke's paint as a fill for a stroke's area, or (for Outline edges) a stroke
2521
+ * in the paint of the area the edge bounds. Never carries the node's id, transform or geometry.
2522
+ */
2523
+ declare function vectorResultStyle(node: VectorPathNode, paint: VectorPathfinderPaint, edge?: boolean): Omit<VectorPathNode, 'id' | 'subpaths'>;
2524
+ /** A piece of an unfilled open path between the points where other paths meet it. */
2525
+ interface VectorBuilderLinePiece {
2526
+ path: BezierPath;
2527
+ segments: BezierSegment[];
2528
+ /** Index of the entry it belongs to. */
2529
+ source: number;
2530
+ bounds: {
2531
+ minX: number;
2532
+ minY: number;
2533
+ maxX: number;
2534
+ maxY: number;
2535
+ };
2536
+ }
2537
+ /** The Shape Builder's planar map of a set of paths. */
2538
+ interface VectorShapeBuilderMap {
2539
+ entries: VectorPathEntry[];
2540
+ map: PlanarMap;
2541
+ /** Entries with no closed subpath (cutting lines; their pieces can be erased). */
2542
+ lines: boolean[];
2543
+ pieces: VectorBuilderLinePiece[];
2544
+ }
2545
+ /** What a Shape Builder gesture touches at a point. */
2546
+ type VectorBuilderHit = {
2547
+ face: number;
2548
+ } | {
2549
+ line: number;
2550
+ };
2551
+ /** The faces and line pieces a gesture touched, in the order touched. */
2552
+ interface VectorBuilderTouched {
2553
+ faces: number[];
2554
+ lines: number[];
2555
+ }
2556
+ /**
2557
+ * The Shape Builder map of `entries` (bottom to top). Filled open subpaths that enclose an area
2558
+ * are closed. Null when nothing can be mapped.
2559
+ */
2560
+ declare function vectorShapeBuilderMap(entries: readonly VectorPathEntry[]): VectorShapeBuilderMap | null;
2561
+ /** The face under `p`, or with `lineTolerance` (erasing) first the line piece that close. */
2562
+ declare function vectorShapeBuilderHit(m: VectorShapeBuilderMap, p: Vec2, lineTolerance?: number | null): VectorBuilderHit | null;
2563
+ /** Points along a polyline no more than `step` apart (the pointer's path through faces). */
2564
+ declare function samplePolyline(points: readonly Vec2[], step: number): Vec2[];
2565
+ /** Adds what a point hits to `touched` (each face or piece once). */
2566
+ declare function addBuilderHit(touched: VectorBuilderTouched, hit: VectorBuilderHit | null): boolean;
2567
+ /** What becomes of one entry: unchanged (absent), removed (`null`), or new outlines (document space). */
2568
+ type VectorBuilderReplacement = {
2569
+ kind: 'fill';
2570
+ path: BezierPath;
2571
+ } | {
2572
+ kind: 'pieces';
2573
+ paths: BezierPath[];
2574
+ } | null;
2575
+ interface VectorShapeBuilderPlan {
2576
+ replace: Map<number, VectorBuilderReplacement>;
2577
+ /** The merged shape (document space), styled like entry `style`; `currentFill` when only outlines enclosed it. */
2578
+ merged: {
2579
+ path: BezierPath;
2580
+ style: number;
2581
+ currentFill: boolean;
2582
+ } | null;
2583
+ }
2584
+ /**
2585
+ * What a gesture does: merging (or with `erase`, deleting) the touched faces takes them away
2586
+ * from every shape covering them; line pieces touched (erasing) or lying between touched faces
2587
+ * go; merging adds the union of the faces as a new shape styled like the top-most shape over the
2588
+ * first face touched (or, for a face only outlines enclose, the top-most shape with the current
2589
+ * fill).
2590
+ */
2591
+ declare function planShapeBuilder(m: VectorShapeBuilderMap, touched: VectorBuilderTouched, erase: boolean): VectorShapeBuilderPlan;
2592
+ /**
2593
+ * The planar map of every visible path's outline as drawn (locked ones included), for the paint
2594
+ * bucket. `gap` closes gaps up to that distance between loose ends.
2595
+ */
2596
+ declare function vectorFillMap(doc: VectorDocument, gap?: number): PlanarMap | null;
2597
+
2598
+ export { type AddVectorNodeOptions, AffineMatrix, DEFAULT_VECTOR_PATH_EDIT, DEFAULT_VECTOR_SNAP, IDENTITY_MATRIX, KAPPA, LazyMouse, type NearestSegment, type RecognizeInkOptions, SvgGradientDef, VECTOR_ARROWHEADS, VECTOR_ARROWHEAD_LABELS, VECTOR_CLIPBOARD_TYPE, VECTOR_CONSTRUCTION_ANGLES, VECTOR_CORNER_KINDS, VECTOR_CORNER_KIND_LABELS, VECTOR_CORNER_WIDGET_INSET, VECTOR_EDIT_TOGGLES, VECTOR_FILL_GAP, VECTOR_INK_MAX_CORNERS, VECTOR_OVERLAY_THEME, VECTOR_PATHFINDER_ACTIONS, VECTOR_PATHFINDER_LABELS, VECTOR_PATHFINDER_OPERATIONS, VECTOR_PATH_ACTIONS, VECTOR_PENCIL_STRING_PX, VECTOR_PRESSURE_NOMINAL, VECTOR_ROTATE_HANDLE_OFFSET, VECTOR_STROKE_ALIGN_LABELS, VECTOR_STYLE_KEYS, VECTOR_TOOLS, VECTOR_TOOL_GLYPHS, VECTOR_TOOL_SHORTCUTS, VECTOR_TRANSFORM_HANDLES, VECTOR_WIDTH_PRESETS, VECTOR_WIDTH_PRESET_IDS, VECTOR_WIDTH_PROFILE_MAX_POINTS, VECTOR_WIDTH_PROFILE_MAX_SCALE, VECTOR_WIDTH_SAME_T, type VariableStrokeOptions, type Vec2, type VectorActionResult, type VectorAlign, type VectorAnchor, type VectorAnchorRef, type VectorAnchorType, type VectorArrange, type VectorArrowAlign, type VectorArrowhead, type VectorArrowheadShape, type VectorAverageAxis, type VectorBooleanOperation, type VectorBounds, type VectorBuilderHit, type VectorBuilderLinePiece, type VectorBuilderPreview, type VectorBuilderReplacement, type VectorBuilderTouched, type VectorCommandOptions, type VectorCorner, type VectorCornerInfo, type VectorCornerKind, type VectorCornerWidget, type VectorDefaults, type VectorDistribute, type VectorDocument, VectorEditorController, type VectorEditorOptions, type VectorEditorState, type VectorFillRule, type VectorGroupNode, type VectorGuideKind, type VectorGuideLabel, type VectorGuideLine, type VectorHandleRef, type VectorHover, type VectorInkShape, type VectorInteraction, type VectorKeyInput, type VectorLineCap, type VectorLineJoin, type VectorMatrix, type VectorModifiers, type VectorNode, type VectorNodeListing, type VectorOverlayRenderData, type VectorPaint, type VectorPathAction, type VectorPathEditOptions, type VectorPathEntry, type VectorPathNode, type VectorPathfinderAction, type VectorPathfinderOperation, type VectorPathfinderPaint, type VectorPointSnap, type VectorPointerInput, type VectorRectSnap, type VectorRenderAnchor, type VectorRenderCornerWidget, type VectorRenderGroup, type VectorRenderGuideLabel, type VectorRenderGuideLine, type VectorRenderHandle, type VectorRenderNode, type VectorRenderPath, type VectorRenderStrokeParts, type VectorRenderWidthPoint, type VectorScaleSnap, type VectorSceneRenderData, type VectorSegmentRef, type VectorSelectionBoxGeometry, type VectorSelectionFrame, type VectorSelectionStyle, type VectorShapeBuilderFace, type VectorShapeBuilderMap, type VectorShapeBuilderPlan, type VectorShapeBuilderResult, type VectorShapeInput, type VectorSnapGuides, type VectorSnapKind, type VectorSnapLeave, type VectorSnapOptions, VectorSnapTargets, type VectorStrokeAlign, type VectorStrokeParts, type VectorStrokeSpot, type VectorStyle, type VectorSubpath, type VectorSvgExportOptions, type VectorSvgImportOptions, type VectorTaperOptions, type VectorTool, type VectorTransformHandle, type VectorViewport, type VectorWaveOptions, type VectorWidthHandle, type VectorWidthPoint, type VectorWidthPointRef, type VectorWidthPreset, type VectorWidthPresetInfo, addBuilderHit, applyMatrix, applyMatrixLinear, applyVectorCornersAttribute, arrowheadInset, arrowheadPath, arrowheadWeight, bendSegment, bezierToSubpaths, boundsFromPoints, boundsIntersect, cloneAnchor, cloneSubpath, cloneVectorDocument, cloneVectorNode, collectPathNodes, constrainToLeave, convertAnchor, cornerBisectorPoint, cornerRadiusChange, cornerSetback, createVectorCommands, curvatureMoveAnchor, cutSubpathAt, dashIntervals, decomposeRigid, effectiveStrokeAlign, ellipseSubpath, eraseFromFill, eraseFromOutline, eraserRegion, expandVectorCorners, expandVectorCornersOf, findVectorNode, fitCornerRadius, generateWidthProfile, getAnchor, getAnchorWorld, getEditablePathIds, getTransformHandlePositions, getVectorCornerWidgets, getVectorOverlayRenderData, getVectorSceneRenderData, getVectorSelectionBoxGeometry, getVectorSelectionFrame, getVectorSelectionStyle, getVectorWidthHandles, getVisibleAnchors, getVisibleHandles, hasPaint, hasStrokeExtras, hasVectorCorners, hitTestVectorNode, hitTestVectorNodes, hitTestVectorStroke, inferAnchorType, insertAnchor, insertWidthPoint, invertMatrix, isClosedBezierShape, isIdentityMatrix, isUniformWidthProfile, isVectorTextTarget, joinSubpaths, knifePath, lineSubpath, locateVectorNode, matrixRotation, mirrorWidthProfile, moveAnchorHandle, multiplyMatrices, nearestSegment, nearestStrokePosition, nextVectorCornerKind, nodeMatrix, parseSvgTransform, parseVectorSvg, planShapeBuilder, polygonSubpath, polylineBounds, pressureWidthProfile, recognizeInkShape, rectSubpath, removeAnchorKeepingShape, removeAnchors, removeAnchorsKeepingShape, removeRedundantPoints, removeWidthPoints, reverseSubpath, reverseWidthProfile, rotateMatrix, roundSubpaths, samplePolyline, sanitizeWidthProfile, scaleFor, scaleMatrix, setAnchorCorner, setSubpathCorners, setWidthPoint, simplifyPolyline, smoothSubpath, splitIntoFaces, splitSubpathAt, starSubpath, strokePositionPoint, strokeWidthProfileOf, subpathEnclosesArea, subpathPointAt, subpathSegment, subpathSegmentCount, subpathsToBezier, taperWaveFactor, toVectorKeyInput, toVectorModifiers, toVectorPointerInput, transformVectorNode, translateAnchor, translateMatrix, unionBounds, variableStrokeOutline, variableStrokeRings, vectorCornerAt, vectorCorners, vectorCornersAttribute, vectorDiamondPath, vectorDocumentToSvg, vectorFillMap, vectorInkShapeName, vectorNodeBounds, vectorNodeRotation, vectorNodeToBezier, vectorPaintToHex, vectorPaintToSvg, vectorParentMatrix, vectorPathData, vectorPathEntries, vectorPathWorldBezier, vectorPathfinderShape, vectorResizeCursor, vectorResultStyle, vectorShapeBuilderHit, vectorShapeBuilderMap, vectorStrokeLineArea, vectorStrokeOutline, vectorStrokeOutlinePath, vectorStrokeParts, vectorStrokeReach, vectorStrokeSvgParts, vectorStrokeWidthGeometry, vectorToolLabel, vectorWorldMatrix, walkVectorNodes, widthProfileAt, widthProfileFromAttribute, widthProfileMaxScale, widthProfilePreset, widthProfilePresetId, widthProfileToAttribute };