Add a Glyph Script
A glyph script restyles the keycap letter and digit legends in an alternative script — Tengwar, runes, Braille and friends (see Glyph Scripts for the user-facing side). This HowTo adds a new one.
The best part: since firmware protocol v10 the glyph-script index is open-ended. The firmware accepts any script byte and simply draws the normal legend for one it doesn’t know, so adding a script does not bump the protocol — you add an enum value, a codepoint block, a font, and a host label. A keyboard that lacks the new font degrades gracefully to Latin.
All firmware paths are relative to keyboards/polykybd/ in the
qmk_firmware fork; the glyphs ship in
the fantasy font-pack bundle (see Font Packs & Resources).
How it works
Each script’s letters and digits are rendered into a dense private codepoint block (0x40
apart: Tengwar 0xE800, Runes 0xE840, …). A table in poly_keymap.c (glyph_script_blocks[],
indexed by the poly_glyph_script enum) maps a script to its block base; letters a..z land at
base+0..25, and scripts with their own numerals put digits at base+26..35. The render hook in
render_key() swaps the legend for the block glyph when a script is active.
Steps
-
Pick a license-clean font. The glyph shapes must be embeddable and redistributable (OFL, Apache, CC0, permissive). Keep user-facing script names generic where a script is a trademark, even though the fonts themselves are fine to embed. Add the source to the font downloader (
fonts/dl-fonts.sh). -
Add the enum value. Append to
enum poly_glyph_scriptinstate.h— it is append-only and byte-identical to the host’sGlyphScriptenum. Add a matching row toglyph_script_blocks[]inpoly_keymap.cwith the next free 0x40-spaced block base. -
Generate the font into its block. Add a
fonts.yamlentry that emits the font at the new PUA block using fontconvert’s sequence remap, soa..z(and digits, if the script has them) land atbase+0... Regenerate the headers, then rebuild thefantasybundle and bump itscontent_versionso the host re-flashes it on connect. -
Wire the host. In PolyKybdHost: add the same value to the
GlyphScriptenum (command_ids.py) and a label toGLYPH_SCRIPT_LABELS(host.py). That automatically adds it to the tray Glyph Script submenu and thepolyctl glyph-script <name>choices — see the Command Line page. -
Reship the bundle. Copy the regenerated
fantasy.plyfintopolyhost/res/fontpack/and updatebundles.jsonwith the new size, hash and version so the host ships the new glyphs and re-flashes them on the next connect. If the category headers are already committed you don’t even needfontconvert— the bundle derives from them deterministically. -
Build and test. Compile the firmware and select the new script from the tray menu or
polyctl. With thefantasybundle flashed the legends switch; without it, they stay Latin. The test rig has amin_protocol-gated round-trip test you can extend.
See Contributing for how to open the pull requests, and the
HID Protocol Reference for the GLYPH_SCRIPT command.