luatex
每次使用我的自定义类 (Minion Pro、Myriad Pro、Minion Math、Latin Modern Mono、Latin Modern Math、XITS) 运行时都会加载大量 otf 字体luaLaTeX
。以下是从我的自定义类中摘录的:
\RequirePackage{fontspec}
\RequirePackage[math-style = TeX]{unicode-math}
\setmathfont[version=bold]{MinionMath-Bold}
\setmathfont[Extension = .otf,
Scale = 1,
Script = Math,
SizeFeatures = {%
{%
Size = -6,
Font = MinionMath-Tiny,
Style = MathScriptScript},
{%
Size = 6-8.4,
Font = MinionMath-Capt,
Style = MathScript},
{%
Size = 8.4-,
Font = MinionMath-Regular},
}
]{MinionMath-Regular}
\setmathfont[range={\mathfrak}]{latinmodern-math.otf}
\setmathfont[range={\mathcal}]{latinmodern-math.otf}
\setmathfont[range={\mathscr}]{xits-math.otf}
\setmathfont[range={}]{MinionMath-Regular.otf}
\usepackage{unicode-minionmath}
\setmainfont{MinionPro}[
Extension = .otf,
UprightFont = *-Regular,
BoldFont = *-Bold,
ItalicFont = *-It,
BoldItalicFont = *-BoldIt,
]
\setsansfont{MyriadPro}[
Extension = .otf,
UprightFont = *-Regular,
BoldFont = *-Semibold,
ItalicFont = *-It,
BoldItalicFont = *-SemiboldIt,
]
\setmonofont{LatinModernMono}
在我的系统(Linux、SSD、Core i3)上,每次运行至少需要 10 秒。如果我理解正确的话,大部分时间都花在读取字节编译的 lua 表上,这些表存储了处理字体所需的所有信息otf
。
查看那些表格(存储在中~/.texlive2016/texmf-var/luatex-cache/generic/fonts/otl/
),我发现那里的大多数元素(unicode字符)几乎从未在我的文档中使用过(用法语书写:我需要 ASCII + 一些重音字母,可能少于 200 个字符)。
问题
luaotfload
如果我建立一些轻量级的 lua 表文件会起作用吗?- 是否有工具可以调整这些 lua 表文件?如果没有,我该如何手动操作并指示
luaotfload
加载它? - 它会加快我的编译时间吗?
编辑
2 的答案可能是使用 之类的工具在字体级别构建我的字体的适当子集fontforge
,从而创建“新的”轻量级字体。据我谷歌搜索到的信息,此技术用于 Web TTF 字体以最小化下载的字体大小。因此,我在问题中添加了第 4 项:“对字体进行子集化是缩小 lua 表文件大小的好方法吗?我可以使用 fontforge 处理 otf 字体吗?如何操作?是否有任何许可限制?”
答案1
每次使用我的自定义类运行 luaLaTeX 时,luatex 都会加载大量 otf 字体 [...] 在我的系统(linux、SSD、core i3)上,每次运行至少需要 10 秒。
您指的是 Luatex 的整个过程吗?我无法谈论 Latex,但在 Context 中,更复杂的文档可以轻松实现这一目标。
如果我理解正确的话,大部分时间都花在读取字节编译的 lua 表上,该表存储了处理 otf 字体所需的所有信息。
Lua 是一种非常高效的语言。解析 Lua 程序非常高效。加载字节编译程序更是如此。这不太可能是你面临的瓶颈。
您可以轻松验证这一点:确定缓存路径( 的最后一行luaotfload-tool -h
),列出子目录otl/
并选择一个字节码文件。扩展名是.luc
。我选择了一个我所知道的最大的文件:kozminpr6n-regular.luc,大小为 2,388,708 字节。这些文件是有效的 Lua 程序,因此我们可以直接用 Luatex 加载它们。为了最大程度地降低 IO 损失,我们还首先清除了 OS 缓存:
$ sudo bash -c "echo 3 >/proc/sys/vm/drop_caches"
$ time texlua /home/phg/.local/texlive/2016/texmf-var/luatex-cache/generic/fonts/otl/kozminpr6n-regular.luc
real 0m0.240s
user 0m0.100s
sys 0m0.017s
编辑
进一步的测量:我决定检查将从缓存加载的字体传递到 Luatex 是否对性能有显著影响。结果发现影响微不足道。
以下是测试设置
加载字体列表并测量运行时间。为了进行更精确的测量,它依赖于
卢阿波西库。时间分为缓存检索本身(fonts.definers.read()
)和将结果输入到
font.define()
。
总结一下结果:在我的老旧系统上,强制 38 种字体通过加载器会使运行时间增加 1.9 秒;如果操作系统缓存很热,这个数字会缩短到大约 1.5 秒。Adobe 的复杂字体大约需要 50 毫秒才能加载。巨大的字体
kozminpr6n-regular.otf
是一个异常值,检索大约需要 300 毫秒,传递需要 50 毫秒font.define()
。
结束编辑
240 秒即可加载 Luatex 二进制文件、生成 Lua 解释器并加载一个巨大的字体表。在 2012 年的低端台式机上。还不错,尤其是考虑到字体通常是按需加载的,而不仅仅是在某个时候定义。
如果我构建一些轻量级的 lua 表文件,luaotfload 会工作吗?
这些是缓存文件。下次发生任何更改时,它们将被覆盖,无需询问。您必须对字体加载器进行修改,才能使更改生效。
是否有工具可以调整这些 lua 表文件?
如上所示,您可以使用 Lua 加载它们,并像任何普通表一样操作它们。相应的文本表示(在文件中.lua
)是纯文本,因此您可以使用编辑器。但它们需要进行字节编译(texluac(1)
)才能与加载器一起使用。
If not, how can
我手动执行此操作并告诉 luaotfload 加载它?
字体加载器会先在缓存中查找字体文件,但如果字体文件不匹配,它也会重写缓存。因此,您必须破解加载器才能避免这种情况。
它会加快我的编译时间吗?
不太可能。加载字节码非常高效,一旦表进入内存,就只会使用处理输入所需的部分。
2 的答案可能是使用 fontforge 之类的工具在字体级别构建适当的字体子集
扔掉你不喜欢的表格。这样可以减少表格大小。确保你没有违反供应商的许可条款。其中一些条款禁止对文件进行任何修改。
看一下这些表格[…]在我看来,那里的大多数元素(unicode字符)几乎从未在我的文档中使用过(用法语写:我需要 ASCII + 一些重音字母,可能少于 200 个字符)。
如果您只排版基于拉丁文的文本,更有希望的方法是坚持使用base
模式,而不是node
Luaotfload 默认的模式。这可以大大加快段落处理速度。