1

我在 Postscript 中做一些表格,有时我需要将当前点保存到一个变量中,所以以后我可以方便地将 xy 值放在堆栈上进行移动。这不是那么简单。我正在寻找一个将 x 和 y 都存储到单个变量中的过程。

假设你在 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 留在堆栈上。

如何创建一个将当前点捕获到一个变量中的过程,该变量将两个值放在运行时确定的堆栈上?

4

3 回答 3

2

以下将在运行时创建一个过程,该过程将在调用时将两个值放入堆栈:

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

这将在堆栈上留下 72 720 72 720。发生的情况是 cp 的定义首先用两个值填充了一个数组。它是可执行的,因此当调用 cp 时,每次调用时都会将两个存储的值压入堆栈,而不管当前点位置的变化。

当然,这样做的用处不仅仅是到达一个明确的点,而是在执行期间捕获一个点。如果代码片段是

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 定义/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。

您可以定义相同的数组两次,使一个引用文字和另一个可执行。重用相同的数组而不是丢弃和分配新数组稍微优雅一些​​。

/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 回答