使用非数学 OpenType 字体进行数学字距调整

使用非数学 OpenType 字体进行数学字距调整

我在 Garamond Premier Pro 中设置论文,它不支持 OpenType 数学。尽管如此,通过混合和匹配,我还是设法拼凑出了一些可用的东西,但有时数学模式下的字距调整不太令人满意。

我想知道是否有办法全局修复此问题,即不必手动调整每个实例的字距。我认为不可能将这些对添加到字体的字距调整表中,因为冲突发生在罗马分隔符和斜体字母之间。此外,分隔符甚至不是来自 Garamond,因为unicode-math 和括号缩放

MWE:

\documentclass{standalone}

\usepackage{amsmath}
\usepackage{amssymb}

\usepackage{fontspec}
\usepackage[math-style=ISO,bold-style=ISO,nabla=upright,partial=upright]{unicode-math}

\def\basemathfont{Latin Modern Math}

\def\myfont{Garamond Premier Pro}
\def\mymathfont{\myfont}
\def\myboldfont{ Semibold}
\def\myitalicfont{ Italic}

\setmainfont[Ligatures=TeX,
RawFeature={+calt,+onum},
ItalicFeatures={RawFeature={+calt,+dlig,+onum,+cswh,+swsh}}]{\myfont}

\let\amp\&
\renewcommand{\&}{{\fontspec{EB Garamond}\textit{\amp}}}

\setmathfont{\basemathfont}

\setmathfont[range={\mathup/{latin,Latin,greek,Greek,num},\partial,
  \mathpunct,\mathbin,\mathrel,\infty,\mathpercent,\mathampersand,\mathdollar,\mathquestion},
CharacterVariant={5,11},Numbers=Lining]{\mymathfont}
\setmathfont[range={\mathit/{latin,Latin,greek,Greek,num},\ell},
CharacterVariant={5,11},Numbers=Lining]{\mymathfont \myitalicfont}
\setmathfont[range=\mathbfup/{latin,Latin,greek,Greek,num},
CharacterVariant={5,11},Numbers=Lining]{\mymathfont \myboldfont}
\setmathfont[range=\mathbfit/{latin,Latin,greek,Greek,num},
CharacterVariant={5,11},Numbers=Lining]{\mymathfont \myboldfont \myitalicfont}


\setmathfont[range={\otimes,\oplus,\square,\boxtimes,\boxminus,\boxplus,\cdot,\nabla,\ll,\gg,\lll,\ggg,\mathcolon,\Rightarrow,\Longrightarrow,\Leftrightarrow,\Longleftrightarrow}]{\basemathfont}
\setmathfont[range={\mathcal,\mathscr,\mathbfscr,
  "2AA1,"2AA2,"2AF7,"2AF8,\lesssim,\gtrsim,\in,\notin,
  \sumint,\equiv,\mp,\prime,\dprime,\trprime,\propto,\sim,\rightarrow,\leftarrow,\leftrightarrow,
  \dots,\ddots,\vdots,\parallel,\perp}]{XITS Math}

\AtBeginDocument{\Umathcode`\* = 0 0 "002A\relax}

% Blackboard bold from AMS math
\DeclareSymbolFont{AMSb}{U}{msb}{m}{n}
\protected\def\mathbb#1{{\mathchar\numexpr256*\symAMSb+`#1\relax}}

\begin{document}
$(j)$
$(f)$
$f(x)$
$[f]$
$\{f\}$
$\displaystyle\left.\frac{\mathrm{d}}{\mathrm{d}x}f\right|_{x=4}$
\end{document}

得出以下结果: 数学字距调整失败,Garamond Premier Pro LuaLaTeX 版本: 数学字距调整失败,Garamond Premier Pro,LuaLaTeX 版本

EB Garamond 也出现了类似的结果

\documentclass{standalone}

\usepackage{amsmath}
\usepackage{amssymb}

\usepackage{fontspec}
\usepackage[math-style=ISO,bold-style=ISO,nabla=upright,partial=upright]{unicode-math}

\def\basemathfont{Latin Modern Math}

\def\myfont{EB Garamond}
\def\mymathfont{\myfont}
\def\myitalicfont{ 12 Italic}

\setmainfont[Ligatures=TeX,
RawFeature={+calt,+onum},
ItalicFeatures={RawFeature={+calt,+dlig,+onum,+cswh,+swsh}}]{\myfont}

\let\amp\&
\renewcommand{\&}{{\fontspec{EB Garamond}\textit{\amp}}}

\setmathfont{\basemathfont}

\setmathfont[range={\mathup/{latin,Latin,greek,Greek,num},\partial,\mathpunct,\mathbin,\mathrel,\infty,\mathpercent,\mathampersand,\mathdollar,\mathquestion},CharacterVariant={5,11},Numbers=Lining]{\mymathfont}
\setmathfont[range={\mathit/{latin,Latin,greek,Greek,num},\ell},CharacterVariant={5,11},Numbers=Lining]{\mymathfont \myitalicfont}

\setmathfont[range={\otimes,\oplus,\square,\boxtimes,\boxminus,\boxplus,\cdot,\nabla,\ll,\gg,\lll,\ggg,\mathcolon,\Rightarrow,\Longrightarrow,\Leftrightarrow,\Longleftrightarrow}]{\basemathfont}
\setmathfont[range={\mathcal,\mathscr,\mathbfscr,
  "2AA1,"2AA2,"2AF7,"2AF8,\lesssim,\gtrsim,\in,\notin,
  \sumint,\equiv,\mp,\prime,\dprime,\trprime,\propto,\sim,\rightarrow,\leftarrow,\leftrightarrow,
  \dots,\ddots,\vdots,\parallel,\perp}]{XITS Math}

\AtBeginDocument{\Umathcode`\* = 0 0 "002A\relax}

\DeclareSymbolFont{AMSb}{U}{msb}{m}{n}
\protected\def\mathbb#1{{\mathchar\numexpr256*\symAMSb+`#1\relax}}

\begin{document}
$(j)$
$(f)$
$f(x)$
$[f]$
$\{f\}$
$\displaystyle\left.\frac{\mathrm{d}}{\mathrm{d}x}f\right|_{x=4}$
\end{document}

EB Garamond 数学字距调整失败 LuaLaTeX 版本: 数学字距调整失败,EB Garamond,LuaLaTeX 版本

编辑:根据评论添加了 LuaLaTeX 版本的示例。要使其正常工作,必须\RequirePackage{luatex85}在顶部添加,如果是 Garamond Premier Pro,则使用文件名而不是字体名称来指定字体(这确实不是可以使用 XeLaTeX)。

答案1

以下摘录解释了 XeTeX 和 LuaTeX 之间的差异mathastext 的文档

编辑这段摘录脱离了上下文,第一句话有点含糊;应该读作“XeTeX 可能会创建斜体更正,但它不会不是在数学模式下使用时遵循 TeXBook 附录 G,与 LuaLaTeX 相反”。我现在(四年后)对此进行了进一步研究,并在下面报告了一些有趣的发现也关于纯文本模式

从 2012/12/28 的简短测试来看,XeTeX 似乎不会为 OpenType 字体创建假斜体校正。因此,当数学模式中的字母使用 OpenType(文本)字体,并且文档使用 XeTeX 引擎编译时,本节中描述的数学模式 TeX 放置算法效果不佳。另一方面,LuaLaTeX 似乎在使用 OpenType 字体时实现了斜体校正,但仅限于斜体字体(据我所知)。在最近的 TeX 安装上尝试以下操作(将使用 OpenType Latin Modern 字体)并比较两个引擎的输出:

\documentclass{article}
\usepackage{fontspec}
\begin{document}
\Huge
$\mathit{f_i^i}$\par $\mathrm{f_i^i}$
\end{document}

注释掉 fontspec 行并使用 pdfLaTeX。在我的 TeX 安装中,所有三个输出都不同。XeTeX 没有斜体校正。LuaLaTeX 有,但只针对斜体字体。pdfLaTeX 有斜体和直立字体的校正。


大约一年前我再次检查,发现没有任何变化。在您的示例中,我检查发现相对于右分隔符的更好间距确实是通过 LuaLaTeX 插入斜体更正来解释的。


这是我现在做的一些额外实验,关于斜体校正是否定义以及是否在数学模式下使用它们。

根据 TeXBook,如果该\fontdimen2参数消失,则当字母连续时应使用斜体校正。LuaLaTeX 会这样做,但 XeTeX 不会。此外,还有一个问题是 XeTeX 定义的斜体校正似乎与 LuaLaTeX 定义的斜体校正不同(这也显示出纯文本模式的差异34.18512pt,参见下面与 相比 35.18033pt的不同水平盒子的宽度\hbox{f\/g\/k)})。

测试文档:

% Time-stamp: <03-11-2016 15:07:54 CET>

\documentclass{article}
\usepackage{fontspec}
\usepackage{ifluatex}
\begin{document}

\Huge
% $\mathit{f_i^i} \mathit{(f\/)}$\par $\mathrm{f_i^i}$

\ifluatex
\usefont {EU2}{lmr}{m}{it}
\else
\usefont {EU1}{lmr}{m}{it}
\fi

\leavevmode\hbox{fgk}

\leavevmode\hbox{f\/g\/k}

\typeout{\the\fontdimen2\font}% 8.70801pt in both engines

$\mathit{fgk}$

\fontdimen2\font 0pt

$\mathit{fgk}$

\showoutput
\end{document}

使用 XeTeX 记录:

....\hbox(17.51552+5.0755)x29.856
.....\EU1/lmr/m/it/24.88 fgk
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 7.40898
...\hbox(17.51552+5.0755)x345.0, glue set 295.81488fil
....\hbox(0.0+0.0)x15.0
....\hbox(17.51552+5.0755)x34.18512
.....\EU1/lmr/m/it/24.88 f
.....\kern 3.63248
.....\EU1/lmr/m/it/24.88 g
.....\kern 0.69664
.....\EU1/lmr/m/it/24.88 k
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 7.40898
...\hbox(17.51552+5.07552)x345.0, glue set 300.144fil
....\hbox(0.0+0.0)x15.0
....\mathon
....\hbox(17.51552+5.07552)x29.856
.....\EU1/lmr/m/it/24.88 glyph#55
.....\EU1/lmr/m/it/24.88 glyph#59
.....\EU1/lmr/m/it/24.88 glyph#70
....\mathoff
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 7.40897
...\hbox(17.51552+5.07552)x345.0, glue set 300.144fil
....\hbox(0.0+0.0)x15.0
....\mathon
....\hbox(17.51552+5.07552)x29.856
.....\EU1/lmr/m/it/24.88 glyph#55
.....\EU1/lmr/m/it/24.88 glyph#59
.....\EU1/lmr/m/it/24.88 glyph#70
....\mathoff

使用 LuaLaTeX 记录:

注意:\kern1.59232之前的\mathoff(将 参数设置为零之后\fontdimen2)是字母 的斜体校正。XeTeX 没有进行这样的斜体校正,而且它为 分配的 k斜体校正值(24.88 磅大小)不是LuaLaTeX 的 。k1.09473pt1.59232pt

(尝试\leavevmode\hbox{k\/}

> 12.29073-1.09473;
                                   11.19600

> 12.78831-1.59232;
                                   11.19599

....\hbox(0.0+0.0)x15.0, direction TLT
....\hbox(17.51552+5.07552)x29.856, direction TLT
.....\EU2/lmr/m/it/24.88 f
.....\EU2/lmr/m/it/24.88 g
.....\EU2/lmr/m/it/24.88 k
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 7.40897
...\hbox(17.51552+5.07552)x345.0, glue set 294.81967fil, direction TLT
....\localpar
.....\localinterlinepenalty=0
.....\localbrokenpenalty=0
.....\localleftbox=null
.....\localrightbox=null
....\hbox(0.0+0.0)x15.0, direction TLT
....\hbox(17.51552+5.07552)x35.18033, direction TLT
.....\EU2/lmr/m/it/24.88 f
.....\kern 4.13008
.....\EU2/lmr/m/it/24.88 g
.....\kern 1.19424
.....\EU2/lmr/m/it/24.88 k
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 7.40897
...\hbox(17.51552+5.07552)x345.0, glue set 298.5517fil, direction TLT
....\localpar
.....\localinterlinepenalty=0
.....\localbrokenpenalty=0
.....\localleftbox=null
.....\localrightbox=null
....\hbox(0.0+0.0)x15.0, direction TLT
....\mathon
....\hbox(17.51552+5.07552)x31.44832, direction TLT
.....\EU2/lmr/m/it/24.88 f
.....\EU2/lmr/m/it/24.88 g
.....\EU2/lmr/m/it/24.88 k
.....\kern1.59232
....\mathoff
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 7.40897
...\hbox(17.51552+5.07552)x345.0, glue set 293.22736fil, direction TLT
....\localpar
.....\localinterlinepenalty=0
.....\localbrokenpenalty=0
.....\localleftbox=null
.....\localrightbox=null
....\hbox(0.0+0.0)x15.0, direction TLT
....\mathon
....\hbox(17.51552+5.07552)x36.77264, direction TLT
.....\EU2/lmr/m/it/24.88 f
.....\kern4.13008
.....\EU2/lmr/m/it/24.88 g
.....\kern1.19424
.....\EU2/lmr/m/it/24.88 k
.....\kern1.59232
....\mathoff

初始答案已被编辑以删除对 cos、sin 等运算符名称的操作...

nb:mathastext(不建议将其用于 OpenType 字体,但我尝试在此使用其相当复杂的数学活动字母机制)没有针对“直立”和“斜体”不同字体的官方接口,“斜体”(如果使用)应该仅通过 NFSS 形状说明符(通常为“it”或“sl”)与“直立”字体不同。这里我们直接使用 EB Garamond 12 Italic,但对于 mathastext,它从 fontspec 接收它作为“直立”字体,即 NFSS 形状说明符为“n”。这就是操作符名称也使用斜体字体的原因。因此,编辑会恢复 mathastext 对用于操作符名称的字体的相应操作。

另一个补充说明是 mathastext 保留了两个数学组。这里实际上只需要一个,但目前没有选项可以将其告诉 mathastext。事实上,我们甚至可以不使用任何额外的数学组,因为所需的数学组已经由 unicode-math 声明。但同样,mathastext 主要用于与传统 TeX 字体一起使用的 pdftex。

\documentclass{standalone}

\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{fontspec}
\usepackage[math-style=ISO,bold-style=ISO,nabla=upright,partial=upright]{unicode-math}

\def\basemathfont{Latin Modern Math}

\def\myfont{EB Garamond}
\def\mymathfont{\myfont}
\def\myitalicfont{ 12 Italic}

\setmainfont[Ligatures=TeX,
RawFeature={+calt,+onum},
ItalicFeatures={RawFeature={+calt,+dlig,+onum,+cswh,+swsh}}]{\myfont}

\let\amp\&
\renewcommand{\&}{{\fontspec{EB Garamond}\textit{\amp}}}

\setmathfont{\basemathfont}

\setmathfont[range={\mathup/{latin,Latin,greek,Greek,num},\partial,\mathpunct,\mathbin,\mathrel,\infty,\mathpercent,\mathampersand,\mathdollar,\mathquestion},CharacterVariant={5,11},Numbers=Lining]{\mymathfont}
\setmathfont[range={\mathit/{latin,Latin,greek,Greek,num},\ell},CharacterVariant={5,11},Numbers=Lining]{\mymathfont \myitalicfont}

% load mathastext minimally
\makeatletter\let\operator@fontORI\operator@font\makeatother
\usepackage[basic, nodigits, nohbar, defaultimath,
            defaultalphabets, defaultmathsizes]{mathastext}
\makeatletter\let\operator@font\operator@fontORI\makeatother
% next line after looking in log file, there is surely better way, but I don't
% know if unicode-math has public interface for fetching the assigned
% NFSS font family name
\MTfamily{EBGaramond12Italic(0)}\Mathastext
%  Perhaps an alternative would be to to do
% skip the initial \setmainfont and issue instead
% \setmainfont[CharacterVariant={5,11},Numbers=Lining]{\mymathfont
% \myitalicfont}
% then:
% \usepackage[...]{mathastext}
% then:
% the correct \setmainfont.
%   but  I don't know how unicode-math interacts with the setmainfont setting
% 
% mathastext does not know that the font is "italic" (from the NFSS point of
% view it is defined with normal not italic shape) and it will thus try
% to insert "italic corrections" (cf documentation.) Get rid of that:
\MTnoicinmath
% Now we can use mathastext's facilities:
\MTsetmathskips{f}{5mu}{5mu}
\MTsetmathskips{j}{5mu}{3mu}
% Nota Bene: such skips are ignored inside inside \math... commands


\setmathfont[range={\otimes,\oplus,\square,\boxtimes,\boxminus,\boxplus,\cdot,\nabla,\ll,\gg,\lll,\ggg,\mathcolon,\Rightarrow,\Longrightarrow,\Leftrightarrow,\Longleftrightarrow}]{\basemathfont}
\setmathfont[range={\mathcal,\mathscr,\mathbfscr,
  "2AA1,"2AA2,"2AF7,"2AF8,\lesssim,\gtrsim,\in,\notin,
  \sumint,\equiv,\mp,\prime,\dprime,\trprime,\propto,\sim,\rightarrow,\leftarrow,\leftrightarrow,
  \dots,\ddots,\vdots,\parallel,\perp}]{XITS Math}

\AtBeginDocument{\Umathcode`\* = 0 0 "002A\relax}

\DeclareSymbolFont{AMSb}{U}{msb}{m}{n}
\protected\def\mathbb#1{{\mathchar\numexpr256*\symAMSb+`#1\relax}}


\begin{document}
$(j)$
$(f)$
$[f]$
$\{f\}$
$\displaystyle\left.\frac{\mathrm{d}}{\mathrm{d}x}f\right|_{x=4}$
\end{document}
% Local Variables:
% TeX-engine: xetex
% End:

在我的 TL2016 上产生:

在此处输入图片描述

您可以根据自己的喜好调整字母左侧和右侧的额外跳过,\MTsetmathskips如上图所示,仅适用于fj

我尝试使用 luatex(使用),这是在我的 TL2016 上使用原始代码(注释掉luatex85所有相关内容)得到的结果:mathastext

在此处输入图片描述

注意这两个导数的不同之处,在 XeTeX 中的渲染很奇怪(参见顶部的“d”;这与使用 无关mathastext,不使用 也一样)。而且分数符号宽度似乎不同。

还有一件事是,出于某种原因,我的等号与你的第二张图片不一样。我图片中的等号使用了 TeXLive 的 EB Garamond。


评论中提出了一个关于 $ij$ 的问题。我忘记了,但你可以使用 defined \Mathnormalby mathastext: 在其中,通过其命令配置的额外跳过\MTsetmathskips将被取消。以下是\MTsetmathskips{j}{5mu}{3mu}上述内容:

在此处输入图片描述

从输入

\MTsetmathskips{j}{5mu}{3mu}

$ij, ijk$

$\Mathnormal{ij}, \Mathnormal{ijk}$

$i\Mathnormal{j}, i\Mathnormal{j}k$

跳过也会在里面消失,\mathnormal但后者未被修改mathastext(参见其选项defaultalphabets),未配置为使用 EB Garamond 12 Italic。

相关内容