使用 pdfTeX/pdfLaTeX 讓 pdf 檔內嵌中文 TTF/TTC


一、 前言

目前國際上使用 Adobe 公司的開放規格 PDF(Portable Document Format) 格式的文件相當普遍,這也包括了政府行政部門及學術機構,因此 pdf 檔實有瞭解、重視的必要。本文主要是在說明如何在 GNU Linux(或其他安裝有相同工具的作業系統,如 FreeBSD)中使用 pdfTeX/pdfLaTeX 來製作中文的 pdf 檔。當然,製作 pdf 檔的方法很多,在這裡說明的只是自由軟體可以辦得到的其中一種方法。

為什麼會使用 pdfTeX/pdfLaTeX 呢?主要是因為可以直接使用中文 TTF,不必浪費磁碟空間來置放 Type1/pk 這些字型檔,而且 pdfTeX 含有許多 pdf 檔應有的功能,如一些 Internet 的超連結、填表格(form)功能 ... 等等。當然,這裡還是會說明如何使用 Type1 字型的情形,讓使用者自行選擇,畢竟兩者在高解析度時的品質還是有差的。

二、 一些需求說明

1. ttf2pt1 - 轉 TTF 為 Type1,並產生 pdfTeX 所需之 enc 檔

http://ttf2pt1.sourceforge.net (先檢查看是否有最新版本)
http://download.sourceforge.net/ttf2pt1/ttf2pt1-3.4.0.tgz
http://download.sourceforge.net/ttf2pt1/ttf2pt1-chinese-3.4.0.tgz

解開壓縮檔後進入 ttf2pt1-3.4.0 目錄,修改 Makefile。視作業系統改一下 CFLAGS_SYS 變數。如需編入 FreeType2,要修改一下 CFLAGS_FT 及 LIBS_FT,建議編譯進去,底下的製作也是以 FreeType2 為主要 parser。

make;make all;make install 即可。
ttf2pt1-chinese 解開後,進入目錄 make install 即可。中文倚天字集及 pdfTeX 所需的 enc 檔是由 Rigel 所貢獻的,真是非常感謝他,本文許多內容也是之前經過他指點過的結果。

2. t1utils - 這是處理 Type1 字型的一些工具

http://www.lcdf.org/~eddietwo/type/#t1utils

我們主要是要 t1asm 這個工具,將 ttf2pt1 轉出來的 PostScript(以下簡稱 ps) ascii 字型碼,再轉成 binary 的模式。雖 ttf2pt1 附有這個工具,但建議還是下載新版的 t1utils 來使用。

3. pdfTeX - 這是取代 tex/latex 指令,直接製造 pdf 檔的工具

ftp://ftp.muni.cz/pub/tex/local/cstug/thanh/pdftex

一定要更新為最近的新版本才能直接使用 TTF。pdftex.tex, supp-mis.tex, supp-pdf.tex 也要一並更新。其中 *.pool 檔要置於 web2c 目錄下,執行 texconfig init 來更新。ftp 站有現成的 static binary 版本可以下載,這樣只要取代系統上原有的檔案就可以了。

4. dvipdfm - dvi 轉 pdf 的工具

http://odo.kettering.edu/dvipdfm

這是傳統方法做出 .dvi 檔後,由 dvi 檔直接轉成 pdf 檔的工具。但目前僅能使用中文 Type1 字型,而無法直接內嵌中文 TTF。

5. teTeX 系統及 CJK package

這在一般的系統應該都會有,只是看使用者有沒有安裝上去。如果沒有的話(大多數是缺 CJK 套件),可能就得自行安裝,為了方便可到 CLE 網站,或 GNU Debian 的網站去抓現成的套件來使用。teTeX 系統請完整安裝,以免漏了某些 packages。

6. 字型

由於一般的商業字型都是有版權的,這裡使用文鼎公司的 GPL-like 的兩套字型來說明,請注意文鼎公司的使用授權聲明。目前新的 Linux distribution 大部份都已附上這兩套字型,這樣就不必麻煩下載了。
ftp://ftp2.tw.freebsd.org/pub/FreeBSD/distfiles/zh-arphicttf-2.11.tar.gz

三、 製作方法

這裡寫一個 sh script 來製作會比較方便。編輯一個 mkfont 的檔案,內容如下:
#!/bin/sh
#
# By Edward G.J. Lee 2001.11.25
# This code is Public Domain.
#
if [ $# -ne 1 ]
then
  echo "Usage: `basename $0` your.ttf"
  exit 1
fi

echo
echo "Now create *.t1a and *.enc files, wait... "
echo
FONTNAME=$1
MAPFILE=/usr/local/share/ttf2pt1/maps/cubig5.map
n=1
while [ $n -lt 10 ]
do
  m=0$n
  ttf2pt1 -GE -pft -Ohub -W0 -L $MAPFILE+$m $FONTNAME ${FONTNAME%.ttf}$m
  n=`expr $n + 1`
done

m=10
while [ $m -lt 56 ]
do
  ttf2pt1 -GE -pft -Ohub -W0 -L $MAPFILE+$m $FONTNAME ${FONTNAME%.ttf}$m
  m=`expr $m + 1`
done

# avoid dvips(k)(before v5.86) t1part module bug.
perl -pi -e 's/_/Z/g' *.t1a *.afm

echo
echo "Now create *.pfb, wait... "
echo
for ps in *.t1a
do
  t1asm -b $ps > ${ps%.t1a}.pfb
done

echo
echo "Now create *.tfm, wait... "
echo
for afm in *.afm
do
  afm2tfm $afm
done

AFM=${FONTNAME%.ttf}-afm
TFM=${FONTNAME%.ttf}-tfm
PFB=${FONTNAME%.ttf}-pfb
ENC=${FONTNAME%.ttf}-enc
rm -f *.t1a
mkdir -p $AFM $TFM $PFB $ENC
mv -f *.enc $ENC
mv -f *.afm $AFM
mv -f *.tfm $TFM
mv -f *.pfb $PFB
echo
echo "OK, all done. :-)"
echo
存檔後 chmod +x mkfont。然後置於一獨立目錄,字型亦要在同一目錄(做個連結亦可)。至於 ttf2pt1 可以使用的參數,請 man ttf2pt1,原則上請照以上的方法製作,這都是和 ttf2pt1 目前的 maintainer Sergey Babkin 討論過的參數,當然,如果您有更好的參數組合,也很希望您能提供出來。ttf2pt1 的 hinting 功能用在 CJK 字型,會有反效果,因此沒有打開。在此致十二萬分對 Sergey Babkin 的感謝,這次 3.4.0 的 release,他已盡了最大努力對中文 TTF 的支援。

進入置放 mkfont 的獨立目錄,執行:

./mkfont bsmi00lp.ttf;./mkfont bkai00mp.ttf
完成後會有以字型名稱為首的 afm, tfm, enc, pfb 目錄。

將 *-afm 目錄下的資料 copy 至 /usr/share/texmf/fonts/afm/CJK 目錄下。
*-tfm copy 至 /usr/share/texmf/fonts/tfm/CJK 目錄下。
*-pfb copy 至 /usr/share/texmf/fonts/type1/CJK 目錄下。
*-enc copy 至 /usr/share/texmf/dvips/CJK 目錄下。
各 CJK 目錄請自行建立。

四、 TeX/LaTeX 系統的設定

以下的步驟,如果完全沒有 TeX/LaTeX 系統架構的認識,可能會有點繁複,不過,耐著性子多試幾次應該是可以順利成功的,也順便瞭解一下 TeX/LaTeX 的檔案系統結構。

新增 /usr/share/texmf/dvips/config/aming.map 內容如下:

bsmi00lp01  ShanHeiSun-Light-01 <bsmi00lp01.pfb
bsmi00lp02  ShanHeiSun-Light-02 <bsmi00lp02.pfb
...
bsmi00lp55  ShanHeiSun-Light-55 <bsmi00lp55.pfb
新增 /usr/share/texmf/dvips/config/akai.map 內容如下:
bkai00mp01  ZenKai-Medium-01 <bkai00mp01.pfb
bkai00mp02  ZenKai-Medium-02 <bkai00mp02.pfb
...
bkai00mp55  ZenKai-Medium-55 <bkai00mp55.pfb
新增 /usr/share/texmf/dvips/config/bsmi00lp.map 內容如下:
bsmi00lp01  <bsmi00lp01.enc <bsmi00lp.ttf
bsmi00lp02  <bsmi00lp02.enc <bsmi00lp.ttf
....
bsmi00lp55  <bsmi00lp55.enc <bsmi00lp.ttf
* bsmi00lp.ttf 要置於 kpathsea 找得到的地方,如
  /usr/share/texmf/fonts/truetype (目錄可自行建立,使用連結亦可)。
新增 /usr/share/texmf/dvips/config/bkai00lp.map 內容如下:
bkai00mp01  <bkai00mp01.enc <bkai00mp.ttf
bkai00mp02  <bkai00mp02.enc <bkai00mp.ttf
....
bkai00mp55  <bkai00mp55.enc <bkai00mp.ttf
在 /usr/share/texmf/dvips/config/config.ps 加入:
p +aming.map
p +akai.map
修改 /usr/share/texmf/pdftex/config/pdftex.cfg,加入:
map +bsmi00lp.map
map +bkai00mp.map
新增 /usr/share/texmf/tex/CJK/Bg5/c00aming.fd 內容如下:
\def\fileversion{4.2.0}
\def\filedate{2001/09/28}
\ProvidesFile{c00aming.fd}[\filedate\space\fileversion]
\DeclareFontFamily{C00}{aming}{}
\DeclareFontShape{C00}{aming}{m}{n}{<-> CJK * bsmi00lp}{}
\DeclareFontShape{C00}{aming}{bx}{n}{<-> CJK * bkai00mp}{}
\endinput
新增 /usr/share/texmf/tex/CJK/Bg5/c00bsmi00lp.fd 內容如下:
\def\fileversion{4.2.0}
\def\filedate{2001/09/28}
\ProvidesFile{c00bsmi00lp.fd}[\filedate\space\fileversion]
\DeclareFontFamily{C00}{bsmi00lp}{}
\DeclareFontShape{C00}{bsmi00lp}{m}{n}{<-> CJK * bsmi00lp}{}
\DeclareFontShape{C00}{bsmi00lp}{bx}{n}{<-> CJK * bkai00mp}{}
\endinput
好了,已經昏頭轉向了嗎?最後執行 texhash(或 mktexlsr),讓 TeX/LaTeX 系統整理一下搜尋目錄。先喝杯水休息一下吧!:-)

五、 成果驗收

經過了以上的努力,您的 TeX/LaTeX 已經具備特異功能啦!就是可以使用中文 Type1 字型來製作 ps/pdf 檔案,也可以直接使用中文 TTF 來製作 pdf 檔案。就讓我們來驗收一下成果吧!

1. TeX 文稿的例子

\def\Fn{\char}
\font\Aa=bsmi00lp01 scaled 1000
\font\CCC=bsmi00lp55 scaled 3000
\font\CCc=bsmi00lp55 scaled 2000
\font\Ccc=bsmi00lp55 scaled 1000
\font\JJJ=bsmi00lp24 scaled 3000
\font\JJj=bsmi00lp24 scaled 2000
\font\Jjj=bsmi00lp24 scaled 1000
{\CCC\Fn108}
{\CCC\Fn109}
{\CCc\Fn110}
{\CCc\Fn111}
{\Ccc\Fn112}
{\Ccc\Fn113}
{\Ccc\Fn114}
{\JJJ\Fn55}
{\JJj\Fn95}
{\Jjj\Fn84}
{\CCC\Fn101}
{\CCC\Fn102}
{\CCc\Fn103}
{\CCc\Fn104}
{\Ccc\Fn105}
{\Ccc\Fn106}
{\Ccc\Fn107}
\bye
將上述文稿檔存成 ex.tex。然後執行:
pdftex ex.tex
這樣就會產生 ex.pdf 檔,這是內嵌了中文 TTF 字型的中文 pdf 檔。如果執行的是:
tex ex.tex
dvipdfm ex
則產生的是內嵌了中文 Type1 字型的中文 pdf 檔。各位可比較一下這兩種方式產生的 pdf 檔有何不同。以下為排版結果,以 xpdf 來閱覽(這是由 xv 抓下來的 png 圖檔,所以會有些失真):

[TeX 文稿實例 ex.pdf 圖示]

2. CJK-LaTeX 文稿的測試

這裡要先製作一個專用的 bg5pdflatex,內容為:
#!/bin/sh
FILE=`echo $1 | sed -e 's|\(.*\)\.[^/]*$|\1|'`
bg5conv < $1 > $FILE.cjk
pdflatex $FILE.cjk
這其實和 bg5latex 內容是一樣的,只不過把 latex 換成 pdflatex 而已。

現在寫一個簡單的 CJK-latex 文稿,命名為 example.tex 內容如下:

\documentclass[12pt,a4paper]{article}
\usepackage{CJK}
\renewcommand{\baselinestretch}{1.2}
\begin{document}
\begin{CJK*}{Bg5}{bsmi00lp}
\center
\section*{將進酒}
君不見~黃河之水天上來~奔流到海不復回\\
君不見~高堂明鏡悲白髮~朝如青絲暮成雪\\
人生得意須盡歡~莫使金樽空對月\\
天生我材必有用~千金散盡還復來\\
烹羊宰牛且為樂~會須一飲三百杯\\
岑夫子~丹丘生~將進酒~君莫停\\
與君歌一曲~請君為我側耳聽\\
鐘鼓饌玉不足貴~但願長醉不願醒\\
古來聖賢皆寂寞~惟有飲者留其名\\
陳王昔時宴平樂~斗酒十千恣讙謔\\
主人何為言少錢~徑須沽取對君酌\\
五花馬~千金裘~呼兒將出換美酒\\
與爾同消萬古愁\\
\end{CJK*}
\end{document}
編譯方式:
bg5pdflatex example.tex
這樣會直接產生 example.pdf 檔,這是內嵌中文 TTF 的 pdf 檔。把文稿內字型的部份 bsmi00lp 改成 aming,然後執行:
bg5latex example.tex
dvips -Pcmz example  ==> 這會產生內嵌中文 Type1 的 ps 檔
dvipdfm example      ==> 這會產生內嵌中文 Type1 的 pdf 檔
dvips 加 -Pcmz 的作用是讓英文的部份也去使用 Type1 字型,這樣才能和中文 Type1 字型相配,dvipdfm/pdftex/pdflatex 會自動去使用英文 Type1 字型,不必加任何參數。當然例子中並沒有用到英文字,但別忘了底部的頁碼編號使用的是 ascii 的數字。以下為排版結果,以 xpdf 來閱覽:

[CJK-LaTeX 文稿實例 example.pdf 圖示]

六、 一些注意事項及現存問題

  1. 以上的說明,請注意字型使用的名稱,使用中文 Type1 字型時是用 aming,使用 TTF 時是用 bsmi00lp,由於設定上的關係,一般字體是取用文鼎細上海宋,碰到粗體字時自動取用文鼎中楷,因為我們沒有其他相配的 free 字型可用,理想的話,應該粗體字要使用粗明或粗黑體。斜體字並沒有設定上去,因為中文排版上自古以來就沒有斜體字體,是晚近受洋文的影響才有所謂斜體字的。

  2. 如果您使用的系統所定義的字型名稱和本文所述相同的話(如 CLE),那可能得自行另改個名稱。

  3. 這樣做出來的 pdf 檔並無搜尋的功能,也沒有 cut&paste 的功能,這在英文沒有這個困擾,只存在於中文,這有待我們自由軟體社群的繼續努力。

  4. 檔案由於字型內嵌,稍嫌大了些,雖 ttf2pt1 改進了不少,使做出來的 ps/pdf 檔縮小不少,但和不內嵌字型的 ps/pdf 比起來,還是嫌大,這當然不完全是技術的問題,而是字型名稱無法統一的問題,這個目前還是無解,Adobe 公司當然不可能把他們的字型 free 出來供大家使用,當然我們可以使用模擬的方式,但這樣是否合法就不知道了。

  5. 自由軟體社群到目前為止尚沒有發展出方便製作 pdf 檔的 GUI 工具,也就是沒有一個有和 Acrobat Distiller 及其相關工具組匹敵的類似工具,這實在是很遺憾,當然這也牽涉了一些版權專利的問題,還希望 Adobe 公司能以更開放的精神來對一些限制鬆綁。


Copyright (c) 2001 李果正(Edward G.J. Lee).
最後修訂日期:2001.12.03
本文件除 sh script 外,為自由文件(FDL),可自由複製、修改、散佈,但請保留版權聲明。sh script 的部份為 Public Domain。文件內所提及的商標皆屬其合法註冊公司所有。