vhea、vmtx テーブル

vhea、vmtx テーブル
「vhea、vmtx テーブル」は、ほぼ「hhea、hmtx テーブル」と似たような形で、垂直レイアウト (縦書き) 用の情報が格納されています。

※ただし、GSUB で縦書きグリフに対応しているフォントの中には、すべてのグリフで送り幅が全角幅の場合、vhea,vmtx テーブルが存在しない場合もあるので、このテーブルが存在しないからといって、フォントが縦書きに対応していないというわけではありません。
レイアウト
水平レイアウトでは、原点は基本的に左下でしたが、
垂直レイアウトでは、原点は基本的に「左右中央、上端」となります。
また、Y 方向が下向きになります。



しかし、フォント内に格納されているアウトラインデータは、基本的に水平レイアウトでの座標値となっているため、縦書き時は、原点を移動する必要があります。
(座標の移動は、フォントを読み込む側が処理する必要があるので、場合によっては、左右の原点は左端のままで扱うこともできます)

X 原点
X の原点は指定されていませんが、縦書きに対応したグリフは、通常、em ボックスの中央に配置されているため、「unitsPerEM / 2」の位置となります。

Y 原点
Y の原点は、グリフの上端へ移動する必要があるため、各グリフの「top side bearing」と「yMax」を足した位置となります。
ただし、実際には、グリフの座標から、水平レイアウトの ascender を引いた位置を原点とします。

なお、その場合は、hhea ではなく、OS/2 の sTypoAscender を使った方が良いです。
源ノフォントなどでは、この2つの ascender は異なる値になっています。
CFF の場合
OpenType で VORG テーブルがある場合は、垂直レイアウト時の各グリフの Y 原点位置が格納されているので、その値を使うことができます。
vhea テーブル
Fixed versionバージョン。
0x00010000 = 1.0
0x00011000 = 1.1
(ver 1.0)
int16 ascent
(ver 1.1)
int16 vertTypoAscender
ver 1.0
中央線から前の行の descent までの距離。

ver 1.1
縦組用の ascender。
em-box の中央から em-box の右端までの距離。
通常、「unitsPerEm / 2」に設定されている。
(ver 1.0)
int16 descent
(ver 1.1)
int16 vertTypoDescender
ver 1.0
中央線から次の行の ascent までの距離。

ver 1.1
縦組用の descender。
em-box の中央から em-box の左端までの距離。
通常、「-unitsPerEm / 2」に設定されている。
(ver 1.0)
int16 lineGap
(ver 1.1)
int16 vertTypoLineGap
ver 1.0
予約 = 0。

ver 1.1
行間。
次の行までの距離は、「em-box width + vertTypoLineGap」。
int16 advanceHeightMaxadvance height の最大値
int16 minTopSideBearingtop side bearing の最小値
int16 minBottomSideBearingbottom side bearing の最小値
int16 yMaxExtentmax(tsb + (yMax - yMin))
int16 caretSlopeRise斜体フォント時のカーソルの傾斜。
水平の場合、0。
int16 caretSlopeRun水平の場合、1
int16 caretOffsetカーソルの移動量
int16 [4]予約 = 0
int16 metricDataFormat現在は 0 のみ
uint16 numOfLongVerMetricsvmtx テーブルのデータ数
vmtx テーブル
構成は、「hmtx テーブル」と同じです。

advanceWidth が advanceHeight、lsb が topSideBearing の値となります。
プログラム
>> 12_vhea_vmtx.c

vhea と vmtx テーブルのデータを表示します。

numGlyphs: 12239

---- vhea ----

version: 0x10000
ascent: 1802
descent: 246
lineGap: 0
advanceHeightMax: 2048
minTopSideBearing: -74
minBottomSideBearing: -325
yMaxExtent: 2373
caretSlopeRise: 0
caretSlopeRun: 1
caretOffset: 0
metricDataFormat: 0
numOfLongVerMetrics: 1

---- vmtx ----

[ gid ] ah, tsb
[00000] 2048, 41
[00001] 2048, 1802
[00002] 2048, 1802
[00003] 2048, 1802
[00004] 2048, 324
...

縦書きの場合、advanceHeight はすべて同じ値である場合がほとんどなので、numOfLongVerMetrics を 1 にして、すべてのグリフで advanceHeight を同じ値にすることができます。