![当 \setmathfont 具有选项 Scale=MatchLowercase 时,出现“尺寸太大”错误](https://linux22.com/image/390933/%E5%BD%93%20%5Csetmathfont%20%E5%85%B7%E6%9C%89%E9%80%89%E9%A1%B9%20Scale%3DMatchLowercase%20%E6%97%B6%EF%BC%8C%E5%87%BA%E7%8E%B0%E2%80%9C%E5%B0%BA%E5%AF%B8%E5%A4%AA%E5%A4%A7%E2%80%9D%E9%94%99%E8%AF%AF.png)
\documentclass{article}
\usepackage{unicode-math}
\setmainfont{Georgia}
\setmathfont[Scale=MatchLowercase]{Cambria Math}
\begin{document}
n $n \sqrt[n]{n}$
\end{document}
上面的代码在使用 XeTeX 排版时会产生错误,提示“尺寸太大”。删除[Scale=MatchLowercase]
可以解决问题,但我需要我正在使用的其他文本和数学字体组合的选项。
这个问题似乎是最近才出现的。我上次排版使用unicode-math
和包含的XeTeX 文档\sqrt[n]{n}
大约是在一年前,当时还没有出现这个问题。最新版本之一,即unicode-math
0.8m还是0.8n?
尽管如此,输出的 PDF 文件还是没问题的。我不确定我是否应该担心,但不得不不断忽略错误是很不方便的。作为一种解决方法,我^{1/n}
现在将使用符号。
答案1
更新
自unicode-math
v0.8o (2019/03/04) 起,此错误已修复,可供正常Scale
使用。更新包括Ulrike Fischer 答案的一个变体更重要的是,fam 2 和 3 中字体尺寸的设置比较混乱。
ScaleAgain = 1.00001
从和ScaleAgain = 0.99999
到ScaleAgain = 1.0001
和的转变ScaleAgain = 0.9999
有效地降低集合的上界 乙见下面的定理 1。集合 乙现在终止于 左右 k=10000
,也就是 左右Scale=0.153
。这意味着,只要用户请求的Scale
是多于 0.153,然后unicode-math
才能正确设置字体尺寸。
如果请求的Scale
值低于 0.153,则字体尺寸问题仍然存在。但我们认为正常使用永远不会产生Scale=0.153
或更低的值,因此我们在大多数情况下是安全的。查看更详细的分析这里和这里。
旧答案
虽然我同意 Ulrike Fischer 的观点,认为这是一个unicode-math
bug,但恐怕我不得不反对“\__um_fontdimen_to_percent:nN
损坏”的说法。事实上,使用\dim_to_decimal_in_sp:n
是一个很大的改进,但它不是真正的问题出在哪里。我将首先提出我的解决方案,然后尝试讨论根本原因。
请注意,以下解决方案只是临时的,直到unicode-math
下一版本中修复此问题为止。
解决方案
对于相对简单的解决方案,您可以使用新功能ScaleAgain
稍微扭曲字体大小(人眼看不到):
\documentclass{article}
\usepackage{unicode-math}% v0.8n, 2019/02/15
\setmainfont{Georgia}
\setmathfont[Scale=MatchLowercase,ScaleAgain=0.99999]{Cambria Math}
\begin{document}
n $n \sqrt[n]{n}$
\end{document}
实际上,您必须尝试ScaleAgain
接近 1 的范围才能进行编译。同样,这个问题将在 的下一个版本中得到修复unicode-math
。
unicode-math
关于v0.8n溢出行为的一个定理
对于那些对奇怪的溢出行为感兴趣的人来说,这里有一个定理,基于 v0.8nScaleAgain
中的两个固定因素。unicode-math
首先来可视化一下哪些Scale
是安全的,哪些可能导致问题:
靠近
Scale=1
:
靠近Scale=1.2
:
靠近Scale=1.5
:
全部绿色的线段代表安全
Scale
因素,而红色的线段代表有问题的。尤其是
Scale=1.031369386
,,Scale=1.031374755
和Scale=1.031384644
Scale=1.031390014
都导致! Dimension too large
。 靠近Scale=1.03138
:
讨论
Georgia 和 Cambria Math 的 x 高度分别为986/2048
和956/2048
。 并且Scale=MatchLowercase
被 正确转换为Scale=1.03138
。fontspec
现在,如果我们应用建议重新定义\__um_fontdimen_to_percent:nN
当使用拉丁现代数学时,我们会惊讶地发现:
\documentclass{article}
\usepackage{unicode-math}% v0.8n, 2019/02/15
% https://tex.stackexchange.com/a/475802, by Ulrike Fischer:
\ExplSyntaxOn
\cs_set:Nn \__um_fontdimen_to_percent:nN
{
\fp_eval:n { \dim_to_decimal_in_sp:n { \fontdimen #1 #2 } / 100 }
}
\ExplSyntaxOff
\newcommand*\tempscale{1.03138}% Also fails at 1.02, 1.05, 1.07
\setmathfont[Scale=\tempscale]{latinmodern-math.otf}
\begin{document}
n $n \sqrt[n]{n}$
\end{document}
仍然会产生! Dimension too large.
错误。
更奇怪的是,如果我们改用或的比例因子 1.03137
, 1.03139
那么您的 Georgia + Cambria Math 示例就可以成功编译,我的拉丁现代数学示例也可以成功编译(无论是否重新定义\__um_fontdimen_to_percent:nN
)。
问题的根源ScaleAgain
在于 的新功能fontspec
,该功能旨在解决长期存在的问题(请参阅使用 unicode-math 和缩放功能放置上标和缩放选项无法与 LuaLaTeX 完全兼容)。哦,还有 TeX“不擅长数学”的事实。
要正确设置与数学相关的旧字体尺寸,unicode-math
必须加载相同的数学字体三次。但是 TeX 不允许以相同大小加载同一种字体两次,因此unicode-math
必须在第二次和第三次加载时以略有不同的大小加载字体。这些略有不同的大小是通过复合ScaleAgain
上一个比例因子。这是在 中引入的 主要原因fontspec
,因此unicode-math
可以ScaleAgain=1.00001
第二次执行ScaleAgain=0.99999
第三次。作为我的评论指出,unicode-math
由于 TeX 的二进制算法,有时无法区分这三种尺寸。
你的例子很“不幸” Scale=1.03138
,有 ,翻译成Round( 1.03138 * 2^16 ) = 67593
。之后ScaleAgain=1.00001
,TeX 看到1.03139
,翻译成Round( 1.03139 * 2^16 ) = 67593
。因此 TeX 认为第二个系列和第一个系列是相同的字体,并继续在 的指令下覆盖 fontdimen's unicode-math
。这会导致溢出,因为新的 fontdimen's 不再是小于一的百分比,而是现在可能变得相当大的物理长度。
使用\setmathfont[Scale=MatchLowercase,ScaleAgain=0.99999]{Cambria Math}
,我们基本上试图防止 TeX 意外加载相同大小的数学字体。
答案2
我认为的定义\__um_fontdimen_to_percent:nN
是错误的,应该\dim_to_decimal_in_sp
使用\dim_to_decimal:n
\documentclass{article}
\usepackage{unicode-math}
\ExplSyntaxOn
\cs_set:Nn \__um_fontdimen_to_percent:nN
{
\fp_eval:n { \dim_to_decimal_in_sp:n { \fontdimen #1 #2 } / 100 }
}
\ExplSyntaxOff
\setmainfont{Georgia}
\setmathfont[Scale=MatchLowercase]{Cambria Math}
\begin{document}
n $n \sqrt[n]{n}$
\end{document}