head テーブル

head テーブル
ここから、各テーブルを解説していきます。

必須となる「head テーブル」には、フォントに関する、基本的な数値の情報が格納されています。
テーブルデータ
uint16メジャーバージョン = 1
uint16マイナーバージョン = 0
Fixed fontRevisionフォント製作者によるバージョン。
16:16 の固定小数点数。
Windows では、この値を使わず、name テーブルのバージョン文字列を使う。
uint32 checkSumAdjustmentファイル全体のチェックサム値。
※フォントコレクションの場合は無視
uint32 magicNumber0x5F0F3CF5 (固定)
uint16 flagsフラグ
uint16 unitsPerEmグリフの 1 em の単位。
グリフの座標値において、全角幅がどれだけの値になるかということ。

16〜16384 までの任意の値。
TrueType アウトラインでは、2の累乗値が推奨されている。

TrueType アウトラインの場合、1024 or 2048 が使われることが多い。
PostScript アウトラインの場合、基本的に 1000 が使われる。
LONGDATETIME created作成日時。
GMT 1904/01/01 00:00:00 からの秒数。
LONGDATETIME modified修正日時。上記と同じ
int16 xMin
int16 yMin
int16 xMax
int16 yMax
すべてのグリフの輪郭を含む範囲
uint16 macStyleMac のフォントスタイルフラグ。
OS/2 テーブルの fsSelection ビットと一致すること。
uint16 lowestRecPPEM読める最小のフォントサイズ。
単位は「PPEM = (pixel / em)」で、1 em に対するピクセル数。
int16 fontDirectionHint文字の流れる方向。
非推奨 (2 に設定する)
int16 indexToLocFormatloca テーブルのオフセット値の型。
0 = Offset16、1 = Offset32
int16 glyphDataFormatグリフデータのフォーマット。
現在は 0 のみ。
プログラム
head テーブルの値を表示するプログラムです。

>> 04_head.c

なお、ここからは、フォントファイルの処理は fontfile.c にまとめてあるので、そちらも併せてコンパイルしてください。

--- head ----

version: 1.0
fontRevision       : 0x0004028F (4.0100)
checkSumAdjustment : 0x4D55DDE6
magicNumber        : 0x5F0F3CF5
flags              : 0000_0000_0000_1111b
unitsPerEm         : 2048
created            : 2010/05/11 13:26:01
modified           : 2019/04/25 13:14:53
xMin,yMin,xMax,yMax: -539, -571, 2048, 1876
macStyle           : 0x0000
lowestRecPPEM      : 6
fontDirectionHint  : 2
indexToLocFormat   : 1
glyphDataFormat    : 0
チェックサムの計算方法
  1. head テーブルの checkSumAdjustment を 0 にセットする
  2. 下記の関数で各テーブルデータのチェックサムを計算し、各 TableRecord テーブル内にセットする
  3. 同じ関数で、フォントファイル全体のチェックサムを計算する
  4. 「0xB1B0AFBA - 全体のチェックサム値」の値を checkSumAdjustment とし、head テーブルにセットする

//ビッグエンディアンの 4byte 値として、すべての値を加算する。
//テーブルデータは 4byte 境界のため、4byte 単位でない場合は、0 を追加する。

uint32_t CalcChecksum(uint8_t *buf, uint32_t len)
{
    uint32_t sum = 0;
    int i;
    
    for(i = 0; i < len / 4; i++, buf += 4)
        sum += ((uint32_t)buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];

    return sum;
}

なお、フォント読み込みでのチェックサム確認時、head テーブルに関しては、そのままチェックサムを計算すると値が一致しませんが、問題ありません。
head テーブルのチェックサムを確認する時は、checkSumAdjustment を 0 として計算してください。
グリフの基本
head テーブルにおいて一番重要となるのは、「unitsPerEm」の値です。

unitsPerEm は、フォントにおいて、グリフの大きさの基準となる「1 em」という長さの中に、どれだけの座標点があるかという値です。
(OpenType の場合は、小数点以下の座標も指定可能なので、純粋に点の数とはなりませんが)

例えば、unitsPerEm が 1000 の場合、1000 x 1000 px の画像の中に文字を描画するようなイメージとなります。
ただし、実際は、座標を元に曲線で描画されるので、ドットで描画するのとは異なります。

横書きの場合は、基本的に、文字の左端、ベースライン位置が原点 (0, 0) になるので、グリフの配置は下の図のような形となります。


フォントサイズ
1 em は、フォントを描画する時の「フォントサイズ」の基準にもなります。

実際にグリフをラスタライズする際には、1 em に対するピクセル数などを決めて、その大きさに合うように座標を拡大縮小して、描画します。

フォントサイズを「pt と解像度 (DPI)」で指定する場合、1 em のピクセルサイズは、以下のように計算できます。

DPI = dot(pixel) / inch
1 pt = 72 inch

から、

dpi = pixel / inch
dpi * inch = pixel    : inch を両辺に掛ける
pixel = dpi * inch    : 左辺と右辺を入れ替え
pixel = dpi * pt / 72 : 1 inch = 1/72 pt なので、inch を pt 単位に置き換え

300 DPI で 12 pt なら、「300 * 12 / 72 = 50 pixel」です。
1 em という単位について
1 em という単位は、グリフの大きさの基準になるというだけで、すべてのグリフが 1 em の範囲に収まるわけではありません。

アウトラインの座標値に制限はないため、unitsPerEm の値とは関係なく、好きな位置に座標を置くことができます。

また、1 em の座標範囲に対して、どのような配置で座標を置くかは、フォントによって異なるため、異なるフォントで同じフォントサイズを指定したとしても、実際のグリフの大きさは微妙に異なる場合があります。