介紹
POSTSCRIPT語(yǔ)言是打印機(jī)頁(yè)面描述的一種程序設(shè)計(jì)語(yǔ)言。他擁有著廣泛的圖形操作,并且可以以任意方式,包含變量,函數(shù),以及過(guò)程的任意組合
。
POSTSCRIPT頁(yè)面描述是由解析器運(yùn)行的程序(gs),postscript程序通常是由其他應(yīng)用程序生成的。
1.1、POSTSCRIPT作為頁(yè)面語(yǔ)言
POSTSCRIPT具有大量的圖形運(yùn)算符,通過(guò)他可以更加詳細(xì)的描述你的頁(yè)面。
文本的字體,位置,方向,尺寸。
幾何圖形的大小,方向,寬度,直線和曲線的位置,任何大小形狀顏色的空間填充。
1.2、POSTSCRIPT作為編程語(yǔ)言
堆棧和運(yùn)算
POSTSCRIPT 編程語(yǔ)言和其他編程語(yǔ)言一樣,適用于各種各樣的數(shù)據(jù),例如數(shù)字,數(shù)組,字符串,以及字符。這種處理數(shù)據(jù)的方法被稱為POSTSCRIPT對(duì)象。
操作數(shù)據(jù)的方法有多種多樣,例如:將數(shù)據(jù)放入變量名,通過(guò)變量名稱進(jìn)行處理。POSTSCRRIPT語(yǔ)言擁有變量,但也可以通過(guò)堆棧直接操作數(shù)據(jù)。
2.1、POSTSCRIPT堆棧
堆棧是一段用于處理數(shù)據(jù)的內(nèi)存,是一種先入后出的存儲(chǔ)原理。
將數(shù)字入棧
12 6.3 -99
1.將12入棧
2.將6.3,入棧,12壓棧
3.將-99 入棧,前兩個(gè)一次類推
2.2、運(yùn)算
加: 5 27 add => 32
減: 8.3 6.6 sub => 1.7
除: 13 8 div => 1.625
除返回整數(shù): 25 3 idiv => 8
除返回余數(shù): 12 10 mod => 2
乘: 6 8 mul => 48
取反: -27 neg => 27
組合運(yùn)算:
6 + (3 ÷ 8)
- 3 8 div 6 add
將3,8入棧,除運(yùn)算,0.375,再講6 入棧,加運(yùn)算,得6.375 - 6 3 8 div add
將6,3,8,入棧,8為棧頂,取3,8,進(jìn)行除運(yùn)算,結(jié)果再與6 進(jìn)行加運(yùn)算
8 - (7 × 3)
- 7 3 mul 8 exch sub
- 8 7 3 mul sub
exch:交換棧的前兩項(xiàng)空間數(shù)據(jù)
清除所有棧數(shù)據(jù): 6 8 12 32 clear => 空
復(fù)制堆棧頂部的數(shù)據(jù): 6 dup => 6 6
刪除堆棧頂部數(shù)據(jù): 17 8 pop => 17
旋轉(zhuǎn)數(shù)據(jù): 7 8 9 3 1 roll => 9 7 8 : 789依次入棧,1代表從頂?shù)降祝?98,978
7 8 9 3 -1 roll => 897 : -1代表從低端到頂端,879, 897
2.3、交互運(yùn)算符
== 將堆棧頂端的數(shù)據(jù)打印出來(lái),并且刪除。
pstack 將整個(gè)棧中的數(shù)據(jù)打印數(shù)來(lái),保留數(shù)據(jù)。
繪圖
3.1、畫(huà)線
- 線
newpath
144 72 moveto
144 432 lineto
stroke
showpage
我們首先調(diào)用newpath,初始化當(dāng)畫(huà)筆狀態(tài)。
x y moveto,將畫(huà)筆的移動(dòng)到x,y的位置
x y lineto,以x,y為終點(diǎn)進(jìn)行畫(huà)線
stroke將構(gòu)建的路徑繪制到當(dāng)前頁(yè)面
showpage打印當(dāng)前頁(yè)
- 交叉線
newpath
72 360 moveto
144 72 rlineto
144 432 moveto
0 -246 rlineto
storke
showpage
x y rlineto:將畫(huà)筆位以x,y進(jìn)行位移
- 正方形
newpath
270 360 moveto
0 72 rlineto
72 0 rlineto
0 -72 rlineto
-72 0 rlineto
4 setlinewidth
stroke showpage
setlinewidth:設(shè)置線的寬度
newpath
270 360 moveto
0 72 rlineto
72 0 rlineto
0 -72 rlineto
-72 0 rlineto
closepath
4 setlinewidth
stroke showpage
closepath:使圖形閉合(不使用的時(shí)候在拐角的地方會(huì)出現(xiàn)一個(gè)小缺口)
3.2、填充圖形
newpath
270 360 moveto
0 72 rlineto
72 0 rlineto
0 -72 rlineto
-72 0 rlineto
closepath
fill showpage
fill:填充圖形
newpath
270 360 moveto
0 72 rlineto
72 0 rlineto
0 -72 rlineto
-72 0 rlineto
closepath
.5 setgray
fill showpage
gray:設(shè)置透明度
多圖的疊層
newpath
252 324 moveto
0 72 rlineto
72 0 rlineto
0 -72 rlineto
-72 0 rlineto
closepath
.5 setgray
fill showpage
newpath
270 360 moveto
0 72 rlineto
72 0 rlineto
0 -72 rlineto
-72 0 rlineto
closepath
.5 setgray
fill showpage
newpath
288 396 moveto
0 72 rlineto
72 0 rlineto
0 -72 rlineto
-72 0 rlineto
closepath
.5 setgray
fill showpage
3.3、總結(jié)
closepath 閉合圖形
lineto 繪制直線
moveto 設(shè)置繪制的起始點(diǎn)
newpath 初始化繪制方式
rlineto 移動(dòng)
fill 繪制填充圖形
setgray 設(shè)置透明度
setlinewidth 設(shè)置線的寬度
stoke 繪制路徑
showpage 打印當(dāng)前頁(yè)
程序變量使用
4.1、變量定義
POSTSCRIPT 變量
變量的定義是將比那兩名和值用def進(jìn)行關(guān)聯(lián)類似
/ppi 75 def %將ppi定義為75
/ppi ppi 1 add def %將ppi + 1的值定義為ppi ppi = 75 + 1 = 86
POSTSCRIPT 程序塊
/inch {72 mul} def
4.2、使用程序和變量
方塊
/box
{
72 0 rlineto
0 72 rlineto
-72 0 rlineto
closepath
}def
newpath
252 324 moveto box
.4 setgray fill
/inch {72 mul}def
/box
{
newpath moveto
1 inch 0 rlineto
0 1 inch rlineto
-1 inch 0 rlineto
closepath
}def
/fillbox
{
setgray fill
}def
3.5 inch 4.5 inch box
0 fillbox
2.75 inch 5 inch box
.4 fillbox
文本打印
5.1、POSTSCRIPT字體
字體是具有統(tǒng)一規(guī)格的字符集。其中包含數(shù)百個(gè)字符集,包含熟悉的TIMES和HELVETICA
使用POSTSCRIPT字體
在你打印文本之前,你需要指定所需的字體,這個(gè)過(guò)程需要三個(gè)步驟
1、查找字體的信息。保存在當(dāng)前環(huán)境中,他用來(lái)提供特定字體的形狀,信息。
2、將字體縮放。
3、將縮放的額字體設(shè)置為當(dāng)前字體,然后打印出來(lái)
%!PS-Adobe-3.0
/Times-Roman findfont 15 scalefont setfont
72 200 moveto (typography) show
showpage
/Times-Roman findfont
查找名稱為Times-Roman的字體,并把它保存到當(dāng)前程序中
15 scalefont
設(shè)置字體大小為15號(hào)的Times-Roman字體
setfont
根據(jù)已經(jīng)保存好的規(guī)格,對(duì)字體進(jìn)行設(shè)置
5.2、動(dòng)態(tài)設(shè)置字體大小
%!PS-Adobe-3.0
/scaleTimes % stack:scale
{
/Times-Roman findfont
each scalefont setfont
}def
6 scaleTimes
72 200 moveto (typography) show
showpage
/Times-Roman findfont 入棧
each scalefont setfont 入棧
6 scaleTimes意義為
6 /Times-Roman findfont each scalefont setfont
each 將 6 和 /Times-Roman 交換位置得
/Times-Roman findfont 6 scalefont setfont
默認(rèn)支持的字體字體:
Times-Roman
Times-Bold
Times-Italic
Times-Boldltalic
Helvetica
Helvetica-Bold
Helvetica-Oblique
Helvetica-Boldltalic
Courier
Courier-Bold
Courier-Oblique
Courier-BoldOblique
%!PS-Adobe-3.0
/MainFont
/STSong-Light--GB-EUC-H findfont 15 scalefont def
/SloganFont
/Helvetica-Oblique findfont 7 scalefont def
/OwnerFont
/Helvetica findfont 10 scalefont def
/rightshow
{
dup stringwidth pop
150 exch sub
0 rmoveto
show
}def
/CardOutline
{
newpath
90 90 moveto
0 144 rlineto
252 0 rlineto
0 -144 rlineto
closepath
.5 setlinewidth
stroke
}def
/doBorder
{
99 99 moveto
0 126 rlineto
234 0 rlineto
0 -126 rlineto
closepath
2 setlinewidth
stroke
}def
/Diamond
{
newpath
207 216 moveto
36 -54 rlineto
-36 -54 rlineto
-36 54 rlineto
closepath
.8 setgray
fill
}def
/doText
{
0 setgray
90 180 moveto
MainFont setfont
(AAA丶死劉) rightshow
90 168 moveto
SloganFont setfont
("The Club of Lonely Hearts") rightshow
216 126 moveto
OwnerFont setfont
(Sam Spade) show
216 111 moveto
(Owner) show
}def
CardOutline
doBorder
Diamond
doText
showpage
/STSong-Light--GB-EUC-H 為中文打?。ㄗⅲ褐形拇蛴r(shí)候要求文件格式為gb2312,否則字庫(kù)不識(shí)別,打印出來(lái)是亂碼)
stringwidth 獲取當(dāng)前字符串的寬度,寄存起為字符串寬度 ,字符串內(nèi)容,寬度在頂端
dup stringwidth pop
150 exch sub
0 rmoveto
show
意義為:
獲取字符串寬度,并將(150 - 字符串寬度的值,0)進(jìn)行偏移,即:打印字符串在150處右端對(duì)其
圖形轉(zhuǎn)換
6.1、坐標(biāo)系變換
POSTSCRIPT圖形操作是在一個(gè)坐標(biāo)系中,這個(gè)坐標(biāo)系被稱為用戶坐標(biāo)系或用戶空間,該坐標(biāo)系獨(dú)立于任何物理設(shè)備。POSTSCRIPT在用戶空間中進(jìn)行繪制,并將結(jié)果傳輸?shù)教囟ǖ拇蛴C(jī)設(shè)備(設(shè)備空間)中。
在程序中,通常使用默認(rèn)的坐標(biāo)系。在這個(gè)空間中,原點(diǎn)是在頁(yè)面的左下角,量度是1/72英寸長(zhǎng)度。
然而,用戶空間是可塑性的,他的坐標(biāo)系可能是在位置,方向,大小變化后的。
6.1.1、用戶空間的平移
translation是從一個(gè)地方運(yùn)動(dòng)到另一個(gè)地方。這個(gè)運(yùn)動(dòng)是原點(diǎn)的運(yùn)動(dòng)。例如:
100 200 translate
將會(huì)把原點(diǎn)右移100個(gè)單位,上移200個(gè)單位,隨后的操作都是根據(jù)這個(gè)新的原點(diǎn)進(jìn)行測(cè)量。
下面的程序?qū)⒄f(shuō)明這個(gè)轉(zhuǎn)化效果。
/Times-Roman findfont 30 scalefont setfont
/square %一個(gè)填充的方塊
{
newpath
0 0 moveto
90 0 lineto %定義正方形的路徑
90 90 lineto
0 90 lineto
closepath fill %進(jìn)行填充
6 92 moveto %文本顯示
(A Box) show } def
square %繪制一個(gè)方塊
200 250 translate %將原點(diǎn)移動(dòng)x + 200 y + 250
square %繪制第二個(gè)方塊
200 250 translate %原點(diǎn)再次移動(dòng)x + 200 y + 250
square %繪制第三個(gè)方塊
showpage
這個(gè)程序定義了一個(gè)方塊,然后通過(guò)原點(diǎn)變換獲得了三個(gè)方塊。
注:原點(diǎn)的變換是相對(duì)于當(dāng)前原點(diǎn)而不是起始原點(diǎn)。
6.1.2、用戶空間的旋轉(zhuǎn)
rotate是從棧中取出一個(gè)數(shù)然后進(jìn)行逆時(shí)針旋轉(zhuǎn)坐標(biāo)軸。(旋轉(zhuǎn)的單位是度)
/Times-Roman findfont 30 scalefont setfont
/square
{
newpath
0 0 moveto
90 0 lineto
90 90 lineto
0 90 lineto
closepath fill
6 92 moveto
(A Box) show } def
square
300 150 translate
60 rotate %逆時(shí)針旋轉(zhuǎn)90度
square
300 150 translate
60 rotate %逆時(shí)針旋轉(zhuǎn)60度
square
showpage
在此,我們只是改變了坐標(biāo)系的位置,方塊實(shí)際上的定義從未改變。
6.1.3、用戶空間的縮放
scale運(yùn)算符允許更改坐標(biāo)單元的大小,這個(gè)運(yùn)算符獲取兩個(gè)參數(shù),一個(gè)x縮放,一個(gè)y縮放,例:
3 3 scale
執(zhí)行此操作,將會(huì)將x,y放大為原來(lái)的三倍。
在此通過(guò)小方塊例子
/Times-Roman findfont 30 scalefont setfont
/square
{
newpath
0 0 moveto
90 0 lineto
90 90 lineto
0 90 lineto
closepath fill
6 92 moveto
(A Box) show } def
square
300 150 translate
1.5 1.5 scale %擴(kuò)大1.5倍
square
300 150 translate
0.5 2 scale %x 縮小到原來(lái)的1/2 y變?yōu)樵瓉?lái)的2倍
square
showpage
6.2、繪圖狀態(tài)
目前為止,我們工作在當(dāng)前的繪圖狀態(tài)中,構(gòu)成當(dāng)前環(huán)境包括(路徑,點(diǎn),灰度值,字體,線寬,用戶坐標(biāo)系)。
6.2.1、保存當(dāng)前的圖形狀態(tài)
有時(shí)候我們需要保存當(dāng)前的圖形狀態(tài),以便以后可以隨時(shí)得到他。
例如:如果想要打印一個(gè)填充的圖形,我們就必須要構(gòu)建一個(gè)適合的路徑,然后填充他。不幸的是fill操作符將會(huì)清除當(dāng)前的路徑。所以在執(zhí)行fill前應(yīng)先保存當(dāng)前的路徑,在fill之后再恢復(fù)保存的路徑就可以了。
保存和恢復(fù)圖形狀態(tài)的操作符是gsave和grestore。
gsave操作符將當(dāng)前圖形狀態(tài)的副本保存在圖形狀態(tài)的堆棧中。這個(gè)堆棧最多可保存32個(gè)圖形狀態(tài)(包括當(dāng)前圖形狀態(tài))。
grestore操作符恢復(fù)最新的gsave圖形狀態(tài)。包括當(dāng)時(shí)的所有特征,路徑,灰度,線寬,用戶坐標(biāo)系。
下面是一個(gè)五角星來(lái)演示這些操作符的使用
/starside
{
72 0 lineto
currentpoint translate
-144 rotate } def
/star %stack: x y
{
moveto
currentpoint translate
4 {starside} repeat
closepath
gsave
.5 setgray fill
grestore
stroke }def
200 200 star
showpage
在這個(gè)程序,定義了兩個(gè)步驟
starside繪制了組成該星星的一條直線。
star根據(jù)坐標(biāo)點(diǎn)填充星星。
添加一條水平線
72 0 lineto %星星的邊長(zhǎng)為72
將坐標(biāo)系原點(diǎn)移動(dòng)到水平線的末尾
currentpoint translate
再講坐標(biāo)系順時(shí)針旋轉(zhuǎn)144度
-144 rotate
repeat:這個(gè)運(yùn)算符需要兩個(gè)參數(shù)
一個(gè)數(shù)字(例子中的4)
一組用括號(hào)括起來(lái)的運(yùn)算(starside)
意思為執(zhí)行指定運(yùn)算4次
4 {starside} repeat
然后跟上結(jié)束符,完成路徑繪制
closepath %畫(huà)筆回到起點(diǎn)
進(jìn)行圖形的填充(填充操作會(huì)清空路徑信息所以要提前保存,不保存的話1.路徑被清空,不會(huì)顯示變沿線以及中間的五邊形,灰度清空所有線的灰度值會(huì)一樣,看不出輪廓)
gsave
.5 setgray fill %將灰度值設(shè)置為0.5進(jìn)行填充
grestore %恢復(fù)保存的默認(rèn)狀態(tài)
以200 200的坐標(biāo)點(diǎn)繪制當(dāng)前圖形,然后提交當(dāng)前頁(yè)面到紙張。
200 200 star
showpage
6.3、曲線
通常圖形圖像不僅僅是由直線構(gòu)成,在postscript中可以使用運(yùn)算符來(lái)定義任何期望的曲線。
6.3.1、圓弧
在本節(jié)中我們將討論圓弧曲線arc
arc操作符是將圓弧添加到當(dāng)前路徑,他需要五個(gè)參數(shù)
弧的曲率中心的x,y坐標(biāo)、曲率半徑、以及從正x軸逆時(shí)針測(cè)量的弧的起始和結(jié)束角。
例:中心在100 150 半徑為36 從逆時(shí)針45到90
100 150 36 45 90 arc
arcn運(yùn)算符和arc類似,只是在方向上相反,為順時(shí)針
100 150 36 45 90 arcn
第一條線是畫(huà)了一個(gè)圓弧
第二條線是先將圖龜移動(dòng)到300 365 然后以40度起點(diǎn)到60度起點(diǎn)畫(huà)弧
newpath
300 400 54 40 140 arc stroke
newpath
300 365 moveto
340 345 54 40 140 arc stroke
showpage
6.3.2、橢圓
圓可以認(rèn)為是一個(gè)0到360的弧線
橢圓可以認(rèn)為是將坐標(biāo)系非均勻縮放之后的圓
/doACircle
{ <br> 0 0 54 0 360 arc stroke } def
/doAnEllipse
{ <br> 1 .75 scale %橫坐標(biāo)不變,縱坐標(biāo)變?yōu)樵瓉?lái)的0.75
doACircle %繪制圓
stroke } def
<br>300 500 translate doACircle
<br>4 {0 -72 translate %不斷縮放坐標(biāo)系
doAnEllipse} repeat
<br>showpage
6.3.3、圓角
相交線經(jīng)常通過(guò)圓角進(jìn)行連接,postscript的arcto運(yùn)算符提供了一種方法。
操作員除了當(dāng)前點(diǎn)意外需要兩個(gè)點(diǎn)和一個(gè)半徑
可以這樣理解:以起始點(diǎn)開(kāi)始,第一個(gè)點(diǎn)為線段連線,再將第一個(gè)點(diǎn)和第二個(gè)點(diǎn)連線,組成相交的一個(gè)角,以r為半徑的圓相切與這兩個(gè)直線,最后形成的弧度即為圓角。

例:列出了兩個(gè)圓角,分別為兩條線段的角度,相同,第一條線段的長(zhǎng)度相同,第二條線段的長(zhǎng)度不同,可以看到,兩個(gè)弧度的大小是一樣的。
/DrawAnX
{
3 3 rmoveto
-6 -6 rlineto
0 6 rmoveto
6 -6 rlineto
stroke
}def
50 50 moveto DrawAnX
50 150 moveto DrawAnX
150 150 moveto DrawAnX
50 50 moveto
50 150 150 150 36 arcto
4 {pop} repeat
200 50 moveto DrawAnX
200 150 moveto DrawAnX
400 150 moveto DrawAnX
200 50 moveto
200 150 400 150 36 arcto
4 {pop} repeat
stroke
showpage
注意:在圓角繪制完成后,當(dāng)前的圖龜停留在最后一次相切的圓角的末端。以第一個(gè)圓弧為例,
起始點(diǎn) 50 50
圓規(guī)確定的點(diǎn)是 50 150 150 150 36
此時(shí)在arcto運(yùn)算符執(zhí)行后有一組數(shù)據(jù)保留在了堆棧中,分別是圓角的起始點(diǎn)和終止點(diǎn)。
起始點(diǎn) 50,150 - 36 = 114
終止點(diǎn) 50 + 36 = 86,150
這四個(gè)點(diǎn)對(duì)于我們來(lái)說(shuō)是沒(méi)有必要的,所以,我們要將其從堆棧中刪除。
例:打印一個(gè)logo
% ------------ Define Procedures -------------
/Helvetica-Bold findfont 27 scalefont setfont
/fourpops %四次出棧
{
4 {pop} repeat } def
/background %繪制背景
{
0 18 moveto
0 72 108 72 18 arcto fourpops
108 72 108 0 18 arcto fourpops
108 0 0 0 18 arcto fourpops
0 0 0 72 18 arcto fourpops
fill } def
/moon
{
.6 setgray %繪制logo中的小圓
81 45 18 0 360 arc fill
} def
/omaha %繪制字體
{
1 setgray
0 -1 moveto
1 2 scale %更改坐標(biāo)系比例
(OMAHA) stringwidth pop %獲取OMAHA字符串的寬度
108 exch sub 2 ``div` `%108 - (字符寬度 / 2)作為x的偏移量
0 rmoveto %將圖龜移動(dòng)到該點(diǎn)進(jìn)行字符串顯示(目的為讓字符串顯示在logo的正中央)
(OMAHA) show } def
255 465 translate
background
moon
omaha
showpage
6.4、總結(jié)
repeat
重復(fù)執(zhí)行程序n次
rotate
逆時(shí)針?lè)较蛐D(zhuǎn)坐標(biāo)系
scale
x,y方向縮放坐標(biāo)系
translate
將坐標(biāo)原點(diǎn)進(jìn)行移動(dòng)
grestore
恢復(fù)上一次保存的圖形狀態(tài)
gsave
保存當(dāng)前圖形狀態(tài)
arc x y r ang1 ang2 -> —
逆時(shí)針添加圓弧
arcn x y r ang1 ang2 -> —
順時(shí)針添加圓弧
arcto x1 y1 x2 y2 r -> xt1 yt1 xt2 yt2
繪制圓弧,參數(shù)五個(gè),兩點(diǎn)一個(gè)半徑,返回值為圓弧的起始點(diǎn)和終止點(diǎn)
currentpoint — -> x y
返回當(dāng)前點(diǎn)的坐標(biāo)
條件語(yǔ)句
POSTSCRIPT語(yǔ)言中有許多操作符用于制定程序內(nèi)流的控制。我們?cè)谇耙徽率褂昧艘粋€(gè)repeat運(yùn)算。所有的控制操作符都使用了之前簡(jiǎn)要提到的對(duì)象類型,即函數(shù),用于我們調(diào)用。
7.1、函數(shù)
函數(shù)(既過(guò)程)是一個(gè)數(shù)組,其內(nèi)容由解析器執(zhí)行。
當(dāng)解析器在程序中遇到一系列對(duì)象(值和名稱)時(shí),它執(zhí)行與這些指令相應(yīng)的操作,將對(duì)象放在堆棧上,查找和執(zhí)行操作符和過(guò)程。
但是如果一系列對(duì)象用括號(hào)括起來(lái),則不會(huì)立即執(zhí)行,而是放在堆棧上。
86 23 add
該行使解析器將數(shù)字86和23相加
{86 23 add}
當(dāng)執(zhí)行置放時(shí),操作符添加一個(gè)程序塊,然后放在堆棧上,函數(shù)通常跟字面名稱,后邊跟def運(yùn)算符,def運(yùn)算符將其與當(dāng)前所保存的名稱相連(這就是函數(shù)的定義)。
7.2、條件語(yǔ)句
7.2.1、比較
POSTSCRIPT提供了一套比較完整額比較運(yùn)算符,這些比較棧上的前兩個(gè)項(xiàng)目,可以是任何類型,返回一個(gè)布爾類型的對(duì)象在堆棧上。他們的等效數(shù)學(xué)符號(hào)為:
eq =; ne ≠; gt >; lt <; ge ≥; le≤;
7.2.2、if
例:檢查是否到達(dá)當(dāng)前行的末尾
/chkforendofline
{ currentpoint pop %獲取x的位置
612 gt %是否大于612
{0 -12 translate 0 0 moveto} if
}def
執(zhí)行取出當(dāng)前的x,比較看是否大于612(即本行的末尾),如果大于,則將原點(diǎn)移動(dòng)到下一行的開(kāi)頭,當(dāng)前點(diǎn)移動(dòng)到原點(diǎn)的位置。
編寫(xiě)一個(gè)程序,對(duì)字符串進(jìn)行簡(jiǎn)單的格式打?。簷z查該字符串的長(zhǎng)度是否適合當(dāng)前行,如果不適合,則移動(dòng)到新的行,然后進(jìn)行打印。
在這里定義了三個(gè)變量:左邊距,右邊距,當(dāng)前文本的垂直位置,以及單獨(dú)文本的垂直距離。
首先復(fù)制要打印的字符串,然后使用stringwith計(jì)算其長(zhǎng)度,然后取出當(dāng)前的x的位置,將兩個(gè)值相加,看是否大于右邊沿,如果大于,跳轉(zhuǎn)到下一行進(jìn)行打印。
% -------------- Variables ---------------
/LM 72 def %定義左邊沿
/RM 216 def %定義右邊沿
/ypos 720 def %當(dāng)前文本的垂直位置
/lineheight 14 def %一行字符的高度
% of text
% ------------- Procedures ---------------
/newline %跳轉(zhuǎn)倒下一行
{ ypos lineheight sub %720 - 14 即為下一行的垂直位置
/ypos exch def %將當(dāng)前文本的垂直高度刷新為新的值
LM ypos moveto } def %將當(dāng)前點(diǎn)移動(dòng)到新的起始點(diǎn)
/prtstr %打印字符串
{ dup stringwidth pop %取出打印的字符串的寬度
currentpoint pop %取出當(dāng)前畫(huà)筆x的位置
add RM gt %相加看是否大于右邊距
{newline} if %條件符合,跳轉(zhuǎn)到下一行
show } def %進(jìn)行打印
%------------- Main Program --------------
/Times-Italic findfont 13 scalefont setfont
LM ypos moveto
(If ) prtstr (you ) prtstr (tell ) prtstr
(the ) prtstr (truth, ) prtstr (you ) prtstr
(don’t ))prtstr (have ) prtstr (to ) prtstr
(remember ) prtstr (anything. ) prtstr
(- Mark ) prtstr (Twain ) prtstr
showpage
7.2.3、ifelse
這個(gè)運(yùn)算符需要堆棧上有三個(gè)對(duì)象:一個(gè)布爾值和兩個(gè)執(zhí)行語(yǔ)句。
如果為真,則執(zhí)行第一個(gè),否則執(zhí)行第二個(gè)。
bool {op1} {op2} ifelse
例:使用ifelse生成了一組灰度交替逐漸減少高度的重疊梯形。
% ------- Variables & Procedures ---------
/scalefactor 1 def
/counter 0 def
/DecreaseScale
{ scalefactor .2 sub
/scalefactor exch def } def
/IncreaseCounter
{ /counter counter 1 add def } def
/trappath
{ 0 0 moveto 90 0 rlineto
-20 45 rlineto -50 0 rlineto
closepath } def
/doATrap
{ gsave %保存當(dāng)前環(huán)境
1 scalefactor scale %設(shè)置當(dāng)前坐標(biāo)軸的壓縮比例
trappath %繪制梯形
counter 2 mod %取余(看是否能被2整除)
0 eq {.5} {0} ifelse
setgray fill %設(shè)置灰度,然后進(jìn)行填充
grestore } def %恢復(fù)環(huán)境
% ------------ Begin Program ----------
250 350 translate
5
{ IncreaseCounter %標(biāo)記當(dāng)前的次數(shù)
doATrap %繪制梯形
DecreaseScale %標(biāo)記當(dāng)前的坐標(biāo)軸y的壓縮比例
0 20 translate %每次將原點(diǎn)向上移動(dòng)20個(gè)單位
} repeat
showpage
7.3、循環(huán)
在POSTSCRIPT中有三個(gè)操作符用來(lái)建立和控制循環(huán)程序。我們已經(jīng)使用過(guò)repeat操作。
7.3.1、for
這個(gè)運(yùn)算符實(shí)現(xiàn)了計(jì)數(shù)循環(huán)。該操作符需要四個(gè)對(duì)象:
起始值、地增量、最終值、重復(fù)的過(guò)程。
for操作在每次執(zhí)行過(guò)程之前將計(jì)數(shù)器的當(dāng)前值放在堆棧上。
例:將字幕k在頁(yè)面上每12個(gè)單元打印一次,
/Times-Italic findfont 10 scalefont setfont
100 100 translate
0 12 600 {0 moveto (k) show } for
showpage
數(shù)字的變化不一定是整數(shù),例如打印一個(gè)zip字符出現(xiàn)陰影效果
/Times-Italic findfont 30 scalefont setfont
/printZip
{ 0 0 moveto (Zip) show} def
320 400 translate
.95 -.05 0
{ setgray
printZip
-1 .5 translate } for
1 setgray printZip
showpage
7.3.2、loop,exit
許多程序需要重復(fù)一個(gè)不確定的數(shù)目,一段時(shí)間或者永遠(yuǎn),或者滿足某種條件,這時(shí)候就要用到重復(fù)。。。直到。。。這種。
POSTSCRIPT提供了一對(duì)運(yùn)算符:loop,exit。
loop操作符重復(fù)執(zhí)行其過(guò)程,直到遇到退出條件。退出導(dǎo)致程序離開(kāi)包含該操作符的最內(nèi)層循環(huán)。退出操作符還會(huì)終止for,repeat,forall操作符啟動(dòng)的循環(huán)。
例:此程序無(wú)限打印howdy。
{(Howdy ) show} loop
例:為了了解loop-exit如何一起工作,以下程序在當(dāng)前頁(yè)面繪制了幾個(gè)圓
/pagewidth 8.5 72 mul def
/doCircle
{ xpos ypos radius 0 360 arc stroke} def
/increase-x
{ xpos radius add
/xpos exch def } def
/lineofcircles %stack: radius y
{ /ypos exch def
/radius exch def
/xpos 0 def
{ xpos pagewidth le
{doCircle increase-x}
{exit} ifelse
}loop
} def
% --------------- Begin Program -----------
10 400 lineofcircles
30 400 lineofcircles
90 400 lineofcircles
showpage