unicorn-hat-extras 0.1.0

High-level convenience features for unicorn-hat: fonts, drawing primitives, animations
Documentation
# unicorn-hat-extras

High-level convenience features for the [unicorn-hat](../unicorn-hat) library.

This crate provides text rendering, scrolling animations, and frame buffers built on top of the core `unicorn-hat` crate. Perfect for creating ticker-tape displays, notifications, and smooth animations on your Pimoroni Unicorn HAT.

## Features

- **📝 Text Rendering**: 5×5 bitmap font optimized for 8×8 displays
- **📜 Scrolling Animations**: Smooth text scrolling in all 4 directions
- **🎞️ Frame Buffers**: Double-buffering for flicker-free animations
- **🎨 Easy Integration**: Works seamlessly with core primitives and drawing functions

## Installation

Add both crates to your `Cargo.toml`:

```toml
[dependencies]
unicorn-hat = "0.1"
unicorn-hat-extras = "0.1"
```

## Quick Start

### Simple Text Display

```rust
use unicorn_hat::{UnicornHat, RGB8, PixelBuffer};
use unicorn_hat_extras::font::{draw_text, FONT_5X5};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut hat = UnicornHat::new()?;

    // Draw "HI" in green at position (0, 1)
    draw_text(&mut hat, &FONT_5X5, 0, 1, "HI", RGB8::GREEN)?;
    hat.display()?;

    Ok(())
}
```

### Scrolling Ticker Tape

```rust
use std::thread;
use std::time::Duration;
use unicorn_hat::{UnicornHat, RGB8};
use unicorn_hat_extras::font::FONT_5X5;
use unicorn_hat_extras::scroller::{Scroller, Direction};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut hat = UnicornHat::new()?;
    let mut scroller = Scroller::new(
        "HELLO WORLD",
        &FONT_5X5,
        RGB8::CYAN,
        Direction::Left,
    );

    // Animate scrolling text
    for _ in 0..100 {
        hat.clear();
        scroller.render(&mut hat)?;
        hat.display()?;
        scroller.step();
        thread::sleep(Duration::from_millis(50));
    }

    Ok(())
}
```

### Double-Buffered Animation

```rust
use unicorn_hat::{UnicornHat, RGB8, PixelBuffer};
use unicorn_hat_extras::frame::Frame;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut hat = UnicornHat::new()?;

    // Prepare frame off-screen
    let mut frame = Frame::new();
    frame.set_pixel(3, 3, RGB8::RED)?;
    frame.set_pixel(4, 4, RGB8::BLUE)?;

    // Display the complete frame at once
    hat.show_frame(frame.get_all())?;

    Ok(())
}
```

## Examples

Run the included examples to see what's possible:

```bash
# Horizontal scrolling ticker tape
sudo cargo run -p unicorn-hat-extras --example ticker_tape

# Vertical scrolling demonstrations
sudo cargo run -p unicorn-hat-extras --example vertical_scroll

# Frame buffer and animation techniques
sudo cargo run -p unicorn-hat-extras --example double_buffer
```

## API Overview

### Font Module (`font`)

- **`FONT_5X5`**: 5×5 pixel bitmap font (ASCII 32-126)
- **`draw_char(buffer, font, x, y, ch, color)`**: Draw a single character
- **`draw_text(buffer, font, x, y, text, color)`**: Draw a text string

Coordinates can be negative for smooth off-screen rendering and scrolling effects.

### Scroller Module (`scroller`)

- **`Scroller::new(text, font, color, direction)`**: Create a scrolling text animation
- **`scroller.step()`**: Advance the scroll position
- **`scroller.render(buffer)`**: Draw the current frame
- **`scroller.set_speed(pixels_per_step)`**: Control scroll speed
- **`scroller.is_complete()`**: Check if text has scrolled off-screen

Supports all 4 directions: `Left`, `Right`, `Up`, `Down`.

### Frame Module (`frame`)

- **`Frame::new()`**: Create an 8×8 off-screen buffer
- **`Frame::with_color(color)`**: Create a frame filled with a color
- **`frame.set_pixel(x, y, color)`**: Modify pixels off-screen
- **`frame.get_all()`**: Get the complete frame buffer
- **`UnicornHat::show_frame(frame_data)`**: Display a frame buffer

Use `Frame` for double-buffering and preparing complex scenes before display.

## Font Details

The included `FONT_5X5` font covers printable ASCII (characters 32-126) and is optimized for readability on small 8×8 displays. Each character is 5 pixels wide and 5 pixels tall, with automatic 1-pixel spacing between characters.

## Performance Tips

- Use `Frame` for complex scenes to avoid partial updates being visible
- Adjust `Scroller` speed with `set_speed()` to match your desired animation framerate
- Call `hat.clear()` before rendering each frame for smooth scrolling
- Negative coordinates are handled efficiently - no need to check bounds manually

## Integration with Core Library

All `extras` functions work with any type implementing the `PixelBuffer` trait, including:
- `UnicornHat` (direct hardware rendering)
- `Frame` (off-screen rendering)
- `TestBuffer` (for unit testing)

This means you can mix and match core primitives (lines, rectangles, gradients) with text rendering and scrolling seamlessly.

## Requirements

- Requires the `unicorn-hat` core library
- Hardware: Pimoroni Unicorn HAT (8×8) on Raspberry Pi
- Must run with `sudo` (see main `unicorn-hat` crate docs for details)

## License

MIT License - see the workspace root [`LICENSE`](../LICENSE) file for details.

## More Information

For more details about the core library, hardware setup, and permissions, see the main [README](../README.md).