PostScript

PostScript
編程範型 多範式堆疊導向程序式
設計者 John Warnock & Chuck Geschke
實作者 Adobe系統
面市時間 1982
穩定版本
PostScript 3
(1997 )
型態系統 動態,強型別
主要實作產品
Adobe PostScript, TrueImage, Ghostscript, InterPress
啟發語言
Lisp
影響語言
PDF
PostScript
副檔名 .ps
網路媒體型式 application/postscript
統一類型標識 com.adobe.postscript
特徵簽章 %!
開發者 Adobe系統
格式類型 列印檔案格式
延伸為 EPS

PostScriptPS)是主要用於電子產業和桌面出版領域的一種頁面描述語言程式語言

歷史

PostScript語言的思想起源於John Warnock1976年在著名的電腦圖形公司Evans and Sutherland時的想法。當時John Gaffney正在開發一個解釋紐約港大型三維圖形資料庫的直譯器。Gaffney設計了非常類似於Forth程式語言Design System語言來處理圖形。

1978年Evans and Sutherland要求Warnock離開舊金山灣猶他州總部去,但是他並不想搬家到那裡去。於是他後來加入了Xerox PARC與Martin Newell一起工作。他們重寫了Design System開發出了用於VLSI設計和字型與圖形列印研究的JaM(John and Martin)系統。這項工作後來發展成為一個名為InterPress的擴充系統。

在1982年12月Warnock和Chuck Geschke一起離開建立了Adobe Systems公司。他們開發了一種類似於InterPress名為PostScript的更簡單的語言,這種產品在1984年推向市場。大概在這個時候,Steve Jobs參觀了他們的工作,他敦促他們改進PostScript作為驅動雷射印表機的語言,它添加到Canon印表機誕生了LaserWriter。

1985年3月,Apple LaserWriter是第一款帶有PostScript的印表機,這也帶來了1980年代中期的桌面印刷革命。它的技術優點和廣泛應用使得PostScript成為列印應用領域影像輸出的一個選擇。直到1990年代,PostScript語言直譯器,有時稱作Raster image processor,曾經一度成為雷射印表機的一個普通組成部分。

隨著使用電子方式發布文件最終版本成為事實上的標準,PostScript就在這個領域不斷地被它的後續版本Portable Document Format也就是PDF所超越,到了2001年更少有印表機支援PostScript,這主要是由於來自於非PostScript的廉價噴墨印表機的不斷加劇的競爭(PostScript直譯器將大幅度地增加印表機成本),以及在電腦上使用軟體彩現PostScript圖像的新方法可以用於任何的印表機,PDF就是這種方法之一。然而使用PostScript的雷射印表機仍然可以大幅度地減少電腦在列印、從電腦到印表機傳輸彩現出的PostScript圖像方面的工作量。

PostScript經歷了兩次主要的更新。第一版稱為PostScript Level 1在1984年發布。PostScript Level 2在1991年發布,它有幾項增強的特性:提升了速度和可靠性;支援RIP內的分割;支援解壓縮,這就意味著如JPEG這樣的圖像能夠直接在PostScript程式中進行處理;支援複合字型以及快取重用內容的Form機制。PostScript Level 3在1997年年底出現,許多舊版運算子變成了基於字典的新版本,它提供了更好的顏色處理以及新的允許在程式內進行壓縮和解壓的過濾器、程式chunking以及先進的錯誤處理。

在列印中的應用

PostScript之前

在PostScript出現之前,印表機設計成將字元——通常是ASCII字元——列印出來。有許多技術用於這項工作,但是大多數都有一個共性也就是字元在物理上很難更改,就像在打字機鍵上的金屬或者光學平板那樣的條帶。

隨著點陣印表機的流行發生的一些變化,在這些系統上字元是用一系列的點「畫」出來的,這些點在印表機中定義為字型表。隨著他們越來越複雜,點陣印表機開始包含有幾種內建的字型,使用者可以選擇所用字型,有一些型號甚至允許使用者下載自己的字元圖形到印表機中。

點陣印表機也帶有列印光柵圖形的能力,圖形在電腦上進行解釋並且使用一系列的跳脫序列將它們按照一系列的點傳送到印表機。這種印表機控制語言隨著印表機的不同而不同,這就要求程式設計師建立許許多多的驅動程式

真正的圖形列印是名為繪圖儀的特殊的裝置所完成的,繪圖儀的確是共享一種常見的語言——HPGL,但是除了列印圖形之外並沒有多大用途。另外,它們通常價格昂貴,速度較慢,所以使用很少。

PostScript列印

PostScript將印表機和繪圖儀的優點組合在一起從而打破了傳統。同繪圖儀一樣,PostScript具有高品質的曲線處理能力並且控制語言簡單能夠用於不同品牌的印表機;同點陣印表機一樣,PostScript提供了一個生成文字和光柵圖形的簡單方法。與它們二者不同的是,PostScript能夠將所有這些不同的內容放在同一頁上,這樣就比以前的印表機或者繪圖儀提供了更具靈活性。

PostScript已經超出了普通的印表機控制語言,並成為一個完善的程式語言。許多應用程式能夠將文件傳送到一個PostScript程式中,它的輸出結果就是原始文件。這個程式能夠傳送到印表機中的直譯器上得到列印文件,或者傳送到另外一個應用程式在螢幕上顯示文件。由於文件程式與目的地無關,所以就被稱為「與裝置無關」。

PostScrip也非常擅長於實現柵格化;所有的東西,甚至是文字都可以用直線和三階貝塞爾曲線表示,貝塞爾曲線以前只有在CAD應用中才能見到,它允許任意的縮放、旋轉或者其他變換。當解釋PostScript程式的時候,直譯器將這些指令轉換成所需的點形成輸出內容。

字型處理

同PostScript一樣複雜的是它的字型處理。豐富的字型系統使用PS基本圖形將字元畫成藝術線條,藝術線條能夠在任意的解析度生成。儘管這聽起來是很直觀的概念,但是需要考慮許許多多的拓撲圖形問題。

其中一個問題是字型在小尺寸的時候實際上並不是進行線性縮放,如果那樣的話字型的某些部分就會不成比例地過大或者過小從而字型看起來不太正確。PostScript使用與字形曲線儲存在一起的隱含資訊(Hints)避免了這個問題的發生,它們基本上是水平或者豎直方向條帶上一些附加資訊,用以標識光柵圖像生成器需要維護的字型中的重要特徵。甚至在很低的解析度的時候字型也是非常好看;通稱為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字型的規範。如Altsys Fontographer(1995年1月被Macromedia收購,自從2005年5月歸FontLab所有)這樣的零售系統加入了建立Type 1字型的能力。從那時開始,就出現了許多免費Type 1字型,例如TeX排版系統中所用字型就是這種格式。

在1990年代早期還有其他幾種基於字形的字型系統,如Bitstream和METAFONT開發的系統,但是它們都不包括通用的列印解決方案,所以並沒有得到廣泛應用。

在1990年代,Adobe和微軟公司一同開發OpenType,它基本上是Type 1和TrueType格式功能的超集。當列印到PostScript輸出裝置的時候,OpenType字型中不需要的部分就會被丟棄,驅動程式送到裝置的內容與傳送TrueType或者Type 1字型完全一樣,根據OpenType字型中的外形不同而有所不同。

其他實現

在1980年代,Adobe利潤的絕大部分都來自於用於印表機的PostScript實現(稱為光柵圖像處理器或者RIP)的高昂授權費用。RIP相當昂貴,並且通常只在少數一些特定的硬體上執行。1980年代中期隨著許多基於RISC的新平台出現,Adobe經常是在支援新機器方面落後一步。

因此第三方的PostScript實現變得很普遍,尤其是在授權費用是關鍵癥結的低階印表機或者新硬體激發更快速度要求的高階排版裝置領域更加常用。一方面,微軟公司和蘋果公司聯合起來努力將Adobe從獨霸印表機的位置拉下馬,微軟公司將它購買的TrueImage PostScript直譯器授權給蘋果公司,蘋果公司將它的新字型格式TrueType授權給微軟公司。(蘋果公司終止了與Adobe保持一致以及它的印表機使用Adobe公司真正的PostScript的策略,但是TrueType在微軟視窗和Macintosh上都成為了標準的outline font。)一些第三方的PostScript的克隆產品仍在廣泛使用,尤其是在作為惠普黑白雷射印表機標準Phoenix Page的中仍在廣泛使用。

許多基本的廉價雷射印表機不支援PostScript,它們的驅動程式根本不使用PostScript。當需要在這樣的印表機上使用PostScript時可以使用名為Ghostscript的PostScript直譯器,這是一個自由軟體。Ghostscript使用主電腦的CPU進行光柵化處理、將結果作為一個大幅的點陣圖傳送到電腦這樣一種方式在非PostScript印表機上列印PostScript文件。Ghostscript也可以在電腦顯示器上預覽PostScript文件以及將PostScript轉換成如TIFFPNG這樣的光柵圖形或者如PDF這樣的向量格式。

解析度非常高的裝置,如imagesetter或者CTP platesetter超過2500dpi的解析度也很常見,仍然需要帶有大量記憶體和磁碟空間的外部光柵圖像處理器。許多稱為數字印刷的高階雷射印表機系統也使用外部光柵圖像處理器將容易升級的電腦系統與特定的列印硬體分開。如EFI頁面存檔備份,存於網際網路檔案館)和Xitron頁面存檔備份,存於網際網路檔案館)這樣的公司專業從事這樣的光柵圖像處理器軟體開發。

作為顯示系統的應用

隨著PostScript成為列印輸出的事實標準,很自然人們也希望將它用來描述螢幕輸出。1980年代後期CPU效能的快速提升以及人們對於視窗系統興趣的逐漸增加,促使人們多次試圖開發使用PostScript作為主要的顯示技術的顯示系統。

使用PS作為顯示系統有許多優點,其中之一就是在其他系統上使用者不僅僅要為螢幕顯示保留點陣圖,而且要為印表機保留Type 1字型,在顯示器上使用PS只需要保留一套從而可以彌補這個缺點。另外一個優點是就是允許「dumbling down」印表機。當LaserWriter發布的時候它是蘋果公司產品線中功能最為強大也是最為昂貴的機器,這樣它就需要相當大的處理能力和記憶體以在合理的時間內生成高達300dpi解析度的頁面。與之形成對比的是,使用NeXT平台的400dpi印表機根本都沒有CPU,相反它是使用電腦的CPU進行頁面生成,然後將生成的頁面點陣圖傳送到印表機。

但是使用PostScript作為視窗系統的一個更為主要的優點是他讓使用者使用一組圖形處理子程式就可以開發桌面印刷和其他大量使用圖形的應用程式,在視窗上進行描畫的程式同樣也可以不經任何轉換直接在印表機上描畫。傳統系統上的桌面印刷應用程式要求程式設計師在各個平台的圖形系統上構建圖形化使用者介面(如Macintosh上的QuickDraw和微軟視窗上的圖形裝置介面(GDI))編輯器,然後編寫另外的程式將圖形轉換成正確的PostScript語言用於列印。這樣的工作通常就會消耗專案的大部分編程工作,並且是程式錯誤的主要來源。

使用PostScript作為顯示技術的兩個主要的例子是Display PostScriptDPS)和NeWS,它們兩者戲劇性地在在哪裡應用顯示邏輯發生了分歧,在DPS中view系統留給了OS去處理,然而在NeWS上整個顯示系統是用用PS寫成的並且在一個單一的複雜直譯器中執行。

PostScript語言

PostScript是一種圖靈完全的程式語言,通常PostScript程式不是人為生成的,而是由其他程式生成的。然而,仍然可以使用手工編制的PostScript程式生成圖形或者進行計算。

PostScript是一種基於堆疊的解釋語言,它類似於Forth語言但是使用從Lisp語言衍生出的資料結構。這種語言的語法使用逆波蘭表示法,這就意味著不需要括號進行分割,但是因為需要記住堆疊結構,所以需要進行訓練才能閱讀這種程式。大部分運算子(其他程式中稱為函式)從堆疊中讀取變數,並且將運算結構放到堆疊中。如數字這樣的符號字面值具有將它們自身副本放到堆疊的效果。

演算法

例如:

 3 4 add 5 1 sub mul

將執行 (3 + 4) × (5 - 1)這樣的計算。

讓我們詳細地分析一下這是如何完成的:

3和4都是符號,它們將自己放到堆疊中,在這兩個命令之後,堆疊將變成這樣:

4
3

add是一個運算子,它將堆疊中最上面的兩個元素取出(在我們的例子中是3和4)、將它們相加、然後將結果放到堆疊上:

7

下面又是兩個符號,它們將把堆疊變成這樣(需要注意的是操作僅僅局限在堆疊頂部,下面的元素不受影響):

1
5
7

另外一個運算子sub,從堆疊頂取出兩個元素、第二個減去第一個、然後將結果放到堆疊:

4
7

很顯然mul同其他兩個運算子一樣,從堆疊取出兩個元素、將它們的乘積放到堆疊:

28

命名變數

上面的例子只是一個古老的逆波蘭表示法計算,當然PostScript也使用變數。詳細地說就是它有一個字典用來尋找所有不是符號的東西;如果查到的話,那個名字下儲存的值就會壓縮到棧中(或者更應該說是執行——參見後面的內容);找不到就返回錯誤。將一個變數放到字典中需要使用def運算子,它用一個名字和一個值作為參數,通過在前面使用斜線構建一個名字。因此

 /x1 15 def

首先將名字「x1」放到堆疊上、然後是值15、然後執行def,它將從堆疊中取出「x1」和15,並且將15寫到字典中「x1」的下面。後面出現的「x1」(注意不要與「/x1」混淆)將會將15放到堆疊而變數並不改變。下面的代碼會將x1的值增加2:

/x1 x1 2 add def

堆疊運算子

PostScript有幾個運算子用於重組或者控制堆疊:複製(dup)、丟棄(pop)和交換(exch)在堆疊頂部進行操作,然而roll旋轉堆疊中的某一部分,copy複製某個特定的部分,index允許象陣列那樣存取堆疊。

處理過程定義

{」和「}」提供了一些編程的工具。「{」將直譯器切換到延遲執行模式,所有的東西甚至是運算子和其他的可執行物件都放到堆疊中,其中一個例外就是「}」,它將堆疊中從「{」開始的所有內容,繫結成一個(匿名)處理過程,然後將它放到堆疊上。

這種結構有幾種不同的用途,如子程式定義(匿名程式賦給一個變數)、迴圈、條件等等:

x1 0 eq { 0 } { 1 x1 div } ifelse

這段代碼首先使用eq測試x1是否是0;根據結果的不同將或者放到堆疊上。在此之後,將兩個過程放到堆疊上,然後執行ifelse,它從堆疊中取出三個參數,如果第三個參數是就執行第二個否則就執行第一個。總之,如果x1是0結果就是0, 其他情況結果就是1/x1。

圖形操作

在生成圖形的時候,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度。

字元「%」用來在PostScript程式中表示注釋。作為一個通用的約定,每個PostScript都以字元「%!」開始這樣所有的裝置都會將它解釋為PostScript。

參考文獻

本條目部分或全部內容出自以GFDL授權發佈的《自由線上電腦詞典》(FOLDOC)。

外部連結

PostScript hacks

#