Custom Fonts

The limited character set of WINANSI, or the plain look of the built-in or bundled fonts, may motivate you to incorporate your own fonts. Custom fonts can enhance the look of your PDF theme substantially.

In order for a third-party font to work properly with Prawn (and hence Asciidoctor PDF), several modifications are required. See Prepare a Custom Font to learn how to prepare your font for use with Asciidoctor PDF.

Selecting your font

To start, find the TTF file collection for the font you want to use. A collection typically consists of four font styles:

  • normal

  • italic

  • bold

  • bold_italic

You’ll need all four variants to support AsciiDoc content properly (unless the font only has a single variant). If you do not register the font correctly, the converter may crash or revert to the fallback font, depending on how the theme is configured. If one of the variants is missing from your collection, you can simply reuse the normal / single variant in its place.

Asciidoctor PDF cannot italicize a font dynamically like a browser can, so the italic styles are required to italicize text.

Once you’ve obtained the TTF (or OTF) files, put them in the directory inside your project where you want to store the fonts. It’s recommended that you name them consistently so it’s easier to type the names in the theme file.

Let’s assume the name of the font is Roboto. Rename the files as follows:

  • roboto-normal.ttf (originally Roboto-Regular.ttf)

  • roboto-italic.ttf (originally Roboto-Italic.ttf)

  • roboto-bold.ttf (originally Roboto-Bold.ttf)

  • roboto-bold_italic.ttf (originally Roboto-BoldItalic.ttf)

Declaring your font

Next, declare the font under the font-catalog key at the top of your theme file. Assign each font a unique key (e.g., Roboto) and specify the path to each of the four font styles under that key.

font:
  catalog:
    merge: false (1)
    Roboto:
      normal: roboto-normal.ttf
      italic: roboto-italic.ttf
      bold: roboto-bold.ttf
      bold_italic: roboto-bold_italic.ttf
1 Set value to true to merge catalog with theme you’re extending.

If you use this form, you must declare all four variants. If you’re missing the font file for one of the variants, configure it to use the same font file as the normal variant.

If your font only has a single variant, assign the font path to the font key directly.

font:
  catalog:
    merge: false (1)
    VLGothic: vlgothic.ttf
1 Set value to true to merge catalog with theme you’re extending.

Font paths can be absolute or relative. Absolute paths are used as is. Relative font paths are resolved from the font search path. You can also use the GEM_FONTS_DIR keyword to refer to the location of the bundled fonts.

You can add any number of fonts to the catalog. Each font must be assigned a unique key, as shown here:

font:
  catalog:
    merge: false (1)
    Roboto:
      normal: roboto-normal.ttf
      italic: roboto-italic.ttf
      bold: roboto-bold.ttf
      bold_italic: roboto-bold_italic.ttf
    Roboto Light:
      normal: roboto-light-normal.ttf
      italic: roboto-light-italic.ttf
      bold: roboto-light-bold.ttf
      bold_italic: roboto-light-bold_italic.ttf
1 Set value to true to merge catalog with theme you’re extending.

You can use the key that you assign to the font in the font catalog anywhere the font-family property is accepted in the theme file. For example, to use the Roboto font for all headings (section titles and discrete headings), use:

heading:
  font-family: Roboto
  font-style: bold

The font name and font style are used to locate an entry in the font catalog.

About Fonts in SVGs

Fonts defined for text in SVGs will be mapped to the font catalog from your theme. So if you have an SVG that requires a specific font, you’ll need to declare that font in the font catalog in your theme.

We recommend that you match the font key in your theme file to the name of the font seen by the operating system. This will allow you to use the same font names (aka families) in both your graphics program and Asciidoctor PDF, thus making them portable.

Configuring the font search path

When you execute Asciidoctor PDF, specify the directory where the fonts reside using the pdf-fontsdir attribute:

$ asciidoctor-pdf -a pdf-theme=basic-theme.yml -a pdf-fontsdir=path/to/fonts document.adoc

You can specify multiple directories by separating the paths with either a comma (,):

$ asciidoctor-pdf -a pdf-theme=basic-theme.yml -a pdf-fontsdir=path/to/fonts,path/to/more-fonts document.adoc

or a semicolon (;) (which requires enclosing the combined value in double quotes to escape the delimiter from the shell):

$ asciidoctor-pdf -a pdf-theme=basic-theme.yml -a pdf-fontsdir="path/to/fonts;path/to/more-fonts" document.adoc

To include the location of the bundled fonts in the search, include the GEM_FONTS_DIR token in the list:

$ asciidoctor-pdf -a pdf-theme=basic-theme.yml -a pdf-fontsdir="path/to/fonts;GEM_FONTS_DIR" document.adoc

When running Asciidoctor PDF on the JVM (perhaps using AsciidoctorJ PDF), you can refer to a directory inside any JAR file on the classpath by prefixing the path with uri:classloader::

$ asciidoctorj -b pdf -a pdf-theme=basic-theme.yml -a pdf-fontsdir="uri:classloader:/path/to/fonts;GEM_FONTS_DIR" document.adoc

Subsetting your font

When Asciidoctor PDF creates the PDF, it only embeds the glyphs from the font that are needed to render the characters present in the document. Effectively, it subsets the font. While that saves space taken up by the generated PDF, you may still be storing the full font in your source repository.

To minimize the size of the source font, you can use FontForge to subset the font ahead of time. Subsetting a font means removing glyphs you don’t plan to use. Doing so is not a requirement, simply a personal preference.