PostScript(PS/EPS 格式)讲解
作者:bobob
一、PostScript概述
Postscript既是一种页面描述语言,也是一种高级解释型脚本语言。由于它与设备的无关性,使得它无论在那种平台上,都能忠实的再现原貌,从而被广泛应用于打印出版行业,同时由于它是一种解释型脚本,所以它也可以像一般编程语言一样用来解决某些问题。
和我们熟悉的pdf文件相比,两者有几个明显的区别:
1.       pdf有严格的文件结构(文件头,所有对象,交叉引用表,文件尾,线性化pdf也有固定格式)和文档结构(由catalog穿起来的逻辑结构),ps则没有这些;
2.       ps的数据类型有十几种,pdf只有8种;
3.       ps有一般编程语言所具有的结构控制条件语句,比如if,ifelse,for,forall,loop,以及function等等,而pdf没有;
4.       pdf最终是要显示出来给别人看的,ps不仅限于这个目的,它还可以做为脚本实现一定非显示的功能;
5.       ps语言中的标准操作符有400多个,有的一个操作符有好几种使用方式(参数类型和数量不同),而且ps没有保留字,这些标准操作符完全可以通过ps脚本改变其原来的含义;
6.       ps文件一般都是没有加密的,所以文件很大,pdf相对要小很多。
通常,一个postscript语言的阅读器,应该包含以下几个大部分:扫描器,解释器,操作数栈,执行栈,字典栈,图形状态栈,虚拟内存区,字体处理块,颜色处理块,以及最后的输出功能,下面将详细说明。
二.Postscript详细介绍
1. 基本类型的数据结构
简单 OBJECTS
复合 OBJECTS
boolean
array
fontID
dictionary
integer
file
mark
gstate (LanguageLevel 2)
name
packedarray (LanguageLevel 2)
null
save
operator
string
real
Array:能容纳不同类型的对象;可以通过index来访问其中的元素;对array的访问必须有下表安全检查,array长度有最大实现限制;要支持嵌套;值的存储符合复合对象的特征。
String:它的元素值必须是0-255之间;长度受程序实现的限制;要能处理转义字符’/’;值的存储要符合复合对象的特征。
Dictionary:用来存储键-值对,要实现在字典中插入一个条目;能查询一个键并得到它关联的值;字典在创建的时候要指定最大条目数,当插入一个条目的时候超过最大条目数,ps level1返回一个dictfull错误,level2以上则自动扩展,最大条目数受字典实现的限制;能支持和字典相关的操作符的实现;值的存储要符合复合对象的特征。
File:解释器和运行环境之间用来交流的一个可读或可写的字符流。要支持像磁盘文件这样可以永久保存的类型,也要支持动态生成的类型;一个file对象要创建并打开一个文件;支持其他操作符的读写操作;支持类似read,readline,write,writeline等等的操作;
Save:save操作符获取当前local虚拟内存的状态快照并返回描述此快照的save object,restore则把local虚拟内存的状态恢复到save产生的快照状态。Restore要实现以下功能:丢弃自从对应的save以来所有在local虚拟内存上产生的对象,归还占用的空间;恢复save时local虚拟内存中的所有复合对象(不包括string);隐式调用grestoreall操作符,把graphics state的状态恢复到save的时候的状态;关闭自save以来所有打开的文件(local虚拟内存起作用的时候打开的)。Restore不会影响操作数栈,字典栈,执行栈,以及global虚拟内存。Save 和 restore可以嵌套。
Gstate:一组图形控制参数,分为两大类:设备无关的包括CTM,position,path,clipping path,clipping path stack,color space,color,font,line width,line cap,line join,miter limit,dash pattern,stroke adjustment;设备无关的包括color rendering,overprint,black generation,undercolor removal,transfer,halftone,flatness,smoothness,device。要实现以上特性的存取操作。
2. 扫描器。
这个是实现浏览器的基础,从字符流中按照postscript语法解析成一个一个的对象,ps‘编码方式有3种:ASCII, binary token, 和 binary object sequence。其中 ASCII的编码方式很普遍,所以只考虑这种方式的编码。扫描器要能识别一下几种ps元素:
A.空白符。除了注释和串中的以外,空白符当作分割对象的单位,连续的空白符当作一个处理; CR和LF以及CR+LF都当作换行处理。
B.注释。除了在字符串中, %之后直到换行的所有字符。
C.数字。包括 3中类型:符号整数(比如0,+5,-3),实数(比如-.002, 34.5,-3.62, 123.6e10, 1.0E-5, 1E6,-1., 0.0),指数(比如 8#1777,16#fff,2#100)。
D. string。有3种形式:()包括的字面文本;<>包括的十六进制编码文本;<~~>包括的ASCII-Base85编码数据。其中()中的数据处理依据以下原则:如果()内包含配对的(),则不需要特殊处理;如果有单个的(或),用/来处理;用/处理的其他转义字符。
E.名字。由常规字符组成又不能解释为数字的词法单位就当作名字处理。除了空白符和界定符之外的所有字符都可以出现在名字中。 /引导一个字面名字,但它本身不是名字的一部分。
F.数组。 [和]界定一个数组,从[开始收集元素,]则构造一个包含这些元素的数组对象。[和]是操作符。
G.过程。 {和}界定一个可执行数组。
H.字典。 <<和>>构造一个字典,过程和[]几乎一样,里面包括key1 value1 key2 value2… keyn valuen这样的对,构造后的字典由解释器放入字典栈。
3. operand stack execution stack dictionary stack graphic state stack clipping path stack
这5个栈和后面的虚拟内存以及gstate是postscript执行环境的主要部分。
A.操作数栈。
可以存放任意postscript对象,因为postscript是操作数在前,操作符在后的语法规则,所以解释器遇到操作数都是先压入操作数栈,直到遇到操作符再从栈顶拿操作数。同时,操作数栈中还可以存放执行的中间结果。操作数栈直接被ps解释器控制,大多数ps操作符可以直接push和pop操作。
B.执行栈。
存放可执行的对象,当解释器延迟当前可执行对象去执行另外一个对象的时候,就把当前可执行对象压入执行栈,等执行了之后再执行它。这个也相当于postscript程序的调用堆栈。受ps解释器控制,ps程序可以读,但是不能写。
C.字典栈。
只存放字典对象,从最底往上,3个对象依次是systemdict,globaldict,userdict。其中systemdict是一个只读的字典,定义了所有标准的操作符(400多个)globaldict和userdict包括了用户自己在虚拟内存中定义的一些变量和操作符,配合save等操作符使用。直接受ps解释器控制,但是只能保存dictionary对象,且最下面的3个字典(systemdict,globaldict,localdict)不能被pop,只有bengin,end,clearstack可以改变dictionary stack。
典型示例:
/average {add 2 div} def
40 60 avergage
执行步骤:
1.把名字average和过程{add 2 div}压入操作数栈
2.遇到def后,查找字典栈,如果这个操作符没有被重新定义,则它的意义是把操作数栈栈顶的两个元素(average和{add 2 div})pop出来,在当前字典中添加一个条目,key是average,value是{add 2 div}。
3.把40和60依次压入操作数栈。
4.遇到average,在字典栈中查找,执行它关联的值(这里是){add 2 div}。这个步骤的执行过程是先执行add,从操作数栈栈顶pop出两个数(40和60),相加,然后把结果100压入操作数栈;遇到2压入操作数栈;遇到div,在字典栈中查找,如果它没有被重新定义,则pop出操作数栈栈顶的两个数,做除法运算,然后把结果50压入操作数栈。
D.图形状态栈。
用来维护一组控制文本和图像显示状态的参数。
设备无关类参数:
1.CTM。当前转换矩阵,把位置从用户坐标转换到设备坐标。
2.position。用户空间当前点的坐标。
3.path。由path构造操作符创建并增加,并隐含的做为类似fill,clip,stroke等操作符的参数。
4.clipping path。设置当前的裁剪区域。
5.clipping path stack。一个clipping path的stack,存放由clipsave保存而且没有被cliprestore释放的clipping path。
6.color space。要被解释的颜色值的种类,比如Device Gray。
7.color。描绘操作符使用的颜色,和color space有关,一般1-4个值。
8.font。用字典来表示当前字体的绘图形状集合。
9.line width,line cap,line join,miter limit。线条相关的特性。
10.dash pattern。线条被stroke的时候,线的虚实类型描述。
设备相关参数:
1.color rendering。如何把 CIE-based color 转换成 device color 的一组参数。
2.overprint。是否覆盖周边颜色。
3.black generation。RGB转换成CMYK的时候,用来产生黑色的一个过程。
4.undercolor removal。计算CMY减少的总量,用产生的黑色做补偿。
E.clipping path stack。由clipsave和cliprestore控制的一个栈,存放clipping path。由于这个栈是graphics state stack的一部分,所以grestore和setgstate会替换整个clipping path stack。
4. 解释器。
在扫描器分析出一个对象和它的属性、类型的时候,解释器就要负责解释它。主要包括一下几个方面:
A.对注释的处理。遇到不是串中的%时,过滤掉%到换行符(或文件结束符)之间的所有字符,当作一个空白字符处理。
B.对数字的处理。分析出来的数字一律压入操作数栈;
C.对名字的处理。名字有3类:前面有/的文法名字,无前缀的可执行名字,带前缀//的立即替换名字。第一种名字压入操作数栈,第二种名字压入执行栈,第三种名字由解释器查找字典,找到后压入操作数栈。
D.对字典的处理。当<<执行时,把一个mark对象压入操作数栈,>>执行时这个字典会被创建,然后压入字典栈。
E.对数组和打包数组的处理。解释器遇到数组时,会顺次执行数组里面的元素。
F.对过程对象的处理。解释器遇到过程对象的时候并不会立即执行,而是先压入操作数栈,等到明确被调用时才会被执行。
5. 虚拟内存。
虚拟内存是psotscript中的一个特殊概念,没有规定物理实现方式,但不管怎么实现,都要符合一下原则。虚拟内存包括4个部分:
A.local虚拟内存。Local虚存是一个类似栈的存储池。在它上面申请内存或修改变量都受制于save和restore。一般而言,local虚拟内存主要是维护当前页面用到的一些参数和变量,作用范围是当前页面(save和restore之间)。
B.global虚拟内存。Global虚拟内存是一个没有固定规律的存储池,在一个程序中,在global虚存中申请内存或修改变量不受save和restore影响。一般是维护整个文件级别的一些参数,用来保证每页开始的时候初始状态都是相同的。
C.local和global之间的交互。包括local和global状态的转变,local和global之间存储数据的相互操作的实现等等。
D.Local虚拟内存在save-restore机制影响下的行为。当一个restore发生时,自上一个save以来,所有在local虚拟内存中申请的内存都会被释放,所有打开的文件都要关闭,同时会恢复gstate的状态。 

PostScript(PS/EPS格式)讲解相关推荐

  1. 如何将Visio图形转换成EPS格式【mark from百度知道】

    因为TeX系统只支持EPS格式的图形插入,但平常我们用得最广泛的是Visio,因此如何有效的转换成为了广大TeX初学者面临的一个比较棘手的问题,下面是我收集到的几种方法,个人推荐方法一.方法一:就是用 ...

  2. 如何将visio画的图转为eps格式?

    latex有时候指定需要eps格式的图片,下面讲两种转换方式适用于两种场景: 1.图中所有线条都是由visio中各元件画成的(simple) 步骤:https://jingyan.baidu.com/ ...

  3. visio的.vsd格式文件转换.eps格式文件的方法+Gsview裁剪EPS文件

    **************************************************************************************************** ...

  4. 将图片保存为.EPS格式

    (1) matlab可直接将生成图片保存为eps格式. print -fhandle -rresolution -dfileformat filename 例子:set(gcf,'paperposit ...

  5. 如何将图片保存为EPS格式

    (1) matlab可直接将生成图片保存为eps格式. print -fhandle -rresolution -dfileformat filename 例子:set(gcf,'paperposit ...

  6. 从零开始学习音视频编程技术(二) 音频格式讲解

    从零开始学习音视频编程技术(二) 音频格式讲解 原文地址:http://blog.yundiantech.com/?log=blog&id=5 1. 音频简介 前面我们说过视频有一个每秒钟采集 ...

  7. eps格式流程图制作流程

    投稿需要的Latex文档插入的eps格式流程图制作流程,先用visio画图,把它保存成pdf格式(visio可以输出pdf格式),然后用adobe acrobat pro DC(ps:一般的版本好像不 ...

  8. PDF矢量图片转为EPS格式图片的方法

    本人写论文,画图一般用的是PPT.在PPT中画好图后再导出为pdf格式文件,然后可以直接在latex中插入图片 最近有一篇论文accept了,上传最终文件时发现投稿系统不接受pdf格式的图片,矢量图只 ...

  9. matlab将图片转成eps,【MATLAB】论文图片处理(各种数据图转换成eps格式)

    最近跟eps图片杠上了..转载一个人人网上matlab到eps图片输出格式较好的方法 随着Latex在论文编辑和排版的日益普及,越来越多的人写文章都用Latex,数据图表作为论文不可缺少的一部分,如何 ...

最新文章

  1. python的flask框架显示柱状图_使用Python的Flask框架,结合Highchart,动态渲染图表(Ajax 请求数据接口)...
  2. 浅谈java内存分配和回收策略
  3. vsftp 安装日志
  4. Android P 调用隐藏API限制原理
  5. opencv videocapture读取视频cap.isOpened 输出总是false
  6. (转) shiro权限框架详解04-shiro认证
  7. linux 通过虚拟ip出路由器,linux模拟路由器实验
  8. 有趣的问题:C的表达式x == x,何时为假?!
  9. 了解信息安全管理体系的基本思路
  10. 请检查网站服务器是否正常.,请检查服务器地址是否正确
  11. 句子生成算法python实现
  12. 硕士研究生计算机专业录取分数线,全国所计算机研究生录取分数线.doc
  13. 揭秘京东文件系统JFS的前世今生,支持双11每秒约10万个对象同时读写
  14. c# 调整图片分辨率
  15. 带固态硬盘的电脑Ubuntu和Windows双系统安装
  16. 项目经理杂事多,该怎么有效的安排时间
  17. 现代c++中实现精确延时方法总结
  18. jpanel麻将自动打牌,碰牌,杠牌
  19. python编程源码
  20. 陈皓,酷壳coolshell.cn博主

热门文章

  1. 一星期学sql day1
  2. annotate()函数--matplotlib
  3. golang grpc
  4. 路由器、猫(调制解调器)和交换机
  5. KVM虚拟化技术介绍及搭建
  6. 如何去除移动磁盘写保护?
  7. memcmp和strcmp的返回值
  8. marquee标签基础及应用
  9. iPhone快捷指令查询汇率
  10. 最新的Python爬取淘宝评价的教程