How to embed fonts - JayPanoz/Soma GitHub Wiki

Once again, we must be very careful or else we will disable the typeface setting (user) in an awful lot of Reading Systems.

Important notes

  • Fonts must be embedded: you can’t use fonts from a remote server e.g. Google webfonts or Typekit, they have to be local.
  • check the typeface licence: ePub/Kindle embedding requires a specific eBook licence that isn’t necessarily available for the typeface you want to use. In any case, ePub/Kindle licence ≠ PDF licence ≠ web licence.
  • test rendering on a significant number of devices: we must deal with so many display (SD & HD, eInk & LCD) and rendering technology (yeah, RMSDK’s got a specific one for ePub 2) that finding a bulletproof typeface can prove quite difficult. There can be nasty bugs, especially with some free fonts, and it is better to, at least, check your typeface in one eInk Reader, Adobe Digital Editions (desktop), iBooks iOS and some Kindle eInk eReader.
  • You’ll probably have to subset and obfuscate the commercial fonts you’ve licensed: there is software that can help you with the subset (e.g. FontPrep on Mac, FontForge, &c.), the obfuscation has to use the IDPF algorithm—as far as I can tell, only Sigil lets you do that in one click.
  • Don’t use dingbats fonts which make use of the alphabet: the user changes the typeface and all of a sudden, your fancy asterism is displayed as a “q”. You don’t want that to happen.

Why embed fonts?

Reading Systems usually ship with a collection of fonts, some even commissioned specific typefaces (e.g. Google → Literata and Kindle → Bookerly) so why embed fonts after all?

As a matter of fact there are many cases in which you don’t have the choice:

  • your eBook contains code examples? Well, some Reading Systems don’t offer a monospace font by default, your code will be displayed using the default typeface (a serif or a sans);
  • your eBook contains passages which must be visually differentiated? Sure you could typeset your manuscript letter using a sans-serif from Reading Systems’ collections but, well, that would suck;
  • you want fancy headings to add some style? There is nothing wrong with that, especially when your headings are just “Chapter 1”, “Chapter 2”, &c.;
  • you need symbols, greek or math? You’d better embed a font since you can only count on ± Unicode 2.0 support with default fonts.

Font embedding is kind of critical but ePub being ePub, it’s not as easy as dragging and dropping files in a folder. So let’s see how to do that properly.

Manifest fonts

Here’s the thing: all files in your ePub must be listed in the <manifest> of the file with the .opf extension—that can be “content.opf” or “package.opf” or “book.opf”, &c. If any file is not, then your ePub file won’t pass ePubCheck thus won’t be valid.

Fortunately this is more annoying than difficult.

An .opf file is just XML so open it in a text editor. Find the <manifest> and add your fonts in there. It is as easy as typing:

/* Font with extension .otf */
<item href="path/to/font.otf" id="arbitrary-id-of-your-font" media-type="application/vnd.ms-opentype" />

/* Font with extension .ttf */
<item href="path/to/font.ttf" id="arbitrary-id-of-your-font" media-type="application/x-font-ttf" />

Repeat for every style (italic, bold, &c.) and that’s it.

Specify fonts in CSS

This is no different than web, we are using @font-face to achieve that. But there is one preferred way to do it for eBooks as we must deal with user settings.

First and foremost, the code snippet:

@font-face {
  font-family: "name";
  src: url('../path/to/font-Regular.otf');
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: "name";
  src: url('../path/to/font-Italic.otf');
  font-weight: normal;
  font-style: italic;
}
@font-face {
  font-family: "name";
  src: url('../path/to/font-Bold.otf');
  font-weight: bold;
  font-style: normal;
}
@font-face {
  font-family: "name";
  src: url('../path/to/font-BoldItalic.otf');
  font-weight: bold;
  font-style: italic;
}

As you may have remarked, we are using the same font family name for all fonts. It’s a lot better than using a different one (e.g. “name”, “name-italic”, “name-bold”, etc.), as some do on the web, because using the same name makes sure that when the user overrides the embedded fonts with the dedicated setting, all styles will be changed.

Use “name-italic” and text in italic won’t be overridden. As a result, the user gets a mix of default roman + embedded italic, which may be baffling.


Please remark our src is minimalistic. To sum things up, we don’t need to bloat that with local and multiple formats. EPUB3 specifications require support for OTF and WOFF. I would not stake my life on good WOFF support though, so stick with OTF, which is backward compatible in practice.

You may also want to consider TTF fonts as their support can be a lot better, especially in Kindle and some ePub2-only RS. While specs make a distinction between OTF and TTF, this distinction is debatable: all OTF files are not the same (TrueType vs. Postscript, the latter being problematic in ePub), some modern TTF files may be considered “OTF lite” in practice….

Use embedded fonts

Body copy

Should you use fonts for body copy, declare font-family for body and let all elements inherit from it. Once again, this is a best practice as it won’t disable the dedicated user setting†.

† Excepted in Calibre’s viewer but that must be a bug/oversight considering how this piece of software doesn’t mind turning your CSS into an absolute mess, by default because yolo, when it converts/creates your eBooks. By the way, it is a mess that some Reading Systems must override, if not reject in some extreme cases, because it may trigger rendering issues. #TruthBeTold #GotProofToBackItUp

body {
  font-family: "name", fallback1, fallback2, classification;
}

Classification can be serif, sans-serif and monospace. Don’t count on cursive and fantasy in practice, even if it is indeed possible to use those 2 values.

Do not ever declare font-family for p, li, &c.

A note on font stacks

Don’t expect eBook-safe fonts like you’d expect web-safe fonts a few years ago.

Actually the concept of eBook-safe fonts has not ever existed at some time. Never have we been able to use one and only “default font” for all devices and apps, not even Georgia or Arial.

Headings

For headings, you’ve got no choice:

h1, h2, h3 {
  font-family: "name", fallback1, fallback2, classification;
}

In this case, overriding is “left to the appreciation” of Reading Systems.

Code

Since embedding a monospace font is a best practice—shame on RS who don’t provide a default…

code, kbd, samp, var {
  font-family: "Your embedded monospace", "Courier New", monospace;
}

Spans

Sometimes you do need to use an embedded font for spans of text. In this case:

.span-class {
  font-family: "Your embedded font", fallbacks, classification;
}

Usually, span is not overridden, which is why it’s a really bad idea to declare the font used for body copy using a span… as a lot of word processors are currently doing.

iBooks meta

So let’s say your embedded font must absolutely be used. iBooks won’t by default, you must tell it it should. And there is one metadata to achieve this.

Let’s go back to the .opf file you edited a few steps ago. Scroll to the top and add, inside the <package> tag:

prefix="ibooks: http://vocabulary.itunes.apple.com/rdf/ibooks/vocabulary-extensions-1.0/"

You should end up with something looking at least like this:

<package xmlns="http://www.idpf.org/2007/opf" prefix="ibooks: http://vocabulary.itunes.apple.com/rdf/ibooks/vocabulary-extensions-1.0/" unique-identifier="stuff" version="3.0">

Then, in <metadata>, add:

<meta property="ibooks:specified-fonts">true</meta>

Unfortunately, this meta is global so you can’t target specific elements like headings, code or spans: iBooks will take all your font-family declarations into account.

Consequently, you may consider using one of its default typefaces for body:

  • Athelas;
  • Charter;
  • Georgia;
  • Iowan Old Style;
  • Palatino;
  • -apple-system (San Fransisco);
  • Seravek;
  • Times New Roman.

or any iOS system typeface. A list can be found there.

Please note this meta will:

  1. add the entry “Original” at the top of the list of typefaces in user settings;
  2. impose your CSS’ Hyphenation & Justification (H&J) for this “Original” setting.

In other words, if the reader wants to use his settings for H&J—you can find them in iOS Settings (app) > iBooks (tab)—he must switch to an iBooks’ typeface (see list of default above).

A note on iBooks’ default typefaces

It seems iBooks is making use of prefixed fonts to benefit from predefined combinations (unconfirmed), font sizes and line heights. See this gist for more details.

So if you are only targeting iBooks, that may be an option. Here’s the prefixed names:

  • iBooks_Athelas;
  • iBooks_Charter;
  • iBooks_Georgia;
  • iBooks_Iowan_Old_Style;
  • iBooks_Palatino;
  • iBooks_system (unconfirmed);
  • iBooks_Seravek;
  • iBooks_Times_New_Roman.

Obviously, you should not declare font-size and line-height in your CSS if you are using those prefixed fonts.

Please note I can’t confirm whether this will work or not. All I know is that iBooks’ devs are using this mechanism but I cannot say with certainty that they have not disabled it for “Publisher CSS”. I’ve never had the time to inquire further into the subject so any confirmation is welcome.

⚠️ **GitHub.com Fallback** ⚠️