4

I am trying to set up variable fonts on LuaLaTeX via the fontspec package. I am trying to get the font size and the optical size (opsz) to have nearly the same value. (I am aware that the opsz variable axis must be between 6 and 144 with a step of 0.1 so the numbers won't be perfectly synced. See: https://fonts.google.com/knowledge/glossary/optical_size_axis)

The fontspec documentation makes it seem like you have to manually set the optical size for each font size and that you have to add an additional font size-optical size pair each time you add a new font. Obviously, this would be exhausting and take a long time. I would prefer that the optical size (almost always) equals the font size automatically. ({Size=X,RawFeature={axis={opsz=X}}} for every possible value for X.)

In the following MWE, I manually set the optical size for each font size defined by the article document class. (And, for some reason, the line spacing for the paragraphs with \LARGE,\huge, and \Huge is messed up.)

EDIT: I have added the code for Bold, Italics, and Bold Italics to help the reader understand how tedious it would be to manually set the optical size for each font size. I haven't even set up the commands for different weights: ExtraLight, Light, Medium, SemiBold, ExtraBold, and Black.

\documentclass{article}
\usepackage[lmargin=1in,rmargin=1in]{geometry}
\raggedright\raggedbottom
\parindent=0pt
\parskip=7pt
\usepackage{blindtext}
\usepackage{fontspec}
\setmonofont{Source Code Pro}%Available for free on Google Fonts.
\setmainfont{SourceSerif4-VariableFont_opsz,wght.ttf}[%Available for free on Google Fonts.
    ,Kerning=On,Numbers={Lining,Tabular}
    %Regular
    ,SizeFeatures={
        {Size=7,RawFeature={axis={opsz=7}}}%\scriptsize
        ,{Size=8,RawFeature={axis={opsz=8}}}%\footnotesize
        ,{Size=9,RawFeature={axis={opsz=9}}}%\small
        ,{Size=10,RawFeature={axis={opsz=10}}}%\normalsize
        ,{Size=12,RawFeature={axis={opsz=12}}}%\large
        ,{Size=14.4,RawFeature={axis={opsz=14.4}}}%\Large
        ,{Size=17.28,RawFeature={axis={opsz=17.3}}}%\LARGE
        ,{Size=20.74,RawFeature={axis={opsz=20.7}}}%\huge
        ,{Size=24.88,RawFeature={axis={opsz=24.9}}}%\Huge
    }
    %Bold
    ,BoldFont={SourceSerif4-VariableFont_opsz,wght.ttf}
    ,BoldFeatures={
        SizeFeatures={
            {Size=7,RawFeature={axis={wght=700,opsz=7}}}%\scriptsize
            ,{Size=8,RawFeature={axis={wght=700,opsz=8}}}%\footnotesize
            ,{Size=9,RawFeature={axis={wght=700,opsz=9}}}%\small
            ,{Size=10,RawFeature={axis={wght=700,opsz=10}}}%\normalsize
            ,{Size=12,RawFeature={axis={wght=700,opsz=12}}}%\large
            ,{Size=14.4,RawFeature={axis={wght=700,opsz=14.4}}}%\Large
            ,{Size=17.28,RawFeature={axis={wght=700,opsz=17.3}}}%\LARGE
            ,{Size=20.74,RawFeature={axis={wght=700,opsz=20.7}}}%\huge
            ,{Size=24.88,RawFeature={axis={wght=700,opsz=24.9}}}%\Huge
        }
    }
    %Italics
    ,ItalicFont={SourceSerif4-Italic-VariableFont_opsz,wght.ttf}
    ,ItalicFeatures={
        SizeFeatures={
            {Size=7,RawFeature={axis={opsz=7}}}%\scriptsize
            ,{Size=8,RawFeature={axis={opsz=8}}}%\footnotesize
            ,{Size=9,RawFeature={axis={opsz=9}}}%\small
            ,{Size=10,RawFeature={axis={opsz=10}}}%\normalsize
            ,{Size=12,RawFeature={axis={opsz=12}}}%\large
            ,{Size=14.4,RawFeature={axis={opsz=14.4}}}%\Large
            ,{Size=17.28,RawFeature={axis={opsz=17.3}}}%\LARGE
            ,{Size=20.74,RawFeature={axis={opsz=20.7}}}%\huge
            ,{Size=24.88,RawFeature={axis={opsz=24.9}}}%\Huge
        }
    }
    %Bold Italics
    ,BoldItalicFont={SourceSerif4-Italic-VariableFont_opsz,wght.ttf}
    ,BoldItalicFeatures={
        SizeFeatures={
            {Size=7,RawFeature={axis={wght=700,opsz=7}}}%\scriptsize
            ,{Size=8,RawFeature={axis={wght=700,opsz=8}}}%\footnotesize
            ,{Size=9,RawFeature={axis={wght=700,opsz=9}}}%\small
            ,{Size=10,RawFeature={axis={wght=700,opsz=10}}}%\normalsize
            ,{Size=12,RawFeature={axis={wght=700,opsz=12}}}%\large
            ,{Size=14.4,RawFeature={axis={wght=700,opsz=14.4}}}%\Large
            ,{Size=17.28,RawFeature={axis={wght=700,opsz=17.3}}}%\LARGE
            ,{Size=20.74,RawFeature={axis={wght=700,opsz=20.7}}}%\huge
            ,{Size=24.88,RawFeature={axis={wght=700,opsz=24.9}}}%\Huge
        }
    }
]
\begin{document}
\texttt{REGULAR}
\par
{\scriptsize\texttt{scriptsize}\hspace{0.5em}\blindtext}
\par
{\footnotesize\texttt{footnotesize}\hspace{0.5em}\blindtext}
\par
{\small\texttt{small}\hspace{0.5em}\blindtext}
\par
{\normalsize\texttt{normalsize}\hspace{0.5em}\blindtext}
\par
{\large\texttt{large}\hspace{0.5em}\blindtext}
\par
{\Large\texttt{Large}\hspace{0.5em}\blindtext}
\par
{\LARGE\texttt{LARGE}\hspace{0.5em}\blindtext}
\par
{\huge\texttt{huge}\hspace{0.5em}\blindtext}
\par
{\Huge\texttt{Huge}\hspace{0.5em}\blindtext}
\par
\texttt{BOLD}{\bfseries
\par
{\scriptsize\texttt{scriptsize}\hspace{0.5em}\blindtext}
\par
{\footnotesize\texttt{footnotesize}\hspace{0.5em}\blindtext}
\par
{\small\texttt{small}\hspace{0.5em}\blindtext}
\par
{\normalsize\texttt{normalsize}\hspace{0.5em}\blindtext}
\par
{\large\texttt{large}\hspace{0.5em}\blindtext}
\par
{\Large\texttt{Large}\hspace{0.5em}\blindtext}
\par
{\LARGE\texttt{LARGE}\hspace{0.5em}\blindtext}
\par
{\huge\texttt{huge}\hspace{0.5em}\blindtext}
\par
{\Huge\texttt{Huge}\hspace{0.5em}\blindtext}
}
\par
\texttt{ITALICS}{\itshape
\par
{\scriptsize\texttt{scriptsize}\hspace{0.5em}\blindtext}
\par
{\footnotesize\texttt{footnotesize}\hspace{0.5em}\blindtext}
\par
{\small\texttt{small}\hspace{0.5em}\blindtext}
\par
{\normalsize\texttt{normalsize}\hspace{0.5em}\blindtext}
\par
{\large\texttt{large}\hspace{0.5em}\blindtext}
\par
{\Large\texttt{Large}\hspace{0.5em}\blindtext}
\par
{\LARGE\texttt{LARGE}\hspace{0.5em}\blindtext}
\par
{\huge\texttt{huge}\hspace{0.5em}\blindtext}
\par
{\Huge\texttt{Huge}\hspace{0.5em}\blindtext}
}
\par
\texttt{BOLD ITALICS}{\itshape\bfseries
\par
{\scriptsize\texttt{scriptsize}\hspace{0.5em}\blindtext}
\par
{\footnotesize\texttt{footnotesize}\hspace{0.5em}\blindtext}
\par
{\small\texttt{small}\hspace{0.5em}\blindtext}
\par
{\normalsize\texttt{normalsize}\hspace{0.5em}\blindtext}
\par
{\large\texttt{large}\hspace{0.5em}\blindtext}
\par
{\Large\texttt{Large}\hspace{0.5em}\blindtext}
\par
{\LARGE\texttt{LARGE}\hspace{0.5em}\blindtext}
\par
{\huge\texttt{huge}\hspace{0.5em}\blindtext}
\par
{\Huge\texttt{Huge}\hspace{0.5em}\blindtext}
}
\end{document}

UPDATE 2023-01-02: I have been testing the HarfBuzz method to auto-size the opsz axis as suggested by Marcel Kruger. I find that it has functionality other than auto-sizing the opsz axis. Two main issues:

(1) If I change the font to Source Sans 3, another variable font, (with nearly the same code as provided by Marcel Kruger) and test using/not using HarfBuzz, I find that the document versions with and without HarfBuzz look significantly different from each other. The document versions should look identical because Source Sans 3 lacks an opsz axis. Thus, Renderer=HarfBuzz has additional functionality other than modifying the opsz axis. The added functionality may or may not be typographically optimal. You can see this for your yourself in the second MWE below.

(2) Using Renderer=HarfBuzz with Source Serif 4 with the \textls letterspacing command from package microtype sometimes produces incorrect letterspacing. I haven't found a pattern of error, but I have replicated some of the error in my second MWE. I have found that I can fix this error by either using Source Sans 3 instead or by setting Kerning=Off locally. In fixing this letterspacing error, I would prefer that the \textls command automatically locally disables kerning.

\documentclass{article}
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhf{}%clears default header footers
\fancyhead[C]{%
    %\addfontfeatures{Kerning=Off}%In my testing, this fixes the bugged letterspacing.
    \textls[100]{LETTERSPACING IS BUGGED}%
}
\fancyfoot[C]{%
    %\addfontfeatures{Kerning=Off}%In my testing, this fixes the bugged letterspacing.
    ~\textls[100]{BUGGED}%
    ~(%
    \textls[100]{LETTER}%
    ~\textls[100]{SPACING}%
    )%
}
\usepackage{microtype}
\usepackage{blindtext}
\usepackage{fontspec}
\setmonofont{Source Code Pro}
\setromanfont{SourceSerif4-VariableFont_opsz,wght.ttf}[%Available for free on Google Fonts.
    ,Kerning=On,Numbers={Lining,Tabular},Renderer=HarfBuzz
    %Bold
    ,BoldFont={SourceSerif4-VariableFont_opsz,wght.ttf}
    ,BoldFeatures={RawFeature={axis={wght=700}}}
    %Italics
    ,ItalicFont={SourceSerif4-Italic-VariableFont_opsz,wght.ttf}
    %Bold Italics
    ,BoldItalicFont={SourceSerif4-Italic-VariableFont_opsz,wght.ttf}
    ,BoldItalicFeatures={RawFeature={axis={wght=700}}}
]
\setsansfont{SourceSans3-VariableFont_wght.ttf}[%Available for free on Google Fonts.
    Kerning=On
    %,Renderer=HarfBuzz%In my testing Renderer=HarfBuzz will change the text display even though Source Sans 3 lacks an opsz axis.
    %Regular
    ,RawFeature={axis={wght=400}}
    %Bold
    ,BoldFont={SourceSans3-VariableFont_wght.ttf}
    ,BoldFeatures={RawFeature={axis={wght=700}}}
    %Italics
    ,ItalicFont={SourceSans3-Italic-VariableFont_wght.ttf}
    ,ItalicFeatures={RawFeature={axis={wght=400}}}
    %Bold Italics
    ,BoldItalicFont={SourceSans3-Italic-VariableFont_wght.ttf}
    ,BoldItalicFeatures={RawFeature={axis={wght=700}}}
]
\renewcommand{\familydefault}{%use this to switch between serif and sans fonts
    \rmdefault%
    %\sfdefault%
}
\begin{document}
{%
    %\addfontfeatures{Kerning=Off}%In my testing, this fixes the bugged letterspacing. Note that I have disabled kerning locally to not mess up the rest of the document.
    \textls[100]{LETTER SPACING IS BUGGED}%
}%
\par
\blinddocument
\small\blinddocument
\tiny\blinddocument
\end{document}

EDIT: I used the showhyphenation package with Renderer=HarfBuzz enabled and found that the latter messes up hyphenation in significant ways. I tested this with other documents.

1 Answer 1

7

You can request the HarfBuzz based renderer and don't specify any opsz feature. The HarfBuzz mode automatically determines the opsz from the font size if no explicit value is given:

\documentclass{article}
\usepackage{blindtext}
\usepackage{fontspec}
\setmonofont{Source Code Pro}
\setmainfont{SourceSerif4-VariableFont_opsz,wght.ttf}[%Available for free on Google Fonts.
    ,Kerning=On,Numbers={Lining,Tabular},Renderer=HarfBuzz
    %Bold
    ,BoldFont={SourceSerif4-VariableFont_opsz,wght.ttf}
    ,BoldFeatures={RawFeature={axis={wght=700}}}
    %Italics
    ,ItalicFont={SourceSerif4-Italic-VariableFont_opsz,wght.ttf}
    %Bold Italics
    ,BoldItalicFont={SourceSerif4-Italic-VariableFont_opsz,wght.ttf}
    ,BoldItalicFeatures={RawFeature={axis={wght=700}}}
]
\begin{document}
\blinddocument
\small\blinddocument
\tiny\blinddocument
\end{document}
1
  • Thanks for the response. The Renderer=HarfBuzz seems to get the correct optical sizing, but it seems to do other things as well. I have updated my original post to reflect my recent testing. Jan 2 at 20:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .