プログラムで作成するPostscript

 自作プログラムで,グラフや画像出力が必要な場合には, Postscriptコードを生成させ利用するということはよくあります. PostscriptはAdobeが作成した言語で, 各種マニュアルを出版しているほか, Web上にそのpdfファイルが置いてあり自由にダウンロードできました. 入門書がBlue Bookで,言語仕様書がRed Book, 使用手引書がGreen Book等々でした. これらは,いずれも邦訳があります. 現在はAdobeのサイトにはこれらのpdfは置いてないようです (Web上にはあるので検索して下さい). Postscriptは普通のプログラム言語なので, 版面作成だけではなくて,様々に利用可能です. 半分冗談でしょうが,ちゃんと動くWebサーバーなんてのもあります. ところが,Green Bookには, 版面配置の最終結果だけをコードすべきだと書いてあります. Postscript開発時には, CPUの速度やメモリ容量は現在の1/100だったので, プリンタを実用的な速度で働かせるためには, このようなガイドラインが必要だったのでしょう. 当然,そうしておけば,速度だけでなく, 演算時のエラー回避, 自由度が低下して判読性が上がる等の効果もあります. この考え方の先には,pdfがあります. これは,版面配置の最終結果だけをコードしたもので, 演算処理は出来ません. つまり,pdfはプログラム言語ではありません. 逆に言うと,AdobeはPostscriptから,版面配置機能だけを, distillしてpdfを作ったということです (Postscriptをpdfに変換するAdobeの製品名がDistillerです). pdfファイルのコードを見ると, Postscriptのあるコーディングスタイルと, 非常によく似ていて,最初は驚いたものです. なお,普通のpdf閲覧ソフトでは,pdfのコードは見られません. 多くのブラウザやメールソフトで,閲覧中のページやメールの, 本当の中身(コード)を見ることが出来るのとは対照的で, 残念なことだと思います.
 今の時点で考えると,こういうことになるのですが, これまでに書いたPostscriptを出力するプログラムでは, Green Book流に版面配置の最終結果だけを念頭に置いたものです. 先日,ふと思い立って,Postscriptに演算処理をさせてみました. そうしたら,当たり前ではあるのですが, コードが劇的にというか,極端に短くなりました. 表示にかかる時間も,特に長くなるということはなく, 可読性に問題がなければ,今後は,こういったスタイルで, コードを書こうと思います.  
 

 上図は,簡単な例のPostscriptを表示させたものを, 更にpngファイルに変換したものです. 元のPostscriptコードは次のようなものです.
%!
%各種設定
/thm 24.0 def%最適温度の定義
/thw 20.0 def%好適温度幅の定義
/Times-Roman findfont 30 scalefont setfont%使用フォントの定義
/rightshow{%右詰文字印字の定義
dup stringwidth pop -1 mul 0 rmoveto show }def
/centershow{%中央文字表示の定義
dup stringwidth pop 2 div neg 0 rmoveto show }def
/vcshow {%縦書の中央文字表示の定義
dup stringwidth pop 2 div neg 0 exch rmoveto gsave 90 rotate show grestore} def
/str 10 string def%文字列バッファの定義
/shownumbx {%数字→文字変換してx軸に表示の定義
moveto cvi str cvs centershow} def
/shownumby {%数字→文字変換してy軸に表示の定義
moveto cvi 10 div str cvs rightshow} def
80 200 translate%原点設定
%各種設定おわり

%関数描画
1 0 0 setrgbcolor%赤を使う
0 0 moveto%原点移動
0 1 1000 {%関数本体
 dup 10 div thm sub dup mul 2 ln mul -4 mul thw dup mul div 2.718281828459 exch exp 300 mul lineto
} for
stroke%実際の描画

%座標の描画
0 0 0 setrgbcolor%黒を使う
0 100 500 {dup 0 moveto 300 lineto} for%y軸とy軸平行線
0 60 300 {dup 0 exch moveto 500 exch lineto} for%x軸とx軸平行線
stroke%実際の描画
0 100 500 {dup 10 div exch -30 shownumbx} for%x軸数字
0 60 300 {dup 30 div exch 10 sub -3 exch shownumby} for%y軸数字
-50 150 moveto (relative response) vcshow%y軸ラベル
250 -60 moveto (temperature \312C) centershow%x軸ラベル
showpage%ページの表示
 コメントを沢山入れたので, 意味は大体分かると思います. これを,GreenBook風にするとどうなるかというと, 例えば関数本体に関しては, 0 0 moveto 0.1 0.1 lineto〜という形で, 曲線の描画が開始され, この後に,「x軸数値 y軸数値 lineto」という記述が, 999個繰り返されることになります. このデータは, 例えばPerlで実際に計算して作成することになりますが, Postscript側で計算させるとしたら, 上記の「0 1 1000 {〜} for」というちょっと長い1行で済みます. 軸や軸数字の所にも同じような構文が現れていますが, これは,他の言語でよく使われる,for next loopです. もちろん,他の言語でも,for next loopを使わないで, いちいち,個別に変数を指定して同様なことをすることが出来ます. しかし,これはかなり非現実的なので, 実際には行われません. ところが,GreenBookはそれを推奨していますし, pdfではそれ以外に記述法がありませんので, 同じ事をするにも,何十倍, 何百倍という分量になってしまいます.
 GreenBookの立場に立たなければ,この様に, コードを極端に短くすることが可能です. 短さだけで言えば, このコードも,更に短くすることが可能でしょうが, この位が可読性という点でも良いんじゃないかと思います. 今後は,こういう形のコードを出力するように, 例えばPerlのプログラムを作るようにしたいと考えています. プログラムでPostscriptのコードを生成する時にも, プログラム次第で,如何様なものも作れますが, 例えば,上記コードの最初の部分の, 「/thm 24.0 def%最適温度」と 「/thw 20.0 def%好適温度幅」 の数値を変更してやれば,それに応じた曲線を描画出来ます.  
 
 
正面玄関(トップページ) 
現行版:2010年1月19日
初 版:2010年1月8日
メールアドレス:nmizunoアットマークaffrc.go.jp