使用过程作为ReusableStreamDecode过滤器的数据源

问题描述

访问根据PostScript规范(第124页),解码过滤器的数据源可以是一个过程。

它说:

该过程必须在操作数堆栈上返回可读字符串 包含任意数量的数据字节。过滤器弹出此字符串 从堆栈中提取数据,并将其内容用作过滤器的输入。重复此过程,直到 过滤器遇到数据结束(EOD)。

这是一个示例PS文件,其中使用字符串文字作为数据源:

%!

/myDataSource (Hello ABC!) /ReusableStreamDecode filter def

% testing random access
myDataSource dup 6 setfileposition read {==} if % 65 A
myDataSource dup 0 setfileposition read {==} if % 72 H
myDataSource dup 8 setfileposition read {==} if % 67 C

如何精心设计PS程序,以用作数据源而不是字符串?这样,我想回避PostScript字符串的大小限制(65535个字符)。 (毕竟,我想用一个/FunctionType 0项定义一个/DataSource <file>函数,其中<file>一个可重定位的文件对象,大于字符串大小的限制。)

解决方法

此解决方案基于用户article指向的beginner6789

从本质上讲,数据是作为字符串数组提供的,将上限扩展到64K²= 4G的数据,这是相当多的。 (PostScript数组具有65535个元素的相同限制,例如PostScript字符串。)

替换原始代码中用作数据源的单个文字字符串的过程一次从数组中获取一个字符串,并在由过滤器调用时将其压入操作数堆栈。我们需要跟踪最后检索到的元素的数组索引。索引变量在userdict中定义,并在执行过程时更新。另外值得注意的是,必须将空字符串()作为数组的最后一个元素放置。它将数据终止信号发送给过滤器:

%!

/myDataArray [(Hello) ( ) (A) (BC) (!) ()] def
userdict /idx 0 put

/myDataSource {myDataArray idx get /idx idx 1 add store} /ReusableStreamDecode filter def

% testing random access
myDataSource dup 6 setfileposition read {==} if % 65 A
myDataSource dup 0 setfileposition read {==} if % 72 H
myDataSource dup 8 setfileposition read {==} if % 67 C