Forum How do I...?

Font fallback doesn't happen for generic fonts if specifying individual styles/weights

jez
Is there a way to redefine the generic fonts such that I can specify to render `font-weight: bold;` with the Semibold style, while still inheriting all the fallback fonts for various unicode characters not present in that font?

I want to Redefine the generic font families in a document. Specifically, I want to specify that the meaning of
font-family: serif;
font-weight: bold;

is typeset using the Semibold style of the font family, not the Bold style. If I just do
@font-face {
  font-family: serif;
  src: local("Crimson Pro");
}

to redefine the generic fallback font using the `local()` functional expression, it picks the Bold style of the font for `font-weight: bold;` text, as evidenced by `pdffonts` (from the Poppler package):
❯ pdffonts example.pdf
name                                 type              encoding         emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
PXAAAA+CrimsonPro-Regular            Type 1C           MacRoman         yes yes no      11  0
PXAAAB+ArialUnicodeMS                TrueType          WinAnsi          yes yes yes     12  0
PXAAAC+CrimsonPro-Bold               Type 1C           MacRoman         yes yes no      13  0
PXAAAD+CrimsonPro-Italic             Type 1C           MacRoman         yes yes no      14  0
PXAAAE+CrimsonPro-BoldItalic         Type 1C           MacRoman         yes yes no      15  0

I can get it to pick the Semibold styles if I specify the `@font-face` stanzas like this, with the `url()` functional expression (instead of `local()`) and paths to the individual styles I want to use:
@font-face {
  font-family: serif;
  font-style: normal;
  font-weight: normal;
  src: url("CrimsonPro-Regular.otf");
}
@font-face {
  font-family: serif;
  font-style: normal;
  font-weight: bold;
  src: url("CrimsonPro-SemiBold.otf");
}
@font-face {
  font-family: serif;
  font-style: italic;
  font-weight: normal;
  src: url("CrimsonPro-Italic.otf");
}
@font-face {
  font-family: serif;
  font-style: italic;
  font-weight: bold;
  src: url("CrimsonPro-SemiBoldItalic.otf");
}

and now the SemiBold styles are chosen:
❯ pdffonts example.pdf
name                                 type              encoding         emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
PXAAAA+CrimsonPro-Regular            Type 1C           MacRoman         yes yes no      11  0
PXAAAB+PrinceFallback                TrueType          WinAnsi          yes yes yes     12  0
PXAAAC+CrimsonPro-SemiBold           Type 1C           MacRoman         yes yes no      13  0
PXAAAD+CrimsonPro-Italic             Type 1C           MacRoman         yes yes no      14  0
PXAAAE+CrimsonPro-SemiBoldItalic     Type 1C           MacRoman         yes yes no      15  0

But this makes certain unicode characters fail to render:
❯ prince-books example.html && open example.pdf
prince: page 1: warning: no font for Arrows character U+21A9, fallback to U+2BD1 ⯑
prince: page 1: warning: no font for Arrows character U+21A9, fallback to U+2BD1 ⯑
prince: page 1: warning: no font for Arrows character U+21A9, fallback to U+2BD1 ⯑
prince: page 1: warning: no font for Arrows character U+21A9, fallback to U+2BD1 ⯑


So it seems that redefining the generic fonts and their weights/styles means that I don't benefit from all the fallback `@font-face` declarations in the `fonts.css` file included in the Prince for Books distribution.

  1. example.html1.2 kB
    HTML
  2. example.pdf25.0 kB
    PDF, using semibold but missing glyphs
  3. fallback-font-example.zip228.2 kB
    HTML and font files