fontspec
fontspec copied to clipboard
Replace NFSS internals for better font scaling
See: https://tex.stackexchange.com/questions/485339/nfss-can-i-scale-fonts-using-fractions-more-accurate-instead-of-decimals
I improved the code by creating a general-purpose macro \AssignScaledResult
. It turns out this macro is suitable not only to the size functions, but also for baseline stretch (e.g., \linespread
).
\documentclass{article}
\usepackage{etoolbox}
\makeatletter
% Look ahead for a decimal or a fraction
\ifx\detect@decimal@or@frac\@undefined
\def\detect@decimal@or@frac#1/#2\detect@decimal@or@frac{%
\edef\@tempa{#2}%
}
\fi
% A general purpose macro \AssignScaledResult{#1}{#2}{#3}{#4}
% #1: One of \numexpr, \dimexpr, \glueexpr or \muexpr
% #2: The target register to hold the scaled result
% #3: Scale factor, either a decimal or a fraction
% #4: The original pre-scaled register
\newcommand*\AssignScaledResult[4]{%
\expandafter\detect@decimal@or@frac#3/0\detect@decimal@or@frac
\def\@tempb{0}%
\ifx\@tempa\@tempb
#2=#3#4\relax
\else
#2=#1#4*#3\relax
\fi
}
% Redefine \set@fontsize
\patchcmd\set@fontsize
{\baselineskip\f@linespread\baselineskip}
{\AssignScaledResult\glueexpr\baselineskip\f@linespread\baselineskip}
{}{\typeout{Couldn't patch \string\set@fontsize}}
% Redefine \empty@sfcnt
\patchcmd\empty@sfcnt
{\@tempdimb \optional@arg\@tempdimb}
{\AssignScaledResult\dimexpr\@tempdimb\optional@arg\@tempdimb}
{}{\typeout{Couldn't patch \string\empty@sfcnt}}
\makeatother
\usepackage{fontspec}
\begin{document}
\fontspec{texgyretermes-regular.otf}%
\the\fontdimen6\font/\the\baselineskip\par
\linespread{1.4}\fontspec{texgyretermes-regular.otf}[Scale=1.2]%
\the\fontdimen6\font/\the\baselineskip\par
\linespread{14/10}\fontspec{texgyretermes-regular.otf}[Scale=12/10]%
\the\fontdimen6\font/\the\baselineskip\par
\end{document}
IMHO, this is perhaps better to be addressed in the LaTeX kernel. The pair \detect@decimal@or@frac
and \AssignScaledResult
will never break existing documents: The original <register>=<decimal_scale><register>
syntax is used whenever the scale is an integer or a decimal, and old documents only use decimal scales. New documents can take advantage of eTeX and use fraction instead.
@FrankMittelbach — what do you think? I could experiment by putting this into fontspec in the shorter term, and we can decide later what to do about kernel matters...