Pen Class

Immutable description of a stroke: its paint, its width and the shape of its corners and ends.

public sealed class Pen

Remarks

A stroke is centered on its path: it covers the points within half Pen.Width of the path, completed by the joins at the vertices and by the caps at the ends of open contours. The vertices that the library creates when it approximates a curve are always joined with LineJoin.Round, so that a wide curved stroke stays smooth; Pen.LineJoin applies to the vertices of the path itself. Pen.Alignment moves the stroke to one side of the path, Pen.StartMarker and Pen.EndMarker draw a shape at the ends of open contours, and Pen.ScalesWithTransform says whether a transformation of the canvas enlarges the pen with the path.

Constructors

NameDescription
Pen(Brush, double)Initializes a new instance of the Pen class.

Pen(Brush, double)

Pen.cs

Initializes a new instance of the Pen class.

public Pen(Brush brush, double width)

Parameters

brush Brush
The paint of the stroke. A color converts implicitly.
width double
The width of the stroke, in pixels, or 0 for a hairline: a stroke one pixel of the canvas wide, whatever the transformation.

Exceptions

ArgumentNullException
brush is null.
ArgumentException
width is not a finite number.
ArgumentOutOfRangeException
width is negative, or exceeds 16777216.

Properties

NameDescription
AlignmentGets where the stroke is, relative to the path. Defaults to PenAlignment.Center.
BrushGets the paint of the stroke.
DashOffsetGets the distance into Pen.DashPattern at which each contour starts. Defaults to 0; a negative distance starts before the pattern.
DashPatternGets the lengths, in pixels, of the dashes and of the gaps of the stroke, alternately and starting with a dash. Empty (the default) for a continuous stroke.
EndMarkerGets the shape drawn at the end of each open contour, or null (the default) for none: the head of an arrow with LineMarker.Arrow.
LineCapGets the shape of the ends of open contours. Defaults to LineCap.Butt.
LineJoinGets the shape of the corners. Defaults to LineJoin.Miter.
MiterLimitGets the limit of LineJoin.Miter joins: the largest allowed ratio between the length of the miter (from the inner corner to the tip) and the width of the stroke. A sharper corner is joined with a LineJoin.Bevel. Defaults to 4 (corners sharper than about 29 degrees are beveled); 1 bevels every corner.
ScalesWithTransformGets a value indicating whether the transformation of the canvas applies to the pen as it applies to the path. Defaults to true.
StartMarkerGets the shape drawn at the start of each open contour, or null (the default) for none.
WidthGets the width of the stroke, in pixels, or 0 for a hairline.

Alignment

Pen.cs

Gets where the stroke is, relative to the path. Defaults to PenAlignment.Center.

public PenAlignment Alignment { get; init; }

Property value

PenAlignment

Exceptions

ArgumentOutOfRangeException
The value is not a defined PenAlignment.

Remarks

A stroke that is not centered is the stroke of a pen twice as wide, of which only one side is kept: what is inside what the path fills (with FillRule.NonZero, an open contour being closed by a straight segment), or what is outside. An inside stroke of the width Pen.Width is therefore exactly as wide along the straight sides of a shape; in a corner sharper than what Pen.MiterLimit allows, an outside stroke is beveled as any stroke is.

The side is kept by a clip, antialiased like any clip (see DrawingCanvas.Clip): a draw call with such a pen keeps one value per pixel of the bounds of its path (of the clip that is active, for an outside stroke), rented when it starts.

Brush

Pen.cs

Gets the paint of the stroke.

public Brush Brush { get; }

Property value

Brush

DashOffset

Pen.cs

Gets the distance into Pen.DashPattern at which each contour starts. Defaults to 0; a negative distance starts before the pattern.

public double DashOffset { get; init; }

Property value

double

Exceptions

ArgumentException
The value is not a finite number.

DashPattern

Pen.cs

Gets the lengths, in pixels, of the dashes and of the gaps of the stroke, alternately and starting with a dash. Empty (the default) for a continuous stroke.

public ReadOnlySpan<double> DashPattern { get; init; }

Property value

ReadOnlySpan<double>

Exceptions

ArgumentException
A length is not a finite number.
ArgumentOutOfRangeException
A length is negative or exceeds 16777216, or the dashes and the gaps of a pattern that is not empty add up to less than 1/1024.

Remarks

The pattern is repeated along each contour of the path, which starts Pen.DashOffset into it; lengths are measured along the path as it is drawn. A pattern of an odd number of lengths is used twice, so that [3] is dashes of 3 and gaps of 3. Each dash is stroked as an open contour: it gets Pen.LineCap at both ends and Pen.LineJoin at the vertices of the path it goes through. A dash of length zero is drawn by its caps alone: a dot with LineCap.Round, a square with LineCap.Square.

When a closed contour ends in the middle of a dash, that dash continues with the first dash of the contour, as one dash. The time to draw a dashed stroke grows with the number of dashes on the canvas.

EndMarker

Pen.cs

Gets the shape drawn at the end of each open contour, or null (the default) for none: the head of an arrow with LineMarker.Arrow.

public LineMarker? EndMarker { get; init; }

Property value

LineMarker?

Remarks

LineCap

Pen.cs

Gets the shape of the ends of open contours. Defaults to LineCap.Butt.

public LineCap LineCap { get; init; }

Property value

LineCap

Exceptions

ArgumentOutOfRangeException
The value is not a defined LineCap.

LineJoin

Pen.cs

Gets the shape of the corners. Defaults to LineJoin.Miter.

public LineJoin LineJoin { get; init; }

Property value

LineJoin

Exceptions

ArgumentOutOfRangeException
The value is not a defined LineJoin.

MiterLimit

Pen.cs

Gets the limit of LineJoin.Miter joins: the largest allowed ratio between the length of the miter (from the inner corner to the tip) and the width of the stroke. A sharper corner is joined with a LineJoin.Bevel. Defaults to 4 (corners sharper than about 29 degrees are beveled); 1 bevels every corner.

public double MiterLimit { get; init; }

Property value

double

Exceptions

ArgumentOutOfRangeException
The value is less than 1, greater than 1048576, or not a number.

ScalesWithTransform

Pen.cs

Gets a value indicating whether the transformation of the canvas applies to the pen as it applies to the path. Defaults to true.

public bool ScalesWithTransform { get; init; }

Property value

bool

Remarks

With true, a stroke drawn inside DrawingCanvas.Transform is the stroke of the path as it is given, transformed: a scaling makes the stroke wider, and a scaling that is not the same along both axes makes it wider in one direction than in the other.

With false, the path is transformed first and the pen strokes the result: Pen.Width, the lengths of Pen.DashPattern and Pen.DashOffset are pixels of the canvas whatever the transformation, the joins and the caps keep their shape, and the markers keep their size and are turned to the direction the path has on the canvas. This is the pen of a chart, of a map or of an icon that is drawn in coordinates of its own: its lines are as wide at every scale.

Without transformation of the canvas the value changes nothing, and VectorPath.Widen, which has no canvas, does not use it.

StartMarker

Pen.cs

Gets the shape drawn at the start of each open contour, or null (the default) for none.

public LineMarker? StartMarker { get; init; }

Property value

LineMarker?

Remarks

The shape is scaled by Pen.Width, turned to the direction of the contour, and painted with Pen.Brush, as one shape with the stroke: see LineMarker. A closed contour has no marker, and neither has a contour without length. With Pen.DashPattern, the markers are at the ends of the contour, not of each dash.

Width

Pen.cs

Gets the width of the stroke, in pixels, or 0 for a hairline.

public double Width { get; }

Property value

double

Remarks

A hairline, as the hairlines of Skia, is the stroke of a pen one pixel wide that the transformation of the canvas does not apply to (Pen.ScalesWithTransform off, whatever it says): the path is placed on the canvas, then stroked one pixel wide, its dashes and its markers measured in pixels of the canvas.