TeXLive 2013のmf2pt1がおかしい件

# 概要

色々な理由から、[METAFONT](http://ja.wikipedia.org/wiki/METAFONT)で記述されたフォントを改造することになった。しかし、普通のMETAFONTはビットマップフォントしか生成出来ない。そこで、[MetaPost](http://ja.wikipedia.org/wiki/MetaPost)などを利用してなんとかAdobe Type1形式のフォントを得ようと試みていた最中に事件が発生した。

ヤバいEnglishしか書けなかったが、全然解決する見込みがないのでStackExchangeに投げたものを公開する。
http://tex.stackexchange.com/questions/122644/wrong-tfm-generated-by-mf2pt1-in-texlive-2013
This post, written in poor English,  is the nearly same as this article.

# やったこと

とりあえず、事件が発生するに至った手順を記述する。

## 元となるMETAFONTファイルの用意

METAFONTで記述されたフォントは、人間でも読める形になっている。例えばTeXで皆がよく利用する _cmr10_ （Computer Modern Roman 10）の冒頭は次のように記述されている。

```METAFONT
% THIS IS THE OFFICIAL COMPUTER MODERN SOURCE FILE cmr10.mf BY D E KNUTH.
% IT MUST NOT BE MODIFIED IN ANY WAY UNLESS THE FILE NAME IS CHANGED!

% Computer Modern Roman 10 point
if unknown cmbase: input cmbase fi

font_identifier:="CMR"; font_size 10pt#;

u#:=20/36pt#;      % unit width
width_adj#:=0pt#;    % width adjustment for certain characters
serif_fit#:=0pt#;    % extra sidebar near lowercase serifs
... 省略 ...
```

このファイル（`cmr10.mf`）を例に今後の話を進めてゆく。

## コンパイル

METAFONTファイルをそのままTeXに流し込むことなど出来ないので、TeXが読める物体へコンパイルする必要がある。ここで`mf`というMETAFONTのコンパイラを使うという選択肢もあるが、これではビットマップフォントしか生成出来ない。そこで、[mf2pt1](http://www.ctan.org/pkg/mf2pt1)という物を使って[Adobe Type 1](http://ja.wikipedia.org/wiki/PostScript%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88#Type_1)（Type 1 font）へコンパイルすることにした。
この作業にあたっては[東京大学大学院人文社会系研究科／文学部西洋古典学研究室の学生有志によるWikiページ](http://glc.l.u-tokyo.ac.jp/pukiwiki/index.php?TeX%2FFont%2FType1)から多くの知識を得た。

この`mf2pt1`は、

1. METAFONTファイルから一文字ずつフォント情報をMetaPostでEPS形式に変換
2. 一文字ずつに生成されたEPSファイルをマージ（マージされたファイルを _“disassembled” Type 1 font_ と呼ぶらしい）
3. disassembled Type 1 fontを`t1asm`（[t1utils](http://www.ctan.org/tex-archive/fonts/utilities/t1utils)に収録）でバイナリ形式のType 1 fontに変換
4. `fontforge`でレンダリングヒント（カーニング情報などか？）を適用

という手順を踏むらしい。

例えば _cmr10.mf_ をコンパイルすると、最終的に次の成果物が得られる。

- PFBファイル（Adobe Type 1フォント）
- TFMファイル（TeX Font Metricファイル）
- AFMファイル（Adobe Font Metricsファイル）

今回はTFMファイルで事件が起きた。

# TFMファイル

そもそもTFMファイルとは、あるフォントについて、文字のカーニングやリガチャの情報を持つファイルのこと。例えばTeXで _ffi_ という文字を表示させると次のようになる。

![latex-image-2.png](https://qiita-image-store.s3.amazonaws.com/0/10815/78b718a2-9d06-a6f0-0fdd-eefe9cce4382.png)

明らかに _f_ と _i_ が融合していると分かる。
また、 _Wr_ という文字を表示させると次のようになる。

![latex-image-1.png](https://qiita-image-store.s3.amazonaws.com/0/10815/96d72508-50c5-d885-d300-79e32633f0a1.png)

この例では _W_ の右側に _r_ が食い込んでいるように見える。

このように、TFMファイルに記述された情報によってTeXは文字と文字の幅などを調整している。つまりTeXであるフォントを使うこととなった場合は、Adobe Type 1形式などのフォントファイルに加えて、TFMファイルなどのフォントのカーニングといった情報を持つファイルも同時に必要となる。

## TFMファイルの閲覧

TFMファイルはバイナリファイルなので、そのままでは何が書かれているのか分からない。そこで`tftopl`で人間が読める形に変換出来る。
例えばTeXLive 2013で配布されている`cmr10.mf`について、`tftopl`を使うと次のような出力が得られる。

```TFM
(FAMILY CMR)
(FACE O 352)
(CODINGSCHEME TEX TEXT)
(DESIGNSIZE R 10.0)
(COMMENT DESIGNSIZE IS IN POINTS)
(COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE)
... 省略 ...
```

# 事件

端的に言えば`mf2pt1`で得られたTFMファイルが壊れていた。`mf2pt1`で`cmr10.mf`をコンパイルして得られたTFMファイルの一部が次のようになっている。

```TFM
   (LABEL C f)
   (LIG C i O 14)
   (LIG C f O 13)
   (LIG C l O 15)
   (KRN O 47 R 0.004861)
   (KRN O 77 R 0.004861)
   (KRN O 41 R 0.004861)
   (KRN O 51 R 0.004861)
   (KRN O 135 R 0.004861)
```

これは文字 _f_ に関するリガチャとカーニングの設定の一部である。`LIG`がリガチャに関する情報を表わし、`KRN`がカーニングに関する情報を表わす。
なんとなく上手くいっているように見えるが、TeXLiveで配布されている`cmr10.tmf`から同じく _f_ に関する情報を抜き出してくると、

```TFM
   (LABEL C f)
   (LIG C i O 14)
   (LIG C f O 13)
   (LIG C l O 15)
   (KRN O 47 R 0.077779)
   (KRN O 77 R 0.077779)
   (KRN O 41 R 0.077779)
   (KRN O 51 R 0.077779)
   (KRN O 135 R 0.077779)
```

などと、カーニングが相当違う値になっている。

# 原因

なんとか上手く動くようにならないものかと思い、色々やってみた。すると、 **TeXLive 2012** であると`mf2pt1`で（恐らく）妥当なTFMファイルが得られるということが分かった。また、`mf2pt1`はPerlで書かれたスクリプトなので中身を読んでみたところ、中でMetaPostを用いてそれでTFMファイルを生成しているということも分った。さらに、TeXLive 2012から2013でMetaPostのバージョンが1.504から1.803へアップデートしているというのも分かった。

例えば`cmr10.mf`を`mf2pt1`でコンパイルした場合、

```
$ mpost -mem=mf2pt1 -progname=mpost '\mode:=localfont; mag:=100.375; bpppix 0.02; nonstopmode; input cmr10.mf'
```

というコマンドが走るということが分かった。なので、このコマンドをTeXLive 2012（MetaPost 1.5）とTeXLive 2013（MetaPost 1.8）で実行したところ、TeXLive 2013では異常なTFMファイルが生成された。

このあたりのことから、恐らく次のような問題だと思われる。

- MetaPostにバグがある
- `mf2pt1`が古い命令を使っていて、それがMetaPost 1.8では正しく動作しない

ただ、MetaPostなど全く触ったことがなかったので、これ以上の原因究明は出来なかった。とりあえず`mf2pt1`をガシガシ使っている人は、TeXLive 2013へのアップデートをしばらく見送ってもいいのではないかと思う。

## mfplain

`mf2pt1.mf`の中味を見てみると、次のように、

```MetaPost
input mfplain;
```

`mfplain`という謎の物体を呼び出しているということが分かった。この`mfplain`は[MetaPostのマニュアル](http://mirrors.ctan.org/graphics/metapost/base/manual/mpman.pdf)の「Legacy Information -> MetaPost Versus METAFONT」で次のように記述されている。

> Since METAFONT is intended for making TEX fonts, it has a number of primitives for generating the tfm files that TEX needs for character dimensions, spacing information, ligatures and kerning. MetaPost can also be used for generating fonts, and it also has METAFONT’s primitives for making tfm files.

どうやら、MetaPostにはTFMファイルを生成するためのプリミティブが用意されているらしい。さらに、

> Even though MetaPost has the primitives for generating fonts, many of the font-making primitives and internal variables that are part of Plain METAFONT are not defined in Plain MetaPost. Instead, there is a separate macro package called mfplain that defines the macros required to allow MetaPost to process Knuth’s Computer Modern fonts ...

とあるので、METAFONTにはあるけどMetaPostのプリミティブではないような命令を、`mfplain`でマクロとして定義しているらしい。
ということはこの`mfplain`がTeXLive 2012と2013で異なっていれば、犯人はこの`mfplain`という可能性が高まる。そこで`mfplain`のバージョンをそれぞれのTeXLiveで調べてみた。
しかし、両方ともバージョン1.9で`diff`は取ってないが恐らくは同じ物体であると思われる。

ちなみにMetaPostのTFMファイル生成用プリミティブは、先ほどのマニュアルによると、

![making_tfm_primitives](http://dl.dropboxusercontent.com/u/16667824/gyazo/761bd8ae91e0c31ea1611459191fea72.png)

となっているらしい。今回はカーニングに関する情報が破損したわけだが、なんだかそのままズバリっぽい`kern`というプリミティブがある。

ゆえに、

- `mfplain`や`mf2pt1.mp`が原因である可能性は少ない
- MetaPostのTFMファイル生成用のプリミティブが犯人である可能性が高い

と言えるような気がする。ということで、MetaPostの[change log](https://foundry.supelec.fr/scm/viewvc.php/trunk/CHANGES?view=markup&revision=1919&root=metapost)を見てみたものの、プリミティブの仕様が変わったというような情報は多分ないように見える。
これは迷宮入りしそう……。

# 回避法

具体的な原因は分からないが、とりあえず現時点でなんとかマトモと思われるTFMファイルを生成する方法をいくつか書いておく。

- TeXLive 2012の`mf2pt1`を使う（MetaPost 1.5を使う）
- `mf`コマンドでMETAFONTファイルからTFMファイルを生成する
- `afm2tfm`を用いてAFMファイルからTFMファイルを生成する

このあたりがよいのではないかと思う。
もしかしたら、TFMファイルの代替としてAFMファイルを使うことが出来るのかもしれないが、どうすれば出来るのかは分からない。