歷史
PostSc
ript語言的思想起源於
John Warnock1976年在著名的計算機圖形公司Evans and Sutherland時的想法。當時John Gaffney正在開發一個解釋紐約港大型三維圖形資料庫的
解釋器。Gaffney設計了非常類似於Forth程式語言的
Design System語言來處理圖形。
1978年Evans和Sutherland要求Warnock離開
舊金山灣到
猶他州總部去,但是他並不想搬家到那裡去。於是他後來加入了
Xerox PARC與Martin Newell一起工作。他們重寫了Design System開發出了用於
VLSI設計和字型與圖形列印研究的
JaM(John and Martin)系統。這項工作後來發展成為一個名為
InterPress的擴展系統。
在1982年12月Warnock和Chuck Geschke一起離開創建了Adobe Systems公司。他們開發了一種類似於InterPress名為PostSc
ript的更簡單的語言,這種產品在1984年推向市場。大概在這個時候,
Steve Jobs參觀了他們的工作,他敦促他們改進PostScript作為驅動
雷射印表機的語言,它添加到
Canon印表機誕生了LaserWriter。
1985年3月,
AppleLaserWriter是第一款帶有PostScript的印表機,這也帶來了二十世紀八十年代中期的桌面印刷革命。它的技術優點和廣泛套用使得PostScript成為列印套用領域影像輸出的一個選擇。直到二十世紀九十年代,PostScript語言
解釋器(有時稱作
RIP(
光柵圖像解釋器))曾經一度成為
雷射印表機的一個普通組成部分。
隨著使用電子方式發布文檔最終版本成為事實上的標準,PostSc
ript就在這個領域不斷地被它的後續版本Portable Document Format也就是
PDF所超越,到了2001年更少有印表機支持PostScript,這主要是由於來自於非PostScript的廉價
噴墨印表機的不斷加劇的競爭(PostScript
解釋器將大幅度地增加印表機成本),以及在計算機上使用軟體翻譯
PostScript圖像的新方法可以用於任何的印表機,PDF就是這種方法之一。然而使用PostScript的雷射印表機仍然可以大幅度地減少計算機在列印、從計算機到印表機傳輸翻譯出的PostSc
ript圖像方面的工作量。
PostScript經歷了兩次主要的更新。第一版稱為PostScript Level 1在1984年發布。PostScript Level 2在1991年發布,它有幾項增強的特性:提升了速度和可靠性;支持RIP內的分割;支持接壓縮,這就意味著如
JPEG這樣的圖像能夠直接在PostScript程式中進行處理;支持複合字型以及快取重用內容的Form機制。PostScript Level 3在1997年年底出現,許多舊版操作符變成了基於字典的新版本,它提供了更好的顏色處理以及新的允許在程式內進行壓縮和解壓的過濾器、程式chunking以及先進的錯誤處理。
列印套用
之前
在PostSc
ript出現之前,印表機設計成將
字元——通常是
ASCII字元——列印出來。有許多技術用於這項工作,但是大多數都有一個共性也就是字元在物理上很難更改,就像在
打字機鍵上的金屬或者光學平板那樣的條帶。
隨著
點陣印表機的流行發生的一些變化,在這些系統上字元是用一系列的點“畫”出來的,這些點在印表機中定義為字型表。隨著他們越來越複雜,點陣印表機開始包含有幾種內置的字型,用戶可以選擇所用字型,有一些型號甚至允許用戶下載自己的字元圖形到印表機中。
點陣印表機也帶有列印光柵圖形的能力,圖形在計算機上進行解釋並且使用一系列的
轉義序列將它們按照一系列的點傳送到印表機。這種印表機控制語言所這印表機的不同而不同,這就要求程式設計師創建許許多多的
驅動程式。
真正的圖形列印是名為
繪圖儀的特殊的設備所完成的,繪圖儀的確是共享一種常見的語言——HPGL,但是除了列印圖形之外並沒有多大用途。另外,它們通常價格昂貴,速度較慢,所以使用很少。
列印
具有高質量的曲線處理能力並且
控制語言簡單能夠用於不同品牌的印表機;同
點陣印表機一樣,PostScript提供了一個生成文本和光柵圖形的簡單方法。與它們二者不同的是,PostScript能夠將所有這些不同的內容放在同一頁上,這樣就比以前的印表機或者繪圖儀提供了更具靈活性。
PostScript已經超出了普通的印表機控制語言,並成為一個完善的程式語言。許多應用程式能夠將文檔傳送到一個PostScript程式中,它的輸出結果就是原始文檔。這個程式能夠傳送到印表機中的
解釋器上得到列印文檔,或者傳送到另外一個應用程式在螢幕上顯示文檔。由於文檔程式與目的地無關,所以就被稱為“與設備無關”。
PostSc
rip也非常擅長於實現rasterization;所有的東西,甚至是文本都可以用直線和立方
貝塞爾曲線表示,貝塞爾曲線以前只有在
CAD套用中才能見到,它允許任意的縮放、旋轉或者其它變換。當解釋PostScript程式的時候,解釋器將這些指令轉換成所需的點形成輸出內容。
字型處理
同PostSc
ript一樣複雜的是它的字型處理。豐富的字型系統使用PS基本圖形(:en:graphics primitives)將
字元畫成藝術線條,藝術線條能夠在任意的解析度生成。儘管這聽起來是很直觀的概念,但是需要考慮許許多多的
拓撲圖形問題。
其中一個問題是字型在小尺寸的時候實際上並不是進行線性縮放,如果那樣的話字型的某些部分
就會不成比例地過大或者過小從而字型看起來不太正確。PostScript使用與字形曲線保存在一起的
隱含信息避免了這個問題的發生,它們基本上是水平或者豎直方向條帶上一些附加信息,用以標識
光柵圖像生成器需要維護的字型中的重要特徵。甚至在很低的解析度的時候字型也是非常好看;通常認為這是手工字型
點陣圖調整才能完成的任務。
當時,在字型中包含這種隱含信息的技術被細心地維護著,包含隱含信息的字型經過壓縮、加密成為
Adobe的
Type 1 Font。Type 1是一個高效的僅僅用來保存字形信息的簡化PS系統,而不是一個完善的語言,PDF也是一種類似的情況。Adobe向那些打算在自己的字型中添加隱含信息的廠商徵收高額的Type 1技術授權使用費用。那些不願意使用隱含信息或者不願支付費用的用戶只能使用
Type 3 Font。Type 3字型允許使用除了標準的隱含信息之外的PostScript語言的所有複雜特性,後來又添加了一些其它的不同特點。
許多人認為授權的費用過於高昂,並且Adobe也不願採用更具吸引力的費率,這樣就導致了Apple在1991年左右開發了他們自己的系統
TrueType。緊隨著TrueType的發布,Adobe就公開了Type 1字型的規範。如AltsysFontographer(1995年1月被
Macromedia收購,自從2005年5月歸FontLab所有)這樣的零售系統加入了創建Type 1字型的能力。從那時開始,就出現了許多免費Type 1字型,例如
TeX排版系統中所用字型就是這種格式。
在二十世紀九十年代早期還有其它幾種基於字形的字型系統,如Bitstream和METAFONT開發的系統,但是它們都不包括通用的列印解決方案,所以並沒有得到廣泛套用。
在二十世紀九十年代,Abobe和微軟公司一同開發
OpenType,它基本上是Type 1和TrueTy
pe格式功能的超集。當列印到PostSc
ript
輸出設備的時候,OpenType字型中不需要的部分就會被丟棄,
驅動程式送到設備的內容與傳送
TrueType或者Type 1字型完全一樣,根據OpenType字型中的外形不同而有所不同。
其它實現
在二十世紀八十年代,Adobe利潤的絕大部分都來自於用於印表機的PostSc
ript實現(稱為
光柵圖像處理器或者
RIP)的高昂授權費用。RIP相當昂貴,並且通常只在少數一些特定的硬體上運行。二十世紀八十年代中期隨著許多基於RISC的新平台出現,Abobe經常是在支持新機器方面落後一步。
因此第三方的PostScript實現變得很普遍,尤其是在授權費用是關鍵癥結的低端印表機或者新硬體激發更快速度要求的高端拍板設備領域更加常用。一方面,微軟公司和
蘋果公司聯合起來努力將
Adobe從獨霸印表機的位置拉下馬,微軟公司將它購買的TrueImagePostScript
解釋器授權給蘋果公司,蘋果公司將它的新字型格式
TrueType授權給微軟公司。(蘋果公司終止了與Adobe保持一致以及它的印表機使用Adobe公司真正的PostSc
ript的策略,但是TrueType在微軟視窗和Macintosh上都成為了標準的outline font。)一些第三方的PostScript的克隆產品仍在廣泛使用,尤其是在作為惠普黑白
雷射印表機標準Phoenix Page的中仍在廣泛使用。
解析度非常高的設備,如imagesetter或者CTPplatesetter超過2500dpi的解析度也很常見,仍然需要帶有大量記憶體和磁碟空間的外部光柵圖像處理器。許多稱為數字印刷的高端
雷射印表機系統也使用外部
光柵圖像處理器將容易升級的計算機系統與特定的列印硬體分開。如
EFI和Xitron這樣的公司專業從事這樣的光柵圖像處理器軟體開發。
系統套用
隨著
PostScript成為列印輸出的事實標準,很自然人們也希望將它用來描述螢幕輸出。二十世紀八十年代後期
CPU性能的快速提升以及人們對於視窗系統興趣的逐漸增加,促使人們多次試圖開發使用PostSc
ript作為主要的顯示技術的顯示系統。
使用PS作為顯示系統有許多優點,其中之一就是在其它系統上用戶不僅僅要為螢幕顯示保留點陣圖,而且要為印表機保留Type 1字型,在顯示器上使用PS只需要保留一套從而可以彌補這個缺點。另外一個優點是就是允許“dumbling down”印表機。當LaserWiter發布的時候它是
蘋果公司產品線中功能最為強大也是最為昂貴的機器,這樣它就需要相當大的處理能力和記憶體以在合理的時間內生成高達300
dpi解析度的頁面。與之形成對比的是,使用NeXT平台的400dpi印表機根本都沒有CPU,相反它是使用計算機的CPU進行頁面生成,然後將生成的頁面
點陣圖傳送到印表機。
但是使用PostSc
ript作為視窗系統的一個更為主要的優點是它讓用戶使用一組圖形處理
子程式就可以開發桌面印刷和其它大量使用圖形的應用程式,在視窗上進行描畫的程式同樣也可以不經任何轉換直接在印表機上描畫。傳統系統上的桌面印刷應用程式要求程式設計師在各個平台的
圖形系統上構建圖形用戶接口(如
Macintosh上的
QuickDraw和微軟視窗上的
圖形設備接口(GDI))編輯器,然後編寫另外的程式將
圖形轉換成正確的PostSc
ript語言用於列印。這樣的工作通常就會消耗項目的大部分編程工作,並且是
程式錯誤的主要來源。
使用PostScript作為顯示技術的兩個主要的例子是Display PostScript(
DPS)和
NeWS,它們兩者戲劇性地在在哪裡套用顯示邏輯發生了分歧,在DPS中view系統留給了OS去處理,然而在NeWS上整個顯示系統是用用PS寫成的並且在一個單一的複雜解釋其中運行。
程式語言
PostSc
ript是一個Turing-complete程式語言,通常
PostScript程式不是人為生成的,而是由其它程式生成的。然而,仍然可以使用手工編制的PostScript程式生成圖形或者進行計算。
PostScript是一個基於堆疊的
解釋語言(例如stack language),它類似於
Forth語言但是使用從
Lisp語言派生出的數據結構。這種語言的語法使用
逆波蘭表示法,這就意味著不需要
括弧進行分割,但是因為需要記住
堆疊結構,所以需要進行訓練才能閱讀這種程式。大部分
運算符(其它程式中稱為
函式)從堆疊中讀取變數,並且將運算結構放到堆疊中。如數字這樣的
符號:en:Literal具有將它們自身副本放到堆疊的效果。
算法
例如:
3 4 add 5 1 sub mul將執行 (3 + 4) × (5 - 1) 這樣的計算。
讓我們詳細地分析一下這是如何完成的:
3 和 4 都是符號,它們將自己放到
堆疊中,在這兩個命令之後,堆疊將變成這樣:
43add是一個運算符,它將堆疊中最上面的兩個元素取出(在我們的例子中是3和4)、將它們相加、然後將結果放到堆疊上:
7下面又是兩個符號,它們將把堆疊變成這樣(需要注意的是操作僅僅局限在堆疊頂部,下面的元素不受影響):
157另外一個運算符
sub,從
堆疊頂取出兩個元素、第二個減去第一個、然後將結果放到堆疊:
47很顯然
mul同其它兩個
運算符一樣,從堆疊取出兩個元素、將它們的乘積放到堆疊:
28
Named variables
上面的例子只是一個古老的
逆波蘭表示法計算,當然PostSc
ript也使用變數。詳細地說就是它有一個
字典用來查找所有不是符號的東西;如果查到的話,那個名字下保存的值就會壓縮到棧中(或者更應該說是
執行——參見後面的內容);找不到就返回錯誤。將一個變數放到字典中需要使用
def運算符,它用一個名字和一個值作為參數,通過在前面使用斜線構建一個名字。因此
/x1 15 def首先將名字“x1”放到
堆疊上、然後是值15、然後執行
def,它將從堆疊中取出“x1”和15,並且將15寫到字典中“x1”的下面。後面出現的“x1”(注意不要與“/x1”混淆)將會將15放到堆疊而變數並不改變。下面的代碼會將x1的值增加2:
/x1 x1 2 add def
堆疊運算符
PostSc
ript有幾個操作符用於重組或者控制
堆疊:複製(
dup)、丟棄(
pop)和交換(
exch)在堆疊頂部進行操作,然而
roll旋轉堆疊中的某一部分,
copy複製某個特定的部分,
index允許象
數組那樣訪問堆疊。
處理過程定義
{和
}提供了一些編程的工具。
{將
解釋器切換到
延遲運行模式,所有的東西甚至是
運算符和其它的可執行對象都放到
堆疊中,其中一個例外就是
},它將堆疊中從
{開始的所有內容,綁定成一個(匿名)處理過程,然後將它放到堆疊上。
這種結構有幾種不同的用途,如子程式定義(匿名程式賦給一個變數)、循環、條件等等:
x1 0 eq { 0 } { 1 x1 div } ifelse這段代碼首先使用
eq測試 x1 是否是 0;根據結果的不同將
真或者
假放到
堆疊上。在此之後,將兩個過程放到堆疊上,然後執行
ifelse,它從堆疊中取出三個參數,如果第三個參數是
真就執行第二個否則就執行第一個。總之,如果 x1 是 0 結果就是 0, 其它情況結果就是 1/x1。
/inc3 { 3 add } defHere
defis used to place something in the
dictionary, only this time it is a procedure instead of a simple integer. This works because the values coming from the dictionary are
executed, not just pushed (as simplistically stated above). Since executing a literal amounts to pushing it, that did not make a difference before. Now executing "inc3" will first look it up in the dictionary, find the procedure object representing "{ 3 add }" and execute that. One value must reside on the stack for this to work, since
addneeds two arguments, only one of which is given in the procedure itself. Naturally, one passes arguments to procedures by placing them on the stack, so we can simply view "inc3" as a procedure that takes one argument. Example call: 這裡
def將內容放到字典中,僅僅在這個時候它是一個過程而不是簡單整數。
71 inc3將71放到堆疊上,inc3將它的值加3,這樣就得到結果74。
圖形操作
To produce graphics, PostSc
ript uses an ordinarycartesian coordinate system. 在生成圖形的時候,
PostScript使用普通的
笛卡爾坐標系。
100 200 moveto 300 400 lineto stroke將“
游標”移到坐標點(100, 200)然後畫線到(300, 400)。
50 70 moveto 100 200 50 80 100 100 curveto stroke生成一個從(50, 70)到(100, 100)的立方
貝塞爾曲線,控制點是(100, 200)和(50, 80)。
250 250 moveto (
Wikipedia) show在位置(250, 250)使用預先選擇的字型畫出文本“Wikipedia”,字型選擇可以使用例如 /Courier findfont 12 scalefont setfont 這樣的命令串。
圖形最初在“
用戶坐標系”中創建,在複製到確定最後輸出的“
設備坐標系”之前它們可以進行旋轉、縮放或者扭曲等變換。
200 300 translate 45 rotate將用戶坐標系中的內容上移 200 點、右移 300 點並且複製到設備坐標系時旋轉 45 度。
字元“%”用來在PostSc
ript程式中表示注釋。作為一個通用的約定,每個PostScript都以字元“%!”開始這樣所有的設備都會將它解釋為PostScript。