@pixerate/editor 0.37.0 → 0.39.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 +7 -0
- package/dist/canvas/index.cjs +43 -25
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +16 -3
- package/dist/canvas/index.d.ts +16 -3
- package/dist/canvas/index.js +19 -1
- package/dist/canvas/index.js.map +1 -1
- package/dist/{chunk-HPEKB352.js → chunk-3LHWTGHW.js} +803 -23
- package/dist/chunk-3LHWTGHW.js.map +1 -0
- package/dist/{chunk-GVB7ZPLZ.cjs → chunk-VNYRI265.cjs} +806 -26
- package/dist/chunk-VNYRI265.cjs.map +1 -0
- package/dist/{stroke-ysgaPpAo.d.ts → pathfinder-D98S2lV5.d.ts} +252 -1
- package/dist/{stroke-CWjFKal4.d.cts → pathfinder-DKRcXiLS.d.cts} +252 -1
- package/dist/vector/index.cjs +867 -220
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +285 -3
- package/dist/vector/index.d.ts +285 -3
- package/dist/vector/index.js +672 -25
- package/dist/vector/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-GVB7ZPLZ.cjs.map +0 -1
- package/dist/chunk-HPEKB352.js.map +0 -1
|
@@ -671,6 +671,48 @@ declare function dividePaths(operands: PathOperandInput[], options?: PathOpsOpti
|
|
|
671
671
|
declare function normalizeBezierPath(path: BezierPathInput, fillRule?: PolygonFillRule, options?: PathOpsOptions): BezierPath;
|
|
672
672
|
/** Filled area of a path under its fill rule (overlaps counted once; exact for curves). */
|
|
673
673
|
declare function bezierPathArea(path: BezierPathInput, fillRule?: PolygonFillRule, options?: PathOpsOptions): number;
|
|
674
|
+
/** One edge of `planarSplit`: a piece of an input segment between two vertices. */
|
|
675
|
+
interface PlanarSplitEdge {
|
|
676
|
+
/** Vertex indices at the start and end of `pts`. */
|
|
677
|
+
a: number;
|
|
678
|
+
b: number;
|
|
679
|
+
/** Control points from vertex `a` to vertex `b`. */
|
|
680
|
+
pts: Point[];
|
|
681
|
+
/** Inputs whose chains run along this edge, ascending (several where outlines coincide). */
|
|
682
|
+
operands: number[];
|
|
683
|
+
/** The source segment it is a piece of (index into `sources`) and its parameters there at `a` and `b`. */
|
|
684
|
+
src: number;
|
|
685
|
+
sa: number;
|
|
686
|
+
sb: number;
|
|
687
|
+
}
|
|
688
|
+
interface PlanarSplitResult {
|
|
689
|
+
vertices: Point[];
|
|
690
|
+
edges: PlanarSplitEdge[];
|
|
691
|
+
/** The input segments, as `src` refers to them. */
|
|
692
|
+
sources: BezierSegment[];
|
|
693
|
+
eps: number;
|
|
694
|
+
scale: number;
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* The chains of every input (open or closed, as given: nothing is closed for filling) split
|
|
698
|
+
* wherever they cross or touch each other or themselves, with the same intersection search as
|
|
699
|
+
* the boolean operations. Coincident pieces become one edge that lists every input along it.
|
|
700
|
+
* Throws a `PathOpsError` when the search does not settle or the input is not finite.
|
|
701
|
+
*/
|
|
702
|
+
declare function planarSplit(inputs: readonly (readonly (readonly BezierSegment[])[])[], options?: PathOpsOptions): PlanarSplitResult;
|
|
703
|
+
/** Result of `pathBooleanSelect`: per selector, its connected parts (each an outer subpath with its holes). */
|
|
704
|
+
interface PathSelectResult extends PathOpsReport {
|
|
705
|
+
parts: BezierPath[][];
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Several boolean selections over one arrangement of the operands (the Pathfinder panel's
|
|
709
|
+
* Trim, Merge, Crop and Minus Back are each a selection per output). A selector gets the
|
|
710
|
+
* ascending indices of the operands covering an area and keeps the area when it returns true.
|
|
711
|
+
* Each selection comes back as its connected parts, largest first, built as `pathBoolean`
|
|
712
|
+
* builds its result; areas that only touch at an edge are one part. Falls back to the
|
|
713
|
+
* polygon engine like `pathBoolean`.
|
|
714
|
+
*/
|
|
715
|
+
declare function pathBooleanSelect(operands: PathOperandInput[], selectors: readonly ((covering: readonly number[]) => boolean)[], options?: PathOpsOptions): PathSelectResult;
|
|
674
716
|
|
|
675
717
|
/**
|
|
676
718
|
* Offset Path and Outline Stroke on Bézier paths.
|
|
@@ -758,4 +800,213 @@ declare function outlineStroke(input: BezierPathInput, options: OutlineStrokeOpt
|
|
|
758
800
|
*/
|
|
759
801
|
declare function offsetPath(input: BezierPathInput, distance: number, options?: OffsetPathOptions): BezierPath;
|
|
760
802
|
|
|
761
|
-
|
|
803
|
+
/**
|
|
804
|
+
* Planar maps: the faces and edges a set of paths divides the plane into (Shape Builder, fill
|
|
805
|
+
* regions, Pathfinder Outline).
|
|
806
|
+
*
|
|
807
|
+
* Unlike `dividePaths`, which splits the *filled areas* of closed shapes, every path here is an
|
|
808
|
+
* edge, open ones included: three crossing lines enclose a triangle, a line across a rectangle
|
|
809
|
+
* splits it in two, and an area enclosed by paths is a face whether or not anything fills it.
|
|
810
|
+
*
|
|
811
|
+
* 1. `planarSplit` (the boolean engine's intersection search) cuts every input segment wherever
|
|
812
|
+
* it meets another one; coincident pieces become one edge.
|
|
813
|
+
* 2. Each edge gives two half-edges. Around every vertex the half-edges leaving it are sorted by
|
|
814
|
+
* the direction in which they cross a small circle around it (half the shortest edge there),
|
|
815
|
+
* which orders tangent curves correctly.
|
|
816
|
+
* 3. A face walk takes, at each vertex, the half-edge just clockwise of the way back — the
|
|
817
|
+
* sharpest left turn. Bounded faces come out counter-clockwise (positive area in a y-up
|
|
818
|
+
* frame), the outer boundary of every connected piece clockwise; spurs (loose line ends) are
|
|
819
|
+
* dropped. Each outer boundary becomes a hole of the smallest face of another piece around
|
|
820
|
+
* it, so nesting is decided face by face, never by an even-odd rule over the whole network.
|
|
821
|
+
* 4. Faces learn which inputs fill them from a point well inside each face.
|
|
822
|
+
*
|
|
823
|
+
* Adjacency is kept in per-vertex lists and half-edge slots (no scans over all edges per step).
|
|
824
|
+
*
|
|
825
|
+
* Ported from vectorcraft-main/crates/pathops/src/planar.rs (`map`, `Map::merge`, `build`,
|
|
826
|
+
* `interior_point`, `without_spurs`, `leaving_angle`, `cut_out`), figcraft-main/crates/doc/src/vector_faces.rs
|
|
827
|
+
* (`faces`: half-edge walk with an angle-sorted next edge, the winding deciding inside or
|
|
828
|
+
* outside) and cadcraft-main/crates/geom/src/region.rs (`enclosing_loop`, `boundary_at_gap`:
|
|
829
|
+
* a ray from the point, the sharpest left turn, islands as holes, gaps between open ends
|
|
830
|
+
* closed). MIT OR Apache-2.0, © ArtCraft Team and contributors. See THIRD_PARTY_NOTICES.md.
|
|
831
|
+
*/
|
|
832
|
+
|
|
833
|
+
/** One input of a planar map. */
|
|
834
|
+
interface PlanarInput {
|
|
835
|
+
/** Its subpaths: closed ones bound faces and the area the input fills, open ones are edges only. */
|
|
836
|
+
path: BezierPathInput;
|
|
837
|
+
/** How its closed subpaths fill (default `nonzero`). */
|
|
838
|
+
fillRule?: PolygonFillRule;
|
|
839
|
+
/** Whether its closed subpaths count as filling the faces inside them (default true). */
|
|
840
|
+
fills?: boolean;
|
|
841
|
+
}
|
|
842
|
+
interface PlanarMapOptions extends PathOpsOptions {
|
|
843
|
+
/**
|
|
844
|
+
* Close gaps up to this distance between loose ends (vertices with one edge): each one joins
|
|
845
|
+
* the nearest other loose end within reach by a straight edge (default 0, off).
|
|
846
|
+
*/
|
|
847
|
+
gap?: number;
|
|
848
|
+
/** Most input segments mapped (default 4096); a bigger input gives no map. */
|
|
849
|
+
maxSegments?: number;
|
|
850
|
+
}
|
|
851
|
+
/** A bounded face: an outer outline with the holes other pieces of the map make in it. */
|
|
852
|
+
interface PlanarFace {
|
|
853
|
+
/** Outer subpath (counter-clockwise in a y-up frame) followed by its holes (clockwise). */
|
|
854
|
+
path: BezierPath;
|
|
855
|
+
/** Area (holes taken out). */
|
|
856
|
+
area: number;
|
|
857
|
+
bounds: {
|
|
858
|
+
minX: number;
|
|
859
|
+
minY: number;
|
|
860
|
+
maxX: number;
|
|
861
|
+
maxY: number;
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
/** A run of edges between junctions (vertices where paths meet or a path ends). */
|
|
865
|
+
interface PlanarChain {
|
|
866
|
+
segments: BezierSegment[];
|
|
867
|
+
/** A loop with no junction on it. */
|
|
868
|
+
closed: boolean;
|
|
869
|
+
/** The input it lies on: the front-most (highest index) where several coincide. */
|
|
870
|
+
source: number;
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* A point strictly inside a filled path (nonzero), well away from its edges where it can be:
|
|
874
|
+
* the middle of the widest span of a few horizontal lines through it. Null for an empty path.
|
|
875
|
+
* Ported from vectorcraft's `interior_point` (cadcraft's `interior_point` for polygons).
|
|
876
|
+
*/
|
|
877
|
+
declare function interiorPoint(path: BezierPathInput | readonly (readonly BezierSegment[])[]): Point | null;
|
|
878
|
+
/**
|
|
879
|
+
* The planar map of a set of paths. Build it with `PlanarMap.build`; faces, chains and fills
|
|
880
|
+
* are computed on first use.
|
|
881
|
+
*/
|
|
882
|
+
declare class PlanarMap {
|
|
883
|
+
readonly vertices: Point[];
|
|
884
|
+
private readonly edges;
|
|
885
|
+
private readonly sources;
|
|
886
|
+
readonly eps: number;
|
|
887
|
+
readonly inputCount: number;
|
|
888
|
+
private readonly around;
|
|
889
|
+
private readonly slot;
|
|
890
|
+
private readonly component;
|
|
891
|
+
private cyclesCache;
|
|
892
|
+
private sourcesCache;
|
|
893
|
+
private readonly fills;
|
|
894
|
+
private constructor();
|
|
895
|
+
/**
|
|
896
|
+
* Maps `inputs` (their subpaths as given: open ones stay open). Null when they cannot be mapped
|
|
897
|
+
* (non-finite points, more than `maxSegments` segments or an intersection search that does
|
|
898
|
+
* not settle) or have no edges.
|
|
899
|
+
*/
|
|
900
|
+
static build(inputs: readonly PlanarInput[], options?: PlanarMapOptions): PlanarMap | null;
|
|
901
|
+
private origin;
|
|
902
|
+
private halfPts;
|
|
903
|
+
/** The half-edge after `h` on the face to its left: the sharpest left turn at its end. */
|
|
904
|
+
private next;
|
|
905
|
+
/** Direction (angle) in which half-edge `h`, leaving `at`, first gets `r` away from it. */
|
|
906
|
+
private leavingAngle;
|
|
907
|
+
/** Segments of a run of half-edges (a loop unless `closed` is false), pieces of one input segment joined again. */
|
|
908
|
+
private cycleSegments;
|
|
909
|
+
private cycles;
|
|
910
|
+
private faceChains;
|
|
911
|
+
/** The bounded faces of the map. */
|
|
912
|
+
get faces(): PlanarFace[];
|
|
913
|
+
/** The inputs whose fill covers face `i`, ascending (empty for an area only outlines enclose). */
|
|
914
|
+
faceSources(i: number): number[];
|
|
915
|
+
/** A point well inside face `i`. */
|
|
916
|
+
faceInterior(i: number): Point | null;
|
|
917
|
+
/** The face under `p` (the smallest one around it), or -1. */
|
|
918
|
+
faceAt(p: Point): number;
|
|
919
|
+
/**
|
|
920
|
+
* The union of faces, traced along the map's own edges: those between two merged faces drop
|
|
921
|
+
* out exactly, so no seam or sliver is left where a boolean union of their outlines could
|
|
922
|
+
* round shared corners apart. Outer subpaths come out counter-clockwise (y-up), holes clockwise.
|
|
923
|
+
*/
|
|
924
|
+
merge(faceIndices: readonly number[]): BezierPath;
|
|
925
|
+
/**
|
|
926
|
+
* The edges joined into runs between junctions: vertices where other than two edges meet, or
|
|
927
|
+
* where the two edges lie on different inputs. Each run is keyed by its input.
|
|
928
|
+
*/
|
|
929
|
+
chains(): PlanarChain[];
|
|
930
|
+
/**
|
|
931
|
+
* The region enclosing `p`, traced as cadcraft does it: a ray from `p` towards +x meets the
|
|
932
|
+
* edges in order; for each, the half-edge with `p` on its left is followed by always taking the
|
|
933
|
+
* sharpest left turn, until a loop that runs counter-clockwise round `p` comes back. The pieces
|
|
934
|
+
* of the map nested inside that loop (islands) become its holes. Null when nothing encloses `p`.
|
|
935
|
+
*/
|
|
936
|
+
regionAt(p: Point): BezierPath | null;
|
|
937
|
+
}
|
|
938
|
+
/** Whether a contour, closed, encloses an area (rather than retracing itself). */
|
|
939
|
+
declare function contourEnclosesArea(contour: BezierContour): boolean;
|
|
940
|
+
/**
|
|
941
|
+
* `path` without `piece`, a run along one of its subpaths between two points (a Shape Builder
|
|
942
|
+
* edge from `PlanarMap.chains`): a closed subpath opens there, an open one splits in two (or
|
|
943
|
+
* loses an end), and a piece that runs all the way round (`closed`, or ending where it starts)
|
|
944
|
+
* takes its subpath with it. With `fillCloses`, open subpaths that enclose an area run on round
|
|
945
|
+
* an invisible closing edge, as the Shape Builder sees a filled path: a piece may run over it,
|
|
946
|
+
* and it never comes back as a visible segment. Null when the piece does not lie on `path`
|
|
947
|
+
* within `tol`.
|
|
948
|
+
*
|
|
949
|
+
* Ported from vectorcraft-main/crates/pathops/src/planar.rs (`cut_out`, `nearest_u`, `span`,
|
|
950
|
+
* `snap_ends`). MIT OR Apache-2.0, © ArtCraft Team and contributors. See THIRD_PARTY_NOTICES.md.
|
|
951
|
+
*/
|
|
952
|
+
declare function cutOutPiece(path: BezierPathInput, piece: {
|
|
953
|
+
segments: readonly BezierSegment[];
|
|
954
|
+
closed?: boolean;
|
|
955
|
+
}, fillCloses: boolean, tol: number): BezierPath | null;
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* The Pathfinder panel's dividing operations over a stack of shapes (index 0 at the back):
|
|
959
|
+
* Divide, Trim, Merge, Crop, Outline and Minus Back. (Unite, Minus Front, Intersect and Exclude
|
|
960
|
+
* are `pathBoolean`.) Every result carries the index of the shape whose paint it keeps.
|
|
961
|
+
*
|
|
962
|
+
* The filled areas come from one arrangement of all shapes (`dividePaths`, `pathBooleanSelect`):
|
|
963
|
+
* each area knows the shapes covering it, so an operation is a choice of areas per result.
|
|
964
|
+
* Outline and Divide with cutting lines use the planar map (`PlanarMap`).
|
|
965
|
+
*
|
|
966
|
+
* Ported from vectorcraft-main/crates/pathops/src/pathfinder.rs (`pathfinder`, `PathfinderOp`,
|
|
967
|
+
* `outline_edges`), MIT OR Apache-2.0, © ArtCraft Team and contributors. See
|
|
968
|
+
* THIRD_PARTY_NOTICES.md.
|
|
969
|
+
*/
|
|
970
|
+
|
|
971
|
+
type PathfinderOperation = 'divide' | 'trim' | 'merge' | 'crop' | 'outline' | 'minusBack';
|
|
972
|
+
declare const PATHFINDER_OPERATIONS: readonly PathfinderOperation[];
|
|
973
|
+
/** A shape of the stack. */
|
|
974
|
+
interface PathfinderShape {
|
|
975
|
+
/** Its outline; open subpaths are closed for filling (unless `line`). */
|
|
976
|
+
path: BezierPathInput;
|
|
977
|
+
fillRule?: PolygonFillRule;
|
|
978
|
+
/** Identifies its paint: Merge joins touching areas whose shapes share a key (default: the index). */
|
|
979
|
+
key?: string | number;
|
|
980
|
+
/**
|
|
981
|
+
* An unfilled open path: a cutting edge for Divide, splitting the faces it crosses without
|
|
982
|
+
* becoming one (ignored by the other operations).
|
|
983
|
+
*/
|
|
984
|
+
line?: boolean;
|
|
985
|
+
}
|
|
986
|
+
/** One result: a filled area (or an open stroke for Outline). */
|
|
987
|
+
interface PathfinderPiece {
|
|
988
|
+
path: BezierPath;
|
|
989
|
+
/** Index of the shape whose paint it keeps. */
|
|
990
|
+
source: number;
|
|
991
|
+
/** Outline edges are open paths (a loop with no junction on it stays closed). */
|
|
992
|
+
open?: boolean;
|
|
993
|
+
}
|
|
994
|
+
interface PathfinderResult extends PathOpsReport {
|
|
995
|
+
pieces: PathfinderPiece[];
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Runs a Pathfinder operation:
|
|
999
|
+
* - `divide`: every face of the arrangement becomes its own piece, painted like the top-most
|
|
1000
|
+
* shape covering it. `line` shapes cut the faces they cross.
|
|
1001
|
+
* - `trim`: hidden parts are removed; one piece per shape that stays visible, nothing merged.
|
|
1002
|
+
* - `merge`: like Trim, then touching or overlapping visible parts of shapes with the same key
|
|
1003
|
+
* become one piece (one per connected area).
|
|
1004
|
+
* - `crop`: the top shape crops the others; it is removed, the visible parts of the shapes below
|
|
1005
|
+
* inside it stay.
|
|
1006
|
+
* - `outline`: every outline is cut where it meets another; the pieces are open paths painted
|
|
1007
|
+
* like the shape they bound (the top-most where outlines coincide).
|
|
1008
|
+
* - `minusBack`: the top shape minus everything behind it.
|
|
1009
|
+
*/
|
|
1010
|
+
declare function pathfinder(op: PathfinderOperation, shapes: readonly PathfinderShape[], options?: PathOpsOptions): PathfinderResult;
|
|
1011
|
+
|
|
1012
|
+
export { type PolygonInput as $, type AffineMatrix as A, type BezierPathInput as B, type CanvasGradientDef as C, type DashedPath as D, type EllipseShape as E, type FlattenOptions as F, type GetShapeRenderDataOptions as G, type PathOpsOptions as H, type PathOpsReport as I, type PathPiece as J, type PathPointAtLength as K, type PathSelectResult as L, type MultiPolygon as M, type PathShape as N, type OffsetPathOptions as O, PlanarMap as P, type PathfinderPiece as Q, type PathfinderResult as R, type SvgGradientDef as S, type PlanarChain as T, type PlanarFace as U, type PlanarInput as V, type PlanarMapOptions as W, type PlanarSplitEdge as X, type PlanarSplitResult as Y, type PolygonBooleanOperation as Z, type PolygonBooleanOptions as _, type BezierPath as a, segmentCurvature as a$, type PolygonOperand as a0, type PolygonPiece as a1, type PolygonToPathOptions as a2, type PolygonWithHoles as a3, type RectShape as a4, type RegularPolygonShape as a5, SHAPE_KINDS as a6, type SegmentIntersection as a7, type ShapeKind as a8, type ShapePaint as a9, gradientToSvgDef as aA, interiorPoint as aB, intersectPaths as aC, intersectPolygons as aD, isCanvasGradient as aE, isShapeDescription as aF, multiPolygonArea as aG, multiPolygonBounds as aH, normalizeBezierPath as aI, offsetPath as aJ, outlineStroke as aK, parseCssGradient as aL, parseSvgPath as aM, pathBoolean as aN, pathBooleanSelect as aO, pathToContours as aP, pathfinder as aQ, planarSplit as aR, pointInBezierPath as aS, pointInMultiPolygon as aT, pointInRings as aU, polygonArea as aV, polygonBoolean as aW, polygonToSvgPath as aX, resolveCanvasGradient as aY, ringSignedArea as aZ, segmentBounds as a_, type ShapeRenderData as aa, type StarShape as ab, type SvgGradientStop as ac, angleToSvgLinearCoords as ad, arcToCubics as ae, bezierPathArea as af, bezierPathBounds as ag, bezierPathLength as ah, bezierPathPointAtLength as ai, bezierPathSignedArea as aj, bezierPathToSvg as ak, closeContour as al, contourEnclosesArea as am, contourSignedArea as an, contoursToPath as ao, countPathSegments as ap, cutOutPiece as aq, dashContours as ar, distanceToBezierPath as as, dividePaths as at, dividePolygons as au, excludePaths as av, flattenSvgPath as aw, formatNumber as ax, getShapeRenderData as ay, getShapeSvg as az, type StrokeJoin as b, segmentDerivative as b0, segmentExtrema as b1, segmentIntersections as b2, segmentLength as b3, segmentNearest as b4, segmentParamAtLength as b5, segmentPoint as b6, segmentTangent as b7, shapeToPolygon as b8, simplifyRing as b9, splitSegment as ba, strokeOutlineRings as bb, subSegment as bc, subtractPaths as bd, subtractPolygons as be, toBezierPath as bf, transformBezierPath as bg, trimSegments as bh, unionPolygons as bi, unitePaths as bj, windingNumber as bk, xorPolygons as bl, type StrokeCap as c, type BezierSegment as d, type PathfinderOperation as e, type PathfinderShape as f, type ShapeDescription as g, type PolygonFillRule as h, type PolygonRing as i, type ShapeSize as j, type BezierCommand as k, type BezierContour as l, type BezierPathToSvgOptions as m, CANVAS_GRADIENT_PRESETS as n, type CanvasLinearGradient as o, type CanvasRadialGradient as p, type DividePathsResult as q, type GradientStop as r, type OutlineStrokeOptions as s, PATHFINDER_OPERATIONS as t, type PathBooleanOperation as u, type PathBooleanResult as v, type PathCommand as w, type PathOperand as x, type PathOperandInput as y, PathOpsError as z };
|
|
@@ -671,6 +671,48 @@ declare function dividePaths(operands: PathOperandInput[], options?: PathOpsOpti
|
|
|
671
671
|
declare function normalizeBezierPath(path: BezierPathInput, fillRule?: PolygonFillRule, options?: PathOpsOptions): BezierPath;
|
|
672
672
|
/** Filled area of a path under its fill rule (overlaps counted once; exact for curves). */
|
|
673
673
|
declare function bezierPathArea(path: BezierPathInput, fillRule?: PolygonFillRule, options?: PathOpsOptions): number;
|
|
674
|
+
/** One edge of `planarSplit`: a piece of an input segment between two vertices. */
|
|
675
|
+
interface PlanarSplitEdge {
|
|
676
|
+
/** Vertex indices at the start and end of `pts`. */
|
|
677
|
+
a: number;
|
|
678
|
+
b: number;
|
|
679
|
+
/** Control points from vertex `a` to vertex `b`. */
|
|
680
|
+
pts: Point[];
|
|
681
|
+
/** Inputs whose chains run along this edge, ascending (several where outlines coincide). */
|
|
682
|
+
operands: number[];
|
|
683
|
+
/** The source segment it is a piece of (index into `sources`) and its parameters there at `a` and `b`. */
|
|
684
|
+
src: number;
|
|
685
|
+
sa: number;
|
|
686
|
+
sb: number;
|
|
687
|
+
}
|
|
688
|
+
interface PlanarSplitResult {
|
|
689
|
+
vertices: Point[];
|
|
690
|
+
edges: PlanarSplitEdge[];
|
|
691
|
+
/** The input segments, as `src` refers to them. */
|
|
692
|
+
sources: BezierSegment[];
|
|
693
|
+
eps: number;
|
|
694
|
+
scale: number;
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* The chains of every input (open or closed, as given: nothing is closed for filling) split
|
|
698
|
+
* wherever they cross or touch each other or themselves, with the same intersection search as
|
|
699
|
+
* the boolean operations. Coincident pieces become one edge that lists every input along it.
|
|
700
|
+
* Throws a `PathOpsError` when the search does not settle or the input is not finite.
|
|
701
|
+
*/
|
|
702
|
+
declare function planarSplit(inputs: readonly (readonly (readonly BezierSegment[])[])[], options?: PathOpsOptions): PlanarSplitResult;
|
|
703
|
+
/** Result of `pathBooleanSelect`: per selector, its connected parts (each an outer subpath with its holes). */
|
|
704
|
+
interface PathSelectResult extends PathOpsReport {
|
|
705
|
+
parts: BezierPath[][];
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Several boolean selections over one arrangement of the operands (the Pathfinder panel's
|
|
709
|
+
* Trim, Merge, Crop and Minus Back are each a selection per output). A selector gets the
|
|
710
|
+
* ascending indices of the operands covering an area and keeps the area when it returns true.
|
|
711
|
+
* Each selection comes back as its connected parts, largest first, built as `pathBoolean`
|
|
712
|
+
* builds its result; areas that only touch at an edge are one part. Falls back to the
|
|
713
|
+
* polygon engine like `pathBoolean`.
|
|
714
|
+
*/
|
|
715
|
+
declare function pathBooleanSelect(operands: PathOperandInput[], selectors: readonly ((covering: readonly number[]) => boolean)[], options?: PathOpsOptions): PathSelectResult;
|
|
674
716
|
|
|
675
717
|
/**
|
|
676
718
|
* Offset Path and Outline Stroke on Bézier paths.
|
|
@@ -758,4 +800,213 @@ declare function outlineStroke(input: BezierPathInput, options: OutlineStrokeOpt
|
|
|
758
800
|
*/
|
|
759
801
|
declare function offsetPath(input: BezierPathInput, distance: number, options?: OffsetPathOptions): BezierPath;
|
|
760
802
|
|
|
761
|
-
|
|
803
|
+
/**
|
|
804
|
+
* Planar maps: the faces and edges a set of paths divides the plane into (Shape Builder, fill
|
|
805
|
+
* regions, Pathfinder Outline).
|
|
806
|
+
*
|
|
807
|
+
* Unlike `dividePaths`, which splits the *filled areas* of closed shapes, every path here is an
|
|
808
|
+
* edge, open ones included: three crossing lines enclose a triangle, a line across a rectangle
|
|
809
|
+
* splits it in two, and an area enclosed by paths is a face whether or not anything fills it.
|
|
810
|
+
*
|
|
811
|
+
* 1. `planarSplit` (the boolean engine's intersection search) cuts every input segment wherever
|
|
812
|
+
* it meets another one; coincident pieces become one edge.
|
|
813
|
+
* 2. Each edge gives two half-edges. Around every vertex the half-edges leaving it are sorted by
|
|
814
|
+
* the direction in which they cross a small circle around it (half the shortest edge there),
|
|
815
|
+
* which orders tangent curves correctly.
|
|
816
|
+
* 3. A face walk takes, at each vertex, the half-edge just clockwise of the way back — the
|
|
817
|
+
* sharpest left turn. Bounded faces come out counter-clockwise (positive area in a y-up
|
|
818
|
+
* frame), the outer boundary of every connected piece clockwise; spurs (loose line ends) are
|
|
819
|
+
* dropped. Each outer boundary becomes a hole of the smallest face of another piece around
|
|
820
|
+
* it, so nesting is decided face by face, never by an even-odd rule over the whole network.
|
|
821
|
+
* 4. Faces learn which inputs fill them from a point well inside each face.
|
|
822
|
+
*
|
|
823
|
+
* Adjacency is kept in per-vertex lists and half-edge slots (no scans over all edges per step).
|
|
824
|
+
*
|
|
825
|
+
* Ported from vectorcraft-main/crates/pathops/src/planar.rs (`map`, `Map::merge`, `build`,
|
|
826
|
+
* `interior_point`, `without_spurs`, `leaving_angle`, `cut_out`), figcraft-main/crates/doc/src/vector_faces.rs
|
|
827
|
+
* (`faces`: half-edge walk with an angle-sorted next edge, the winding deciding inside or
|
|
828
|
+
* outside) and cadcraft-main/crates/geom/src/region.rs (`enclosing_loop`, `boundary_at_gap`:
|
|
829
|
+
* a ray from the point, the sharpest left turn, islands as holes, gaps between open ends
|
|
830
|
+
* closed). MIT OR Apache-2.0, © ArtCraft Team and contributors. See THIRD_PARTY_NOTICES.md.
|
|
831
|
+
*/
|
|
832
|
+
|
|
833
|
+
/** One input of a planar map. */
|
|
834
|
+
interface PlanarInput {
|
|
835
|
+
/** Its subpaths: closed ones bound faces and the area the input fills, open ones are edges only. */
|
|
836
|
+
path: BezierPathInput;
|
|
837
|
+
/** How its closed subpaths fill (default `nonzero`). */
|
|
838
|
+
fillRule?: PolygonFillRule;
|
|
839
|
+
/** Whether its closed subpaths count as filling the faces inside them (default true). */
|
|
840
|
+
fills?: boolean;
|
|
841
|
+
}
|
|
842
|
+
interface PlanarMapOptions extends PathOpsOptions {
|
|
843
|
+
/**
|
|
844
|
+
* Close gaps up to this distance between loose ends (vertices with one edge): each one joins
|
|
845
|
+
* the nearest other loose end within reach by a straight edge (default 0, off).
|
|
846
|
+
*/
|
|
847
|
+
gap?: number;
|
|
848
|
+
/** Most input segments mapped (default 4096); a bigger input gives no map. */
|
|
849
|
+
maxSegments?: number;
|
|
850
|
+
}
|
|
851
|
+
/** A bounded face: an outer outline with the holes other pieces of the map make in it. */
|
|
852
|
+
interface PlanarFace {
|
|
853
|
+
/** Outer subpath (counter-clockwise in a y-up frame) followed by its holes (clockwise). */
|
|
854
|
+
path: BezierPath;
|
|
855
|
+
/** Area (holes taken out). */
|
|
856
|
+
area: number;
|
|
857
|
+
bounds: {
|
|
858
|
+
minX: number;
|
|
859
|
+
minY: number;
|
|
860
|
+
maxX: number;
|
|
861
|
+
maxY: number;
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
/** A run of edges between junctions (vertices where paths meet or a path ends). */
|
|
865
|
+
interface PlanarChain {
|
|
866
|
+
segments: BezierSegment[];
|
|
867
|
+
/** A loop with no junction on it. */
|
|
868
|
+
closed: boolean;
|
|
869
|
+
/** The input it lies on: the front-most (highest index) where several coincide. */
|
|
870
|
+
source: number;
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* A point strictly inside a filled path (nonzero), well away from its edges where it can be:
|
|
874
|
+
* the middle of the widest span of a few horizontal lines through it. Null for an empty path.
|
|
875
|
+
* Ported from vectorcraft's `interior_point` (cadcraft's `interior_point` for polygons).
|
|
876
|
+
*/
|
|
877
|
+
declare function interiorPoint(path: BezierPathInput | readonly (readonly BezierSegment[])[]): Point | null;
|
|
878
|
+
/**
|
|
879
|
+
* The planar map of a set of paths. Build it with `PlanarMap.build`; faces, chains and fills
|
|
880
|
+
* are computed on first use.
|
|
881
|
+
*/
|
|
882
|
+
declare class PlanarMap {
|
|
883
|
+
readonly vertices: Point[];
|
|
884
|
+
private readonly edges;
|
|
885
|
+
private readonly sources;
|
|
886
|
+
readonly eps: number;
|
|
887
|
+
readonly inputCount: number;
|
|
888
|
+
private readonly around;
|
|
889
|
+
private readonly slot;
|
|
890
|
+
private readonly component;
|
|
891
|
+
private cyclesCache;
|
|
892
|
+
private sourcesCache;
|
|
893
|
+
private readonly fills;
|
|
894
|
+
private constructor();
|
|
895
|
+
/**
|
|
896
|
+
* Maps `inputs` (their subpaths as given: open ones stay open). Null when they cannot be mapped
|
|
897
|
+
* (non-finite points, more than `maxSegments` segments or an intersection search that does
|
|
898
|
+
* not settle) or have no edges.
|
|
899
|
+
*/
|
|
900
|
+
static build(inputs: readonly PlanarInput[], options?: PlanarMapOptions): PlanarMap | null;
|
|
901
|
+
private origin;
|
|
902
|
+
private halfPts;
|
|
903
|
+
/** The half-edge after `h` on the face to its left: the sharpest left turn at its end. */
|
|
904
|
+
private next;
|
|
905
|
+
/** Direction (angle) in which half-edge `h`, leaving `at`, first gets `r` away from it. */
|
|
906
|
+
private leavingAngle;
|
|
907
|
+
/** Segments of a run of half-edges (a loop unless `closed` is false), pieces of one input segment joined again. */
|
|
908
|
+
private cycleSegments;
|
|
909
|
+
private cycles;
|
|
910
|
+
private faceChains;
|
|
911
|
+
/** The bounded faces of the map. */
|
|
912
|
+
get faces(): PlanarFace[];
|
|
913
|
+
/** The inputs whose fill covers face `i`, ascending (empty for an area only outlines enclose). */
|
|
914
|
+
faceSources(i: number): number[];
|
|
915
|
+
/** A point well inside face `i`. */
|
|
916
|
+
faceInterior(i: number): Point | null;
|
|
917
|
+
/** The face under `p` (the smallest one around it), or -1. */
|
|
918
|
+
faceAt(p: Point): number;
|
|
919
|
+
/**
|
|
920
|
+
* The union of faces, traced along the map's own edges: those between two merged faces drop
|
|
921
|
+
* out exactly, so no seam or sliver is left where a boolean union of their outlines could
|
|
922
|
+
* round shared corners apart. Outer subpaths come out counter-clockwise (y-up), holes clockwise.
|
|
923
|
+
*/
|
|
924
|
+
merge(faceIndices: readonly number[]): BezierPath;
|
|
925
|
+
/**
|
|
926
|
+
* The edges joined into runs between junctions: vertices where other than two edges meet, or
|
|
927
|
+
* where the two edges lie on different inputs. Each run is keyed by its input.
|
|
928
|
+
*/
|
|
929
|
+
chains(): PlanarChain[];
|
|
930
|
+
/**
|
|
931
|
+
* The region enclosing `p`, traced as cadcraft does it: a ray from `p` towards +x meets the
|
|
932
|
+
* edges in order; for each, the half-edge with `p` on its left is followed by always taking the
|
|
933
|
+
* sharpest left turn, until a loop that runs counter-clockwise round `p` comes back. The pieces
|
|
934
|
+
* of the map nested inside that loop (islands) become its holes. Null when nothing encloses `p`.
|
|
935
|
+
*/
|
|
936
|
+
regionAt(p: Point): BezierPath | null;
|
|
937
|
+
}
|
|
938
|
+
/** Whether a contour, closed, encloses an area (rather than retracing itself). */
|
|
939
|
+
declare function contourEnclosesArea(contour: BezierContour): boolean;
|
|
940
|
+
/**
|
|
941
|
+
* `path` without `piece`, a run along one of its subpaths between two points (a Shape Builder
|
|
942
|
+
* edge from `PlanarMap.chains`): a closed subpath opens there, an open one splits in two (or
|
|
943
|
+
* loses an end), and a piece that runs all the way round (`closed`, or ending where it starts)
|
|
944
|
+
* takes its subpath with it. With `fillCloses`, open subpaths that enclose an area run on round
|
|
945
|
+
* an invisible closing edge, as the Shape Builder sees a filled path: a piece may run over it,
|
|
946
|
+
* and it never comes back as a visible segment. Null when the piece does not lie on `path`
|
|
947
|
+
* within `tol`.
|
|
948
|
+
*
|
|
949
|
+
* Ported from vectorcraft-main/crates/pathops/src/planar.rs (`cut_out`, `nearest_u`, `span`,
|
|
950
|
+
* `snap_ends`). MIT OR Apache-2.0, © ArtCraft Team and contributors. See THIRD_PARTY_NOTICES.md.
|
|
951
|
+
*/
|
|
952
|
+
declare function cutOutPiece(path: BezierPathInput, piece: {
|
|
953
|
+
segments: readonly BezierSegment[];
|
|
954
|
+
closed?: boolean;
|
|
955
|
+
}, fillCloses: boolean, tol: number): BezierPath | null;
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* The Pathfinder panel's dividing operations over a stack of shapes (index 0 at the back):
|
|
959
|
+
* Divide, Trim, Merge, Crop, Outline and Minus Back. (Unite, Minus Front, Intersect and Exclude
|
|
960
|
+
* are `pathBoolean`.) Every result carries the index of the shape whose paint it keeps.
|
|
961
|
+
*
|
|
962
|
+
* The filled areas come from one arrangement of all shapes (`dividePaths`, `pathBooleanSelect`):
|
|
963
|
+
* each area knows the shapes covering it, so an operation is a choice of areas per result.
|
|
964
|
+
* Outline and Divide with cutting lines use the planar map (`PlanarMap`).
|
|
965
|
+
*
|
|
966
|
+
* Ported from vectorcraft-main/crates/pathops/src/pathfinder.rs (`pathfinder`, `PathfinderOp`,
|
|
967
|
+
* `outline_edges`), MIT OR Apache-2.0, © ArtCraft Team and contributors. See
|
|
968
|
+
* THIRD_PARTY_NOTICES.md.
|
|
969
|
+
*/
|
|
970
|
+
|
|
971
|
+
type PathfinderOperation = 'divide' | 'trim' | 'merge' | 'crop' | 'outline' | 'minusBack';
|
|
972
|
+
declare const PATHFINDER_OPERATIONS: readonly PathfinderOperation[];
|
|
973
|
+
/** A shape of the stack. */
|
|
974
|
+
interface PathfinderShape {
|
|
975
|
+
/** Its outline; open subpaths are closed for filling (unless `line`). */
|
|
976
|
+
path: BezierPathInput;
|
|
977
|
+
fillRule?: PolygonFillRule;
|
|
978
|
+
/** Identifies its paint: Merge joins touching areas whose shapes share a key (default: the index). */
|
|
979
|
+
key?: string | number;
|
|
980
|
+
/**
|
|
981
|
+
* An unfilled open path: a cutting edge for Divide, splitting the faces it crosses without
|
|
982
|
+
* becoming one (ignored by the other operations).
|
|
983
|
+
*/
|
|
984
|
+
line?: boolean;
|
|
985
|
+
}
|
|
986
|
+
/** One result: a filled area (or an open stroke for Outline). */
|
|
987
|
+
interface PathfinderPiece {
|
|
988
|
+
path: BezierPath;
|
|
989
|
+
/** Index of the shape whose paint it keeps. */
|
|
990
|
+
source: number;
|
|
991
|
+
/** Outline edges are open paths (a loop with no junction on it stays closed). */
|
|
992
|
+
open?: boolean;
|
|
993
|
+
}
|
|
994
|
+
interface PathfinderResult extends PathOpsReport {
|
|
995
|
+
pieces: PathfinderPiece[];
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Runs a Pathfinder operation:
|
|
999
|
+
* - `divide`: every face of the arrangement becomes its own piece, painted like the top-most
|
|
1000
|
+
* shape covering it. `line` shapes cut the faces they cross.
|
|
1001
|
+
* - `trim`: hidden parts are removed; one piece per shape that stays visible, nothing merged.
|
|
1002
|
+
* - `merge`: like Trim, then touching or overlapping visible parts of shapes with the same key
|
|
1003
|
+
* become one piece (one per connected area).
|
|
1004
|
+
* - `crop`: the top shape crops the others; it is removed, the visible parts of the shapes below
|
|
1005
|
+
* inside it stay.
|
|
1006
|
+
* - `outline`: every outline is cut where it meets another; the pieces are open paths painted
|
|
1007
|
+
* like the shape they bound (the top-most where outlines coincide).
|
|
1008
|
+
* - `minusBack`: the top shape minus everything behind it.
|
|
1009
|
+
*/
|
|
1010
|
+
declare function pathfinder(op: PathfinderOperation, shapes: readonly PathfinderShape[], options?: PathOpsOptions): PathfinderResult;
|
|
1011
|
+
|
|
1012
|
+
export { type PolygonInput as $, type AffineMatrix as A, type BezierPathInput as B, type CanvasGradientDef as C, type DashedPath as D, type EllipseShape as E, type FlattenOptions as F, type GetShapeRenderDataOptions as G, type PathOpsOptions as H, type PathOpsReport as I, type PathPiece as J, type PathPointAtLength as K, type PathSelectResult as L, type MultiPolygon as M, type PathShape as N, type OffsetPathOptions as O, PlanarMap as P, type PathfinderPiece as Q, type PathfinderResult as R, type SvgGradientDef as S, type PlanarChain as T, type PlanarFace as U, type PlanarInput as V, type PlanarMapOptions as W, type PlanarSplitEdge as X, type PlanarSplitResult as Y, type PolygonBooleanOperation as Z, type PolygonBooleanOptions as _, type BezierPath as a, segmentCurvature as a$, type PolygonOperand as a0, type PolygonPiece as a1, type PolygonToPathOptions as a2, type PolygonWithHoles as a3, type RectShape as a4, type RegularPolygonShape as a5, SHAPE_KINDS as a6, type SegmentIntersection as a7, type ShapeKind as a8, type ShapePaint as a9, gradientToSvgDef as aA, interiorPoint as aB, intersectPaths as aC, intersectPolygons as aD, isCanvasGradient as aE, isShapeDescription as aF, multiPolygonArea as aG, multiPolygonBounds as aH, normalizeBezierPath as aI, offsetPath as aJ, outlineStroke as aK, parseCssGradient as aL, parseSvgPath as aM, pathBoolean as aN, pathBooleanSelect as aO, pathToContours as aP, pathfinder as aQ, planarSplit as aR, pointInBezierPath as aS, pointInMultiPolygon as aT, pointInRings as aU, polygonArea as aV, polygonBoolean as aW, polygonToSvgPath as aX, resolveCanvasGradient as aY, ringSignedArea as aZ, segmentBounds as a_, type ShapeRenderData as aa, type StarShape as ab, type SvgGradientStop as ac, angleToSvgLinearCoords as ad, arcToCubics as ae, bezierPathArea as af, bezierPathBounds as ag, bezierPathLength as ah, bezierPathPointAtLength as ai, bezierPathSignedArea as aj, bezierPathToSvg as ak, closeContour as al, contourEnclosesArea as am, contourSignedArea as an, contoursToPath as ao, countPathSegments as ap, cutOutPiece as aq, dashContours as ar, distanceToBezierPath as as, dividePaths as at, dividePolygons as au, excludePaths as av, flattenSvgPath as aw, formatNumber as ax, getShapeRenderData as ay, getShapeSvg as az, type StrokeJoin as b, segmentDerivative as b0, segmentExtrema as b1, segmentIntersections as b2, segmentLength as b3, segmentNearest as b4, segmentParamAtLength as b5, segmentPoint as b6, segmentTangent as b7, shapeToPolygon as b8, simplifyRing as b9, splitSegment as ba, strokeOutlineRings as bb, subSegment as bc, subtractPaths as bd, subtractPolygons as be, toBezierPath as bf, transformBezierPath as bg, trimSegments as bh, unionPolygons as bi, unitePaths as bj, windingNumber as bk, xorPolygons as bl, type StrokeCap as c, type BezierSegment as d, type PathfinderOperation as e, type PathfinderShape as f, type ShapeDescription as g, type PolygonFillRule as h, type PolygonRing as i, type ShapeSize as j, type BezierCommand as k, type BezierContour as l, type BezierPathToSvgOptions as m, CANVAS_GRADIENT_PRESETS as n, type CanvasLinearGradient as o, type CanvasRadialGradient as p, type DividePathsResult as q, type GradientStop as r, type OutlineStrokeOptions as s, PATHFINDER_OPERATIONS as t, type PathBooleanOperation as u, type PathBooleanResult as v, type PathCommand as w, type PathOperand as x, type PathOperandInput as y, PathOpsError as z };
|