TTX/FontTools が Version 2.5 から Apple カラーフォントをサポートしているようなので、これを使ってAppleカラーフォントを試作してみた。以下メモ。
サンプルファイル
output/nxTokiACF.ttf が出力されたフォントです。
作成方法
流れとしては、まずひな形となるTTFフォントをFontForgeなどで出力し、それを TTX で XML ファイルに出力する。そして出力されたXMLファイル(.ttx)を編集してカラービットマップを追加し、それを TTX でTTFフォントにコンパイルする。
使うもの
以下の手順ではこれらのツールにパスが通っているものとする。
- TTX/FontTools 2.5
- AFDKOの最新版にも入ってます。
- TTXのインストールについては次のページを参照
- Python
また、カラービットマップの設定については Apple Color Emoji.ttf を参考にするとスムーズにできるかと。次の場所にあります。
- /System/Library/Fonts/Apple Color Emoji.ttf
Appleカラーフォントとsbixテーブル
カラーフォントのビットマップデータは 'sbix' テーブルに格納される。
sbix テーブルの詳しい説明は次の Apple のページ参照
必要そうなところだけまとめる次の図のようになっている。らしい。
- ‘sbix’テーブルの下にいくつかの strike データレコードがくる。
- strike は ppem (PPEMを表す)、resolution (画像の解像度)、多数の glyph データレコードを含む。
- PPEMは画面のdpiとフォントのポイント数によって決まる数値で、
ppem = pointSize * dpi / 72
で求められる。ppemとresolutionの組み合わせごとにstrikesがつくられる。 - dpiが72でppemを正方形の画像の一辺のサイズにすると、画像の一辺がemの大きさになるようだ?
- Apple Color Emoji ではつぎの様なppem, dpiの組み合わせのstrikeがあった
- PPEMは画面のdpiとフォントのポイント数によって決まる数値で、
ppem | 20 | 32 | 40 | 48 | 64 | 96 | 160 |
dpi | 72 | 72 | 72 | 72 | 72 | 72 | 72 |
画像サイズ | 20x20 | 32x32 | 40x40 | 48x48 | 64x64 | 96x96 | 160x160 |
手順
というわけで、実際にフォントをつくってみる。Aをカラービットマップで表示するようにする。
画像の用意
次の画像を用意した。サイズは512x512。
ひな形の作成
まずひな形となるTTFフォント nxTokiACF_base.ttf をFontForgeで作成した。作成方法の詳細は省略。
Units/EMを800に指定した。グリフについてはAに800の幅を設定したのみ。フォントの名前などを適当に設定。など。
次に TTX でTTFフォントをXMLファイル(.ttx)にダンプする。
ttx -o nxTokiACF.ttx nxTokiACF_base.ttf
XMLファイルの編集
出力されたXMLファイル nxTokiACF.ttx を編集する。
Apple Color Emoji.ttf に値を合わせるため hhea テーブルの ascent を 800 に、 descent を -250 に設定した。ただし合わせる必要があるのか分からない。要検証。
<hhea> <tableVersion value="1.0"/> <ascent value="800"/> <descent value="-250"/> ...
他にも Apple Color Emoji.ttf を参考に設定をいじった部分があるが、あまりよく分かってない。
次にカラービットマップを追加する。これは 'sbix' テーブルによって設定されるので、それに従って作成する。
フォントが描画されるサイズによって表示される画像を変えることもできるが、面倒なので大きなサイズ(512x512)の画像一つだけにした。フォントの表示サイズによって表示されるビットマップを変えるには、ppemを変えたstrikeを他にも用意し、それらの中で対応する大きさのビットマップを設定するとよい。
strike について、dpiを72にし、ppemを画像サイズと同じにするとよさそうなので、512x512の画像と併せてppemを512としている。
次のようなXMLコードを挿入する。場所は<ttFont>~</ttFont>のタグの直下ならどこでも良さそうだが<gasp>~</gasp>の後においた。
<sbix> <version value="1"/> <flags value="00000000 00000001"/> <strike> <ppem value="512"/> <resolution value="72"/> <glyph name=".notdef"/> <glyph name=".null"/> <glyph name="nonmarkingreturn"/> <glyph name="space"/> <glyph graphicType="png " name="A" originOffsetX="0" originOffsetY="0"> <hexdata> (ここに16進ダンプが入ります) </hexdata> </glyph> </strike> </sbix>
「(ここに16進ダンプが入ります)」は実際にはPNG画像のバイナリデータを16進数の文字列にダンプしたものが入る。
この16進ダンプには次のようなPythonスクリプトを使って行うことができる。
# coding: utf-8 import binascii, sys def dump(filename): with open(filename, 'rb') as f: bin = f.read() hexdump = binascii.hexlify(bin) print(hexdump) if __name__ == '__main__': argvs = sys.argv if len(argvs) != 2: quit() else: dump(argvs[1])
ダンプ後の文字列は非常に長くなるので貼り付けた後はフォントの編集が面倒になる。適当に参照を書いておいて後でスクリプトで置換するなどするといいのではないかと思う。
実際に<hexdata>~</hexdata>の代わりに次の様に書いておき、Pythonスクリプトで16進ダンプに置換するようにした。
<hexdata src="bitmaps/512/A.png"/>
課題、疑問点
- Apple Color Emoji では Units/EM が 800, Ascender が 800, Descender が -250 となっている。フォントとして変な値に思うがどうしてこのような設定になっているのか。またそうしなかった場合何か不具合が生じるのだろうか。
- ビットマップがどの位置に表示されるのか。アウトラインに何も設定しない場合、ビットマップの原点(左下端)がベースラインのやや下になるようだ。また、アウトラインを設定した場合、そのy座標の最小値よりもやや下に表示されているように見える。この下がる幅については詳細不明。要検証。
- Apple Color Emoji をみるかぎり絵文字がビットマップで表示されるグリフに対しては glyf テーブルに左下(0,0)と右上(800,800)に点が打たれている。
- Apple Color Emoji はビットマップがすべて正方形である。正方形でないビットマップを設定するとどうなるのだろうか。
- Apple Color Font はWebフォントとして使用しようとするとブラウザに搭載されたサニタイザで 'sbix' の情報が削除されてしまうらしく、Webフォントでは使えないようだ。
その他
- GlyphsだとApple Color Fontか作成できるようです。