home / uni / gs-cyg-ttf Cygwin + Ghostscrpit + Windows TrueTypeフォント

●Ghostscriptのインストール

 Cygwinのsetupから簡単インストール。 これを最初に書いた時点ではGPL-gs-8.63が入るようになっていた。 今(2012年9月22日、Cygwin 1.7.16)は GPL-gs-9.06 が入る。 「Cygwin で 日本語 TeX --- ptetex を簡単インストール」あたりでTEXを入れていると、/usr/local/binに既にgs7がいたりするので、whichで確認して適当にPATHを設定してください。 Xサーバー(X11/xorg-serverとX11/xinit)も入れておくと便利。

●gsのドキュメント
 /usr/share/doc/ghostscript-ver 以下。 今Cygwin 1.7.16で見てみたら、/usr/share/doc/ghostscript になっていた。

 HTMLで入っている。 gs本体の使い方はuse.html。

●TrueTypeフォントを使う

 use.htmlの「How Ghostscript finds files / CID font substitution」以下に書いてある。 lib/cidfmapはCygwinで普通にgsをインストールすると/usr/share/ghostscript/ver/lib/cidfmapになる。 同様に、Resource/Init/cidfmapは/usr/share/ghostscript/ver/Resource/Init/cidfmapになる。 で、どちらかのファイルにこんな行を追加する。

/MS-Gothic << /FileType /TrueType /Path (/usr/share/mswin/Fonts/MSGOTHIC.TTC) /SubfontID 1 /CSI [(Japan1) 3] >> ;

 Cygwin 1.7.16 / GPL-gs-9.06 では、インストール直後には lib/cidfmap が存在しないようだ。 また、lib/cidfmap に書いた場合、GS_LIB環境変数や-Iオプションで明示的にパスを指定してやらないと読み込まれない。 Resource/Init/cidfmap は最初から存在しているが、コメントだけ書いてあって、実質中身は空っぽ。 こちらは書き加えさえすれば環境変数などを設定しなくても読み込んでくれる。 バージョンアップがあった場合、おそらく lib/cidfmap の方は上書きされず、Resource/Init/cidfmap は上書きされるのではないかと思う。 だから、lib/cidfmap に書いておいて、~/.profile あたりにexport GS_LIB=/usr/share/ghostscript/ver/libと書いておくのがよいと思う。 もしかしたら Cygwin 1.5 / GPL-gs-8 の時代からそうだったかもしれない・・・そうだった気がするが、もう忘れた。


 というか、どうもGS_LIBで指定したパスのどこかに置いておけばいいようなので、~/.ghostscriptとか適当にディレクトリを作ってそこにcidfmapを置いて、GS_LIB環境変数にそのディレクトリを設定しておくのが楽みたい。

 私の場合、設定ファイル全般を一箇所に集めてgitで管理しているので、~/.ghostscriptからcidfmapの実体へシンボリックリンクを張っている。(31 Dec 2017)


 実際には lib/mkcidfm.ps (make cidfmap の意味だろう)というPostScriptで書かれたスクリプトがあって、

$ cd /usr/share/ghostscript/ver
$ gs -q -dNODISPLAY -dBATCH -sFONTDIR=/cygdrive/c/windows/fonts -sCIDFMAP=lib/cidfmap lib/mkcidfm.ps

とやれば、Windowsのフォントディレクトリをガサガサあさってよきに計らってくれる。 ドキュメントのWin32用gsと同じことをやっているのだが、-dNODISPLAYを指定しないとXを見に行ってしまうのと、cidfmap 内では c:/windows/fonts と書けないようなので、その部分だけ変えてある。

 一応cidfmapの中身も説明しておく。 このファイルもPostScriptソースなので、PostScriptのマナーにしたがって書く。 途中に改行が入っても大丈夫(だと思う)。シェルスクリプトやCのマクロみたいに行末に「\」を書く必要もない(はず)。 /で始まるのはID文字列。 最初の/MS-Gothicはこれから定義しようとするフォントの名前。 << ... >>は「辞書」を定義することを示していて、中身は「キーの名前」「値」をひと組として、好きなだけ並べる。

 Windowsのフォントは通常はC:\WINDOWS\Fontsにあり、use.htmlにはc:/WINDOWS/fonts/...というような記法があるが、Cygwinのgsの場合は/cygdrive/c/WINDOWS/Fonts/...と書かなければならないようだ。 これは面倒なので、/usr/share あたりにシンボリックリンクを作ってmswin -> /cygdrive/c/WINDOWS としておくか、いっそのことマウントしてしまえば、/usr/share/mswin/Fonts/...と書けるようになる。 ちなみにファイル名はWindows上でフォントフォルダを開いて、エクスプローラーの表示形式を「詳細」にすれば分かる。 Win7では複数のファイルが複数のファイルがひとつのファミリーとしてまとめてあることがあって(たとえばTimes New Romanがそうなっている、次で説明する/SubfontIDの逆)、その場合はファミリーを開いてみるとファミリーの中にある個々のフォントが表示されるので、これを調べればよい。

 /SubfontIDはフォントファイルの拡張子が.ttcのときに使う。 .ttcはTrueTypeコレクションのことで、ひとつのファイルに複数のTrueTypeフォントが入っている。 その何番目のフォントを使うかを指定する。 最初のフォントが0。 使いたいフォントが何番目かは、Windows上でフォントを見てみればよい。 .ttcファイルをダブルクリックするとフォントの見本が出るが、中央上に>>というボタンが出るので、望みのフォントが出るまで押す。 押した回数=/SubfontIDに指定する数値。 例えばMSGOTHIC.TTCには「MS ゴシック」「MS Pゴシック」「MS UI Gothic」の三つのフォントが入っていることが分かる。 このうち「MS Pゴシック」を使いたければ、/SubfontID 1と書く。 /SubfontIDは大文字・小文字を区別するので注意。/SubFontIDではダメ。

 [ ... ]は「配列」だが、普通の配列とはちょっと様相が違って、異なるタイプのオブジェクトもひとまとめにできる。 Japan1はAdobeが決めたCIDフォントの字形集合、3はその3番目の改定版みたいな意味だが、よく分からん。 Adobeの出したドキュメントをちゃんと読めば分かるんだろうけど。

 最後にセミコロン;が要る。 なぜかは知らない。

 これでTrueTypeフォントがgsで使えるようになる。 試しにお化けさんとお話してみる。 gsはデフォルトでXに出力しようとするので、Xサーバーを立ち上げておくとすぐに結果を見ることができる。

$ gs
GPL Ghostscript 8.63 (2008-08-01)
Copyright (C) 2008 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>/MS-Gothic findfont
Can't find (or can't open) font file /usr/share/ghostscript/8.63/Resource/Font/MS-Gothic.
Can't find (or can't open) font file MS-Gothic.
Querying operating system for font files...
Loading MS-Gothic font from /cygdrive/c/Windows/Fonts/msgothic.ttc... 2782296 1365844 14287000 12284601 1 done.
GS<1>

あれ。 見つからないと言われています。 一応、Windowsのmsgothic.ttcを読み込んでいますが、日本語が正しく通りません。

●PostScript内で指定するフォントの名前と文字コード
 PostScriptファイル内で指定するフォント名は、上で指定した/MS-Gothicの後ろに、ハイフンに続けてCMap名を付けたものになる。 CMap名はResource/CMapにあるファイル名を指定すればよい。 CMapは各文字の文字コードをCID・・・フォント内の字形の番号に変換する働きがあるので、CMap名で文字コードも決まる。

 Cygwin版Ghostscriptの9.21〜9.22-2まではCMapの状態がなんか中途半端なので、先にこのページの2017年の状況を参照のこと。(31 Dec 2017 / 16 Feb 2018)

 普通はシフトJISなら-90ms-RKSJ-Hを、EUCならば-EUC-Hを、Unicode(UCS2というかUTF-16ビッグエンディアン)ならば-UniJIS-UCS2-Hを、UTF-8ならば-UniJIS-UTF8-Hを付ける。 最後の-Hは「横書き」。 -Vにすると「縦書き」になるが、GPL-gs-8.63ではカッコの向き、送り量、横方向の位置、句読点や拗音の位置など、いろいろうまくいかない。 GPL-gs-8.64でどうなったかは知らない。

$ gs
GPL Ghostscript 8.63 (2008-08-01)
Copyright (C) 2008 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>/MS-Gothic-90ms-RKSJ-H findfont
Loading a TT font from /usr/share/mswin/Fonts/msgothic.ttc to emulate a CID font MS-Gothic ... Done.
GS<1>

無事に見つけてくれた模様。 ここで、

GS>/MS-Gothic-90ms-RKSJ-H findfont
Can't find (or can't open) font file /usr/share/ghostscript/9.06/Resource/Font/MS-Gothic-90ms-RKSJ-H.
Can't find (or can't open) font file MS-Gothic-90ms-RKSJ-H.
Querying operating system for font files...
Can't find (or can't open) font file /usr/share/ghostscript/9.06/Resource/Font/MS-Gothic-90ms-RKSJ-H.
Can't find (or can't open) font file MS-Gothic-90ms-RKSJ-H.
Didn't find this font on the system!
Substituting font Courier for MS-Gothic-90ms-RKSJ-H.
Loading NimbusMonL-Regu font from /usr/share/ghostscript/fonts/n022003l.pfb... 2696024 1361014 2894632 1511793 1 done.
GS<1>

となってしまう場合。 この例では一生懸命代わりのフォントを探して何かロードしているが、やはり日本語はうまく出ないだろう。 環境変数GS_LIBや、-Iオプションで /usr/share/ghostscript/ver/lib を探すように設定するとうまくいく、と思う。 とにかく、うまくいけば一発でLoading a TT font from ... Done.の行が出るはず。

 続けてフォントをスケーリングして、文字を表示してみる。 このあたりはAdobeのPostScript Language Reference Manualに詳しく載っている(当たり前か)。 この場合はシフトJISなので、端末がシフトJISの設定になっていれば、そのまま全角文字を通せる。

GS<1>50 scalefont setfont
GS>10 10 moveto
GS>(あいう) show
GS>


・・・この辺は略・・・

 シフトJISの場合、コード中に\(0x5C)が入っていると化ける。 有名なのは「表示」(0x955C 0x8EA6)かな。

GS>(表示) show

「表示」がきちんと表示されません(笑)。 これは「\」がエスケープキャラクタになっているから。 「\」そのものを表現したいときには「\\」と書く約束になっているので、0x5Cが二連発になるように、「表」の後ろに「\」を書き加えればOK。 あるいは、「< >」で囲った16進数でもよい。

GS>(表\示) show
GS><955c8ea6> show

 EUCやUTF-8にはこのような問題はない。 端末をEUCやUTF-8に設定できるなら(オリジナルのPuTTYはEUCはだめ、UTF-8は可能、Cygwin1.7から入るようになったmintty(Cygwin Terminal)はEUCも使える!)これらも試してみるとよい。

●PDF化
 例えばこんなpsファイルを作っておいて、
%!
/MS-Gothic-90ms-RKSJ-H findfont 50 scalefont setfont
10 10 moveto
(あいうえお) show
%%EOF

出力デバイスとしてpdfwriteを指定したり、ps2pdfを使ったりすればあっという間に、

$ ps2pdf gs-aiueo.ps
Error: /invalidfileaccess in /findfont
・・・略・・・
GPL Ghostscript 8.63: Unrecoverable error, exit code 1
$

エラーの出来上がり、じゃなくって。 ps2pdfは基本的に指定されたパス以外のフォントは読み込めないようになっているようだ。 この挙動を変えるには、環境変数GS_FONTPATH(あるいはコマンドライン-sFONTPATH=として)にフォントのあるパスを設定するか、お気楽には-dNOSAFERを付ける(出所の分からないファイルに対しては-dNOSAFERは使わないこと!)。 Windowsではファイル名の大文字・小文字を区別しないが、Unixでは区別するので、gsもファイルパスの大文字・小文字を区別している。 このため、GS_FONTPATH環境変数に指定するパスはcidfmapに書いたパスと大文字・小文字も一致していなければならない。 つまり、cidfmapに大文字・小文字が乱れ飛んだ状態でパスを書くとすごく面倒なことになる。 後からcidfmapを編集する場合も注意。

$ ps2pdf -dNOSAFER gs-aiueo.ps

出来上がったのがこれ → gs-aiueo.pdf

 環境によっては真っ白なPDFが出来上がることがある。 PostScriptファイルはテキストファイルだが、PDFは半分テキスト半分バイナリなので、テキストマウントされたディレクトリで作業をしているとこうなるのだが、ならないこともある。 冒頭のサイトでインストールしたgs7がこの症状を起こすようだ。 Cygwinのsetupで入れたgs8は大丈夫みたい。 Xには出るのにPDFには出ない場合、これを疑うとよい。 od -tx1でPDFファイルをダンプしてみて改行コードが「0D 0A」になっていたらほぼ確実。 解決策はバイナリマウントしなおすか、こうする。

$ ps2pdf -dNOSAFER gs-aiueo.ps - | cat > gs-aiueo.pdf

ハイフンは標準出力の指定、パイプは必ずバイナリになり、catを通してリダイレクトするとテキストマウントされているディレクトリでも、どうもバイナリのまま出力するらしい。 ダメだったらごめん。

●カーニングとリガチャ
 おまけ。 英文では文字の組み合わせによって字間を調整している。 例えば、「WA」のような組み合わせの場合、お互いが多少食い込むようにしないと妙に隙間が空いて見栄えが悪くなる。 この「文字の間隔を詰める」のがカーニング(kerning)。

 一方、文字の組み合わせによっては字形が変化して一体化してしまう場合がある。 これがリガチャ(ligature、合字)。 カーニングは字形(グリフ)は変わらず字間だけが変わるが、リガチャは字形(グリフ)そのものが変わってしまう。 リガチャにもいろいろあって、アルファベットを組み合わせた表記を、実際には合字で印字するような場合もあるが、英文でリガチャと言ったら一般的に次の5つ。

ff fi fl ffi ffl

圧倒的によく見るのはfi。iの点がfの上の部分とくっついて一体化する。 他にftとかstとかijとかもあるが、あまり一般的ではない模様。 Unicodeにはリガチャのための文字コードが定義されていて、上の5つのコードは以下の通り。

UCS2UTF-8リガチャ
FB00EF AC 80ff
FB01EF AC 81fi
FB02EF AC 82fl
FB03EF AC 83ffi
FB04EF AC 84ffl

※参考: Alphabetic Presentation Forms (Unicode Consortium)

 ただし、フォントによってグリフがあったりなかったりする。 リガチャのグリフがあるかどうかはWindowsの「文字コード表」(多分アクセサリ→システムツールあたり)で分かる。 フォントを選んで、文字セットをUnicodeにして、検索する文字の名前に「ligature」と打ち込むと、リガチャが出てくる。 Win32 APIではGetFontUnicodeRangesでどの文字コードにグリフが存在するかが分かる。 これ以外のAPIではグリフがないときに置き換えられる文字(〓とかね)の情報が返ってきたりして、グリフが本当にあるのかどうか分からない。

 例えば「MS Pゴシック」では、上の5種のうちfiとflだけがリガチャになっていて、ffをカーニングで処理する。 カーニングされるかどうかはWin32のAPIGetKerningPairsで分かる。 ffi・fflはfとfi、fとflを単に並べただけで、fの右側のデフォルトのスペースがマイナスになっているので、カーニングしなくても勝手に重なる、らしい。 これはGetCharABCWidthsで分かる。

 実際にどう表示されるかはWindowsのペイントでも分かる。 リガチャは直接入力できないので、「文字コード表」からコピーして張り付ける。

「MS Pゴシック」だとffのカーニングが分かりづらいので、Times New Romanも載せてみた。 Times New Romanもffはカーニング、fiはリガチャ。 ffは最初のfの頭の下に、ふたつ目のfの横線が食い込んでいる、つまり、文字間隔が負になっている様子が分かる。 fiはiの点がfの頭と一体化している。 Times New Romanはさすがにきれい。 それに対して「MS Pゴシック」はカーニングとリガチャのバランスが取れてない。 flはグリフとしてはあったけど、まあこんなもんですかね。

 ちなみに、Times New Romanのfの右側のスペースはデフォルトで100ptに対して-9pt、ffのカーニング量は100ptに対して2pt分詰める、でした。 カーニング量の一覧を見てると正になる(字間を拡げる)こともあるんですね。

 Ghostscriptにもやらせてみましょう。 UTF-8でやってみます。 Times New RomanもMS-Times-Romanという名前でcidfmapに書いておきました。

%!
/MS-Gothic-UniJIS-UTF8-H findfont
50 scalefont setfont
10 60 moveto
<666620 EFAC8120 EFAC8220 66EFAC8120 66EFAC82> show
/MS-Times-Roman-UniJIS-UTF8-H findfont
50 scalefont setfont
10 10 moveto
<666620 EFAC8120 EFAC8220 66EFAC8120 66EFAC82> show
%%EOF

これをkern-ligature.psという名前で保存して、

$ gs
GPL Ghostscript 8.63 (2008-08-01)
Copyright (C) 2008 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>(kern-ligature.ps) run

結果はこの通り。

PDFにするとこんな感じ

2017年の状況 home / uni / gs-cyg-ttf

●CMapが見つからん! (31 Dec 2017)

 Cygwin版のgs9.21〜9.22-2の話。 ウチの環境だけかもしれないし、そのうち直るかもしれない。→ gs9.22-3で直りました。(17 Feb 2018)

GS>/MS-Gothic-UniJIS-UTF8-H findfont
Scanning /fonts for fonts... 3 files, 3 scanned, 3 new fonts.
Scanning /sysfont for fonts... 680 files, 487 scanned, 381 new fonts.
Querying operating system for font files...
Can't find (or can't open) font file /usr/share/ghostscript/9.22/Resource/Font/MS-Gothic-UniJIS-UTF8-H.
Can't find (or can't open) font file MS-Gothic-UniJIS-UTF8-H.
Didn't find this font on the system!
Substituting font Courier for MS-Gothic-UniJIS-UTF8-H.
Can't find (or can't open) font file /usr/share/ghostscript/9.22/Resource/Font/NimbusMonoPS-Regular.
Can't find (or can't open) font file NimbusMonoPS-Regular.
Loading NimbusMonoPS-Regular font from /usr/share/fonts/urw-base35/NimbusMonoPS-Regular.t1... 7647676 6186340 5410592 4037956 1 done.
GS<1>

 MSゴシックフォントが見つかりません。 とりあえず、CIDフォントが見えるかどうか確かめます。

GS>/MS-Gothic /CIDFont findresource
Loading a TT font from /sysfont/msgothic.ttc to emulate a CID font MS-Gothic ... Done.
Can't find CMap UniJIS-UCS2-H building a CIDDecoding resource.
Error: /undefinedresource in findresource
Operand stack:
...

おやおやぁ? CMapがないと言われています。 どれどれ。

GS>/UniJIS-UTF8-H /CMap findresource
Error: /undefinedresource in findresource
Operand stack:
   UniJIS-UTF8-H   CMap   UniJIS-UTF8-H
...

本当に見つかりません。 リソースは/usr/share/ghostscript/ver/Resource以下にあるはずなので、覗いてみます。

$ ls -a /usr/share/ghostscript/9.22/Resource/CMap
./  ../

空っぽ。なんでやねん!

 とりあえず、どこかにCMapがないか、探し回ります。

$ find /usr/share -name UniJIS-UTF8-H
/usr/share/poppler/cMap/Adobe-Japan1/UniJIS-UTF8-H
/usr/share/texmf-dist/fonts/cmap/adobemapping/cmap-resources/cmapresources_japan1-6/CMap/UniJIS-UTF8-H

ありました。 popplerの下か、TeXの下です。 ここにすべてシンボリックリンクを張ってやればよいのですが・・・。 実は、Ghostscriptのリソースはgsのライブラリパスを見に行くようになっています。 その一部をGS_LIB環境変数で指定できるのですが、ビルトインのパスもあり、これはgs -hで確認できます。

$ gs -h
GPL Ghostscript 9.22 (2017-10-04)
Copyright (C) 2017 Artifex Software, Inc.  All rights reserved.
Usage: gs [switches] [file1.ps file2.ps ...]
...
Search path:
   /usr/share/ghostscript/9.22/Resource/Init :
   /usr/share/ghostscript/9.22/lib :
   /usr/share/ghostscript/9.22/Resource/Font :
   /usr/share/ghostscript/fonts : /usr/share/fonts/urw-base35 :
   /usr/share/fonts : /usr/share/poppler/cMap/Adobe-CNS1 :
   /usr/share/poppler/cMap/Adobe-GB1 :
   /usr/share/poppler/cMap/Adobe-Japan1 :
   /usr/share/poppler/cMap/Adobe-Japan2 :
   /usr/share/poppler/cMap/Adobe-Korea1
Ghostscript is also using fontconfig to search for font files
For more information, see /usr/share/ghostscript/9.22/doc/Use.htm.
Please report bugs to bugs.ghostscript.com.

なので、パッケージを作った人はpopplerの下を見に行くように設定したつもりのようです。 しかし、popplerにあるCMapはディレクトリ階層にCMapが入っていないため、gsは探せなかったのです。 いつものディレクトリからシンボリックリンクを張ってもいいのですが、要は/usr/share/poppler/cMap/Adobe-Japan1/CMap/UniJIS-UTF8-Hの形で見えればいいので、こうするのが一番簡単でしょう。

$ cd /usr/share/poppler/cMap/Adobe-Japan1; ln -s . CMap

ついでなので、全部のディレクトリにリンクを作っておきましょう。

$ cd /usr/share/poppler/cMap; for i in *; do ( cd $i; ln -s . CMap); done
$ ls -x /usr/share/poppler/cMap/Adobe-Japan1/CMap/
78-EUC-H                 78-EUC-V             78-H
78ms-RKSJ-H              78ms-RKSJ-V          78-RKSJ-H
78-RKSJ-V                78-V                 83pv-RKSJ-H
...

無事に見えました。 実際にGhostscriptから試してみます。

$ gs
GPL Ghostscript 9.22 (2017-10-04)
Copyright (C) 2017 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>/UniJIS-UTF8-H /CMap findresource
GS<1>pop
GS>/MS-Gothic-UniJIS-UTF8-H findfont
Scanning /fonts for fonts... 3 files, 3 scanned, 3 new fonts.
Scanning /sysfont for fonts... 680 files, 487 scanned, 381 new fonts.
Querying operating system for font files...
Loading a TT font from /sysfont/msgothic.ttc to emulate a CID font MS-Gothic ... Done.
GS<1>

無事に見えるようになりました。

 最初はTeXのCMapへシンボリックリンクを張っていたのですが、gs -hして見慣れないディレクトリがGhostscriptのライブラリパスとして含まれていたのでpopplerに気がつきました。


Copyright (C) 2011-2017 akamoz.jp

$Id: gs-cyg-ttf.htm,v 1.12 2018/02/16 15:40:38 you Exp $