PostScript中的Path Construction
前言
在PS中,path用来定义形状,轨迹和各种类型的区域。在程序中,使用path可以实现划线,定义填充区域的形状以及定义其他图形的裁剪框。 一个path由一组connect或disconnect的直线段和曲线段组成,一对连续定义的点才会被成为connect(第二个线段的起点就是第一个线段的终点)。一个path的线段的方向是有符号的。 一个path由一个或多个disconnect的subpath组成,每个subpath包含一组connected的线段。path的拓扑是自由的,可以是凹的,凸的,包含多个subpath描绘多个孤区域(disjoint areas不知道怎么翻译,暂且叫孤区域吧),自身任意方式相交。操作符closepath明确的把一个subpath的终点和它的起点链接,这样的subpath被成为是闭合的(closed),没有明确闭合的成为开口的(open)。path虽然不能直接当object访问,但是它的构造和使用还是在程序的控制之下。ps程序可以读出path,或者,通常用来控制paint相关的操作符。 “当前路径”(current path) “当前路径”是graphic state的一部分,path构建操作符修改的只是“当前路径”,通常是为其增加一个点,paint操作符则隐含的使用“当前路径”,gsave和grestore分别保存和恢复“当前路径”。程序里面用newpath开始一个新的path,它会把“当前路径”初始化为empty(一些paint操作符会在执行完了之后重新初始化“当前路径”),然后使用一个或多个操作符为“当前路径”添加线段。操作符的调用顺序是任意的,但是第一个操作符必然为moveto。 最后一个被加进去的节点一般被称为“当前点”(current point )。如果“当前路径”为空,则“当前点”没有定义。绝大多数操作符添加线段是从“当前点”开始的。如果没有“当前点”,则会产生一个nocurrentpoint错误。 下面是一个清单,列出了最常用的路径构造操作符。 moveto 建立一个新的“当前点”(没有添加线段到“当前路径”),因此,这个操作符创建了一个subpath。 lineto 添加一个直线到“当前路径”,使之成为新的“当前点”。 arc, arcn, arct, and arcto 添加一个圆弧到“当前路径”。 curveto 添加一个立方贝塞尔曲线到“当前路径”。 rmoveto, rlineto, and rcurveto 执行moveto, lineto, 以及curveto操作,但是通过在用户空间转换,指定一个相对于“当前点”的新点, 而不是绝对坐标. closepath 添加一个直线,连接“当前点”和当前subpath的起始点(通常这个点是由最近的一个moveto指定),因此关闭当前subpath。 注意:path构建操作符不会在page上留下任何痕迹,只有paint操作符才会执行他们。通常描绘一个图形元素的程序是通过把这个元素定义成path,然后再调用某个paint操作符实现的。 This is repeated for each element on the page.所有用来描述path的点都是定义在“用户空间”(user space)。程序在添加点到“当前路径”的时候,所有坐标都会通过CTM转换到“设备空间”(device space)。改变CTM不会影响“设备空间”里面已经存在的点的坐标。 通过调用一个定义的构建path的ps过程,可以在页面描述里面重复使用同一个path。此时每个path可以通过如下3个步骤被构建和paint: 1. 修改CTM, 如果有必要,通过调用坐标转换操作符来定位,转向,以及缩放这个path。 2. 调用ps过程构建这个path。 3. 调用paint操作符,把它显示在页面上。 一般情况下,path的描述是不变的,LanguageLevel 2 里面的user path 操作符可以合并上面的2和3步骤,并通过gsave和grestor操作符把整个过程封装起来。如下就是个例子: /box % 在当前用户坐标系统定义一个path,它的原点是左下角。 { newpath 0 0 moveto 0 1 lineto 1 1 lineto 1 0 lineto closepath } def gsave % 保存当前graphics state,并创建一个可以修改的新的graphics state。 72 72 scale % 修改CTM,此后按照72倍显示。 box fill % 在左下角画一个单元的矩形并用黑色填充。因为现在一个单元是1 英寸,所以这个矩形边长是1英寸。 2 2 translate %继续修改CTM,使原点移到距离页面左边和底边都是2英寸的位置。 box fill % 再次画这个矩形,位置在距离左下角高2英寸,靠右2英寸。 grestore % 恢复刚才保存过的graphics state。现在返回到了默认的用户空间。 “裁剪路径”(Clipping Path) graphics state还包含了一个“裁剪路径”,它限制了页面上被paint相关操作符影响的区域。闭合的subpaths定义了paint可以影响到的区域落在区域内的元素会被显示在页面上,而区域之外的则不会显示出来。“裁剪路径”只会影响当前paint类的操作符; 它对上一节提到的path构造操作符没有影响。当path最终被描绘出来的时候,其结果只受当时的“裁剪路径”影响,而不是path被构造的时候的那个。 在PS level 3中,graphics state同时包含了一个辅助的“裁剪路径”栈,它通过clipsave和cliprestore操作符出栈和入栈。因为“裁剪路径”是graphics state的一个元素,因此gsave和grestore切换graphics state的时候也会替换整个“裁剪路径”。 |