1

私は Postscript でいくつかのフォームを作成していますが、現在のポイントを変数に保存する必要がある場合があるため、後で moveto のスタックに xy 値を便利に配置できます。それほど単純ではありません。x と y の両方を 1 つの変数に格納するプロシージャを探しています。

あなたが 72 720 にいるとします。私は CP などの変数に両方を格納できるようにしたいと考えています。もちろん、保存したい場合は

/cp {72 720} def

そして、呼び出されたときに 72 720 を含むスタックを残すプロシージャを作成します。しかし、実行中に任意の場所を保存したい場合はどうすればよいでしょうか? 次のコードは機能しません。

/cp {currentpoint} def
72 720 moveto
cp 
100 100 moveto
cp

このコードは毎回 currentpoint を呼び出し、72 720 100 100 をスタックに残します。

現在のポイントを変数に取り込み、実行時に決定された 2 つの値をスタックに置くプロシージャをどのように作成しますか?

4

3 に答える 3

2

次の例では、呼び出されたときにスタックに 2 つの値を配置するプロシージャを実行時に作成します。

72 720 moveto
/cp [ currentpoint ] cvx def
cp
100 100 moveto
cp

これにより、スタックに 72 720 72 720 が残ります。cp の定義が最初に 2 つの値で配列を埋めます。cp が呼び出されると、現在のポイント位置の変更に関係なく、 is が呼び出されるたびに 2 つの格納された値がスタックにプッシュされるように、実行可能になります。

もちろん、これの有用性は、明示的なポイントに到達することではなく、実行中にポイントをキャプチャすることです。コードフラグメントが

72 720 moveto
(Begin with, end with) show
/cp [ currentpoint ] cvx def

% intervening code ...

cp moveto
(, whatever!) show

これの有用性はより明白です。

これが機能するには、現在のポイントが存在する必要があることに注意してください。質問セクションでは、実行が保留されているため、プロシージャ {currentpoint} を作成できます。ただし、 currentpoint が現在のポイントなしで呼び出されると、postscript エラーが発生します。これを調べるために、短い追記プログラムが続きます。

%!
/fontsize 14 def
/lineheight 16 def

/Times-Roman findfont fontsize scalefont setfont

/newline 
   {72 currentpoint exch pop lineheight sub
    dup 72 lt {showpage pop 720} if
    moveto
    } def

/cp2 { currentpoint } def

72 720 moveto
/cp1 [ currentpoint ] cvx def
cp1
cp2
(Test line) show
cp1
cp2

144 500 moveto
cp1
cp2
/cp1 [ currentpoint ] cvx def
cp1
cp2

(Test line) stringwidth

newline 
(-top of stack-) show 
newline
count {30 string cvs show newline} repeat
(-bottom of stack-) show newline

showpage

これを理解するためにインターネットで多くの参考文献を検索しましたが、何も表示されませんでした。x と y の値を別々の変数に格納するという手段に頼っていましたが、そのアプローチの優雅さから、このアプローチを思いつきました。これが何らかのキーワードで扱われるトピックであることがわかっている場合は、お知らせください。

于 2013-02-26T02:45:20.493 に答える
1

このようなことができます。独自の関数を定義する予定がある場合は、独自の辞書を定義することから始めて、それを辞書スタックの一番上に配置する必要があります。

ディクショナリ内に2 要素配列を定義して、現在のポイントを配列に格納cpaするための x、y 定義を保持します。配列から currentpoint を復元するように/cp定義します/CP

    /mydict 100 dict def
    mydict begin

    /cpa {2 array} def
    /cp {/cpa currentpoint cpa astore def}  def
    /CP { cpa aload pop moveto } def

%test out the functions
    123 456 moveto %move to a point
    cp             %save that point

    986 654 moveto %move to a different point
    CP             %restore the saved point
    (Currentpoint ) == currentpoint exch == ==  %print out the current 

gsave/grestore および save/restore についてもお読みください。これらはおそらくあなたが本当に求めているものです。

于 2013-02-26T05:44:31.253 に答える
1

私はここで他の両方の答えが好きです(そして賛成しました)が、いくつかの楽しい小さなコーナー、IMOを示す同じアイデアのわずかなバリエーションがあります.

同じ配列を 2 回定義して、一方を参照リテラルにし、もう一方を実行可能にすることができます。新しい配列を破棄して割り当てるよりも、同じ配列を再利用する方がわずかにエレガントです。

/cpa 2 array def           % literal array for storing
/cpx cpa cvx def           % executable version of same array for spilling on the stack

currentpoint cpa astore pop  % save currentpoint

cpx moveto                 % return to currentpoint

現在、スケーリング、回転、平行移動のいずれかを使用して現在の変換行列 (CTM) を変更した場合、これは機能しません。より一般的な解決策として、 (ユーザー空間に関して安定transformしている)座標をデバイスにしてから使用する必要があります。これは次のことにつながります。itransform

/cpa 2 array def           % literal array for storing
/cpx cpa cvx def           % executable version of same array
/cps { currentpoint transform cpa astore pop } def   % save currentpoint
/cpr { cpx itransform moveto } def                   % return to currentpoint

これにより、CTM が変更された場合でも、同じデバイスの場所に戻ります。

于 2013-03-03T07:16:18.183 に答える