Fonts & non-Latin scripts
Picking fonts the path renderer can find — and what to expect for Arabic, Devanagari, CJK, emoji.
Domotion's path renderer needs to find a real font file on disk to extract glyph outlines from. This page covers how the lookup works, how to handle web fonts, and what to expect for non-Latin scripts.
Where Domotion looks for fonts
Path mode reads outlines using fontkit. The lookup table mapping
font-family values to font files on disk is tuned for macOS
system fonts: SF Pro, SF Mono, New York, Helvetica Neue, etc.
- macOS: the bundled mapping covers the standard system fonts. Author your demos in those families and the path renderer will "just work" with no font config.
- Linux / Windows: the mapping table is much sparser. The
capture still works, but path-mode glyphs whose font isn't found fall
back to native SVG
<text>with the captured CSS font properties, which means the result depends on whatever the rendering browser has installed.
If you need cross-platform path rendering, do your captures on macOS (or in a CI runner with macOS images) and ship the resulting SVGs. The glyph outlines are baked in — Linux and Windows viewers will see them correctly even though they lack the source fonts.
Picking a font that captures cleanly
Three rules of thumb:
- Stay in the system stack when you can.
-apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif— the resolved system font is one Domotion knows. - If you use a web font, wait for it. Always
await page.evaluate(() => document.fonts.ready)before capturing — otherwise you'll capture the fallback typeface and the layout will be subtly wrong. - Avoid rare display faces. A handful of decorative fonts use OpenType features Domotion doesn't shape (variable-axis interpolation along axes other than weight, certain SVG-in-OpenType color tables); those fall back to raster.
Non-Latin scripts
Domotion handles complex scripts by detecting fallback-font runs (Chromium
has already chosen a different font for them) and shaping each run as a unit
with font.layout(runText). That means contextual joining,
ligature clusters, and mark-on-base positioning all survive — Latin,
Cyrillic, Greek, Arabic (initial / medial / final / isolated forms; bidi via
bidi-js), Hebrew, Devanagari (cluster reordering, ligatures),
Thai (mark-on-base), and CJK (Han, Hiragana, Katakana, Hangul; GPOS positioning)
all round-trip. Other complex scripts (Tibetan, Khmer, Burmese) flow through
the same pipeline.
Mixed-script lines like "Hello مرحبا नमस्ते" work — each contiguous fallback run is shaped as a unit, and the per-character anchor offsets keep the runs aligned with what Chromium painted.
Emoji and color-bitmap glyphs are the exception: each unique glyph is
screenshotted once and embedded as a base64 PNG, then referenced via
<use> for dedup.
Verified shaping accuracy
fontkit's shaping is within ~1% of HarfBuzz on Arabic and Thai, and pixel-identical on Devanagari and CJK ideographs at typical body sizes. The test suite includes one fixture per script that diffs the SVG render against the Chromium PNG — the path renderer is within Domotion's overall 3% pixel-diff threshold for all of them.
Web fonts
If you load a web font via <link rel="stylesheet" href="...">
or @import url(...):
- Wait for
document.fonts.readybefore capturing. - If the web font isn't in Domotion's bundled mapping table (most aren't),
the path renderer will fall back to native
<text>with the captured CSS font-family. The text will still render, just not as embedded outlines. - For self-contained output with a custom font, you can pre-process the
SVG and inject a base64-embedded
@font-face. That's outside Domotion's current public surface; file an issue if this matters for your use case.
Decoration handling
Underlines and strike-throughs are positioned using the font's own
post.underlinePosition / OS/2.yStrikeoutPosition
tables, not as a fraction of font size. This matches Chromium and avoids the
slight "underline too low" effect you sometimes see in rasterized SVG
output.
See also
- Text rendering — the behind-the-scenes story.
- CSS support: text & fonts