Commit Graph
1 Commits
Author SHA1 Message Date
JMR-devandClaude Opus 4.8 071034de65 feat(compose): add a font family picker with bundled open-source fonts
Bundle four SIL OFL 1.1 fonts in res/font (no build-time downloads, F-Droid
safe): Inter, Lora, and JetBrains Mono as weight-variable TTFs plus a static
Merriweather Regular cut (its variable font is 4.4 MB) — ~1.5 MB total. Each
family's OFL license text is committed under THIRD_PARTY_LICENSES/, and *.ttf/
*.otf are marked binary in .gitattributes so the bytes commit intact.

Add FontRegistry: display name <-> email-safe CSS stack <-> Compose FontFamily,
with three generic Sans/Serif/Monospace entries that need no bundled file. Each
bundled stack names the family first then falls back to a generic (e.g.
'Lora', Georgia, serif), so a recipient whose client lacks the face still gets
a sensible one. resolveFontFamily maps a stored CSS stack back to a FontFamily
for in-editor rendering, and is now passed into RichTextBodyField from
ComposeScreen so styled runs actually render in their font.

Add FontPicker (ui/compose/format): a toolbar dropdown applying
RichStyle.FontFamily(css) via the generalized applyStyle/clearStyle path, with a
leading "Default" entry that clears it; each menu entry previews itself in its
own face. Appended at the END of the toolbar (with the size/alignment controls),
after the block and link buttons — per the #73/#76 lesson, nothing may shift the
bullet/numbered/quote buttons that the compose E2E taps without scrolling.

Tests: FontRegistryTest (JVM) proves every CSS stack survives an html
round-trip, the resolver maps known/unknown stacks, and bundled stacks end in a
generic fallback; a compile-only FontPickerTest drives the picker in isolation
(default label, current-font label, menu lists every font, picking reports the
css / Default clears).

Closes #72

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 00:31:09 -05:00