我正在用Postscript做一些表格,有时我需要将当前点保存到变量中,因此以后我可以方便地将x y值放在堆栈上以进行moveto。这不是那么简单。我正在寻找一个将x和y都存储到一个变量中的过程。
假设您现在是72720。我希望一个变量,例如CP,能够存储两者。当然,如果您想存储
/cp {72 720} def
并且您将创建一个过程,该过程在被调用时将使堆栈中包含72720。但是,如果要在执行期间存储任意位置该怎么办?以下代码不起作用。
/cp {currentpoint} def
72 720 moveto
cp
100 100 moveto
cp
该代码每次都仅调用currentpoint,在堆栈上保留72 720 100 100。
您如何创建一个将当前点捕获到一个变量中的过程,该变量将在运行时确定的堆栈上放置两个值?
以下将在运行时创建一个过程,该过程将在调用时将两个值放到堆栈中:
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,将导致后记错误。接下来是一个简短的脚本程序来探索这一点。
%!
/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值存储在单独的变量中,但是这种方法的精巧之处使我想出了这种方法。如果有人知道这是使用某个关键字解决的主题,请告诉我们。
您可以做这样的事情。如果您打算定义自己的函数,则应首先定义自己的字典,然后开始将其放在字典堆栈的顶部
在字典中定义一个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并保存/恢复。这些也许是您真正追求的。
虽然我在这里喜欢(并赞成)其他两个答案,但我对同一想法略有改动,这说明了一些有趣的小角落,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
到设备坐标(相对于用户空间stable),然后再使用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已更改,这也会使您返回相同的设备位置。