fontspec icon indicating copy to clipboard operation
fontspec copied to clipboard

Replace NFSS internals for better font scaling

Open wspr opened this issue 5 years ago • 2 comments

See: https://tex.stackexchange.com/questions/485339/nfss-can-i-scale-fonts-using-fractions-more-accurate-instead-of-decimals

wspr avatar Jun 18 '19 03:06 wspr

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}

scale

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.

RuixiZhang42 avatar Jun 23 '19 01:06 RuixiZhang42

@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...

wspr avatar Jun 23 '19 03:06 wspr