的下一个版本babel
将为 CJK 提供基本的换行功能luatex
。当我进行一些实验时,我发现 Fandol 家族中存在一种奇怪且令人费解的行为。该文件为:
\documentclass{article}
\usepackage{fontspec}
\setmainfont{FandolSong-Regular.otf}
\begin{document}
\section{现代建筑教育}
中国的现代建筑教育体系不是来自本土建筑营造的延续
\end{document}
结果是:
请注意,章节主体紧跟标题,没有任何垂直分隔。它与xetex
中的许多其他字体配合使用时效果良好luatex
,但与 Fandol 配合使用时效果不佳。(TeXLive 2018 和 2019。)
答案1
这里发生了什么?让我们先看看\section
实际做了什么:在 中article.cls
,\section
定义为
\newcommand\section{\@startsection {section}{1}{\z@}%
{-3.5ex \@plus -1ex \@minus -.2ex}%
{2.3ex \@plus.2ex}%
{\normalfont\Large\bfseries}}
在 中source2e.pdf
,我们可以找到 的所有参数的解释\@startsection
。对于第五个参数,它表示
跳过后:如果为正,则跳至下方标题,否则为负,跳至进入标题的右侧。
您在 Fandol 中观察到的是标题与常规文本之间没有空格的标题,因此显然会触发第二种情况。但这意味着参数是不积极。这可能看起来很奇怪,因为上面的命令通过了{2.3ex \@plus.2ex}
,这当然看起来是积极的。
但是让我们退一步来看看{2.3ex \@plus.2ex}
实际上是什么:\@plus...}
与我们无关,所以我们只看2.3ex
。这里的单位ex
是当前字体的“x 高度”,但x-height
对于像 Fandol 这样的 CJK 字体来说, a 没有意义。现在在相应的 OpenType 字段中,Fandol 必须设置一些值,因此 Fandol 将其“x 高度”设置为0
。这由 luaotfload 拾取,它将 x 高度传递0
给 LuaTeX。现在2.3ex=2.3*"x-height"=2.3*0=0
。
因此,afterskip
参数设置为0
,它不是正数。因此,根据其文档,\@startsection
生成一个插入标题,在插入标题右侧不留任何空间。
现在 XeTeX 和 luaotfload 之间的区别在于缺少的 x 高度值的处理:
luaotfload 仅在字体不包含任何 x 高度时才使用 fallback,而 XeTeX 也会在字体明确指定 x 高度时使用 fallback 0
。您可以通过修补字体在 LuaTeX 中模拟 XeTeX 行为:
\documentclass{article}
\directlua{
luatexbase.add_to_callback("luaotfload.patch_font", function (fontdata)
local parameters = fontdata.parameters
if not parameters then return end
if not (parameters.x_height or parameters[5] or 0) == 0 then return end
if fontdata.characters and fontdata.characters[120] then
parameters.x_height = fontdata.characters[120].height
else
parameters.x_height = (parameters.ascender or 0)/2
end
end, "Fix x-height")
}
\usepackage{fontspec}
\setmainfont{FandolSong-Regular.otf}
\begin{document}
\section{现代建筑教育}
中国的现代建筑教育体系不是来自本土建筑营造的延续
\end{document}