连字

连字

从 2.7 版开始luaotfload支持字体功能文件(.fea已被删除

ConTeXt 邮件列表Hans 演示了如何通过 Lua 进行字体替换。最新的 ConTeXt 发行版中提供了更多示例 (001002003004005006007

过去我一直使用字体特性文件来实时调整字体的字距。从 Hans 的例子中,我不清楚如何在新语法中调整字距。下面的例子不是按预期工作。

\documentclass{article}
\usepackage{fontspec}
\directlua{
fonts.handlers.otf.addfeature {
    name = "kern",
    {
        type = "pair",
        data = {
            [0x0041] = { [0x0056] = { false, { -200, 0, 0, 0 } } },
        }
    }
}
}
\setmainfont{Latin Modern Roman}
\begin{document}
AV
\end{document}

我们能否获得有关如何使用该fonts.handlers技术调整 LuaTeX 字体功能的全面指南?


相关问题:

(这些涉及到luaotfload.patch_font回调)

答案1

赤红对于试验新方法很有用,因为它是免费的,并且定义了它可以支持的一些功能。以下是其最新版本中定义的功能:

       | r | i | b | bi | sb si |
|------+---+---+---+----+-------|
| c2sc | ✓ | ✓ | ✓ |    |       |
| kern | ✓ | ✓ | ✓ | ✓  | ✓     |
| liga |   |   |   | ✓  |       |
| onum | ✓ | ✓ |   | ✓  |       |
| ordn | ✓ |   |   |    |       |
| pnum | ✓ | ✓ |   | ✓  | ✓     |
| smcp | ✓ | ✓ | ✓ |    |       |
| zero | ✓ |   |   |    |       |

连字

最令人惊讶的是,它只liga以粗体斜体定义,所以让我们先修复它。

以下是我们添加该功能之前的 Crimson:

\documentclass{article}
\usepackage{fontspec}
\setmainfont{Crimson}
\begin{document}
The five baffled officials flew off.

\textit{The five baffled officials flew off.}
\end{document}

示例输出

现在来修复这个问题:

\documentclass{article}
\usepackage{fontspec}
\directlua{
fonts.handlers.otf.addfeature {
    name = "liga",
    {
        type = "ligature",
        data = {
            ['f_f'] = { "f", "f" },
            ['f_i'] = { "f", "i" },
            ['f_f_i'] = { "f", "f", "i" },
            ['f_l'] = { "f", "l" },
            ['f_f_l'] = { "f", "f", "l" },
            ['T_h'] = { "T", "h" },
        }
    },
    "some ligatures"
  }
}
\setmainfont{Crimson}
\begin{document}
The five baffled officials flew off.

\textit{The five baffled officials flew off.}
\end{document}

第二个示例的输出

在 中['f_i'] = { "f", "i" }['f_i']是连字的字形名称,{ "f", "i" }是要连字的字母。因此,如果您的字体将连字称为“fi”而不是“f_i”,则应写入['fi'] = { "f", "i" }。还请注意,在某些字体中,['f_f_b'] = { "f", "f", "b" }不起作用,但['f_f_b'] = { "ff", "b" }可以。

正如 Ulrike Fischer 在tex.stackexchange.com/a/352864在她对这个问题的回答中,如果您luaotfload最近(2017 年 2 月 4 日)进行了更新,则需要修改\directlua如下调用:

\directlua{
  fonts.handlers.otf.addfeature{
    name = "liga",
    type = "ligature",
    data = {
      ['f_f'] = { "f", "f" },
      ['f_i'] = { "f", "i" },
      ['f_f_i'] = { "f", "f", "i" },
      ['f_l'] = { "f", "l" },
      ['f_f_l'] = { "f", "f", "l" },
      ['T_h'] = { "T", "h" },
    },
  }
}

风格和语境替代

某些替代字符是否可取取决于附近的情况。例如,Crimson 的长尾“Q”在“u”之前很有吸引力,但如果它出现在单词末尾,则看起来很傻或与其他字形相冲突。比较一下salt,它在任何地方用替代字符替换字形,以及calt,它仅在某些情况下替换它:

\documentclass{article}
\usepackage{fontspec}
\directlua{
  fonts.handlers.otf.addfeature{
    name = "salt",
    type = "alternate",
    data =
    {
      Q = "Q.alt01",
    },
  }
  fonts.handlers.otf.addfeature{
    name = "calt",
    type = "chainsubstitution",
    lookups = {
      {
        type = "substitution",
        data = {
          ["Q"] = "Q.alt01",
        },
      },
    },
    data = {
      rules = {
        {
          after  = { { "u" } },
          current = { { "Q" } },
          lookups = { 1 },
        },
      },
    },
  }
}
\setmainfont{Crimson}
\begin{document}
(Questions about NASDAQ.) Meh.

{\addfontfeature{RawFeature=+salt}
  (Questions about NASDAQ.) Oops!}

{\addfontfeature{RawFeature=+calt}
  (Questions about NASDAQ.) That’s better.}
\end{document}

示例输出

如果 Crimson 的小写字母中有一个长尾 Q,你可以通过添加如下一行来获得它:["q.sc"] = "q.scalt01",

上级

在这里我找到了原理,或者说部分原理,但最好不要将其应用于 Crimson,因为上级 4-9 和 0 的设计位置要高于上级 1-3,如下面注释 10 中特别明显:

\documentclass{article}
\usepackage{fontspec,realscripts}
% see Ulrike’s answer at tex.stackexchange.com/a/235302/7883
\renewcommand\footnotemarkfont{\addfontfeature{RawFeature={+sups}}}
\renewcommand\fakesuperscript[1]{#1}
\usepackage[paperwidth=180pt,paperheight=150pt,margin=12pt]{geometry}
\directlua{
fonts.handlers.otf.addfeature {
    name = "sups",
    {
        type = "substitution",
        data = {
            one = "¹",
            ["one.onum"] = "¹",
            two = "²",
            ["two.onum"] = "²",
            three = "³",
            ["three.onum"] = "³",
            four = "⁴",
            ["four.onum"] = "⁴",
            five = "⁵",
            ["five.onum"] = "⁵",
            six = "⁶",
            ["six.onum"] = "⁶",
            seven = "⁷",
            ["seven.onum"] = "⁷",
            eight = "⁸",
            ["eight.onum"] = "⁸",
            nine = "⁹",
            ["nine.onum"] = "⁹",
            zero = "⁰",
            ["zero.onum"] = "⁰",
        }
    },
    "footnote figures"
  }
}
\setmainfont{Crimson}
\begin{document}
There\footnote{Note.} are\footnote{Note.} far\footnote{Note.}
too\footnote{Note.} many\footnote{Note.}  footnotes\footnote{Note.}
in\footnote{Note.} this\footnote{Note.}  little\footnote{Note.}
sentence.\footnote{Note.}
\end{document}

sups 功能示例

如果您想要有脚注数字,则必须添加更多这样的行(例如,["one.prop"] = "¹",等等),无论您使用的是默认数字、旧式数字、比例数字、斜线零还是提供的任何其他类型的数字。

对于luaotfload2017 年 2 月,使用\directlua方式如下:

\directlua{
  fonts.handlers.otf.addfeature{
    name = "sups",
    type = "substitution",
    data = {
      one = "¹",
      ["one.onum"] = "¹",
      two = "²",
      ["two.onum"] = "²",
      three = "³",
      ["three.onum"] = "³",
      four = "⁴",
      ["four.onum"] = "⁴",
      five = "⁵",
      ["five.onum"] = "⁵",
      six = "⁶",
      ["six.onum"] = "⁶",
      seven = "⁷",
      ["seven.onum"] = "⁷",
      eight = "⁸",
      ["eight.onum"] = "⁸",
      nine = "⁹",
      ["nine.onum"] = "⁹",
      zero = "⁰",
      ["zero.onum"] = "⁰",
    },
  }
}

删除连字符

Crimson 对于演示如何移除连字符没有多大用处,因此这里是 FPL Neu(github.com/rstub/fplneu) 不带 'fk' 连字符:

\documentclass{article}
\usepackage{fontspec}
\directlua{
fonts.handlers.otf.addfeature {
    name = "nofk",
    {
        type = "multiple",
        data = {
          ["f_k"] = { "f", "k" },
        }
    },
    "get rid of fk ligatures"
  }
}
\setmainfont{FPL Neu}
\begin{document}
Kafka

\addfontfeature{RawFeature=+nofk}
Kafka
\end{document}

示例输出

在 Garamond Premier Pro 等带有长臂 f 的字体中,结果几乎不可见,而且我似乎无法将此nofk功能与额外的字距调整结合起来。

对于luaotfload2017 年 2 月,使用\directlua方式如下:

\directlua{
  fonts.handlers.otf.addfeature{
    name = "nofk",
    type = "multiple",
    data = {
      ["f_k"] = { "f", "k" },
    },
  }
}

在标准连字符中选择

有些字体的liga功能超出了人们的预期。例如,LTC Kaatskill Pro 是一款可爱的 Goudy 设计,它将 œ 变成了标准连字而不是自由连字,结果不仅像“œdema”这样的单词受到影响,甚至“does”和“poem”也受到影响。使用type = "multiple",就像上面的“fk”一样,会修复“does”但会干扰“œdema”,所以我们需要另一种方法。

为了说明这一点,我们来看一下免费提供的加洛林小写字母。使用liga,它产生的结果可以帮助学生轻松进入古文字学课程:

\documentclass[12pt,latin]{octavo}
\usepackage{babel,fontspec,microtype}
\setmainfont{0850 Carolina Tours}
\linespread{1.10345}
\begin{document}
Invocat te, Domine, fides mea quam dedisti mihi, quam inspirasti mihi
per humanitatem Filii tui, per ministerium praedicatoris tui.
\end{document}

输出

出于装饰目的而非学术目的,我们希望删除已定义liga但当代读者不熟悉的内容。

除了无害的“ff”、“fi”、“fl”、“ft”和“ll”之外,还liga添加了“oe”连字符和尾目替换“ae”;它还将“i”和“j”替换为无点版本,并将“ſ”替换为“s”,将“u”替换为“v”,将“V”替换为“U”。我们可以通过关闭来删除这些连字和替换liga,并通过将它们定义为来添加回无害的连字rlig,这是默认情况下启用的功能:

\documentclass[12pt,latin]{octavo}
\usepackage{babel,fontspec,microtype}
\directlua{
  fonts.handlers.otf.addfeature{
    name = "rlig",
    type = "ligature",
    data = {
      ['f_f'] = { "f", "f" },
      ['fi'] = { "f", "i" },
      ['fl'] = { "f", "l" },
      ['f_t'] = { "f", "t" },
      ['l_l'] = { "l", "l" },
    },
  }
}
\setmainfont{0850 Carolina Tours}[
  Ligatures=NoCommon]
\linespread{1.10345}
\begin{document}
Invocat te, Domine, fides mea quam dedisti mihi, quam inspirasti mihi
per humanitatem Filii tui, per ministerium praedicatoris tui.
\end{document}

输出

顽固的字体

有时一个或多个连字符不起作用,按上述方法添加它们也无济于事。当字体的查找以错误的顺序定义连字符时,就会发生这种情况,如哈立德·霍斯尼讲话如果查找特别复杂,则在不编辑字体本身的情况下解决问题可能会非常困难,但通常不需要编辑字体。

例如,Goudy 的新风格在其功能中定义了“fi”和“fl” liga,在其功能中定义了略有不同的“fi”和“fl”字形dlig。还有“ct”、“fb”、“ff”、“ffi”、“fj”、“ffl”、“fk”、“st”和(斜体)“Th”的字形,但没有定义任何功能来简化它们的使用。添加两个字符的连字可以liga工作,但添加“ffi”和“ffl”连字则不行,显然是因为“fi”和“fl”连字已经在查找中了。但是如果我们关闭liga并定义我们想要的连字,那么一切都很好rlig

\documentclass{article}
\usepackage{fontspec}
\directlua{
  fonts.handlers.otf.addfeature{
    name = "rlig",
    type = "ligature",
    data = {
      ['ffi'] = { "f", "f", "i" },
      ['ffl'] = { "f", "f", "l" },
      ['fb'] = { "f", "b" },
      ['ff'] = { "f", "f" },
      ['fh'] = { "f", "h" },
      ['fi'] = { "f", "i" },
      ['fj'] = { "f", "j" },
      ['fk'] = { "f", "k" },
      ['fl'] = { "f", "l" },
    },
  }
  fonts.handlers.otf.addfeature{
    name = "ilig",
    type = "ligature",
    data = {
      ['Th'] = { "T", "h" },
      ['Th.swsh'] = { "T.swsh", "h" },
    },
  }
}
\setmainfont{Newstyle}[
  Script=Default,
  Ligatures=NoCommon,
  Numbers=OldStyle,
  ItalicFeatures={RawFeature=+ilig}]
\begin{document}
The five baffled officials flew off.

\textit{The five baffled officials flew off.}

\textit{\addfontfeatures{Style=Swash}The five baffled officials flew off.}
\end{document}

输出

如果字体的liga功能包含许多连字符,则更容易继续liga,只分解有问题的连字符,然后在 中恢复它们rlig。例如,这会产生与上面相同的输出:

\documentclass{article}
\usepackage{fontspec}
\directlua{
  fonts.handlers.otf.addfeature{
    name = "nolg",
    type = "multiple",
    data = {
      ['fi'] = { "f", "i" },
      ['fl'] = { "f", "l" },
    },
  }
  fonts.handlers.otf.addfeature{
    name = "rlig",
    type = "ligature",
    data = {
      ['ffi'] = { "f", "f", "i" },
      ['ffl'] = { "f", "f", "l" },
      ['fb'] = { "f", "b" },
      ['ff'] = { "f", "f" },
      ['fh'] = { "f", "h" },
      ['fi'] = { "f", "i" },
      ['fj'] = { "f", "j" },
      ['fk'] = { "f", "k" },
      ['fl'] = { "f", "l" },
    },
  }
  fonts.handlers.otf.addfeature{
    name = "ilig",
    type = "ligature",
    data = {
      ['Th'] = { "T", "h" },
      ['Th.swsh'] = { "T.swsh", "h" },
    },
  }
}
\setmainfont{Newstyle}[
  Script=Default,
  Numbers=OldStyle,
  ItalicFeatures={RawFeature=+ilig},
  RawFeature=+nolg]
\begin{document}
The five baffled officials flew off.

\textit{The five baffled officials flew off.}

\textit{\addfontfeatures{Style=Swash}The five baffled officials flew off.}
\end{document}

警告

我真的不明白我做了什么,也许有更好的方法(我很乐意了解),但至少事情或多或少是有效的。

附录

怀着忐忑不安的心情,我创作了我的第一个(也可能是最后一个)GitHub 存储库,我会逐步记录我尝试修复的字体。这应该可以防止这个答案被很少有人接触过的字体讨论所淹没,避免其他使用相同字体的人重复我的劳动,也许还可以让我们共同发现更令人满意的解决方案。

答案2

这个(根据上下文列表中的示例改编)对我有用

2017 年 2 月编辑

语法似乎已经改变。数据和类型不再位于子表中,解释文本会造成伤害。对我来说有效的新代码(在当前的 TeXLive 2016 和 MiKTeX 中)是

\documentclass{article}
\usepackage{fontspec}
\directlua
{
 fonts.handlers.otf.addfeature 
  {
    name = "ktest",
    type = "kern",
    data = 
        {
            ["A"] = { ["V"] =  -200 },
        },
  }
 }
\setmainfont{Latin Modern Roman}[RawFeature=+ktest]
\setsansfont{Latin Modern Roman}

\begin{document}
  AV \sffamily AV
\end{document}

旧版

\documentclass{article}
\usepackage{fontspec}
\directlua{
fonts.handlers.otf.addfeature {
    name = "ktest",
    {
        type = "kern",
        data = {
            ["A"] = { ["V"] =  -200 },
        }
    },
    "extra kerns"
}
}
\setmainfont{Latin Modern Roman}[RawFeature=+ktest]
\setsansfont{Latin Modern Roman}

\begin{document}
  AV \sffamily AV
\end{document}

在此处输入图片描述

但我认为,关于正确的语法(而不是单独使用似乎也可以)和值(-200 是什么单位)还有相当多的未解决的问题["A"] A?这些额外的功能应该如何命名?它们都需要一个名字吗?软件包如何实现这些功能并避免与其他软件包发生冲突?

相关内容