fontspec (Xe/Lua)

fontspec 是一个可以把系统中安装的 OpenType / TrueType 字体 按书体名直接调用 的包。只要写 \setmainfont{Some Font} 就能切换正文字体,合字、数字样式等 OpenType 功能也可通过 key=value 选项启用。但有一个硬性前提:必须使用 XeLaTeX 或 LuaLaTeX,传统的 pdfLaTeX 不能使用。本页依次介绍如何载入它、指定罗马体/无衬线/等宽字体、定义额外字体族,以及按文件和按功能选择字体。

fontspec 是什么,以及它需要的引擎

传统 TeX 只能使用为它准备的专用格式字体,不能直接使用电脑上已有的书体。fontspec 是一个 让你通过书体名(或文件名)使用 OpenType / TrueType 字体的包,这些字体可以安装在系统中,也可以放在项目内。它把字体选择桥接到 LaTeX 的 NFSS(字体选择机制),负责粗体、斜体的自动切换,并开放 OpenType 更丰富的排版功能。

首先必须记住一个硬性限制:fontspec 只在 XeLaTeX 或 LuaLaTeX 中工作,因为这些引擎原生处理 Unicode 和系统字体。它 不能用于 pdfLaTeX(pdftex);如果在 pdfLaTeX 下尝试 \usepackage{fontspec},会报错。请确认你的文档由哪个引擎处理,必要时用 lualatex / xelatex 编译。如果是新项目,考虑到日文支持,LuaLaTeX 通常是稳妥的默认选择。

载入方式很简单:\usepackage{fontspec}。在 XeLaTeX 和 LuaLaTeX 中,它往往已经由类或其他包自动载入;显式写出也没有坏处。

设置罗马体、无衬线和等宽字体

文档的三种基础书体在导言区用这三个命令指定。\setmainfont{…} 设置罗马体(正文默认字体),\setsansfont{…} 设置无衬线体(\textsf\sffamily 调用的字体),\setmonofont{…} 设置等宽/打字机体(\texttt\ttfamily 的字体)。参数就是系统注册的 字体名称

document.tex
% xelatex か lualatex でコンパイルする
\documentclass{article}
\usepackage{fontspec}
\setmainfont{TeX Gyre Termes}   % 本文(ローマン体)
\setsansfont{TeX Gyre Heros}    % サンセリフ体
\setmonofont{TeX Gyre Cursor}   % 等幅体
\begin{document}
This is the main font; \textsf{this is sans}; \texttt{this is mono}.
\end{document}

fontspec 会从书体名自动找到该族的粗体和斜体成员,并分配给 \textbf\textit 及二者的组合。照常写 \textbf{…}\emph{…},就会使用所选字体族的粗体和斜体。还要注意,如果这些命令放在导言区,同一字体也会用于 \mathrm 等数学中的罗马体(LaTeX 在这一处理阶段固定数学字体,因此只有导言区设置才有效)。数学本身的字体另行管理,用下文的 unicode-math 设置。

额外字体族与临时指定

当需要罗马体/无衬线/等宽三者之外的书体时,可用 \newfontfamily 定义新的切换命令。第一个参数是要创建的命令名(你自定的反斜杠名称),第二个参数是字体名。

document.tex
\usepackage{fontspec}
\newfontfamily\titlefont{TeX Gyre Bonum}
\newfontfamily\quotefont{TeX Gyre Schola}
% ...
\titlefont A heading in Bonum

{\quotefont A quoted passage in Schola.}

这样定义的 \titlefont\rmfamily 一样,是 声明式切换命令:它会把字体应用到后续所有文字。若要限定范围,就像 {\titlefont …} 那样用花括号包住。只用一次的字体可以不定义,直接把 \fontspec{Font Name} 作为现场声明使用;不过它每次都会重新载入字体,反复使用的书体最好用 \newfontfamily 定义。

按书体名选择 / 按文件选择

指定字体有两种方式。一种是按 OS 注册的书体名 选择,像 \setmainfont{TeX Gyre Termes} 这样直接写名称。这很方便,但对方环境中也必须安装同一字体。另一种是 按文件选择,把字体文件随项目一起提供;当你需要保证可复现的输出时,这才是合适的方式。

按文件选择时,在选项中给出 Path=(字体所在目录)和 Extension=(如 .otf.ttf 的扩展名),再用 UprightFont=BoldFont=ItalicFont=BoldItalicFont= 分配各字重和样式的文件。这些值中的星号 * 是占位符,会被第二个参数给出的 共同文件名(基名)替换

document.tex
\usepackage{fontspec}
% プロジェクト内の fonts/ に置いた OTF を、ファイル名で指定する
\setmainfont{LibreBaskerville}[
  Path       = ./fonts/ ,
  Extension  = .otf ,
  UprightFont    = *-Regular ,
  BoldFont       = *-Bold ,
  ItalicFont     = *-Italic ,
  BoldItalicFont = *-BoldItalic ,
]

在这个例子中,基名 LibreBaskerville 会展开到各个值中,因此会载入 fonts/LibreBaskerville-Regular.otffonts/LibreBaskerville-Bold.otf 等文件。下表对比两种指定方式。

方法写法适用场景
By name\setmainfont{Font Name};OS 注册名快速处理;自己机器上的草稿和个人文档
By filePath / Extension / *Font 指向随附文件重视可复现性;协作、发布、CI、自制或未注册字体

用选项启用 OpenType 功能

OpenType 字体包含合字、数字样式、小型大写等排版功能,fontspec 通过 key=value 选项 启用它们。最常用的有:

  • Ligatures= — 控制合字。Ligatures=TeX 启用 TeX 风格的输入转换,例如 `-- 转为 en dash,--- 转为 em dash,TeX 式引号转为弯引号(标准配置中常默认开启)。其他值包括 Common(标准 fi、fl 等合字)、Rare/Discretionary(可选合字)和 Historic`。
  • Numbers= — 数字样式。可把 OldStyle(带升降部、融入正文的旧式数字)或 Lining(高度一致的现代数字)与 Proportional(比例宽度)或 Monospaced(等宽)组合。
  • Letters=SmallCaps — 小型大写。也可使用 Letters=Uppercase 等值。
  • StylisticSet= — 按编号选择字体提供的替代字形集合(Stylistic Set)。
  • Scale= — 缩放比例。除数字外,Scale=MatchLowercase(匹配 x-height)和 Scale=MatchUppercase(匹配大写高度)很方便,可让辅助字体与正文字体大小协调。
  • Script= / Language= — 选择非拉丁文字或语言特定的造形规则(例如 Script=Arabic)。

这些写在字体设置命令的选项中,也就是第二个参数的方括号里。下面的例子让正文字体启用 TeX 风格合字旧式数字

document.tex
\usepackage{fontspec}
\setmainfont{TeX Gyre Pagella}[
  Ligatures = TeX ,
  Numbers   = OldStyle ,
]
% サンセリフは本文に大きさをそろえて読み込む
\setsansfont{TeX Gyre Heros}[Scale = MatchLowercase]

若只想给某个范围而非整个文档添加功能,使用 \addfontfeature{…}(多个功能用 \addfontfeatures{…})。它会 把指定功能局部添加到当前字体,只在包围它的花括号范围内生效。

latex
In a table we want {\addfontfeature{Numbers={Lining,Monospaced}} 01234 56789} aligned.

数学与日文:分开管理的字体

fontspec 负责的是 正文(文本)的拉丁字体。有两个领域需要另行处理。

一个是 数学字体。若想在 XeLaTeX 或 LuaLaTeX 中让数学也使用 OpenType 字体,需要在 fontspec 之外另行载入 unicode-math 包,并用 \setmathfont{…} 指定 OpenType 数学字体(Latin Modern Math、STIX Two Math 等)。记住文本的 \setmainfont 和数学的 \setmathfont 角色不同,会很有帮助。详情见数学字体页面。

另一个是 日文\setmainfont 只设置拉丁字体,对日文字体没有影响。在 LuaLaTeX 中,应使用相当于日文版 fontspecluatexja-fontspec 包,并用带 “j(Japanese)” 的命令设置日文字体:\setmainjfont{…}(明朝,即日文正文)、\setsansjfont{…}(Gothic)、\newjfontfamily 等;选项大体与 fontspec 共通。简言之,拉丁文字用 \setmainfont,日文用 \setmainjfont,两条路线并行。日文字体在专门页面中说明。