Project Introduction
Relevant source files
The following files were used as context for generating this wiki page:
guiltty is a Rust library designed for drawing pixel-level 2D graphics directly into a terminal. Unlike traditional character-cell TUI toolkits like ratatui or cursive which operate on a grid of characters, guiltty leverages the kitty graphics protocol to render actual pixels, smooth shapes, and precise images. Sources: README.md:1-12
The project is structured as a host-independent library, allowing developers to create canvases, draw text and shapes, and manage movable sprites with background preservation. It currently supports a backend-agnostic core and a specific implementation for the kitty protocol. Sources: README.md:14-23
Architecture Overview
The project is organized as a Cargo workspace containing three primary crates and an examples directory. This separation ensures that the core rendering logic remains independent of the specific terminal transmission protocols. Sources: README.md:27-31, Cargo.toml:1-8
Crate Structure
| Crate | Description |
|---|---|
guiltty-core | Contains backend-agnostic primitives, the Canvas, shape drawing logic, and the Backend trait. |
guiltty-kitty | Implements the KittyBackend, which encodes canvas data into kitty graphics protocol escape sequences. |
guiltty | A facade crate that re-exports the public API from core and the kitty backend for ease of use. |
examples | Contains runnable demo binaries for manual visual verification. |
Sources: README.md:32-40, crates/guiltty/src/lib.rs:4-9, examples/Cargo.toml:1-12
System Data Flow
The following diagram illustrates how data flows from user-defined shapes and sprites into the pixel buffer, and finally to the terminal via a backend.
The diagram shows the transition from abstract drawing commands to raw pixel buffers and finally to terminal-specific escape sequences. Sources: crates/guiltty-core/src/lib.rs:72-100, crates/guiltty-kitty/src/lib.rs:24-40, tasks/plan.md:46-55
Core Components
The Canvas and Pixel Buffer
The Canvas is the central structure for drawing. it maintains a row-major Vec<Color> buffer where each pixel is represented as an RGBA8 value. It provides methods for setting individual pixels and retrieving the entire buffer as a byte slice for backends. Sources: crates/guiltty-core/src/lib.rs:102-148
Primitives and Styling
- Color: Represents RGBA8 components. Sources: crates/guiltty-core/src/lib.rs:7-24
- Point & Rect: Basic geometric structures for pixel-addressable coordinates. Sources: crates/guiltty-core/src/lib.rs:27-60
- TextStyle: Configures color and integer scaling for the built-in 3x5 bitmap font. Sources: crates/guiltty-core/src/lib.rs:232-248
Drawing Logic
The library supports several drawing operations, including lines (via Bresenham's algorithm with Liang-Barsky clipping), rectangles, ellipses, and triangles. Sources: crates/guiltty-core/src/lib.rs:319-450
A notable feature is the Shape::Path variant, which supports both open and closed paths. Closed paths are filled using a scanline polygon fill algorithm with the even-odd rule. Sources: crates/guiltty-core/src/lib.rs:303-317, crates/guiltty-core/src/lib.rs:456-506, tasks/plan.md:83-93
Sprite System
The Sprite system allows for movable 2D bitmaps that can be positioned over a canvas. It includes a "save-under/restore-under" mechanism to prevent sprites from leaving trails when they move. Sources: crates/guiltty-core/src/lib.rs:649-652, crates/guiltty-core/src/lib.rs:695-711
This sequence ensures that moving a sprite automatically restores the background it previously covered before drawing it at the new location. Sources: crates/guiltty-core/src/lib.rs:713-755
Rendering Backends
Backends must implement the Backend trait, which defines the present method. Sources: crates/guiltty-core/src/lib.rs:88-97
KittyBackend Implementation
The KittyBackend is the primary implementation. It transforms the Canvas pixel buffer into the Kitty Graphics Protocol. Key features include:
- Base64 Encoding: Encodes RGBA8 data for transmission. Sources: crates/guiltty-kitty/src/lib.rs:81-83
- Chunking: Splits large payloads into 4096-byte chunks (APC sequences) as required by the protocol. Sources: crates/guiltty-kitty/src/lib.rs:16, crates/guiltty-kitty/src/lib.rs:84
- Image/Placement IDs: Uses unique IDs to ensure that repeated calls to
present()update the same on-screen image rather than creating new ones. Sources: crates/guiltty-kitty/src/lib.rs:20-22, crates/guiltty-kitty/src/lib.rs:104-118
Project Status and Tooling
Guiltty is currently in an early scaffold/pre-alpha stage. While core drawing and sprite logic are implemented and unit-tested, terminal rendering via the Kitty protocol is under active development. Sources: README.md:42-53
Development Standards
- MSRV: The Minimum Supported Rust Version is pinned to
1.96.0. Sources: Cargo.toml:14, tasks/issue-16-consumability-assessment-from-iklo-guiltty-s.md:37-41 - Linting: Strict
clippyandrustfmtrules are enforced via workspace configuration. Sources: Cargo.toml:19-25, clippy.toml:1-5, rustfmt.toml:1-5 - Testing: CI enforces a code coverage floor of 90% using
llvm-cov. Sources: tasks/plan.md:15, tasks/issue-8-chore-ci-hardening-follow-ups-caching-sha-pinned.md:6
Summary
The guiltty project provides a foundational Rust library for high-fidelity terminal graphics. By abstracting the complexities of pixel-level drawing and protocol-specific encoding, it enables the creation of TUIs that surpass the limitations of character-grid systems. The architecture emphasizes a clean separation between core drawing logic and backend transmission, ensuring extensibility for future terminal protocols. Sources: README.md:1-23, crates/guiltty-core/src/lib.rs:1-6