Expand description
ANSI/SGR cell-diff renderer shared by retroglyph’s terminal-family backends.
TerminalRenderer converts Tile content into standard ANSI/CSI escape sequences (cursor
movement, SetForegroundColor/SetBackgroundColor/SGR attributes, synchronized update markers)
and writes them to any std::io::Write sink. It has no opinion about where those bytes end up
or how input arrives; two crates plug it into a concrete environment:
+-----------------------+
| TerminalRenderer |
| (this crate: Tile -> |
| ANSI/SGR escape |
| sequences) |
+-----------------------+
^ ^
| |
std::io::Write std::io::Write
(String buffer) (stdout)
| |
+-----------------------------+ +-----------------------------+
| retroglyph-terminal-wasm | | retroglyph-crossterm |
| pushed JS key/resize events | | raw mode, alternate screen, |
| -> String pulled by JS each | | kitty keyboard protocol, |
| frame (xterm.js renders it) | | crossterm::event polling |
+-----------------------------+ +-----------------------------+retroglyph-crosstermdrives a real TTY: raw mode, alternate screen, the kitty keyboard protocol, andcrossterm::eventpolling. It writes this renderer’s output straight tostdout.retroglyph-terminal-wasmdrives a browser terminal emulator (e.g. xterm.js) from WASM: no TTY, no polling, output collected into aStringfor JS to pull each frame, input pushed in from JS callbacks.
§Features
This crate has no default features; every feature below is optional and off unless enabled.
§dev
⚪ Optional.
Forwards retroglyph-core’s dev feature, which forces development diagnostics on in a build
that would otherwise compile them out (see retroglyph_core::dev).
§egc
⚪ Optional.
Forwards to retroglyph-core’s egc feature.
This crate has EGC-aware and non-EGC-aware code paths gated on the same flag name.
§Why not part of retroglyph-window
retroglyph-window splits input (winit event loop) from output (Presenter) because every
windowed backend shares one runtime driver: the winit event loop. That split lets renderer
crates avoid depending on winit’s frequent major-version bumps.
Crossterm and the wasm/xterm.js driver share no such runtime: crossterm owns a blocking poll loop against a real TTY, and the wasm driver is pushed into by JS with no polling loop at all. What they do share is the ANSI/SGR cell-diff renderer, so that is what lives in this crate.
§no_std
This crate always requires std (an impl std::io::Write sink), unlike retroglyph-core,
which supports no_std.
§RGB color fallback on 256-color terminals
By default (ColorSupport::Truecolor), Color::Rgb tiles are written out verbatim as a
24-bit truecolor SGR sequence (38;2;r;g;b / 48;2;r;g;b, one of the codes this crate’s
internal SGR-color writer emits), with no quantization. This mirrors crossterm’s own
SetForegroundColor/SetBackgroundColor behavior (and that of most Rust terminal-UI crates):
truecolor codes are written unconditionally, and it is left to the terminal emulator (or a
multiplexer like tmux/screen sitting in between) to interpret or degrade them. In practice:
- Terminals that advertise truecolor support (
$COLORTERM=truecoloror24bit) render the exact color. - Many terminals and multiplexers that only support the 256-color palette (
$TERM=*-256color) approximate the requested RGB to the nearest palette entry themselves, since terminal implementations commonly downsample unrecognized-depth SGR sequences rather than drop them. - A minority of older/limited terminals may render truecolor sequences incorrectly (wrong color,
or no color at all) if they don’t recognize the extended
;2;SGR form.
Callers that know the receiving terminal is more limited (or that $NO_COLOR is set) can set
TerminalRenderer::with_color_support/TerminalRenderer::set_color_support to
ColorSupport::Indexed256, ColorSupport::Ansi16, or ColorSupport::None instead:
draw then quantizes every Color::Rgb tile through
Color::to_indexed/Color::to_ansi (or forces Color::Default) before writing its SGR
sequence, so the emitted bytes match what was actually requested rather than relying on the
terminal to downsample. This crate does not auto-detect terminal capabilities itself (that
belongs to a backend that actually has access to $TERM/$NO_COLOR, e.g.
retroglyph-crossterm’s CrosstermOptions); ColorSupport::Truecolor remains the default.
Callers that need a specific, correct color regardless of ColorSupport should use
Color::Indexed or Color::Ansi explicitly instead of Color::Rgb; both are passed
through untranslated (38;5;n / plain ANSI codes) at every ColorSupport level except
ColorSupport::None (which forces Color::Default regardless of the requested color) and
have no ambiguity across terminal color depths.
Structs§
- Terminal
Renderer - A generic ANSI/SGR cell-diff renderer.
Enums§
- Color
Support - How aggressively
TerminalRendererquantizesColorbefore emitting an SGR sequence.