OTFをTTFに変換してcmapテーブルを修正する
(この記事は、2016年2月24日のQiita記事の転載です)
はじめに
fontforgeやGlyphsなどでOTFフォントをTTFフォントに変換することができます。しかし、SourceHanSansなどのCJKフォントでは、変換されたTTFが正しくない場合があります。
どうおかしいか
SourceHanSansJPでは、例えば次のようなグリフが複数のコードにマップされています。
金: U+2FA6, U+91D1 首: U+2FB8, U+9996 音: U+2FB3, U+97F3 黎: U+9ECE, U+F989 罹: U+7F79, U+F9E6 樂: U+6A02, U+F914, U+F95C, U+F9BF
ところが変換されたTTFのcmapでは、ひとつのグリフがひとつのコードだけにマップされてしまいます。
修正方法
Adobe Font Development Kit for OpenTypeなどに含まれて居るttx
を使うと、cmapの修正ができます。
ttx -t cmap [font file]
とすると、フォントのcmapがXMLで取り出せます。このcmapファイルを修正した上で、
ttx -m [font file] [修正済みcmap]
とすると、font fileにcmapが反映されます。
もう少し細かく
次の手順で修正できるはずです。
- 元のOTFからcmapを取り出す
- 同じグリフを参照している文字コードのリストを作る。この時、文字コードからと、グリフ名の両方から参照できる構造が良い。
- 文字コード→グリフ名
- グリフ名→[文字コード, 文字コード…]
- TTFからcmapを取り出す
- cmapの文字コードを2.のリストと照らし合わせて、文字コードが一致したら、
- 2.のリスト内で、対応するグリフ名を全て書き換える(グリフのnameが変わっていることがあるので)。
- 2.のリストから、その文字コードを削除する
- 上記4.が終了した時に、2.のリストに残っている情報をcmapに書き出す。
- 上記5.で修正したcmapをTTFに書き込む。
手動では無理
SourceHanSans JPでは、500以上のグリフが複数のコードにマップされています。これを手動でチェックして反映するのはほとんど不可能です。
なのでコードを書きました
こちらに置いてあります。
https://github.com/skoji/convert-otf-to-ttf-and-fix-cmap
最後に
間違いの指摘や、より良い方法の提案を待ちわびています。