とりあえずカラーグリフをなんとかしてみたので…
「👶🏼」をInDesignのテキストフレームにコピペするとミッシング・グリフが2つ表示されます。この事からこの絵文字はサロゲートペア2つで構成されているのがわかります。前のコードはベースになるカラーグリフ(例の黄色い顔のやつ)のユニコードを示しています。後ろのコードはカラー変更のための定義用キャラクタみたいです。何という名前なのでしょう。
今回はAppleColorEmojiフォントからグリフ抜き出してなんかしてみるやつをダイジェストでお届けしようと思いました。
先にcmapテーブルからGIDを取得します。このフォントの場合、cmapテーブルはひとつでFormat12( Segmented coverage)というUCS-4をサポートするフォーマットで記述されています。これはサロゲートエリアをサポートする為の選択です。他にもサロゲートエリアをサポートするフォーマットはありますが、多くのグリフがサロゲートエリアに集中しているためにこのフォーマットが適しているとの判断だと思われます。
これはfontPharser.jsxって凶悪なフォント解析ツールでの解析結果ですが、cmapテーブルはversion=0, SubTalbeLength =1, PlatformID=0(Unicode), EncodingID=4(Unicode2.0)となっています。サブテーブルはversion=0xcでformat12, startOffset=0x0000000cです。これをformat12の定義に従ってUnicodeGIDのテーブルを読み出します。
次にグリフの実態に関してです。グリフ自体はビットマップでsbixテーブル内に保持されています。
グリフ総数はmaxpテーブルに記述されていますのでそれを読み出します。0x678ですから1656個のグリフが存在することになります。しかしながら特殊なグリフなどが存在していまして、こちらはglyfテーブルにアウトラインが保持されています。これはミッシング・グリフ等のものです。実際にビットマップが存在するグリフは1611個となっています。
基本的にsbixテーブルのstrikeで適当なppemを持ったテーブルからカラーグリフを抽出して配置するのですが、このサロゲートペアが2つ並んだものは後ろのコード値により前のコード値より導き出したGID値をシフトさせます。例えば2つめのコードが0x1f3bであればGIDを+1します。カラーは5種類定義されています。この2つ目に並べられるカラー定義に利用されるグリフのユニコードは0x1f3b〜0x1f3ffの値をとり、1〜5のシフト幅を持ちます。
という事で上の例では
Unicode/0x1f476
サロゲートペアを正しく処理するとこの様になります。cmapテーブルを前述の様に展開して変換テーブルを得ます。そこから目的のGID値は
GID = 1053
となりますが、もう一つサロゲートペアがついてきていますので、それを対処する必要があります。2つ目のコードは0x1f3fcですから先程得たGIDに+2します。結果求めるGID値は
GID=1055
となります。ちなみに2つめのサロゲートペアもcmap上にGIDが定義されており、グリフもあります。これは各カラーの四角のベタになっています。
さて諸々をすっ飛ばして進みます。sbixテーブルはこのフォントの場合、解像度違いのstrikeを7個持ちます。これは文字サイズに応じて適切な解像度となるビットマップグリフを得るための仕組みです。
ここでstrikeの構造について書いておきましょう。
PPEMサイズ(16bit)、PPI(16bit)、glyphDataOffsets(32bit)✕(グリフ総数+1)
各strikeはこのような構造をとりまます。ここで注意が必要なのはグリフデータオフセットの構造です。グリフデータは各グリフデータオフセットから始まります。そしてデータ自体は隙間なく詰められていますので終端は次のグリフ開始位置の1バイト手前となります。要するに次のグリフ開始位置を目印にデータを取り出す事になるのです。その為、最後のグリフの終端を判別できるようグリフ総数+1のグリフデータオフセットが記述されています。
グリフデータにもヘッダが付加されていてx,yそれぞれのOrignOffsetが16bitで記述されていますが、このフォントの場合、全てのグリフがどちらも0x0000となっています。つづいて4byteのTagが続きます。これはビットマップデータのファイル形式で「png 」「jpg 」「tiff」等を利用できます。ここまでくれば、あとはデータを抽出してファイルとして保存するだけです。
今回は面倒なので一番ppemの大きいstrike6を決め打ちで展開します。ちなみにこのstrike6のグリフは160px✕160pxのサイズで300dpi利用を想定すると1/2インチ程のサイズでの利用が可能です。
そして1055番目のグリフは…
となります。
一連を実行した結果がこちら。
最後に鯵さんに…
[youtube https://www.youtube.com/watch?v=9M32_uLSxio&w=560&h=315]