ByteScope

OpenType 字型檔案格式

OpenType 字型,通常帶 CFF/PostScript 外框。

MIME 類型
font/otf
副檔名
.otf
分類
字型

Magic number(檔案簽章)

0x000000004F54544FOTTO'OTTO' sfnt tag

關於 OpenType 字型格式

OpenType 是微軟與 Adobe 共同推出、用來同時接替 TrueType 和 Type 1 的格式。.otf 檔案用的是和 .ttf 一樣的 sfnt 容器——同樣的表目錄、同樣的大端序數字、同樣的 head、cmap、name 與 OS/2 表——只是外框改成用 Type 2 charstring 寫的三次貝茲曲線,存在單一張 CFF 表裡,而位移 0 的標籤是 ASCII 字串 OTTO,不是版本號。排版界一提到 OpenType 就想到的東西,從連字、小型大寫到上下文替代字,全都住在 GSUB 與 GPOS 表裡,而 TrueType 類型的字型同樣用得到。

檔頭結構,一個位元組一個位元組看

位移長度欄位意義
04sfntVersion4F 54 54 4F,也就是 ASCII 的 OTTO 四個字母,而且整個檔案裡就只有它宣告這些外框是 PostScript 而不是 TrueType。包著 CFF 字型的 WOFF 或 WOFF2,位移 4 也會出現同樣這 4 個位元組,因為那層外殼把這個欄位往後推了 4 個位元組。
42numTables後面接著幾筆 16 位元組的表記錄。大端序,而且它本身就是個好用的合理性檢查:真實字型帶的表大約是九到三十張,所以出現上千的數值,代表這不是 sfnt 檔案、或是讀取端把位元組序搞反了。
62searchRange不大於 numTables 的最大 2 次方乘以 16。這是解析器都忽略的舊二分搜尋提示,而真實字型很常寫錯:Apple 就有一個 OTTO 系統字型的值和公式對不上,而每個點陣化引擎都毫無怨言地打開它。
82entrySelector同一個 2 次方取以 2 為底的對數。同一段被放棄的提示的一部分,之所以留著,只是因為從一個全世界工具都會讀的目錄裡移掉一個欄位,風險從來都不划算。
102rangeShiftnumTables 乘 16 再減掉 searchRange。三個殘留欄位裡的最後一個;這裡對不上,完全不能說明字型健不健康。
12variableTable records每筆 16 個位元組:標籤、檢查碼、絕對檔案位移與長度,全部大端序。因為記錄依標籤排序、而空白字元排在所有字母前面,OTTO 字型的第一筆記錄幾乎一定是 CFF 加一個空白(43 46 46 20),這是「這檔案是不是標頭宣稱的那種」兩秒鐘的目視檢查。
variable54head table透過它的目錄記錄找到。往內 12 個位元組是 magic number 5F 0F 3C F5;unitsPerEm 在 +18,而且值得知道的是 PostScript 外框慣用 1000、TrueType 慣用 2048,但兩者在任一類型裡都合法、也都真的出現在出貨字型裡,所以它是線索而不是判準。
variablevariableCFF table一整支完整嵌進來的 Compact Font Format 程式,有自己的標頭、自己的 INDEX 結構、一份 top dictionary,以及畫出字形的 charstring。它是字型裡的字型,所以 CFF 表壞掉會做出一個「所有 sfnt 層級檢查都過、字族名稱與度量都正確、就是什麼都畫不出來」的檔案。

怎麼跟長得像的格式分開

容易搞混的怎麼分
TrueType 字型位移 0 那 4 個位元組,沒別的。4F 54 54 4F 代表 CFF 外框,00 01 00 00 代表 glyf 外框。副檔名兩個方向都不可靠:.otf 合法地可以裝 TrueType 外框,而 OpenType 這個詞講的是外殼,不是裡面的曲線。要確定的話,就看目錄裡列的是 CFF 表還是 glyf 表。
Type 1 (PFB/PFA)OpenType/CFF 當初就是為了取代它而生的格式。二進位的 Type 1 字型開頭是 PFB 區段標記 80 01,純文字變體開頭則是字面上的 %!PS-AdobeFont。兩者都不是 sfnt:沒有表目錄、沒有 cmap,也沒辦法用 Unicode 碼位定址字形。Adobe 在 2023 年結束 Type 1 的支援,而那些外框被搬到的地方就是 OTTO 檔案。
WOFF2 字型為網頁包起來的 CFF 字型,位移 0 讀到 77 4F 46 32、位移 4 讀到 4F 54 54 4F,所以 OTTO 標籤還在,只是被推開了。這件事兩個方向都會坑粗糙的偵測器:在前 16 個位元組裡到處掃 OTTO 的會把 WOFF2 判成 OpenType 字型,而只檢查位移 0 的會把同一個檔案判成未知。
TrueType Collection (.ttc)集合檔案裝 CFF 字型和裝 TrueType 一樣容易,而且兩者都藏在位移 0 的標籤 74 74 63 66(ttcf)後面。真正的表目錄在從第 12 個位元組起列出的那些位移上,所以 OTTO 標籤會出現在檔案深處而不是最前面——用 hex 搜尋 OTTO 找得到,檢查位移 0 找不到。

常見的壞法

  • 下載被截斷。目錄在最前面、活了下來,所以標籤和長度看起來都對,而 CFF 表——它通常是檔案裡最大的東西,因此通常排在最後——正是被切掉的那部分。字型在選單裡列得好好的,卻什麼都畫不出來。
  • 文字模式傳輸。CFF charstring 裡的換行被轉換過,第一個 0D 0A 之後的東西全部位移,而因為 CFF 是一層層 INDEX 巢狀而成、會自我描述的結構,失敗不會乾乾淨淨:解析器順著某個長度欄位走進別的東西的中間,然後在離真正損壞處很遠的地方報錯。
  • checkSumAdjustment 過期。任何做子集化或修補、卻忘了重算 head 表往內 8 個位元組那個值的工具,留下的字型算繪起來完美無缺、驗證卻不過,而且會讓編輯前簽署過的 DSIG 表失效。
  • 被改名的網頁字型。從字型服務下載 .woff2 再給它 .otf 副檔名,到哪都裝不起來;那些位元組是 Brotli 壓縮過的,前 4 個是 wOF2。作業系統給的錯誤訊息通常說檔案損毀,於是大家跑去找一個根本不存在的損壞。
  • 前面被塞了垃圾。透過會回傳 HTML 錯誤頁的網頁認證入口或代理伺服器取得的字型,位移 0 是一段 doctype。後面每個環節都回報「無法辨識的字型格式」,而在 hex 檢視器裡看一眼前 16 個位元組,調查就結束了。

這個格式現在還在用嗎

OTF 是字體公司出貨的格式。字體公司零售的字型、Adobe 應用程式隨附的字型庫,以及幾乎所有針對印刷與編輯設計的字型,來的都是帶 CFF 外框的 OTTO 檔案,因為設計圈的血統就是從那裡來的,也因為三次曲線比較貼近字體設計師實際的畫法。在網頁上它和 TrueType 處境相同:@font-face 用得了,但從來不是正確答案,已經被包著同樣那些表的 WOFF2 取代。它在 PDF 裡有個無可取代的角色,因為 CFF 字型程式可以子集化之後直接嵌進 PDF,這也是為什麼印刷流程在乎的是留著 OTF,而不是只留網頁版。可變字型的路線在這裡也分岔了:可變的 CFF 字型需要較新的 CFF2 表,而它的支援來得比可變 TrueType 更晚也更不平均,所以設計師要出一整套可變字族時,即使原稿是三次曲線畫的,最後常常還是交 TrueType 類型。

在這個站上打開 OpenType 字型檔

這些全部在你的瀏覽器裡跑,檔案不會離開你的電腦。

相關格式

容易和 OpenType 字型搞混的格式,可以比對它們的開頭位元組。

格式開頭位元組副檔名
TrueType 字型00 01 00 00.ttf
WOFF 字型77 4F 46 46.woff
WOFF2 字型77 4F 46 32.woff2

常見問題

檔案的 magic number 是什麼?

檔案開頭的前幾個位元組,不管檔名寫什麼,它標明的是真正的格式。PNG 一定以 89 50 4E 47 開頭,ZIP 則是 50 4B 03 04。作業系統、瀏覽器和 file 指令讀的都是這幾個位元組,而不是相信副檔名 — 這就是為什麼把檔案改名並不會改變它實際上是什麼。

我要怎麼自己檢查 magic number?

在 macOS 或 Linux 上,xxd -l 16 檔名 會印出前 16 個位元組;在 Windows 上,PowerShell 的 Format-Hex -Path 檔名 -Count 16。或者把檔案丟進本站的檔案類型辨識工具,它會在本機讀取位元組並告訴你是什麼格式,不會上傳任何東西。

為什麼兩種格式的 magic number 會一樣?

因為其中一種是建立在另一種之上。docx、xlsx、pptx、apk、jar 與 epub 骨子裡都是 ZIP 壓縮檔,所以全都以 ZIP 的簽章開頭;要分辨它們得看裡面的項目。Java class 檔和 macOS 的通用二進位檔都以 CA FE BA BE 開頭,靠緊接其後的欄位區分。

有完全沒有 magic number 的檔案嗎?

有。XML、HTML、JSON、SVG、CSV 這類以文字為基礎的格式沒有固定的位元組簽章,所以改用結構來辨識:開頭的 <?xml 宣告、<svg 元素,或是 { 後面接著帶引號的鍵。這種偵測是合理推測而非確定,因此本參考頁會把這些格式標示為結構偵測。

magic number 相符就代表檔案安全嗎?

不代表。它告訴你的是格式,不是內容是否無害 — 一個貨真價實的 PDF 或 docx 仍然可能夾帶惡意內容。辨識真實類型是有用的第一道檢查,尤其在副檔名和位元組不一致的時候,但它不是惡意軟體掃描。

手上有檔案可能是 OpenType 字型?用檔案類型辨識工具查出來 — 它在本機讀取 magic number,不上傳任何東西。或者瀏覽所有格式。