Entropic Thoughts

Fake Bold Small Caps in XeLaTeX with Fontspec

Fake Bold Small Caps in XeLaTeX with Fontspec

I'm a typography geek. There are few things in the world so pleasing as seeing something beautifully typeset.

There are also few things that are as aggravating as something typeset without any thought to aesthetics. This blog, at the time of writing, is experiencing some (technical?) trouble with the foundry I use to provide web fonts. This means it's rendering whatever default font the user happens to have on their computer. It's annoying me to no end, but I hope I'll have it sorted out soon. (Update: I wrote more about the problem here.)

So, now that I'm back at school, I'll obviously typeset all my homework assignments in LaTeX. I want to have an answer to a question look something along these lines:

The problem is that when I switched to this type family, it looked like this:

You can probably see what went wrong. The small caps that works elsewhere in the text does not appear to work when the bold font weight is used. This is caused by the font lacking bolded small caps, which should technically be designed separately from all other styles.

However, user sdaau on Stack Exchange had a solution for just my problem!

You can read in more detail about how the solution works in his answer on Stack Exchange, but the gist is that instead of real bold small caps, we take the regular small caps and fake bold them as a substitute. It works brilliantly.

Fontspec disrecommends faking styles that don't exist in the font, but this is such a minor use case that I don't want to throw out a perfectly good type family when the fake bolding actually works reasonably well.

And it's just two lines of TeX code! If your type family is named "Foobar", then after you've \setmainfont{Foobar}, you can

\fontspec[FakeBold=2.5]{Foobar}
\DeclareFontShape{\UTFencname}{Foobar(0)}{bx}{sc}{<->ssub * Foobar(1)/m/sc}{}

This tells fontspec that "when you try to render bolded small caps for the first instance of Foobar, try instead to render regular small caps for the second instance of Foobar". The second instance of Foobar has all symbols fake bolded. Brilliant!

(Note that I've modified the Stack Exchange answer in one way: I changed the hard-coded EU1 encoding assumption into the XeLaTeX variable \UTFencname. I did this because it appears some of my XeLaTeX installations by default load fonts with the EU1 encoding, and others with the TU encoding. This way the code works for either.)