10

Is ist possible to define a new series with fontspec? I tried the following but …

  1. it throws an error if the font doesn’t have a light version instead of replacing the font, like \bfseries does. In other word there’s no fallback.
  2. my \ltseries isn’t deactivated by \mdseries.
\documentclass{article}

\usepackage{fontspec}
\setmainfont{Source Sans Pro}
   % http://www.google.com/fonts/specimen/Source+Sans+Pro

\newcommand{\ltseries}{%
   \addfontfeatures{UprightFont={* Light},ItalicFont={* Light Italic}}%
}

\begin{document}
\ltseries
Light

\mdseries
Regular

\bfseries
Bold
\end{document}

If found Possible values for \fontseries and \fontshape but it doesn’t tell how to define a new series. Furthermore this is for LaTeX and it’s NFSS, while I’m using XeTeX with fontspec.

  • \newfontfamily or \newfontface. – Manuel May 12 '14 at 14:17
  • @Manuel: Unfortunately not. With these two I have to define the base font too and so \ltseries will change the family too. – Tobi May 12 '14 at 14:58
  • If you want to definde \ltseries like that (and you are sure it's enough), you could redefine \mdseries (and \bfseries) to be the same but with other UprightFont and ItalicFont. – Manuel May 12 '14 at 18:47
8

There is no official interface. You can do it this way (this is lualatex-syntax, for the xelatex syntax check e.g. eu1lmr.fd). You should be aware that it will not work together with local font changes through \addfontfeatures or a local \fontspec as this often create a new family.

\documentclass{article}

\usepackage{fontspec}
\setmainfont{Source Sans Pro}

\normalfont
\makeatletter
\DeclareFontShape{\f@encoding}{\f@family}{l}{n}%
     {<->    name:sourcesanspro-light:script=latn;+trep;+tlig;
      }{}

\DeclareFontShape{\f@encoding}{\f@family}{l}{it}%
     {<->    name:sourcesanspro-lightit:script=latn;+trep;+tlig;
      }{}
\makeatother

\DeclareRobustCommand{\ltseries}{%
\fontseries{l}\selectfont}

\begin{document}
\ltseries
Light

\mdseries
Regular

\bfseries
Bold

 \normalfont
 {\addfontfeatures{Ligatures=NoCommon} abc \ltseries abc}

\end{document}
  • 1
    Ulrike's answer is correct. Adding support for arbitrary NFSS series and shapes is on my todo list (and actually the current version of GitHub allows you to name the NFSS family if you wish) -- I guess I was just putting off the idea of also adding \textlt/\ltseries to go along with everything. Always seemed like I should tackle a better way of switching between font series. – Will Robertson May 12 '14 at 22:48
  • Thanks Ulrike. It worked after I found out what the correct font name is :-) – Tobi May 12 '14 at 23:26
  • (Hopefully) short question: Is it save to replace \f@family with SourceSansPro(0) or is it better to add \sffamily before declaring the new shapes? (I know my example used \setmainfont but actually it is \setsansfont …) – Tobi May 12 '14 at 23:32
  • @Tobi I would use \sffamily + \f@family. The family name (the number) can change if use the font also with other features. \sffamily does no harm in the preamble: At \begin{document} a \normalfont is issued. – Ulrike Fischer May 13 '14 at 7:24
  • @WillRobertson: It would be very fine if one could add more series/shapes. I just did go to some length to add a semibold series in one document. Naturally it would be even better if one could add more NFSS-axes to handle e.g. variants like different number types or ligatures without ending with another family name. – Ulrike Fischer May 13 '14 at 7:30
4

Ulrikes’s answer works fine after changing \DeclareFontShape in the XeTeX-way, this is how it looks like:

\documentclass{article}

\usepackage{fontspec}
\setsansfont{Source Sans Pro}
   % http://www.google.com/fonts/specimen/Source+Sans+Pro

\begingroup % \DeclareFontShape acts globally
\makeatletter
\sffamily

\DeclareFontShape{\f@encoding}{\f@family}{l}{n}%
     {<->    "[SourceSansPro-Light]:mapping=tex-text"
      }{}
\DeclareFontShape{\f@encoding}{\f@family}{l}{it}%
     {<->    "[SourceSansPro-LightIt]:mapping=tex-text"
      }{}
\endgroup % removes the effects of \sffamily and \makeatletter

\DeclareRobustCommand{\ltseries}{%
  \fontseries{l}\selectfont}

\makeatother

\begin{document}
\ltseries
Light (not available)

\mdseries
Regular

\bfseries
Bold

\sffamily
\ltseries
Light

\mdseries
Regular

\bfseries
Bold
\end{document}

The \sffamily before \DeclareFontShape is necessary to let \f@family have the right family name. At the document begin there’s a \normalfont so \sffamily doesn’t change the font for the document here …

  • 1
    \makeatletter is missing; you can enclose the two \DeclareFontShape commands between \begingroup\sffamily and \endgroup, changing the explicit family name by \f@family, because \DeclareFontShape is implicitly global. – egreg May 12 '14 at 23:40
  • @egreg: Thanks, I forgot the \makeatletter when copying the code to the MWE … – Tobi May 13 '14 at 8:45
4

With a recent version of fontspec (v2.5a at time of writing) there is an official interface to declare new font shapes: One can use the FontFace option to define a new NFSS font face:

\documentclass{article}

\usepackage{fontspec}
\setsansfont[
   FontFace = {lt}{n}{SourceSansPro-Light},
   FontFace = {lt}{it}{SourceSansPro-LightIt},
]{Source Sans Pro}

\DeclareRobustCommand{\ltseries}{\fontseries{lt}\selectfont}
\DeclareTextFontCommand{\textsi}{\sishape}

\begin{document}
\ltseries
Light \textit{Italic} (not available) 

\mdseries
Regular \textit{Italic}

\bfseries
Bold \textit{Italic}

\sffamily
\ltseries
Light \textit{Italic}

\mdseries
Regular \textit{Italic}

\bfseries
Bold \textit{Italic}
\end{document}

This is much more comfortable than using \DeclareFontShape. In the example I also added the definition of \textlt which was missing in the other answers.

  • The example works perfectly. I had to put in a Font= because I like to use the font options for illustration purposes (e.g., {Font=* Light, Colour=blue, Scale=2.1,}), but then it turned out that the font files I was using (v1, from 2012) were somewhat buggy, and installing a more recent version of Source Sans Pro (2014) fixed things. – Cicada May 5 at 10:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.