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.