Guiltty Core Crate
Relevant source files
The following files were used as context for generating this wiki page:
The guiltty-core crate serves as the foundational, backend-agnostic engine for the Guiltty project. Its primary purpose is to provide the data structures and logic required for drawing pixel-level 2D graphics, including primitives, text, shapes, and movable sprites. It establishes the Backend trait, which allows different rendering implementations (such as the kitty graphics protocol) to consume a standardized pixel buffer for terminal display.
Sources: crates/guiltty-core/src/lib.rs:1-6, README.md:18-22
This crate is designed to be host-independent and focuses on providing a raw pixel buffer (RGBA8) and the algorithms needed to manipulate it. It manages canvas state, coordinate clipping, and sprite background preservation without depending on specific terminal escape sequences or platform-specific FFI.
Sources: README.md:6-12, crates/guiltty-core/src/lib.rs:107-113
Architecture and Data Structures
The core architecture centers around the Canvas struct, which manages an underlying buffer of Color objects. Primitives like Point and Rect provide the coordinate system, while the Backend trait defines how this data is eventually presented.
Core Primitives
The library uses a top-left origin coordinate system based on i32 for positioning and u32 for dimensions.
| Data Structure | Description | Key Fields |
|---|---|---|
Color | RGBA8 color representation. | r, g, b, a (u8) |
Point | A pixel-addressable coordinate. | x, y (i32) |
Rect | A pixel-addressable rectangle. | x, y (i32), width, height (u32) |
Sources: crates/guiltty-core/src/lib.rs:8-66
Canvas and Buffer Management
The Canvas is a row-major RGBA8 pixel buffer. Each Canvas instance is assigned a unique u64 ID, which is critical for sprite "save-under" logic to ensure background pixels aren't restored to the wrong canvas after a clone or swap.
The rgba8_bytes() method flattens the internal Vec<Color> into a Vec<u8> format (R, G, B, A order) suitable for transmission by backends.
Sources: crates/guiltty-core/src/lib.rs:107-160
Drawing Logic
guiltty-core implements several standard computer graphics algorithms to manipulate the pixel buffer.
Shapes and Fills
The Shape enum defines supported geometries, while Fill determines how they are painted.
- Bresenham's Line Algorithm: Used for
Shape::Line, featuring Liang-Barsky clipping to optimize rendering for off-screen or extreme coordinates. - Even-Odd Rule Scanline Fill: Used for closed
Shape::Pathvariants. It handles concave and self-intersecting polygons by sorting scanline crossings. - Barycentric Sign Test: Used for
Shape::Trianglefilling. - Elliptical Inclusion Test: Uses floating-point division
(dx/rx)² + (dy/ry)² <= 1.0to avoid integer overflows with large radii.
Sources: crates/guiltty-core/src/lib.rs:341-365, crates/guiltty-core/src/lib.rs:412-420, crates/guiltty-core/src/lib.rs:484-515
Text Rendering
Text is rendered using a minimal, built-in 3x5 bitmap font. Supported characters currently include digits 0-9, uppercase A-Z, and spaces. Text can be scaled using an integer factor in the TextStyle.
Sources: crates/guiltty-core/src/lib.rs:162-184, crates/guiltty-core/src/lib.rs:242-286
Sprite System
The sprite system supports movable bitmaps with background preservation.
Save-Under Mechanism
When a Sprite is drawn onto a Canvas, the crate captures the pixels currently occupying the sprite's target area. This is stored in a DrawnFootprint.
This flow ensures that moving a sprite does not leave a "trail" on the canvas, provided no other drawing operations occurred in that footprint between the last draw and the move.
Sources: crates/guiltty-core/src/lib.rs:728-765
Bitmap Loading
The Bitmap struct represents the sprite's content. It can be initialized from solid colors or loaded from disk.
| Method | Source | Description |
|---|---|---|
Bitmap::solid | Internal | Creates a uniform color bitmap. |
Bitmap::from_file | External (image crate) | Loads PNG, JPEG, GIF, or BMP and converts to RGBA8. |
Sources: crates/guiltty-core/src/lib.rs:604-633, crates/guiltty-core/Cargo.toml:13
Error Handling
The crate defines a guiltty_core::Error enum for recoverable conditions. Recoverable errors are surfaced to the caller via Result, while panics are reserved for developer-level invariant violations (e.g., dimension overflows).
Error::Backend(String): Encapsulates errors reported by the rendering backend.Error::ImageLoad(String): Reports failures duringBitmap::from_file(e.g., missing file or corrupt data).
Sources: crates/guiltty-core/src/lib.rs:70-90
Integration with Backends
The Backend trait is the bridge between the core pixel buffer and terminal rendering.
pub trait Backend {
type Error: std::error::Error;
/// Presents canvas's current pixel buffer to the terminal.
fn present(&mut self, canvas: &Canvas) -> Result<(), Self::Error>;
}
The guiltty facade crate re-exports these core types alongside specific backends like KittyBackend for easier consumption.
Sources: crates/guiltty-core/src/lib.rs:96-103, crates/guiltty/src/lib.rs:1-8
Summary
guiltty-core provides a robust, platform-independent foundation for 2D terminal graphics. By implementing complex drawing algorithms (Bresenham, Liang-Barsky, Scanline fill) and a stateful sprite system with background preservation, it enables high-level graphical operations within a raw pixel buffer. This buffer is then passed through a standardized Backend trait for final rendering in terminal environments.