Table of Contents

Class LineCanvas

Namespace
Terminal.Gui.Drawing
Assembly
Terminal.Gui.dll

A canvas for composing box-drawing and line-art characters with automatic intersection resolution. See Drawing Deep Dive for an in-depth look at the design and usage of this class.

public class LineCanvas : IDisposable
Inheritance
LineCanvas
Implements
Inherited Members

Remarks

LineCanvas is the core rendering primitive for borders, frames, and any box-drawing art in Terminal.Gui. Lines are added via AddLine(Point, int, Orientation, LineStyle, Attribute?) and the canvas automatically resolves intersections — where two lines cross or meet, the correct Unicode junction glyph (T, cross, corner, etc.) is produced. This makes it trivial to compose complex bordered layouts without manually computing junction characters.

Merging and SuperViewRendersLineCanvas. When SuperViewRendersLineCanvas is true on a SubView, the SubView's LineCanvas is merged into the SuperView's canvas via Merge(LineCanvas). All lines then participate in a single intersection-resolution pass, producing seamless junctions across view boundaries. This is how adjacent tab headers, nested frames, and other multi-view border compositions achieve connected line art.

Exclusion regions (Exclude(Region)). Prevents resolved cells from appearing in GetCellMap() output. Lines still exist in the canvas and still participate in intersection resolution (auto-join), but excluded positions are filtered out of the final output. Use this when something else has already been drawn at a position — for example, a title label on a border, or a SubView that renders its own LineCanvas independently.

Reserved cells (Reserve(Rectangle)). Marks positions as intentionally empty — no line exists here and none should be rendered by other canvases either. Unlike Exclude(Region), reserved cells have no effect on this canvas's resolution or output. They are metadata consumed during multi-canvas compositing (see RenderLineCanvas(DrawContext?)): when multiple independently-resolved canvases are layered, reserved cells claim their positions so that cells from canvases composited later do not show through. Use this for intentional gaps in borders, such as the opening where a focused tab header connects to the content area.

Clipped merge. The Merge(LineCanvas, Region?) overload supports merging with an exclusion region that clips incoming lines at the line level — before intersection resolution. Excluded cells are not added as lines and therefore do not participate in auto-join. Note that this can fragment lines and produce incorrect junction glyphs; prefer per-canvas resolution with Reserve(Rectangle) and compositing for overlapped views.

Output. Call GetCellMap() (or GetMap()) to resolve all intersections and produce a dictionary mapping screen coordinates to the glyphs (with attributes) to render. GetCellMapWithRegion() additionally returns a Region covering the drawn cells, which is used for transparency tracking.

Does not support diagonal lines. All lines are axis-aligned (horizontal or vertical).

Constructors

LineCanvas()

Creates a new instance.

LineCanvas(IEnumerable<StraightLine>)

Creates a new instance with the given lines.

Properties

Bounds

Gets the rectangle that describes the bounds of the canvas. Location is the coordinates of the line that is the furthest left/top and Size is defined by the line that extends the furthest right/bottom.

Fill

Optional FillPair which when present overrides the Attribute (colors) of lines in the canvas. This can be used e.g. to apply a global GradientFill across all lines.

Lines

Gets the lines in the canvas.

Methods

AddLine(Point, int, Orientation, LineStyle, Attribute?)

Adds a new length long line to the canvas starting at start.

Use positive length for the line to extend Right and negative for Left when Orientation is Horizontal.

Use positive length for the line to extend Down and negative for Up when Orientation is Vertical.

AddLine(StraightLine)

Adds a new line to the canvas

Clear()

Clears all lines from the LineCanvas.

ClearCache()

Clears any cached states from the canvas. Call this method if you make changes to lines that have already been added.

ClearExclusions()

Clears the exclusion region. After calling this method, GetCellMap() and GetMap() will return all points in the canvas.

Dispose()
Exclude(Region)

Causes the provided region to be excluded from GetCellMap() and GetMap(). Lines at excluded positions still exist in the canvas and still participate in intersection resolution (auto-join), but the resolved cells are filtered out of the output.

GetCellMap()

Evaluates the lines that have been added to the canvas and returns a map containing the glyphs and their locations. The glyphs are the characters that should be rendered so that all lines connect up with the appropriate intersection symbols.

GetCellMapWithRegion()

Evaluates the lines and returns both the cell map and a Region encompassing the drawn cells. This is more efficient than calling GetCellMap() and GetRegion(Dictionary<Point, Cell?>) separately as it builds both in a single pass through the canvas bounds.

GetLineDirections(string?)

Maps a box-drawing grapheme to its line directions. Used during overlapped LC compositing to determine whether a lower-Z cell adds directions that don't point toward reserved gaps.

GetMap()

Evaluates the lines that have been added to the canvas and returns a map containing the glyphs and their locations. The glyphs are the characters that should be rendered so that all lines connect up with the appropriate intersection symbols.

GetMap(Rectangle)

Evaluates the lines that have been added to the canvas and returns a map containing the glyphs and their locations. The glyphs are the characters that should be rendered so that all lines connect up with the appropriate intersection symbols.

GetRegion(Dictionary<Point, Cell?>)

Efficiently builds a Region from line cells by grouping contiguous horizontal spans. This avoids the performance overhead of adding each cell individually while accurately representing the non-rectangular shape of the lines.

GetReservedCells()

Gets the set of reserved cells, or null if none have been reserved.

Merge(LineCanvas)

Merges one line canvas into this one.

Merge(LineCanvas, Rectangle)

Merges one line canvas into this one, clipping all lines to the specified bounds.

RemoveLastLine()

Removes the last line added to the canvas

Reserve(Rectangle)

Reserves a rectangular region of cells. Reserved cells do not produce visible output and do not affect this canvas's intersection resolution or GetCellMap() output. They are metadata consumed during multi-canvas compositing (see RenderLineCanvas(DrawContext?)): reserved cells claim their positions so that cells from canvases composited later do not show through.

ToString()

Returns the contents of the line canvas rendered to a string. The string will include all columns and rows, even if Bounds has negative coordinates. For example, if the canvas contains a single line that starts at (-1,-1) with a length of 2, the rendered string will have a length of 2.