svg_path

Core SVG path data structures and constructors.

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.

Types

An axis-aligned bounding box.

pub type BoundingBox {
  BoundingBox(min: Point, max: Point)
}

Constructors

Options for classifying a point relative to a subpath’s fill area.

pub type ContainmentOptions {
  ContainmentOptions(
    tolerance: Float,
    samples: Int,
    max_iterations: Int,
  )
}

Constructors

  • ContainmentOptions(
      tolerance: Float,
      samples: Int,
      max_iterations: Int,
    )

Options for detecting scalar zero crossings along a segment.

pub type CrossingOptions {
  CrossingOptions(
    samples: Int,
    tolerance: Float,
    max_iterations: Int,
  )
}

Constructors

  • CrossingOptions(
      samples: Int,
      tolerance: Float,
      max_iterations: Int,
    )

Error measurements for a fitted cubic Bezier segment.

pub type CubicFitReport {
  CubicFitReport(
    root_sum_square: Float,
    root_mean_square: Float,
    max: Float,
  )
}

Constructors

  • CubicFitReport(
      root_sum_square: Float,
      root_mean_square: Float,
      max: Float,
    )

    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.

Options for finding the distance from a point to a segment.

pub type DistanceOptions {
  DistanceOptions(
    samples: Int,
    tolerance: Float,
    max_iterations: Int,
  )
}

Constructors

  • DistanceOptions(
      samples: Int,
      tolerance: Float,
      max_iterations: Int,
    )

How construction and editing helpers reconcile segment endpoints.

pub type EndpointPolicy {
  Strict
  Wiggle
  WiggleWith(Float)
  Bridge
  WiggleThenBridge
  WiggleThenBridgeWith(Float)
  Custom(
    fn(Segment, Segment, Bool) -> #(
      Segment,
      List(Segment),
      Segment,
    ),
  )
}

Constructors

  • Strict

    Endpoints must already match exactly.

  • Wiggle

    Move nearby endpoints together within the default wiggle tolerance.

  • WiggleWith(Float)

    Move nearby endpoints together within the supplied tolerance.

  • Bridge

    Keep endpoints unchanged and insert a straight line if needed.

  • WiggleThenBridge

    Try Wiggle; if that fails, use Bridge.

  • WiggleThenBridgeWith(Float)

    Try wiggle with the supplied tolerance; if that fails, use Bridge.

  • Custom(
      fn(Segment, Segment, Bool) -> #(Segment, List(Segment), Segment),
    )

    Reconcile non-matching adjacent segments with a caller-provided function.

    The middle segments are inserted between the adjusted adjacent segments. The callback’s third argument is True only for a closing join from the last segment back to the first segment.

Errors returned by path construction and editing helpers.

pub type Error {
  AlreadyClosed
  Discontinuous(
    previous_index: Int,
    next_index: Int,
    expected: Point,
    got: Point,
    distance: Float,
  )
  EmptySubpath
  NotClosed
  EmptyPath
  EmptySubpaths
  DegenerateArc
  CannotMapArcNonlinearly
  IncompatibleHorizontalWiggle(
    previous_end: Point,
    next_start: Point,
  )
  IncompatibleVerticalWiggle(
    previous_end: Point,
    next_start: Point,
  )
  InvalidSplice(start: Int, delete: Int, length: Int)
  InvalidSubpathParameter(
    segment_index: Int,
    t: Float,
    length: Int,
  )
  InvalidPathParameter(subpath_index: Int, length: Int)
  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)
  InvalidContainmentTolerance(tolerance: Float)
  InvalidContainmentSamples(samples: Int)
  InvalidContainmentMaxIterations(max_iterations: Int)
  InvalidIntersectionTolerance(tolerance: Float)
  InvalidIntersectionMaxDepth(max_depth: Int)
  InvalidSelfIntersectionMinimumArcLengthSeparation(Float)
  InvalidSelfIntersectionDistanceTolerance(Float)
  OverlappingSegments
  MultipleNonemptySubpaths
  NotCloseEnough(expected: Point, got: Point, tolerance: Float)
  SplitOutsideSegment
}

Constructors

  • AlreadyClosed

    The 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_index is the segment whose end point was expected. next_index is the segment whose start point did not match. distance is the distance between expected and got.

  • EmptySubpath

    The operation requires a non-empty subpath.

  • NotClosed

    The operation requires a closed subpath.

  • EmptyPath

    The operation requires a path with at least one subpath.

  • EmptySubpaths

    The operation requires a path with at least one non-empty subpath.

  • DegenerateArc

    The arc cannot be converted to center-parameter form.

  • CannotMapArcNonlinearly

    Nonlinear point mapping cannot preserve an SVG arc segment.

  • IncompatibleHorizontalWiggle(
      previous_end: Point,
      next_start: Point,
    )

    A wiggle operation could not reconcile two horizontal line segments.

  • IncompatibleVerticalWiggle(
      previous_end: Point,
      next_start: Point,
    )

    A wiggle operation could not reconcile two vertical line segments.

  • InvalidSplice(start: Int, delete: Int, length: Int)

    A splice was requested with invalid bounds.

    This is returned when start is negative, delete is negative, or start is 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.0 range.

  • InvalidPathParameter(subpath_index: Int, length: Int)

    A path parameter was outside the valid subpath index range.

  • 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 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 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 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 for subdivision must be greater than zero.

  • InvalidParametricTolerance(tolerance: Float)

    Parametric fitting tolerance must be 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 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.

  • ParametricFitFailed

    A parametric interval could not determine a stable cubic fit.

  • DegenerateCubicFitTangent

    A cubic fit tangent was too small to normalize.

  • UnderdeterminedCubicFit

    A cubic fit did not have enough sample information to determine controls.

  • InvalidLinearizeTolerance(tolerance: Float)

    The line approximation tolerance must be 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.

  • InvalidDistanceSamples(samples: Int)

    The number of distance scan samples must be greater than zero.

  • InvalidDistanceTolerance(tolerance: Float)

    The distance tolerance must be 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.

  • InvalidContainmentTolerance(tolerance: Float)

    The containment tolerance must be 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.

  • InvalidIntersectionTolerance(tolerance: Float)

    The intersection tolerance must be greater than zero.

  • InvalidIntersectionMaxDepth(max_depth: Int)

    The intersection subdivision depth must be greater than zero.

  • InvalidSelfIntersectionMinimumArcLengthSeparation(Float)

    The self-intersection minimum arc length separation must be greater than zero.

  • InvalidSelfIntersectionDistanceTolerance(Float)

    The self-intersection distance tolerance must be greater than zero.

  • OverlappingSegments

    The two segments overlap in more than a single point.

  • MultipleNonemptySubpaths

    The path contains more than one non-empty subpath.

  • NotCloseEnough(expected: Point, got: Point, tolerance: Float)

    Two points were too far apart for a wiggle operation to merge them.

  • SplitOutsideSegment

    The requested split point is outside the segment’s 0.0..1.0 parameter 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)

Options for approximating segments with straight lines.

pub type LinearizeOptions {
  LinearizeOptions(tolerance: Float, max_depth: Int)
}

Constructors

  • LinearizeOptions(tolerance: Float, max_depth: Int)

Options for minimizing a scalar function along a segment.

pub type MinimizeOptions {
  MinimizeOptions(
    samples: Int,
    tolerance: Float,
    max_iterations: Int,
  )
}

Constructors

  • MinimizeOptions(
      samples: Int,
      tolerance: Float,
      max_iterations: Int,
    )

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),
    )

An SVG path, made of zero or more subpaths.

pub type Path {
  Path(subpaths: List(Subpath))
}

Constructors

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

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

The nearest point on a path to an input point.

Move-only subpaths are skipped. When multiple path points are equally nearest, this records one valid nearest point. The chosen point and parameter are not guaranteed to be canonical for ties or flat minima.

pub type PathProjection {
  PathProjection(
    at: PathParameter,
    point: Point,
    distance: Float,
  )
}

Constructors

A point where a path intersects itself.

pub type PathSelfIntersection {
  PathSelfIntersection(
    point: Point,
    parameters: #(PathParameter, PathParameter),
  )
}

Constructors

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)
  PointMapFunctionError(error)
}

Constructors

  • PointMapPathError(Error)

    The path structure could not be mapped.

  • PointMapFunctionError(error)

    The caller-provided point mapping function failed.

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

  • Line(start: Point, end: Point)

    A straight line segment.

  • QuadraticBezier(start: Point, control: Point, end: Point)

    A quadratic Bezier curve segment.

  • CubicBezier(
      start: Point,
      control1: Point,
      control2: Point,
      end: Point,
    )

    A cubic Bezier curve segment.

  • Arc(
      start: Point,
      radius: Point,
      x_axis_rotation: Float,
      large_arc: Bool,
      sweep: Bool,
      end: Point,
    )

    An elliptical arc segment. x_axis_rotation is in degrees.

A point intersection between two segments.

pub type SegmentIntersection {
  SegmentIntersection(
    left_t: Float,
    right_t: Float,
    point: Point,
  )
}

Constructors

  • SegmentIntersection(left_t: Float, right_t: Float, point: Point)

The nearest point on a segment to an input point.

When multiple segment points are equally nearest, this records one valid nearest point. The chosen point and parameter are not guaranteed to be canonical for ties or flat minima.

pub type SegmentProjection {
  SegmentProjection(t: Float, point: Point, distance: Float)
}

Constructors

  • SegmentProjection(t: Float, point: Point, distance: Float)

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,
    )

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

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)

The nearest point on a subpath to an input point.

When multiple subpath points are equally nearest, this records one valid nearest point. The chosen point and parameter are not guaranteed to be canonical for ties or flat minima.

pub type SubpathProjection {
  SubpathProjection(
    at: SubpathParameter,
    point: Point,
    distance: Float,
  )
}

Constructors

A point where a subpath intersects itself.

pub type SubpathSelfIntersection {
  SubpathSelfIntersection(
    point: Point,
    parameters: #(SubpathParameter, SubpathParameter),
  )
}

Constructors

Values

pub fn arc_angle_at(
  segment: Segment,
  t t: Float,
) -> Result(Float, Error)

Return the ellipse angle, in degrees, reached at arc parameter t.

This is a root-module convenience wrapper around ellipse.angle_at. Non-arc segments return DegenerateArc.

pub fn arc_center_data(
  segment: Segment,
) -> Result(ellipse.CenterArcData, Error)

Return an elliptical arc segment as center-parameter arc data.

pub fn arc_derivative(
  segment: Segment,
  at t: Float,
) -> Result(Point, Error)

Return an arc segment’s derivative with respect to parameter t.

This is a root-module convenience wrapper around ellipse.arc_derivative that accepts an svg_path.Arc segment and returns svg_path.Point. Non-arc segments return DegenerateArc.

pub fn arc_derivative_at_angle(
  segment: Segment,
  angle angle: Float,
) -> Result(Point, Error)

Return an arc segment’s derivative at an ellipse angle in degrees.

This is a root-module convenience wrapper around ellipse.arc_derivative_at_angle that accepts an svg_path.Arc segment and returns svg_path.Point. Non-arc segments return DegenerateArc.

pub fn arc_end_angle(segment: Segment) -> Result(Float, Error)

Return the end angle, in degrees, of an arc segment.

This is a root-module convenience wrapper around ellipse.arc_end_angle. Non-arc segments return DegenerateArc.

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 arc_point(
  segment: Segment,
  at t: Float,
) -> Result(Point, Error)

Evaluate an arc segment at parameter t.

This is a root-module convenience wrapper around ellipse.arc_point that accepts an svg_path.Arc segment and returns svg_path.Point. Non-arc segments return DegenerateArc.

pub fn arc_point_at_angle(
  segment: Segment,
  angle angle: Float,
) -> Result(Point, Error)

Evaluate an arc segment at an ellipse angle in degrees.

This is a root-module convenience wrapper around ellipse.arc_point_at_angle that accepts an svg_path.Arc segment and returns svg_path.Point. Non-arc segments return DegenerateArc.

pub fn bounding_box_center(box: BoundingBox) -> Point

Return the center point of a bounding box.

pub fn bounding_box_diameter(box: BoundingBox) -> Float

Return the taxicab diameter of a bounding box.

This is the box width plus the box height.

pub fn bounding_box_height(box: BoundingBox) -> Float

Return the height of a bounding box.

pub fn bounding_box_union(
  first: BoundingBox,
  second: BoundingBox,
) -> BoundingBox

Return the smallest axis-aligned bounding box containing both boxes.

pub fn bounding_box_union_many(
  boxes: List(BoundingBox),
) -> Result(BoundingBox, Nil)

Return the smallest axis-aligned bounding box containing every box.

pub fn bounding_box_width(box: BoundingBox) -> Float

Return the width of a bounding box.

pub fn default_containment_options() -> ContainmentOptions

Return the default options for point containment.

pub fn default_crossing_options() -> CrossingOptions

Return the default options for segment crossing detection.

pub fn default_distance_options() -> DistanceOptions

Return the default options for point-to-segment distance measurement.

pub fn default_length_options() -> LengthOptions

Return the default options for segment and subpath length approximation.

pub fn default_linearize_options() -> LinearizeOptions

Return the default options for straight-line approximation.

pub fn default_minimize_options() -> MinimizeOptions

Return the default options for segment minimization.

pub fn default_parametric_options() -> ParametricOptions

Return the default options for parametric subpath fitting.

pub fn fit_cubic_with_endpoint_tangents(
  start start: Point,
  end end: Point,
  start_tangent start_tangent: Point,
  end_tangent end_tangent: Point,
  samples samples: List(#(Float, Point)),
) -> Result(#(Segment, CubicFitReport), Error)

Fit a cubic Bezier segment with fixed endpoints and endpoint tangents.

This is a root-module convenience wrapper around bezier.fit_cubic_with_endpoint_tangents. It accepts svg_path.Point values, returns an svg_path.CubicBezier segment, and maps fit failures into svg_path.Error.

pub fn fit_cubic_with_endpoints(
  start start: Point,
  end end: Point,
  samples samples: List(#(Float, Point)),
) -> Result(#(Segment, CubicFitReport), Error)

Fit a cubic Bezier segment with fixed endpoints and no tangent constraints.

This is a root-module convenience wrapper around bezier.fit_cubic_with_endpoints. It accepts svg_path.Point values, returns an svg_path.CubicBezier segment, and maps fit failures into svg_path.Error.

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_bounding_box(
  path: Path,
) -> Result(BoundingBox, Error)

Return the exact axis-aligned bounding box of all non-empty subpaths.

pub fn path_combine(paths: List(Path)) -> Path

Combine paths by concatenating their subpaths.

pub fn path_containment(
  point: Point,
  within path: Path,
  using fill_rule: FillRule,
) -> Result(PointContainment, Error)

Classify a point relative to a path’s combined fill area.

Winding and crossing counts are accumulated across all non-move-only subpaths. Each open subpath is implicitly closed independently. A boundary match on any subpath takes precedence. Empty and move-only paths are Outside.

pub fn path_containment_with(
  point: Point,
  within path: Path,
  using fill_rule: FillRule,
  options options: ContainmentOptions,
) -> Result(PointContainment, Error)

Classify a point relative to a path’s combined fill area using explicit options.

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_derivative_at_length(
  path: Path,
  distance distance: Float,
) -> Result(Point, Error)

Return the path derivative at a traveled distance from the path start.

pub fn path_derivative_at_length_with(
  path: Path,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Point, Error)

Return the path derivative at a traveled distance using explicit options.

pub fn path_distance(
  point: Point,
  to path: Path,
) -> Result(Float, Error)

Return the shortest distance from a point to a path.

Move-only subpaths are skipped.

pub fn path_distance_with(
  point: Point,
  to path: Path,
  options options: DistanceOptions,
) -> Result(Float, Error)

Return the shortest distance from a point to a path using explicit options.

pub fn path_empty() -> Path

Create an empty path.

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_from_subpath(subpath: Subpath) -> Path

Create a path containing a single subpath.

pub fn path_length(path: Path) -> Result(Float, Error)

Return the approximate length of a path.

Empty paths have length 0.0. Move-only subpaths contribute 0.0.

pub fn path_length_with(
  path: Path,
  options options: LengthOptions,
) -> Result(Float, Error)

Return the approximate length of a path using explicit options.

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_parameter_at_length(
  path: Path,
  distance distance: Float,
) -> Result(PathParameter, Error)

Return the path parameter at a traveled distance from the path start.

The distance is measured across subpaths in path order. Move-only subpaths contribute no length and are skipped for lookup. The returned value is an ordinary public PathParameter.

pub fn path_parameter_at_length_with(
  path: Path,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(PathParameter, Error)

Return the path parameter at a traveled distance using explicit options.

pub fn path_parameters_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_point_at_length(
  path: Path,
  distance distance: Float,
) -> Result(Point, Error)

Return the path point at a traveled distance from the path start.

pub fn path_point_at_length_with(
  path: Path,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Point, Error)

Return the path point at a traveled distance using explicit options.

pub fn path_projection(
  point: Point,
  to path: Path,
) -> Result(PathProjection, Error)

Return the nearest point on a path to an input point.

Move-only subpaths are skipped. An empty path returns EmptyPath; a path containing only move-only subpaths returns EmptySubpaths.

pub fn path_projection_with(
  point: Point,
  to path: Path,
  options options: DistanceOptions,
) -> Result(PathProjection, Error)

Return the nearest point on a path to an input point using explicit options.

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_start(path: Path) -> Result(Point, Error)

Return the start point of the first subpath in a path.

pub fn path_subdivide_to_max_length(
  path: Path,
  max_length max_length: Float,
) -> Result(Path, Error)

Subdivide every segment in a path into pieces of at most max_length.

Existing subpath boundaries and closed states are preserved.

pub fn path_subdivide_to_max_length_with(
  path: Path,
  max_length max_length: Float,
  options options: LengthOptions,
) -> Result(Path, Error)

Subdivide every segment in a path into pieces of at most max_length using explicit length options.

pub fn path_subpaths(path: Path) -> List(Subpath)

Return the subpaths 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_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 path_winding(
  point: Point,
  within path: Path,
) -> Result(PathWinding, Error)

Return the signed winding number of a path around a point.

Open subpaths are implicitly closed, matching path_containment. If the point is within the boundary tolerance of any non-empty subpath, the result is BoundaryWinding because the winding number is not numerically stable at that point.

pub fn path_winding_with(
  point: Point,
  within path: Path,
  options options: ContainmentOptions,
) -> Result(PathWinding, Error)

Return the signed winding number of a path around a point using explicit containment options.

pub fn points_bounding_box(
  points: List(Point),
) -> Result(BoundingBox, Nil)

Return the smallest axis-aligned bounding box containing every 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.

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_lengths(
  segment: Segment,
  from from: Float,
  to to: Float,
) -> Result(Segment, Error)

Return the portion of a segment between two traveled distances.

Distances are measured in path coordinate units from the segment start and must be inside 0.0..length, inclusive. If from is greater than to, the returned segment traverses the interval in reverse.

pub fn segment_between_lengths_many(
  segment: Segment,
  between distances: List(Float),
) -> Result(List(Segment), Error)

Return segment portions between adjacent traveled distances.

Distances are measured in path coordinate units from the segment start and must be inside 0.0..length, inclusive. Empty and singleton lists return an empty list.

pub fn segment_between_lengths_many_with(
  segment: Segment,
  between distances: List(Float),
  options options: LengthOptions,
) -> Result(List(Segment), Error)

Return segment portions between adjacent traveled distances using explicit length options.

pub fn segment_between_lengths_with(
  segment: Segment,
  from from: Float,
  to to: Float,
  options options: LengthOptions,
) -> Result(Segment, Error)

Return the portion of a segment between two traveled distances using explicit length options.

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_bounding_box(
  segment: Segment,
) -> Result(BoundingBox, Error)

Return a segment’s exact axis-aligned bounding box.

pub fn segment_crossings(
  segment: Segment,
  where f: fn(Point) -> Float,
) -> Result(List(Float), Error)

Find scalar sign-change crossings along a segment using default options.

This samples t in 0.0..1.0, detects sign changes of f(segment_point(t)), and refines each bracket with bisection. It finds crossings visible at the configured sampling resolution; tangent roots and pairs of crossings inside one sample window may be missed.

pub fn segment_crossings_with(
  segment: Segment,
  where f: fn(Point) -> Float,
  options options: CrossingOptions,
) -> Result(List(Float), Error)

Find scalar sign-change crossings along a segment using explicit options.

pub fn segment_degenerate_lines(
  segment: Segment,
  tolerance tolerance: Float,
) -> Result(option.Option(List(Segment)), Error)

Detect a curve that is contained in an absolute-width strip and replace it with ordered line segments when possible.

tolerance is the maximum distance from the replacement line or lines to the curve, in path coordinate units. Ok(None) means that the segment is not line-degenerate. Ok(Some(lines)) preserves collinear backtracking; Some([]) represents a curve with no movement. Lines themselves return Ok(None). The tolerance must be greater than zero.

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_derivative_at_length(
  segment: Segment,
  distance distance: Float,
) -> Result(Point, Error)

Return the segment derivative at a traveled distance from the segment start.

pub fn segment_derivative_at_length_with(
  segment: Segment,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Point, Error)

Return the segment derivative at a traveled distance using explicit options.

pub fn segment_distance(
  point: Point,
  to segment: Segment,
) -> Result(Float, Error)

Return the shortest distance from a point to a segment.

Lines are measured exactly. Quadratic Beziers, cubic Beziers, and arcs are measured by finding stationary points of squared distance in 0.0..1.0.

pub fn segment_distance_with(
  point: Point,
  to segment: Segment,
  options options: DistanceOptions,
) -> Result(Float, Error)

Return the shortest distance from a point to a segment using explicit options.

pub fn segment_end(segment: Segment) -> Point

Return the end point of a segment.

pub fn segment_is_zero_length(
  segment: Segment,
  tolerance tolerance: Float,
) -> Result(Bool, Error)

Return whether a segment has length at most tolerance.

tolerance is measured in path coordinate units and may be exactly 0.0 for an exact zero-length check. Lines are measured exactly. Quadratic Beziers, cubic Beziers, and arcs are measured with default length options.

pub fn segment_length(segment: Segment) -> Result(Float, Error)

Return the approximate length of a segment.

Lines are measured exactly. Quadratic Beziers, cubic Beziers, and arcs are approximated by adaptive Simpson integration of segment speed.

pub fn segment_length_with(
  segment: Segment,
  options options: LengthOptions,
) -> Result(Float, Error)

Return the approximate length of a segment using explicit options.

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_minimize(
  segment: Segment,
  measure f: fn(Point) -> Float,
) -> Result(Float, Error)

Return the segment parameter where a scalar function is minimized.

This numerically minimizes f(segment_point(t)) for t in 0.0..1.0.

pub fn segment_minimize_with(
  segment: Segment,
  measure f: fn(Point) -> Float,
  options options: MinimizeOptions,
) -> Result(Float, Error)

Return the segment parameter where a scalar function is minimized using explicit options.

pub fn segment_parameter_at_length(
  segment: Segment,
  distance distance: Float,
) -> Result(Float, Error)

Return the segment parameter at a traveled distance from the segment start.

The distance is measured in path coordinate units, not normalized. Lines are inverted exactly. Quadratic Beziers, cubic Beziers, and arcs are inverted numerically using the same length options as segment_length_with.

pub fn segment_parameter_at_length_with(
  segment: Segment,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Float, Error)

Return the segment parameter at a traveled distance using explicit options.

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_point_at_length(
  segment: Segment,
  distance distance: Float,
) -> Result(Point, Error)

Return the segment point at a traveled distance from the segment start.

pub fn segment_point_at_length_with(
  segment: Segment,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Point, Error)

Return the segment point at a traveled distance using explicit options.

pub fn segment_projection(
  point: Point,
  to segment: Segment,
) -> Result(SegmentProjection, Error)

Return the nearest point on a segment to an input point.

pub fn segment_projection_with(
  point: Point,
  to segment: Segment,
  options options: DistanceOptions,
) -> Result(SegmentProjection, Error)

Return the nearest point on a segment to an input point using explicit options.

pub fn segment_reverse(segment: Segment) -> Segment

Reverse the traversal direction of a segment.

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.

pub fn segment_start(segment: Segment) -> Point

Return the start point of a segment.

pub fn segment_subdivide_to_max_length(
  segment: Segment,
  max_length max_length: Float,
) -> Result(List(Segment), Error)

Subdivide a segment into pieces of at most max_length.

Splits are chosen by traveled arc length, not by equal Bezier or arc parameter spacing. Zero-length segments are returned unchanged.

pub fn segment_subdivide_to_max_length_with(
  segment: Segment,
  max_length max_length: Float,
  options options: LengthOptions,
) -> Result(List(Segment), Error)

Subdivide a segment into pieces of at most max_length using explicit length options.

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.

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. Degenerate arcs fall back to a straight line between their endpoints.

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.

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_assert(segments: List(Segment)) -> Subpath

Create an open subpath from a non-empty continuous list of segments, panicking if the segments are invalid.

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 to an open subpath, panicking if invalid.

pub fn subpath_assert_append_segment_with(
  subpath: Subpath,
  segment: Segment,
  policy endpoint_policy: EndpointPolicy,
) -> Subpath

Append a segment with an endpoint policy, panicking if invalid.

pub fn subpath_assert_join(subpaths: List(Subpath)) -> Subpath

Join open subpaths, panicking if invalid.

pub fn subpath_assert_join_with(
  subpaths: List(Subpath),
  policy endpoint_policy: EndpointPolicy,
) -> Subpath

Join open subpaths with an endpoint policy, panicking if invalid.

pub fn subpath_assert_polygon(points: List(Point)) -> Subpath

Create a closed polygon subpath, panicking if the point list is invalid.

pub fn subpath_assert_polyline(points: List(Point)) -> Subpath

Create an open polyline subpath, panicking if the point list is invalid.

pub fn subpath_assert_set_closed(
  subpath: Subpath,
  closed closed: Bool,
) -> Subpath

Set a subpath’s semantic closed state, panicking if invalid.

pub fn subpath_assert_set_closed_with(
  subpath: Subpath,
  closed closed: Bool,
  policy endpoint_policy: EndpointPolicy,
) -> Subpath

Set a subpath’s semantic closed state with an endpoint policy, panicking if invalid.

pub fn subpath_assert_splice(
  subpath: Subpath,
  start start: Int,
  delete delete: Int,
  insert insert: List(Segment),
) -> Subpath

Replace a range of segments, panicking if the splice is invalid.

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, panicking if invalid.

pub fn subpath_assert_with(
  segments: List(Segment),
  policy endpoint_policy: EndpointPolicy,
) -> Subpath

Create an open subpath with an endpoint policy, panicking if construction fails.

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_between_lengths(
  subpath: Subpath,
  from from: Float,
  to to: Float,
) -> Result(Subpath, Error)

Return the open subpath between two traveled distances.

Distances are measured in path coordinate units from the subpath start and must be inside 0.0..length, inclusive. The resulting parameters follow the same interval rules as subpath_between.

pub fn subpath_between_lengths_many(
  subpath: Subpath,
  between distances: List(Float),
) -> Result(List(Subpath), Error)

Split a subpath at multiple traveled distances.

Distances are measured in path coordinate units from the subpath start and must be inside 0.0..length, inclusive. The resulting parameters follow the same split-point rules as subpath_between_many.

pub fn subpath_between_lengths_many_with(
  subpath: Subpath,
  between distances: List(Float),
  options options: LengthOptions,
) -> Result(List(Subpath), Error)

Split a subpath at multiple traveled distances using explicit length options.

pub fn subpath_between_lengths_with(
  subpath: Subpath,
  from from: Float,
  to to: Float,
  options options: LengthOptions,
) -> Result(Subpath, Error)

Return the open subpath between two traveled distances using explicit length options.

pub fn subpath_between_many(
  subpath: Subpath,
  between 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_bounding_box(
  subpath: Subpath,
) -> Result(BoundingBox, Error)

Return a non-empty subpath’s exact axis-aligned bounding box.

pub fn subpath_clean(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_containment(
  point: Point,
  within subpath: Subpath,
  using fill_rule: FillRule,
) -> Result(PointContainment, Error)

Classify a point relative to a subpath’s fill area.

Open and closed subpaths use the same fill geometry: an open subpath is implicitly closed by a straight line from its end to its start. Move-only subpaths have no fill area or boundary.

pub fn subpath_containment_with(
  point: Point,
  within subpath: Subpath,
  using fill_rule: FillRule,
  options options: ContainmentOptions,
) -> Result(PointContainment, Error)

Classify a point relative to a subpath’s fill area using explicit options.

tolerance is measured in path coordinate units and determines the width classified as Boundary. samples and max_iterations control numerical projection and adaptive line approximation for curves.

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_derivative_at_length(
  subpath: Subpath,
  distance distance: Float,
) -> Result(Point, Error)

Return the subpath derivative at a traveled distance from the subpath start.

pub fn subpath_derivative_at_length_with(
  subpath: Subpath,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Point, Error)

Return the subpath derivative at a traveled distance 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_end(subpath: Subpath) -> Result(Point, Error)

Return the end point of a subpath.

pub fn subpath_is_closed(subpath: Subpath) -> Bool

Check whether a subpath is closed.

pub fn subpath_is_zero_length(
  subpath: Subpath,
  tolerance tolerance: Float,
) -> Result(Bool, Error)

Return whether a subpath is a zero-length drawing subpath.

Empty subpaths are not considered zero-length drawing subpaths. A non-empty subpath is zero-length when every segment has length at most tolerance.

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.

pub fn subpath_length(subpath: Subpath) -> Result(Float, Error)

Return the approximate length of a subpath.

Empty subpaths have length 0.0.

pub fn subpath_length_with(
  subpath: Subpath,
  options options: LengthOptions,
) -> Result(Float, Error)

Return the approximate length of a subpath using explicit options.

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_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_at_length(
  subpath: Subpath,
  distance distance: Float,
) -> Result(SubpathParameter, Error)

Return the subpath parameter at a traveled distance from the subpath start.

The distance is measured in path coordinate units, not normalized. The returned value is an ordinary public SubpathParameter.

pub fn subpath_parameter_at_length_with(
  subpath: Subpath,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(SubpathParameter, Error)

Return the subpath parameter at a traveled distance using explicit options.

pub fn subpath_parameter_canonicalize(
  subpath: Subpath,
  parameter parameter: SubpathParameter,
  tolerance tolerance: Float,
) -> Result(SubpathParameter, Error)

Snap a subpath parameter to its canonical boundary address when it is within tolerance of a segment boundary.

Internal segment ends canonicalize to the next segment’s t = 0.0. The 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.

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_parameters_compare(
  a: SubpathParameter,
  b: SubpathParameter,
) -> order.Order

Compare two subpath parameters by segment index and then local t.

pub fn subpath_parametric(
  from start: Float,
  to end: Float,
  point point_function: fn(Float) -> Point,
) -> Result(Subpath, Error)

Approximate a parametric curve with a sequence of cubic Bezier segments.

The parameter interval is split uniformly into default_parametric_options().initial_piece_count pieces. Each piece is fitted with a cubic, then recursively bisected in parameter space until the maximum sampled fitting error is within tolerance.

pub fn subpath_parametric_with(
  from start: Float,
  to end: Float,
  point point_function: fn(Float) -> Point,
  options options: ParametricOptions,
) -> Result(Subpath, Error)

Approximate a parametric curve with a sequence of cubic Bezier segments using explicit options.

If options.tangent is Some(tangent_function), each cubic is constrained to match the endpoint tangent directions returned by that function. If it is None, control points are fitted from samples while the endpoints are fixed.

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_point_at_length(
  subpath: Subpath,
  distance distance: Float,
) -> Result(Point, Error)

Return the subpath point at a traveled distance from the subpath start.

pub fn subpath_point_at_length_with(
  subpath: Subpath,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Point, Error)

Return the subpath point at a traveled distance using explicit options.

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_set_closed_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_projection(
  point: Point,
  to subpath: Subpath,
) -> Result(SubpathProjection, Error)

Return the nearest point on a subpath to an input point.

pub fn subpath_projection_with(
  point: Point,
  to subpath: Subpath,
  options options: DistanceOptions,
) -> Result(SubpathProjection, Error)

Return the nearest point on a subpath to an input point using explicit options.

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_segments(subpath: Subpath) -> List(Segment)

Return the segments in a subpath.

pub fn subpath_set_closed(
  subpath: Subpath,
  closed closed: Bool,
) -> Result(Subpath, Error)

Set a subpath’s semantic closed state.

Setting closed to False always succeeds. Setting it to True requires a non-empty subpath’s end point to exactly match its start point. Empty subpaths may be closed.

pub fn subpath_set_closed_with(
  subpath: Subpath,
  closed closed: Bool,
  policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)

Set a subpath’s semantic closed state with an endpoint policy.

Setting closed to False always succeeds. Setting it to True uses the given endpoint policy to reconcile a non-empty subpath’s end point with its start point. Empty subpaths may be closed.

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.

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_start(subpath: Subpath) -> Result(Point, Error)

Return the start point of a subpath.

pub fn subpath_subdivide_to_max_length(
  subpath: Subpath,
  max_length max_length: Float,
) -> Result(Subpath, Error)

Subdivide every segment in a subpath into pieces of at most max_length.

Existing segment boundaries are preserved. The subpath’s closed state is preserved.

pub fn subpath_subdivide_to_max_length_with(
  subpath: Subpath,
  max_length max_length: Float,
  options options: LengthOptions,
) -> Result(Subpath, Error)

Subdivide every segment in a subpath into pieces of at most max_length using explicit length options.

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.

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.

pub fn wiggle_then_bridge_with(
  tolerance: Float,
) -> EndpointPolicy

Create a wiggle-then-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.

Search Document