loca、glyf テーブル
この2つのテーブルには、TrueType のアウトラインデータが格納されています。
※ PostScript アウトラインの場合、このテーブルは存在しません。
「loca」には、各グリフごとの glyf テーブルのオフセット位置が、
「glyf」には、各グリフのアウトラインデータが格納されています。
※ PostScript アウトラインの場合、このテーブルは存在しません。
「loca」には、各グリフごとの glyf テーブルのオフセット位置が、
「glyf」には、各グリフのアウトラインデータが格納されています。
loca テーブル
すべてのグリフの、glyf テーブルのオフセット位置が格納されています。
まずは、ここでオフセット値を取得します。
※ numGlyphs は、maxp テーブル内の値です。
テーブル先頭から、「グリフ数 + 1」個分のオフセット値の配列が格納されています。
オフセット値のデータ型は、head テーブル内の「indexToLocFormat」値で決まります。
0 で Offset16、1 で Offset32 です。
※ Offset16 の場合は、実際のオフセット値を2で割った値となっています。
まずは、ここでオフセット値を取得します。
※ 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 テーブルのオフセット値を使って参照します。
各グリフの先頭には、以下のデータがあります。
この後に、輪郭のデータが続きます。
numberOfContours の値によってデータが異なりますが、今回は複合グリフのデータは省略します。
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 0 | ON_CURVE_POINT | 1 = 輪郭線上にある点。 0 = 輪郭線上にはない、制御点。 |
---|---|---|
bit 1 | X_SHORT_VECTOR | X 座標のデータ型。0 = int16、1 = uint8 |
bit 2 | Y_SHORT_VECTOR | Y 座標のデータ型。0 = int16、1 = uint8 |
bit 3 | REPEAT_FLAG | ON の場合、 このフラグと同じ値を、指定回数分繰り返す。 次のバイト値が、繰り返す数の値となる。 |
bit 4 | X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR | X_SHORT_VECTOR が 1 (uint8) の場合、 X 座標の値は、0 = 負、1 = 正。 X_SHORT_VECTOR が 0 (int16) の場合、 0 = X 座標の値が存在する 1 = 前の X 座標と同じ (座標値を省略) |
bit 5 | Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR | 上と同じ。Y 座標 |
bit 6 | OVERLAP_SIMPLE | ON で、それぞれの輪郭が重なる場合がある。 OpenType では、このフラグを使用する必要はない。 |
bit 7 | Reserved | 予約 = 0 |
プログラム
>> 10_glyf.c
フォント内の指定文字のアウトラインデータを表示します。
左の座標 (x, y) は、原点からの位置です。
raw (x, y) は、データの生の座標値です。
値の詳しい検証は、次で行います。
フォント内の指定文字のアウトラインデータを表示します。
$ ./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) は、データの生の座標値です。
値の詳しい検証は、次で行います。