#![no_std] bitmap font engine for MCUs: compile TTF/OTF/BDF into a compact .etf format, load from ROM or external flash, lay out text, and draw pixels—optionally through embedded-graphics.
Note: This repo have NOT published yet (
publish = false).
.etffonts with optional PackBits RLEetfc: subset / Unicode ranges / variable-font axesReadStorage+ExternalEtfFontfor SPI NOR (and friends)- Stack LRU
GlyphCache(no heap) - Layout: multiline, character/word wrap, line spacing
- Built-in
AsciiFont8x16, GB2312/GBK decoder embedded-graphics0.8TextRendereradapter
| Crate | Role |
|---|---|
embedded-text-font-core |
Traits (Font, ReadStorage, …), GBK |
embedded-text-font |
.etf parse, external storage, cache |
embedded-text-font-font |
Static fonts |
embedded-text-font-renderer |
Layout + draw |
embedded-text-font-eg |
EG adapter |
etfc |
Font compiler CLI |
TTF/OTF/BDF ──etfc──► .etf ──► EtfFont / ExternalEtfFont ──► layout ──► pixels
▲ ReadStorage / GlyphCache (optional)
[dependencies]
embedded-text-font = { path = "crates/embedded-text-font" }
embedded-text-font-renderer = { path = "crates/embedded-text-font-renderer" }
# optional:
embedded-text-font-eg = { path = "crates/embedded-text-font-eg" }
embedded-graphics = "0.8"use embedded_text_font_core::Point;
use embedded_text_font::EtfFont;
use embedded_text_font_renderer::{LayoutConfig, draw_multiline_text};
let font = EtfFont::parse(include_bytes!("ui.etf")).unwrap();
let cfg = LayoutConfig::new().with_max_width(128);
let origin = Point::new(0, font.ascent() as i32);
draw_multiline_text("Hello", origin, &font, cfg, |x, y, on| {
if on { /* plot (x, y) */ }
Ok::<(), core::convert::Infallible>(())
})
.unwrap();External flash + cache:
use embedded_text_font::{ExternalEtfFont, GlyphCache};
let font = GlyphCache::<_, 32, 256>::new(ExternalEtfFont::new(&flash).unwrap());embedded-graphics:
use embedded_graphics::{pixelcolor::BinaryColor, prelude::*, text::{Baseline, Text}};
use embedded_text_font_eg::EmbeddedEtfRenderer;
use embedded_text_font::EtfFont;
let font = EtfFont::parse(include_bytes!("ui.etf")).unwrap();
let style = EmbeddedEtfRenderer::new(&font, BinaryColor::On);
Text::with_baseline("Hello", Point::zero(), style, Baseline::Top).draw(&mut display)?;cargo run -p etfc -- compile \
--font Font.ttf --output ui.etf \
--size 16 --ranges 0020-007E,4E00-9FFF --compress| Flag | Meaning |
|---|---|
-f / -o |
Input font / output .etf |
-s / -r |
Subset file / Unicode ranges |
-c |
PackBits RLE |
--size |
Em size in px (default 16) |
--encoding |
BDF encoding (utf8, gbk, …) |
--variation |
e.g. wght=400 |
cargo run -p etfc -- inspect --font Font.ttf --size 16 --compress
ASCII-art preview in the terminal:
cargo run --bin example-latin # compressed Latin ETF
cargo run --bin example-builtin-ascii # AsciiFont8x16
cargo run --bin example-chinese
cargo run --bin example-spi-flash # ExternalEtfFont + GlyphCache
cargo run --bin example-eg
cargo run --bin example-layout
cargo run --bin example-gbk # GBK decode → same CJK string as chineseAlso: example-japanese, example-variable-width, example-italic.