svg_path
Shared SVG path model, construction, editing, and parameter evaluation.
This module models paths as a list of subpaths, and subpaths as continuous
segment lists. Use svg_path/parse and svg_path/serialize when working
directly with SVG path data strings.
Use svg_path/measure for arc lengths and distance-addressed evaluation,
svg_path/bounds for bounds, svg_path/containment for fill queries,
svg_path/distance for projections and closest pairs, and svg_path/fit
for parametric and constrained curve fitting. Shared option records and
geometry error payloads remain here so operations compose without conversion.
Coordinates follow SVG’s page convention: positive x points right and
positive y points down. Angles are in degrees unless explicitly stated
otherwise. Segment parameters normally run from 0.0 to 1.0; evaluation
and unchecked segment splitting also allow extrapolation. A parameter is
not an arc-length fraction. Use the *_at_length helpers for traveled
distances, and *_directions for singularity-safe unit tangents.
Types
A closest-point pair, parameterized by each geometry’s address type. Tied minima return one valid pair; addresses are not canonical for ties. Segment addresses are Float, subpath addresses SubpathParameter, and path addresses PathParameter. Distances are in path-coordinate units. Path searches skip move-only subpaths.
pub type ClosestPair(left_address, right_address) {
ClosestPair(
left_at: left_address,
right_at: right_address,
left_point: Point,
right_point: Point,
distance: Float,
)
}
Constructors
Options for classifying a point relative to a subpath’s fill area.
pub type ContainmentOptions {
ContainmentOptions(
tolerance: Float,
samples: Int,
max_iterations: Int,
fallback_ray_angles: List(Float),
)
}
Constructors
-
ContainmentOptions( tolerance: Float, samples: Int, max_iterations: Int, fallback_ray_angles: List(Float), )Arguments
- tolerance
-
Finite, positive distance at which a point is classified as boundary.
- samples
-
Number of scan samples used by projection and crossing queries.
- max_iterations
-
Maximum refinement steps for projection and crossing candidates.
- fallback_ray_angles
-
Fallback ray angles, in degrees, tried when the heuristic ray gives inconsistent positive/negative containment answers.
Options for detecting scalar zero crossings along a segment.
pub type CrossingOptions {
CrossingOptions(
samples: Int,
signed_line_distance_tolerance: Float,
max_iterations: Int,
)
}
Constructors
-
CrossingOptions( samples: Int, signed_line_distance_tolerance: Float, max_iterations: Int, )Arguments
- samples
-
Number of equal parameter windows scanned before refinement.
- signed_line_distance_tolerance
-
Maximum finite, positive signed line-distance residual accepted during refinement.
- max_iterations
-
Maximum bisection steps for one candidate window.
Constraint state of one fitted cubic control handle.
pub type CubicFitHandleState {
UnconstrainedHandle
PositiveHandle
CollapsedHandle
}
Constructors
-
UnconstrainedHandleThe fit did not constrain this handle to a direction.
-
PositiveHandleThe direction-constrained handle has positive length.
-
CollapsedHandleThe nonnegative fit selected zero handle length.
Error measurements and active handle constraints for a fitted cubic.
pub type CubicFitReport {
CubicFitReport(
root_sum_square: Float,
root_mean_square: Float,
max: Float,
start_handle: CubicFitHandleState,
end_handle: CubicFitHandleState,
)
}
Constructors
-
CubicFitReport( root_sum_square: Float, root_mean_square: Float, max: Float, start_handle: CubicFitHandleState, end_handle: CubicFitHandleState, )Arguments
- root_sum_square
-
sqrt(sum(distance(sample, fitted)^2)). - root_mean_square
-
sqrt(sum(distance(sample, fitted)^2) / sample_count). - max
-
The largest sample distance.
- start_handle
-
Constraint state of the handle adjacent to the segment start.
- end_handle
-
Constraint state of the handle adjacent to the segment end.
Options for singularity-safe direction queries.
pub type DirectionOptions {
DirectionOptions(relative_tolerance: Float)
}
Constructors
-
DirectionOptions(relative_tolerance: Float)Arguments
- relative_tolerance
-
Candidate vectors at or below this fraction of the largest local candidate are treated as collapsed. This must be finite and non-negative; zero skips only exact zero vectors.
Singularity-safe unit traversal directions at a path parameter.
incoming points in the direction of traversal as the parameter is
approached. outgoing points in the direction of traversal after the
parameter. Either side is absent when the addressed geometry has no
direction on that side.
pub type Directions {
Directions(
incoming: option.Option(Point),
outgoing: option.Option(Point),
)
}
Constructors
-
Directions( incoming: option.Option(Point), outgoing: option.Option(Point), )
Options for finding the distance from a point to a segment.
samples controls arc projection and the explicit sampling-based projection
API. Quadratic and cubic projection uses polynomial root isolation instead.
pub type DistanceOptions {
DistanceOptions(
samples: Int,
tolerance: Float,
max_iterations: Int,
)
}
Constructors
-
DistanceOptions( samples: Int, tolerance: Float, max_iterations: Int, )Arguments
- samples
-
Number of equal parameter windows used by sampling-based projection.
- tolerance
-
Maximum finite, positive geometric window diameter during refinement.
- max_iterations
-
Maximum refinement steps for one projection candidate.
How construction and editing helpers reconcile segment endpoints.
pub type EndpointPolicy {
Strict
Wiggle
WiggleWith(Float)
Bridge
WiggleElseBridge
WiggleElseBridgeWith(Float)
Custom(
fn(Segment, Segment, EndpointPolicyContext) -> List(Segment),
)
}
Constructors
-
StrictEndpoints must already match exactly.
-
WiggleMove nearby endpoints together within the default wiggle tolerance.
Horizontal and vertical lines stay horizontal and vertical. If adjacent horizontal/horizontal or vertical/vertical lines are misaligned, a bridge is inserted regardless of endpoint distance.
-
WiggleWith(Float)Move nearby endpoints together within the supplied tolerance.
Horizontal and vertical lines stay horizontal and vertical. If adjacent horizontal/horizontal or vertical/vertical lines are misaligned, a bridge is inserted regardless of endpoint distance.
-
BridgeKeep endpoints unchanged and insert a straight line if needed.
-
WiggleElseBridgeTry
Wiggle; if that fails, useBridge. -
WiggleElseBridgeWith(Float)Try wiggle with the supplied tolerance; if that fails, use
Bridge. -
Custom( fn(Segment, Segment, EndpointPolicyContext) -> List(Segment), )Reconcile adjacent segments with a caller-provided function.
For ordinary adjacent pairs, the returned segments replace the pair. For a closing join from the last segment back to the first segment, they replace only the last segment. An empty list deletes the replaced segment or pair. If the returned list is nonempty, its first segment must start where the previous segment started. The callback’s context identifies the first/last forward pair and the separate closing join. Replacement segments are not visited again; only the final replacement is used as
previousfor the next input.
The position of an endpoint-policy call in construction.
first marks the first forward pair; last marks a forward pair whose
next is the final input segment. Both are true for a two-segment input.
They describe input traversal, not the size of the replacement list.
The separate closing call has only closing true. A singleton has no
forward call, but closing calls the policy with that segment twice.
Empty subpaths have no calls. Deletions can leave no preceding segment
for a remaining input segment, in which case no pairwise call is made.
pub type EndpointPolicyContext {
EndpointPolicyContext(first: Bool, last: Bool, closing: Bool)
}
Constructors
-
EndpointPolicyContext(first: Bool, last: Bool, closing: Bool)
Shared geometry failures from construction, evaluation, and numerical queries. Operation modules document which failures apply to their contracts. Detailed parameters and numerical diagnostics are preserved when failures propagate.
pub type Error {
AlreadyClosed
Discontinuous(
previous_index: Int,
next_index: Int,
expected: Point,
got: Point,
distance: Float,
)
EmptySubpath
NotClosed
EmptyPath
EmptySubpaths
DegenerateArc
CannotMapArcNonlinearly
DegeneratePointPairSimilarity
InvalidSplice(start: Int, delete: Int, length: Int)
InvalidSubpathParameter(
segment_index: Int,
t: Float,
length: Int,
)
InvalidPathParameter(subpath_index: Int, length: Int)
InvalidDirectionRelativeTolerance(relative_tolerance: Float)
IndeterminateDirection
InvalidWiggleTolerance(tolerance: Float)
InvalidSubpathInterval(
from: SubpathParameter,
to: SubpathParameter,
)
InvalidCrossingSamples(samples: Int)
InvalidCrossingTolerance(tolerance: Float)
InvalidCrossingMaxIterations(max_iterations: Int)
CrossingMaxIterationsReached(estimate: Float, value: Float)
InvalidMinimizeSamples(samples: Int)
InvalidMinimizeTolerance(tolerance: Float)
InvalidMinimizeMaxIterations(max_iterations: Int)
MinimizeMaxIterationsReached(estimate: Float, value: Float)
InvalidLengthTolerance(tolerance: Float)
InvalidLengthMaxDepth(max_depth: Int)
LengthMaxDepthReached(estimate: Float, error: Float)
InvalidZeroLengthTolerance(tolerance: Float)
InvalidLengthDistance(distance: Float, length: Float)
InvalidSubdivisionMaxLength(max_length: Float)
InvalidParametricTolerance(tolerance: Float)
InvalidParametricSamplesPerPiece(samples: Int)
InvalidParametricInitialPieceCount(piece_count: Int)
InvalidParametricMaxDepth(max_depth: Int)
InvalidParametricInterval(start: Float, end: Float)
NonFiniteParametricPoint(parameter: Float, point: Point)
NonFiniteParametricTangent(parameter: Float, tangent: Point)
ParametricMaxDepthReached(error: Float)
ParametricFitFailed
DegenerateCubicFitTangent
UnderdeterminedCubicFit
InvalidLinearizeTolerance(tolerance: Float)
InvalidLinearizeMaxDepth(max_depth: Int)
LinearizeMaxDepthReached(error: Float)
InvalidDistanceSamples(samples: Int)
InvalidDistanceTolerance(tolerance: Float)
InvalidDistanceMaxIterations(max_iterations: Int)
DistanceMaxIterationsReached(estimate: Float, value: Float)
DistanceRootIsolationFailed
InvalidContainmentTolerance(tolerance: Float)
InvalidContainmentSamples(samples: Int)
InvalidContainmentMaxIterations(max_iterations: Int)
InvalidContainmentRayAngle(angle: Float)
InconsistentContainment
IndeterminateWindingSideLevels
InconsistentWindingSideLevels
InvalidIntersectionTolerance(tolerance: Float)
InvalidParameterSnapTolerance(tolerance: Float)
InvalidOverlapTolerance(tolerance: Float)
InvalidOverlapSamples(samples: Int)
InvalidIntersectionMaxDepth(max_depth: Int)
IntersectionTerminalWindowLimitExceeded(limit: Int)
IntersectionDepthLimitReached(
left_from: Float,
left_to: Float,
right_from: Float,
right_to: Float,
)
InvalidIntersectionParameterSnapExponent(exponent: Int)
InvalidSelfIntersectionMinimumArcLengthSeparation(
minimum_arc_length_separation: Float,
)
InvalidSelfIntersectionDistanceTolerance(
distance_tolerance: Float,
)
OverlappingSegments
InternalOverlapClassificationInconsistency
InternalUncertifiedSegmentIntersection(
left_distance: Float,
right_distance: Float,
tolerance: Float,
)
InternalOverlapParameterCorrespondenceInconsistency
NonAffineOverlapCorrespondence
MultipleNonemptySubpaths
NotCloseEnough(expected: Point, got: Point, tolerance: Float)
SplitOutsideSegment
}
Constructors
-
AlreadyClosedThe subpath is already closed and cannot accept more segments.
-
Discontinuous( previous_index: Int, next_index: Int, expected: Point, got: Point, distance: Float, )A segment starts somewhere other than the previous segment’s end point.
previous_indexis the segment whose end point was expected.next_indexis the segment whose start point did not match.distanceis the distance betweenexpectedandgot. -
EmptySubpathThe operation requires a non-empty subpath.
-
NotClosedThe operation requires a closed subpath.
-
EmptyPathThe operation requires a path with at least one subpath.
-
EmptySubpathsThe operation requires a path with at least one non-empty subpath.
-
DegenerateArcThe arc cannot be converted to center-parameter form.
-
CannotMapArcNonlinearlyNonlinear point mapping cannot preserve an SVG arc segment.
-
DegeneratePointPairSimilarityA point-pair similarity needs distinct source points.
-
InvalidSplice(start: Int, delete: Int, length: Int)A splice was requested with invalid bounds.
This is returned when
startis negative,deleteis negative, orstartis greater than the subpath length. -
InvalidSubpathParameter( segment_index: Int, t: Float, length: Int, )A subpath parameter was outside the valid segment index or
0.0..1.0range. -
InvalidPathParameter(subpath_index: Int, length: Int)A path parameter was outside the valid subpath index range.
-
InvalidDirectionRelativeTolerance(relative_tolerance: Float)A direction relative tolerance must be finite and non-negative.
-
IndeterminateDirectionGeometry has no usable direction for the requested operation.
-
InvalidWiggleTolerance(tolerance: Float)A custom endpoint wiggle tolerance must be finite and non-negative.
-
InvalidSubpathInterval( from: SubpathParameter, to: SubpathParameter, )A subpath interval would not produce a positive-length piece.
-
InvalidCrossingSamples(samples: Int)The number of crossing scan samples must be greater than zero.
-
InvalidCrossingTolerance(tolerance: Float)The crossing tolerance must be finite and greater than zero.
-
InvalidCrossingMaxIterations(max_iterations: Int)The crossing bisection iteration limit must be greater than zero.
-
CrossingMaxIterationsReached(estimate: Float, value: Float)A bracketed crossing could not be refined within the iteration limit.
-
InvalidMinimizeSamples(samples: Int)The number of minimization scan samples must be greater than zero.
-
InvalidMinimizeTolerance(tolerance: Float)The minimization tolerance must be finite and greater than zero.
-
InvalidMinimizeMaxIterations(max_iterations: Int)The minimization iteration limit must be greater than zero.
-
MinimizeMaxIterationsReached(estimate: Float, value: Float)A minimization window could not be refined within the iteration limit.
-
InvalidLengthTolerance(tolerance: Float)The length approximation tolerance must be finite and greater than zero.
-
InvalidLengthMaxDepth(max_depth: Int)The length approximation recursion limit must be greater than zero.
-
LengthMaxDepthReached(estimate: Float, error: Float)A length approximation could not be refined within the recursion limit.
-
InvalidZeroLengthTolerance(tolerance: Float)The zero-length tolerance must be finite and zero or greater.
-
InvalidLengthDistance(distance: Float, length: Float)A requested arc-length distance was outside
0.0..length. -
InvalidSubdivisionMaxLength(max_length: Float)The maximum segment length must be finite and greater than zero.
-
InvalidParametricTolerance(tolerance: Float)Parametric fitting tolerance must be finite and greater than zero.
-
InvalidParametricSamplesPerPiece(samples: Int)Parametric fitting needs at least two interior samples per piece.
-
InvalidParametricInitialPieceCount(piece_count: Int)Parametric fitting initial piece count must be greater than zero.
-
InvalidParametricMaxDepth(max_depth: Int)Parametric fitting recursion depth must be zero or greater.
-
InvalidParametricInterval(start: Float, end: Float)Parametric fitting needs distinct, finite start and end parameters.
-
NonFiniteParametricPoint(parameter: Float, point: Point)The caller-provided parametric function produced a non-finite point.
-
NonFiniteParametricTangent(parameter: Float, tangent: Point)The caller-provided tangent function produced a non-finite tangent.
-
ParametricMaxDepthReached(error: Float)A parametric interval could not be fitted within the recursion limit. Carries the remaining geometric fitting error, not the recursion depth.
-
ParametricFitFailedA parametric interval could not determine a stable cubic fit.
-
DegenerateCubicFitTangentA cubic fit tangent was too small to normalize.
-
UnderdeterminedCubicFitA cubic fit did not have enough sample information to determine controls.
-
InvalidLinearizeTolerance(tolerance: Float)The line approximation tolerance must be finite and greater than zero.
-
InvalidLinearizeMaxDepth(max_depth: Int)The line approximation recursion limit must be greater than zero.
-
LinearizeMaxDepthReached(error: Float)A segment could not be approximated within the recursion limit. Carries the remaining geometric approximation error, not the recursion depth.
-
InvalidDistanceSamples(samples: Int)The number of distance scan samples must be greater than zero.
-
InvalidDistanceTolerance(tolerance: Float)The distance tolerance must be finite and greater than zero.
-
InvalidDistanceMaxIterations(max_iterations: Int)The distance bisection iteration limit must be greater than zero.
-
DistanceMaxIterationsReached(estimate: Float, value: Float)A bracketed distance candidate could not be refined within the iteration limit.
-
DistanceRootIsolationFailedPolynomial distance-root isolation produced an inconsistent bracket.
-
InvalidContainmentTolerance(tolerance: Float)The containment tolerance must be finite and greater than zero.
-
InvalidContainmentSamples(samples: Int)The number of containment samples must be greater than zero.
-
InvalidContainmentMaxIterations(max_iterations: Int)The containment iteration limit must be greater than zero.
-
InvalidContainmentRayAngle(angle: Float)A containment fallback ray angle must be finite.
-
InconsistentContainmentEvery attempted containment ray gave inconsistent opposite-direction answers.
-
IndeterminateWindingSideLevelsNo regular interior sample could determine a segment’s winding sides.
-
InconsistentWindingSideLevelsSymmetric regular samples disagreed about a segment’s winding sides.
-
InvalidIntersectionTolerance(tolerance: Float)The intersection tolerance must be finite and greater than zero.
-
InvalidParameterSnapTolerance(tolerance: Float)The subpath-parameter snap tolerance must be finite and greater than zero.
-
InvalidOverlapTolerance(tolerance: Float)The overlap tolerance must be finite and zero or greater.
-
InvalidOverlapSamples(samples: Int)Endpoint-projection overlap detection requires at least one sample.
-
InvalidIntersectionMaxDepth(max_depth: Int)The intersection subdivision depth must be greater than zero.
-
IntersectionTerminalWindowLimitExceeded(limit: Int)Intersection search generated more terminal windows than its safety limit.
-
IntersectionDepthLimitReached( left_from: Float, left_to: Float, right_from: Float, right_to: Float, )Intersection refinement exhausted its depth before resolving this window.
-
InvalidIntersectionParameterSnapExponent(exponent: Int)The intersection parameter snap exponent must be between 1 and 15.
-
InvalidSelfIntersectionMinimumArcLengthSeparation( minimum_arc_length_separation: Float, )The self-intersection arc-length separation must be finite and positive.
-
InvalidSelfIntersectionDistanceTolerance( distance_tolerance: Float, )The self-intersection distance tolerance must be finite and positive.
-
OverlappingSegmentsThe two segments overlap in more than a single point.
-
InternalOverlapClassificationInconsistencyPoint-intersection logic reported an overlap that the shared overlap classifier did not confirm.
-
InternalUncertifiedSegmentIntersection( left_distance: Float, right_distance: Float, tolerance: Float, )Point-intersection logic returned parameters that do not evaluate back to the reported point within the requested tolerance.
-
InternalOverlapParameterCorrespondenceInconsistencyOpposite-direction subpath overlap correspondence checks disagreed.
-
NonAffineOverlapCorrespondenceCoincident segment portions do not have a single affine correspondence between their parameter intervals.
Normalize or linearize degenerate, multiply traced, or non-monotone segments before retrying the overlap operation.
-
MultipleNonemptySubpathsThe path contains more than one non-empty subpath.
-
Two points were too far apart for a wiggle operation to merge them.
-
SplitOutsideSegmentThe requested split point is outside the segment’s
0.0..1.0parameter range.
The SVG fill rule used for point containment and filled area.
pub type FillRule {
Nonzero
EvenOdd
}
Constructors
-
Nonzero -
EvenOdd
Options for approximating the length of a segment or subpath.
pub type LengthOptions {
LengthOptions(tolerance: Float, max_depth: Int)
}
Constructors
-
LengthOptions(tolerance: Float, max_depth: Int)Arguments
- tolerance
-
Maximum finite, positive path-coordinate error in one length estimate.
- max_depth
-
Maximum recursive subdivision depth.
Options for approximating segments with straight lines.
tolerance is an absolute distance in path coordinate units (default 0.01).
Scale it with uniformly scaled geometry for comparable relative detail;
keep max_depth unchanged. Smaller tolerances can require more subdivisions.
When used for fill-rule area, this is not a bound on the final area error.
pub type LinearizeOptions {
LinearizeOptions(tolerance: Float, max_depth: Int)
}
Constructors
-
LinearizeOptions(tolerance: Float, max_depth: Int)Arguments
- tolerance
-
Maximum finite, positive deviation from the line approximation.
- max_depth
-
Maximum recursive subdivision depth.
Options for minimizing a scalar function along a segment.
pub type MinimizeOptions {
MinimizeOptions(
samples: Int,
parameter_tolerance: Float,
max_iterations: Int,
)
}
Constructors
-
MinimizeOptions( samples: Int, parameter_tolerance: Float, max_iterations: Int, )Arguments
- samples
-
Number of equal parameter windows scanned for local minima.
- parameter_tolerance
-
Maximum finite, positive parameter-window width accepted during refinement.
- max_iterations
-
Maximum golden-section steps for one candidate window.
Options for building a subpath from a parametric curve.
pub type ParametricOptions {
ParametricOptions(
tolerance: Float,
samples_per_piece: Int,
initial_piece_count: Int,
max_depth: Int,
tangent: option.Option(fn(Float) -> Point),
)
}
Constructors
-
ParametricOptions( tolerance: Float, samples_per_piece: Int, initial_piece_count: Int, max_depth: Int, tangent: option.Option(fn(Float) -> Point), )Arguments
- tolerance
-
Maximum finite, positive sampled fitting error for one piece.
- samples_per_piece
-
Number of interior fitting samples per candidate piece; at least two.
- initial_piece_count
-
Positive number of equal parameter pieces before adaptive subdivision.
- max_depth
-
Non-negative maximum recursive subdivision depth; zero forbids refinement.
- tangent
-
Optional derivative function used to constrain endpoint tangents.
A point intersection between two paths.
Multiple parameters are retained on both paths because a single point can be reached through multiple subpaths or through self-intersecting subpaths. Segment-boundary aliases are canonicalized to one traversal address.
pub type PathIntersection {
PathIntersection(
point: Point,
left_parameters: List(PathParameter),
right_parameters: List(PathParameter),
)
}
Constructors
-
PathIntersection( point: Point, left_parameters: List(PathParameter), right_parameters: List(PathParameter), )
A local address on a path.
subpath_index addresses a subpath in the path, and at addresses a
segment parameter inside that subpath.
pub type PathParameter {
PathParameter(subpath_index: Int, at: SubpathParameter)
}
Constructors
-
PathParameter(subpath_index: Int, at: SubpathParameter)
A closest pair addressed on two paths.
pub type PathPathProjection =
ClosestPair(PathParameter, PathParameter)
A point projection addressed within a path.
pub type PathProjection =
Projection(PathParameter)
A point where a path intersects itself.
pub type PathSelfIntersection {
PathSelfIntersection(
point: Point,
parameters: #(PathParameter, PathParameter),
)
}
Constructors
-
PathSelfIntersection( point: Point, parameters: #(PathParameter, PathParameter), )
The signed winding number of a path around a point.
pub type PathWinding {
Winding(Int)
BoundaryWinding
}
Constructors
-
Winding(Int) -
BoundaryWinding
A 2D point.
pub type Point {
Point(x: Float, y: Float)
}
Constructors
-
Point(x: Float, y: Float)
The position of a point relative to a filled subpath.
pub type PointContainment {
Inside
Outside
Boundary
}
Constructors
-
Inside -
Outside -
Boundary
Errors returned by fallible point-mapping helpers.
pub type PointMapError(error) {
PointMapPathError(error: Error)
PointMapFunctionError(error: error)
}
Constructors
-
PointMapPathError(error: Error)The path structure could not be mapped.
-
PointMapFunctionError(error: error)The caller-provided point mapping function failed.
A nearest point and its reusable geometry address. Tied minima return one valid point; addresses are not canonical for ties. Move-only subpaths are skipped by path projections.
pub type Projection(address) {
Projection(at: address, point: Point, distance: Float)
}
Constructors
-
Projection(at: address, point: Point, distance: Float)
A single SVG path segment.
pub type Segment {
Line(start: Point, end: Point)
QuadraticBezier(start: Point, control: Point, end: Point)
CubicBezier(
start: Point,
control1: Point,
control2: Point,
end: Point,
)
Arc(
start: Point,
radius: Point,
x_axis_rotation: Float,
large_arc: Bool,
sweep: Bool,
end: Point,
)
}
Constructors
A closest pair addressed on a segment and a path.
pub type SegmentPathProjection =
ClosestPair(Float, PathParameter)
A point projection addressed by a segment parameter.
pub type SegmentProjection =
Projection(Float)
A closest pair addressed on two segments.
pub type SegmentSegmentProjection =
ClosestPair(Float, Float)
A point intersection between a standalone segment and a subpath.
segment_t addresses the standalone segment. subpath_parameters retains
each distinct traversal address reaching this point on the subpath;
segment-boundary aliases are canonicalized to one address.
pub type SegmentSubpathIntersection {
SegmentSubpathIntersection(
point: Point,
segment_t: Float,
subpath_parameters: List(SubpathParameter),
)
}
Constructors
-
SegmentSubpathIntersection( point: Point, segment_t: Float, subpath_parameters: List(SubpathParameter), )
A closest pair addressed on a segment and a subpath.
pub type SegmentSubpathProjection =
ClosestPair(Float, SubpathParameter)
Options for finding self-intersections in one subpath.
pub type SelfIntersectionOptions {
SelfIntersectionOptions(
minimum_arc_length_separation: Float,
distance_tolerance: Float,
)
}
Constructors
-
SelfIntersectionOptions( minimum_arc_length_separation: Float, distance_tolerance: Float, )Arguments
- minimum_arc_length_separation
-
Finite, positive arc-length separation between two reported addresses.
- distance_tolerance
-
Finite, positive distance between coincident points.
A positioned sequence of path segments, optionally closed.
The first segment, when present, starts at the subpath start point. The last segment of a closed subpath, when present, also ends at the subpath start point. Empty subpaths may be open or closed.
The constructor is opaque so that these invariants are maintained. Use
subpath, subpath_empty, subpath_append_segment, or their _with
variants to build values.
pub opaque type Subpath
A point intersection between two subpaths.
Multiple parameters are retained on both subpaths because a single point can be reached multiple times by a self-intersecting subpath. Segment-boundary aliases are canonicalized to one traversal address.
pub type SubpathIntersection {
SubpathIntersection(
point: Point,
left_parameters: List(SubpathParameter),
right_parameters: List(SubpathParameter),
)
}
Constructors
-
SubpathIntersection( point: Point, left_parameters: List(SubpathParameter), right_parameters: List(SubpathParameter), )
A local address on a subpath segment.
segment_index addresses a segment in the subpath, and t is that
segment’s local parameter. Subpath APIs require t to be inside
0.0..1.0; unlike segment APIs, subpath parameters do not extrapolate.
pub type SubpathParameter {
SubpathParameter(segment_index: Int, t: Float)
}
Constructors
-
SubpathParameter(segment_index: Int, t: Float)
A closest pair addressed on a subpath and a path.
pub type SubpathPathProjection =
ClosestPair(SubpathParameter, PathParameter)
A point projection addressed within a subpath.
pub type SubpathProjection =
Projection(SubpathParameter)
A point where a subpath intersects itself.
pub type SubpathSelfIntersection {
SubpathSelfIntersection(
point: Point,
parameters: #(SubpathParameter, SubpathParameter),
)
}
Constructors
-
SubpathSelfIntersection( point: Point, parameters: #(SubpathParameter, SubpathParameter), )
A closest pair addressed on two subpaths.
pub type SubpathSubpathProjection =
ClosestPair(SubpathParameter, SubpathParameter)
Values
pub fn arc_center_data(
segment: Segment,
) -> Result(ellipse.CenterArcData, Error)
Return an elliptical arc segment as center-parameter arc data.
Returns DegenerateArc for non-arc segments, coincident arc endpoints, or
either absolute radius at or below 1e-9. Uses ellipse.endpoint_to_center:
negative radii are made positive, and radii too small to span the endpoints
are enlarged. This does not replace degenerate arcs with lines.
pub fn arc_from_center_data(
data: ellipse.CenterArcData,
) -> Segment
Create an elliptical arc segment from center-parameter arc data.
pub fn arc_from_endpoint_data(
data: ellipse.EndpointArcData,
) -> Segment
Create an elliptical arc segment from endpoint-parameter arc data.
pub fn default_direction_options() -> DirectionOptions
Return the default options for singularity-safe direction queries.
pub fn default_linearize_options() -> LinearizeOptions
Return the default options for straight-line approximation.
pub fn default_self_intersection_options() -> SelfIntersectionOptions
Return the default options for subpath and path self-intersection detection.
pub fn path_append_subpath(path: Path, subpath: Subpath) -> Path
Append a subpath to the end of a path.
pub fn path_arcs_to_cubic_beziers(path: Path) -> Path
Convert every arc in a path to cubic Bezier curves.
This applies subpath_arcs_to_cubic_beziers to each subpath.
pub fn path_as_subpath(path: Path) -> Result(Subpath, Error)
Convert a path with zero or one non-empty subpaths into a subpath.
Empty subpaths are ignored. If more than one non-empty subpath is present,
this returns MultipleNonemptySubpaths. If a path has only empty subpaths,
the first empty subpath is returned.
pub fn path_by_point_pair_similarity(
path: Path,
source_start source_start: Point,
source_end source_end: Point,
target_start target_start: Point,
target_end target_end: Point,
) -> Result(Path, Error)
Map a path by the similarity taking source_start and source_end to
target_start and target_end.
pub fn path_derivative(
path: Path,
at parameter: PathParameter,
) -> Result(Point, Error)
Return a path’s subpath derivative at a path parameter.
pub fn path_directions(
path: Path,
at parameter: PathParameter,
) -> Result(Directions, Error)
Return singularity-safe unit traversal directions at a path parameter.
pub fn path_directions_with(
path: Path,
at parameter: PathParameter,
options options: DirectionOptions,
) -> Result(Directions, Error)
Return singularity-safe unit traversal directions using explicit options.
pub fn path_end(path: Path) -> Result(Point, Error)
Return the end point of the last subpath in a path.
pub fn path_filter_subpaths(
path: Path,
keeping predicate: fn(Subpath) -> Bool,
) -> Path
Keep only the subpaths that satisfy a predicate.
pub fn path_map_points(
path: Path,
with f: fn(Point) -> Point,
) -> Result(Path, Error)
Map the defining points of every segment in a path.
Each subpath’s closed state is preserved. For nonlinear functions, this maps
endpoints and control points, not the exact image of every point on each
rendered curve. If any segment is an arc, this returns
CannotMapArcNonlinearly.
pub fn path_map_subpaths(
path: Path,
with f: fn(Subpath) -> Subpath,
) -> Path
Map over the subpaths in a path.
pub fn path_normalize_svg_arcs(path: Path) -> Path
Apply exact SVG arc normalization independently to every subpath.
pub fn path_parameter_compare(
a: PathParameter,
b: PathParameter,
) -> order.Order
Compare two path parameters by subpath index, then subpath parameter.
pub fn path_point(
path: Path,
at parameter: PathParameter,
) -> Result(Point, Error)
Evaluate a path at a path parameter.
pub fn path_rebuild_with(
path: Path,
policy endpoint_policy: EndpointPolicy,
) -> Result(Path, Error)
Rebuild every subpath in a path using an endpoint policy.
This re-runs endpoint reconciliation on each subpath’s current segment list and preserves each subpath’s open/closed state. Empty subpaths are preserved unchanged.
pub fn path_reverse(path: Path) -> Path
Reverse the traversal direction of a path.
This reverses each subpath and reverses the path’s subpath order.
pub fn path_second_derivative(
path: Path,
at parameter: PathParameter,
) -> Result(Point, Error)
Return a path’s segment second derivative at a path parameter.
pub fn path_start(path: Path) -> Result(Point, Error)
Return the start point of the first subpath in a path.
pub fn path_to_cubic_beziers(path: Path) -> Path
Convert every segment in a path to cubic Bezier curves.
This applies subpath_to_cubic_beziers to each subpath.
pub fn path_to_cubic_beziers_strict(
path: Path,
) -> Result(Path, Error)
Convert a path to cubics, stopping at the first arc-conversion error.
Subpath order, starts, and closed flags are preserved. Uses the same
approximation as path_to_cubic_beziers, without straight-cubic recovery.
pub fn path_to_lines(path: Path) -> Result(Path, Error)
Approximate every segment in a path with straight lines.
Subpath order, move-only subpaths, and closed states are preserved.
pub fn path_to_lines_with(
path: Path,
options options: LinearizeOptions,
) -> Result(Path, Error)
Approximate every segment in a path with straight lines using explicit options.
pub fn path_try_map_points(
path: Path,
with f: fn(Point) -> Result(Point, error),
) -> Result(Path, PointMapError(error))
Map the defining points of every segment in a path with a fallible function.
This has the same geometry semantics as path_map_points, but the mapping
function may reject individual points.
pub fn point_by_point_pair_similarity(
point: Point,
source_start source_start: Point,
source_end source_end: Point,
target_start target_start: Point,
target_end target_end: Point,
) -> Result(Point, Error)
Map a point by the similarity taking source_start and source_end to
target_start and target_end.
If the input point is exactly source_start or source_end, the returned
point is exactly the corresponding target point.
pub fn segment_arcs_to_cubic_beziers(
segment: Segment,
) -> List(Segment)
Convert an arc segment to cubic Bezier curves, preserving other segments.
Non-arc segments are returned unchanged as a single-item list. An arc may
become several cubic Bezier segments.
This infallible conversion retains its historical fallback: if ellipse
conversion fails, it returns a straight cubic between the endpoints.
Use segment_arcs_to_cubic_beziers_strict to report DegenerateArc instead.
pub fn segment_arcs_to_cubic_beziers_strict(
segment: Segment,
) -> Result(List(Segment), Error)
Approximate an arc with cubics, returning DegenerateArc if conversion fails.
Non-arcs are unchanged. This uses the same quarter-turn approximation and
exact endpoint reconciliation as segment_arcs_to_cubic_beziers, but never
substitutes a straight cubic on failure. Strictness concerns error recovery,
not approximation accuracy. Coincident endpoints and either absolute radius
at or below 1e-9 are rejected; negative and insufficient radii follow the
correction rules of arc_center_data.
pub fn segment_as_path(segment: Segment) -> Path
View a segment as a path containing one one-segment open subpath.
pub fn segment_as_subpath(segment: Segment) -> Subpath
View a segment as a one-segment open subpath.
This conversion is total because a single segment is necessarily a continuous segment sequence.
pub fn segment_between(
segment: Segment,
from from: Float,
to to: Float,
) -> Result(Segment, Error)
Return the portion of a segment between two parameters.
from and to are not clamped. Values outside 0.0..1.0 extrapolate
along the same segment. If from is greater than to, the returned segment
traverses the interval in reverse.
pub fn segment_between_inside(
segment: Segment,
from from: Float,
to to: Float,
) -> Result(Segment, Error)
Return the portion of a segment between two parameters.
from and to must be inside 0.0..1.0, inclusive. If from is greater
than to, the returned segment traverses the interval in reverse.
pub fn segment_between_many(
segment: Segment,
between points: List(Float),
) -> Result(List(Segment), Error)
Return segment portions between adjacent parameters.
Parameters are not clamped. Values outside 0.0..1.0 extrapolate along the
same segment. Empty and singleton lists return an empty list.
pub fn segment_between_many_inside(
segment: Segment,
between points: List(Float),
) -> Result(List(Segment), Error)
Return segment portions between adjacent parameters.
All parameters must be inside 0.0..1.0, inclusive. Empty and singleton
lists return an empty list.
pub fn segment_by_point_pair_similarity(
segment: Segment,
source_start source_start: Point,
source_end source_end: Point,
target_start target_start: Point,
target_end target_end: Point,
) -> Result(Segment, Error)
Map a segment by the similarity taking source_start and source_end to
target_start and target_end.
Segment defining points exactly equal to source_start or source_end are
mapped exactly to the corresponding target point.
pub fn segment_derivative(
segment: Segment,
at t: Float,
) -> Result(Point, Error)
Return a segment’s derivative with respect to parameter t.
t is not clamped.
pub fn segment_directions(
segment: Segment,
at t: Float,
) -> Result(Directions, Error)
Return singularity-safe unit traversal directions at a segment parameter.
The segment parameter may extrapolate as with segment_point. At 0.0
only outgoing is present, and at 1.0 only incoming is present.
pub fn segment_directions_with(
segment: Segment,
at t: Float,
options options: DirectionOptions,
) -> Result(Directions, Error)
Return singularity-safe unit traversal directions using explicit options.
A zero relative tolerance skips only exactly collapsed candidate vectors.
pub fn segment_map_points(
segment: Segment,
with f: fn(Point) -> Point,
) -> Result(Segment, Error)
Map the defining points of a segment.
Lines, quadratic Beziers, and cubic Beziers are mapped by applying f to
their endpoints and control points. For nonlinear functions, this is not the
exact image of every point on the rendered curve. Arc segments return
CannotMapArcNonlinearly because an arbitrary nonlinear mapping does not
generally preserve SVG arc parameters.
pub fn segment_normalize_svg_arc(
segment: Segment,
) -> option.Option(Segment)
Apply SVG’s exact interpretation rules to one arc, without a tolerance.
Coincident endpoints omit the arc (None), even when a radius is zero.
Otherwise a zero radius produces the straight endpoint-to-endpoint line;
nonzero radii are made positive. Non-arcs are unchanged. This does not
enlarge insufficient radii or approximate narrow ellipses.
pub fn segment_point(
segment: Segment,
at t: Float,
) -> Result(Point, Error)
Evaluate a segment at parameter t.
t is not clamped. Values outside 0.0..1.0 extrapolate along the same
segment.
pub fn segment_remap_endpoints(
segment: Segment,
new_start new_start: Point,
new_end new_end: Point,
) -> Result(Segment, Error)
Remap a segment so its current endpoints become new_start and new_end.
The returned segment starts exactly at new_start and ends exactly at
new_end.
pub fn segment_second_derivative(
segment: Segment,
at t: Float,
) -> Result(Point, Error)
Return a segment’s second derivative with respect to parameter t.
t is not clamped.
pub fn segment_split(
segment: Segment,
at t: Float,
) -> Result(#(Segment, Segment), Error)
Split a segment at parameter t.
t is not clamped. Values outside 0.0..1.0 extrapolate along the same
segment.
pub fn segment_split_inside(
segment: Segment,
at t: Float,
) -> Result(#(Segment, Segment), Error)
Split a segment at parameter t, returning an error outside 0.0..1.0.
Values exactly at 0.0 or 1.0 are accepted and produce one zero-length
segment. For an Arc, the empty portion is a Line and the other portion is
the original Arc, since coincident-endpoint arcs have no defined ellipse.
pub fn segment_to_cubic_beziers(
segment: Segment,
) -> List(Segment)
Convert a segment to one or more cubic Bezier curves.
Lines and quadratic Beziers are converted exactly. Cubic Beziers are
returned unchanged. Arcs may become several cubic Bezier segments.
Arc conversion failures use the straight-cubic fallback documented by
segment_arcs_to_cubic_beziers.
pub fn segment_to_cubic_beziers_strict(
segment: Segment,
) -> Result(List(Segment), Error)
Convert a segment to cubics, returning DegenerateArc on arc failure.
Non-arcs use the exact conversions of segment_to_cubic_beziers.
Arcs use segment_arcs_to_cubic_beziers_strict; strictness does not make
their cubic approximation exact or introduce an accuracy tolerance.
pub fn segment_to_lines(
segment: Segment,
) -> Result(List(Segment), Error)
Approximate a segment with one or more straight lines.
Lines are returned unchanged. Beziers and arcs are subdivided until each
resulting chord is within the default geometric tolerance. Arcs rejected by
arc_center_data return DegenerateArc; SVG-specific replacements require
explicit normalization through svg_path.path_normalize_svg_arcs.
pub fn segment_to_lines_with(
segment: Segment,
options options: LinearizeOptions,
) -> Result(List(Segment), Error)
Approximate a segment with straight lines using explicit options.
pub fn segment_try_map_points(
segment: Segment,
with f: fn(Point) -> Result(Point, error),
) -> Result(Segment, PointMapError(error))
Map the defining points of a segment with a fallible function.
This has the same geometry semantics as segment_map_points, but the
mapping function may reject individual points.
pub fn subpath(segments: List(Segment)) -> Result(Subpath, Error)
Create an open subpath from a non-empty continuous list of segments.
Returns EmptySubpath if the segment list is empty. Use subpath_empty
when you need to represent a move-only subpath.
Returns Discontinuous if any segment starts somewhere other than the
previous segment’s end point. The error includes the two segment indices
that failed to meet.
pub fn subpath_append_segment(
subpath: Subpath,
segment: Segment,
) -> Result(Subpath, Error)
Append a segment to an open subpath.
The new segment must start exactly at the current end point.
pub fn subpath_append_segment_with(
subpath: Subpath,
segment: Segment,
policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)
Append a segment to an open subpath using the given endpoint policy.
Returns AlreadyClosed for a closed source. Otherwise follows
subpath_append_segment, allowing the policy to reconcile endpoint gaps.
Reconciliation errors propagate; the original subpath start is preserved.
pub fn subpath_arcs_to_cubic_beziers(subpath: Subpath) -> Subpath
Convert every arc in a subpath to cubic Bezier curves.
Lines, quadratic Beziers, and cubic Beziers are preserved. Elliptical arcs are approximated with one or more cubic Beziers, split into chunks of at most a quarter turn. Degenerate arcs fall back to a straight-line cubic Bezier between their endpoints.
pub fn subpath_as_path(subpath: Subpath) -> Path
View a subpath as a path containing that single subpath.
pub fn subpath_assert(segments: List(Segment)) -> Subpath
Create an open subpath from a non-empty continuous list of segments.
Panics if the list is empty or any consecutive endpoints differ exactly.
This is useful for hand-authored paths where invalid continuity would be a
programmer error. Use subpath when you want to handle construction errors.
pub fn subpath_assert_append_segment(
subpath: Subpath,
segment: Segment,
) -> Subpath
Append a segment, asserting subpath_append_segment.
Panics if the source is closed or the new segment’s start differs from the
current end. Use subpath_append_segment for a non-panicking result.
pub fn subpath_assert_append_segment_with(
subpath: Subpath,
segment: Segment,
policy endpoint_policy: EndpointPolicy,
) -> Subpath
Append a segment with an endpoint policy.
Panics if the source is closed or endpoint reconciliation returns an error.
See subpath_append_segment_with for the non-panicking version.
pub fn subpath_assert_close(subpath: Subpath) -> Subpath
Close a subpath, asserting subpath_close.
Panics if a nonempty subpath’s end differs from its start. Empty subpaths may be closed.
pub fn subpath_assert_close_with(
subpath: Subpath,
policy endpoint_policy: EndpointPolicy,
) -> Subpath
Close a subpath with an endpoint policy, asserting subpath_close_with.
Panics if closing-boundary reconciliation returns an error, including a
custom-policy contract violation. Empty subpaths may be closed without
invoking the policy. See subpath_close_with
for the non-panicking version and policy invocation rules.
pub fn subpath_assert_join(subpaths: List(Subpath)) -> Subpath
Join open subpaths, asserting subpath_join.
Panics for an empty input list, a closed input subpath, or endpoint gaps
that prevent continuous reconstruction. Use subpath_join to handle errors.
pub fn subpath_assert_join_with(
subpaths: List(Subpath),
policy endpoint_policy: EndpointPolicy,
) -> Subpath
Join open subpaths with an endpoint policy.
Panics for an empty input list, a closed input subpath, or an error during
endpoint reconciliation. See subpath_join_with for a non-panicking result.
pub fn subpath_assert_polygon(points: List(Point)) -> Subpath
Create a closed polygon subpath from at least two points.
Panics if fewer than two points are supplied. Points need not be distinct,
and the polygon need not be simple or have nonzero area. See
subpath_polygon for closing-edge behavior and a non-panicking result.
pub fn subpath_assert_polyline(points: List(Point)) -> Subpath
Create an open polyline subpath from at least two points.
Panics if fewer than two points are supplied. Points need not be distinct.
This is the asserting counterpart of subpath_polyline, not a coordinate
validation function.
pub fn subpath_assert_splice(
subpath: Subpath,
start start: Int,
delete delete: Int,
insert insert: List(Segment),
) -> Subpath
Replace a range of segments, asserting the rules of subpath_splice.
Panics for a negative start or delete, a start beyond the segment
count, or a result with discontinuous endpoints (including closure).
Use subpath_splice for a non-panicking result.
pub fn subpath_assert_splice_with(
subpath: Subpath,
start start: Int,
delete delete: Int,
insert insert: List(Segment),
policy endpoint_policy: EndpointPolicy,
) -> Subpath
Replace a range of segments with an endpoint policy.
Panics on any error from subpath_splice_with: invalid index/count as
described by subpath_splice, or failure to reconcile the resulting
boundaries while preserving the subpath’s closed state.
pub fn subpath_assert_with(
segments: List(Segment),
policy endpoint_policy: EndpointPolicy,
) -> Subpath
Create an open subpath with an endpoint policy.
Panics on any error from subpath_with: an empty input list, an endpoint
gap the policy cannot reconcile, or a custom replacement that violates
the EndpointPolicy contract. Use subpath_with to handle those errors.
pub fn subpath_between(
subpath: Subpath,
from from: SubpathParameter,
to to: SubpathParameter,
) -> Result(Subpath, Error)
Return the open subpath between two subpath parameters.
Parameters must be valid for the subpath and must describe a positive-length interval. Open subpaths reject reversed intervals. Closed subpaths allow wrapped intervals, but equal parameters are still rejected.
pub fn subpath_by_point_pair_similarity(
subpath: Subpath,
source_start source_start: Point,
source_end source_end: Point,
target_start target_start: Point,
target_end target_end: Point,
) -> Result(Subpath, Error)
Map a subpath by the similarity taking source_start and source_end to
target_start and target_end.
pub fn subpath_close(subpath: Subpath) -> Result(Subpath, Error)
Close a subpath without changing its geometry.
A nonempty subpath’s end must exactly equal its start; otherwise returns
Discontinuous. Empty subpaths may be closed. Use subpath_close_with to
reconcile endpoints instead of requiring an exact match.
pub fn subpath_close_with(
subpath: Subpath,
policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)
Close a subpath using an endpoint reconciliation policy.
Reconciles a nonempty subpath’s end with its start, even if it is already closed. This invokes the policy exactly once, for the closing pair only; interior pairs are not revisited. Repeated calls can change geometry if the policy is not idempotent. Empty subpaths may be closed and do not invoke the policy.
pub fn subpath_derivative(
subpath: Subpath,
at parameter: SubpathParameter,
) -> Result(Point, Error)
Return a subpath’s segment derivative at a subpath parameter.
The parameter must address a segment in the subpath, with t inside
0.0..1.0. Internal segment-end parameters are evaluated through their
canonical next-segment start address.
pub fn subpath_directions(
subpath: Subpath,
at parameter: SubpathParameter,
) -> Result(Directions, Error)
Return singularity-safe unit traversal directions at a subpath parameter.
At internal vertices and closed seams, directions are taken from the adjacent segments. Directionless segments are skipped. Open subpath ends have only the side supplied by the subpath.
pub fn subpath_directions_with(
subpath: Subpath,
at parameter: SubpathParameter,
options options: DirectionOptions,
) -> Result(Directions, Error)
Return singularity-safe unit traversal directions using explicit options.
pub fn subpath_empty(at start: Point) -> Subpath
Create an empty open subpath at a start point.
This represents a move-only subpath such as M 0 0.
pub fn subpath_is_closed(subpath: Subpath) -> Bool
Check whether a subpath is closed.
pub fn subpath_is_empty(subpath: Subpath) -> Bool
Check whether a subpath has no segments (a move-only subpath).
pub fn subpath_join(
subpaths: List(Subpath),
) -> Result(Subpath, Error)
Join open subpaths into one open subpath.
Each subpath’s end point must exactly match the next subpath’s start point. Empty open subpaths can act as identity values when their start points line up with their neighbors.
pub fn subpath_join_with(
subpaths: List(Subpath),
policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)
Join open subpaths using the given endpoint policy.
Returns EmptySubpath for an empty input list and AlreadyClosed if any
input is closed. Follows subpath_join, except the policy may repair gaps;
reconciliation errors propagate.
pub fn subpath_map_points(
subpath: Subpath,
with f: fn(Point) -> Point,
) -> Result(Subpath, Error)
Map the defining points of every segment in a subpath.
The subpath’s closed state is preserved. For nonlinear functions, this maps
endpoints and control points, not the exact image of every point on each
rendered curve. If any segment is an arc, this returns
CannotMapArcNonlinearly.
pub fn subpath_normalize_svg_arcs(subpath: Subpath) -> Subpath
Normalize SVG arcs while preserving subpath boundaries, start, and closure. An entirely omitted subpath remains an empty subpath, not a zero-length line. This does not remove zero-length lines or simplify other geometry.
pub fn subpath_normalize_zero_length_lines(
subpath: Subpath,
) -> Subpath
Remove zero-length line segments from a subpath.
If cleanup would remove every segment, one zero-length line is preserved so a zero-length drawing subpath does not become a move-only subpath.
pub fn subpath_open(subpath: Subpath) -> Subpath
Open a subpath without changing its segments, endpoints, or traversal order.
Only the semantic closed flag is cleared. This cannot fail and does not
reconcile endpoints. Empty and already-open subpaths are returned unchanged.
Use subpath_open_at to choose a new start along a closed traversal.
pub fn subpath_open_at(
subpath: Subpath,
at parameter: SubpathParameter,
) -> Result(Subpath, Error)
Break open a closed subpath at the given subpath parameter.
The returned subpath is open and traverses the whole loop from the split
point back to itself. The parameter must address a segment in the closed
subpath, with t inside 0.0..1.0.
pub fn subpath_parameter_canonicalize(
subpath: Subpath,
parameter parameter: SubpathParameter,
) -> Result(SubpathParameter, Error)
Return the exact canonical address of a subpath parameter.
An exact internal segment end canonicalizes to the next segment’s t = 0.0. The exact end of a closed subpath’s last segment canonicalizes to
SubpathParameter(0, 0.0). The end of an open subpath’s last segment
remains at t = 1.0. Parameters merely near a boundary are unchanged.
A local t = -0.0 canonicalizes to 0.0.
pub fn subpath_parameter_compare(
a: SubpathParameter,
b: SubpathParameter,
) -> order.Order
Compare two subpath parameters by segment index and then local t.
pub fn subpath_parameter_from_end(
subpath: Subpath,
segment_index segment_index: Int,
t t: Float,
) -> Result(SubpathParameter, Error)
Return a validated subpath parameter addressed as if the subpath were reversed.
segment_index addresses the reversed segment list. t is also measured in
the reversed segment’s direction, then converted back into the original
subpath’s coordinates.
pub fn subpath_parameter_snap_to_boundary(
subpath: Subpath,
parameter parameter: SubpathParameter,
tolerance tolerance: Float,
) -> Result(SubpathParameter, Error)
Snap a subpath parameter to a segment boundary in parameter space, then return its canonical address.
tolerance is measured in the addressed segment’s local parameter units,
not in path coordinate units. It must be finite and greater than zero.
pub fn subpath_point(
subpath: Subpath,
at parameter: SubpathParameter,
) -> Result(Point, Error)
Evaluate a subpath at a subpath parameter.
The parameter must address a segment in the subpath, with t inside
0.0..1.0. Internal segment-end parameters are evaluated through their
canonical next-segment start address.
pub fn subpath_polygon(
points: List(Point),
) -> Result(Subpath, Error)
Create a closed subpath connecting the given points with line segments.
The input must contain at least two points. If the last point equals the first point, no extra zero-length closing line is added.
This is equivalent to constructing a subpath_polyline from the same points
and closing it with subpath_close_with(..., policy: Bridge).
pub fn subpath_polyline(
points: List(Point),
) -> Result(Subpath, Error)
Create an open subpath connecting the given points with line segments.
The input must contain at least two points.
pub fn subpath_rebuild_with(
subpath: Subpath,
policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)
Rebuild a subpath using an endpoint policy.
This re-runs endpoint reconciliation on the subpath’s current segment list and preserves the subpath’s open/closed state. Empty subpaths are preserved unchanged.
pub fn subpath_remap_endpoints(
subpath: Subpath,
new_start new_start: Point,
new_end new_end: Point,
) -> Result(Subpath, Error)
Remap a subpath so its current endpoints become new_start and new_end.
Empty subpaths keep their empty segment list and move to new_start.
pub fn subpath_reverse(subpath: Subpath) -> Subpath
Reverse the traversal direction of every segment in a subpath.
The subpath’s closed state is preserved.
pub fn subpath_second_derivative(
subpath: Subpath,
at parameter: SubpathParameter,
) -> Result(Point, Error)
Return a subpath’s segment second derivative at a subpath parameter.
The parameter must address a segment in the subpath, with t inside
0.0..1.0. Internal segment-end parameters are evaluated through their
canonical next-segment start address.
pub fn subpath_splice(
subpath: Subpath,
start start: Int,
delete delete: Int,
insert insert: List(Segment),
) -> Result(Subpath, Error)
Replace a range of segments in a subpath.
start is a zero-based segment index and delete is the number of
segments to remove. If start + delete extends past the end of the subpath,
everything from start onward is deleted. Negative start, negative
delete, and start greater than the subpath length return
InvalidSplice.
The edited subpath must remain continuous. Closed subpaths preserve their closed state. If the splice result is nonempty, the subpath start is updated to the first resulting segment’s start point. If the splice result is empty, the previous start point is preserved.
pub fn subpath_splice_with(
subpath: Subpath,
start start: Int,
delete delete: Int,
insert insert: List(Segment),
policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)
Replace a range of segments in a subpath using the given endpoint policy.
Index, deletion, start-point, and closure rules are those of subpath_splice.
The policy reconciles resulting boundaries; errors from that reconciliation
propagate, including violations of the EndpointPolicy custom contract.
pub fn subpath_split(
subpath: Subpath,
at at: SubpathParameter,
) -> Result(#(Subpath, Subpath), Error)
Split an open subpath at a subpath parameter.
The split point must be inside the subpath: it cannot be the first point,
the last point, outside the segment list, or outside the addressed segment’s
0.0..1.0 parameter range. Closed and empty subpaths are rejected.
pub fn subpath_split_many(
subpath: Subpath,
at points: List(SubpathParameter),
) -> Result(List(Subpath), Error)
Split a subpath at multiple subpath parameters.
Open subpaths return the outer pieces as well as the pieces between split points, so an empty split list returns the original subpath. Open split points must be strictly increasing and cannot include the very start or very end. Closed split points must be cyclically increasing and distinct. For closed subpaths, an empty split list returns an empty list, and a single split point returns one open subpath traversing the whole loop from that point back to itself.
pub fn subpath_to_cubic_beziers(subpath: Subpath) -> Subpath
Convert every segment in a subpath to cubic Bezier curves.
Lines and quadratic Beziers are converted exactly. Cubic Beziers are
preserved. Elliptical arcs are approximated with one or more cubic Beziers,
split into chunks of at most a quarter turn.
Arc conversion failures use the straight-cubic fallback documented by
segment_arcs_to_cubic_beziers.
pub fn subpath_to_cubic_beziers_strict(
subpath: Subpath,
) -> Result(Subpath, Error)
Convert a subpath to cubics, stopping at the first arc-conversion error. Preserves the start and closed flag, including for empty subpaths. No partial converted subpath or fallback geometry is returned on failure.
pub fn subpath_to_lines(
subpath: Subpath,
) -> Result(Subpath, Error)
Approximate every segment in a subpath with straight lines.
The subpath’s start point and closed state are preserved. Move-only subpaths remain move-only.
pub fn subpath_to_lines_with(
subpath: Subpath,
options options: LinearizeOptions,
) -> Result(Subpath, Error)
Approximate every segment in a subpath with straight lines using explicit options.
pub fn subpath_try_map_points(
subpath: Subpath,
with f: fn(Point) -> Result(Point, error),
) -> Result(Subpath, PointMapError(error))
Map the defining points of every segment in a subpath with a fallible function.
This has the same geometry semantics as subpath_map_points, but the
mapping function may reject individual points.
pub fn subpath_with(
segments: List(Segment),
policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)
Create an open subpath using the given endpoint reconciliation policy.
Empty segment lists still return EmptySubpath.
Other construction rules are those of subpath, except that policy
may repair endpoint gaps. Returns an error if the policy cannot reconcile
a boundary or a custom replacement violates the EndpointPolicy contract.
pub fn wiggle_else_bridge_with(
tolerance: Float,
) -> EndpointPolicy
Create a wiggle-else-bridge endpoint policy with a custom distance tolerance.
pub fn wiggle_with(tolerance: Float) -> EndpointPolicy
Create a wiggle endpoint policy with a custom distance tolerance.