[Tex/LaTex] Avoiding increase of number of fonts (families) with fontspec/xelatex

fontspecxetex

(I actually came to a solution with this, which I've posted separately, but I thought it'd be good to document anyways – and of course, any comments to this are welcome)

This is the problem – I need to "style fonts" in a document, which I compile using xelatex and fontspec. And it seems each time I call \setmainfont or \fontspec or \addfontfeature (which I thought are for "styling"), a new "font family" gets created.

Below is an MWE, that generates the following output (compiled with xelatex test.tex):

test.png

Note that each call to abovementioned functions causes 'Junicode(X+1)' to be instantiated; thankfully, \fontsize{size}{skip} doesn't seem to increase the number of fonts.

Here is the code (inline links: 1,
2,
3,
4,
5
):

\documentclass[letterpaper,12pt]{article}

% http://tex.loria.fr/ctan-doc/macros/latex/doc/html/fntguide/node36.html
% dumps to log
% \usepackage{tracefnt}

% \typeout{ == \the\paperwidth / \the\paperheight ==}
% \typeout{ == \the\pdfpagewidth / \the\pdfpageheight ==}
\pdfpagewidth=\paperwidth \pdfpageheight=\paperheight

% default font change:
% http://www.forkosh.com/pstex/latexcommands.htm
%   \fontencoding{T1}
%   \fontfamily{garamond}
%   \fontseries{m}
%   \fontshape{it}
%   \fontsize{12}{15}
%   \selectfont


\usepackage{fontspec}

\defaultfontfeatures{Ligatures=TeX}
\setmainfont{Junicode}


% trick for fake smallcaps, https://tex.stackexchange.com/a/56097/2595
% each \setmainfont / \fontspec / \addfontfeature command creates a new Junicode(X) font
% here we are at Junicode(0)
% create Junicode(1) with fake bold
\fontspec[FakeBold=2.5]{Junicode}

% map Junicode(0)/bx/sc (bold smallcaps) to Junicode(1)/m/sc (normal smallcaps of fake bold)
\DeclareFontShape{EU1}{Junicode(0)}{bx}{sc}{<->ssub * Junicode(1)/m/sc}{}

% for debugging fonts: https://tex.stackexchange.com/a/14382/2595
\makeatletter
\newcommand{\showfont}{Encoding: \f@encoding{},
  Family: \f@family{},
  Series: \f@series{},
  Shape: \f@shape{},
  Size: \f@size{}
}
\makeatother

\usepackage{tikz}


% from: https://tex.stackexchange.com/a/10524/2595
% change this to get the formatting you want
\newcommand{\parnum}{\bfseries\arabic{parcount}}

\newcounter{parcount}
\newenvironment{parnumbers}{%
   \par%
%    \reversemarginpar%
%    \everypar{\stepcounter{parcount}\leavevmode\marginpar[\hfill\parnum]{\parnum}}%
   \everypar{\stepcounter{parcount}\leavevmode\reversemarginpar{\makebox[20pt][r]{\hfill\parnum.\space}}}%
}{}


\begin{document}

\begin{parnumbers}

  {\scshape \showfont Aa}

  {\fontspec[Letters=SmallCaps]{Junicode} \showfont Aa}

  {\bfseries\scshape \showfont Aa}

  \showfont Aa

  \normalsize \showfont Aa

  \fontspec[Scale=1.0] {Junicode} \showfont Aa

  \addfontfeature{Scale=1.0} \showfont Aa

  \fontsize{9}{10} \showfont Aa

  \fontsize{9}{10}\selectfont \showfont Aa

  \addfontfeature{Scale=0.9} \showfont Aa

  \fontsize{8}{10}\selectfont \showfont Aa

  \normalsize \showfont Aa

  \begin{tikzpicture} \node { \normalsize \showfont Aa }; \end{tikzpicture}

  \showfont Aa

\end{parnumbers}

\end{document}

Best Answer

Well yes, new font families are created. But why does it worry you? A font family is simply a label. fontspec has to sort all your font definitions in the existing nfss-system. Which axis of the nfss system (encoding, family, shape, series, sizes) should a change like Letters=SmallCaps or Ligatures=TeX use instead? If you would use the shape or series axis you would not be able to combine your font with commands like \bfseries or \itshape.

In an extended nfss-system with more axis fontspec could use one of them. But in this case you would get new values in this axis. It would be a bit more cleaner and logical, but not more.

Related Question