2D character canvas for rendering diagrams.
Uses {col, row} coordinate maps for the grid. Supports direction-based
junction merging when box-drawing characters overlap: each cell tracks a
direction bitfield, and the correct junction character is derived from
the combined directions.
Cells can be protected (node borders) — protected cells only accept junction merges that add a new direction, not plain overwrites.
Summary
Functions
Returns the character-to-directions mapping.
Clamp canvas to a maximum width. Cells beyond max_col are dropped.
Check if a horizontal range of cells on row contains only spaces.
Returns true if every cell from col_start to col_end - 1 is empty.
Direction bitfield constant for down.
Direction bitfield constant for left.
Direction bitfield constant for right.
Direction bitfield constant for up.
Returns the direction-to-character mapping.
Draw a horizontal line of a character from col_start to col_end.
Draw a vertical line of a character from row_start to row_end.
Fill a horizontal span with a character from col_start to col_end (exclusive).
Flip the canvas horizontally (for RL direction).
Flip the canvas vertically (for BT direction).
Get the character at a position.
Get the full cell at a position, or a default empty cell.
Get the style key at a position.
Create a new canvas with the given dimensions.
Mark a cell as protected. Protected cells only accept junction merges that add a new direction, not plain overwrites from edge lines.
Check if a cell is protected.
Place a character on the canvas, optionally merging junctions.
Place text with per-segment style keys. Each segment is {text, style_key}.
Place a string of text starting at {col, row}. Each character is placed
without junction merging. Wide (CJK) characters advance by 2 columns.
Render canvas to a string, trimming trailing whitespace per line and removing both leading and trailing empty lines.
Render canvas to an ANSI-colored string using the given theme.
Expand the canvas to at least the given dimensions.
Return {char, style_key} pairs for each cell as a list of rows.
Types
@type style() :: String.t()
@type t() :: %Boxart.Canvas{ cells: %{optional(coord()) => Boxart.Canvas.Cell.t()}, height: non_neg_integer(), width: non_neg_integer() }
Functions
@spec char_to_directions() :: %{required(String.t()) => non_neg_integer()}
Returns the character-to-directions mapping.
@spec clamp_width(t(), pos_integer()) :: t()
Clamp canvas to a maximum width. Cells beyond max_col are dropped.
Check if a horizontal range of cells on row contains only spaces.
Returns true if every cell from col_start to col_end - 1 is empty.
@spec dir_down() :: 2
Direction bitfield constant for down.
@spec dir_left() :: 4
Direction bitfield constant for left.
@spec dir_right() :: 8
Direction bitfield constant for right.
@spec dir_up() :: 1
Direction bitfield constant for up.
@spec direction_to_char() :: %{required(non_neg_integer()) => String.t()}
Returns the direction-to-character mapping.
Draw a horizontal line of a character from col_start to col_end.
Draw a vertical line of a character from row_start to row_end.
Fill a horizontal span with a character from col_start to col_end (exclusive).
Flip the canvas horizontally (for RL direction).
Flip the canvas vertically (for BT direction).
Get the character at a position.
@spec get_cell(t(), integer(), integer()) :: Boxart.Canvas.Cell.t()
Get the full cell at a position, or a default empty cell.
Get the style key at a position.
@spec new(non_neg_integer(), non_neg_integer()) :: t()
Create a new canvas with the given dimensions.
Mark a cell as protected. Protected cells only accept junction merges that add a new direction, not plain overwrites from edge lines.
Check if a cell is protected.
Place a character on the canvas, optionally merging junctions.
When merge is true and both the existing cell and the new character
have directional information (from box-drawing characters), their
direction bits are OR'd together and the correct junction character
is derived from the combined bitfield.
Options
:merge- whether to merge box-drawing junctions (default:true):style- style key for the cell (default:"")
Place text with per-segment style keys. Each segment is {text, style_key}.
Place a string of text starting at {col, row}. Each character is placed
without junction merging. Wide (CJK) characters advance by 2 columns.
Render canvas to a string, trimming trailing whitespace per line and removing both leading and trailing empty lines.
@spec render_ansi(t(), Boxart.Theme.t()) :: String.t()
Render canvas to an ANSI-colored string using the given theme.
@spec resize(t(), non_neg_integer(), non_neg_integer()) :: t()
Expand the canvas to at least the given dimensions.
Return {char, style_key} pairs for each cell as a list of rows.