« アイコン。 | トップページ | コンテナ »

2009年1月20日 (火)

OpenTypeフォントの続き(9)・・・インストラクション

久しぶりにOpenTypeフォントの続き。今回はインストラクション

インストラクションは特定のグリフに、または、フォント全体に関連付けることができる。特定のグリフに関連付けられたインストラクションはグリフプログラム(Glyph Program)と呼ばれ、glyfテーブルに格納され、そのグリフが要求される度に実行される。フォントプログラム(Font Program)はfpgmテーブルに格納されるインストラクションで、フォントにアクセスされる最初に一度だけ実行される。コントロール値プログラム(Control Value Program)はprepテーブルに格納されるインストラクションで、フォントのポイントサイズが変わるたびに実行される。

ところで、インストラクションを実行するプログラムはTrueTypeインタプリタと呼ばれるが、TrueTypeインタプリタは主に

  • インストラクションストリーム
  • インタプリタスタック
  • グラフィックスステート

で構成される。インストラクションのオプコードとデータは順序付けれた一連のバイト値として格納されるが、この一連のバイト値はインストラクションストリームと呼ばれ、インストラクションポインタ(IP)が次に実行するインストラクションを指し示す。

Opentype9_ip_2

また、TrueTypeインタプリタはインストラクションに必要なデータとインストラクションによって生成された結果をスタックに格納するが、このスタックはインタプリタスタックと呼ばれる。ほとんどのインストラクションはこのスタックに対して操作を行うが、PUSH命令と呼ばれるインストラクションはインストラクションストリームからその引数を取り、それをスタックに転送する。

PUSH命令
インストラクション 説明
NPUSHB[] PUSH N Bytes
NPUSHW[] PUSH N Words
PUSHB[abc] PUSH Bytes
PUSHW[abc] PUSH Words

ところで、インタプリタスタックの各要素は32ビットの固定長であるので、PUSH命令でインストラクションストリームから取り出したデータはゼロ拡張や符号拡張を行い32ビット長にしてからスタックにPOPする必要がある。

と、いろいろ省略してるが、まぁ、TrueTypeインタプリタを作る人以外は、これ以上、深入りしてもしょうがないような気がするので、実際にインストラクションを解析してみる。まずは、Tahomaフォントのフォントプログラムから。

Opentype9_1

フォントプログラムでは主に他で使用される関数やインストラクションが定義されるのだが、そのためのFDEF(Function DEFinition)命令が見てとれる。次は、コントロール値プログラム。

Opentype9_2

PUSH命令だらけである。先ほども書いたが、PUSH命令は引数がインストラクションストリームから取られるので、PUSH命令の次の命令のオフセットが引数のサイズだけ飛んでいるのである。最後はグリフプログラム。

Opentype9_3

とこんな感じ。

ちなみに、TrueTypeインタプリタの実行環境のメモリ要件など関する情報はmaxpテーブルに格納されている。

Opentype9_4_2

上の画像はTahomaフォントのmaxpテーブルの内容であるが、例えば、定義されている関数の数(MaxFunctionDefs)は57個、定義されているインストラクションの数は(MaxInstructionDefs)は0個、グリフプログラムの最大バイト数(MaxSizeOfInstructions)は1406バイトであるので、グリフプログラムの実行のために1406バイト以上のメモリを確保しておけばよい・・・・

というかT2FAnalyzerのプログラムが巨大になり手に負えなくなってきたwobbly・・・リファクタリングしないとだめだなぁ・・・

« アイコン。 | トップページ | コンテナ »

フォント」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1497665/39651733

この記事へのトラックバック一覧です: OpenTypeフォントの続き(9)・・・インストラクション:

« アイコン。 | トップページ | コンテナ »

自作ソフトウェア

無料ブログはココログ

メモ