feat(theme): user-selectable custom fonts (#19) #55

Merged
makiolaj merged 3 commits from feat/custom-fonts into release/v2.13.0 2026-07-02 08:40:49 +00:00
Owner

Per-role custom font picker in Settings → Appearance (M3 brand/plain roles): system default, bundled OFL fonts (Atkinson Hyperlegible, Lora, JetBrains Mono), or a user-loaded .ttf/.otf via SAF (validated by CustomFontStore, degrades to system font on failure). Font size & colour intentionally out of scope per the issue thread.

The document picker is restricted to font MIME types so only fonts are selectable.

Closes #19. On-device verified (standard fonts + file-loaded font path).

🤖 Generated with Claude Code

Per-role custom font picker in Settings → Appearance (M3 brand/plain roles): system default, bundled OFL fonts (Atkinson Hyperlegible, Lora, JetBrains Mono), or a user-loaded .ttf/.otf via SAF (validated by CustomFontStore, degrades to system font on failure). Font size & colour intentionally out of scope per the issue thread. The document picker is restricted to font MIME types so only fonts are selectable. Closes #19. On-device verified (standard fonts + file-loaded font path). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
makiolaj added 3 commits 2026-07-02 08:28:18 +00:00
Add a per-role font picker in Appearance settings. The two Material
typeface roles can be set independently: brand (display/headline) and
plain (title/body/label). Each can be the system default, a bundled
font (Atkinson Hyperlegible, Lora, JetBrains Mono), or a .ttf/.otf the
user loads from the device. The choice rebuilds the app-wide typography
in MainActivity; a null/"system" choice leaves the Material default.

Per the issue discussion the font-size and font-colour parts were
dropped — Android's accessibility font scaling and the dynamic-colour
theme already cover them.

Custom files are copied into app-private storage and validated with
android.graphics.fonts.Font.Builder before replacing the previous one,
so a bad pick can't wedge global text rendering; a missing/unreadable
file degrades to the system font. Each bundled font is previewed in its
own face in the picker. OFL licences + attribution vendored under
licenses/fonts/.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts:
#	app/src/main/java/de/jeanlucmakiola/calendula/data/prefs/SettingsPrefs.kt
#	app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/SettingsViewModel.kt
feat(theme): filter custom-font picker to font MIME types
All checks were successful
Translations / check (pull_request) Successful in 29s
CI / ci (pull_request) Successful in 5m5s
efca0c86c4
Restrict the "Choose file…" document picker to font MIME types
(font/ttf, font/otf, font/sfnt, font/collection plus legacy
application/* font aliases) instead of */*, so only fonts are
selectable. CustomFontStore's Font.Builder validation still guards
anything a provider mislabels.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
makiolaj merged commit 262b2b8273 into release/v2.13.0 2026-07-02 08:40:49 +00:00
makiolaj deleted branch feat/custom-fonts 2026-07-02 08:40:50 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: makiolaj/calendula#55