[Tex/LaTex] With fontspec, how can one define a variation of a font family

fontspecxetex

I keep running into the following situation using fontspec with XeTeX:

  • I define a "base" font family using \newfontfamily.
  • I then want to access a "spaced small caps" variant, using the LetterSpace feature within the SmallCapsFeatures set.
  • I then want to define yet another variation on the former small caps spacing settings, for use in a different context within the paragraph.

So far, the only way I've figured out how to do this is to define wholly separate font families for each of these three variations (no adjustment to spacing, one adjustment to spacing, and some other adjustment to spacing), like so:

\setmainfont[BoldFont={* Semibold},
             Numbers={OldStyle,Proportional}]
            {Adobe Garamond Pro}

\newfontfamily\rmaltfamily
  [BoldFont={* Semibold},
   Numbers={OldStyle,Proportional},
   SmallCapsFeatures={LetterSpace=2.5}]
  {Adobe Garamond Pro}

\newfontfamily\rmaltloosefamily
  [BoldFont={* Semibold},
   Numbers={OldStyle,Proportional},
   SmallCapsFeatures={LetterSpace=4.0}]
  {Adobe Garamond Pro}

In the spirit of not repeating oneself, that's just awful. The only thing I intend to change between those is the presence and value of the LetterSpace feature.

I tried using the \addfontfeature command as shown in Example 42 in the fontspec manual to layer these changes over the current font, but, despite what the manual suggests, at least with my fonts, the LetterSpace feature is only available for specification within the SmallCapsFeature set, which is in turn only available for specification within either the \newfontfamily or \fontspec commands.

For reference here, the manual advertises that the following should be possible:

\fontspec{Didot}
\addfontfeature{LetterSpace=0.0}
USE TRACKING FOR DISPLAY CAPS TEXT \\
\addfontfeature{LetterSpace=2.0}
USE TRACKING FOR DISPLAY CAPS TEXT

Though my three separate \fontfamily definitions do work, it feels like the wrong tool for the job. Is there some better way to define a basic font family and then layer in a few changes in it, such that those changes can be used in certain contexts and be restricted in scope?

Best Answer

This works for me

\documentclass[a4paper]{article}
\usepackage{fontspec}
\setmainfont[BoldFont={* Semibold},
             Numbers={OldStyle,Proportional}]
            {Adobe Garamond Pro}

\begin{document}

{\scshape Abcde fghi}

{\addfontfeatures{SmallCapsFeatures={LetterSpace=2.5}}\scshape Abcde fghi \upshape Abcde fghi}

{\addfontfeatures{SmallCapsFeatures={LetterSpace=4.0}}\scshape Abcde fghi \upshape Abcde fghi}

\end{document}

The small caps words are letter spaced, those in upright shape aren't.

enter image description here

As far as I know, it's not possible to define a new font family as a variant of another, but something like

\newcommand{\spacedsc}{\normalfont
  \addfontfeatures{SmallCapsFeatures={LetterSpace=2.5}}%
  \scshape}

is quite similar. From the .log file I can see that fontspec doesn't recompute the font assignments once this variation is used; in other words each subsequent use of \spacedsc will load the font family computed the first time. Maybe Will Robertson can be more precise on the question.