PostScript

PostScript（PS）是主要用於電子產業和桌面出版領域的一種頁面描述語言和程式語言。

## 歷史

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轉換成如TIFF和PNG這樣的光柵圖形或者如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 PostScript（DPS）和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語言手冊第三版（PLR3），以及 補充，是事實上規範性文件，根據它的封面顏色通常稱為「紅皮書」。第一版包括PostScript Level 1，第二版包括稱為PostScript Level 2的擴展版本以及Display PostScript的文檔，第三版包括PostScript 3（這一版Adobe放棄了名字中的「level」）但是不再包括DPS。
- PostScript語言教程與手冊是相應的入門圖書，根據封面封面顏色通常稱為「藍皮書」。
- PostScript語言程序設計是相應的入門圖書，通常稱為「綠皮書」。
- PostScript入門導引介紹PostScript系統入門書籍。
- 數學圖表：幾何與PostScript手冊—Bill Casselman著。
- Thinking in PostScript，1990年Glenn Reid, Addison-Wesley著—available online courtesy of the author.這是一個詳盡的教程。
- PS-to-PDF轉換器，使用Ghostscript將Postscript轉換成PDF的在線轉換器。
- Type 1字體格式，PDF格式。
- T.Greer PrintForum，PostScript編程論壇和討論社區。
- http://www.planiglobe.com/ free (CC by/sa) PostScript Maps

### PostScript hacks

- Life in PostScript - a PostScript version of Conway's Game of Life
- PS-HTTPD - a webserver written in PostScript
- PostScript fractals
- PostScript barcodes
- PostScript HTML renderer
- A PostScript raytracer，from Ray Tracing News, September 5 1988, Volume 1, Number 8 .

## 基本資料

- 域：PostScript 3標誌
- 編程范型：多範式：面向堆棧，過程式
- 發行時間：1982
- 設計者：John Warnock & Chuck Geschke
- 開發者：Adobe系統
- 軟體版本週期：PostScript 3
- 軟體版本週期：1997
- turing-complete：Yes
- 類型系統：動態，強類型
- 軟體實現：Adobe PostScript, TrueImage, Ghostscript, InterPress
- 受影響於：Lisp
- 施影響於：PDF
- 擴展名：.ps
- mime：application/postscript
- 統一類型標識：com.adobe.postscript
- magic：`%!`
- 所有者：Adobe系統
- 類型：列印文件格式
- 擴展為：EPS