std/font — Text rendering¶
import std/font
A bitmap font for driving small displays. Each glyph is 5 columns wide and 8 pixels tall: one byte per column, one bit per pixel. Rendering a character emits its 5 glyph columns followed by 1 blank spacing column (an advance of 6).
The module offers three ways to consume rendered text, trading memory for convenience:
Render to a buffer you own (
@font_render) — you control the storage.Render to a library buffer (
@font_render_buf) — zero setup, but a shared static buffer.Stream column-by-column to a callback (
@font_stream,@font_fold) — constant SRAM regardless of text length.
Font metrics¶
- @font_width() -> u8¶
Glyph width in columns (bytes per character) — 5.
- @font_height() -> u8¶
Glyph height in pixels (bits per column byte) — 8.
- @font_advance() -> u8¶
Horizontal advance per character: glyph width plus one spacing column — 6.
Single glyphs¶
- @font_get_col($char: u8, $col: u8) -> u8¶
Return one column byte of the glyph for ASCII code
$char.$colis the column index 0–4; out-of-range columns return0.
- @font_get_glyph($char: u8, $dest: ptr ram u8)¶
Copy all 5 column bytes of
$char’s glyph into$dest(which must hold at least@font_width= 5 bytes).
Sizing¶
- @font_text_cols($str: str ram) -> u16¶
Number of columns a string needs when rendered: characters × advance (6 per character). Use it to size a buffer for
@font_render.
- @font_render_capacity() -> u16¶
The column capacity of the internal buffer used by
@font_render_buf. Strings longer than this (in columns) are truncated there.
Render to a buffer¶
- @font_render($str: str ram, $dest: ptr ram u8, $max_cols: u16) -> u16¶
Render
$strinto the caller’s buffer$destas a stream of column bytes (5 glyph + 1 spacer per character). Writing stops once$max_colscolumns have been produced, so$destis never overrun. Returns the number of columns actually written.
- @font_render_buf($str: str ram, $out_cols: ptr ram u8) -> ptr ram u8¶
Convenience renderer that writes into a library-owned SRAM buffer, so you need not allocate or size anything. The produced column count is written to
*$out_colsand a pointer to the column stream is returned.The buffer is a single static region shared across calls (there is no heap on AVR), so each call overwrites the previous result — copy the bytes out if you need to keep them. Output is capped at
@font_render_capacitycolumns.
Streaming (constant memory)¶
- @font_stream($str: str ram, $sink: fn(u8))¶
Stream the column bitmap of
$strto your callback$sink, one byte at a time (5 glyph columns + 1 spacer per character). Nothing is buffered, so SRAM use is O(1) no matter how long the text is — ideal for pushing large text straight to a display.$sinkis your function of typefn(u8); pass it with&@yourfunc.
- @font_fold($str: str ram, $init: u8, $sink: fn(u8,u8)->u8) -> u8¶
Fold the column bitmap of
$strthrough your callback, threading an accumulator:$acc = sink($acc, column_byte)for every column, starting from$init. Returns the final accumulator. Pure and allocation-free — handy for a checksum or CRC over rendered text, or any custom reduction.$sinkhas typefn(u8,u8)->u8taking(acc, byte).
Example¶
Stream “Hi” straight to an SPI display, buffering nothing:
target atmega328p
import std/font
import std/spi
@to_display($b: u8) { @spi_transfer($b) } # your sink: push one column byte to the panel
@main {
@spi_init_master_raw() # bring up SPI for the display
@font_stream("Hi", &@to_display) # render "Hi", stream each column to @to_display
# Or fold the same pixels into an XOR checksum, no display needed:
ram imut $sum: u8 = @font_fold("Hi", 0, &@xor_acc) # thread each byte through @xor_acc
loop * { }
}
@xor_acc($acc: u8, $b: u8) -> u8 { return $acc ^ $b } # combine accumulator with each byte