Skip to main content

Surface class

Namespace: Arlecchino.Rendering · Assembly: Arlecchino.Core

The drawing target: a grid of cells, each holding one symbol and one style, serialized into a single write per frame. Needs nothing but an IArlecchinoTerminal, so it works outside a hosted application too.

public class Surface

Constructors

MemberSummary
Surface(IArlecchinoTerminal)Creates a surface that draws to a terminal.

Properties

MemberSummary
ContentWhere a view draws: the frame minus its padding, or the room a layout left it. A view asks for this and gets whatever it has been given, so a layout can be added without any view knowing.
FrameThe whole frame as a region.
FrameHeightHeight of the current frame in rows.
FrameWidthWidth of the current frame in cells.
HorizontalPaddingCells kept free on the left and right by the flow calls.
VerticalPaddingRows kept free above and below by the flow calls.

Methods

MemberSummary
AppendLine(string, IArlecchinoColor, Align, Margin)Writes one line at the flow cursor and moves it down. Stops silently once the frame is full, so a view never has to bound its own output.
Build()Sends the composed frame to the terminal, writing only what changed since the last one — an idle frame writes nothing at all. The first frame, a resize and a fixed size send everything.
Clip(SurfaceRegion)Confines every write to a rectangle until the returned scope is disposed, dropping whatever falls outside it. Scopes nest, and a clip inside a clip is their intersection.
FillLine()Draws a rule across the content width at the flow cursor.
FillLineAt(int, IArlecchinoColor)Draws a rule across the content width on a given row.
ForgetPreviousFrame()Drops the memory of the last frame, so the next Surface.Build sends the whole screen instead of the difference. Use it after something else wrote to the terminal.
ListWindow()How many rows a scrolling list may use: what is left of the frame minus room for the chrome, never fewer than four.
Passthrough(int, int, string, string)Hands the terminal something the cell grid cannot express, such as an image, to be written verbatim at a cell after every cell of the frame. It is re-sent only once it changes.
SetFixedSize(int, int)Pins the frame size instead of asking the terminal, which is what makes headless rendering possible. A fixed-size surface always sends whole frames.
SkipLine()Leaves a blank line at the flow cursor.
StartFrame()Begins a frame: reads the terminal size, reallocates if it changed, clears every cell and skips the vertical padding. Nothing reaches the terminal until Surface.Build.
WriteAt(int, int, string, IArlecchinoColor)Writes at an exact cell, clipped to the frame. A wide symbol takes two cells; writing over either half clears the other, and one that would be split by the right edge is dropped.
WriteBlock(IReadOnlyList<string>, IArlecchinoColor, Align, Margin)Places a block of prepared lines as a unit, ignoring the flow cursor. Vertical alignment flags work here, which is how the hints box is anchored to a corner.
WriteLineAt(int, string, IArlecchinoColor)Restyles a whole row and writes text at the horizontal padding, ignoring the flow cursor.
WriteTableRow(string[], int[], IArlecchinoColor, string)Writes a row of padded columns at the flow cursor.

Constructors in detail

Surface(IArlecchinoTerminal)

public Surface(IArlecchinoTerminal terminal);

Creates a surface that draws to a terminal.

Parameters

NameTypeDescription
terminalIArlecchinoTerminalWhere composed frames are written.

Properties in detail

Content

public SurfaceRegion Content { get; }

Where a view draws: the frame minus its padding, or the room a layout left it. A view asks for this and gets whatever it has been given, so a layout can be added without any view knowing.

Type SurfaceRegion

Frame

public SurfaceRegion Frame { get; }

The whole frame as a region.

Type SurfaceRegion

FrameHeight

public int FrameHeight { get; }

Height of the current frame in rows.

Type int

FrameWidth

public int FrameWidth { get; }

Width of the current frame in cells.

Type int

HorizontalPadding

public int HorizontalPadding { get; set; }

Cells kept free on the left and right by the flow calls.

Type int

VerticalPadding

public int VerticalPadding { get; set; }

Rows kept free above and below by the flow calls.

Type int

Methods in detail

AppendLine(string, IArlecchinoColor, Align, Margin)

public void AppendLine(string line, IArlecchinoColor style, Align align, Margin margin);

Writes one line at the flow cursor and moves it down. Stops silently once the frame is full, so a view never has to bound its own output.

Parameters

NameTypeDescription
linestringText to write.
styleIArlecchinoColorStyle for the line; the default role when omitted.
alignAlignHorizontal alignment inside the content width.
marginMarginExtra space around the line.

Build()

public void Build();

Sends the composed frame to the terminal, writing only what changed since the last one — an idle frame writes nothing at all. The first frame, a resize and a fixed size send everything.

Clip(SurfaceRegion)

public IDisposable Clip(SurfaceRegion region);

Confines every write to a rectangle until the returned scope is disposed, dropping whatever falls outside it. Scopes nest, and a clip inside a clip is their intersection.

Parameters

NameTypeDescription
regionSurfaceRegionThe only part of the frame writes may reach.

Returns IDisposable — Dispose it to go back to the clip that was in force before.

FillLine()

public void FillLine();

Draws a rule across the content width at the flow cursor.

FillLineAt(int, IArlecchinoColor)

public void FillLineAt(int row, IArlecchinoColor? style = null);

Draws a rule across the content width on a given row.

Parameters

NameTypeDescription
rowintRow in frame coordinates.
styleIArlecchinoColorStyle for the rule; the default role when omitted.

ForgetPreviousFrame()

public void ForgetPreviousFrame();

Drops the memory of the last frame, so the next Surface.Build sends the whole screen instead of the difference. Use it after something else wrote to the terminal.

ListWindow()

public int ListWindow();

How many rows a scrolling list may use: what is left of the frame minus room for the chrome, never fewer than four.

Returns int — Rows available for list content.

Passthrough(int, int, string, string)

public void Passthrough(int row, int column, string payload, string undraw = "");

Hands the terminal something the cell grid cannot express, such as an image, to be written verbatim at a cell after every cell of the frame. It is re-sent only once it changes.

Parameters

NameTypeDescription
rowintRow of the cell it starts at, counted from the top of the frame.
columnintColumn of that cell.
payloadstringThe bytes to write, escapes and all.
undrawstringWhat removes it again, written where the payload was. Empty when nothing can: a sixel on a terminal that will not say what color is behind its text has to be left where it is.

SetFixedSize(int, int)

public void SetFixedSize(int width, int height);

Pins the frame size instead of asking the terminal, which is what makes headless rendering possible. A fixed-size surface always sends whole frames.

Parameters

NameTypeDescription
widthintWidth in cells.
heightintHeight in rows.

SkipLine()

public void SkipLine();

Leaves a blank line at the flow cursor.

StartFrame()

public void StartFrame();

Begins a frame: reads the terminal size, reallocates if it changed, clears every cell and skips the vertical padding. Nothing reaches the terminal until Surface.Build.

WriteAt(int, int, string, IArlecchinoColor)

public void WriteAt(int row, int column, string text, IArlecchinoColor style);

Writes at an exact cell, clipped to the frame. A wide symbol takes two cells; writing over either half clears the other, and one that would be split by the right edge is dropped.

Parameters

NameTypeDescription
rowintRow in frame coordinates.
columnintColumn in frame coordinates.
textstringText to write.
styleIArlecchinoColorStyle for the text.

WriteBlock(IReadOnlyList<string>, IArlecchinoColor, Align, Margin)

public void WriteBlock(
IReadOnlyList<string> lines,
IArlecchinoColor style,
Align align,
Margin margin);

Places a block of prepared lines as a unit, ignoring the flow cursor. Vertical alignment flags work here, which is how the hints box is anchored to a corner.

Parameters

NameTypeDescription
linesIReadOnlyList<T><string>Lines of the block.
styleIArlecchinoColorStyle for the block.
alignAlignHorizontal and vertical alignment against the frame.
marginMarginSpace kept free from the edges it is aligned to.

WriteLineAt(int, string, IArlecchinoColor)

public void WriteLineAt(int row, string line, IArlecchinoColor? style = null);

Restyles a whole row and writes text at the horizontal padding, ignoring the flow cursor.

Parameters

NameTypeDescription
rowintRow in frame coordinates.
linestringText to write.
styleIArlecchinoColorStyle for the row; the default role when omitted.

WriteTableRow(string[], int[], IArlecchinoColor, string)

public void WriteTableRow(
string[] strings,
int[] widths,
IArlecchinoColor style,
string prefix = "");

Writes a row of padded columns at the flow cursor.

Parameters

NameTypeDescription
stringsstring[]Cell texts, in column order.
widthsint[]Column widths: a positive width right-aligns the cell, a negative one left-aligns it.
styleIArlecchinoColorStyle for the row.
prefixstringText placed before the first column, such as a marker.