什么是的PostScript词典,以及如何对它们进行访问(通过Ghostscript的)?(What

2019-06-25 15:59发布

我平时看ghostscript作为一个命令行工具; 但是,我从来没有停止在设置和目前有选择的绝对量惊讶-这是由于这样的事实, ghostscript是一个完全成熟的PostScript语言解释(我经常忘记)。

例如,在查询Ghostscript的默认选项/输出装置的设置(如“pdfwrite”或“tiffg4”) ; 一个人学会如何检索给定输出设备的默认选项。 不过,我想知道的是 - 在这些选项涉及到所谓的PostScript词典?

或者,把它换句话说 - 是什么的PostScript词典; 并没有什么设施ghostscript有,查询(也可能)修改这些数据?

Answer 1:

说得最简单的术语:PostScript里,一本字典是关键(名称)+值对的列表。 字典允许PostScript解释程序查找是否存在的关键和获取它的价值在任何程序中使用它。 该解释还可以创建按键,存储或修改值,甚至创建完整的自定义词典(由PostScript代码的处理决定)。 键通常是类型名称 (但也可以是其他任何类型的,以及与的除外)。

这些词典中的两个必须始终存在,对于PostScript解释的任何实现:

  • systemdict这一个拥有预先定义的PostScript运营商(和实现,以让他们做什么的PostScript规范期望它们)。

  • userdict这一个保持的PostScript程序的变量和程序(认为其由语言定义的操作符和程序定义的值和参数的组合构成“程序”是指从函数或子程序)。

关于名字一个字:名称是什么其他的编程语言是uniq的标识符 (他们是区分大小写)。 这些标识符可能是变量或方法的名称。 它们可以由ASCII的256个字符的任意组合(但他们没有字符串 )。

正如你可能知道,PostScript是一个堆栈取向的语言。 它使用了几个栈:

  • 操作数堆栈此堆栈保存每个单个操作数和中间操作的每一个的结果(转向最后的结果暂时入操作数堆栈的最上面的元素)。

  • 字典栈正如其名说:这堆仅持有字典。 作为这种叠层限定用于任何键/名称查找当前上下文。

  • 执行堆栈这一个容纳可执行对象,当前正在执行即为主程序文件 。 如果解释器中断当前对象的执行时,它把被中断的对象到该堆栈​​。 一个对象被完全执行之后,将其从堆栈中取出并执行与所述一个是最顶部的现在仍在继续。

  • 图形状态栈此堆栈托管用于图形元素的喷射当前上下文:当前线宽设置,当前字体,当前彩色或灰度值,电流路径...当前图形状态可以被保存( gsave )和恢复( grestore )以后。 最顶端的图形状态始终是当前图形状态

所有这些堆栈是相互独立的。 然而,操作数,词典和图形状态栈是的PostScript程序的控制下(即,可以通过将其进行操作)。 执行堆栈是解释的独有财产。

对于每个堆栈有某些限制(作为元素可以存储在其上的数等)。 的PostScript知道哪些可以操纵堆栈操作符:把一个新的元素在栈中,取出最上面的元素( pop ),重复最上面的元素( dup ),洗牌堆栈(元素的顺序roll ),交换两个顶级-moste元素( exch ),相当一些(一个很好的介绍成PostScript编程是从Adobe的“蓝皮书”)。

正如我已经说过,词典有自己的堆栈 ,它拥有所有词典PostScript解释可以使用。

在该叠层可以有字体的单独的字典,或者任意数量的词典的程序的PostScript想要创建(使用dict关键字)和私人使用,或一些字典特定于某个PostScript解释,如Ghostscript的。

systemdict始终是最底层的一个; 以上这是userdict 。 这两个不能被从字典堆栈中移除,何在所有其他的人可以经受任何堆栈操作操作者(如pop其从堆栈中移除最上面的元素)。

每当解释正在寻找一个名字,它搜索字典对于这个名字,从最顶层的字典。 因此userdict之前搜索systemdict 。 只要名字被找到(关键),解释停止搜索,并使用该键(或者更确切地说,值其持有)。 这种架构的结果是程序员的PostScript可能会覆盖在被预定义-任何PostScript操作符systemdict用他自己的变体。

此外,一些字典可以是用于PS程序“私人”(无访问,如字体字典)或“只读”。


更新 -更多的答案:

  • 我怎样才能获得包含在其他词典列表userdictsystemdict
  • 一个Ghostscript的电力用户怎样才能打印出的字典的内容?


Answer 2:

其他答案已经涵盖了“什么是字典?” 你的问题的一部分。 现在,让我们来“的Ghostscript如何访问它们?”

也许问题应该是:“我怎样才能(电力用户,开发者,一个怪胎...)访问它们?”

您可以通过编写一个简单的PostScript程序的一行打印出上已知到您的PostScript解释程序(可能是Ghostscript的)的任何访问字典的内容 - 或者通过简单地调用解释(Ghostscript的)与移交的程序代码命令行( -c ... )。

你只需要知道相应的字典这个名称。

让我们来看看一个有趣的这样的内部Ghostscript的字典,叫.distillersettings

gs \
 -dNODISPLAY \
 -c ".distillersettings {exch ==only ( ) print ==} forall quit"

结果:

/default -dict-
/prepress -dict-
/PSL2Printer -dict-
/ebook -dict-
/screen -dict-
/printer -dict-

这可能不会第一眼就告诉你了。 但是你可能认识一些在字典中的键名: /prepress/printer/screen/ebook ...

所有这些,你可以在命令行的Ghostscript使用,要求预先定义的一组设置,当你想通过做输出-sDEVICE=pdfwrite (Ghostscript的“Distiller'酷似功能)。 要问这样的一组设置,只需添加-dPDFSETTINGS=/printer的命令行。

在第二眼,现在你将看到的内容.distillersettings字典本质上是一组6个字典。 这是一个“词典的词典”。

字典内容不是默认(不与上面的PostScript代码)打印出来。 但是,如果你想要他们,你可以使用一个叫做特定的Ghostscript-程序===而不是标准的PostScript语言操作==在上面的命令。 这个程序的行为与== execpt,它也扩大了字典和打印所有键:其中包含的值对。

要小心与===程序: -dict-你试图扩大可veeeeeery长,可能会导致你失去你的视力。 :-)

在我国目前的情况下,但它仍在可控范围内:

gs \
 -dNODISPLAY \
 -c ".distillersettings {exch ==only ( ) print ===} forall quit"

现在输出的是:

 /default << /Optimize false /DoThumbnails false /PreserveEPSInfo true /ColorConversionStrategy /LeaveColorUnchanged /DownsampleMonoImages false /EmbedAllFonts true /CannotEmbedFontPolicy /Warning /PreserveOPIComments true /GrayACSImageDict << /HSamples [2 1 1 2] /VSamples [2 1 1 2] /QFactor 0.9 /Blend 1 >> /DownsampleColorImages false /PreserveOverprintSettings true /CreateJobTicket false /AutoRotatePages /PageByPage /NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats] /ColorACSImageDict << /HSamples [2 1 1 2] /VSamples [2 1 1 2] /QFactor 0.9 /Blend 1 >> /DownsampleGrayImages false /UCRandBGInfo /Preserve >>
 /prepress << /DoThumbnails true /MonoImageResolution 1200 /ColorImageDownsampleType /Bicubic /PreserveEPSInfo true /ColorConversionStrategy /LeaveColorUnchanged /GrayImageDownsampleType /Bicubic /EmbedAllFonts true /CannotEmbedFontPolicy /Error /PreserveOPIComments true /GrayImageResolution 300 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.15 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /ColorImageResolution 300 /PreserveOverprintSettings true /CreateJobTicket true /AutoRotatePages /None /MonoImageDownsampleType /Bicubic /NeverEmbed [] /ColorACSImageDict << /ColorTransform 1 /QFactor 0.15 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /CompatibilityLevel 1.4 /UCRandBGInfo /Preserve >>
 /PSL2Printer << /DoThumbnails false /CompatibilityLevel 1.2 /TransferFunctionInfo /Preserve /MonoImageResolution 1200 /PreserveEPSInfo true /CompressFonts true /ColorImageDownsampleType /Bicubic /GrayImageDownsampleType /Bicubic /ColorConversionStrategy /LeaveColorUnchanged /EmbedAllFonts true /ColorACSImageDict << /ColorTransform 1 /QFactor 0.15 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /CannotEmbedFontPolicy /Error /PreserveOPIComments true /CompressPages true /GrayImageResolution 600 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.15 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /ColorImageResolution 600 /PreserveOverprintSettings true /AutoRotatePages /None /MonoImageDownsampleType /Bicubic /ASCII85EncodePages true /MaxViewerMemorySize 8000000 /NeverEmbed [] /PreserveHalftoneInfo true /UCRandBGInfo /Preserve >>
 /ebook << /DoThumbnails false /MonoImageResolution 300 /ColorImageDownsampleType /Bicubic /PreserveEPSInfo false /ColorConversionStrategy /sRGB /GrayImageDownsampleType /Bicubic /EmbedAllFonts true /CannotEmbedFontPolicy /Warning /PreserveOPIComments false /GrayImageResolution 150 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.76 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> /ColorImageResolution 150 /PreserveOverprintSettings false /CreateJobTicket false /AutoRotatePages /All /MonoImageDownsampleType /Bicubic /NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats] /ColorACSImageDict << /ColorTransform 1 /QFactor 0.76 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> /CompatibilityLevel 1.4 /UCRandBGInfo /Remove >>
 /screen << /DoThumbnails false /MonoImageResolution 300 /ColorImageDownsampleType /Average /PreserveEPSInfo false /ColorConversionStrategy /sRGB /GrayImageDownsampleType /Average /EmbedAllFonts true /CannotEmbedFontPolicy /Warning /PreserveOPIComments false /GrayImageResolution 72 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.76 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> /ColorImageResolution 72 /PreserveOverprintSettings false /CreateJobTicket false /AutoRotatePages /PageByPage /MonoImageDownsampleType /Average /NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats] /ColorACSImageDict << /ColorTransform 1 /QFactor 0.76 /Blend 1 /HSamples [2 1 1 2] /VSamples [2 1 1 2] >> /CompatibilityLevel 1.3 /UCRandBGInfo /Remove >>
 /printer << /DoThumbnails false /MonoImageResolution 1200 /ColorImageDownsampleType /Bicubic /PreserveEPSInfo true /ColorConversionStrategy /UseDeviceIndependentColor /GrayImageDownsampleType /Bicubic /EmbedAllFonts true /CannotEmbedFontPolicy /Warning /PreserveOPIComments true /GrayImageResolution 300 /GrayACSImageDict << /ColorTransform 1 /QFactor 0.4 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /ColorImageResolution 300 /PreserveOverprintSettings true /CreateJobTicket true /AutoRotatePages /None /MonoImageDownsampleType /Bicubic /NeverEmbed [] /ColorACSImageDict << /ColorTransform 1 /QFactor 0.4 /Blend 1 /HSamples [1 1 1 1] /VSamples [1 1 1 1] >> /CompatibilityLevel 1.4 /UCRandBGInfo /Preserve >>

还没那么好。 因此,让我们设法得到它更好。 我们可以做到这一点的方法是修改我们的PostScript代码:我们告诉它现在访问.distillersettings字典,并从它的关键之一的值(让我们使用/screen )。 因为我们知道,价值是另外一个字典,我们知道我们会得到另一组关键的:我们将能够我们之前的方式相同的格式值对:

gs \
 -q \
 -dNODISPLAY \
 -c ".distillersettings /screen get {exch ==only ( ) print ===} forall quit"

现在,这看起来更好,不是吗? 见自己:

/DoThumbnails false
/MonoImageResolution 300
/ColorImageDownsampleType /Average
/PreserveEPSInfo false
/ColorConversionStrategy /sRGB
/GrayImageDownsampleType /Average
/EmbedAllFonts true
/CannotEmbedFontPolicy /Warning
/PreserveOPIComments false
/GrayImageResolution 72
/GrayACSImageDict -dict-
/ColorImageResolution 72
/PreserveOverprintSettings false
/CreateJobTicket false
/AutoRotatePages /PageByPage
/MonoImageDownsampleType /Average
/NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica     /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats]
/ColorACSImageDict -dict-
/CompatibilityLevel 1.3
/UCRandBGInfo /Remove

当你的锐利的眼睛可能已经发现:一些键值再次字典 。 你可以自由地再次使用上面的命令,这时候用===代替第二的==来解决的奥秘/GrayACSImageDict -dict-等可保持隐藏...

在任何情况下,现在你知道你打字保存只需使用什么-dPDFSETTINGS=/screen ,而不是列举嵌入在这一切的单一参数/screen字典...

而且你也知道,你需要重写如果您想一般的“屏幕”的输出质量,但与所有的字体嵌入获得什么区别单个值:

gs \
 -o out.pdf \
 -sDEVICE=pdfwrite \
 -dPDFSETTINGS=/screen \
 -c "<</NeverEmbed [ ] /AlwaysEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats]>> setdistillerparams" \
 -f input.pdf

您可以探索了很多有趣的事情这条路大约Ghostscript的内部,只要你知道它使用字典的名称。 :-)



Answer 3:

好的答案的很多了,但没有人提到了这一点:

当调用ghostscript的,在-d-s选项创建systemdict初始定义。 这可以让你做你的后记程序的参数调用 。

使用-dname[=token]设置值到零,或一个数字(或任何其他单个后记令牌)。 使用-sname=string设置字符串值(在大多数情况下工作,以及作为名字)。

你可以操作所有的堆栈与经营权在一定程度上。

  • token推到操作数栈从字符串或文件(这是什么解释循环使用消耗节目流,所以这是你所使用的是否通过文件或直接从键盘上输入代码)
  • pop从操作数栈丢弃
  • begin推字典栈
  • end从字典堆栈弹出
  • runexec%procedure-invocation推到堆栈EXEC
  • exitstop弹出或清除EXEC栈
  • gsave在图形压栈gstate
  • grestore流行的图形堆栈
  • save推动所有VM-内容的拷贝(所有类型的字典和数组,而不是字符串)
  • restore快退的内存来保存状态(恢复所有类型的字典和数组到以前的状态)

字典,是复合对象,继承了一些通用于所有复合对象运营商。

  • -typename-创建对象,例如dict
  • length对象的报告大小
  • put插入元素
  • get检索元素
  • copy用另一对象内容的对象
  • forall做一下每个元素
  • *load候补检索元件(字典, load执行与搜索where ,然后get ;对于阵列, aload溢出的操作数堆栈上的阵列的整个内容)
  • *store备用插入元件(用于字典, store执行与搜索where ,然后put如果找到,或def如果不是;对于阵列, astore填充堆栈上从对象阵列)

为了这套房,词典添加

  • def投入当前字典(字典栈顶)
  • known查询字典的元件
  • where查询所有字典对于元素
  • maxlength不再有趣后PS Level 2增加自动扩展词典和GC
  • dictstack的dictstack复制到一个数组(也许你想搜索自下而上,你可以!)
  • 名称不是由斜线/是自动load ED,并且如果可执行,执行
  • //token被构造后记目的是通过一个双斜线前面任何名称都是load ED和代入程序阵列。 这是非常强大的,因为你可以模仿Lisp的宏。

编辑:还有一两件事。 创建一个字典的时候有一个时间/空间权衡,当你选择了字典大小。 字典是一个哈希表几乎可以肯定实现(在所有,但最简单的解释),而且大多数散列函数可避免碰撞时的表大约是半满的(经验法则: 使用双级速度http://stardict.sourceforge.net/Dictionaries.php下载 )。 由于2级,当然,词典会自动在添加大小+ 1个元素,推测是通过分配K *大小的新词典生长(其中,k是大概1.5或2); 但手动控制大小可以给你一个速度提升。 在1级,如果你不乘引用您的字典,你可以安装一个替代dictfullerrordict成长的字典并重新执行看跌期权(或DEF或其他)。 由于二级做到这一点在内部,它可以取代所有引用。



Answer 4:

如果您想获得其包含在其他词典列表systemdictuserdict的字典,只需要运行:

for _dict in userdict systemdict; \
   do \
   gs \
     -dNODISPLAY \
     -c "${_dict} {exch ==only ( ) print ==} forall quit"; \
done \
| awk '{print $1, $2}' \
| grep -- -dict- \
| sort

这将产生你可以调查潜在的“有趣”的名字字典名称的排序列表。

你会发现这样的名字,像FontmaplocaldictAdobeGlyphListuserparams.eexec_param_dict.substitutefamiliesEncodingDirectorycolorspacedict.distillerparamkeysdevicedict.symbol_list ,...

随着这些名字的你可以看一下有关的Ghostscript的内部运行FE或多或少有趣的信息和花絮:

gs \
  -q \
  -dNODISPLAY \
  -c "Fontmap {exch ==only ( ) print ==} forall quit"

正如你所看到的,甚至为Ghostscript使用的FONTMAP存储在字典中。 我在这里的成绩的提取物在本地是这样的:

[....]
/Arial [/ArialMT]
/Arial,Bold [/Arial-BoldMT]
/AvantGarde-Book [/URWGothicL-Book]
/Bookman-Demi [/URWBookmanL-DemiBold]
/Calligraphic-Hiragana [(fhirw.gsf)]
/Calligraphic-Katakana [(fkarw.gsf)]
/Charter-Bold [/CharterBT-Bold]
/CharterBT-Bold [(bchb.pfa)]
/Courier [/NimbusMonL-Regu]
/Courier-Bold [/NimbusMonL-Bold]
/Courier-BoldOblique [/NimbusMonL-BoldObli]
/Courier-Oblique [/NimbusMonL-ReguObli]
/Helvetica [/NimbusSanL-Regu]
/Helvetica-Bold [/NimbusSanL-Bold]
/NewCenturySchlbk-Bold [/CenturySchL-Bold]
/Palatino-Roman [/URWPalladioL-Roma]
/Symbol [/StandardSymL]
/Times-Bold [/NimbusRomNo9L-Medi]
/TimesNewRoman,Bold [/TimesNewRomanPS-BoldMT]
/Utopia-Regular [(putr.pfa)]
/ZapfDingbats [/Dingbats]
[....]

小心的注意事项:以上是不实际的,你就会有,当你要处理的FONTMAP 文件的Ghostscript应该使用(一般或特定任务)使用的文件格式。 对于该格式,请阅读为例FONTMAP文件中的注释为运为Ghostscript。 上述列表的表示FONTMAP如Ghostscript的存储在其内部字典



Answer 5:

在PostScript中Dictionaires是一个“容器”的对象,它们在本质上是对的列表,一个键和一个值。 见PostScript语言参考手册的更多细节,在第三版特别是部分3.3.9。

词典通常用于一组参数传递给PostScript操作符或功能,例如操作者的图像可以采取一个字典的说法,但他们同样可以很好简单地存储。

字典可以访问的权限,因此可能有只读字典,其值可以进行检查,但不能修改和字体字典可以是“无访问”,以防止被的PostScript提取的轮廓数据。

条目,其中不只读或无访问权限可以被随意修改的字典。



文章来源: What are PostScript dictionaries, and how can they be accessed (via Ghostscript)?