らんだむな記憶

blogというものを体験してみようか!的なー

Type 1 フォント (1)

今時 Type 1 フォントなんて?という気もするんだけど、あり得ないほどごく稀に中身を見たいなんてこともあるかもしれない。T1_SPEC.pdf聖典だと思うけど、これだけだとつらいので・・・手を動かして眺めていきたい。

無難なフォントをということで GitHub - trueroad/HaranoAjiFonts: 原ノ味フォント / Harano Aji Fonts から原ノ味フォントをとってくる。今回は HaranoAjiGothic-Regular.otf を使う。ただ、ちょっと大きいので、

pyftsubset HaranoAjiGothic-Regular.otf --gids=0-9353 --desubroutinize

でちょっと小さくした HaranoAjiGothic-Regular.subset.otf を作る。ここから

tx -t1 -o font.ps HaranoAjiGothic-Regular.subset.otf
tx -t1 -decid -g 656,1125-7477,7633-7886,7961-8004,8266-8267,8284-8285,8359-8717 -o HaranoAjiGothic-Regular-Ideographs.pfa font.ps

などとするととりあえず漢字っぽいものが集まっている Type 1 フォント HaranoAjiGothic-Regular-Ideographs.pfa が得られる。

さて、ここから fonttools を使って中身をやんわり見たい。基本的には https://github.com/fonttools/fonttools/blob/main/Lib/fontTools/t1Lib/__init__.py から欲しい部分を拝借して叩いて眺めるという流れである。

from fontTools.t1Lib import findEncryptedChunks
from fontTools.misc import eexec

して

with open('HaranoAjiGothic-Regular-Ideographs.pfa', 'rb') as f:
    data = f.read()

chunks = findEncryptedChunks(data)

すると、Type 1 フォントの中身が eexec encryption の箇所とそうでない箇所がバラバラのチャンクとして得られる。具体的には T1_SPEC.pdf の Figure 2a. の通りで、

  • ASCII のチャンク
  • eexec encryption のチャンク
  • ASCII のチャンク

の計 3 つのチャンクが得られる。そこで 7.2 eexec Encryption を参考に、initial key R = 55665 を使って

for isEncrypted, chunk in chunks:
    if isEncrypted:
        decrypted_data, R = eexec.decrypt(chunk, 55665)
        print(decrypted_data[:1000])

すると、

b"ccccdup /Private\n14 dict dup begin\n/-| {string currentfile exch readstring pop} def\n/|- {def} def\n/| {put} def\n/BlueValues [-250 -250 1100 1100] def\n/StdHW [58] def\n/StdVW [63] def\n/StemSnapH [58 65 84] def\n/StemSnapV [63 73 89] def\n/LanguageGroup 1 def\n/RndStemUp false def\n/password 5839 def\n/MinFeature {16 16} def\n/OtherSubrs[{}{}{}{systemdict/internaldict known not{pop 3}{1183615869\nsystemdict/internaldict get exec dup/startlock known{/startlock get exec}{dup\n/strtlck known{/strtlck get exec}{pop 3}ifelse}ifelse}ifelse}executeonly]def\n/Subrs 5 array\ndup 0 15 -| \x1c`\xd8\xa8\xcc1\xfe+\xf6\xe0z\xa3\xe5A\xe2 |\ndup 1 9 -| \x1c`\xd8\xa8\xc9\xc3\xd0m\x9e |\ndup 2 9 -| \x1c`\xd8\xa8\xc9\xc2\x02\xd7\x9a |\ndup 3 5 -| \x1c`\xd8\xa8I |\ndup 4 13 -| \x1c`\xd8\xa8\xcc6t\xf4\x11D\xb1;w |\ndef\nput\ndup /CharStrings\n7016 dict dup begin\n/cid656 122 -| \x1c`\xd8\xa8\xc9\xb5\xee1\xa0O_\x9b\xba\xab\xd4\x98[O9+D`\xd4\xe5Dv?M\x93\xcbe ,\xe6\xb3\r\xbcx\xdcB\xc1\xd4>\xb4[d\x0f^\xaa\x0c\x10\x0bu\xf6\xc0\n\xa9\xec\xcc\x0e\x1f\x87\xb8\xe3\xf2\x18it\x9d\x00'F\xdd\x11\xad\x8b\xd41\x9f\xf9^[\x9f\xf1\xfc\x9e3\xce\x8d\x05X\xd2v[Wl+XmJ\xda\xde}\xcf>\xb2\xe7\xce\xb6\x87-\xbd\xa7\xa7\xd5\xda\xd6o\xc1\xd2\xad\xf2 |-\n/cid1125 174 -| \x1c`\xd8\xa8\xc9\xb5\xee1\x9e+ \x98\xee\xeb\xfb\x01\xdb>\xf6Z u\xb0\xdd\x033Dl\xe5\xd5\xaf\x07H\x12\xe0\xbe\x19\xa2\xf3\xaf\x99\x00\xa5CB\x9c\x94\xd4\x84\xfc\x08\x10\x03\x03%\\\xa8\xb2`\xfa\xe2\x19(\x14U>\x11\x8f\xa7\xc9K@\xdb\x03C\xd3\x8f>\x82\xe5}3o\xd9\x15\xcaR\xa9\xb9\xcem\x16\x9dF`\xa8\x0f3|\xb5W\xed\x8duwBbWK\x0fv%\xc1y(\x16"

が出てきてなるほどねと。cccc の 4 バイトは IV (Initial Vector) のはず。