Fonts
compose2pdf embeds whatever fonts Compose lays the text out with — bundled Inter,
custom Font(resource)/Font(file) families, or platform system fonts — automatically.
InterFontFamily
val InterFontFamily: FontFamily
Bundled Inter font family using static (non-variable) font files.
Included fonts
| Weight | Style | File |
|---|---|---|
FontWeight.Normal |
FontStyle.Normal |
Inter-Regular.ttf |
FontWeight.Bold |
FontStyle.Normal |
Inter-Bold.ttf |
FontWeight.Normal |
FontStyle.Italic |
Inter-Italic.ttf |
FontWeight.Bold |
FontStyle.Italic |
Inter-BoldItalic.ttf |
This is the default defaultFontFamily for renderToPdf. When used, both Compose layout and PDFBox font embedding use the same font files, eliminating any rendering mismatch.
Font resolution chain
When the SVG-to-PDF converter encounters text, it resolves fonts in this order:
- Bundled fonts – Inter Regular, Bold, Italic, BoldItalic (when using
InterFontFamily) - Captured typefaces – the exact fonts Compose loaded while laying out this content. Fonts declared via
Font(resource)/Font(file)(including through theme typography) are captured here and embedded byte-exactly; they never need to be installed on the machine. - The composition’s Skia font collection – the same lookup Compose’s text shaper used, covering system fonts and glyph-fallback runs.
- Skia’s system font manager – by family name (results are verified to carry the requested family, so an unknown name can’t silently embed a substitute).
- Platform font directories – filename search:
- macOS:
/Library/Fonts/,~/Library/Fonts/,/System/Library/Fonts/ - Linux:
/usr/share/fonts/,~/.local/share/fonts/ - Windows:
C:\Windows\Fonts\
- macOS:
- PDF standard 14 – Helvetica, Times-Roman, Courier and their variants (last resort; never embedded). Substituted glyphs wider than the space the layout measured are horizontally compressed so they cannot overlap the next character, and a warning naming the unresolved family is logged.
Using system fonts
Pass null to skip the bundled fonts:
val pdf = renderToPdf(defaultFontFamily = null) {
Text("System font")
}
Custom fonts
Supply your own FontFamily:
val myFont = FontFamily(
Font(resource = "fonts/MyFont-Regular.ttf", weight = FontWeight.Normal),
Font(resource = "fonts/MyFont-Bold.ttf", weight = FontWeight.Bold),
)
val pdf = renderToPdf(defaultFontFamily = myFont) {
Text("Custom font!")
}
Font files should be in src/main/resources/. The font does not need to be installed
on the machine — the loaded data itself is subset and embedded, which makes
resource-loaded fonts the most reliable choice for headless server rendering.
Variable fonts embed at their default instance only. PDFBox cannot instantiate
variable-font axes. A variable font’s default (regular) instance embeds correctly,
but instances styled away from the default on wght/wdth/slnt/ital — e.g.
bold of a variable-only family — fall back to a compressed standard font. The
filesystem search additionally skips files with an fvar table. Prefer static
.ttf/.otf files per weight.
See also
- Usage: Text and Fonts – Text styling and font configuration
- renderToPdf – The
defaultFontFamilyparameter