UOF Font Format
UOF is the uniOS runtime font format. It stores preprocessed bitmap font data (coverage atlas + metrics + kerning) for the userspace GUI library, so no desktop font parsing happens at runtime.
Identity
- Extension:
.uof - Magic:
0x4E464F55(UOFN, little-endian) - Version: 2
- Runtime users: libgui text rendering (apps, menubar, dock, window manager, terminal)
File Layout
typedef struct { // 54 bytes, packed, little-endian
uint32_t magic; // 0x4E464F55
uint16_t version; // 2
uint16_t flags; // bit0: horizontally oversampled atlas
uint16_t pixel_size;
uint16_t oversample_x; // subcolumns per output pixel (4 or 1)
uint16_t atlas_width; // output pixels; row stride = width * oversample_x
uint16_t atlas_height;
int16_t ascent; // px
int16_t descent; // px
int16_t line_gap; // px
uint32_t glyph_count;
uint32_t kerning_count; // exception pairs
uint16_t matrix_c1; // kern class matrix dims (row = left glyph class)
uint16_t matrix_c2;
uint32_t fallback_index;
uint32_t glyph_offset;
uint32_t kerning_offset;
uint32_t matrix_offset;
uint32_t atlas_offset; // RLE stream runs to end of file
} UofHeader2;
typedef struct { // 20 bytes, sorted by codepoint
uint32_t codepoint;
uint16_t atlas_x; // subcolumn units
uint16_t atlas_y;
uint16_t width; // output px (oversampled: includes 1 px pad per side)
uint16_t height;
int16_t bearing_x26; // 26.6 fixed point
int16_t bearing_y; // px
int16_t advance_x26; // 26.6 fixed point
uint8_t kern_left; // class id when this glyph is the left pair member
uint8_t kern_right; // class id when this glyph is the right pair member
} UofGlyph2;
typedef struct { // 10 bytes, sorted by (left, right), unique
uint32_t left_cp;
uint32_t right_cp;
int16_t value; // 26.6, additive with the class matrix
} UofKern2;
Sections follow in order: glyph table, kerning exceptions, the (matrix_c1+1) x (matrix_c2+1) row-major int16 class matrix (26.6 values), then the atlas.
The atlas is 8-bit coverage, RLE-compressed as (run_length-1, value) byte pairs (max run 256) expanding to exactly atlas_width * oversample_x * atlas_height bytes. Loaders validate every offset, count and rect before trusting the file, and reject anything that is not version 2.
Rasterization model
- Glyphs are rendered from the source outlines at 4x pixel size with hinting disabled and box-filtered down vertically; horizontally, UI fonts keep full 4x resolution (oversampling) so the runtime can position glyphs on true subpixel positions.
- Runtime subpixel positioning: the pen accumulates in 26.6 fixed point; each glyph's phase (fractional pen position, quantized to 1/16 px) selects a 5-tap FIR filter over the subcolumns of its output pixels. Mono fonts skip this (integer grid, single sample per pixel).
- Kerning comes from GPOS pair positioning, flattened into the class matrix plus additive exception pairs; the runtime looks up
matrix[left->kern_left][right->kern_right] + exception(left_cp, right_cp)between adjacent glyphs. - Advances and kerning are 26.6, so spacing matches the scalable font metrics instead of rounded integers.
- The 8-bit coverage is linear pixel area. The runtime blitter blends in linear light with polarity-aware coverage shaping that is symmetric by construction: light-on-dark coverage is shaped with gamma 2.0, and dark-on-light coverage is shaped so the stored pixel is the mirror of the light-on-dark ramp (for pure black/white pairs,
v_dark + v_light = 255at every coverage level). Transparent-background draws resolve polarity per pixel from the destination under the glyph; seesrc/usr/libgui/font.cpp.
Runtime Use
At startup the GUI picks a pixel size from the framebuffer dimensions (11-15, clamped to 11..18) and loads the nearest size of each family from /usr/share/fonts/:
| Prefix | Family | Use | Oversample |
|---|---|---|---|
inter-ui |
Inter UI (regular) | Default UI text | 4 |
inter-title |
Inter UI (semibold) | Headings and emphasis | 4 |
geist-mono |
Geist Mono | Terminal and code | 1 (integer grid) |
Filenames follow <prefix>-<size>.uof. Text strings are decoded as UTF-8 (invalid bytes render the fallback glyph), and codepoints beyond the charset also render the fallback glyph. Measurement, truncation and drawing share one walker (src/usr/libgui/font_internal.h), so laid-out width always matches drawn width.
Generation
Font sources live under assets/fonts_src/. Regenerate all families and sizes (8-18):
pip install freetype-py fonttools # cross-platform; wheels bundle FreeType
python3 tools/uof_convert.py --all
Single file: python3 tools/uof_convert.py --font <src> --output <out>.uof --size <n> --charset ui|mono. The ui charset covers printable ASCII, Latin-1, Latin Extended-A, Greek, Cyrillic and typographic punctuation; the mono charset covers ASCII, common Latin-1 punctuation/symbols and the box-drawing block. Codepoints the font lacks are skipped silently.
The tool self-validates every emitted file (re-parses it, checks bounds and sort order). tools/uof_preview.py renders sample text from a .uof with the same math as the runtime for host-side visual checks:
python3 tools/uof_preview.py rootfs/usr/share/fonts/inter-ui-13.uof --scale 4
Generated font files are committed; keep binaries and sources in sync in the same change. UOF is not a general desktop font format — it exists to avoid parsing full desktop font formats inside the GUI runtime.