Table of Contents

Class PathBuilder

Namespace
Egami.Drawing
Assembly
Egami.Drawing.dll

Builds a Path one command at a time. Arcs, ovals and round corners become cubic curves as they are added, so a path holds only lines, quadratics and cubics. A line or curve with no contour open starts one at the last contour's start (or the origin), as SVG and Skia do. Building takes time in proportion to the points added; ToPath(FillRule) copies them, so the builder can go on or be reused.

public sealed class PathBuilder
Inheritance
PathBuilder
Inherited Members

Examples

// A path is built once and never changes, so it can be drawn many times and from many threads.
Path heart = new PathBuilder()
    .MoveTo(150, 60)
    .CubicTo(150, 30, 100, 20, 90, 60)
    .CubicTo(80, 100, 130, 130, 150, 160)
    .CubicTo(170, 130, 220, 100, 210, 60)
    .CubicTo(200, 20, 150, 30, 150, 60)
    .Close()
    .ToPath();
canvas.FillPath(heart, Rgba8.Red);

// SVG's arc command, and the even-odd rule: an inner contour becomes a hole.
Path frame = new PathBuilder()
    .AddRect(new RectF(10, 10, 60, 60))
    .AddCircle(new Vector2(40, 40), 20)
    .MoveTo(10, 120)
    .ArcTo(radii: new Vector2(30, 20), rotationDegrees: 0, largeArc: false, clockwise: true, end: new Vector2(70, 120))
    .Close()
    .ToPath(FillRule.EvenOdd);
canvas.FillPath(frame, Rgba8.Black);

bool hit = heart.Contains(new Vector2(150, 100));   // hit testing on the curves themselves
RectF box = heart.TightBounds;                       // curves measured at their extremes

Constructors

PathBuilder()

Initializes a new instance of the PathBuilder class, empty.

public PathBuilder()

Properties

CurrentPoint

Gets the point the next command starts from: the last point added, or the contour's start after Close().

public Vector2 CurrentPoint { get; }

Property Value

Vector2

IsEmpty

Gets a value indicating whether nothing has been added.

public bool IsEmpty { get; }

Property Value

bool

Methods

AddArc(RectF, float, float)

Adds the arc of an ellipse as a new open contour: from startDegrees through sweepDegrees, where 0 is the right end of the horizontal axis and positive angles turn clockwise on screen. A sweep beyond ±360 degrees draws the whole ellipse once.

public PathBuilder AddArc(RectF oval, float startDegrees, float sweepDegrees)

Parameters

oval RectF

The rectangle the ellipse fills.

startDegrees float

Where the arc starts.

sweepDegrees float

How far it turns.

Returns

PathBuilder

This builder.

AddCircle(Vector2, float, PathDirection)

Adds a circle as a closed contour.

public PathBuilder AddCircle(Vector2 center, float radius, PathDirection direction = PathDirection.Clockwise)

Parameters

center Vector2

The center.

radius float

The radius.

direction PathDirection

Which way the outline runs.

Returns

PathBuilder

This builder.

AddOval(RectF, PathDirection)

Adds an ellipse filling a rectangle as a closed contour of four cubics, starting at the right end of its horizontal axis.

public PathBuilder AddOval(RectF oval, PathDirection direction = PathDirection.Clockwise)

Parameters

oval RectF

The rectangle the ellipse fills.

direction PathDirection

Which way the outline runs.

Returns

PathBuilder

This builder.

AddPath(Path)

Adds every contour of another path.

public PathBuilder AddPath(Path path)

Parameters

path Path

The path to add; its fill rule is not copied.

Returns

PathBuilder

This builder.

AddPath(Path, Matrix3x2)

Adds every contour of another path, transformed.

public PathBuilder AddPath(Path path, Matrix3x2 transform)

Parameters

path Path

The path to add; its fill rule is not copied.

transform Matrix3x2

The transform for its points.

Returns

PathBuilder

This builder.

AddPolygon(ReadOnlySpan<Vector2>, bool)

Adds a polygon through the points as a new contour.

public PathBuilder AddPolygon(ReadOnlySpan<Vector2> points, bool close = true)

Parameters

points ReadOnlySpan<Vector2>

The corners, in order.

close bool

Whether to close the contour back to the first point.

Returns

PathBuilder

This builder.

AddRect(RectF, PathDirection)

Adds a rectangle as a closed contour of its own, starting at the top-left corner.

public PathBuilder AddRect(RectF rect, PathDirection direction = PathDirection.Clockwise)

Parameters

rect RectF

The rectangle.

direction PathDirection

Which way the outline runs.

Returns

PathBuilder

This builder.

AddRoundRect(RoundRect, PathDirection)

Adds a round rectangle as a closed contour: a line along each side and a quarter-ellipse cubic at each rounded corner, starting where the top-left corner's curve ends. Square corners add no curve.

public PathBuilder AddRoundRect(RoundRect roundRect, PathDirection direction = PathDirection.Clockwise)

Parameters

roundRect RoundRect

The round rectangle.

direction PathDirection

Which way the outline runs.

Returns

PathBuilder

This builder.

ArcTo(Vector2, Vector2, float)

Adds a circular arc of radius that turns from the line towards corner onto the line from corner to end, touching both, with a straight line to where the arc starts: the rounded corner of HTML canvas's and Skia's arcTo. When the lines are parallel or the radius is 0, a line to the corner is added.

public PathBuilder ArcTo(Vector2 corner, Vector2 end, float radius)

Parameters

corner Vector2

The corner the arc rounds.

end Vector2

A point on the second line; the arc ends on that line, not at this point.

radius float

The arc's radius.

Returns

PathBuilder

This builder.

Exceptions

ArgumentOutOfRangeException

radius is negative.

ArcTo(Vector2, float, bool, bool, Vector2)

Adds an elliptical arc to end in SVG's endpoint form (the A command), following SVG 1.1's implementation notes: radii too small to reach the end point are scaled up until they do, a zero radius draws a straight line, and an end point equal to the current point adds nothing.

public PathBuilder ArcTo(Vector2 radii, float rotationDegrees, bool largeArc, bool clockwise, Vector2 end)

Parameters

radii Vector2

The ellipse's x and y radius; signs are ignored.

rotationDegrees float

The ellipse's x axis, turned clockwise from the page's x axis.

largeArc bool

Whether to take the arc of more than 180 degrees.

clockwise bool

Whether the arc runs clockwise on screen (SVG's sweep flag of 1).

end Vector2

Where the arc ends.

Returns

PathBuilder

This builder.

Examples

// A path is built once and never changes, so it can be drawn many times and from many threads.
Path heart = new PathBuilder()
    .MoveTo(150, 60)
    .CubicTo(150, 30, 100, 20, 90, 60)
    .CubicTo(80, 100, 130, 130, 150, 160)
    .CubicTo(170, 130, 220, 100, 210, 60)
    .CubicTo(200, 20, 150, 30, 150, 60)
    .Close()
    .ToPath();
canvas.FillPath(heart, Rgba8.Red);

// SVG's arc command, and the even-odd rule: an inner contour becomes a hole.
Path frame = new PathBuilder()
    .AddRect(new RectF(10, 10, 60, 60))
    .AddCircle(new Vector2(40, 40), 20)
    .MoveTo(10, 120)
    .ArcTo(radii: new Vector2(30, 20), rotationDegrees: 0, largeArc: false, clockwise: true, end: new Vector2(70, 120))
    .Close()
    .ToPath(FillRule.EvenOdd);
canvas.FillPath(frame, Rgba8.Black);

bool hit = heart.Contains(new Vector2(150, 100));   // hit testing on the curves themselves
RectF box = heart.TightBounds;                       // curves measured at their extremes

Close()

Closes the contour with a straight line back to its start. The next command starts from there.

public PathBuilder Close()

Returns

PathBuilder

This builder.

CubicTo(Vector2, Vector2, Vector2)

Adds a cubic Bézier curve.

public PathBuilder CubicTo(Vector2 control1, Vector2 control2, Vector2 end)

Parameters

control1 Vector2

The first control point.

control2 Vector2

The second control point.

end Vector2

Where it ends.

Returns

PathBuilder

This builder.

CubicTo(float, float, float, float, float, float)

Adds a cubic Bézier curve.

public PathBuilder CubicTo(float control1X, float control1Y, float control2X, float control2Y, float x, float y)

Parameters

control1X float

The first control point, x.

control1Y float

The first control point, y.

control2X float

The second control point, x.

control2Y float

The second control point, y.

x float

Where it ends, x.

y float

Where it ends, y.

Returns

PathBuilder

This builder.

LineTo(Vector2)

Adds a straight line.

public PathBuilder LineTo(Vector2 point)

Parameters

point Vector2

Where it ends.

Returns

PathBuilder

This builder.

LineTo(float, float)

Adds a straight line.

public PathBuilder LineTo(float x, float y)

Parameters

x float

Where it ends, x.

y float

Where it ends, y.

Returns

PathBuilder

This builder.

MoveTo(Vector2)

Starts a new contour.

public PathBuilder MoveTo(Vector2 point)

Parameters

point Vector2

Where it starts.

Returns

PathBuilder

This builder.

MoveTo(float, float)

Starts a new contour.

public PathBuilder MoveTo(float x, float y)

Parameters

x float

Where it starts, x.

y float

Where it starts, y.

Returns

PathBuilder

This builder.

QuadTo(Vector2, Vector2)

Adds a quadratic Bézier curve.

public PathBuilder QuadTo(Vector2 control, Vector2 end)

Parameters

control Vector2

The control point.

end Vector2

Where it ends.

Returns

PathBuilder

This builder.

QuadTo(float, float, float, float)

Adds a quadratic Bézier curve.

public PathBuilder QuadTo(float controlX, float controlY, float x, float y)

Parameters

controlX float

The control point, x.

controlY float

The control point, y.

x float

Where it ends, x.

y float

Where it ends, y.

Returns

PathBuilder

This builder.

RelativeArcTo(Vector2, float, bool, bool, Vector2)

Adds an SVG endpoint arc whose end is an offset from the current point (SVG's a command).

public PathBuilder RelativeArcTo(Vector2 radii, float rotationDegrees, bool largeArc, bool clockwise, Vector2 end)

Parameters

radii Vector2

The ellipse's x and y radius.

rotationDegrees float

The ellipse's x axis, turned clockwise.

largeArc bool

Whether to take the arc of more than 180 degrees.

clockwise bool

Whether the arc runs clockwise on screen.

end Vector2

The end's offset.

Returns

PathBuilder

This builder.

RelativeCubicTo(Vector2, Vector2, Vector2)

Adds a cubic curve whose points are offsets from the current point.

public PathBuilder RelativeCubicTo(Vector2 control1, Vector2 control2, Vector2 end)

Parameters

control1 Vector2

The first control point's offset.

control2 Vector2

The second control point's offset.

end Vector2

The end's offset.

Returns

PathBuilder

This builder.

RelativeLineTo(Vector2)

Adds a straight line to an offset from the current point.

public PathBuilder RelativeLineTo(Vector2 delta)

Parameters

delta Vector2

The offset of the end.

Returns

PathBuilder

This builder.

RelativeMoveTo(Vector2)

Starts a new contour at an offset from the current point.

public PathBuilder RelativeMoveTo(Vector2 delta)

Parameters

delta Vector2

The offset.

Returns

PathBuilder

This builder.

RelativeQuadTo(Vector2, Vector2)

Adds a quadratic curve whose points are offsets from the current point.

public PathBuilder RelativeQuadTo(Vector2 control, Vector2 end)

Parameters

control Vector2

The control point's offset.

end Vector2

The end's offset.

Returns

PathBuilder

This builder.

Reset()

Removes everything added, to build another path.

public PathBuilder Reset()

Returns

PathBuilder

This builder.

ToPath(FillRule)

Returns the path built so far, which never changes afterwards. The builder keeps its contents.

public Path ToPath(FillRule fillRule = FillRule.NonZero)

Parameters

fillRule FillRule

The path's fill rule.

Returns

Path

The path.

Exceptions

ArgumentException

A point is not a finite number.

ArgumentOutOfRangeException

fillRule is not defined.