OpenTypeレイアウトへの道(5)・・・GSUBテーブル
ということで、やっとGSUBテーブルに突入。
GSUBテーブルはフォントでサポートされる様々なスクリプトや言語システムを表すためのグリフ置換(Glyph Substitution)の情報を定義するテーブルであり、様々な言語システムでグリフ置換が必須である。
GSUBテーブルはScriptList、FeatureList、LookupListへのオフセットを定義するGSUBヘッダーで始まり、GSUBヘッダーの構造は次のようになる。
| 型 | 名前 | 説明 |
| Fixed | Version | バージョン番号 |
| Offset(USHORT) | ScriptList | ScriptListへのGSUBテーブルの先頭からのオフセット |
| Offset(USHORT) | FeatureList | FeatureListへのGSUBテーブルの先頭からのオフセット |
| Offset(USHORT) | LookupList | LookupListへのGSUBテーブルの先頭からのオフセット |
また、前回説明したが、Lookupテーブルは1つ以上のLookupサブテーブルによって定義され、ルックアップタイプによってそのLookupサブテーブルの構造が違うが、グリフ置換でサポートされているルックアップタイプは次のようになる。
| 値 | タイプ | 説明 |
| 1 | 単独置換(Single Substitution) | 1つのグリフを他の1つのグリフで置き換える |
| 2 | 複数置換(Multiple Substitution) | 1つのグリフを複数のグリフで置き換える |
| 3 | 代替置換(Alternate Substitution) | 1つのグリフを複数のグリフの内の1つのグリフで置き換える |
| 4 | 合字置換(Ligature Substitution) | 複数のグリフを1つのグリフで置き換える |
| 5 | 文脈依存置換(Contexual Substitution) | 1つ以上のグリフを文脈に応じて置き換える |
| 6 | 連鎖型文脈依存置換(Chaining Contexual Substitution) | 1つ以上のグリフを連鎖文脈に応じて置き換える |
| 7 | 拡張置換(Extension Substitution) | 他の置換のための拡張メカニズム |
| 8 | 逆順連鎖型文脈依存単独置換(Reverse Chaining Contexual Single Substitution) | |
| 9以上 | 予約済み | 将来の使用 |
ルックアップタイプ1の単独置換は1つのグリフを他の1つのグリフに置き換える置換で、例えば、縦書きために横書きのグリフを縦書きのグリフを置き換えたりするために使われる。ルックアップタイプ2の複数置換は、1つのグリフを複数のグリフに置き換える置換で、合字分解などで使われる(例えば、合字のグリフ"fi"を"f"と"i"の2つのグリフに置き換える等)。ルックアップタイプ4の合字置換は、複数のグリフを1つのグリフに置き換える置換である(例えば、"f"と"i"の二つのグリフを"fi"という単一のグリフに置き換える等)。ルックアップタイプ7の拡張置換は、他の置換のための拡張メカニズムで、通常のLookupサブテーブルは16ビット(USHORT)のオフセット位置に格納されるが、32ビットのオフセット位置に格納するために使われる。
各ルックアップタイプのLookupサブテーブルの構造だが、ここでは、ルックアップタイプ1の単独置換のLookupサブテーブルの構造だけを見てみる。ルックアップタイプ1の単独置換のLookupサブテーブルのフォーマットは2つあり、その構造はそれぞれ次のようになる。
| 型 | 名前 | 説明 |
| USHORT | SubstFormat | フォーマット識別子=1 |
| Offset(USHORT) | Coverage | CoverageテーブルへのLookupサブテーブルの先頭からのオフセット |
| USHORT | DeltaGlyphID | グリフインデックスのデルタ値 |
単独置換フォーマット1は出力グリフのグリフインデックスを計算して求めるのだが、出力グリフのグリフインデックスを求めるには、定数のデルタ値(DeltaGlyphID)を入力グリフのグリフインデックスに加算する。Coverageはグリフ置換を適用するグリフを定義するCoverageテーブルへのオフセットである。
| 型 | 名前 | 説明 |
| USHORT | SubstFormat | フォーマット識別子=2 |
| Offset(USHORT) | Coverage | CoverageテーブルへのLookupサブテーブルの先頭からのオフセット |
| USHORT | GlyphCount | Subsitutes配列内のグリフインデックスの数 |
| GlyphID(USHORT) | Substitutes[GlyphCount] | Substitutes配列(カバレッジインデックス順) |
単独置換フォーマット2はフォーマット1より融通の利くフォーマットであるが、より多くのスペースを必要とする。
ということで、実際にフォントを解析してみるのだが、まずは、前回のMSゴシックのGSUBテーブルのLookupListの解析結果を再掲載する。
このインデックス0のルックアップはkana->JAN言語システム内で定義されている縦書きのためのvertフィーチャーで使われているルックアップであるが、今回の説明を踏まえて、そのルックアップタイプが1(単独置換)であることも分かる。また、Lookupサブテーブルは1つである。
次にこのLookupサブテーブルの中身を見てみる。
上の画像より、例えばグリフインデックス1941のグリフのエントリがCoverageテーブルに含まれている(カバレッジインデックスは42)ので、このグリフはグリフ置換の対象になるが、このグリフがグリフ置換によって、グリフインデックス19641のグリフに置換されることも分かる(Substitutes配列のインデックス42のエントリ)。
次にこれらグリフインデックス1941、19641のグリフをglyfテーブルで見ると、
句点「。」のグリフであるのだが、以上を踏まえると、
vertフィーチャーによって横書きの句点のグリフが縦書きの句点のグリフに置換されるように定義されていることが分かる。
Tahomaフォントはややこしいので省略・・・
最後に、T2FAnalyzerの方も最新版をアップロードしてあるのだが、現状、ルックアップタイプ1~4までのLookupサブテーブルにしか対応していない
。内部的にすべてのルックアップタイプのサブテーブルを解析しているのだが、GUIの方がまだ・・というより、しばらく他の事やろう。ははは。
| 固定リンク
「フォント」カテゴリの記事
- OpenTypeフォントの続き(12)・・・PostScriptアウトラインの更に続き(2009.11.12)
- OpenTypeフォントの続き(11)・・・PostScriptアウトラインの続き(2009.11.07)
- OpenTypeフォントの続き(10)・・・PostScriptアウトライン(2009.11.04)
- OpenTypeフォントの続き(2)・・・OpenTypeテーブル(2008.02.07)
- CFF/Type2 Charstring(2009.10.26)





コメント
vanillaさん、今晩は。
GSUBテーブル、初めて見させていただきました。
何となくイメージが湧いてきました。
しかし縦書きグリフ取得でMSゴシックはOKでしたが、他メーカのフォントではGSUBを持たないものもあるようです。
結構複雑な仕掛けみたいですね。
#T2FAnalyzerのサイズが3倍以上になっているのにはびっくりしました。
投稿: vector | 2008年8月23日 (土) 19時16分
お久しぶりです。
>GSUBテーブル、初めて見させていただきました。
何となくイメージが湧いてきました。
しかし縦書きグリフ取得でMSゴシックはOKでしたが、他メーカのフォントではGSUBを持たないものもあるようです。
基本的に、GSUBテーブルで置換元のグリフ(Coverageテーブルで)と置換先のグリフを定義しますが、縦書きのためのvertフューチャーがおわかりのように、MSゴシックでは、kanaスクリプトで定義されていて、一方、Uniscribeが入力文字列から文字列(ラン)のスクリプトを判断するのですが、句読点や括弧をhaniスクリプトと定義しているようで、MSゴシックでは縦書きのグリフに置換できないようです。MSゴシックのScriptListにhani->JAN->vertなどのエントリを追加するだけでいいのですが、Microsoftはそれすらもしないなんて。うむむ。
>T2FAnalyzerのサイズが3倍以上になっているのにはびっくりしました。
ははは。やっぱりお気づきになりましたか。プログラムを新規に3倍書いたのではなく、グリッドとかを高機能のものに置き換えたので膨れ上がりました。
投稿: vanilla | 2008年8月24日 (日) 01時59分