GSUB テーブル (2) - FeatureList

FeatureList
次に、FeatureList テーブルを解説します。

「縦書き置換」「合字置換」「文字幅置換」など、各置き換えの種類ごとに分けられたデータとなっています。

実際に使う際には、ScriptList からインデックス番号を取得して参照するか、直接 FeatureList をテーブルを参照します。
テーブルデータ
FeatureList
uint16 featureCountFeatureRecord の数
FeatureRecord featureRecords[featureCount]FeatureRecord の配列。
featureTag の数値順に並んでいる。

ScriptList テーブルで取得したインデックス番号は、この配列の添字となる。

FeatureRecord
Tag featureTag識別子 ('vert' など)
Offset16 featureOffsetFeature テーブルへのオフセット位置。
(FeatureList の先頭を 0 する)

Feature
Offset16 featureParams0 (予約)
uint16 lookupIndexCount配列の数
uint16 lookupListIndices[lookupIndexCount]LookupList テーブルのインデックス番号 (0〜) の配列。
任意の順番で並んでいる。

最終的に、LookupList テーブルを参照するためのインデックス値が取得できます。

LookupList には、対象となるグリフを検索して、置き換えるためのデータが格納されています。
FeatureRecord のタグ (featureTag)
タグ一覧は、仕様書の「Feature tags」にあります (GSUB/GPOS 共通)。

GSUB で使われる主なタグは、以下の通りです。

文字置換
aalt複数あるバリエーションからの選択
nalt丸付き文字に置換
rubyルビ用かなに置換
loclデフォルトの形から、言語ごとにローカライズされたグリフに置換
合字/分解
liga合字置換
ccmp2つ以上のグリフの合字/分解
他の機能よりも先に実行する。
dlig活版印刷用の合字置換
縦書き
vert縦書きグリフへの置換
vrt2縦書き+欧文などを右に90度回転したグリフ。vert を上書きする。
vrtr縦書きでの横向き表示に適したグリフに置換。
vert と一緒に使うことを想定している。vrt2 と一緒には使えない。
幅変換
hwid全角を半角に置換
fwid半角を全角に置換
pkna等幅をプロポーショナルに置換
pwidプロポーショナルを等幅に置換
twid全角の1/3幅のグリフに置換
qwid全角の1/4幅のグリフに置換
字形変換
hkna標準のひらかなを横書き専用の字形に置換 (印刷上の最適化)
vkna標準のひらかなを縦組み用に置換
ital1つのフォントに、通常と斜体、両方の欧文が含まれる場合、通常グリフを斜体のグリフに置換。
漢字などの置換
smpl簡略字体、または中国語の簡体字に置換
trad旧字体、または中国語の繁体字に置換
jp78JIS90 → JIS78 に置換
jp83JIS90 → JIS83 に置換
jp90JIS78/83 → JIS90 に置換
jp04X 0213:2004 → それ以外に置換
nlck印刷標準字体
exptJIS78 字形に置換
hojoJIS X 0212-1990 と JIS X 0213:2004 の文字セットが重複しているため、両方をサポートするフォントを作成する場合は、0213 の方が推奨される。
0213 → 0212 のグリフに置き換える。
数字など
dnom数字やスラッシュを、分数用の分母グリフに置換
numr数字やスラッシュを、分数用の分子グリフに置換
frac分数用のグリフに置換
subs下付き文字
sups上付き文字
zero中にスラッシュがある数字のゼロに置換

複数処理
GSUB では、グリフの置換を複数連続して行うことができます。
('vert' で縦書き置換した後に、さらに別の文字に置き換えるなど)

仕様書にて、同時に使用できないタイプは指定されていますが、それらの処理は完全にソフトウェア側に委ねられているため、必要に応じて適当に対処する必要があります。
プログラム
>> 18_gsub_feature.c

GSUB の FeatureList の一覧を表示するプログラムです。

各 FeatureList インデックスを参照している ScriptList のタグも併せて表示しています。

---- FeatureList ----

featureCount: 631

[0] 'aalt' | offset:3788 | 0,1, ('DFLT' '*def')
[1] 'aalt' | offset:3796 | 0,1, ('cyrl' '*def')
[2] 'aalt' | offset:3804 | 0,1, ('cyrl' 'JAN ')
...
[574] 'vert' | offset:7672 | 49,50,53, ('hani' '*def')
[575] 'vert' | offset:7682 | 49,50,53, ('hani' 'JAN ')
[576] 'vert' | offset:7692 | 49,52,53, ('hani' 'KOR ')
[577] 'vert' | offset:7702 | 49,53, ('hani' 'ZHH ')
[578] 'vert' | offset:7710 | 49,51,52, ('hani' 'ZHS ')
[579] 'vert' | offset:7720 | 49,53, ('hani' 'ZHT ')
...

見てみるとわかりますが、同じタグで、LookupList インデックス値も全く同じものが複数個ならんでいる場合が多いです。

ただし、featureTag によっては、各言語によってインデックス値が異なっている場合もあります。

「源ノ明朝」や「源ノ角ゴシック」のような、中国語/日本語/韓国語がセットになっている CJK フォントでは、上記のように、各言語によって置き換える縦書きグリフが一部異なっています。

縦書きで必要なもの
vert」または「vrt2」です。

vrtr」はあまり使われていないと思うので、この2つのいずれかで、縦書きグリフへの変換を行います。

vrt2」には、基本的に「vert」と同じグリフに加えて、欧文などを時計回りに90度回転したグリフが含まれています。
縦書き中で欧文を横書きしたい場合に使います。

この2つのタグは、フォントによっては、片方しかない場合や、両方含まれている場合もあります。
どちらを使うかはソフトウェアによって異なるため、必要に応じて適切なものを使ってください。