複製鏈接
請複製以下鏈接發送給好友

PostScript語言

鎖定
PostScript(PS)是主要用於電子產業和桌面出版領域的一種頁面描述語言和編程語言。 PostScript是Adobe公司開發的一種設備無關的打印機程序語言,用來驅動數字印刷機和顯示。
中文名
PostScript語言
應用領域
電子產業和桌面出版
類    型
頁面描述語言和編程語言
作    用
驅動數字印刷機和顯示

PostScript語言發展歷史

PostScript語言的思想起源於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名為PostScript的更簡單的語言,這種產品在1984年推向市場。大概在這個時候,Steve Jobs參觀了他們的工作,他敦促他們改進PostScript作為驅動激光打印機的語言,它添加到Canon打印機誕生了LaserWriter。
1985年3月,AppleLaserWriter是第一款帶有PostScript的打印機,這也帶來了二十世紀八十年代中期的桌面印刷革命。它的技術優點和廣泛應用使得PostScript成為打印應用領域影像輸出的一個選擇。直到二十世紀九十年代,PostScript語言解釋器(有時稱作rip(光柵圖像解釋器))曾經一度成為激光打印機的一個普通組成部分。
隨着使用電子方式發佈文檔最終版本成為事實上的標準,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語言之前

在PostScript出現之前,打印機設計成將字符——通常是ASCII字符——打印出來。有許多技術用於這項工作,但是大多數都有一個共性也就是字符在物理上很難更改,就像在打字機鍵上的金屬或者光學平板那樣的條帶。
隨着點陣打印機的流行發生的一些變化,在這些系統上字符是用一系列的點“畫”出來的,這些點在打印機中定義為字體表。隨着他們越來越複雜,點陣打印機開始包含有幾種內置的字體,用户可以選擇所用字體,有一些型號甚至允許用户下載自己的字符圖形到打印機中。
點陣打印機也帶有打印光柵圖形的能力,圖形在計算機上進行解釋並且使用一系列的轉義序列將它們按照一系列的點發送到打印機。這種打印機控制語言所這打印機的不同而不同,這就要求程序員創建許許多多的驅動程序
真正的圖形打印是名為繪圖儀的特殊的設備所完成的,繪圖儀的確是共享一種常見的語言——HPGL,但是除了打印圖形之外並沒有多大用途。另外,它們通常價格昂貴,速度較慢,所以使用很少。

PostScript語言打印

PostScript將打印機和繪圖儀的優點組合在一起從而打破了傳統。同繪圖儀一樣,PostScript具有高質量的曲線處理能力並且控制語言簡單能夠用於不同品牌的打印機;同點陣打印機一樣,PostScript提供了一個生成文本和光柵圖形的簡單方法。與它們二者不同的是,PostScript能夠將所有這些不同的內容放在同一頁上,這樣就比以前的打印機或者繪圖儀提供了更具靈活性。
PostScript已經超出了普通的打印機控制語言,併成為一個完善的編程語言。許多應用程序能夠將文檔傳送到一個PostScript程序中,它的輸出結果就是原始文檔。這個程序能夠發送到打印機中的解釋器上得到打印文檔,或者發送到另外一個應用程序在屏幕上顯示文檔。由於文檔程序與目的地無關,所以就被稱為“與設備無關”。
PostScrip也非常擅長於實現光柵化;所有的東西,甚至是文本都可以用直線和立方貝塞爾曲線表示,貝塞爾曲線以前只有在CAD應用中才能見到,它允許任意的縮放、旋轉或者其他變換。當解釋PostScript程序的時候,解釋器將這些指令轉換成所需的點形成輸出內容。

PostScript語言字體處理

同PostScript一樣複雜的是它的字體處理。豐富的字體系統使用PS基本圖形(:en:graphics primitives)將字符畫成藝術線條,藝術線條能夠在任意的分辨率生成。儘管這聽起來是很直觀的概念,但是需要考慮許許多多的拓撲圖形問題。
其中一個問題是字體在小尺寸的時候實際上並不是進行線性縮放,如果那樣的話字體的某些部分就會不成比例地過大或者過小從而字體看起來不太正確。PostScript使用與字形曲線保存在一起的隱含信息避免了這個問題的發生,它們基本上是水平或者豎直方向條帶上一些附加信息,用以標識光柵圖像生成器需要維護的字體中的重要特徵。甚至在很低的分辨率的時候字體也是非常好看;通常認為這是手工字體位圖調整才能完成的任務。
當時,在字體中包含這種隱含信息的技術被細心地維護着,包含隱含信息的字體經過壓縮、加密成為AdobeType 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和TrueType格式功能的超集。當打印到PostScript輸出設備的時候,OpenType字體中不需要的部分就會被丟棄,驅動程序送到設備的內容與傳送TrueType或者Type 1字體完全一樣,根據OpenType字體中的外形不同而有所不同。

PostScript語言其他實現

在二十世紀八十年代,Adobe利潤的絕大部分都來自於用於打印機的PostScript實現(稱為光柵圖像處理器或者RIP)的高昂授權費用。RIP相當昂貴,並且通常只在少數一些特定的硬件上運行。二十世紀八十年代中期隨着許多基於RISC的新平台出現,Abobe經常是在支持新機器方面落後一步。
因此第三方的PostScript實現變得很普遍,尤其是在授權費用是關鍵癥結的低端打印機或者新硬件激發更快速度要求的高端拍板設備領域更加常用。一方面,微軟公司和蘋果公司聯合起來努力將Adobe從獨霸打印機的位置拉下馬,微軟公司將它購買的TrueImagePostScript解釋器授權給蘋果公司,蘋果公司將它的新字體格式TrueType授權給微軟公司。(蘋果公司終止了與Adobe保持一致以及它的打印機使用Adobe公司真正的PostScript的策略,但是TrueType在微軟視窗和Macintosh上都成為了標準的outline font。)一些第三方的PostScript的克隆產品仍在廣泛使用,尤其是在作為惠普黑白激光打印機標準Phoenix Page的中仍在廣泛使用。
許多基本的廉價激光打印機不支持PostScript,它們的驅動程序根本不使用PostScript。當這樣的打印機需要支持PostScript的使用,可以使用名為Ghostscript自由軟件PostScript解釋器。Ghostscript使用主計算機的CPU進行rasterization、將結果作為一個大幅的位圖發送到計算機這樣一種方式在非PostScript打印機上打印PostScript文檔。Ghostscript也可以在計算機顯示器上預覽PostScript文檔以及將PostScript轉換成如TIFFPNG這樣的光柵圖形或者如PDF這樣的矢量格式。
分辨率非常高的設備,如imagesetter或者CTPplatesetter超過2500dpi的分辨率也很常見,仍然需要帶有大量內存和磁盤空間的外部光柵圖像處理器。許多稱為數字印刷的高端激光打印機系統也使用外部光柵圖像處理器將容易升級的計算機系統與特定的打印硬件分開。如EFI和Xitron這樣的公司專業從事這樣的光柵圖像處理器軟件開發。

PostScript語言系統應用

隨着PostScript成為打印輸出的事實標準,很自然人們也希望將它用來描述屏幕輸出。二十世紀八十年代後期CPU性能的快速提升以及人們對於視窗系統興趣的逐漸增加,促使人們多次試圖開發使用PostScript作為主要的顯示技術的顯示系統。
使用PS作為顯示系統有許多優點,其中之一就是在其他系統上用户不僅僅要為屏幕顯示保留位圖,而且要為打印機保留Type 1字體,在顯示器上使用PS只需要保留一套從而可以彌補這個缺點。另外一個優點是就是允許“dumbling down”打印機。當LaserWiter發佈的時候它是蘋果公司產品線中功能最為強大也是最為昂貴的機器,這樣它就需要相當大的處理能力和內存以在合理的時間內生成高達300dpi分辨率的頁面。與之形成對比的是,使用NeXT平台的400dpi打印機根本都沒有CPU,相反它是使用計算機的CPU進行頁面生成,然後將生成的頁面位圖傳送到打印機。
但是使用PostScript作為視窗系統的一個更為主要的優點是它讓用户使用一組圖形處理子程序就可以開發桌面印刷和其它大量使用圖形的應用程序,在視窗上進行描畫的程序同樣也可以不經任何轉換直接在打印機上描畫。傳統系統上的桌面印刷應用程序要求程序員在各個平台的圖形系統上構建圖形用户接口(如Macintosh上的QuickDraw和微軟視窗上的圖形設備接口(GDI))編輯器,然後編寫另外的程序將圖形轉換成正確的PostScript語言用於打印。這樣的工作通常就會消耗項目的大部分編程工作,並且是程序錯誤的主要來源。
使用PostScript作為顯示技術的兩個主要的例子是Display PostScript(DPS)和NeWS,它們兩者戲劇性地在在哪裏應用顯示邏輯發生了分歧,在DPS中view系統留給了OS去處理,然而在NeWS上整個顯示系統是用用PS寫成的並且在一個單一的複雜解釋其中運行。

PostScript語言編程語言

PostScript是一個Turing-complete編程語言,通常PostScript程序不是人為生成的,而是由其他程序生成的。然而,仍然可以使用手工編制的PostScript程序生成圖形或者進行計算。
PostScript是一個基於堆棧的解釋語言(例如stack language),它類似於Forth語言但是使用從Lisp語言派生出的數據結構。這種語言的語法使用逆波蘭表示法,這就意味着不需要括號進行分割,但是因為需要記住堆棧結構,所以需要進行訓練才能閲讀這種程序。大部分運算符(其它程序中稱為函數)從堆棧中讀取變量,並且將運算結構放到堆棧中。如數字這樣的符號:en:Literal具有將它們自身副本放到堆棧的效果。

PostScript語言算法

例如:
3 4 add 5 1 sub mul將執行 (3 + 4) × (5 - 1) 這樣的計算。
讓我們詳細地分析一下這是如何完成的:
3 和 4 都是符號,它們將自己放到堆棧中,在這兩個命令之後,堆棧將變成這樣:
43add是一個運算符,它將堆棧中最上面的兩個元素取出(在我們的例子中是3和4)、將它們相加、然後將結果放到堆棧上:
7下面又是兩個符號,它們將把堆棧變成這樣(需要注意的是操作僅僅侷限在堆棧頂部,下面的元素不受影響):
157另外一個運算符sub,從堆棧頂取出兩個元素、第二個減去第一個、然後將結果放到堆棧:
47很顯然mul同其它兩個運算符一樣,從堆棧取出兩個元素、將它們的乘積放到堆棧:
28
Named variables
上面的例子只是一個古老的逆波蘭表示法計算,當然PostScript也使用變量。詳細地説就是它有一個字典用來查找所有不是符號的東西;如果查到的話,那個名字下保存的值就會壓縮到棧中(或者更應該説是執行——參見後面的內容);找不到就返回錯誤。將一個變量放到字典中需要使用def運算符,它用一個名字和一個值作為參數,通過在前面使用斜線構建一個名字。因此
/x1 15 def首先將名字“x1”放到堆棧上、然後是值15、然後執行def,它將從堆棧中取出“x1”和15,並且將15寫到字典中“x1”的下面。後面出現的“x1”(注意不要與“/x1”混淆)將會將15放到堆棧而變量並不改變。下面的代碼會將x1的值增加2:
/x1 x1 2 add def

PostScript語言堆棧運算符

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

PostScript語言處理過程定義

{}提供了一些編程的工具。{解釋器切換到延遲運行模式,所有的東西甚至是運算符和其它的可執行對象都放到堆棧中,其中一個例外就是},它將堆棧中從{開始的所有內容,綁定成一個(匿名)處理過程,然後將它放到堆棧上。
這種結構有幾種不同的用途,如子程序定義(匿名程序賦給一個變量)、循環、條件等等:
x1 0 eq { 0 } { 1 x1 div } ifelse這段代碼首先使用eq測試 x1 是否是 0;根據結果的不同將或者放到堆棧上。在此之後,將兩個過程放到堆棧上,然後執行ifelse,它從堆棧中取出三個參數,如果第三個參數是就執行第二個否則就執行第一個。總之,如果 x1 是 0 結果就是 0, 其他情況結果就是 1/x1。
/inc3 { 3 add } defHeredefis used to place something in thedictionary, only this time it is a procedure instead of a simple integer. This works because the values coming from the dictionary areexecuted, 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, sinceaddneeds 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。

PostScript語言圖形操作

To produce graphics, PostScript 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 度。
字符“%”用來在PostScript程序中表示註釋。作為一個通用的約定,每個PostScript都以字符“%!”開始這樣所有的設備都會將它解釋為PostScript。