Apple Color Emojiフォントを見本になにかする その2
後回しにしたチェックサムの件…
OTFフォントのチェックサムというのはとても面白い仕組みです。基本的に32bitの符号なし整数なのでファイルの頭から4バイトづつ読み出して全部足した下位32ビット分がそれに当たるのですがどのフォントを見ても0xB1B0AFBAになります。日本語フォントであろうが欧文フォントであろうが0xB1B0AFBAです。TrueType、ポストスクリプト系等は全く関係ありません。それもそのはず、headテーブルにChecksum Adjustmentっていうやつがあって、全体足したやつを0xB1B0AFBAから引いたデータとして書き込んであるからです。本日の豆知識でしたw
で終わっちゃうとまずいので続けます。このChecksum Adjustmentっていうデータはチェックサムを計算する際には絶対に4バイト切れずに読み込まれます。テーブルは名前の順で収容されているし、テーブル長は任意です。しかし、このChecksum Adjustmentはどんな事があっても頭の2バイトとかが別に読み込まれたりしません。必ず4バイトの塊で読み込まれます。何故かと言うと各テーブルの長さは4バイトの倍数の長さになるように調整されているからです。もちろん、各テーブルのテーブル・レコード・エントリのlengthプロパティは4の倍数にはなっていません。このlengthは実際のテーブル長が表記されているからです。しかし、フォントデータ上では4の倍数になるように0x00でパディングされて収容されています。ですからテーブルデータを読み出す際はきちんと開始位置をチェックしないとずれます。前のテーブルが終わったからと言って次のテーブルが始まるとは限らないのです。
脱線していますが、テーブル・レコード・エントリにもチェックサムがあったのは覚えていますか? これらも前述の様な感じで32ビットの符号なし整数です。ほとんどがそれでいけるのですが「head」テーブルだけが少々特殊です。さっきなんか書いてたよなぁと思った人、すばらしい記憶力ですw このテーブルだけは少々加工しての算出が必要です。というか、単純にChecksum Adjustmentの値を除外するだけです。リファレンスにはまずChecksum Adjustmentの値を0にしてからチェックサムの計算をしろって書いてます。
そうした諸々を勘案すると、以下のようなスクリプトが書けます。
var f = File.openDialog("Select table..."); f.encoding = 'BINARY'; var sum = 0, n, k; if (f.open('r')){ if (f.name.indexOf("head")>-1){ while (!f.eof) { n = 16777216; for(k=0;k<4;k++){ if (f.eof) break; sum += f.readch().charCodeAt(0) * n; n /= 256; } } f.seek(8); n = 16777216; for(k=0;k<4;k++){ if (f.eof) break; sum -= f.readch().charCodeAt(0) * n; n /= 256; } } else { while (!f.eof) { n = 16777216; for(k=0;k<4;k++){ if (f.eof) break; sum += f.readch().charCodeAt(0) * n; n /= 256; } } } f.close(); sum %= Math.pow(2,32); $.writeln("0x"+ sum.toString(16)); }
こんなかんじですね。もちろんExtendscriptですからご注意を。ファイルを選択するようになっていますが、これは前回のfont_cutter.jsxを利用してテーブルを分割したものを対象としている為です。
また、フォントデータ自体がビッグエンディアンで記述されているので、スプリットしたテーブルデータ自体はパディングを含みませんが問題なく計算できます。
さあ、みなさんモ○○ワフォントとかをぶった切ってチェックサムを計算してみてください。
ちなみに……ReiminPr6-Lightを……
Table Record Entry value... BASE 0x1b8e18d8 0x992a90 0xe4 CFF 0xbf604232 0x4051c 0x8f3abd GPOS 0xb160459e 0x98f7a0 0x32ee GSUB 0xce969259 0x95ec80 0x30b1e OS/2 0x89c9aa91 0x160 0x60 VORG 0xac9cf860 0x992b74 0x3b4 cmap 0xb5d08e88 0x888 0x3fc71 head 0xfa3c4d5a 0xfc 0x36 hhea 0xb135278 0x134 0x24 hmtx 0x565bed5c 0x933fdc 0x153bc maxp 0x5a125000 0x158 0x6 name 0x859f2e9a 0x1c0 0x6c5 post 0xffb80032 0x404fc 0x20 vhea 0x998637f 0x949398 0x24 vmtx 0xc7533296 0x9493bc 0x158c4
Calculated value. BASE 0x1b8e18d8 CFF 0xbf604232 GPOS 0xb160459e GSUB 0xce969259 OS/2 0x89c9aa91 VORG 0xac9cf860 cmap 0xb5d08e88 head 0xfa3c4d5a hhea 0xb135278 hmtx 0x565bed5c maxp 0x5a125000 post 0xffb80032 vhea 0x998637f vmtx 0xc7533296
と計算結果はきちんと整合性が取れております。
しかし、これをApple Color Emoji.ttfでやると全然合わないorz. 清々しいほどマッチしませんw
ということで、この件引き続き調査が必要です。
次回から各テーブルの解説を始めます(^-^)/
…Appleのドキュメント読んでもわかんないwww