= Use Custom Fonts
:url-fontforge: https://fontforge.github.io/en-US/
:url-roboto: https://github.com/googlefonts/roboto/releases
:conum-guard-yaml: #

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.

IMPORTANT: In order for a third-party font to work properly with Prawn (and hence Asciidoctor PDF), several modifications are required.
See xref:prepare-custom-font.adoc[] to learn how to prepare your font for use with Asciidoctor PDF.

[#select]
== 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.

WARNING: 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 {url-roboto}[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_)

[#declare]
== 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.

[,yaml,subs=attributes+]
----
font:
  catalog:
    merge: false {conum-guard-yaml} <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.

[,yaml,subs=attributes+]
----
font:
  catalog:
    merge: false {conum-guard-yaml} <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 <<configure-search-path,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:

[,yaml,subs=attributes+]
----
font:
  catalog:
    merge: false {conum-guard-yaml} <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:

[,yaml]
----
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.
****

[#configure-search-path]
== Configuring the font search path

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

 $ asciidoctor-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 --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 --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 --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 --theme basic-theme.yml -a pdf-fontsdir="uri:classloader:/path/to/fonts;GEM_FONTS_DIR" document.adoc

== Using system fonts from Microsoft Windows

You can configure Asciidoctor PDF to use the system fonts provided by Microsoft Windows.
If you decide to use these fonts without modification, you'll need to define a xref:fallback-font.adoc[fallback font].
This step is necessary since these fonts do not support all the xref:prepare-custom-font.adoc#required-characters[required characters] Asciidoctor PDF needs in order to function properly.

To retain consistent font metrics, you'll also want to use a system font as the fallback font.
Windows provides two fonts, Segoe UI Symbol [.path]_seguisym.ttf_ and Segoe UI Emoji [.path]_seguiemj.ttf_, that work well as fallback fonts to fill in the characters required by Asciidoctor PDF.
These fonts have baselines that align with other Windows system fonts better than the bundle fonts in Asciidoctor PDF, so they're more suitable as fallback fonts in this scenario.

Here's an example of how to register Times New Roman from Windows as the main font and Segoe UI Symbol from Windows as the fallback.

[,yaml]
----
font:
  catalog:
    TimesNewRoman:
      normal: times.ttf
      italic: timesi.ttf
      bold: timesbd.ttf
      bold_italic: timesbi.ttf
    SegoeUISymbol: seguisym.ttf
  fallbacks:
  - SegoeUISymbol
----

In order for Asciidoctor PDF to locate these system fonts, you'll need to configure the `pdf-fontsdir` attribute to look in the Windows font folder, which is [.path]_c:/Windows/Fonts_.
For example, you can pass the following option when invoking Asciidoctor PDF:

 -a pdf-fontsdir="c:/Windows/Fonts;GEM_FONTS_DIR"

See <<configure-search-path>> for more information about this attribute.

[#subset]
== 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 {url-fontforge}[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.
