今回も前回に引き続いてGhostScript/PostScriptを使って図形を描きます。

○四角形を表示する(rectfill, rectstroke)

 次に四角形を表示してみましょう。
塗りつぶされた四角形を描く場合はrectfill、線だけの四角形を描くにはrectstrokeを使います。どちらの命令も値は4つで以下の順番で指定します。

X座標 Y座標 横幅 縦幅

以下の例では座標(20,80)に横幅、縦幅ともに100の四角形が描かれます。

【rect1.ps】

%!PS
1 0 0 setrgbcolor
20 80 100 100 rectfill
showpage

線だけの場合は以下のようになります。

【rect2.ps】

%!PS
1 0 0 setrgbcolor
20 80 100 100 rectstroke
showpage

次に四角形の色を変えて描いてみます。色を変えるにはプログラムで言うところの変数を使います。GhostScript/PostScriptでは名前と値を辞書に登録することで変数と同じように使うことができます。
辞書に登録するには/の後に名前を書いて、その後に定義内容を書きます。そして最後にdefを指定します。
以下の例ではRという名前の内容を0にしています。一般的なプログラム言語では「R=0」と同じです。

/R 0 def

変数の値を計算する場合も同様に名前と辞書への登録になります。
以下の例ではRに0.2を足します。一般的なプログラム言語では「R=R+0.2」と同じです。

/R R 0.2 add def

次に繰り返しですが、単純に繰り返すだけであれば以下のようになります。

繰り返し回数 {
 繰り返す内容
} repeat

四角形をずらすためにtranslateを使って座標系を変えます。translateは横方向のずれと縦方向のずれ(オフセット/相対座標)を示す2つの値が必要です。以下の例では横方向に100、縦方向に0だけ座標系を移動されます。これにより原点座標が変わるためrectfillなどで指定した図形をずらして描画することができます。

100 0 translate

以下のようにすると四角形が5つ色を変えながら横に描画されます。

【rect3.ps】

%!PS
/R 0 def
0 400 translate
5 {
R 0 0 setrgbcolor
0 0 100 100 rectfill
100 0 translate
/R R 0.2 add def
} repeat
showpage

repeatは入れ子にすることができます。せっかくなので赤と緑の4色グラデーションのような感じで描いてみましょう。
横と縦方向に座標をずらして描画しますが、座標系を保存するためにgsave、座標系を復元するためにgrestoreを使います。

【rect4.ps】

%!PS
/G 0 def
10 100 translate
5 {
/R 0 def
gsave
5 {
R G 0 setrgbcolor
0 0 100 100 rectfill
100 0 translate
/R R 0.2 add def
} repeat
grestore
0 100 translate
/G G 0.2 add def
} repeat
showpage

もっと細かく描画したい場合は繰り返しの数と移動量、色の変化量などを変更します。
本当は移動量や変化量などは/で始まる名前で定義した方がいいのですが、気になる人は挑戦してみてください。

【rect5.ps】

%!PS
/G 0 def
10 100 translate
50 {
/R 0 def
gsave
50 {
R G 0 setrgbcolor
0 0 10 10 rectfill
10 0 translate
/R R 0.02 add def
} repeat
grestore
0 10 translate
/G G 0.02 add def
} repeat
showpage

○四角形を表示する(パスでつなぐ方法)

 次に四角形を直線のパスをつなげて表示してみましょう。単純な四角形であればrectstrokeやrectfillで問題ありませんが、四角形っぽい複雑な図形やAdobe Illustratorなどの編集ソフトを作るような場合には図形はパスで構築した方が便利な面があります。(既存アプリケーションに不満がある人は挑戦してみるといいかもしれません)
 パスで四角形を構築するにはmovetoとlinetoを組み合わせます。その際、newpath/closepathを使って複数の直線の組み合わせを1つのパスとして構築します。
 また、作成したパスを再利用する場合は/名前 {~} として作成したパスに名前を付けておきます。
 以下の例では四角形にboxという名前を付けて赤い線で描画しています。

【path1.ps】

%!PS
/box {
newpath
0 0 moveto
0 100 lineto
100 100 lineto
100 0 lineto
closepath
} def

20 400 translate
1 0 0 setrgbcolor
box
stroke
showpage

線でなく赤色で塗りつぶしたい場合は以下のようにfillを使います。

【path2.ps】

%!PS
/box {
newpath
0 0 moveto
0 100 lineto
100 100 lineto
100 0 lineto
closepath
} def

20 400 translate
1 0 0 setrgbcolor
box
fill
showpage

塗りを赤色、線を青色にする場合は以下のようになります。先に塗った後に線を描いていますが、strokeとfillの順番を入れ替えれば線を描画した後に塗り潰した四角形が表示されます。

【path3.ps】

%!PS
/box {
newpath
0 0 moveto
0 100 lineto
100 100 lineto
100 0 lineto
closepath
} def

20 400 translate
1 0 0 setrgbcolor
box
fill
box
0 0.2 1 setrgbcolor
10 setlinewidth
stroke
showpage

○ベジエ曲線を表示する

 次にベジエ曲線を表示してみましょう。GhostScript/PostScriptで採用されているベジエ曲線は3次のベジエ曲線です。
この3次ベジエ曲線は4つの座標をスムーズに結ぶ曲線です。

ベジエ曲線を描くにはcurvetoを使います。パラメーターはx1 y1 x2 y2 x3 y3の合計6つです。あれ?ベジエ曲線は台形だから4つの点が必要、つまり8つのパラメーターが必要なのでは?と思った人もいるかもしれません。実は残りの1つの座標(開始座標)は現在のペンの位置になります。このようにしておくことで連続した曲線や直線を描くのが容易になるためです。また、多少なりともデータサイズの節約にもなります。と書いても昔と違って今はデータサイズを気にするようなことはないでしょう。

 実際にベジエ曲線を描くコードは以下のようになります。

【bez1.ps】

%!PS
newpath
50 100 moveto
80 140 180 100 250 50 curveto
stroke
showpage

連続したベジエ曲線を描く場合は以下のように続けて座標値とcurvetoを指定します。ちなみに初期のベクトルフォントであるAdobe Type 1 Fontはベジエ曲線の組み合わせでしたが、これはフォントのような角が多い場合に角が作りやすいベジエ曲線はデータサイズが軽減されるから、という理由もあったかもしれません。その後、対抗馬として登場するTrueTypeは3次ベジエ曲線でなく2次ベジェ曲線が採用されています。


・TrueType Reference Manual
https://developer.apple.com/fonts/TrueType-Reference-Manual/

【bez2.ps】

%!PS
newpath
50 100 moveto
80 140 180 100 250 50 curveto
300 100 320 120 340 10 curveto
stroke
showpage

.
編集部おすすめ