| Crates.io | retrofont |
| lib.rs | retrofont |
| version | 0.2.2 |
| created_at | 2025-11-09 14:40:16.941828+00 |
| updated_at | 2025-12-14 13:29:26.289546+00 |
| description | Retro terminal font toolkit: TDF/FIGlet parsing, rendering, conversion. |
| homepage | |
| repository | https://github.com/mkrueger/retrofont |
| max_upload_size | |
| id | 1924180 |
| size | 255,543 |
A Rust library for parsing, rendering, and converting retro ASCII/ANSI art fonts, supporting both FIGlet and TheDraw (TDF) formats with full Unicode support.
Add to your Cargo.toml:
[dependencies]
retrofont = "0.1.2"
use retrofont::{Font, RenderOptions, test_support::BufferTarget};
fn main() -> retrofont::Result<()> {
// Load a font (auto-detects format)
let data = std::fs::read("fonts/doom.flf")?;
let fonts = Font::from_bytes(&data)?;
let font = &fonts[0]; // FIGlet returns one font, TDF can have multiple
// Create a rendering target
let mut target = BufferTarget::new();
let options = RenderOptions::default();
// Render text character by character
for ch in "HELLO".chars() {
font.render_char(&mut target, ch, &options)?;
target.next_char(); // Advance to next character position
}
// Get the result
println!("{}", target.to_string());
Ok(())
}
Create your own output format by implementing the FontTarget trait:
use retrofont::{FontTarget, Cell};
use std::fmt;
struct HtmlTarget {
html: String,
}
impl FontTarget for HtmlTarget {
type Error = fmt::Error;
fn draw(&mut self, cell: Cell) -> Result<(), Self::Error> {
// Escape HTML characters
let ch = match cell.ch {
'<' => "<",
'>' => ">",
'&' => "&",
c => {
self.html.push(c);
return Ok(());
}
};
self.html.push_str(ch);
Ok(())
}
fn next_line(&mut self) -> Result<(), Self::Error> {
self.html.push_str("<br>\n");
Ok(())
}
fn next_char(&mut self) -> Result<(), Self::Error> {
// Optional: Handle character spacing
Ok(())
}
}
Convert FIGlet fonts to TheDraw format:
use retrofont::{
figlet::FigletFont,
tdf::TdfFontType,
convert::{convert_to_tdf, is_figlet_compatible_with_tdf}
};
fn convert_font() -> retrofont::Result<()> {
// Load FIGlet font
let data = std::fs::read("input.flf")?;
let figlet = FigletFont::from_bytes(&data)?;
// Check compatibility
if is_figlet_compatible_with_tdf(&figlet, TdfFontType::Block) {
// Convert to TDF
let tdf = convert_to_tdf(&figlet, TdfFontType::Block)?;
// Serialize to bytes
let tdf_bytes = tdf.as_tdf_bytes()?;
std::fs::write("output.tdf", tdf_bytes)?;
}
Ok(())
}
use retrofont::{Font, tdf::TdfFont};
fn handle_bundle() -> retrofont::Result<()> {
// Load a TDF bundle (multiple fonts)
let data = std::fs::read("bundle.tdf")?;
let fonts = Font::from_bytes(&data)?;
// Iterate through fonts
for (i, font) in fonts.iter().enumerate() {
println!("Font {}: {}", i, font.name());
// Check character availability
if font.has_char('A') {
// Render specific character
let mut target = BufferTarget::new();
font.render_char(&mut target, 'A', &RenderOptions::default())?;
}
}
// Create a new bundle
if let Font::Tdf(tdf1) = &fonts[0] {
if let Font::Tdf(tdf2) = &fonts[1] {
let bundle = TdfFont::create_bundle(&[tdf1.clone(), tdf2.clone()])?;
std::fs::write("new_bundle.tdf", bundle)?;
}
}
Ok(())
}
Control rendering behavior with RenderOptions:
use retrofont::{RenderOptions, RenderMode};
// Default: Display mode
let opts = RenderOptions::default();
// Edit mode: shows font construction markers
let opts = RenderOptions::edit();
// Custom configuration
let opts = RenderOptions {
render_mode: RenderMode::Display,
outline_style: 5, // Use outline style 5 (0-18 available)
};
Load fonts from any Read source:
use std::io::Cursor;
use retrofont::Font;
fn load_from_memory(data: Vec<u8>) -> retrofont::Result<Vec<Font>> {
let cursor = Cursor::new(data);
Font::from_reader(cursor)
}
Each rendered cell contains:
pub struct Cell {
pub ch: char, // Unicode character
pub fg: Option<u8>, // Foreground color (0-15)
pub bg: Option<u8>, // Background color (0-15)
pub blink: bool, // Blink attribute
pub bold: bool, // Bold attribute (future use)
}
The library uses a Result<T> type alias with FontError:
use retrofont::{Font, FontError, Result};
fn load_font(path: &str) -> Result<Vec<Font>> {
let data = std::fs::read(path)?; // IO errors auto-convert via From
Font::from_bytes(&data)
}
[dependencies]
retrofont = { version = "0.1.2", default-features = false, features = ["tdf"] }
Available features:
tdf: TheDraw font support (default)figlet: FIGlet font support (default)convert: Font conversion utilities (default)color: Color rendering support (default)HashMap<char, Glyph> for memory efficiencyfrom_reader()Licensed under either of:
at your option.
Contributions welcome! Please ensure:
cargo testcargo clippycargo fmt