Providing font files maintains uniformity of the menus across varying browsers and operating systems. The standard pfodWeb build
embeds Roboto's Latin and Latin Extended fonts. Extra off-line locally loaded fonts can be added to the extraFonts
directory without needing to recompile pfodWeb.
This document describes how to add other fonts without having to rebuild pfodWeb.html.
pfodWeb.html embeds Roboto's Latin and Latin Extended
subsets directly as base64 data:, because almost every pfodWeb screen needs them and
they're always wanted as soon as the page loads. References to every other font needed
(Cyrillic, Greek, etc.) are moved out into a separate, plain CSS file —
extraFonts/pfodweb-extra-fonts.css — referenced via an ordinary
<link rel="stylesheet href="extraFonts/pfodweb-extra-fonts.css"> tag rather than inlined.
This split matters for two reasons:
pfodWeb.html would
permanently add hundreds of KB to the pfodWeb.html file that's loaded on every page load, for scripts most
devices never display.@font-face rule in
pfodweb-extra-fonts.css declares a unicode-range. The browser only loads the locally hosted
woff2 file the first time a character inside that range actually needs to be painted. A sketch
that never sends Cyrillic text never triggers a load of the Cyrillic woff2 files at all.extraFonts/ sits next to pfodWeb.html and pfodProxy.exe in every
build output (Windows, Linux, and the Contents/MacOS folder of the macOS .app) — not embedded inside
pfodWeb.html
font-family: 'Roboto' so pfodWeb's existing font stacks pick it up automatically.extraFonts/.@font-face rule to pfodweb-extra-fonts.css following the existing
pattern — same font-family: 'Roboto', correct unicode-range, and a normal +
italic pair if both are available. The filename itself is just a local reference you choose; it
doesn't need to follow the Roboto-<Style>-<Subset> convention used by the real
Roboto subsets — name it after whatever font you actually sourced the woff2 from, since it's the
font-family: 'Roboto' label (not the filename) that makes pfodWeb's font stacks pick it up:
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 100 900;
font-display: swap;
src: url('NotoSansThai-Normal.woff2') format('woff2');
unicode-range: U+0E01-0E5B;
}
Four extra scripts are currently included in the /extraFonts directory,
each as a separate woff2 per style (normal/italic).
If you don't need these fonts you can just delete the /extraFonts directory
| Subset | Files | unicode-range covers |
|---|---|---|
| Cyrillic | Roboto-Normal-Cyrillic.woff2, Roboto-Italic-Cyrillic.woff2 |
Russian and related Cyrillic-script languages |
| Cyrillic Extended | Roboto-Normal-CyrillicExt.woff2, Roboto-Italic-CyrillicExt.woff2 |
Additional Cyrillic letters used by some minority languages |
| Greek | Roboto-Normal-Greek.woff2, Roboto-Italic-Greek.woff2 |
Modern Greek |
| Greek Extended | Roboto-Normal-GreekExt.woff2, Roboto-Italic-GreekExt.woff2 |
Polytonic Greek (accented historical text) |
pfodWeb.html attempts to load the locally hosted extraFonts/pfodweb-extra-fonts.css stylesheet.
The extraFonts/pfodweb-extra-fonts.css and fonts are entirely optional. If the .css or one of its
woff2 files is missing, the local load attempt returns 404 not found, and the pfodWeb continues to work just fine — text
in that script falls back to Arial / the OS system font instead of Roboto. Nothing in pfodWeb depends on
this local directory being present.
Every rule inside that file uses font-family: 'Roboto' — the same family name
used everywhere else in pfodWeb. Because each rule's unicode-range only covers its own
script, the browser layers all of them (the two inlined Latin/LatinExt faces plus whichever extraFonts
faces are present) into one logical "Roboto" that automatically picks the right face per character. No
JS or font-stack changes are needed elsewhere in pfodWeb to support a new script — once a matching
@font-face rule exists in extraFonts/pfodweb-extra-fonts.css,
any text containing those characters just renders correctly.
Both font-weight: 100 900 (a variable-font weight range covering normal and
bold in one file) and normal/italic styles are declared per subset, mirroring
the four faces already inlined in pfodCommon.css.
extraFonts/pfodweb-extra-fonts.css (and then the
individual .woff2 files that CSS references via relative url(...)), pfodProxy and ESP_PicoW_pfodWebServer
(in the micro self-hosted case) has no specific route for /extraFonts/..., so the request falls through to a generic
fallback handler that serves static files. That handler:
pfodProxy executable itself
lives in (std::env::current_exe()'s parent), not the current working directory and rejects any ..
path segments (basic directory-traversal guard).Content-Type, maps .woff2 → font/woff2,
.css → text/css, etc. OR returns a plain 404 if the file's missing.pfodWeb_src/fonts/fetch-roboto.js only fetches the two subsets inlined in
pfodWeb.html (Latin, Latin Extended) by default — Cyrillic, Cyrillic Extended, Greek, and
Greek Extended are commented out of its KEEP_SUBSETS list, since they no longer need to be
embedded. To pull a fresh copy of one of the extraFonts subsets:
KEEP_SUBSETS near the top of
fetch-roboto.js.node pfodWeb_src/fonts/fetch-roboto.js. It writes the new woff2 file(s) into
pfodWeb_src/fonts/ (not extraFonts/)./extraFonts/ by hand, then re-comment the
line(s) you uncommented in step 1.