The Layered Runtime Model
Textagram separates every drawing into three independent layers: shapes (heavy box-drawing glyphs), connectors (light box-drawing glyphs and arrowheads), and text (freeform characters). Each layer tracks its own data and invariants — they never merge silently at runtime.
Shapes Layer
Shapes are the heavy box-drawing characters: corners, tees, crosses, and straight bars. They form the structural backbone of diagrams.
#[derive(Debug, Clone)]
pub struct ShapesLayer {
buffer: LayerBuffer,
}Connectors Layer
Connectors use light box-drawing glyphs and route between shapes using A*-style pathfinding. They are the most dynamic layer — rerouting when shapes move or resize.
#[derive(Clone, Debug)]
pub struct ConnectorsLayer {
buffer: LayerBuffer,
}Text Layer
Text lives in its own layer, with grapheme-aware storage that handles emoji, combining marks, and wide characters correctly.
#[derive(Clone, Debug)]
pub struct TextLayer {
width: u16,
height: u16,
cells: Vec<char>,
meta: Vec<TextCellMeta>,
}Composition Order
When rendering, layers compose in a specific order: shapes first, then text on top, then connectors on top of everything. Connectors are always visible, even when crossing over shapes or text.