NFSS:我可以使用分数(更准确)而不是小数来缩放字体吗?

NFSS:我可以使用分数(更准确)而不是小数来缩放字体吗?

我希望能够将分数表达式传递给s*[<number>]\DeclareFontShape最终目标是指示 LaTeX2e 的新字体选择方案 (NFSS) 执行更准确的计算。可以做到吗?

\documentclass{article}
\usepackage{fontspec}
\setmainfont{texgyretermes-regular.otf}[
  Scale=1.10502958579881657 % 747/676
]
\setsansfont{texgyreheros-regular.otf}[
  Scale=1.00685871056241427 % 734/729
]
\begin{document}
\fontsize{10.5bp}{15.75bp}\selectfont
By NFSS: \the\numexpr\fontdimen6\font\relax\par
What I want: \the\numexpr\dimexpr10.5bp*747/676\relax\relax\par
\sffamily
By NFSS: \the\numexpr\fontdimen6\font\relax\par
What I want: \the\numexpr\dimexpr10.5bp*734/729\relax\relax
\end{document}

比例1
在我的实际文档中,我将拉丁字体与 CJK 字体混合在一起,因此需要各种缩放因子……我不喜欢舍入误差那么大 5sp……


背景信息对于那些不熟悉 TeX 二进制算法的人来说。在下面的例子中,我尝试将原始维度放大 1.2。当1.2\mydimen遇到时,TeX 首先将浮点数转换1.2为其内部整数表示:Round(1.2*65536) = Round(78643.2) = 78643。然后将舍入后的结果乘以1,000,000sp产生Floor(78643*1,000,000/2^16) = Floor(1199996.9482421875) = 1,199,996sp

但是如果我们将 重写 1.2为 6/5,然后使用原语\multiply\divide,或者使用 eTeX 的表达式扩展,我们可以得到更准确的结果。

\documentclass{article}
\newdimen\mydimen
\newcommand*\onemillionsp{15.2587890625pt\relax}
\begin{document}
\mydimen\onemillionsp
\verb|\mydimen|: \the\numexpr\mydimen\relax\par
\mydimen1.2\mydimen
\verb|1.2\mydimen|: \the\numexpr\mydimen\relax\par
\smallskip

Use \verb|\multiply| and \verb|\divide| primitives:\par
\mydimen\onemillionsp
\multiply\mydimen by 6\divide\mydimen by 5\relax
\verb|\mydimen * 6 / 5|: \the\numexpr\mydimen\relax\par
\smallskip

Use eTeX's extension:\par
\mydimen\onemillionsp
\verb|\<expression>|: \the\numexpr\mydimen*6/5\relax
\end{document}

尺度2

答案1

NFSS 毕竟是可以入侵的,如果 LaTeX3 团队有人感兴趣的话,可以试试这个增强版:)

分数

我的新实现\empty@sfcnt与十进制表达式兼容。但是,分数表达式语法需要 eTeX 的\dimexpr

\documentclass{article}

\makeatletter
% Look ahead for either a decimal or a fraction
%   and extract all stuff after the first slash:
\def\detect@decimal@or@frac#1/#2\detect@decimal@or@frac{%
  \edef\@tempa{#2}%
}
% Hack into NFSS:
\def\empty@sfcnt#1{%
      \@tempdimb \f@size\p@
      \ifx\optional@arg\@empty
      \else
% The following line was the original:
%        \@tempdimb \optional@arg\@tempdimb
% Replaced with my new implementation:
        \expandafter\detect@decimal@or@frac
          \optional@arg/0\detect@decimal@or@frac
        \def\@tempb{0}%
        \ifx\@tempa\@tempb
          % A decimal or an integer is passed here
          \@tempdimb \optional@arg\@tempdimb
        \else
          % A fraction is passed here
          \@tempdimb \dimexpr\@tempdimb*\optional@arg\relax
        \fi
% End of new implementation
        #1{Font\space shape\space `\curr@fontshape'\space
           will\space be\MessageBreak
           scaled\space to\space size\space \the\@tempdimb}%
      \fi
      \edef\external@font{\mandatory@arg\space at\the\@tempdimb}}
\makeatother

\usepackage{fontspec}

\newcommand\test[1]{%
  \begingroup
  \texttt{\string\fontspec\{texgyretermes-regular.otf\}[Scale=\{#1\}]}:\\
  \fontspec{texgyretermes-regular.otf}[Scale={#1}]%
  \the\fontdimen6\font\par
  \medskip
  \endgroup
}
\setlength\parindent{0pt}

\begin{document}
\test{1}
\test{1.2}
\test{6/5}
\test{1,4}
\test{14/10}
\test{1.105029585798816568}% 747/676
\test{747/676}
\end{document}

相关内容