Font not found: could not substitute 'CustomFont'This warning means a font referenced in the PDF is not embedded and cannot be found on the system. The renderer falls back to a substitute font, producing garbled text, character replacement, or incorrect layout. The fix is to embed all required fonts before saving.
The PDF references fonts by name but does not include the font data. When the document is rendered on a system that does not have those fonts installed, the renderer must substitute a different font. Substitutes often have different metrics, leading to text overflow, layout shifts, and visual differences.
PDFs created on a developer's machine may reference fonts that are installed locally (e.g. a commercial typeface or a system font unique to macOS or Windows). On a Linux server these fonts are absent, causing the substitution warning.
Font subsetting reduces file size by including only the glyphs actually used in the document. If the PDF is later edited to add new characters that were not in the original subset, those glyphs are missing from the embedded font and cannot be rendered.
Use PDFluent's embed_all_fonts() before calling save(). This walks every page and text object, finds the referenced fonts, and embeds the full font data into the PDF. The resulting file renders identically on any system.
use pdfluent::PdfDocument;
let mut doc = PdfDocument::open("with-missing-fonts.pdf")?;
// Embed all referenced fonts into the document
doc.embed_all_fonts()?;
doc.save("with-embedded-fonts.pdf")?;For new documents, embed a subset of each font containing only the glyphs needed. This keeps file size reasonable while ensuring the document renders correctly everywhere.
use pdfluent::{PdfDocument, FontSubset};
let mut doc = Document::new();
let font = FontSubset::from_file("MyFont.ttf")?;
let mut page = doc.add_page((595.0, 842.0));
page.set_font(&font, 12.0);
page.draw_text(50.0, 750.0, "Hello, world!")?;
// Subset is embedded automatically on save
doc.save("output.pdf")?;In a pipeline that receives PDFs from external sources, check for missing fonts before passing documents to a renderer. This lets you embed fonts proactively or return a helpful error to the caller.
use pdfluent::PdfDocument;
let doc = PdfDocument::open("incoming.pdf")?;
let missing = doc.find_missing_fonts()?;
if !missing.is_empty() {
eprintln!("Missing fonts: {:?}", missing);
// Optionally embed system fonts as substitutes:
// doc.substitute_missing_fonts(&FontDirectory::system())?;
}