(この記事は、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が反映されます。

もう少し細かく

次の手順で修正できるはずです。

  1. 元のOTFからcmapを取り出す
  2. 同じグリフを参照している文字コードのリストを作る。この時、文字コードからと、グリフ名の両方から参照できる構造が良い。
    • 文字コード→グリフ名
    • グリフ名→[文字コード, 文字コード…]
  3. TTFからcmapを取り出す
  4. cmapの文字コードを2.のリストと照らし合わせて、文字コードが一致したら、
    1. 2.のリスト内で、対応するグリフ名を全て書き換える(グリフのnameが変わっていることがあるので)。
    2. 2.のリストから、その文字コードを削除する
  5. 上記4.が終了した時に、2.のリストに残っている情報をcmapに書き出す。
  6. 上記5.で修正したcmapをTTFに書き込む。

手動では無理

SourceHanSans JPでは、500以上のグリフが複数のコードにマップされています。これを手動でチェックして反映するのはほとんど不可能です。

なのでコードを書きました

こちらに置いてあります。

https://github.com/skoji/convert-otf-to-ttf-and-fix-cmap

最後に

間違いの指摘や、より良い方法の提案を待ちわびています。