summaryrefslogtreecommitdiff
path: root/info/latex-notes-zh-cn/src/fonts.tex
blob: c4f586448153196c637e546eefd1a5ecbbfe1953 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
\chapter{字体}

关于字体有三个重要概念:glyph、typeface、font。glyph~通常被翻译为字形,也有翻译为字体的;typeface~是一个书法和印刷领域的概念,它通常被翻译为字体或书体;font~曾经和~typeface~混用,但现在一般用作电脑领域的概念,在中国大陆被翻译为字体,在台湾被翻译为字型。

上述翻译的混乱令人十分无奈,包老师决定在本文中把它们分别翻译为字形、字样、字体,以正视听。

字形是一个字符的具体图形表现形式,一个字符可以有多个字形,比如汉字中的“強/强”、“戶/户/戸”;字样是一组相同风格样式的字形的集合,比如中文字样有宋、仿、楷、黑、隶、篆等;一种字样可以对应电脑上的几种字体。

\section{字样}
\label{sec:typeface}
拉丁字母的字样主要有三大类:Serif(Roman)、Sans Serif~和~Mono-space~(Typewriter)。Serif~的笔画边缘部分有些装饰,类似于中文的宋体、仿宋、楷体、魏书等。Sans Serif~的笔画则是平滑的,类似于中文的黑体。Sans~这个词来源于法语,就是“没有”的意思。Monospace~则是等宽字样。

每一类字样都可以有加粗(bold)、斜体(italic)、倾斜(oblique)等修饰效果。Italic~通常对原字样进行过重新设计,它修饰精细,多用于~Serif;~Oblique~也称作~slanted,基本上是把正体倾斜,多用于~Sans Serif。通常~oblique~看起来比~italic~要宽一些。

\Fref{tab:typeface}列出了几种常见的字样。

\begin{table}[htbp]
\caption{常见字样}
\label{tab:typeface}
\centering
\begin{tabular}{llll}
    \toprule
    操作系统 & Serif           & Sans Serif & Monospace \\
    \midrule
    Mac OS   & Times           & Helvetica  & Courier \\
    Windows  & Times New Roman & Arial      & Courier New \\
    \bottomrule
\end{tabular}
\end{table}

\section{字体格式}
\label{sec:font}

\subsection{点阵字体和矢量字体}
电脑上用的字体(font)按数据格式可以分为三大类:点阵字体(bitmap)、轮廓(outline)字体和笔画(stroke-based)字体。

点阵字体通过点阵来描述字形。早期的电脑受到容量和绘图速度的限制,多采用点阵字体。点阵字体后来渐渐被轮廓字体所取代,但是很多小字号字体仍然使用它,因为这种情况下轮廓字体缩放太多会导致笔画不清晰。

轮廓字体又称作矢量字体,它通过一组直线段和曲线来描述字形。轮廓字体易于通过数学函数进行缩放等变换,形成平滑的轮廓。轮廓字体的主要缺陷在于它所采用的贝塞尔曲线(Bézier curves)在光栅(raster)设备(比如显示器和打印机)上不能精确渲染,因而需要额外的补偿处理比如字体微调(font hinting)。但是随着电脑硬件的发展,人们一般不在意它比点阵字体多出的处理时间。

笔画字体其实也是轮廓字体,不过它描述的不是完整的字形,而是笔画。它多用于东亚文字。

\subsection{常见字体}

常见的轮廓字体技术有:Type 1~和~Type 3、TrueType、OpenType、~\MF~等。

Adobe~的~Type 1~和~Type 3~基于~PS,它们采用三次贝塞尔曲线。Type 1~支持微调,它使用一个简化的~PS~子集;Type 3~不支持微调,但它可以使用全部~PS~功能,因此既可以包含轮廓字体也可以包含点阵字体信息。
    
1991~年,Apple~发布了~TrueType,它采用二次贝塞尔曲线。二次曲线处理起来比三次曲线快,但是需要更多的点来描述。所以从~TrueType~到~Type 1的转换是无损的,反之是有损的。1994~年,Apple~着手研究~TrueType~的下一代技术:TrueType GX,它后来演变为Apple Advanced Typography(AAT)。

1996~年,微软和~Adobe~联合发布了~OpenType。它比起~AAT~的优势有:跨平台、开放和易于开发、支持更多的语言比如阿拉伯语。

早在~1984~年~Knuth~就发布了~\MF,它与~TrueType~和~OpenType的区别是,不直接描述字形轮廓,而描述生成轮廓的笔的轨迹。笔的形状可以是椭圆形或多边形,尺寸缩放自如,字形边缘也柔和一些。两种字体可以用同一个~\MF~文件,当然还有不同的参数。\MF~技术如此先进,却没有流行开来。对此~Knuth~解释道,要求一位设计字体的艺术家掌握~60~个参数太变态了,那是用来折磨数学家的。

Type 1~和~Type 3~把字体信息存储在两种文件里:metrics~和~glyph~文件。metrics~文件有~AFM(Adobe font metrics)和~PFM(printer font metrics),glyph~文件有~PFA(printer font ASCII)和~PFB(printer font binary)。~\LaTeX~使用的~metrics~格式是~TFM(TeX Font Metrics)。

TrueType~的文件后缀是~.ttf,OpenType~的是~.ttf~和~.otf。\MF~虽然用矢量图形来定义字形,实际输出的却是一种点阵格式:PK~(packed raster)。

上述字体按技术的先进性,从高到低的排序为:OpenType、~TrueType、Type 1、Type 3、PK,我们应优先选用~OpenType~和~TrueType。

\subsection{合纵连横}
Adobe~收取的~Type 1~专利许可费一度十分昂贵,穷人们只好用免费的~Type 3。为了打破这种垄断,Apple~开发了~TrueType。1991~年~TrueType~发布之后,Adobe随即公开了~Type 1~的规范,~Type 1~字体从贵族堕落为平民,因而流行开来。

1980~年代中后期,Adobe~的大部分盈利来自于~PS~解释器的许可费。面对这种垄断局面,微软和~Apple~联合了起来。微软把买来的~PS~解释器~TrueImage~授权给~Apple,Apple~则把~TrueType~授权给微软。

微软得陇望蜀,又企图获得~AAT~的许可证,未遂。为了打破~Apple~的垄断,微软联合~Adobe~在1996年发布了~OpenType。Adobe~在2002~年末将其字体库全面转向~OpenType。

上面这几出精彩好戏充分展示了商场上的勾心斗角、尔虞我诈,没有永恒的伙伴,只有永恒的利益。但它同时也告诉我们,市场竞争中受益的还是广大的消费者。

\section{字体应用}

PS~支持~Type 1~和~Type 3,而~PDF~除了这两种还支持~TrueType~和~OpenType。\verb|latex|、DVI浏览器、各种~driver~分别采用不同的字体技术。

\subsection{DVI}
\verb|latex|~编译~\LaTeX~源文件生成~DVI~时只需要\verb|.tfm|~文件,因为~DVI~并不包含字形信息,而只包含对字体的引用。DVI~浏览器显示~DVI~时一般使用~PK,它在系统中查找相应的~\verb|.pk|~文件,若找不到就调用~\MF~在后台自动生成。

\subsection{dvips}
缺省情况下,\verb|dvips|~也会查找~\verb|.pk|~,或调用~\MF~自动生成;然后把~PK~转换成包含点阵字体的~Type 3,它的参数~\verb|-D|~可以用来控制该点阵字体的分辨率。用~\verb|ps2pdf|~处理含~Type 3~的~PS~时,输出的自然是含~Type 3~的~PDF。

GSview~在低分辨率下可以很好地渲染~Type 3,Adobe Reader~或~Acrobat~却不能,因为它们使用的~Adobe Type Manager~不支持包含完整~PS~的~Type 3。含~Type 3~的~PDF~看起来会有些模糊,所以应尽量避免使用。

\verb|dvips|~的另一个参数~\verb|-Ppdf|~把~Type 1~嵌入生成的~PS,这样再~\verb|ps2pdf|~就能生成含~Type 1~的~PDF。

\verb|dvips|~不支持真正的(native)TrueType,用户只能把~TrueType~先转成~PK~或~Type 1,这样绕了个弯效果总会打些折扣。

\verb|dvips|~的字体详细使用方法可查阅其手册\citep{Rokicki_2005}第~6~章,此处不赘述。

\subsection{dvipdfm(x)}
\verb|dvipdfm|~支持~PK~和~Type 1,它可以用一个~\verb|t1fonts.map|~文件建立~PK~文件和~Type 1~文件之间的映射,这样生成的~PDF~用的就是~Type 1。\verb|dvipdfm|~也不支持真正的~TrueType。

\verb|dvipdfmx|~通过正确的设置可以使用真正的~TrueType,它对中日韩等东亚文字的支持也较好,所以它对我们来说是~Driver~的首选。

\section{TrueType~字体安装配置}
CJK~自带的~UTF-8~编码字体~gbsn~和~gkai只包含~GB2312~字符集,而~CTeX~只提供~GBK~编码字体,因此中文用户通常需要自己安装配置~UTF-8~编码的~TrueType~字体。

在使用~TrueType~之前,用户通常需要作以下准备工作:
\begin{enumerate}
    \item 用转换程序~\verb|ttf2tfm|~生成~TFM。
    \item 配置字体定义文件~\verb|.fd|。
    \item 配置~\verb|ttf2pk|~,因为~DVI~浏览器和~\verb|dvips|~都会自动调用~\verb|ttf2pk|~来生成~PK。
    \item 配置~\verb|dvipdfmx|。
\end{enumerate}

\subsection{目录和文件}
通常每个发行包都会参照~TDS~建立自己的目录系统,把各种文件发在固定的位置。比如~MiKTeX~顶层目录如下,在本节后面的示例中我们将使用这些目录的缩写。
\begin{code}
Install: D:\edit\MiKTeX 2.7
UserData: C:\Documents and Settings\Alpha\Local Settings\
    Application Data\MiKTeX\2.7
UserConfig: C:\Documents and Settings\Alpha\
    Application Data\MiKTeX\2.7
\end{code}

目录多了有个缺点,文件不知道放在哪里好。MiKTeX~中有的配置文件居然在四个目录下各有一份,实在是令人发指。幸好我们可以用下面的命令检查配置文件的具体名字和路径。

\begin{code}
initexmf --edit-config-file=ttf2pk
\end{code}

\subsection{ttf2tfm}
比如我们想把~\verb|SimSun18030.ttc|(18030~字符集的新宋体)转换为~UTF8~编码的字体文件,我们需要执行以下步骤。

\begin{enumerate}
    \item 把需要的~\verb|.ttf|~文件复制到~\verb|UserData/fonts/truetype/chinese/|。
    \item 用下面的命令生成\verb|.tfm|~和~\verb|.enc|~文件。
    \item 把~\verb|*.tfm|~复制到~\verb|UserData/fonts/tfm/chinese/utf8song/|。
    \item 把~\verb|*.enc|~复制到~\verb|UserData/fonts/enc/chinese/utf8song/|。
\end{enumerate}

\begin{code}
ttf2tfm SimSun18030.ttc -q -w utf8song@Unicode@
\end{code}

\subsection{字体定义文件}
字体定义文件将字体引用名和实际的字体文件联系起来,比如我们在~\verb|CJK|~环境中引用~\verb|usong|~时,系统将会找到并使用~\verb|utf8song*.tfm|。

\begin{code}
%UserData\tex\latex\CJK\UTF8\C70usong.fd
\ProvidesFile{c70usong.fd}
%character set: GB18030
%font encoding: Unicode
\DeclareFontFamily{C70}{usong}{\hyphenchar \font\m@ne}
\DeclareFontShape{C70}{usong}{m}{n}{<-> CJK * utf8song}{}
\DeclareFontShape{C70}{usong}{m}{it}{<-> CJK * utf8song}{}
\DeclareFontShape{C70}{usong}{bx}{n}{<-> CJKb * utf8song}{
    \CJKbold}
\endinput
\end{code}

\subsection{配置~\texttt{ttf2pk}}
MiKTeX~中~\verb|ttf2pk|~的配置文件是~\verb|ttf2pk.ini|~,在其它的发行包中可能是~\verb|ttf2pk.cfg|。

\verb|ttf2pk.ini|~中有一个~\verb|.map|~文件列表,后者定义了~TrueType~应该按编码转为~PK~等信息。

比如下面这个文件列表会让~\verb|ttf2pk|~读取~\verb|foo.map|~和~\verb|bar.map|。

\begin{code}
map foo.map
map bar.map
\end{code}

如果系统找不到~\verb|ttf2pk.ini|,它会缺省使用~\verb|ttfonts.map|。
\begin{code}
%UserData\ttf2tfm\base\ttfonts.map
utf8song@Unicode@ SimSun18030.ttc
\end{code}

\subsection{配置~\texttt{dvipdfmx}}
配置~\verb|dvipdfmx|~是为了让~PDF~正确地嵌入~TrueType,否则生成的文件中的内容不能复制、粘贴。

\begin{code}
%UserConfig\dvipdfm\config\dvipdfmx.cfg
f cid-x.map
\end{code}

\begin{code}
%UserData\dvipdfm\config\cid-x.map
utf8song@Unicode@ unicode SimSun18030.ttc
\end{code}

\bibliographystyle{unsrtnat}
\bibliography{reading}
\newpage