これは小波秀雄が
Postscript で図形を描くために書き溜めているメモです.
拙作のライブラリと併用すれば,
簡単な記述で描画を実現できます.
|a|b|
まずは直線を引いたり,円を描くための EPS ファイルを 作成してみます.これで試した後,とにかく早く描画をしたい 人は,小波秀雄作のPostscript ライブラリを利用するとよいでしょう.
%!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: 0 0 400 300
50 50 moveto 100 90 lineto 100 160 lineto 10 70 lineto
stroke
closepath stroke
fill
変数,手続きを簡単に定義して使うことができる.
/m {moveto} def /l {lineto} defこれ以降は,moveto, lineto の代わりに m, l だけでよい.
/x1 {100} def /y1 {120} defこれ以降は,x1, y1 を使って書くことができる.
1 1 0 setrgbcolor
7 setlinewidth
newpath 180 100 15 30 180 arc strokestroke の代わりに fill を使えば塗りつぶしになる.また newpath を省略すると余計な線が描かれることがある.
newpath 280 100 15 0 360 arc stroke
とりあえず簡単な絵を作りたい人は,ここからPostscript ライブラリ の方へ飛んでみるといいでしょう.
EPS(Encapsulated Postscirpt)は,1枚の画像の大きさを決めて出力するタイプの フォーマットで,下のようなヘッダを付けるだけで,EPS になります. showpage は使いません.
%!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: 0 0 600 600 %%HiResBoundingBox: 0 0 599.5 600.2
3行目は拡張版用,2行目と併用するらしい.あまり使わないみたい.
|a| dup → |a|a|
|a|b|c| 2 copy → |a|b|c|b|c|
|f|e|d|c|b|a| 5 1 roll → |a|f|e|d|c|b| |f|e|d|c|b|a| 5 2 roll → |b|a|f|e|d|c|
|d|c|b|a| count → |d|c|b|a|4|
指定回数繰り返す
5 {proc} repeat
x1 から始めて終了条件 x2 に達するまで dx ずつ増やして繰り返す
x1 dx x2 {proc} for変数の順序に注意
50 10 200 {50 10 0 360 arc stroke} for
x1 dx x2 {y moveto 0 length rlineto stroke} for
y1 dy y2 {x exch moveto length 0 rlineto stroke} for
[a b c d ...] w setdash
[] 0 setdash
(foo.ps) run
ある PS ファイル foo.ps があったときに,それを直接 描画に使うのではなく, 別ファイル hoge1.ps , hoge2.ps などから上のように読み込んで使うようにするとよい. dviout だと異なった bmc ファイルになるし, GIMP で加工して書き戻したときにも,原型の方は壊されないですむ.
d c b a 3 array astore → |d|[c b a]|
[c b a] aload → |c|b|a|[c b a]|
このとき,トップには元の配列が残されているので, 不要なら pop して捨てる.
現在の色を変数に保存しておいて,後でまたその色に戻すには, 次のようにするとよい.
currentrgbcolor 3 array astore /rgb exch def 1 0 0 setrgbcolor % 他の色に設定 ... ... rgb aload pop setrgbcolor % 元の色に戻す
gsave, grestore を使うと,現在のパス,色などをセーブしておいて,あとで再利用できる.
塗りつぶしと輪郭描きを同一のパスについて行うには次のようにするとよい.
4 setlinewidth 1 0 0 setrgbcolor 50 50 moveto 150 50 lineto 100 130 lineto % パスを生成 gsave % 上の状態をすべてセーブ. 0.5 setlinewidth 1 1 0 setrgbcolor fill grestore % 線の太さ,描画色,パスが呼び戻される. closepath stroke
gsave はグラフィック状態をスタックに保存するので, 複数回実行すると,その回数分の状態が記憶される.
1 setlinewidth 1 0 0 setrgbcolor 50 150 moveto 150 150 lineto 100 230 lineto closepath gsave gsave 1 1 0 setrgbcolor fill grestore 4 setlinewidth stroke grestore 1 1 1 setrgbcolor 0.5 setlinewidth stroke
文字列を表示させるためには,次の例のような手続きを必要とします.
上の処理は一度行っておけば,その後の出力は同じ設定のままで行われることになります.
show によって打ち出される文字列は,左下隅がカレントポイントに置かれます. したがって,moveto などによってカレントポイントが設定されていないと エラーになります.ただし,カレントポイントは文字出力によっても 更新されていきますので,常に moveto を使う必要があるわけではありません.
/Times-Roman findfont 10 scalefont setfont 100 200 moveto (ABC) show
下のPDFファイル(chartable.pdf) は,Postscript で使われる欧文フォントの一覧です. 表は Times-Roman, Times-Italic 等のフォント名ごとに 作成されています. それぞれの表は 40 〜 377(8進法表記)の整数,(あれば) 対応するアスキー文字,そして該当するフォントそのものが表示されています.
含まれているフォントは次のとおりです.
文字によってはアスキー文字の中にないものもあります.たとえば 英国のポンドを表す £ のような文字です.それらの文字は アスキーコードの 0x80 から 0xFF までに割り当てています. ただし文字の扱いでは 8進法で使うのが普通で, 0200 から 0377 がその範囲になります. その場合にこの表を参照して使います.
表を見て,文字に 対応する8進数を調べます. £ であれば 243 となりますから, バックスラッシュを付けて次のように記述すればオーケーです.
/Times-Roman findfont 12 scalefont setfont 100 250 moveto (I have 120\243 in my purse.) showなお,次のようにすれば16進法を使うことも可能ですが, 8進法を使うときのように文字列に埋め込むことが出来ないので, 使いやすくはありません.
/Times-Roman findfont 12 scalefont setfont 100 200 moveto (I have 120)show <A3> show ( in my purse.) show
ギリシャ文字は Symbol というフォントを指定すると出力することが出来ます. この場合 アスキーのアルファベットと同じ場所に 割り振られているので,たとえば "a" → "α" のように すれば,特に問題なく利用できます.ただし,数学記号なども Symbol の中に 入っていて,80H (0200) 以上に割り当てられていますので, この表を見る必要のあるケースも出てきます.次は α' を出力する例です.
/Symbol findfont 12 scalefont setfont (a\242) show
Ghostscript で使える欧文フォントのサンプルは次にありますので,さらに多様な フォントが必要になったら,参考にしてください.
xfigType1.pdf(表示はこちら) xfigType1.ps(ダウンロードして調べて下さい)
和文フォントを利用するには,文字コードの問題を押さえておくことが必要です. Postscript で使いやすい文字コードは UTF-8 です. Shift-JIS は,特定の文字で文字化けを起こす現象が知られており, 使うべきではありません.
UTF-8 インストールされていれば,それを使うのがよいでしょう. EUC-JPもまだ使えます.
使用する文字コードごとに,上の XXXX の部分を次のようにします. 最近の OS であればUTF-8 を使えば大丈夫でしょう。
日本語は縦書きにもできます.この場合,次のようにフォント指定を変更すれば 自動的に縦書きになります.例は明朝体を UTF-8 で使っている場合です.
H は Horizontal V は Vertical からきています.
Ryumin-Light-UniJIS-UTF8-H findfont 12 scalefont setfont 100 200 moveto (日本語の表示) show
/GothicBBB-Medium-UniJIS-UTF8-V findfont 12 scalefont setfont 100 200 moveto (日本語の表示) show
% 型となる図形の定義.ただし fill, stroke は行わない! clip % 図形などを描く.すると型で切り抜かれて描画される. initclip % clip を解除
/Times-Italic findfont 70 scalefont setfont 45 100 moveto (QP) false charpath clip 80 3 170 {5 exch moveto 200 0 rlineto stroke} for initclip
/m {moveto} def /l {lineto} def /s {stroke} def -1000 10 1000 { % -1000 左端 水平間隔 右端 70 120 120 % 下端 斜線 x y : 比と符号でデザイン変更 4 2 roll 2 copy moveto 3 2 roll add 3 1 roll add exch lineto stroke } for
% 2つの円の内側にハッチを入れる /m {moveto} def /l {lineto} def /s {stroke} def newpath 100 100 60 0 360 arc % 左の円を作る 240 100 60 sub m % 右の円の円周上に移動 newpath は使えない 240 100 60 0 360 arc % 右の円 clip % ハッチを描く -800 10 1000 { % 水平方向の間隔は 10 0 200 200 % 左斜め下への斜線 4 2 roll 2 copy m 3 2 roll add 3 1 roll add exch l s } for initclip
図形には輪郭だけを与えて, stroke していないことに注意.
/cm {28.346 mul} def
上のようにしておけば, 12.3 cm と,単位付きの長さを扱うように記述できる.
100 200 /y exch def /x exch defこれで x, y に 100, 200 が代入されている。
/localdict 1 dict def /sampleproc { localdict begin /localvariable const def end } defここで,/localdict 1 の 1 は常にこの値でよい.この値は 初期の言語仕様で バッファサイズ を指定するために使われたのだが,現在の仕様では自動的に メモリが割り当てられる.
ある手続きを定義して,その中のローカル変数に パラメータを渡したいというのはよく起きる. このときには上のサンプルの形の中で exch 演算子を使うとよい.
次のサンプルでは,x1, y1 にそれぞれ 10, 20 が, x2, y2 にそれぞれ 100, 190 が代入される. 実行して確かめるとよい.このやり方を使えば, 複雑なスタック操作をやらなくて済む.
%!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: 0 0 300 250 /ldict 1 dict def /proc { ldict begin /y2 exch def /x2 exch def /y1 exch def /x1 exch def x1 y1 10 0 360 arc stroke x2 y2 5 0 360 arc fill end } def 10 20 100 190 proc
(ABC) dup stringwidth pop 2 div neg x add y moveto show
注意:この手続きで縦位置を合わせることはできない.
決められた図形を任意の場所に描画するには, moveto などよりも translate を使ったほうが汎用性が高い. ただし,この場合には,移動した後で translate による移動を原点に ふたたび戻すことになるので, 多少面倒ではある.
今,原点付近にある図形を描画する手続きを proc とすると,それを任意の場所に描画してから状態を 元に戻す手続き putprocat は次のように 書く.
/putprocat { 2 copy neg exch neg exch 4 2 roll translate proc translate } defputprocat は次のように使う.
x y putprocat
gs -q -dEPSCrop -dNOSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -r600 -dText AlphaBits=2 -dGraphicsAlphaBits=2 -sOutputFile=hoge.png hoge.ps
この例では解像度を 600dpiにしている。 なお 次のようにコマンド化しておくと便利である。 次のシェルスクリプトを ps2png というファイル名でパスの通ったディレクトリに置いておく。
#!/bin/sh fname=$1 pngfile=${fname%.*}.png echo $pngfile gs -q -dNOSAFER -dBATCH -dEPSCrop -r600 -dNOPAUSE \ -sDEVICE=png16m -dGraphicsAlphaBits=4 \ -dTextAlphaBits=4 \ -sOutputFile=$pngfile $fname
実行は次のように簡単で,これで拡張子を .png にしたファイル hoge.png が生成する。
ps2png hoge.ps