Skip to content

Bundle the site's typefaces in the Android app - #69

Merged
octopranav merged 1 commit into
mainfrom
bundled-typefaces
Sep 24, 2026
Merged

octopranav merged 1 commit into
mainfrom
bundled-typefaces

Conversation

@octopranav

Copy link
Copy Markdown
Owner

What changes

  • The app has been set in the device's serif, sans and monospace faces as stand-ins. It now carries the site's three typefaces, each in its role:

    • Bitter for display
    • IBM Plex Sans for body text
    • IBM Plex Mono for codes and labels
  • designsystem/src/main/res/font/ holds five files from the google/fonts repository, byte for byte:

    File Upstream
    bitter.ttf ofl/bitter/Bitter[wght].ttf (variable)
    ibm_plex_sans.ttf ofl/ibmplexsans/IBMPlexSans[wdth,wght].ttf (variable)
    ibm_plex_mono_regular.ttf ofl/ibmplexmono/IBMPlexMono-Regular.ttf
    ibm_plex_mono_medium.ttf ofl/ibmplexmono/IBMPlexMono-Medium.ttf
    ibm_plex_mono_semibold.ttf ofl/ibmplexmono/IBMPlexMono-SemiBold.ttf
  • Both OFL licence texts ship in the app's assets, as the licence requires.

  • Theme.kt points each role at its family. Every weight the scale uses is set on the variable fonts' weight axis.

  • audit/fonts.py pins each font to the git hash of its upstream file. It also requires each licence to be present and still name its reserved font name. It comes with tests and a CI step.

Why unmodified

Both licences reserve the name: "Bitter Pro" for Bitter, "Plex" for IBM Plex. A subset or a merged copy of the site's WOFF2 files would be a modified version still carrying the reserved name. So the originals are bundled, and the audit keeps them original: a font saved again by a tool renders the same and breaks the licence silently.

Checks

  • Every downloaded file matched the git hash the GitHub contents API reports for it upstream. The staged objects carry the same hashes.
  • python audit/fonts.py passes, and the audit tests pass: 51 in all, 8 new. The new tests cover a changed byte, a missing font, an unpinned font, a missing licence, and a licence without its reserved name.
  • Emulator: Bitter semibold in the emergency card's title, Plex Sans in body text, Plex Mono in codes with its dotted zero.
  • The explicit axis setting matters. Built without it, Bitter drew "Where I am" in its thinnest master, with about a sixth of the ink of the semibold.
  • The APK grows by about 0.6 MB compressed (1.3 MB installed).

The app was set in the device's serif, sans and monospace faces as stand-ins.
It now carries the site's three, Bitter, IBM Plex Sans and IBM Plex Mono,
under the Open Font Licence, with each licence in the app's assets.

Both licences reserve the font's name, so a subset or converted copy could
not ship under it. The files are the designers' own as published in the
google/fonts repository, unmodified, and audit/fonts.py pins each to the git
hash of its upstream file, with a CI step and tests that watch it fail on a
changed byte, a missing or unpinned font and a missing licence.

Bitter and Plex Sans are variable fonts. Each weight is set on the weight
axis explicitly: asked only for a weight, Compose draws Bitter in its
default master, which is its thinnest. The fonts add about 0.6 MB to the
download.
@octopranav
octopranav merged commit 0f5ea14 into main Sep 24, 2026
21 checks passed
@octopranav
octopranav deleted the bundled-typefaces branch September 24, 2026 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant