ByteScope

TrueType フォントファイル形式

TrueType のアウトラインフォント。

MIME タイプ
font/ttf
拡張子
.ttf
カテゴリ
フォント

マジックナンバー(ファイル署名)

0x0000000000010000····sfnt version 1.0

TrueType フォント形式について

TrueType は 1980 年代後半に Apple が設計し Microsoft が採用した形式で、各グリフを 2 次ベジエ曲線の集まりとして記述し、加えて小さいサイズでその曲線をピクセルグリッドへどう吸着させるかをラスタライザに指示するバイトコードのヒンティングプログラムを持ちます。ファイル自体は sfnt コンテナで、先頭の短いディレクトリがフォント内の全テーブルを 4 文字のタグで列挙し、各テーブルは絶対ファイルオフセットで指される独立したブロブです。だからテーブルの追加・削除・並べ替えが他に影響を与えずに行えます。オフセット 0 のバージョンタグ 00 01 00 00 が、アウトラインを PostScript ではなく TrueType だと示しています。

ヘッダーの構造(バイト単位)

オフセット長さフィールド意味
04sfntVersionTrueType アウトラインなら 00 01 00 00。同じ枠には他に 3 つの値が入り得て、それぞれ別種のファイルを意味します。4F 54 54 4F(OTTO)は PostScript アウトラインの OpenType フォント、74 74 63 66(ttcf)は複数の書体をまとめたコレクション、74 72 75 65(true)は Mac で作られた一部のフォントが今も持っている古い Apple のタグです。00 01 00 00 だけを見る判定器は、最後の 1 つを黙って取りこぼします。
42numTablesディレクトリに続くテーブルレコードの数。sfnt ファイルの多バイト数値はどのプロセッサが書いたかに関係なくすべてビッグエンディアンで、これもその 1 つです。リトルエンディアン前提の読み手が即座に目に見える形で間違える、数少ない形式でもあります。
62searchRangenumTables を超えない最大の 2 のべき乗に 16 を掛けた値。レコードを二分探索するためのヒントとしてだけ存在しますが、出荷されているフォント(Apple のシステム書体を含む)でも間違っていることが多く、パーサーはこれを無視してレコードを線形にたどります。
82entrySelectorその 2 のべき乗の 2 を底とする対数。これも二分探索ヒントの名残で、同じく無視して構いません。ここに依存しているラスタライザは何十年も前からありません。
102rangeShiftnumTables × 16 から searchRange を引いた値。実在のフォントでも驚くほどの割合で間違っており、この 3 つのフィールドが後方互換のために残された無用の長物であることの、最も分かりやすい証拠になっています。
12variableTable records1 レコード 16 バイトで、4 文字のタグ、チェックサム、絶対ファイルオフセット、長さが、すべてビッグエンディアンで並びます。レコードはタグのアルファベット順に並ぶので、ディレクトリの先頭に来るのは「ファイル内で最初にあるもの」ではなく「最初にソートされるもの」です。テーブル本体はどんな順序で置かれていてもよく、だから確実に探す手段はオフセットだけです。
variable54head table固定位置ではなく、ディレクトリのレコード経由でたどり着きます。その 12 バイト目にマジックナンバー 5F 0F 3C F5 があり、これが「本当に sfnt かどうか」を確かめる最も確実な検査です。unitsPerEm は +18、loca テーブルのオフセットが 16 ビットか 32 ビットかを決める indexToLocFormat は +50 にあります。
variablevariableglyf and loca tablesloca は glyf へのオフセットの配列で、グリフ 1 つにつき 1 つ、加えて終端が入ります。glyf のほうが輪郭そのものを持ちます。loca のエントリ幅が head にあるフィールド 1 つで決まる構造なので、indexToLocFormat が食い違っているフォントは、他のすべての部分が問題なく検証を通るのにアウトラインだけがゴミになります。

似た形式との見分け方

紛らわしい形式見分け方
OpenType フォントどちらも sfnt ファイルであり、意味のあるあらゆる観点で OpenType です。違うのはアウトラインの流儀で、それをオフセット 0 の 4 バイトが宣言しています。00 01 00 00 なら glyf テーブルに入った 2 次の TrueType アウトライン、4F 54 54 4F(OTTO)なら CFF テーブルに詰め込まれた 3 次の PostScript アウトライン。拡張子はどちらの向きにも証拠になりません。.otf という名前で TrueType アウトラインを持つファイルはいくらでもあります。
TrueType Collection (.ttc)コレクションは 74 74 63 66(ttcf)で始まり、オフセット 4 にバージョン、8 にフォント数、その後ろに通常のテーブルディレクトリを指すオフセットの配列が続きます。複数の書体がグリフデータを 1 部だけ共有する形です。macOS はシステムのファミリーの大半をこの形で同梱しているので、オフセット 0 に 00 01 00 00 を要求するツールに .ttc を渡すと、何一つおかしくないのに破損として拒否されます。
WOFF フォント同じフォントを、ウェブ向けに包んだもの。ラッパーがオフセット 0 に 77 4F 46 46(wOFF)を置き、元の sfntVersion は flavor フィールドとしてオフセット 4 へ移されます。だから TrueType フォントを収めた WOFF は、オフセット 0 ではなく 4 に 00 01 00 00 が読めます。.ttf にリネームしても何も変わりません。テーブルは依然として zlib のストリームです。
WOFF2 フォント1 世代進んだ同じ関係で、オフセット 0 が 77 4F 46 32(wOF2)、流儀はやはりオフセット 4 です。フォント本体全体が 1 本の Brotli ストリームなので、ブラウザのネットワークパネルから保存して .ttf にリネームした WOFF2 は、名前を戻しても救えません。ラッパーを理解するツールで展開するしかありません。

よくある壊れ方

  • ダウンロードの途中切れ。先頭のディレクトリは残るので、hex ビューアにはもっともらしいテーブル数とタグ一式が見えますが、後ろのレコードのオフセットと長さがファイル末尾より先を指します。ディレクトリ内で最大の「オフセット + 長さ」を実際のファイルサイズと比べれば、何もデコードせずに 1 回の走査で捕まえられます。
  • テキストモード転送。改行を変換する FTP クライアントやビルド手順は、ヒンティングのバイトコードやグリフデータの中の 0D 0A をすべて 0A に変えてしまいます。ディレクトリ自体にはその組み合わせがめったに含まれないのでパースは通り、フォントは開き、正しいグリフ数を報告し、そして意味不明な描画をします。
  • 古いままの checkSumAdjustment。サブセット化やパッチのツールは、head テーブルの 8 バイト目にあるこの値を計算し直さずにテーブルを書き換えがちです。ラスタライザは無視するのでフォントはどこでも動きますが、検証ツールは警告を出しますし、編集前は有効だった DSIG の署名テーブルは無意味になります。
  • リネームされたウェブフォント。ブラウザから .woff2 を保存して .ttf と名付けるのが、フォントがインストールできない理由として断然多いものです。中身は Brotli で圧縮されていて wOF2 で始まっているのに、OS は「形式が違う」ではなく「ファイルが壊れています」と報告するので、人は見当違いの問題を探しに行くことになります。
  • 先頭に付いたゴミ。エラーページを差し込むプロキシ越しに取得したフォントや、セッションが切れた後にダウンロードしたフォントは、オフセット 0 に HTML の doctype が入っていて、フォントのデータは 1 バイトも含まれていません。ファイルサイズがもっともらしいことが多いので、先頭 4 バイトを読むまで何もおかしく見えません。

この形式の現在地

TrueType は今もデスクトップ組版の主力です。Windows も macOS もシステムの書体の大半を TrueType アウトラインとして(たいていはコレクションにまとめて)同梱していますし、この形式を有名にしたヒンティングのバイトコードは、低密度の画面に小さな文字を描く場面では今なお効いています。ウェブではほぼ完全に置き換えられました。ブラウザは @font-face 経由で素の .ttf も受け付けますが、それを配信するのは帯域の無駄です。WOFF2 がまったく同じテーブルを 3 分の 1 ほど少ないバイト数で届けるからです。TrueType が今も第一候補なのは、ダウンロードではなくインストールするもの(デザインツールに入れる書体、組み込み機器、印刷のワークフロー、PDF)と、また編集する予定のあるものです。テーブルが素直に格納されていて、どのフォントエディタも直接読み書きできます。OpenType 1.8 で加わったバリアブルフォントの拡張も同じ 2 次アウトラインの上に建てられているので、今どきのバリアブルフォントも下地は TrueType のファイルです。

TrueType フォントファイルをこのサイトで開く

どれもブラウザ内で動きます。ファイルが端末から出ることはありません。

関連する形式

TrueType フォントと混同しやすい形式です。先頭バイトを見比べてください。

形式先頭バイト拡張子
OpenType フォント4F 54 54 4F.otf
WOFF フォント77 4F 46 46.woff
WOFF2 フォント77 4F 46 32.woff2

よくある質問

ファイルのマジックナンバーとは何ですか?

ファイル先頭の数バイトで、名前が何であろうとその形式を示すものです。PNG は必ず 89 50 4E 47 で始まり、ZIP は 50 4B 03 04 で始まります。OS もブラウザも file コマンドも、拡張子を信用せずこのバイト列を読みます。だからファイル名を変えても中身の正体は変わりません。

マジックナンバーを自分で確認する方法は?

macOS や Linux なら xxd -l 16 ファイル名 で先頭 16 バイトが表示されます。Windows なら PowerShell で Format-Hex -Path ファイル名 -Count 16 です。あるいはこのサイトのファイル形式判別ツールにドロップすれば、ローカルでバイト列を読んで形式を教えてくれます。アップロードはありません。

2 つの形式が同じマジックナンバーを持つのはなぜ?

一方が他方の上に作られているからです。docx、xlsx、pptx、apk、jar、epub はすべて中身が ZIP アーカイブなので ZIP の署名で始まり、区別するには内部のエントリを見る必要があります。Java の class ファイルと macOS のユニバーサルバイナリはどちらも CA FE BA BE で始まり、直後のフィールドで見分けます。

マジックナンバーがまったくないファイルもある?

あります。XML、HTML、JSON、SVG、CSV といったテキストベースの形式には固定のバイト署名がないため、構造から判別します。先頭の <?xml 宣言、<svg 要素、あるいは { に続く引用符付きのキーなどです。これは確定ではなく推測なので、このリファレンスではそうした形式をプローブ判別として示しています。

マジックナンバーが一致すればそのファイルは安全?

いいえ。わかるのは形式であって、中身が無害かどうかではありません。正規の PDF や docx でも悪意のあるペイロードを含んでいることがあります。特に拡張子とバイト列が食い違うときに真の形式を知るのは有用な第一段階ですが、マルウェアスキャンではありません。

TrueType フォントかもしれないファイルをお持ちですか?ファイル形式判別ツールで調べる — マジックナンバーをローカルで読み取ります。アップロードは一切ありません。またはすべての形式を見る。