loca, glyf テーブル

loca、glyf テーブル
この2つのテーブルには、TrueType のアウトラインデータが格納されています。
※ PostScript アウトラインの場合、このテーブルは存在しません。

loca」には、各グリフごとの glyf テーブルのオフセット位置が、
glyf」には、各グリフのアウトラインデータが格納されています。
loca テーブル
すべてのグリフの、glyf テーブルのオフセット位置が格納されています。
まずは、ここでオフセット値を取得します。

numGlyphs は、maxp テーブル内の値です。

Offset16 offsets[numGlyphs + 1]
または
Offset32 offsets[numGlyphs + 1]

テーブル先頭から、「グリフ数 + 1」個分のオフセット値の配列が格納されています。

オフセット値のデータ型は、head テーブル内の「indexToLocFormat」値で決まります。
0 で Offset16、1 で Offset32 です。

※ Offset16 の場合は、実際のオフセット値を2で割った値となっています。

  • オフセット値は、glyf テーブルの先頭を 0 とした値で、4 byte 単位に揃えられています。
    ただし、古いフォントなど、まれに 4byte 単位になっていない場合があるので、注意してください。
  • オフセット値は、値の小さい順に並んでいます。
  • 配列の最後の値は、「glyf テーブルの長さ」と一致します。
  • グリフにアウトラインデータがない場合、オフセット値は「offset[i] = offset[i + 1]」となっています。
    次のグリフのオフセット値と同じであれば、アウトラインデータはないと判断できます。
    そのため、配列の数が1つ多くなっています。
  • 各グリフのアウトラインデータの長さは、「offset[i + 1] - offset[i]」で算出できます。
glyf テーブル
すべてのグリフのアウトラインデータが、グリフ ID 順に、連続して格納されています。
loca テーブルのオフセット値を使って参照します。

各グリフの先頭には、以下のデータがあります。

int16 numberOfContours輪郭の数。
一筆書きによるアウトラインがいくつあるか。

負の値の場合は、複数のグリフのアウトラインを結合した、複合グリフ。
int16 xMin
int16 yMin
int16 xMax
int16 yMax
輪郭の最小/最大 X、Y 位置。
左下が (xMin, yMin) で、右上が (xMax, yMax)。

この後に、輪郭のデータが続きます。
numberOfContours の値によってデータが異なりますが、今回は複合グリフのデータは省略します。
単純なグリフのデータ
uint16 endPtsOfContours[numberOfContours]各輪郭の最後の座標のインデックス値。
「この配列の最後の値 + 1」が座標の総数となる。
uint16 instructionLength命令の総バイト数。0 でデータなし。
uint8 instructions[instructionLength]グリフ命令のバイトコードデータ
uint8 flags[可変]各座標のフラグ値の配列。
座標の総数分の値があるが、REPEAT_FLAG が ON の場合は、同じフラグ値を指定数分繰り返す。
uint8 or int16 xCoordinates[可変]各ポイントの X 座標。
フラグで、「前の座標と同じ」に指定されている場合は、省略される。

最初の点 (座標インデックス = 0) は原点からの位置。
それ以降はすべて、前の座標からの相対位置。
uint8 or int16 yCoordinates[可変]各ポイントの Y 座標

フラグ
bit 0ON_CURVE_POINT1 = 輪郭線上にある点。
0 = 輪郭線上にはない、制御点。
bit 1X_SHORT_VECTORX 座標のデータ型。0 = int16、1 = uint8
bit 2Y_SHORT_VECTORY 座標のデータ型。0 = int16、1 = uint8
bit 3REPEAT_FLAGON の場合、
このフラグと同じ値を、指定回数分繰り返す。
次のバイト値が、繰り返す数の値となる。
bit 4X_IS_SAME_OR_POSITIVE_X_SHORT_VECTORX_SHORT_VECTOR が 1 (uint8) の場合、
X 座標の値は、0 = 負、1 = 正。

X_SHORT_VECTOR が 0 (int16) の場合、
0 = X 座標の値が存在する
1 = 前の X 座標と同じ (座標値を省略)
bit 5Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR上と同じ。Y 座標
bit 6OVERLAP_SIMPLEON で、それぞれの輪郭が重なる場合がある。
OpenType では、このフラグを使用する必要はない。
bit 7Reserved予約 = 0
プログラム
>> 10_glyf.c

フォント内の指定文字のアウトラインデータを表示します。

$ ./10_glyf font.ttf "A"

第二引数に、アウトラインを表示したい1文字を指定してください。
(U+0000〜U+FFFF の範囲内)

U+002D
glyphID: 16

---- loca ----

format: Offset32
offset: 1936 (next: 1992)

---- glyf ----

numberOfContours: 1
xMin,yMin,xMax,yMax: 102, 545, 630, 705
endPtsOfContours: 3,
instructionLength: 27
instructions:
64,16,1,0,44,1,2,1,4,3,2,1,0,14,3,2,1,0,46,46,46,46,43,43,42,49,48,

points:
== contour [0] ==

(630, 545) : raw (630, 545)
{ON_CURVE_POINT, }

(102, 545) : raw (-528, 0)
{ON_CURVE_POINT, Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR, }

(102, 705) : raw (0, 160)
{ON_CURVE_POINT, Y_SHORT_VECTOR, X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR, Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR, }

(630, 705) : raw (528, 0)
{ON_CURVE_POINT, Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR, }

左の座標 (x, y) は、原点からの位置です。
raw (x, y) は、データの生の座標値です。

値の詳しい検証は、次で行います。