使用Postscript中的可执行数组在堆栈上推送多个值

时间:2013-02-26 02:45:20

标签: postscript

我在Postscript中做了一些表单,有时我需要将当前点保存到变量中,所以稍后我可以方便地将x y值放在堆栈上以进行移动。这不是那么简单。我正在寻找一个将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。

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

3 个答案:

答案 0 :(得分: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值存储在单独的变量中,但这种方法的不雅使我想出了这种方法。如果有人知道这是某个关键字下的主题,请告诉我们。

答案 1 :(得分:1)

你可以这样做。如果您打算定义自己的函数,首先应该定义自己的字典并开始将它放在字典堆栈的顶部

在字典中定义一个2元素数组cpa来保存x,y define /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并保存/恢复。这些也许就是你真正追求的。

答案 2 :(得分: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已更改,也会返回相同的设备位置。