Donner
Embeddable browser-grade SVG2 engine
Loading...
Searching...
No Matches
donner::Path Class Reference

Immutable 2D vector path. More...

#include "donner/base/Path.h"

Classes

struct  Command
 A command in the path, pairing a verb with the index of its first point. More...
struct  PointOnPath
 Result of sampling the path at a given arc length distance. More...
struct  Vertex
 Vertex in a path's edge list, used for marker placement. More...

Public Types

enum class  Verb : uint8_t {
  MoveTo ,
  LineTo ,
  QuadTo ,
  CurveTo ,
  ClosePath
}
 Verb types describing how points are connected. More...

Public Member Functions

 Path ()=default
 Construct an empty path.
 Path (const Path &)=default
 Path (Path &&) noexcept=default
Pathoperator= (const Path &)=default
Pathoperator= (Path &&) noexcept=default
Accessors
std::span< const Vector2dpoints () const
 Returns the points array.
std::span< const Commandcommands () const
 Returns the commands array.
bool empty () const
 Returns true if the path has no commands.
size_t verbCount () const
 Returns the number of commands (verbs) in the path.
Geometric queries
Box2d bounds () const
 Returns the axis-aligned bounding box of the path.
Box2d transformedBounds (const Transform2d &transform) const
 Returns the bounding box of the path transformed by transform.
bool isInside (const Vector2d &point, FillRule fillRule=FillRule::NonZero) const
 Returns true if the given point is inside this path's fill region.
bool isOnPath (const Vector2d &point, double strokeWidth) const
 Returns true if the given point is within strokeWidth / 2 of any path segment.
double pathLength () const
 Compute the total arc length of the path.
PointOnPath pointAtArcLength (double distance) const
 Sample the path at the given arc length distance from the start.
Vector2d pointAt (size_t index, double t) const
 Evaluate the position on segment index at parameter t in [0, 1].
Vector2d tangentAt (size_t index, double t) const
 Return the un-normalized tangent vector at segment index, parameter t.
Vector2d normalAt (size_t index, double t) const
 Return the normal vector (perpendicular to the tangent) at segment index, parameter t.
Box2d strokeMiterBounds (double strokeWidth, double miterLimit) const
 Compute the bounding box of the stroked path, accounting for miter joins.
Conversions
Path cubicToQuadratic (double tolerance=0.1) const
 Convert all cubic Bézier curves to quadratic approximations within tolerance.
Path toMonotonic () const
 Split all curves at Y-extrema so each segment is monotonic in Y.
Path flatten (double tolerance=0.25) const
 Flatten all curves to line segments within tolerance.
Path strokeToFill (const StrokeStyle &style, double flattenTolerance=0.25) const
 Convert this path's stroke to a filled outline.
Iteration
template<typename F>
void forEach (F &&fn) const
 Iterate over path segments, calling fn for each command.
std::vector< Vertexvertices () const
 Returns the vertices of the path as a flat list for marker placement.

Static Public Member Functions

static constexpr size_t pointsPerVerb (Verb verb)
 Returns the number of points consumed by a given verb.

Friends

class PathBuilder
std::ostream & operator<< (std::ostream &os, Path::Verb verb)
 Ostream output operator for Verb.
std::ostream & operator<< (std::ostream &os, const Path &path)
 Ostream output operator.

Detailed Description

Immutable 2D vector path.

Once constructed via PathBuilder, a Path is immutable and thread-safe. Paths are suitable for caching in ECS components (e.g., GPU band data for the Geode renderer).

Supports line segments, quadratic Bézier curves, and cubic Bézier curves.


Class Documentation

◆ donner::Path::PointOnPath

struct donner::Path::PointOnPath

Result of sampling the path at a given arc length distance.

Collaboration diagram for donner::Path::PointOnPath:
[legend]
Class Members
double angle Tangent angle in radians (atan2).
Vector2d point Position on the path.
Vector2d tangent Un-normalized tangent vector at the point.
bool valid = true False if distance exceeds path length.

Member Enumeration Documentation

◆ Verb

enum class donner::Path::Verb : uint8_t
strong

Verb types describing how points are connected.

Enumerator
MoveTo 

Start a new subpath. Consumes 1 point.

LineTo 

Straight line to a point. Consumes 1 point.

QuadTo 

Quadratic Bézier curve. Consumes 2 points (control, end).

CurveTo 

Cubic Bézier curve. Consumes 3 points (c1, c2, end).

ClosePath 

Close the current subpath. Consumes 0 points.

Member Function Documentation

◆ cubicToQuadratic()

Path donner::Path::cubicToQuadratic ( double tolerance = 0.1) const

Convert all cubic Bézier curves to quadratic approximations within tolerance.

This is critical for the Slug GPU rendering pipeline, where quadratic root-finding in the fragment shader is significantly cheaper than cubic.

Parameters
toleranceMaximum allowed distance between the cubic and its quadratic approximation. Default 0.1 is suitable for text-size content.
Returns
A new Path containing only MoveTo, LineTo, QuadTo, and ClosePath verbs.

◆ flatten()

Path donner::Path::flatten ( double tolerance = 0.25) const

Flatten all curves to line segments within tolerance.

Parameters
toleranceMaximum distance between the curve and its line approximation.
Returns
A new Path containing only MoveTo, LineTo, and ClosePath verbs.

◆ forEach()

template<typename F>
void donner::Path::forEach ( F && fn) const
inline

Iterate over path segments, calling fn for each command.

The callback receives the verb and a span of the points consumed by that verb:

  • MoveTo: 1 point (destination)
  • LineTo: 1 point (destination)
  • QuadTo: 2 points (control, end)
  • CurveTo: 3 points (c1, c2, end)
  • ClosePath: 0 points
Parameters
fnCallback invoked for each command.

◆ isInside()

bool donner::Path::isInside ( const Vector2d & point,
FillRule fillRule = FillRule::NonZero ) const

Returns true if the given point is inside this path's fill region.

Uses a winding-number ray-casting algorithm. Points lying exactly on the path boundary are also considered inside.

Parameters
pointPoint to test.
fillRuleFill rule to use (NonZero or EvenOdd).

◆ isOnPath()

bool donner::Path::isOnPath ( const Vector2d & point,
double strokeWidth ) const

Returns true if the given point is within strokeWidth / 2 of any path segment.

Parameters
pointPoint to test.
strokeWidthWidth of the stroke.

◆ normalAt()

Vector2d donner::Path::normalAt ( size_t index,
double t ) const

Return the normal vector (perpendicular to the tangent) at segment index, parameter t.

Computed as the 90-degree counter-clockwise rotation of the normalized tangent.

Parameters
indexCommand index.
tParameter in [0, 1].

◆ pathLength()

double donner::Path::pathLength ( ) const

Compute the total arc length of the path.

Line segments are measured directly. Quadratic Bezier curves are elevated to cubics. Cubic Bezier arc lengths are approximated via recursive subdivision.

◆ pointAt()

Vector2d donner::Path::pointAt ( size_t index,
double t ) const

Evaluate the position on segment index at parameter t in [0, 1].

  • MoveTo: returns the point.
  • LineTo / ClosePath: linear interpolation.
  • QuadTo: De Casteljau quadratic evaluation.
  • CurveTo: De Casteljau cubic evaluation.
Parameters
indexCommand index.
tParameter in [0, 1].

◆ pointAtArcLength()

Path::PointOnPath donner::Path::pointAtArcLength ( double distance) const

Sample the path at the given arc length distance from the start.

Returns the position, tangent vector, and tangent angle at that distance. If distance exceeds the total path length, returns the endpoint with valid = false.

◆ strokeMiterBounds()

Box2d donner::Path::strokeMiterBounds ( double strokeWidth,
double miterLimit ) const

Compute the bounding box of the stroked path, accounting for miter joins.

At each join between segments, the miter extension is computed and included in the bounding box when it does not exceed miterLimit.

Parameters
strokeWidthWidth of the stroke.
miterLimitMaximum miter length (as per SVG stroke-miterlimit).
Returns
Bounding box including stroke and miter extensions.

◆ strokeToFill()

Path donner::Path::strokeToFill ( const StrokeStyle & style,
double flattenTolerance = 0.25 ) const

Convert this path's stroke to a filled outline.

Takes stroke parameters and returns a new closed Path whose fill region represents the area that would be covered by stroking this path with the given style.

The implementation flattens curves to line segments first, then offsets each segment by width/2 perpendicular to the segment direction, applying the specified line join at corners and line cap at open subpath endpoints.

Parameters
styleStroke parameters (width, cap, join, miter limit).
flattenToleranceTolerance for curve flattening.
Returns
A new Path representing the filled outline of the stroke.

◆ tangentAt()

Vector2d donner::Path::tangentAt ( size_t index,
double t ) const

Return the un-normalized tangent vector at segment index, parameter t.

The tangent is the first derivative of the curve at t. For degenerate cubic curves where the derivative is zero, the parameter is slightly adjusted and retried.

  • MoveTo: forwards to the next segment's tangent at t=0.
  • LineTo / ClosePath: constant direction (endpoint - startPoint).
  • QuadTo: derivative of the quadratic Bézier.
  • CurveTo: derivative of the cubic Bézier.
Parameters
indexCommand index.
tParameter in [0, 1].

◆ toMonotonic()

Path donner::Path::toMonotonic ( ) const

Split all curves at Y-extrema so each segment is monotonic in Y.

Required for Slug band decomposition — a monotonic curve intersects any horizontal band boundary at most once.

Returns
A new Path where every QuadTo and CurveTo segment is Y-monotonic.

◆ vertices()

std::vector< Path::Vertex > donner::Path::vertices ( ) const

Returns the vertices of the path as a flat list for marker placement.

Each vertex contains a point on the path and an orientation vector indicating the direction at that point. For vertices at joints between segments, the orientation is interpolated between the outgoing tangent of the previous segment and the incoming tangent of the next.


The documentation for this class was generated from the following files:
  • donner/base/Path.h
  • donner/base/Path.cc