Help us understand the problem. What is going on with this article?

OpenTypeの仕様入門 (前編)

More than 3 years have passed since last update.

OpenType

OpenTypeというのは世界中で最も使われているフォントファイル形式の仕様です。
仕様はこことかにあります。
これを理解すればだいたいOKです。

THE END


さて、仕様を読むのが面倒な方は下の続きもどうぞ。

OpenTypeフォントの構造

簡単にまとめると以下のような構造です。

  1. ヘッダ
  2. データ

簡単ですね。
そして、このヘッダの中には

  • それがどういう情報であるのか
  • 見るべきデータがどこにあるのか

が書かれています。

データの中にもまたヘッダがあることがあります。
そこにもやはり、それがどういう情報であるか、次に見るデータがファイル中のどこにあるか、ということが記されています。

冒頭に提示した仕様は、ヘッダがどのような構造体なのか、データがどういう意味を持つかということをまとめたものになります。

OpenTypeテーブル

フォントはヘッダとデータで構成されているというお話をしました。
フォントの先頭のヘッダにはテーブルと呼ばれるデータ構造が

  • いくつあるのか
  • どこにあるのか

ということが書かれています。
いくつあるのか、というのは実にわかりやすいですね。
10個あるのなら10という数値を指定された位置に書いておけばいいだけです。
しかし、どこにあるのかという情報はどのように保存されるのでしょうか。
正解は、何バイト先にデータあるのかという表現になります。
基準(0バイト先)はその文脈によって違い、これは仕様に明記されています。

さて、ここで先ほど登場したテーブルについて、代表的なものをリストにしてみました。

  • cmap: 文字コードのコードポイントからグリフIDへのマップ
    • これについては明日、もう少し詳しく説明します
  • head: フォントについての雑多な情報
  • hmtx: 各グリフの水平方向の送り幅などの情報
  • hhea: hmtxテーブルのデータ数などの情報
  • OS/2: フォントについての雑多な情報
  • maxp: フォント内の様々な最大値の定義(フォント描画エンジン向けの情報ですね)
  • name: フォント名などの情報
  • post: PostScript向けの情報
    • ここまでの8つのテーブルがフォントに必須の情報になります
  • vmtx: hmtxの縦書き用の情報
  • vhea: hheaの縦書き用の情報
    • これらは縦書きで非常に重要な情報なのですが必須ではなく、FreeTypeはこれが存在しない場合にはこのフィールドを自動で埋めてしまうので気をつけましょう
  • glyf: TrueType系のグリフデータ
  • loca: glyfテーブルのグリフデータとグリフIDの対応情報
  • CFF␣: PostScript系のグリフデータ
    • これらのグリフデータについては下でもう少しだけ説明します
  • GSUB: グリフIDを文字列の描画条件に従って違うグリフIDに変換する情報
  • GPOS: グリフの位置を、描画条件やグリフの並びに従って移動する情報
    • この2つについても明日の(後半)の記事でもう少し詳しく書きます

各テーブルは役割は様々ですが、全てを統合すると「指定された文字をどこにどういう風に描画するべきか」ということがコンピュータで解釈しやすい形で記されています。
ここに挙げた代表的なものの他にも多くのテーブルがあります。
特に最近、OpenType 1.8で追加されたバリアブルフォントに関連して非常に多くのテーブルが追加されました。

は半角スペース(U+0020)を表現しています。cmapなどをタグと呼び、タグは4字で構成されるためこのようになっています。
glyfとかいいですよね。これはglyphが入っているテーブルのタグです)

OpenTypeコレクション

余談ですが、フォントの先頭のヘッダが上の形式以外の場合があります。
これはフォントの拡張子が.ttc.otcの場合に見られるもので、ヘッダには内部に含まれるフォントの数と、そのフォントがファイル中のどこにあるのかが書かれます。

つまり、一つのフォントファイルに複数のフォントを含めることができるものです。
Windowsで「MS ゴシック」「MS Pゴシック」がまとめられていたりします。
また、最近のmacOSで多くのフォントがこの形式に変わったことでTeX界隈で少し話題になったりもしました。

グリフ

グリフというのは、フォントの中で一つの描画要素として扱う単位です。
基本的には文字コードのコードポイント一つが、グリフ一つに対応付けられます。
これを行なってくれるのが先に出てきたcmapテーブルです。
cmapテーブルについては明日の後編にまわして、ここではグリフについて説明します。

グリフは描画要素です。
そしてご存知のように画像には大きく2つ

  • ベクター画像
  • ラスター画像

があります。
フォントにもこの2つのグリフデータの形式があります。
ここではそれぞれ、アウトライングリフ、ビットマップグリフと呼ぶことにします。

アウトライングリフ

アウトライングリフにも2種類があります。

  • TrueType系(代表的な拡張子は.ttf
    • アウトラインデータは2次のベジェ曲線で表現される
    • グリフデータはglyflocaにある
  • PostScript系(代表的な拡張子は.otf
    • アウトラインデータは3次のベジェ曲線で表現される
    • グリフデータはCFF␣にある
    • CFFの仕様はOpenTypeとはまた別に存在する

つまり、PostScript系のフォントの方がグリフの表現自由度は1次高いことになります。
一方で、ヒンティングの機構はTrueType系の方が強いらしいのですが、私にはちょっと難しいですね。
ヒンティングというのは描画サイズに応じてアウトラインの制御点の位置を調整する機構のことです。
残念ながら仕様を把握していないので説明はスキップいたします。すみません。

ビットマップグリフ

グレースケールのビットマップグリフはEBDTEBLCというテーブルにあります。
EBLCにはEBDTのどこにどういうサイズの何階調のビットマップがあるかということが記されています。
EBLCで指定されたEBDTのアドレスには2,4,16,256いずれかの階調のグレースケール画像が直列化されて収っています。
ちなみに私は2階調(白黒)のビットマップグリフ以外に出会ったことがありません。

おわりに

明日は後編をお届けします(1日では書き終わらなかった)。
明日の内容は

  1. グリフIDの取得
  2. グリフIDの変換
  3. グリフの移動

です。
なお、カラー絵文字についてはどこかで1枠使います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away