从 PostScript 中计算任意 PostScript 代码的边界框

问题描述 投票:0回答:1

我希望能够运行一些任意的 PostScript 代码,并找出它的边界框是什么,以便在我再次运行时居中和/或缩放该 PostScript 代码。这需要在 PostScript 解释器的一次调用中全部发生。 (即发生在我可以发送到打印机的

.ps
文件中)

伪代码:

Run this PostScript code without drawing anything
    <some arbitrary PostScript code>
Get the bounding box of the code that just ran
Do some computations to center it, and/or scale it if it's too big
Run the PostScript code with scaling/translation, and actually draw
    <the same arbitrary PostScript code>

任意的PostScript代码可能会绘制多条路径,所以不是调用

pathbbox
那么简单。 (有没有办法将任意的 PostScript 代码块组合成一个路径,以便可以使用
pathbbox
?)

这似乎类似于这个问题,不幸的是自 1992 年以来一直没有答案。

不可接受 答案是涉及多次调用 PostScript 解释器的任何答案。 (例如使用 GhostScript bbox 设备。)这必须作为普通的 PostScript 程序在任何(*)兼容的 PostScript 解释器上运行。

(*) 要求 PostScript Level 3 是可以接受的,但要求特定实现(例如 GhostScript)是不可接受的

postscript
1个回答
0
投票

这是“可能的”但并非微不足道,答案在很大程度上取决于准确性、性能和可靠性对您的重要性,以及您准备在该项目上投入多少时间以及您的 PostScript 编程水平能力。

理论上,您可以重新定义每个 PostScript 标记操作符(例如笔划、填充、图像、所有显示变体等),而不是绘制结果,确定由该操作标记的页面区域。对于某些运算符(例如 rectfill),这是微不足道的,对于其他运算符,它会更复杂,但仍然可以通过使用 charpath 和 pathforall 来确定任何 PostScript 操作标记的区域。

现在介绍你的第一点; pathbbox 本身是不够的,因为任何 PostScript 绘图操作都可以通过剪辑来绘制,而剪辑不一定是简单的矩形。

考虑这个使用矩形剪辑的简单示例:

%!

100 100 translate

0 0 0 setrgbcolor
-45 rotate
0 0 moveto
0 100 lineto
50 100 lineto
50 0 lineto
closepath
clip
newpath

90 rotate
0 -50 translate
0 1 0 setrgbcolor
0 0 moveto
0 100 lineto
50 100 lineto
50 0 lineto
closepath
fill

showpage

为了帮助可视化正在发生的事情,让我们将剪辑绘制为黑色笔划。看起来像这样:

并呈现为:

如果我们将 pathboox 应用到填充路径,它将不会应用剪辑(并将使用 CTM 报告它的坐标),因此与实际呈现的结果相比,结果将是错误的(执行 pathbbox 然后撤消 CTM并转换为默认用户空间导致 bbox 为 64.64、64.64、170.71、170.71,而 bbox 设备以 72 dpi 返回的实际 bbox 为 100、64、171、136)。

您必须将当前剪辑与当前路径相交(如果正在绘制路径,则使用 clippath 检索当前剪辑和 currentpath 检索当前路径)或矩形路径(如果执行类似图像运算符的操作),然后工作出该交叉点的边界框,以确定 rendered.

的边界框

有其他困难;当描边线时,您需要考虑线宽以确定标记的区域,线连接可以斜接,您需要确定斜接终止的位置,曲线可以延伸到基于简单矩形边界框的边缘在他们的端点上。

所有这些问题都在渲染时通过扫描转换路径来处理。基本上这意味着将复杂的形状转换为一系列填充的矩形。在极限情况下,矩形的高度是一条扫描线(即一个像素高)。裁剪只是相交矩形的一种情况。

当然,这确实会导致精度限制,因为矩形是设备分辨率。以 72 dpi 扫描转换浅曲线的结果可能与以 720 dpi 扫描转换的结果不同。这就是 Ghostscript bbox 设备使用高分辨率的原因。

现在 PostScript 是一种编程语言,所以显然您可以在 PostScript 中进行扫描转换和矩形交集。另一方面,它也是一种解释性语言,因此相对较慢;这就是性能限制的来源。对于复杂的 PostScript 输入,扫描转换和相交矩形列表可能需要相当长的时间(并且确实会占用相当多的内存来存储矩形列表)如果执行后记。

最后的可靠性;它并不常见,但真正任意的 PostScript 可以定义它自己的序言,直接从 systemdict 中读取运算符,而不是使用当前定义(例如

/myfill systemdict /fill load def
)。这样做的 PostScript 会逃避操作员的重新定义,然后操作员将不会运行“bbox”程序并阻止它工作。

所以有a解决方案;我并不声称它是唯一的,但我不知道有更好的解决方案可以纯粹在 PostScript 和任何 PostScript 解释器中工作。我认为这将是一项艰巨的任务。

© www.soinside.com 2019 - 2024. All rights reserved.