# 高度組版機能テーブル (ATT)

これらは OpenType (当初 TrueType Open と呼ばれていました) と Apple (GX または Apple 高度タイポグラフィ (ATT)) とで違いがあります。このソフトの OpenType と Apple に対するサポートはどちらも不完全です。

- Apple の高度タイポグラフィ
- どの機能が OpenType と AAT の間で変換可能か?
- other true type and open type tables
- What is unsupported
- FontForge's non-standard extensions

## `GPOS`, `GSUB` および `GDEF` OpenType テーブル

これらの2つのテーブルは、グリフの位置変更と置き換えに用いられます。 GPOS テーブルは、以下のような物を制御することができます: カーニング、アクセントの位置指定、筆記体の結合など。 GSUB テーブルは以下のようなものを制御することができます: 合字、アラビア文字の複数の形、縦書き用の文字回転、小型大文字への変換、インド系文字のグリフ再配置など。

このページは、各テーブルで何をすることができるかの基本的な知識があることを仮定しています。それらに関してのより詳しい情報を得るには、以下の OpenType の文書を読み、学習して自家薬籠中のものとしてください。

- GPOS と GSUB に共通するヘッダ
- GPOS テーブル (グリフの位置決めに用いる)
- GSUB テーブル (グリフの置換に用いる)
- GDEF テーブル (グリフのクラス分けと合字キャレットテーブルの指定に用いる)
- OpenType がサポートする機能タグのリスト
- OpenType がサポートする用字系タグのリスト
- OpenType がサポートする言語タグのリスト

GPOS テーブルと GSUB テーブルの基本的アイディアは、各スクリプト (またはあるスクリプトを使用する言語) が、それらの文字に適用可能な“機能”の組をもっているという考えです。個々の機能はそれぞれが、その機能のためのデータを含む 1 個の索引に付随しています。用字系の例としては、ラテン文字の‘latn’, アラビア文字の‘arab’, 漢字の‘hani’が挙げられます。機能の例を 2 つ挙げれば、グリフの対の間のカーニング情報を提供する‘kern’や、ある一連のグリフを、単語の先頭に来たときに用いる別のグリフに置き換える‘init’があります。

FontForge は、これらの 2 つのテーブルによって可能なことの全ての範囲をサポートするわけではありません。

### `GPOS` テーブル

FontForge は GPOS テーブルの以下のサブテーブルを読み込みます:

| name | 読み込みサポート | 書き出しサポート
--- | --- | --- | ---
1 | 1 文字の調整 | このタイプのサブテーブルでは、特定のグリフのメトリックを変更することができます。どのようなコンテキストで変更が起こるかは、機能タグで指定します。例えば、‘tnum’ (表用数字) 機能により、プロポーショナル幅の数字の送り幅をある固定値に合わせてから (左サイドベアリングを調整して) 幅の中心に揃えることにより、プロポーショナル幅の数字を変更することができます。 | これらは `エレメント(L)`→`グリフ情報(I)...`→`[位置]` コマンドで作成することができます。
2 | 文字の対への調整 | このタイプのサブテーブルでは、フォントデザイナーがグリフのメトリックの特定の要素を変更することができます。最も一般的な使い方としては、カーニングで、最初のグリフの送り幅が、次に来るグリフが何であるかによって変わる場合に使用するものです。しかし、このテーブルはそれよりも一般的な用途に用いることができ、基底グリフの上に置かれるマーク (アクセント、母音) の位置指定をサポートすることができます (ただし、これはマークからの基底グリフ指定サブテーブルを使うともっと効率的に行うことができるのですが)。 | ‘kern’機能はメトリックビューから作成することができ、‘vkrn’は `メトリック(M)`→`横書きカーニングを縦書きに`で指定することができます。
3 | 筆記体の接続 | このサブテーブルでは、フォントデザイナーが隣接するグリフ同士を特定の位置で接続するように強制することができます。これは、ウルドゥー語で必要となる傾いた筆記体を出力するのに使用することができます。 | このサブテーブルでサポートされているのは‘curs’機能だけです。これは、`点(P)`→`アンカーを追加(A)...` コマンドによって作成できます。
4 | マークから基底グリフへ | フォントデザイナーは、このサブテーブルを使ってマーク (アクセント、母音記号など) グリフを基底グリフの上にどう配置するかを指定することができます。各グリフには接続点とを設定することができ、マークの接続点は基底グリフの接続点に重ね合わせられ、それによって それら正しく接続することになります。「概要」で示した私の例をご覧ください。 | これらは `点(P)`→`アンカーを追加(A)...` コマンドで作成することができます。
5 | マークから合字へ | このサブテーブルは前のものと非常によく似ていますが、基底グリフが合字であって、同じタイプのアクセントを置くことができるいくつかの異なる点が存在してよいいことです。 | これらは `点(P)`→`アンカーを追加(A)...` コマンドで作成することができます。
6 | マークからマークへ | このサブテーブルは上の 2 つに非常によく似ていますが、基底グリフそのものがマークであってもよい点が異なります。これは基底グリフに 2 個のアクセントが接続し、それらが基底グリフに対して同じ接続点をもっている場合に使用することができます。2 番目のアクセントは基底グリフからではなく、最初のアクセントからの相対位置によって配置されることになります。 | これらは `点(P)`→`アンカーを追加(A)...` コマンドで作成することができます。
7 | 文脈依存の位置指定 | フォントデザイナーは、このサブテーブルを使って、複数のグリフが特定の文字列 (または文字列のクラス) の中に現れたときの位置指定を制御することができます。 | これらは `エレメント(L)`→`フォント情報(F)...`→`[文脈依存]` コマンドで作成することができます。
8 | 文脈依存の連鎖型位置指定 | これは上記の機能のより複雑なバージョンで、実際には本当に新しい機能を追加するものではありませんが、同じ事柄に対するより論理的なアプローチを提供しています。 | これらは `エレメント(L)`→`フォント情報(F)...`→`[文脈依存]` コマンドで作成することができます。
9 | 拡張位置指定 | これは、GPOS テーブルが 64K より大きいときに使用します。これを使っていることは、フォントデザイナーからはまったく見えないようになっているべきです。 | FontForge は、必要になったときにこのサブテーブルを使います。
10+ | 将来の使用のために予約 |  | FontForge は (ほかの誰もと同様に) これらのサブテーブルにまだ対応していません。

FontForge には、これらのテーブルを使用するいくつかの機能に対して、どのようにデフォルト値を与えるべきかの知識が組み込まれています。これに関しては、`エレメント(L)`→`組版機能(Y)`→`デフォルトのATT(D)` コマンドを参照してください。

FontForge は GPOS テーブル内の機能の順番を保持し、フォントが出力されるときには前と同じ順番で出力されるはずです。

### `GSUB` テーブル

FontForge は以下のサブテーブルを GSUB テーブルから読み込みます:

| name | 読み込みサポート | 書き出しサポート
--- | --- | --- | ---
1 | 単純置換 (単独置換) | フォントデザイナーはこのサブテーブルを使って、あるグリフを別のグリフに、機能タグごとに定められた文脈の下で変更することができ。例えば、多くの用字系では、単語の終りに来たときには単語内に来たときと異なる形をもつ文字があります (これは、アラビア文字のほとんどの文字、ヘブライ文字のいくつか、ギリシャ文字の小文字シグマおよびルネッサンスのラテン文字の長い s/短い s のペアにおいては事実です)。そのために、‘fina’機能は通常の形から語尾専用の形への対応づけを行い、ワードプロセッサは各単語の末尾で、置換が必要かどうかを調べるためにその機能を使います。 | これらは `エレメント(L)`→`グリフ情報(I)...`→`[置換]` コマンドで作成することができます。
2 | 複数置換 | フォントデザイナーはこのサブテーブルを使って、1 個のグリフを別のグリフの列に置換することができます。これは一般的に、かなり技術的なレイアウトの作業に使用されます。 | これらは `エレメント(L)`→`グリフ情報(I)...`→`[複数置換]` コマンドで作成することができます。
3 | 選択肢つき置換 | フォントデザイナーはこのサブテーブルを使って、一連の“選択肢”を各グリフに持たせることができます。よくある一例としては、イタリックフォントの各大文字に、数種類のスワッシュ変種がある例でしょう。ワードプロセッサは、これらのどの変種が適切かを選ばせることができるでしょう。 | これらは `エレメント(L)`→`グリフ情報(I)...`→`[選択型の置換]` コマンドで作成することができます。
4 | 合字置換 | フォントデザイナーはこのサブテーブルを使って、複数のグリフの並びを別の 1 個のグリフに置き換えることができます。よくある例としては、 というグリフの並びが合字 に置き換えられるなどの合字処理があります。 | これらは `エレメント(L)`→`グリフ情報(I)...`→`[合字]` コマンドで作成することができます。
5 | 文脈依存の置換 | 個のサブテーブルでは、複数のグリフの並びを別のグリフの並び (またはグリフの並びのクラス) に置き換えることができます | これらは `エレメント(L)`→`フォント情報(F)...`→`[文脈依存]` コマンドで作成することができます。
6 | 文脈連鎖依存の置換 | これは上記の機能のより複雑なバージョンで、実際には本当に新しい機能を追加するものではありませんが、同じ事柄に対するより論理的なアプローチを提供しています。 | これらは `エレメント(L)`→`フォント情報(F)...`→`[文脈依存]` コマンドで作成することができます。
7 | 拡張置換 | これは、GSUB テーブルが 64K より大きいときに使用します。これを使っていることは、フォントデザイナーからはまったく見えないようになっているべきです。 | FontForge は、必要になったときにこのサブテーブルを使います。
8 | 逆順・連鎖型文脈依存の単独置換 | これを使うと、グリフ置換を逆順に行うことができます。これは連鎖型文脈置換サブテーブルの変種です。 | これらは `エレメント(L)`→`フォント情報(F)...`→`[文脈依存]` コマンドで作成することができます。
9+ | 将来の使用のために予約 |  | FontForge は (ほかの誰もと同様に) これらのサブテーブルにまだ対応していません。

FontForge には、これらのテーブルを使用する機能のいくつかに対しては、どのようにデフォルト値を与えるかの知識も組み込まれています。

FontForge はこれらのテーブルのうちのいくつかを出力できますが、テキストレイアウト/ワードプロセッシング処理を行うプログラムは、このテーブルを参照して、実際にグリフを再配置する作業を行う必要があります。

FontForge は GSUB テーブル内の機能の順番を保持しており、ユーザはそれを `エレメント(L)`→`フォント情報(F)...` コマンドで並べ替えることができます。

### `GDEF` テーブル

FontForge は合字キャレットを GDEF テーブルから読み込みます。

FontForge は、グリフクラス定義サブテーブル (必要な場合) または合字キャレット (必要な場合) を含む GDEF テーブルを生成します。

## Apple 高度組版機能 (ATT)

上に書いたように、私はこれらのテーブルの機能の詳細には立ち入りません。より詳しい情報に関しては Apple の文書を参照してください。

- ‘kern’テーブル
- ‘lcar’ (合字キャレット) テーブル
- ‘morx’ (拡張グリフ変形) テーブル
  - ‘mort’ (‘morx’ の旧版) テーブル
  - ‘feat’ (機能) テーブル
  - Apple のフォント機能登録簿
  - ‘mort’/‘morx’テーブルのサブテーブルの説明
- ‘opbd’ (視覚的境界線) テーブル
- ‘prop’ (グリフ属性) テーブル

現在、FontForge は以下のテーブルの読み書きを (Apple モードがフォント出力時に設定されていれば) 行います:

GDEF にほぼ相当する OpenType のテーブル
tag | name | 読み込みサポート | 書き出しサポート
--- | --- | --- | ---
`'lcar'` | 合字キャレットテーブル | FontForge は合字キャレットを読み込みます | FontForge は、ユーザが合字キャレットを出力していればこのテーブルを出力します。
`'prop'` | グリフ属性テーブル | FontForge は、ヘブライ文字とアラビア文字にあたり、‘r2la’置換を行うののがどの文字であるかを特定するためにこのテーブルを読み込みます。 | FontForge は、フォントに何らかの右から左へ書くグリフが含まれているときにこのテーブルを出力します。

GPOS にほぼ相当する OpenType のテーブル
tag | name | 読み込みサポート | 書き出しサポート
--- | --- | --- | ---
`'kern'` | カーニングテーブル | FontForge は横書き/縦書きカーニングペアとカーニングクラスを読み込みます。FontForge は文脈依存のカーニング情報を状態機械に読み込むこともできます。 | FontForge は、フォントにカーニングデータが含まれていればそれ――カーニングペア・クラスごとのカーニングおよび状態機械によるカーニング――を出力します。
`'opbd'` | 視覚的字端テーブル | FontForge は視覚的字端を読み込みます | FontForge は、ユーザが単純な位置による左端および右端の指定 (‘lfbd’と‘rtbd’) を行った場合、これらのテーブルを出力します。

FontFonge には `‘mort’` (グリフ変形) テーブルと `‘morx’` (拡張グリフ変形) テーブルのサポートが含まれています。これらは大まかに GSUB テーブルと対応しています。注意: OpenType の昨日に直接対応するすべての任意の機能タイプ/設定の組合せは、読み込み時に OpenType タグに変換されます。それが機能/設定の対に書き戻されるのは、Apple 対応のフォントを生成したとき (FontForge の機能/設定から OpenType タグへの対応表を拡張するには、`ファイル(F)`→`環境設定(E)...` を使用してください)。

`‘mort’` または `‘morx’` テーブルのサブテーブル
| 名前 | 読み込みサポート | 書き出しサポート
--- | --- | --- | ---
0 | インド系文字用の再配置 | FontForge はこれらを読み込み、状態機械として格納することができます (それらは フォント情報 で編集することができます)。 | すべてのインド系文字状態機械は、出力されるフォントに書き出されます。
1 | 文脈依存のグリフ置換 | FontForge はこれらを読み込み、状態機械として格納することができます (それらは フォント情報 で編集することができます)。 | フォントに何らかの状態機械が含まれていれば、それらはここに書き出されます。もし、状態機械が存在しないならば、以下のようにして OpenType 機能から変換します: FontForge は、フォントに‘init’,‘medi’,‘fina’または‘isol’による単純置換が含まれていれば、このサブテーブルを使って筆記体の接続機能を書き出します。 一定の条件を満たしている場合には、FontForge は OpenType の文脈依存テーブル/連鎖型文脈依存テーブルを Apple の文脈依存グリフ置換テーブルに変換することができます。
2 | 合字置換 | FontForge は無条件の合字情報を読み込み、OpenType の合字として格納することができます (それらは グリフ情報 で編集することができます)。 | フォントに何らかの合字が含まれていれば (または Apple の機能/設定に変換可能な OpenType タグが存在すれば) このテーブルが出力されます。
4 | 文脈非依存のグリフ置換 | FontForge はこれらを読み込み、OpenType の単純置換として格納することができます (それらは グリフ情報 で編集することができます)。 | フォントに何らかの置換が含まれていれば (または Apple の機能/設定に変換可能な OpenType タグが存在すれば) このテーブルが出力されます。
5 | 文脈依存のグリフ挿入 | FontForge はこれらを読み込み、状態機械として格納することができます (それらは フォント情報 で編集することができます)。 | すべてのグリフ挿入状態機械は出力されるフォントに書き出されます。

### OpenType と AAT との間ではどの機能が相互変換可能か?

いくつかの機能は OpenType と AAT でほとんど同じ意味をもっており (それらの表現方法はまったく異なりますが)、他のいくつかは場合によっては変換可能なほど十分似ていますが、その他は本質的に共通の基盤をもっていません。

OpenType テーブル | AAT テーブル | 説明
--- | --- | ---
GDEF | lcar | 合字キャレット情報は‘GDEF’と‘lcar’で本質的に等しく、FontForge は両形式の読み込みと、相互変換を問題なく行えます。
GPOS | kern | ほとんどの場合、カーニング情報は片方のフォーマットからもう一方へと変換可能です。両方とも縦書きカーニングと右横書きのカーニングをサポートしています。 OpenType はカーニングコマンドを条件連鎖型の機能を通じて提供可能で、Apple では状態機械によって制御することが可能です。FontForge は両方をサポートしていますが、相互変換はしません。
GPOS | opbd | GPOS 機能‘lfbd’および‘rfbd’は Apple の opbd テーブルを生成するのに十分なだけの情報を備えています。FontForge が opbd テーブルを服務フォントを読み込んだときには、適切な‘lfbd’および‘rtbd’機能を作成します。FotnForge が Apple モードのフォントを出力するときにそれらの機能が存在する場合、‘opbd’テーブルを作成します。同様に、FontForge が opbd テーブルを読み込むとき、‘lfbd’と‘rtbd’機能を作成します。
GPOS |  | 私はその他の GPOS 機能を AAT に変換する方法については知りません。
GSUB | morx | ‘mort’および‘morx’テーブルは同じ機能をもっています (‘mort’テーブルは古いフォーマットで、Apple は現在それの代わりに‘morx’を用いることを推奨しています)。FontForge はどちらも読み込むことはできますが、‘morx’テーブルのみを出力します。相互変換ができるかどうかは個別の機能タイプおよびサブテーブルに依存します。以下を参照してください:
GSUB | mort

#### GSUB および morx サブテーブルの解析と機能タグ

OpenType が 4 文字の機能タグ (‘liga’など) を使用しているのに対し、Apple は機能設定を表す 2 個の数値 (<1,2> など) を使用します。FontForge にとっては、OpenType の機能と Apple の機能を相互変換できるようにするためには、まず 2 つの名前付規約の間の対応づけが存在しなければなりません。時には、単純な直接変換が存在する場合もあります (例えば、‘liga’と <1,2> はどちらも“一般的な合字”を表します)。FontForge が、相互変換が十分可能なほど似ているとみなしているタグと機能の設定の一覧は、以下を参照してください。

GSUB テーブルには 7 種類のサブテーブルフォーマットがあるのに対し、morx テーブルには 5 種類があります。

GSUB サブ テーブル | morx サブ テーブル | 説明
--- | --- | ---
単独 | 文脈 独立な グリフ | これらの 2 種類のサブテーブルはほとんど正確に同じ機能をもっています。それぞれ 1 個のグリフをもう 1 つのグリフにすることができます。morx サブテーブルではグリフを削除することもできますが、GSUB サブテーブルではこれを許していません。
複数 |  | この GSUB サブテーブルは、1 個のグリフを複数のグリフによって置き換える個とが可能です。以下の相違点を除いて、Apple のグリフ挿入サブテーブルとある程度の類似点があります: ‘morx’サブテーブルは、常に現在のグリフをグリフストリームに残すのに対して、このサブテーブルは残す必要はありません。 ‘morx’サブテーブルは文脈依存であるのに対し、このサブテーブルは完全に文脈独立です (ただし、このサブテーブルが文脈依存または連鎖型文脈依存サブテーブルに包まれているときは、結果が文脈依存になることもあり得ます)。
| グリフ 挿入 | この morx サブテーブルを使うと、グリフの列を現在のグリフの前後に挿入することができます (現在のグリフは常にそのまま残ります)。このサブテーブルは文脈依存です (すなわち、挿入が起こるのを特定の文脈に制限することができます)。上に挙げた GPOS の複数置換テーブルとある種の類似性があります。
選択肢 |  | この GSUB サブテーブルを使うと、1 個のグリフをいくつかの選択肢から (おそらくは、ワードプロセッサーの UI の助けを借りて) 任意の 1 個と交換することができます。この一例はいくつかの変種のスワッシュをがある文字です。‘morx’テーブルにはこれと似たような機能はありません。
合字 | 合字 | どちらのフォーマットにも合字サブテーブルは存在します。‘GSUB’のバージョンは文脈非依存です (合字は常に適用されます――合字置換を OpenType の文脈依存の置換に埋め込んで、実行条件をつけることはできますが)。‘morx’バージョンは文脈依存にすることも可能です (私が調べた限りでは、文脈非依存であるのが通例でしたが)。FontForge は文脈非依存の合字のみをサポートしています。 FontForge はすべての文脈非依存の合字を‘morx’サブテーブルから読み込むことができます。FontForge は文脈依存の合字をすべて捨ててしまいます。 OpenType では、文脈依存の合字は、合字サブテーブルを文脈依存または連鎖型文脈依存サブテーブルに埋め込むことによって作成可能です。
| 文脈依存の グリフ | この morx サブテーブルを使うと、単純グリフ置換をいくつかの文脈に適用することができます。一見して、これは OpenType の文脈依存サブテーブルに変換することができるように思えますが、それが可能なのはごく稀な場合でしかありません。
文脈依存 |  | これらの GSUB サブテーブルはその他の置換の任意の集合を文脈依存の形で適用することが可能です。一見して (適切な入れ子構造の置換を含む) この種類のテーブルは‘morx’の文脈依存グリフ置換、文脈依存の合字、またはグリフ挿入にさえ変換することが可能なように思えるでしょう。それが可能なのはごく稀な場合でしかありません。
連鎖型 文脈依存 |
逆順の 連鎖型 文脈依存 |  | この GSUB サブテーブルはグリフのストリームに対して逆順に適用されるもので、所定の文脈に一致するごとに単独グリフ置換を 1 回行うことができます。‘morx’にはこれに似た機能は存在しません。
| インド系 文字の 再配置 | この‘morx’サブテーブルを使うと、グリフのストリームに含まれるいくつかの文字の順番を交換する事ができます。 GSUB には (同じく GPOS にも) 似たような機能は存在しません。

#### なぜ文脈依存のグリフ置換はたまにしか AAT で出力できないのか?

嘆かわしいことに、OpenType と AAT とが提供している機能は、文脈を照合する処理に関しては共通点がないのです。ある部分では AAT のほうが機能豊富で、別の部分では OpenType のほうが機能豊富です。FontForge が OpenType の文脈依存置換を AAT の置換に変換することができるのは、その OpenType 置換が AAT の能力を超えた機能を使用していないことを FontForge が検出できたときに限られます。現在のところ、具体的には以下の条件を満たしている必要があります:

- その OTF タグに適合する Apple の機能が存在する
- それに加え、以下のどれか 1 つが正しい:
  1. 以下のどちらかの条件が満たされている:
     - そのサブテーブルが適用範囲フォーマットであるか、もしくは
     - そのサブテーブルがちょうど 1 個の入れ子構造の単純グリフ置換を含んでいるか、または
       ちょうど 2 個の単純グリフ置換を含んでいて、それらのうちの 1 つが、最後に一致したグリフを参照している (そして、もう 1 つのほうは参照していない)
  2. または以下の場合。
     - そのサブテーブルがグリフフォーマットかクラスフォーマットのどちらかである
     - クラスフォーマットの場合、バックトラックと前方参照クラスは全てメインクラスと同じであるか、それらを使っていないかのどちらかでなければなりません。
     - あるルールが所定のグリフ位置での置換を含んでいる場合、現在のルールに一致するそのグリフ位置までのすべてのルールもまた、その位置における置換を含んでいなければなりません。
     - ちょうど 1 個の置換を含むルールは認められます。
       途中に 1 個の置換を含み最後のグリフで起こる置換を 1 個含むルールも認められます。
       ルールには、さらに追加の置換を含むことができる場合があります。それは、途中までの置換とその部分まで正確に同じ置換を行う別のルールがある場合に限ります。
       これによると、以下の置換セットは正しいことになります:

       ルール | a | b | c | d | e | f
       ルール | a | b | c | d |  |
       ルール | a | b |  |  |  |
       置換 | A | B | C | D | E | F

       ここでは 3 番目のルールは“ab”に一致し、それを“AB”に変換します (これは途中までの置換 1 個と最後までの置換 1 個を含んでいるので、正しいルールです) その後、“ab”の後に“cd”が来た場合にはルール 2 が呼び出され、“cd”を“CD”に置き換え (この場合も、1 個の中間置換と 1 個の末尾までの置換を含んでおり、これも問題ありません)、さらに“ef”が後ろに来たならば、それらは“EF”に変換されます。

       以下は正しくありません:

       置換 |  | B |
       ルール | a | b | c
       ルール | a | b |
       置換 | A |  |

       2 つのルールは異なる場所での置換を含んでいるので、それらが同じグリフを含んでいるならば Apple 状態機械では表現できません。

FontForge は、AAT の文脈依存グリフ置換サブテーブルを変換しようと試みることすらありません。OpenType に変換可能な場合があまりにも少なくて、試みる価値がないからです。

注意: もし FontForge が以下の処理を行えば、より多くの照合を状態機械に変換することができるでしょう:

1. 複雑な照合を表現するためにいくつかの状態機械を使う
2. 一時的な状態フラグとして、追加のグリフをフォントに付け加える

これらの両方とも、FontForge が実現する予定はありません。

#### バグ

連鎖型文脈依存置換から Apple の文脈依存グリフ置換への変換処理に関する微妙なバグが存在します。AAT にはバックトラックリストの概念が存在しないので、それにより置換が起こる順番が変わってしまう可能性があります。

#### なぜすべての文脈依存/連鎖型文脈依存テーブルを変換できないのか?

ええと、いくつかの機能は明らかに片方にしか存在しません。文脈依存の位置指定は AAT にはありませんし、インド系文字の再配置は OpenType にはありません。 だからここでは両方でサポートされているらしい、文脈依存の置換に話をしぼることにしましょう。以下の議論は、文脈の照合処理の能力に基づいており、文脈依存の合字・グリフ挿入・グリフ置換およびカーニングのどれについても同じことが言えるので、ここで示す例は表現が簡単なグリフ置換のみを挙げます (それにまた、FontForge が変換を行おうとするのは文脈依存のグリフ置換のみに限られるからです)。しかしそれに限っても、OpenType と Apple が仕様で示している文脈依存の置換を行う方法は、根本的にかけ離れた概念に基づいています。 以下のような、グリフリストフォーマットによる文脈依存の置換があるとします:

初期シーケンス | a | b | c | d
置き換え対象 |  | B | C |

ここで、OpenType ではこれは“abcd”というシーケンスを探し出し、それから“b”を“B”に、“c”を“C”に置き換えます。しかしこれは Apple 状態機械では表現できません。OpenType では照合が最初に行われ、後から置換が行われます。状態機械では置換は (ほとんど) 照合と同期的に行われるので、最後の“d”があろうが無かろうが行わなければなりません。(ここで私がグリフ列を使用したのは、簡単に表示できるからであることに注意してください。同じ問題は、置換がクラスまたは適用範囲テーブルで表現されている場合にも起こります)

以下のような、2 個のグリフ列を含むテーブルがあるとします:

初期シーケンス | a | b | c | d
置き換え対象 |  | B |  |
初期シーケンス | a | b | c | e
置き換え対象 |  |  | C |

これは、最後に“d”が存在すれば“b”を置き換え、その他の場合には“c”を置き換えます。これも、Apple の状態機械では表現できません。

最後に、以下の場合があったとします:

初期シーケンス | a | b | c | d
置き換え対象 |  |  | C |
初期シーケンス | b | c | e |
置き換え対象 | B |  |  |

この置換が与えられた場合、シーケンス“abce”は AAT では動作しません。 "a" を読み込んだ時には“abcd”の分岐に入り、"d" を探そうとして“e”にぶつかるまで照合は失敗しません。ここでは、“bce”の分岐に入るのは遅すぎです(ので、一致しないことになります)。なぜなら、“b”のグリフは置換位置として印づけられなかったからです。

一方、Apple の状態機械は OpenType ではできないような事を表現できます (ここでも文脈依存のグリフ置換に話を絞ります)。単語の最初 (または最後) のスワッシュグリフの場合を考えます。単語は、入力の最初または空白文字の次に始まるものと考えられるでしょう。しかし OpenType の文脈依存/連鎖型文脈依存においては、Apple の状態機械に存在する“入力の始まり”(または入力の終り) を表現する方法がありません。

Apple のグリフ置換はグリフを削除する糊塗ができるので、文脈依存グリフ置換テーブルは 2 文字の合字を作成することができます (片方のグリフを合字に変換し、もう片方を削除します) が、OpenType でこれを行うためには、合字置換を使用しなければなりません。

最後に、AAT 状態機械は一般的な正規表現を用いた照合処理が可能ですが、OpenType テーブルは固定長の文字列との照合しかできません。数式を組版していて、変数の後ろに続く任意の桁数の数字を下つき文字にしたいとしましょう (その場合、x23 は x23 になります)。数字が連続する限り同じ置換処理を続ける状態機械を書くのはまったく簡単ですが、同じ表現力を OpenType で得るには、無限個のルールが必要となります。

これらの例はおそらく非常に不自然に見えるでしょうが、(スワッシュ文字の例を除いては) 確かにその通りです。しかし、これらは、2 つのフォーマットが非常に異なる表現能力をもっており、片方のフォーマットで書かれた任意の入力を受け取ってもう片方のフォーマットでの等価な出力に変換するコンバータを書くのが不可能であることを示す実例です。

### Apple と OpenType の機能

Apple と OpenType の 機能 の対応表
(私がサポートしている物のみ)
Apple の機能設定 | OpenType の機能名 | OpenType タグ
--- | --- | ---
必須の合字 | 必須の合字 | rlig
一般的な合字 | 標準の合字 | liga
稀な合字 | 任意の合字 | dlig
分数 | 分数 | frac
文脈依存の選択肢 | 筆記体の接続 | calt
縦書き字形 | 縦書きおよび回転 | vrt2
等幅数字 | 表用数字 | tnum
上つき文字 | 上つき文字 | sups
下つき文字 | 下つき文字 | subs
プロポーショナルテキスト | プロポーショナル幅 | pwid
半角テキスト | 半角 | hwid
全角テキスト | 全角 | fwid
繁体字中国語 | 繁体字 | trad
簡体字中国語 | 簡体字 | smpl
1978 年版 JIS 字形 | 1978 年版 JIS 字形 | jp78
1983 年版 JIS 字形 | 1983 年版 JIS 字形 | jp83
1990 年版 JIS 字形 | 1990 年版 JIS 字形 | jp90

FontForge は morx テーブル内の機能の順番を保持し、ユーザはそれを `エレメント(L)`→`フォント情報(F)...` コマンドで並べ替えることができます。(これは GSUB テーブルのために使用されるのと同じリストです。Mac に対応する機能が無い GSUB 機能は無視されます)。

## どの機能がサポートされていないのか?

FontForge は OpenType と AAT のどちらでも、(まだ) すべての高度組版機能が使用可能なわけではありません。

### OpenType

- FontForge は TrueType の点を使った位置指定の制御をサポートしていません。
- FontForge does not support some of the more esoteric uses of the lookup flags. FontForge は照合フラグのとくに秘教的な使用法のいくつかをサポートしていません。
- FontForge は GDEF テーブルの接続リストサブテーブルと MarkAttachClassDef サブテーブルに対応していません。
- FontForge は BASE テーブルと JUST テーブルに対応していません。
- FontForge は VORG テーブルに対して最小限の対応しか行っていません。

対応しているテーブルの完全なリストはこちらを参照してください。

### Apple 高度組版機能

- FontForge は決して‘mort’テーブルを生成しません。‘mort’テーブルを読み込むことはできますが、出力するのは‘morx’テーブルだけです。
- FontForge は文脈依存の合字を解析することができません。状態 0 から始まる合字は発見できますが、他の状態から始まる (すなわち、文脈依存の) 合字は発見できません。
- FontForge は以下の Apple 固有のテーブルに対応していません。
  - acnt (アクセントの接続)
  - bsln (ベースライン)
  - fdsc (フォント記述子)
  - fmtx (フォントメトリック)
  - hsty (スタイル指定時の幅情報)
  - just (行揃え)
  - trak (トラッキング)
  - Zapf (グリフ参照)

対応している機能の完全なリストについては、ここを参照して下さい。

― 前 ― 目次 ― 次 ―