マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

LuaTeX が直接 Type1 する件が結局解らなかった

てきとーに垂れ流したメモ。

luaotfload が新しくなってアレ?

luaotfload v2.7:
* Remove support for builtin Fontforge libraries (this includes the PFA, PFB, DFONT, and feature file readers).

ふむ。ということは、従来(v2.6)の luaotfload は「PFB」(Type1 フォント)をサポートしていたらしい。ということは、実は LuaTeX では OpenType だけでなく、Type1 フォントの“直接”指定ができる(できた)ということなのか。調べてみたけど、何だかよくわからない、という話。

“TFM 経由”と“直接”

新しい TeX エンジンにおいては、フォントの指定方法には次の 2 種類がある。

  • “TFM 経由”: オリジナルの TeX と同じで、TFM ファイル(*.tfm)を用意して、それに物理フォントをマップする、という方法。
    • pdfTeX では PK 形式、PFB 形式(バイナリの Type1)、OpenType 形式(TrueType グリフの形式も含む)がサポートされている。LuaTeX でのサポート状況も同じようなものだろう。
    • この方式で一番よく利用されている形式は PFB(Type1)。
    • TFM が 8 ビット空間を前提にしているので、この方式で定義したフォントは全て 8 ビットになる。マップ行にリエンコード(.enc)が指定されているならそのエンコーディングに、指定されていないならビルトインのエンコーディングになるはず。
  • “直接”: TFM を経由せずに、物理フォントを直接指定する。
    • XeTeX と LuaTeX でのみ使用可能な方法。
    • この方式で定義されたフォントは Unicode の符号空間をもつ。
    • 一般的には、OpenType フォント(TrueType グリフのものも含む)について利用される。

実は、LuaTeX はデフォルトでは、少なくともインタフェースとなる \font プリミティブのレベルにおいては、“TFM 経由”の指定しかサポートしていない。そして、XeTeX と同じような“直接”指定を可能にするためのパッケージが luaotfload なのである。

だとすると、「luaotfload が Type1 をサポートする」というのは、何となく、「Type1 フォントの“直接”指定ができる」ことを意味する、ような気がする。

Type1 を“直接”指定したい話

例えば TeX Live に収録されている Times のクローンである「NimbusRomNo9L-Regu」を例に挙げる。

  • PS フォント名は NimbusRomNo9L-Regu。
  • ビルトインのエンコーディングは StandardEncoding(これの Berry 識別子が“8a”)。
  • TeX Live でのファイル名は utmr8a.pfb。
  • TFM ファイル utmr8a.tfm は存在しない
  • TeX では、これを TeXBase1Encoding(Berry 識別子が“8r”)にリエンコードしたものを utmr8r として使っている。
    utmr8r NimbusRomNo9L-Regu " TeXBase1Encoding ReEncodeFont " <8r.enc <utmr8a.pfb
    従って、utmr8r.tfm は存在する。

さてこの状態において、

\font\test=utmr8r

とすると、“TFM 経由”(utmr8r.tfm を経由)で NimbusRomNo9L-Regu が指定される。これはアタリマエであり、また pdfTeX と同じ動作である。

しかし、仮に LuaTeX(+ luaotfload v2.6)で Type1 が“直接”指定できるとなると、utmr8r.tfm とは無関係に NimbusRomNo9L-Regu が指定できるはずである。それを実現するにはどうすればいいか。

マニュアルを読むと

luaotfload パッケージのマニュアルにおいては、Type1 フォントを指定する話は、次の 1 ヶ所しか出てこない。

For example, conventional type1 font can be loaded with a file: request like so:
\font\lmromanten={file:ec-lmr10} at 10pt
The luaotfload package: 3.3.1 Loading by File Name

そしてこれは“TFM 経由”の指定である。何故かというと、TeX Live には ec-lmr10.tfm という TFM ファイルはあるが、ec-lmr10.pfb というフォントファイルは存在しないからである。ec-lmr10.tfm のマップ先は LMRoman10-Regular という Type1 フォントであるが、これのファイル名は lmr10.pfb である。

つまり、ここで登場する \font 命令は、もっと一般的な次の形式と等価である。

\font\lmromanten=ec-lmr10 at 10pt

(なお,\font の右辺にある波括弧については,過去の記事を参照されたい。)

結局のところ、luaotfload のマニュアルでは「Type1 を“直接”指定する話」は全く登場しなかったことになる。何となく、「Type1 は当然“TFM 経由”で使うもの」という雰囲気も感じ取れる。

ZR さんの予想

マニュアルの記述は措いておいて、とにかく「Type1 を“直接”指定できる」と信じた上で、その場合の \font 命令の書き方を考えよう。

Type1 の代わりに、“直接”指定が一般的に行われる OpenType フォントのことを考える。例えば TeXGyreTermes-Regular を“直接”指定したい場合は次の何れかを書くことになる。*1

  • フォント名指定:
    \font\test=name:TeXGyreTermes-Regular
    
  • ファイル名指定:
    \font\test=file:TeXGyreTermes-Regular.otf
    
  • 接頭辞を省略した形:
    \font\test=TeXGyreTermes-Regular
    \font\test=TeXGyreTermes-Regular.otf
    

これの類推で考えると、Type1 フォントの“直接”指定の書式は以下のようになりそうである。

\font\test=name:NimbusRomNo9L-Regu %(1)
\font\test=file:utmr8a.pfb %(2)
\font\test=NimbusRomNo9L-Regu %(3)
\font\test=utmr8a.pfb %(4)

実際にやってみる

TeX Live 2015 において次のような plain LuaTeX 文書を実際にコンパイルしてみる。

\input luaotfload.sty
\font\test=name:NimbusRomNo9L-Regu %(1)
\test Hello!\bye

\font の行を (1)〜(4) の各々で置き換える。)

その結果であるが、フォント名指定の (1) と (3) については、「そのようなフォント名はデータベースにない」というエラーになった。luaotfload で作られるフォント名データベースには Type1 フォントの情報は入っていないということか。

C>luatex test
This is LuaTeX, Version beta-0.80.0 (TeX Live 2015/W32TeX) (rev 5238)
 restricted \write18 enabled.
(./test.tex (c:/texlive/2015/texmf-dist/tex/luatex/luaotfload/luaotfload.sty
(c:/texlive/2015/texmf-dist/tex/latex/base/ltluatex.tex)(using write cache: C:/t
exlive/2015/texmf-var/luatex-cache/generic)(using read cache: C:/texlive/2015/te
xmf-var/luatex-cache/generic C:/Users/yato/.texlive2015/texmf-var/luatex-cache/g
eneric)
luaotfload | main : initialization completed in 0.521 seconds)
luaotfload | db : Reload initiated (formats: otf,ttf,ttc,dfont); reason: "Font N
imbusRomNo9L-Regu not found.".
! Font \test=name:NimbusRomNo9L-Regu not loadable: metric data not found or bad.
<to be read again>
\test
l.3 \test
        Hello!\bye

ファイル名指定の (2) と (4) については、かなり不思議な結果になった。フォントの定義および使用の段階では何もエラーは出ないが、ところが実際に PDF ファイルを出力する段になって、“Invalid font type”のエラーが出て、結局 PDF ファイルは出力されなかった。

C>luatex test
This is LuaTeX, Version beta-0.80.0 (TeX Live 2015/W32TeX) (rev 5238)
 restricted \write18 enabled.
(./test.tex (c:/texlive/2015/texmf-dist/tex/luatex/luaotfload/luaotfload.sty
(c:/texlive/2015/texmf-dist/tex/latex/base/ltluatex.tex)(using write cache: C:/t
exlive/2015/texmf-var/luatex-cache/generic)(using read cache: C:/texlive/2015/te
xmf-var/luatex-cache/generic C:/Users/yato/.texlive2015/texmf-var/luatex-cache/g
eneric)
luaotfload | main : initialization completed in 0.521 seconds)(load luc: C:/texl
ive/2015/texmf-var/luatex-cache/generic/fonts/otf/utmr
8a.luc)(save: C:/texlive/2015/texmf-var/luatex-cache/generic/fonts/otf/utmr8a.lu
a)(save: C:/texlive/2015/texmf-var/luatex-cache/generic/fonts/otf/utmr8a.luc)
[1{c:/texlive/2015/texmf-var/fonts/map/pdftex/updmap/pdftex.map}])<c:/texlive/20
15/texmf-dist/fonts/type1/urw/times/utmr8a.pfb
!LuaTeX error (file c:/texlive/2015/texmf-dist/fonts/type1/urw/times/utmr8a.pfb)
: Invalid font type
 ==> Fatal error occurred, no output PDF file produced!

ソースを少し変えて、実際にフォントのグリフは出力せず、代わりにグリフの幅の情報を表示させてみた。

\input luaotfload.sty
\font\test=file:utmr8a.pfb %(2)
\message{\the\fontcharwd\test`M:\the\fontcharwd\test`i}\bye

すると、これは次のような妥当そうな値を表示する。

8.89pt:2.78pt

以上の結果を踏まえると、LuaTeX + luaotfload では、「Type1 フォントの情報を直接読み込むことはできるが、それを出力 PDF 中のフォントとして利用することはできない」ということになる、ように思える。

というわけではなさそうな話

以上で話が終わればいいが,現実はそんなに甘くなかったらしい。

イロイロ試してみていたところ,なんと一見絶対に失敗しそうに思える次の書式が実は成功する,ということが判明した。

\font\test=file:utmr8a %(5)
\font\test=utmr8a %(6)

つまり,以下のソースはコンパイルが成功し,しかも書いたテキストが完璧に出力されている。

\input luaotfload.sty
\font\test=file:utmr8a
\test Moje vznášedlo je plné úhořů.\bye

StandardEncoding にも Latin-1 にもない文字も扱えているので,フォントが Unicode エンコーディングで扱われていることが判る。従って,“TFM 経由”ではなく“直接”指定であることは間違いない。それにしても,本来 Unicode の知識を持っていないはずの Type1 フォントが Unicode で扱えているのは何とも不思議な感じである……。

*1:フォントファミリ名である“TeXGyreTermes”や“TeX Gyre Termes”でも指定できるが、ここではそれは措いておく。