PostScript で printf デバッグ

PostScript TUTORIAL and COOKBOOKの51ページに星の形を描くプログラムがあります。文字列を表示する print とスタックを表示する pstack を使って動作する様子を追いかけてみます。

  • Chapter 6: MORE GRAPHICS (Saving the Graphics State)
/starside
  { 72 0 lineto              % 右へ72ポイント線を引くためのパスを追加
                             % 実際に線を引くのは stroke のとき
                             % 塗りつぶすのにも同じパスを使っている。

    currentpoint             % 現在位置の座標をスタックに積む

    translate                % ユーザ空間座標をスタックの位置に移動

   -144 rotate } def         % ユーザ空間座標を-144回転

/star %stack: x y
  { moveto                   % スタックの座標に移動

    currentpoint             % 現在位置の座標をスタックに積む

    translate                % ユーザ空間座標をスタックの位置に移動

    4 {starside} repeat      % starside を4回実行する

    closepath                % 描いたパスをmovetoのへ連結して閉じる。

    gsave                    % 塗りつぶすとパスが消えてしまうので
                             % グラフィック環境をスタックへ保存

    .5 setgray               % 0:白 1.0 黒 0.5の中間色設定

     fill                    % 塗りつぶす
    grestore                 % パス等の描写情報をリストア
    stroke } def             % 星形の線を引く

% x:200 y:200 をスタックに積んでstar手続きを呼びます。
200 200 star
showpage

要するに手で★を描くときと同じ方法です。

  • まず、 x:200 y:200 に移動します。
    • 72ポイントの横線を引く
    • 線を引いた先に基準点を移動させる(ここが 0 0 になる)
    • -144度座標を回転させる

 これを4回繰り返します。

  • 最後に始点を結ぶと言う動作で星を描いています。


print、 pstackを入れまくって動作する様子を表示してみます。

/starside
{
  (== starsider ==\n) print 
  pstack                  % 全部スタック表示
  (== 72 0 lineto ==\n) print 
  72 0 lineto             % 水平に右方向へ72ポイントの線を引く
  currentpoint            % 線を引いた終点の座標をスタックに積む
  (== currentpoint ==\n) print 
  pstack                  % 全部スタック表示
  (== translate ==\n) print 
  translate               % ユーザ空間をスタックに積んだ値に移動
  (== -144 rotate ==\n) print 
  -144 rotate             % -144 座標系回転
 } def             %rotate coord. sys.

/star %stack: x y
{
  (== Call Star ==\n) print 
  pstack                  % 全部スタック表示
  (== moveto ==\n) print 
  moveto
  (== currentpoint ==\n) print 
  currentpoint            % 線を引いた終点の座標をスタックに積む
  pstack                  % 全部スタック表示
  (== translate ==\n) print 
  translate               % ユーザ空間をスタックに積んだ値に移動
  4 {starside} repeat
  (== closepath ==\n) print 
  closepath
  gsave
  .5 setgray fill
  grestore
  stroke } def

200 200 star
showpage
  • print、 pstack の入った star.ps を ps2pdf で pdf に変換します。
> ps2pdf star.ps star.pdf
== Call Star ==
200
200
== moveto ==           % x:200 y:200 に移動。
== currentpoint ==     % 現在位置を取得しスタックへ。
200.0
200.0
== translate ==        % ユーザ座標をスタックの位置へ。
== starsider ==        % starsider が呼ばれた。
== 72 0 lineto ==      % 右へ72ポイントのパス
== currentpoint ==     % 現在位置を取得しスタックへ。
0.0
72.0
== translate ==        % ユーザ座標をスタックの位置へ。
== -144 rotate ==      % -144 度ユーザ座標を回転
== starsider ==        % starsider が呼ばれた。
% 以下同様
== 72 0 lineto ==
== currentpoint ==
0.0
72.0000076
== translate ==
== -144 rotate ==
== starsider ==
== 72 0 lineto ==
== currentpoint ==
0.0
72.0000076
== translate ==
== -144 rotate ==
== starsider ==
== 72 0 lineto ==
== currentpoint ==
1.14440918e-05
72.0000076
== translate ==
== -144 rotate ==

少し修正すると正五角形を描くことが出来ます。

% Regular polygon
/polygonside
{
  72 0 lineto             % 水平に右方向へ72ポイントの線を引く
  currentpoint            % 線を引いた終点の座標をスタックに積む
  translate               % ユーザ空間をスタックに積んだ値に移動
  -72 rotate               % 座標系回転 正七角形(-51.42857 rotate )
 } def

/polygon
{
  currentpoint            % 線を引いた終点の座標をスタックに積む
  translate               % ユーザ空間をスタックに積んだ値に移動
  4{polygonside} repeat   % 正七角形(6{polygonside} repeat)
  closepath
  gsave
  .5 setgray fill
  grestore
  stroke
} def

200 200 moveto
polygon
showpage

外角の和は360度ですので、以下の値にすると正七角形になります。

  • -51.42857 rotate % 座標系回転 360 / 7
  • 6{polygonside} repeat % 7 -1