Bitmap Memory Model
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The Bitmap Memory Model in guiltty defines how pixel data is structured, stored, and manipulated within the library to enable pixel-level 2D graphics in the terminal. At its core, the model relies on a project-wide RGBA8 color model, representing each pixel with four bytes (Red, Green, Blue, and Alpha). This consistency ensures that data can flow seamlessly from external image files and procedural drawing operations into a unified buffer suitable for transmission via backends like the Kitty graphics protocol.
Sources: crates/guiltty-core/src/lib.rs:7-17, README.md:1-10, tasks/plan.md:105-112
The memory model distinguishes between two primary structures: the Canvas, which serves as a mutable render target, and the Bitmap, which represents static drawable material used for sprites. Both structures utilize a row-major Vec<Color> buffer to store pixel data, allowing for efficient indexing and coordinate-to-memory mapping.
Sources: crates/guiltty-core/src/lib.rs:98-105, crates/guiltty-core/src/lib.rs:592-598
Core Data Structures
Color Representation
The Color struct is the fundamental unit of the memory model. It uses the RGBA8 format, where each component is an 8-bit unsigned integer (u8).
| Field | Type | Description |
|---|---|---|
r | u8 | Red component (0-255) |
g | u8 | Green component (0-255) |
b | u8 | Blue component (0-255) |
a | u8 | Alpha (opacity) component (0-255; 0 = transparent, 255 = opaque) |
Sources: crates/guiltty-core/src/lib.rs:7-17
Buffer Layout and Indexing
Both Canvas and Bitmap organize pixels in a row-major format, starting from the top-left origin (0,0). The index in the underlying vector is calculated as (y * width) + x.
The indexing logic uses usize for calculations to prevent overflows on large canvases that might otherwise exceed u32 limits during multiplication.
Sources: crates/guiltty-core/src/lib.rs:136-142, crates/guiltty-core/src/lib.rs:659-665
The Bitmap Structure
The Bitmap struct represents an immutable (after creation) pixel buffer used as source material for drawing operations, specifically for sprites.
Creation and Loading
Bitmaps can be initialized in three ways:
- Manual Buffer: Providing a
Vec<Color>directly viaBitmap::new. - Solid Color: Creating a uniform color block via
Bitmap::solid. - File Loading: Loading from PNG, JPEG, GIF, or BMP formats via
Bitmap::from_file.
When loading from files, the system automatically converts various source formats (grayscale, RGB, etc.) into the standard RGBA8 model. Grayscale images replicate luminance across R, G, and B, while formats without alpha channels are assigned a default opaque alpha value of 255.
Sources: crates/guiltty-core/src/lib.rs:604-642, tasks/plan.md:112-118
The Canvas Structure
The Canvas is the active memory region where drawing occurs. It maintains a unique id to track its instance, which is critical for sprite management and background preservation.
Memory Allocation
Canvas allocation involves calculating the total length as width * height. The system panics if this product overflows usize or exceeds platform memory limits, ensuring that the buffer remains addressable.
Sources: crates/guiltty-core/src/lib.rs:115-130
Exporting for Transmission
To interface with backends, the Canvas can flatten its Vec<Color> into a Vec<u8> of raw bytes. This conversion produces a continuous sequence of [R, G, B, A, R, G, B, A, ...] bytes.
This diagram shows the flow of pixel data from the internal memory model to the terminal output.
Sources: crates/guiltty-kitty/src/lib.rs:70-80
Sprite and Footprint Management
A unique aspect of the memory model is how it handles moving objects through Sprite and DrawnFootprint.
Save-Under/Restore-Under Logic
To prevent sprites from "smearing" across the canvas when they move, the Canvas uses a save-under mechanism. Before a sprite is drawn at a new position, the pixels at that location are captured into a DrawnFootprint.
- Check ID: The system verifies the
canvas_idin theDrawnFootprintmatches the currentCanvasto prevent restoring pixels onto the wrong target. - Restore: The previous position's pixels are restored from the
DrawnFootprintback to theCanvas. - Capture & Draw: The new position's background is saved, and the sprite's bitmap is drawn over it.
Sources: crates/guiltty-core/src/lib.rs:730-745, crates/guiltty-core/src/lib.rs:756-788
This sequence ensures background preservation during sprite movement within the memory buffer.
Sources: crates/guiltty-core/src/lib.rs:756-795
Technical Summary
The Bitmap Memory Model provides a robust foundation for terminal graphics by enforcing a strict RGBA8 standard. By utilizing row-major vectors and safe indexing, it balances performance with memory safety. The inclusion of instance tracking through unique IDs allows the library to manage complex state transitions, such as sprite movement, entirely within the memory model before the final pixel buffer is serialized for terminal backends.
Sources: crates/guiltty-core/src/lib.rs:98-105, crates/guiltty-core/src/lib.rs:756-760