在windows下想好好用用utf8编码写点东西发现不是那么容易。ctex提供的字体和配置包可以很好的解决gbk编码的字体问题,大家也很多都喜欢使用gbk编码。出于种种原因,我个人比较喜欢使用utf8,所以想将这一环境配得更好些。
查看ctex提供的字体和配置包(ctex-cs-1.5.4和ctex-fonts-2.4.6)不难发现,对于gbk编码的字体,ctex提供了truetype和type1两种选择,type1字体已经编译好放在font/type1/chinese/gbk*各个目录下,但是utf8的字体,只提供了tfm,即没有提供truetype的配置(在pdftex/chinese下)也没有提供type1的编译字体,pdflatex总是使用ttfonts.map的配置产生pk字体嵌入,效果很差。这样,只有自己来做了。
研究了两天如何配置,发现网上的文章大部分都是针对比较老版本的pdflatex的了,而且也不再起作用,故无奈之下只有不断尝试。下面将先说明如何配置truetype字体的。
另外也顺便说明如何使得英文和数字(ASCII字体)也使用中文字体。
一 配置truetype字体
1. 安装ctex的字体和配置文件(可以从ctex网站获得安装文件)
2. 使用如下脚本生成所需要的tfm、enc和map文件(目录请自行修改为所用系统适合的目录)(该代码修改自ctex论坛上instanton 兄提供的脚本)
1
set
ttfile
=
"
%SystemRoot%\Fonts\%1
"
2
rd /S /Q
"
%LOCALTEXMF%\pdftex\chinese\%2
"
3
rd /S /Q
"
%LOCALTEXMF%\fonts\tfm\chinese\%2
"
4
if
not
exist
"
%LOCALTEXMF%\pdftex\chinese\%2
"
mkdir
"
%LOCALTEXMF%\pdftex\chinese\%2
"
5
if
not
exist
"
%LOCALTEXMF%\fonts\tfm\chinese\%2
"
mkdir
"
%LOCALTEXMF%\fonts\tfm\chinese\%2
"
6
7
ttf2tfm
"
%SystemRoot%\fonts\%1
"
-w
%2
@Unicode@
.
tfm
8
ttf2tfm
"
%SystemRoot%\fonts\%1
"
-s
0.167
%2
sl@Unicode@
.
tfm
9
move
*
.
tfm
"
%LOCALTEXMF%\fonts\tfm\chinese\%2
"
10
rm *
.
map
11
12
for
%%i in
(
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
a
,
b
,
c
,
d
,
e
,
f
)
do
(
13
for
%%j in
(
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
a
,
b
,
c
,
d
,
e
,
f
)
do
(
14
if
exist
%2
%%i%%j
.
enc
echo
%2
%%i%%j ^
<
%2
%%i%%j
.
enc ^
<
%1
>>
ttf-
%2
.
map
15
if
exist
%2
%%i%%j
.
enc
echo
%2
sl%%i%%j ^
<
%2
%%i%%j
.
enc ^
<
%1
>>
ttf-
%2
.
map
16
))
17
18
move
*
.
enc
"
%LOCALTEXMF%\pdftex\chinese\%2\
"
19
move
*
.
map
"
%LOCALTEXMF%\pdftex\chinese\
"
该脚本的意思很简单,输入两个参数<字体的ttf名称>和<希望构造的字体名>,后者将会是在fd文件中使用的名称,例如
genttf.bat fzst.ttf unisong
将产生使用系统目录下的fzst.ttf字体构造的名为unisong 的tex字体
两个循环的意图在于根据存在的enc文件编号将对应配置行写入map文件中
3. 使用initexmf --edit-config-file updmap编辑updmap文件,在其中加入
Map ttf-<fontname>.map
以使得pdflatex可以找到对应的字体和编码文件
4. 依次执行
initexmf -u
initexmf --mkmaps
initexmf -u
刷新系统。现在你可以将你的ttf字体嵌入到生成的pdf文件中了,不再是pk点阵字体了。
二 配置type1字体
接下来是type1字体的嵌入,这当然涉及到type1字体的生成了,但是步骤与上面大同小异,只是在脚本中需要添加一处ttf2pt1的调用而已。
生成type1字体的脚本如下
1
set
ttfile
=
"
%SystemRoot%\Fonts\%1
"
2
rd /S /Q
"
%LOCALTEXMF%\pdftex\chinese\%2
"
3
rd
/S /Q
"
%LOCALTEXMF%\fonts\afm\chinese\%2
"
4
rd
/S /Q
"
%LOCALTEXMF%\fonts\type1\chinese\%2
"
5
rd
/S /Q
"
%LOCALTEXMF%\fonts\tfm\chinese\%2
"
6
if
not
exist
"
%LOCALTEXMF%\pdftex\chinese\%2
"
mkdir
"
%LOCALTEXMF%\pdftex\chinese\%2
"
7
if
not
exist
"
%LOCALTEXMF%\fonts\afm\chinese\%2
"
mkdir
"
%LOCALTEXMF%\fonts\afm\chinese\%2
"
8
if
not
exist
"
%LOCALTEXMF%\fonts\type1\chinese\%2
"
mkdir
"
%LOCALTEXMF%\fonts\type1\chinese\%2
"
9
if
not
exist
"
%LOCALTEXMF%\fonts\tfm\chinese\%2
"
mkdir
"
%LOCALTEXMF%\fonts\tfm\chinese\%2
"
10
11
ttf2tfm
"
%SystemRoot%\fonts\%1
"
-w
%2
@Unicode@
.
tfm
12
ttf2tfm
"
%SystemRoot%\fonts\%1
"
-s
0.167
%2
sl@Unicode@
.
tfm
13
move
*
.
tfm
"
%LOCALTEXMF%\fonts\tfm\chinese\%2
"
14
rm *
.
map
15
16
for
%%i in
(
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
a
,
b
,
c
,
d
,
e
,
f
)
do
(
17
for
%%j in
(
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
a
,
b
,
c
,
d
,
e
,
f
)
do
(
18
if
exist
%2
%%i%%j
.
enc ttf2pt1 -b -W0 -GFAE -l plane
+
0x%%i%%j %ttfile%
%2
%%i%%j
19
if
exist
%2
%%i%%j
.
enc
echo
%2
%%i%%j ^
<
%2
%%i%%j
.
enc ^
<
%2
%%i%%j
.
pfb
>>
t1-
%2
.
map
20
if
exist
%2
%%i%%j
.
enc
echo
%2
sl%%i%%j ^
<
%2
%%i%%j
.
enc ^
<
%2
%%i%%j
.
pfb
>>
t1-
%2
.
map
21
))
22
23
move
*
.
enc
"
%LOCALTEXMF%\pdftex\chinese\%2\
"
24
move
*
.
afm
"
%LOCALTEXMF%\fonts\afm\chinese\%2\
"
25
move
*
.
pfb
"
%LOCALTEXMF%\fonts\type1\chinese\%2\
"
26
move
*
.
map
"
%LOCALTEXMF%\pdftex\chinese\
"
可以看到18行使用ttf2pt1产生pfb文件。
我尝试过使用ttf2pfd产生asm文件再用t1asm产生pfb文件,pdflatex总是说pfb文件不是预期的,同样使用ttf2pt1产生t1a文件再用t1asm产生pfb文件也是这个错误,所以在这里不使用t1asm来生成pfb文件而是直接使用ttf2pt1的 -b选项来生成二进制的pfb文件就可以了。
注意 该脚本生成type1字体需要一些时间,一个字体大约3min(e4600(2.8GHz)+2Gddr3)
三 对ASCII字符使用中文字体
作为ASCII字符,latex一般将使用系统内的tex字体(例如cmr或者ptm字体)。但是,在很多时候,我们也许想让输出的文档中的部分数字和英文字体也使用自定义的中文字体中的字形,例如宋体的1234abcd等,而用第一和第二部分的方法所做出来的配置将不能满足这个要求,cjk将不会使用低于256索引的字符作为输出。因此我们需要按照nfss的方法再做一些配置。以truetype的fzst(方正宋体)为例。
1. 使用ttf2tfm生成ascii字符的tfm文件
ttf2tfm fzst
.
ttf
注意到没有使用-w选项,这样生成的tfm将只包含ascii的字形。将该文件命名为t1song.tfm
2. 书写fd文件
类似于下面的t1song.fd文件
1
\
def
\
fileversion{
4.8
.
1
}
2
\
def
\
filedate{
2008
/
11
/
19
}
3
\
ProvidesFile{t1song
.
fd}[
\
filedate
\
space
\
fileversion]
4
5
\
DeclareFontFamily{T1}{song}{}
6
7
\
DeclareFontShape{T1}{song}{m}{n}{
<
-
>
t1song }{}
8
9
\
DeclareFontShape{T1}{song}{m}{sl}{
<
-
>
t1song }{}
10
11
\
DeclareFontShape{T1}{song}{m}{it}{
<
-
>
t1song }{}
12
13
\
DeclareFontShape{T1}{song}{b}{n}{
<
-
>
t1song }{}
14
15
\
DeclareFontShape{T1}{song}{b}{sl}{
<
-
>
t1song }{}
16
17
\
DeclareFontShape{T1}{song}{b}{it}{
<
-
>
t1song }{}
18
19
\
DeclareFontShape{T1}{song}{bx}{n}{
<
-
>
ssub * t1song
/
b
/
n}{}
20
\
DeclareFontShape{T1}{song}{bx}{sl}{
<
-
>
ssub * t1song
/
b
/
sl}{}
21
\
DeclareFontShape{T1}{song}{bx}{it}{
<
-
>
ssub * t1song
/
b
/
it}{}
22
23
\
endinput
注意其中的t1song对应于上一步生成的t1song.tfm
3. 更新map文件
如果你使用的是miktex2.7的话,那么可以这么做
输入initexmf --edit-config-file updmap
在弹出的文件中添加
Map ttf-ascii.map
一行,保存退出。如果不是使用miktex,那么你只需要简单的updmap.cfg文件中添加这么一行就可以了。
然后新建ttf-ascii.map文件,在其中输入
t1song <unisong00.enc <fzst.ttf
表明使用生成的unisong00.enc(第一部分说明如何生成),和使用的truetype字体为fzst.ttf
4. 将各个文件放置到合适的位置,然后执行
initexmf -u
initexmf --mkmaps
initexmf -u
普通的tex系统执行
texhash
updmap
texhash
即可
现在你可以使用nfss的字体选择命令来使用这些ascii的字体了,例如
\fontencoding{T1}\fontfamily{song}\selectfont test1234
就将使用fzst的字体显示test1234了
Gook luck!