プログラムで作成する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