Turtle Fonts (.font)
Turtle fonts store vector glyphs as compact command streams. All integer fields are little-endian.
The file starts with a glyph index. Each index entry stores the Unicode codepoint, the glyph advance, and an offset into the shared glyph code blob.
Glyph code is a bytecode stream of drawing commands. Each stream is terminated by an end command (0x00).
§1 Data Encoding
const CodepointAdvancePair = packed struct(u32) {
codepoint: u24, // Unicode codepoint
advance: u8, // horizontal advance
};
const GlyphIndexEntry = struct {
oap: CodepointAdvancePair,
offset: u32, // byte offset into glyph_code
};
const TurtleFontFile = struct {
magic: u32 = 0x4c2b8688,
glyph_count: u32,
glyph_index: [glyph_count]GlyphIndexEntry, // sorted by codepoint
glyph_code: [*]u8, // concatenated glyph command streams
};
§2 Glyph Code Encoding
Glyph code uses single-byte opcodes. The low nibble stores the command id and the high nibble is zero.
const CommandId = enum(u4) {
end = 0, // 0x00, terminates one glyph stream
move_rel = 1, // then (i8 dx, i8 dy)
move_abs = 2, // then (i8 x, i8 y)
line_rel = 3, // then (i8 dx, i8 dy)
line_abs = 4, // then (i8 x, i8 y)
point = 5, // no coordinates
};
const EncodedCommand = packed struct(u8) {
cmd: CommandId,
pad: u4 = 0,
};
Relative commands update the current pen position by delta. Absolute commands set the pen position directly. line_* draws from previous position to current position, and point draws a dot at the current position.
§3 Constraints
-
magicmust be0x4c2b8688. -
glyph_indexshould be sorted by increasing codepoint for binary search lookup. -
Every codepoint must fit into
u21. -
Every glyph offset is relative to the start of
glyph_code. -
Each glyph stream must contain an
endcommand byte (0x00) before end-of-file.