PostScript 常見問題解答/使用 PostScript
在以下幾種情況下,PostScript 印表機是理想的選擇:
- 你需要列印包含已放置 EPS 檔案的文件
- 你從第三方接收列印作業,並且需要可移植的 頁面描述語言
- 你期望列印可變內容文件
- 桌面印表機充當更昂貴的印表機或影像設定器的廉價校樣機
- 向量頁面描述比頁面柵格影像要短得多
- 你執行的是 類 Unix 系統,其中 PostScript 語言充當印表機 API。
帶有非 PostScript 印表機的軟體 RIP 正在成為 PostScript 印表機的一個很好的替代方案。與內建的 RIP 不同,軟體和硬體可以輕鬆升級。主機作業系統還提供了更好的除錯環境。
PostScript 是一種低階的 頁面描述語言。PostScript 圖形模型基於表示元素:線條、曲線、字元、影像。它沒有單詞、段落、對齊、腳註等概念。大多數作者更喜歡在更高層次上工作,並從高階頁面描述生成表示格式(PostScript、PDF、PCL 等)。
TeX 是一種排版程式,專為高質量地編排包含大量數學和技術表示式的材料而設計。它已被許多作者和出版商採用,他們用來生成技術書籍和論文。它是由斯坦福大學的唐納德·克努斯教授建立的,最初是為了準備他的書籍系列《計算機程式設計藝術》。
groff(GNU troff)軟體是一個排版軟體包,它讀取混合有格式化命令的純文字並生成格式化的輸出。
在 Mac OS 和 Microsoft Windows 上的 PostScript 印表機驅動程式可以從傳入的 GDI 呼叫生成 PostScript 檔案。因此,所有可以列印的應用程式也可以生成 PostScript。但是,檔案中的圖形原語集將受到 GDI 圖形模型的限制。大多數圖形編輯器和 DTP 應用程式繞過 GDI 並直接生成 PostScript。這有助於生成更好的 PostScript,併為應用程式提供更靈活的圖形模型。
有時,需要手動建立或修改 PS 檔案。PostScript 檔案可能很大,並且包含二進位制資料。文字編輯器不應該擴充套件製表符或標準化行尾。emacs 是一個不錯的選擇,因為它可擴充套件並且包含 PostScript 主模式。
在類 Unix 系統上,你可以使用 lpr
lpr -S computer_name -P queuename filename.ps
在 Microsoft Windows 上,你可以將檔案傳送到印表機,如下所示:
copy /b filename.ps lpr1
或
copy /b filename.ps \\computer_name_or_ip\printersharename
一些印表機也支援 lpr 協議。
PrintFile 是一個免費的 GUI Windows 程式,它將檔案複製到系統列印佇列。它也可以從符合 DSC 的 PostScript 檔案中選取頁面。
在 Classic Mac OS 上,你可以將檔案拖放到印表機圖示上。
PostScript 檔案是為順序列印而設計的 - 影像通常儲存為內聯流,頁面大小和解析度是頁面描述的一部分。
檢視器應該以隨機順序和放大倍數瀏覽文件。這可以透過將 PostScript 轉換為內部形式來實現,該內部形式允許直接訪問頁面元素,並快速裁剪不可見的物體。沒有一個 PostScript 檢視器以這種方式工作。
GSview 是由 Ghostgum Software 的 Russel Lang 開發的 Ghostscript 的免費圖形介面。頁面選擇是透過 DSC 處理實現的;縮放是透過重新解釋頁面實現的。GSview 可用於 Win32、Win32s、OS/2 和 GNU/Linux。舊版本可用於 Win16。還有其他用於 Ghostscript 的圖形 X 視窗前端 - 例如 mgv、Moonshiner 和 Okular。
PostScript 可以使用 Ghostscript、ps2pdf 線上、Distiller、PDFCreator 和其他幾個程式輕鬆轉換為 PDF。與 PS 檢視器相比,PDF 檢視器要多得多。此外,PDF 檢視器通常比大多數 PS 檢視器更友好,因此檢視 PS 檔案最方便的方法是先將其轉換為 PDF 檔案。最流行的免費 PDF 檢視器是 Adobe Reader、Evince、Foxit Reader、MuPDF、Okular、PDF-XChange Viewer、Sumatra PDF 和 Xpdf。
許多網路印表機不接受包含二進位制資料的 PS 檔案。
有時不可能將檔案重新建立為 7 位 ASCII,但任何檔案都可以輕鬆地轉換為 ASCII 流,並透過相應的解碼過濾器執行。以下指令碼將標準輸入轉換為十六進位制流,並新增解碼程式碼。所有 DSC 註釋都將被隱藏,但大多數印表機都會忽略它們。該指令碼在 bash 和 GNU/Linux 系統上進行了測試。
#! /bin/sh
echo '%!'
echo 'currentfile /ASCIIHexDecode filter cvx exec'
od -A n -v -t x1
echo '>'
MS-DOS 和 Windows 的指令碼版本必須從自身中讀取 '>' 字元,因為 echo ">" 列印 ">"(帶引號)。
@echo off
rem ">"
echo %%!
echo currentfile /ASCIIHexDecode filter cvx exec
od -A n -v -t x1
od -A n -v -t c -j 16 -N 1 %0
od(八進位制轉儲)來自 GNU Textutils 包。它在所有預設的類 Unix 系統(包括 macOS)上可用,並且可以使用 Cygwin 或 MinGW 包在 Windows 上安裝。
PostScript 實用程式可以使用 PostScript 語言輕鬆程式設計。以下程式讀取輸入檔案或標準輸入,壓縮它,可選地使用 ASCII85 編碼進行轉換,然後寫入輸出檔案或標準輸出。該程式由 Ghostscript 執行,使用:
gs -q [-dASCII] [-dLEVEL3] -- encode.ps [INFILE [OUTFILE]]
其中
-q禁止將版權資訊寫入 stdout-dASCII選擇 ASCII85 編碼-dLEVEL3選擇在 3 級中引入的 Flate 編碼encode.ps是程式INFILE是輸入檔案,預設為 stdinOUTFILE是輸出檔案,預設為標準輸出。
%!
% encode.ps - compress and encode PS file to reduce upload time.
% This won't work if the file contains multiple jobs separated by ^D
%
/stderr (%stderr)(w) file def
/error { stderr exch writestring } bind def
/closetarget <</CloseTarget true>> readonly def
%
/openfile % fname mode -> file
{ { file } stopped
{ exch (Cannot open file: ) error error (w) eq { (for writing\n) } { (for reading\n) } ifelse error
flush quit
}
if
} bind def
%
/main % - -> -
{ mark shellarguments
{ counttomark 2 le
{ counttomark
{ { (%stdin)(r) file (%stdout)(w) file }
{ (r) openfile (%stdout)(w) file }
{ (w) openfile exch (r) openfile exch }
}
exch get exec dup % input output output
//systemdict /ASCII .knownget dup { true eq and } if
{ //closetarget /ASCII85Encode filter
(/ASCII85Decode filter)
}
{ () }
ifelse
exch % input output () output
//systemdict /LEVEL3 .knownget dup { true eq and } if
{ //closetarget /FlateEncode filter exch
(/FlateDecode filter)
}
{ //closetarget /LZWEncode filter exch
(/LZWDecode filter)
}
ifelse
concatstrings % input output output ()
2 index (%!\ncurrentfile) writestring
2 index exch writestring
exch ( cvx exec\n) writestring
exch 61440 string % output input buf
{ 3 copy readstring pop % output input buf output buf
dup () eq { pop pop exit } if
writestring
}
loop
pop closefile closefile false
}
{ (Incorrect number of file name arguments.\n) error true
}
ifelse
}
{ (Missing '--' preceding encode.ps\n) error true
}
ifelse
{ (Usage: gs -q -dASCII -dLEVEL3 -- encode.ps INFILE OUTFILE\n) error flush
}
if
} bind def
%
main clear quit
如果需要,可以在將檔案下載到印表機之前進行 DSC 處理。開發一個基於 ASCII85 的 DSC 感知轉換器留給讀者作為練習。
封裝 PostScript,或 EPS 檔案,通常用於包含在可列印的 PostScript 或其他 EPS 檔案中。與可列印的 PostScript 不同,它們可能具有
showpage運算子未包含- 影像移出可列印區域
- 影像大小過大或過小
- PC 風格的標題和預覽
因此,直接將 EPS 檔案傳送到 PostScript 印表機可能會導致 PostScript 錯誤或僅列印頁面。
標準方法是在圖形設計應用程式中將 EPS 放置在頁面中,然後列印。
為了直接列印 EPS 檔案,您需要新增一個 PS 標題,它將執行所有必要的調整。
cat header.ps file.eps | lpr
在 net.anastigmatix.Import 資源頁面上給出了一個合適的標題作為示例。
將檔案傳送到 PostScript 直譯器。如果您喜歡結果,則該檔案有效。PostScript 直譯器包括
- 任何 PostScript 印表機
- Ghostscript
- Acrobat Distiller
- 顯示 PostScript
當然還有其他的,但這些是最簡單/最便宜的獲取方式。
事實上,這將只檢查 PostScript 程式在經過測試的直譯器上的正確性。不同的直譯器提供非常不同的執行環境,這會使 PS 程式採用不同的分支。
PostScript 程式可能會產生意外的輸出,而不會報告任何 PostScript 錯誤。在關鍵任務情況下,必須在雷射印表機上列印並由設計人員簽署的校樣。
使用 bbox 裝置解釋檔案並計算 HiResBoundingBox 行。
gs -q -dNOPAUSE -dBATCH -sDEVICE=bbox foo.ps 2>&1 | grep -c HiResBoundingBox
命令也比較快
yes | gs -q -dBATCH -sDEVICE=nullpage foo.ps | grep -c showpage
假設文件符合 DSC,可以直接在文件中計算 %%Page 註釋。
grep -c %%Page: file.ps
首先,您需要決定是什麼使頁面成為彩色頁面。可能,單色頁面在 CMY 分量的密度為零。要使用 Ghostscript 檢查這一點,您需要選擇一個真彩色 CMYK 裝置,安裝正確的 CRD 並光柵化檔案。
如果任何畫素在 CMY 平面中具有非零分量,則該頁面為彩色頁面。
DSC(文件結構約定)旨在提供一種簡單的方法來解析 PostScript 文件,重新排列頁面,新增缺失的字型,替換影像等。雖然大多數程式生成 DSC 註釋,但很少有程式使用它們。看來,即使是主要供應商也從未測試過 DSC 註釋的正確性。
有時,聲稱 DSC 符合性的文件在修改後會因 PostScript 錯誤而失敗。更糟糕的是,頁面可能會以某種微妙的方式損壞。例如,可增量下載字型的某些字元可能會被靜默替換為預設字元。
基於 DSC 註釋的頁面選擇由 PrintFile 和 GSview 使用。
PDF 可以作為一種方便的中間格式,尤其是在多次執行頁面提取時。您可以使用 Ghostscript 將檔案轉換為 PDF 並提取一定範圍的頁面,如下所示
ps2pdf input.ps output.pdf
gs -dFirstPage=1 -dLastPage=2 output.pdf
偶爾,其他圖形格式可能比 PDF 效果更好。作者曾經編寫了 bilist.cpp,將兩個 A5 頁面放在一張 A4 頁面上,並將頁面重新排列為一些舊 PCL 印表機的簽名。
有幾種方法可以解決這個問題。每種方法都有其優點。
直接操作保留了大多數 PS 結構,並且佔用最少的處理器時間。不幸的是,它僅適用於符合 DSC 的 PostScript 檔案。雖然大多數主流應用程式生成的 DSC 檔案聲稱符合 DSC,但很少有檔案經過這樣的測試。例如,Microsoft PS 驅動程式預設情況下會生成不符合規範的檔案。
來自 psutils 的 psselect 可以選擇和重新排列符合 DSC 的 PS 檔案中的頁面。
轉換為光柵影像是一種簡單可靠的方法。例如,bilist.cpp 從 PCL 檔案中提取頁面,將頁面重新排列為簽名,並將它們放置成兩頁一頁。Ghostscript 可用於 PostScript 到 PCL 的轉換。
轉換為 PDF 極大地簡化了進一步的文件處理。PDF 檔案中的頁面可以以任何大小或順序提取和列印。PostScript 檔案可以使用多種應用程式轉換為 PDF。例如,Ghostscript
ps2pdf input.ps output.pdf
要從 PDF 檔案中提取一定範圍的頁面到另一個 PDF 檔案,請使用
ps2pdf -dFirstPage#111 -dLastPage#666 input.pdf output.pdf
要從 PDF 檔案中提取一定範圍的頁面並轉換為 PS 檔案,請使用
ps2ps -dFirstPage#111 -dLastPage#666 input.pdf output.ps
將 PDF 檔案連線起來始終很安全,如下所示
gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=file.pdf \
-c save pop -f file1.dsc file2.dsc file3.dsc ...
以上方法足以以任何順序重新排列頁面,但複雜的工作可以更有效地完成。PDF 檔案可以轉換為簡單的符合 DSC 的 PS 檔案。
pdf2dsc source.pdf output.dsc
輸出檔案將非常簡單,因為所有複雜性都隱藏在 Ghostscript 庫中。使用任何 DSC 實用程式、文字編輯器或指令碼都很容易修改格式。
%!PS-Adobe-3.0
%...
/Page null def/Page# 0 def/PDFSave null def/DSCPageCount 0 def
/DoPDFPage {dup /Page# exch store pdfgetpage pdfshowpage } def
GS_PDF_ProcSet begin pdfdict begin
file.pdf) (r) file { DELAYSAFER { .setsafe } if } stopped pop
pdfopen begin
%%Page: 1 1
1 DoPDFPage
%%Page: 2 2
2 DoPDFPage
%%Trailer
currentdict pdfclose end end end
%%EOF
更新後的檔案可以轉換回 PDF。
ps2pdf source.dsc result.pdf
DSC 檔案使用 GS 庫,如果 DSC 檔案僅提供給 Ghostscript,則效果很好。要生成可移植的 PS 檔案,請將其轉換回 PS。
當驅動程式為單色印表機生成 PostScript 流時,它通常會將彩色影像轉換為灰度,以實現更好的傳輸時間、更快的渲染和更低的資源使用。將向量物件轉換為灰度不會節省太多空間或時間。因此,驅動程式將其留給 PostScript 直譯器。
當作業列印到通用 PostScript 印表機驅動程式時,這個問題經常發生。通用驅動程式不是最好的驅動程式。它僅限於大多數印表機上可用的 PostScript 語言的通用子集。它是單色的,只有少量介質、字型選擇,沒有特殊功能。來自通用驅動程式的 PostScript 檔案將在多種印表機上列印,但許多功能將缺失。
雖然看起來每臺印表機都使用特殊的驅動程式,但實際上是同一個驅動程式配置用於不同的印表機。驅動程式從 PPD 檔案中獲取配置引數。如果可能,應使用本機 PPD 檔案。Acrobat Distiller PPD 是生成不包含特定於供應商的功能的彩色 PostScript 檔案的不錯選擇。
對頁面進行光柵化並將頁面重新組合到複合檔案非常簡單。光柵化可以在每平面 8 位或每平面 1 位進行,具體取決於是否需要對複合影像進行任何顏色校正。
在向量級別合併平面要困難得多。為此工作的唯一已知工具是來自 Creo(現已停產且不受支援)的 Seps2Comp Acrobat 外掛。可以使用包括 Ghostscript 和 Acrobat Distiller 在內的許多程式將 PostScript 檔案轉換為 PDF。
Windows 驅動程式在進行 N-up 列印時會在虛擬頁面周圍生成黑框。這些框是在 `nupshowpage` 過程中繪製的。要刪除這些框,必須修改此過程。在 3 級直譯器上,`Hack-MSDriver-n-up` `IdiomSet` 可以在直譯器載入作業檔案時識別並替換此過程。不需要修改作業檔案。要啟用替換,需要將 idiom 檔案複製到印表機或基於主機的直譯器上的 `/Resource/IdiomSet/` 目錄中。基於主機的直譯器上的 PostScript 根目錄可能與系統根目錄不同。對於一次性替換,您也可以將 `IdiomSet` 檔案附加到作業檔案前面。
對於 1 級和 2 級直譯器,必須使用任何文字編輯器從作業檔案本身中刪除 `framenup { ... } if` 片段。
%!PS-Adobe-3.0
%%Title: Hack-MSDriver-n-up
% Remove black frame around n-up pages generated by MS Driver
%%VMusage: 0 0
%%VMlocation: global
%%EndComments
%%BeginResource: IdiomSet Hack-MSDriver-n-up
currentuserparams /IdiomRecognition get
<</IdiomRecognition false>> setuserparams
currentglobal true setglobal
/Hack-MSDriver-n-up
<< 8 dict begin
/; /grestore load def
/V /div load def
/@ /dup load def
/~ /exch load def
/rs /rectstroke load def
/! /pop load def
/? /ifelse load def
/+ /translate load def
/nupshowpage
[ { ; $m concat
framenup
{ pagemarg_nup 2 V nups V
@ $m idtransform abs neg ~ abs neg ~
paperw_nup paperh_nup rs
}
if
/pgx_nup pgx_nup 1 add
@ nx_nup eq
{ ! 0 store paperw_nup 1 nx_nup sub mul
/pgy_nup pgy_nup
1 add @ ny_nup eq
{ ! 0 store paperh_nup 1 ny_nup sub mul
}
{ store paperh_nup
}
?
}
{ store paperw_nup 0
}
? + $m matrix invertmatrix concat startpage
} bind
{ ; $m concat
/pgx_nup pgx_nup 1 add
@ nx_nup eq
{ ! 0 store paperw_nup 1 nx_nup sub mul
/pgy_nup pgy_nup
1 add @ ny_nup eq
{ ! 0 store paperh_nup 1 ny_nup sub mul
}
{ store paperh_nup
}
?
}
{ store paperw_nup 0
}
? + $m matrix invertmatrix concat startpage
} bind
]
end
>> /IdiomSet defineresource pop
setglobal <</IdiomRecognition 3 -1 roll>> setuserparams
%%EndResource
%%EOF
待寫。
該文件可以被縮放或只是移動。
psresize -PA4 -pletter a4.ps letter.ps
psnup -pletter -Pa4 a4file.ps letterfile.ps
修復頁面裝置,策略 3。
PostScript 文件中的圖形通常作為 EPS 檔案包含,可以使用文字編輯器輕鬆提取。在符合 DSC 的文件中,EPS 檔案使用文字編輯器進行封裝。
%%BeginDocument
...
%%EndDocument
不要忘記 EPS 檔案可以巢狀。
從 PostScript 檔案中提取的 EPS 檔案沒有預覽,可以使用 Ghostscript 重新生成預覽。
如果您能執行 Perl,請查詢 `bw_convert`,這是一個微小的 Perl 指令碼,它將 PostScript 檔案中的每個 RGB 顏色宣告更改為黑色或灰色值。簡單來說,它將 "setrgbcolor" 替換為 "pop pop pop 0 setgray"。可以在 bw_convert 中找到該指令碼。該網站上沒有記錄指令碼作者。然而,這個指令碼實際上是一個關於如何不做事的絕佳例子;作者並沒有真正理解 PostScript 是一種程式語言,簡單的詞法更改往往會失敗,而在一開始新增一行額外的程式碼會更有效。該指令碼也不處理影像、CMYK 資料或 2 級顏色運算子。
可以透過在 PostScript 檔案開頭新增以下行來完成類似的操作
/setrgbcolor {0.11 mul 3 1 roll 0.59 mul 3 1 roll 0.30 mul add add setgray} def
它將覆蓋 `setrgbcolor` 並使用 `setgray` 計算灰度顏色。但這不會影響影像,也可能不會改變您想要更改的所有內容。也可能存在其他問題,因此不保證結果。
3 級 PostScript 有一種強大的方法可以微調裝置相關顏色到裝置無關顏色的校正:`UseCIEColor` 頁面裝置鍵和 `DefaultGray、DefaultRGB、DefaultCMYK` 顏色空間。
當 `UseCIEColor` 標誌開啟時,灰度、RGB 和 CMYK 顏色被解釋為 `DefaultGray`、`DefaultRGB` 和 `DefaultCMYK` 顏色空間中的顏色。鮮為人知的是,裝置顏色空間的陣列形式(例如 `[DeviceCMYK]`)可以被定義為 `Default*` 資源,有效地停用相應的轉換。
CMYK 到裝置無關顏色的轉換通常是不希望的,因為會導致黑色生成資訊的丟失。
對日期和時間的內建訪問是透過 `currentdevparams` 和 `setdevparams` 在 `%Calendar%` 裝置上進行的,該裝置出現在 PostScript 語言參考手冊 2012 版補充說明 中,用於 PostScript 語言級別 2。以下程式碼將日期和時間寫入標準輸出
(%Calendar%) /IODevice resourcestatus {
pop pop (%Calendar%) currentdevparams
dup /Running get {
dup /Year get 4 string cvs print (-) print
dup /Month get 2 string cvs print (-) print
dup /Day get 2 string cvs print ( ) print
dup /Hour get 2 string cvs print (:) print
dup /Minute get 100 add 3 string cvs 1 2 getinterval print (:) print
/Second get 100 add 3 string cvs 1 2 getinterval print (\n) print
} {
(Clock/calendar is present but not running.\n) print
} ifelse
} {
(No clock/calendar present.\n) print
} ifelse
該標準沒有提供時區資訊,時鐘通常設定為本地時間。它的範圍擴充套件到 2079 年。如果直譯器在主機作業系統上執行,則作業系統可能會確定 `setdevparams` 是否能夠真正設定時鐘。
基於主機的 PostScript 直譯器可以訪問檔案系統,包括命名管道和裝置,因此可能性是無限的。這個例子是在 GNU+Linux 上使用特定直譯器 Ghostscript 測試的。
在一個終端上鍵入以下內容
mkfifo foo
while true; do date >foo; done
在同一目錄中的另一個終端上執行 `gs -dNODISPLAY`,然後鍵入
/t { (foo)(r) file closefile (foo)(r) file dup
28 string readstring pop = closefile} def
現在,在 Ghostscript 提示符下鍵入 `t` 會顯示當前時間,使用主機作業系統的 `date` 命令而不是 `%Calendar%` 裝置。
PostScript 已被用來實現一個 HTTP 伺服器。