我可以缩小 luaotfload 生成的 lua 表吗?

我可以缩小 luaotfload 生成的 lua 表吗?

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 个字符)。

问题

  1. luaotfload如果我建立一些轻量级的 lua 表文件会起作用吗?
  2. 是否有工具可以调整这些 lua 表文件?如果没有,我该如何手动操作并指示luaotfload加载它?
  3. 它会加快我的编译时间吗?

编辑

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模式,而不是nodeLuaotfload 默认的模式。这可以大大加快段落处理速度。

相关内容