How font resolution works

EggPdf resolves fonts in this order:

  1. @font-face declarations in CSS — from http(s) URLs (Google Fonts and other CDNs), data: URIs, or files (relative paths resolve against basePath)
  2. System-installed TrueType/OpenType fonts matched by name
  3. Built-in PDF standard fonts: Helvetica, Times, Courier

Remote <link rel="stylesheet"> tags are fetched too, so a plain Google Fonts <link> works out of the box — every declared weight (300–900) selects its own face, and codepoints missing from the chosen font (symbols like ⚠) fall back to a system symbol font automatically.

Any matched TrueType font is automatically subset — only the glyphs actually used in the document are embedded, keeping PDF size small.

CSS font-family

Use any installed font name in CSS:

body { font-family: Arial, sans-serif; }
h1   { font-family: 'Georgia', serif; }
code { font-family: 'Courier New', monospace; }

If the named font is installed on the machine running EggPdf, it will be found, subset, and embedded. If not found, EggPdf falls back to the next font in the stack, and ultimately to Helvetica.

Built-in PDF fonts

These 14 fonts are always available without embedding — zero overhead:

  • Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique
  • Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic
  • Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique
  • Symbol, ZapfDingbats

These are the 14 standard PDF fonts defined in the PDF specification. Every PDF viewer renders them without needing a font file embedded in the document.

Webfonts — Google Fonts and remote URLs

Reference a hosted stylesheet exactly like on the web — EggPdf fetches the CSS, downloads the declared faces, and embeds subsets with the document's real glyphs (full Unicode, including Vietnamese and other extended Latin):

<link href="https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:wght@300;400;600;700;800" rel="stylesheet">
<style>
body { font-family: 'Be Vietnam Pro', Arial, sans-serif; }
</style>

Intermediate weights (font-weight: 500/600/800…) embed the matching variant instead of snapping to regular/bold, and text is measured with the real font metrics so line breaks match the browser's.

@font-face — load from file

Load fonts that aren't installed system-wide by providing a file path in @font-face and setting basePath when calling the API:

<style>
@font-face {
    font-family: 'Inter';
    src: url('fonts/Inter-Regular.ttf');
    font-weight: 400;
}
@font-face {
    font-family: 'Inter';
    src: url('fonts/Inter-Bold.ttf');
    font-weight: 700;
}
body { font-family: 'Inter', Helvetica, sans-serif; }
</style>

Then render with basePath:

byte[] pdf = HtmlToPdf.Render(html, basePath: "./assets/");

The url('fonts/Inter-Regular.ttf') path resolves relative to basePath. Use absolute paths in src: url(...) if you prefer not to set basePath.

Weight and style

Standard CSS values are supported: font-weight: 400, font-weight: 700, font-weight: bold, font-style: italic, font-style: normal. EggPdf selects the best matching font file from the system — for example, Arial-Bold.ttf for font-family: Arial; font-weight: bold.

When an exact weight/style variant is not found, EggPdf applies the CSS font-weight matching algorithm to pick the closest available variant rather than substituting a different typeface.