One quad per segment, offset to StrokeGeometryOptions.alignment's
side; one join at every interior vertex, and at every vertex of a closed
ring; one cap at each end of an open polyline. Joins and caps are drawn on
the corner's outer side only, which is the side a gap would otherwise
appear on — the inner side of a corner is covered by the two quads already,
twice.
That double coverage is this function's one honest defect, and it is stated
rather than worked around: under an opaque paint it is invisible, and under
a translucent one the inside of every corner blends twice. The exact answer
is a boolean union of the band with itself, which is the same
planar-subdivision pass §52's self-intersection row waits on — see this
module's header. alignment: "outside" on a convex outline avoids it
entirely, because no corner's inner side is on the drawn side.
Joins
A miter join extends both outer edges to their intersection, and falls
back to bevel when the resulting spike is longer than
StrokeGeometryOptions.miterLimit times the width — the SVG rule,
and the reason the limit exists at all: at a hairpin the intersection runs
off to infinity. A bevel join is the one triangle across the gap; a
round join is a fan whose chords stay within
StrokeGeometryOptions.tolerance of the true arc, the same sagitta
bound Path.flatten uses on an arc command.
A hairpin — two segments doubling exactly back on each other — has no
bevel and no miter, only a round join; with the other two it leaves the
notch its geometry actually has, rather than a wedge nobody asked for.
What contributes nothing
A polyline of fewer than two distinct points strokes to nothing, and is
dropped rather than refused: Path.flatten returns a lone moveTo as a
single point and says explicitly that it is not the operation that gets to
decide whether that is a dot, and this is that operation deciding — a dot is
a Circle, and inventing one here would make every stray moveTo in an
imported document sprout a blob. Consecutive duplicate points are dropped
for the same reason: a zero-length segment has no direction to offset along.
Non-finite coordinates are refused (§85).
Expands polylines into the triangles of their stroke (§52 "stroke expansion", §58
StrokeStyle).What it draws
One quad per segment, offset to StrokeGeometryOptions.alignment's side; one join at every interior vertex, and at every vertex of a closed ring; one cap at each end of an open polyline. Joins and caps are drawn on the corner's outer side only, which is the side a gap would otherwise appear on — the inner side of a corner is covered by the two quads already, twice.
That double coverage is this function's one honest defect, and it is stated rather than worked around: under an opaque paint it is invisible, and under a translucent one the inside of every corner blends twice. The exact answer is a boolean union of the band with itself, which is the same planar-subdivision pass §52's self-intersection row waits on — see this module's header.
alignment: "outside"on a convex outline avoids it entirely, because no corner's inner side is on the drawn side.Joins
A
miterjoin extends both outer edges to their intersection, and falls back tobevelwhen the resulting spike is longer than StrokeGeometryOptions.miterLimit times the width — the SVG rule, and the reason the limit exists at all: at a hairpin the intersection runs off to infinity. Abeveljoin is the one triangle across the gap; aroundjoin is a fan whose chords stay within StrokeGeometryOptions.tolerance of the true arc, the same sagitta boundPath.flattenuses on an arc command.A hairpin — two segments doubling exactly back on each other — has no bevel and no miter, only a round join; with the other two it leaves the notch its geometry actually has, rather than a wedge nobody asked for.
What contributes nothing
A polyline of fewer than two distinct points strokes to nothing, and is dropped rather than refused:
Path.flattenreturns a lonemoveToas a single point and says explicitly that it is not the operation that gets to decide whether that is a dot, and this is that operation deciding — a dot is aCircle, and inventing one here would make every straymoveToin an imported document sprout a blob. Consecutive duplicate points are dropped for the same reason: a zero-length segment has no direction to offset along. Non-finite coordinates are refused (§85).