Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ProwlEngine/Prowl.Quill/llms.txt

Use this file to discover all available pages before exploring further.

Every stroked path in Prowl.Quill reads from a mutable state object that you configure before calling Stroke() or FillAndStroke(). State is inherited until you explicitly change it, so you only need to set what is different from the previous shape. Use SaveState() / RestoreState() to scope style changes to a block of draw calls without having to manually restore each field.

Color and Width

SetStrokeColor

Sets the color applied to all stroked paths until changed.
void SetStrokeColor(Color32 color)
canvas.SetStrokeColor(Color32.FromArgb(255, 255, 255, 255)); // Opaque white
canvas.SetStrokeColor(Color32.FromArgb(128, 255, 80, 80));   // Semi-transparent red

SetStrokeWidth

Sets the stroke width in logical units. The default is 2. Values below 1 produce hair-thin lines; values above 20 produce thick bands.
void SetStrokeWidth(float width = 2f)

SetStrokeScale

Multiplies the effective stroke width and dash lengths by a scale factor. This is useful when the canvas transform includes a zoom level — setting the stroke scale to the inverse zoom keeps lines visually constant-width.
void SetStrokeScale(float scale)
float zoom = 2.0f;
canvas.TransformBy(Transform2D.CreateScale(zoom, zoom));
canvas.SetStrokeScale(zoom); // Compensate so strokes stay 1 logical unit wide

Joint Styles

SetStrokeJoint

Controls how corners are drawn where two line segments meet. The JointStyle enum has three values:
void SetStrokeJoint(JointStyle joint)
The two segment ends are capped with a flat edge and connected by a filled triangle. This is the default — it is the cheapest to tessellate and avoids the spike problem of miter joins at sharp angles.
canvas.SetStrokeJoint(JointStyle.Bevel);
canvas.SetStrokeColor(Color32.FromArgb(255, 255, 100, 100));
canvas.SetStrokeWidth(8f);

canvas.BeginPath();
canvas.MoveTo(20, 80);
canvas.LineTo(80, 20);
canvas.LineTo(140, 80);
canvas.Stroke();

Cap Styles

Caps are applied to the open ends of a path (i.e., paths where the first and last points do not meet). You can set both caps at once with SetStrokeCap, or set start and end independently.
void SetStrokeCap(EndCapStyle cap)         // Sets both start and end caps
void SetStrokeStartCap(EndCapStyle cap)    // Start of the path only
void SetStrokeEndCap(EndCapStyle cap)      // End of the path only
The stroke ends exactly at the first and last path points with no extension. This is the default and produces the tightest bounding box.
canvas.SetStrokeCap(EndCapStyle.Butt);
canvas.SetStrokeColor(Color32.FromArgb(255, 255, 100, 100));
canvas.SetStrokeWidth(16f);

canvas.BeginPath();
canvas.MoveTo(30, 60);
canvas.LineTo(170, 60);
canvas.Stroke();

Mixed caps example

// Arrow-like: flat start, round tip
canvas.SetStrokeStartCap(EndCapStyle.Butt);
canvas.SetStrokeEndCap(EndCapStyle.Round);
canvas.SetStrokeWidth(12f);
canvas.SetStrokeColor(Color32.FromArgb(255, 255, 255, 150));

canvas.BeginPath();
canvas.MoveTo(20, 80);
canvas.LineTo(200, 80);
canvas.Stroke();

Miter Limit

SetMiterLimit

When the joint style is Miter, this value caps how far the miter spike can extend before the joint automatically falls back to Bevel. The limit is expressed as a ratio of the miter length to the stroke width. The default is 4.
void SetMiterLimit(float limit = 4)
// Very sharp angles allowed — use with care
canvas.SetStrokeJoint(JointStyle.Miter);
canvas.SetMiterLimit(10f);

// Conservative — falls back to bevel at moderate angles
canvas.SetMiterLimit(2f);

Tessellation and Rounding

SetTessellationTolerance

Controls the maximum allowed deviation (in logical units) when flattening Bézier curves and arcs into line segments. Lower values produce smoother curves with more triangles. Default is 0.5.
void SetTessellationTolerance(float tolerance = 0.5f)

SetRoundingMinDistance

Sets the minimum distance between consecutive arc sample points. This bounds the maximum segment count for very large arcs or circles. Default is 3 logical units.
void SetRoundingMinDistance(float distance = 3)

Dash Patterns

SetStrokeDash

Activates a dash pattern on all subsequent strokes. The pattern list alternates between dash length and gap length in logical units (e.g., [10, 5] = 10-unit dash, 5-unit gap). If the list has an odd number of elements it is automatically doubled so the pattern can tile evenly. The optional offset shifts the phase along the path.
void SetStrokeDash(List<float> pattern, float offset = 0.0f)
// Simple equal dashes and gaps
canvas.SetStrokeDash(new List<float> { 10, 5 });

// Long-short-long pattern
canvas.SetStrokeDash(new List<float> { 20, 5, 5, 5 });

// Animated marching ants (increment offset each frame)
canvas.SetStrokeDash(new List<float> { 8, 4 }, offset: _time * 20f);

ClearStrokeDash

Reverts to a solid stroke.
void ClearStrokeDash()

Global Alpha

SetGlobalAlpha

Applies a uniform transparency multiplier to all subsequent vertices, including fills and strokes. Values range from 0 (fully transparent) to 1 (fully opaque, the default).
void SetGlobalAlpha(float alpha)
// Fade out an entire group of shapes
canvas.SetGlobalAlpha(0.4f);
canvas.RectFilled(10, 10, 100, 60, Color32.FromArgb(255, 255, 100, 100));
canvas.CircleFilled(80, 80, 30, Color32.FromArgb(255, 100, 200, 255));
canvas.SetGlobalAlpha(1.0f); // Restore full opacity
SetGlobalAlpha multiplies the vertex alpha at the point of insertion. This is different from a blend-mode layer — it does not compose the group first. For composited group transparency, use SaveState() / RestoreState() together with a semi-transparent fill.

Putting It All Together

// Heartbeat-style animated polyline with round joins and caps
canvas.SaveState();

canvas.SetStrokeColor(Color32.FromArgb(255, 80, 220, 120));
canvas.SetStrokeWidth(5f);
canvas.SetStrokeJoint(JointStyle.Round);
canvas.SetStrokeCap(EndCapStyle.Round);
canvas.SetMiterLimit(4f);

canvas.BeginPath();
canvas.MoveTo(10,  60);
canvas.LineTo(40,  60);
canvas.LineTo(60,  10);   // Spike up
canvas.LineTo(80,  110);  // Spike down
canvas.LineTo(100, 60);
canvas.LineTo(190, 60);

canvas.Stroke();

// Dashed reference line
canvas.SetStrokeColor(Color32.FromArgb(80, 255, 255, 255));
canvas.SetStrokeWidth(1f);
canvas.SetStrokeDash(new List<float> { 6, 4 });
canvas.BeginPath();
canvas.MoveTo(10, 60);
canvas.LineTo(190, 60);
canvas.Stroke();

canvas.RestoreState();

Build docs developers (and LLMs) love