PostScript当前图形状态实现

3
我有一个关于PostScript中当前图形状态和图形状态堆栈的问题。
在我的代码中,我现在有一个表示当前图形状态的堆栈。 当我初始化解释器时,它会创建一个新的GraphicsState对象并将其添加到“gsstack”中。
我的当前图形状态被实现为:“gsstack.Peek()”,它始终返回最顶部的图形状态。
使用gsave操作符,我创建了当前图形状态的克隆,并将其推送到“gsstack”上,这样我就有了一个新的最顶部的图形状态(这意味着我有了一个新的当前图形状态对象)。
现在用grestore操作符还原,它从http://www.tailrecursive.org/postscript/operators.html#grestore读取。
“将当前图形状态设置为图形状态堆栈中最顶部的图形状态,并将该状态从堆栈中弹出。”
那么这个grestore是如何工作的呢?因为我的当前图形状态已经是最顶部的图形状态了...我应该把它从堆栈中弹出吗?

我的实现有问题吗?当我初始化解释器时,我应该创建一个新的当前图形状态对象,但不将其添加到“gsstack”中,只有在调用gsave运算符时才将其推送到“gsstack”中吗?

提前致谢。


请使用正确的PostScript参考手册http://www.adobe.com/products/postscript/pdfs/PLRM.pdf,而不是第三方教程。 - piokuc
最顶层的图形状态始终是当前的图形状态。混乱的信息。https://dev59.com/g2XWa4cB1Zd3GeqPKz25#11139870 - juFo
如果对您有用,我在C语言中提供了一个基本完整的Level-1解释器此处(它缺少一些非常难的运算符,如definefont)。 - luser droog
1个回答

0

是的,grestore 只是弹出图形栈。

就像字典栈底部应该始终有 systemdict 和 userdict(至少),图形栈上始终应该有至少一个图形状态。因此,如果 grestore 在栈上只找到一个状态,它应该抛出错误(就像 end 应该在只找到永久字典(Level-1 的 systemdict 和 userdict,添加 Level-2 的 statusdict 和 globaldict)时抛出错误一样)。

但是,您可能希望以不同于其他堆栈的方式实现图形栈,因为它也受到 saverestore 的影响。 restore 应该弹出比最后一个 save 更近的所有状态。如果图形栈被实现为数组或字典的链接列表,则 restore 将在没有任何额外麻烦的情况下完成其工作。

来自 PLRM,第三版:

– grestore –
将当前图形状态重置为图形状态堆栈顶部的状态,并弹出图形状态堆栈,恢复与匹配的gsave操作时生效的图形状态。该运算符提供了一种简单的方法来撤消复杂的转换和其他图形状态修改,而无需逐个重新建立所有图形状态参数。
如果堆栈上最顶部的图形状态是使用save而不是gsave保存的(也就是说,自最近的未匹配save以来没有进行gsave操作),则grestore会将该最顶部的图形状态还原,但不会从堆栈中弹出它。如果没有未匹配的save(这只能在未封装的作业期间发生),并且图形状态堆栈为空,则grestore没有任何效果。
您可能希望先忽略save和restore,只关注gsave和grestore(以及其余的图形功能)。save和restore变得非常复杂。我已经多次重新设计我的解释器,试图让它们正常工作。

1
如果您启动解释器,您将拥有一个图形状态堆栈,其中包含一个默认的图形状态。当前的图形状态不直接查看 .Peek() 堆栈,而是具有图形状态堆栈中最顶部项的副本。 因此,解释器具有一个默认的GSStack和一个当前图形状态中该GS的副本。 - juFo
这似乎可以为active gstate制作副本。但是使用.Peek()也应该可以。对于我的解释器,我使用了Cairo进行图形处理,它有自己的内部gstate堆栈。因此,使用gsave/grestore使保存/恢复变得困难。 - luser droog
但是 Peek() 看起来并且使用的是您放置在堆栈上的最后一个项目。这听起来不好? :s - juFo
当前的图形状态是堆栈上的顶部状态。使用Peek()似乎是最简单的方法。但是通过制作副本并更直接地访问它,可能会获得性能提升。我建议您首先使用Peek(); 但如果分析表明Peek()是性能瓶颈,则可以考虑拥有一个CurrentGState对象,并在gsavegrestore中更新它。 - luser droog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接