# retroglyph > A 2D pseudographic terminal library **Version:** 0.1.0 **Authors:** Matan Lurey **License:** MIT **Repository:** https://github.com/crates-lurey-io/retroglyph **Keywords:** roguelike, terminal, grid, gamedev **Dependencies:** - ixy (0.6.0-alpha.7) - image (0.25) [features: png] - unicode-width (0.2) - bitflags (2.4) - crossterm (0.28) - softbuffer (0.4) - alpha-blend (0.2) [features: std] - winit (0.30) - log (0.4) - grixy (0.6.0-alpha.7) [features: alloc, buffer] - unicode-segmentation (1.13) **Features:** - std: [] - software: [dep:winit, dep:softbuffer, dep:log, std] - software-tilesets: [software, dep:image, dep:alpha-blend, dep:log] - egc: [dep:unicode-segmentation] - default: [std, egc] - crossterm: [dep:crossterm, std] - software-default-font: [software] Generated: 2026-06-22 01:13:48 UTC Created by: [cargo-llms-txt](https://github.com/masinc/cargo-llms-txt) ## Core Documentation - [Complete API Documentation](llms-full.txt): Full public API documentation with detailed descriptions - [README](README.md): Project overview and getting started guide - [Cargo.toml](Cargo.toml): Project configuration and dependencies ## Table of Contents ### src/tile.rs - pub struct Tile - impl Default for Tile - impl Tile ### src/event.rs - pub struct KeyModifiers - impl KeyModifiers - impl BitOr for KeyModifiers - impl BitOrAssign for KeyModifiers - impl BitAnd for KeyModifiers - impl BitAndAssign for KeyModifiers - impl Not for KeyModifiers - pub enum KeyCode - pub struct KeyEvent - pub enum MouseButton - pub enum MouseEventKind - pub struct MouseEvent - pub enum Event ### src/color.rs - pub enum AnsiColor - impl AnsiColor - pub struct InvalidAnsiIndex - impl core::fmt::Display for InvalidAnsiIndex - impl TryFrom for AnsiColor - pub enum Color - impl Color ### src/layout.rs - pub enum HAlign - pub enum VAlign - pub struct TextMetrics - pub struct TextLayout - impl TextLayout ### src/terminal.rs - pub struct Terminal - impl Terminal ### src/backend/headless.rs - pub struct Headless - impl Headless - impl Backend for Headless ### src/backend/crossterm.rs - impl From for crossterm::style::Color - impl From for crossterm::style::Attributes - pub struct Crossterm - impl Crossterm - impl Drop for Crossterm - impl Backend for Crossterm - impl TryFrom for crate::event::KeyCode - impl From for crate::event::KeyModifiers - impl From for crate::event::MouseButton - impl TryFrom for crate::event::MouseEventKind - impl TryFrom for crate::event::MouseEvent - impl TryFrom for Event ### src/backend/software/sprite_cache.rs - pub struct Sprite - pub struct SpriteCache - impl SpriteCache - impl Default for SpriteCache - pub fn source_over ### src/backend/software/bitmap_font.rs - pub struct BitmapFont - impl BitmapFont - impl PartialEq for BitmapFont - impl Eq for BitmapFont - pub mod vga8x16 - pub const vga8x16::FONT ### src/backend/software/config.rs - pub enum SoftwareBackendError - impl fmt::Display for SoftwareBackendError - impl std::error::Error for SoftwareBackendError - pub struct SoftwareBackend - impl Default for SoftwareBackend - pub struct SoftwareBackendBuilder - impl SoftwareBackendBuilder - impl Default for SoftwareBackendBuilder ### src/backend/software/windowed.rs - pub trait WindowedBackend ### src/backend/software/mod.rs - pub mod bitmap_font - pub mod config - pub mod sprite_cache - pub mod tileset - pub use bitmap_font::BitmapFont - pub use config::{SoftwareBackend, SoftwareBackendBuilder, SoftwareBackendError} - pub mod windowed - pub use windowed::WindowedBackend - pub struct SoftwareRenderer - pub enum SurfaceError - impl core::fmt::Display for SurfaceError - impl std::error::Error for SurfaceError - impl SoftwareRenderer - impl SoftwareBackend - impl Backend for SoftwareRenderer - impl WindowedBackend for SoftwareRenderer - impl WindowApp - impl ApplicationHandler for WindowApp ### src/backend/software/tileset.rs - pub enum TilesetError - impl fmt::Display for TilesetError - impl std::error::Error for TilesetError - pub enum Codepage - impl Codepage - pub const CP437_TO_UNICODE - pub struct TilesetOptions - impl TilesetOptions - pub struct TilesetBuilder - impl TilesetBuilder ### src/backend/mod.rs - pub mod crossterm - pub mod headless - pub mod software - pub use crossterm::Crossterm - pub use headless::Headless - pub use software::{SoftwareBackend, SoftwareRenderer, WindowedBackend} - pub trait Backend ### src/style.rs - impl core::fmt::Debug for CellModifier - pub struct Style - impl Style ### src/grid.rs - pub struct Size - pub type Pos - pub type Rect - impl From for Size - impl From for Unknown - pub struct Cells - impl Iterator for Cells - pub struct CellsMut - impl Iterator for CellsMut - impl LayerBuf - pub struct Grid - impl Grid - impl Grid - impl Grid - impl Index for Grid - impl IndexMut for Grid - impl fmt::Display for Grid - impl fmt::Debug for Grid ### src/text.rs - pub struct Span - impl Span - impl From for Span - pub struct Line - impl Line - impl From for Line - impl From for Line - impl From for Line - impl From for Line ### src/lib.rs - pub mod backend - pub mod color - pub mod event - pub mod grid - pub mod layout - pub mod style - pub mod terminal - pub mod text - pub mod tile - pub use backend::Crossterm - pub use backend::software::SoftwareBackend - pub use backend::software::tileset::{Codepage, TilesetBuilder, TilesetError, TilesetOptions} - pub use backend::{Backend, Headless} - pub use color::{AnsiColor, Color, InvalidAnsiIndex} - pub use event::{Event, KeyCode, KeyEvent, KeyModifiers, MouseButton, MouseEvent, MouseEventKind} - pub use grid::{Grid, Pos, Rect, Size} - pub use layout::{HAlign, TextLayout, TextMetrics, VAlign} - pub use style::{CellModifier, Style} - pub use terminal::Terminal - pub use text::{Line, Span} - pub use tile::Tile --- ## README.md ### retroglyph A 2D pseudographic terminal library for Rust. ![crossterm demo](tests/snapshots/crossterm_demo.svg) `retroglyph` provides a styled character grid, double-buffered rendering, and pluggable backends. You drive the game loop; `retroglyph` handles drawing efficiently and feeding you input events. #### Features
Grid API — place styled characters on a multi-layer grid with full color support Up to 256 layers. Each cell carries a glyph, foreground/background color, text modifiers (bold, italic, underline, blink, reverse, dim, hidden, strikethrough), and sub-cell pixel offsets. Layer 0 is always allocated; layers 1+ are allocated on first write — single-layer games pay zero overhead. Colors cover the full spectrum: the terminal's default foreground/background, the 16 standard ANSI colors, the 256-color palette, and 24-bit RGB.
Double buffering — diff-based presentation sends only changed cells `Terminal::present()` compares the current frame against the previous one and forwards only the changed cells to the backend. Pixel-based backends (software renderer) request full frames because sub-cell offsets can leave orphaned pixels from the previous frame.
Stateful drawing API — chainable builder for everyday rendering Set the active style with `fg()`, `bg()`, `modifier()`, then place characters with `put()`. Print strings with `print()` (handles newlines and wide characters), render styled spans with `print_styled()`, or lay out text in a bounded rectangle with `print_box()`. Clear the active layer, all layers, or a rectangular region. Switch layers with `layer(id)`. Or bypass the builder and access the grid directly via `grid_mut()`.
Text layout and word wrapping — styled spans with configurable alignment `Span` and `Line` provide styled text primitives. `TextLayout` is a builder that word-wraps a `Line` to a bounded rectangle, then positions it with independent horizontal and vertical alignment (left/center/right, top/middle/bottom). Measure the result before rendering with `TextLayout::measure()`.
Extended grapheme cluster support — combining marks, emoji, and CJK wide chars With the `egc` feature (enabled by default), the library handles full Unicode grapheme clusters: combining marks, ZWJ emoji sequences, and multi-codepoint characters. CJK characters and emoji automatically occupy two grid columns with a transparent spacer in the adjacent cell. Multi-codepoint graphemes are capped at 8 codepoints to prevent combining-mark bombs.
Pluggable backends — swap rendering targets without touching game logic The `Backend` trait has a small surface: draw cells, flush, poll events, resize, cursor control. - **Headless** — in-memory with no I/O. The workhorse for unit and integration tests. Provides `format_view()` for snapshot testing with insta and `push_event()` for synthetic input. - **Crossterm** (feature `crossterm`) — full terminal with raw mode, alternate screen, and mouse capture. Registers a panic hook to safely restore the terminal on crashes. - **Software** (feature `software`) — pixel-based rendering via winit + softbuffer. Uses a 1-bit bitmap font (embedded VGA 8x16 with `software-default-font`), with sub-cell pixel offsets, multi-layer compositing, configurable scale factor, and a headless mode for pixel-level testing. - **Sprite tilesets** (feature `software-tilesets`) — PNG sprite sheets mapped to a codepage (CP437, Unicode range, or custom), rendered with RGBA alpha blending over bitmap font glyphs.
Input handling — keyboard, mouse, resize, and close events `Terminal::poll(timeout)` returns `Option` with support for keyboard (all standard keys + modifier flags), mouse (buttons, movement, scroll), window resize, and close events. `has_input()` checks for events without blocking. Resize events are automatically applied to the grid before the event reaches your code.
no_std compatible — core crate compiles without std Disable the `std` feature (requires an allocator). Useful for embedded or kernel-space roguelikes.
#### Quick start ```toml [dependencies] retroglyph = { version = "0.1", features = ["crossterm"] } ``` ```rust use retroglyph::{Terminal, backend::Crossterm, color::Color, event::{Event, KeyCode}}; fn main() -> std::io::Result<()> { let mut term = Terminal::new(Crossterm::new()?); loop { term.clear(); term.fg(Color::GREEN); term.put(5, 5, '@'); term.present(); if let Some(Event::Key(k)) = term.poll(std::time::Duration::from_secs(1)) { if k.code == KeyCode::Char('q') { break; } } } Ok(()) } ``` Run the interactive demo: ```sh cargo run --example crossterm_demo --features crossterm ``` ## Cargo.toml ```toml [workspace] members = ["tools/cargo-bin"] resolver = "2" [workspace.metadata.bin] wasm-server-runner = { version = "1.0.1" } hk = { version = "1.48.0" } [package] name = "retroglyph" version = "0.1.0" edition = "2024" rust-version = "1.88" authors = ["Matan Lurey "] license = "MIT" description = "A 2D pseudographic terminal library" repository = "https://github.com/crates-lurey-io/retroglyph" keywords = ["roguelike", "terminal", "grid", "gamedev"] categories = ["game-development", "graphics"] [lints.rust] unsafe_code = "forbid" missing_docs = "warn" unreachable_pub = "warn" unused_qualifications = "warn" [lints.clippy] all = { level = "deny", priority = -1 } pedantic = { level = "deny", priority = -1 } nursery = { level = "deny", priority = -1 } must_use_candidate = "deny" missing_errors_doc = "deny" missing_panics_doc = "deny" module_name_repetitions = "allow" [dependencies] ixy = "0.6.0-alpha.7" grixy = { version = "0.6.0-alpha.7", features = ["alloc", "buffer"] } unicode-width = "0.2" bitflags = "2.4" unicode-segmentation = { version = "1.13", default-features = false, optional = true } crossterm = { version = "0.28", optional = true } winit = { version = "0.30", optional = true } softbuffer = { version = "0.4", optional = true } image = { version = "0.25", optional = true, default-features = false, features = ["png"] } alpha-blend = { version = "0.2", optional = true, default-features = false, features = ["std"] } log = { version = "0.4", optional = true } [features] default = ["std", "egc"] std = [] egc = ["dep:unicode-segmentation"] crossterm = ["dep:crossterm", "std"] software = ["dep:winit", "dep:softbuffer", "dep:log", "std"] software-tilesets = ["software", "dep:image", "dep:alpha-blend", "dep:log"] software-default-font = ["software"] [[example]] name = "crossterm_demo" required-features = ["crossterm"] [[example]] name = "software_demo" required-features = ["software-default-font"] [[example]] name = "tileset_demo" required-features = ["software-tilesets", "software-default-font"] [[example]] name = "software_subpixel_demo" required-features = ["software-default-font"] [[example]] name = "wasm_demo" required-features = ["software-default-font"] [[example]] name = "headless_demo" required-features = [] [[example]] name = "runner" required-features = [] [target.'cfg(target_arch = "wasm32")'.dev-dependencies] wasm-bindgen = "=0.2.106" console_error_panic_hook = "0.1" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] portable-pty = "0.9.0" vt100 = "0.15" [dev-dependencies] toml = "0.8" serde = { version = "1", features = ["derive"] } image = { version = "0.25", default-features = false, features = ["png"] } insta = { version = "1.34", features = ["yaml"] } ```