當 \setmathfont 具有選項 Scale=MatchLowercase 時出現「尺寸太大」錯誤

當 \setmathfont 具有選項 Scale=MatchLowercase 時出現「尺寸太大」錯誤
\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中。套裝 現在終止於 around  k=10000,即 around Scale=0.153。這意味著,只要用戶請求Scale的是多於 0.153,則unicode-math可以正確設定字體尺寸。

如果請求的值Scale低於 0.153,則字體尺寸問題仍然存在。但人們認為正常使用永遠不會產生Scale=0.153或降低,因此我們對大多數零件來說是安全的。查看更詳細的分析這裡這裡


舊答案

雖然我同意 Ulrike Fischer 的觀點,認為這是一個unicode-math錯誤,但恐怕我不得不不同意「\__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
規模1
靠近Scale=1.2
規模1.2
靠近Scale=1.5
規模1.5

全部綠色的線段代表安全Scale因素,而紅色的線段代表有問題的線段。

這是嚴格的數學描述:
定理

特別是,Scale=1.031369386Scale=1.031374755Scale=1.031384644Scale=1.031390014 全部導致 ! Dimension too large。靠近Scale=1.03138
規模1.03138


討論

Georgia 和 Cambria Math 的 x 高度分別為986/2048956/2048。並Scale=MatchLowercase正確轉換Scale=1.03138fontspec.現在,如果我們應用建議重新定義\__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的unicode-math。這會導致溢出,因為新的 fontdimen 不再是小於 1 的百分比,而是現在可能變得相當大的物理長度。

使用\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}

相關內容