標籤:

為什麼從由方正書版的大樣文件列印而成的 pdf 中複製出來的標點符號都是亂碼?

我們的雜誌是別人給排版,完了以後給我們大樣文件我們再列印成pdf,比較蛋疼的問題是我們從列印出來的pdf中複製文字的話,標點符號(準確說應該是非漢字)都是亂碼,但顯示是沒有問題的。我也見過排得很好的pdf(當然我不知道人家是用什麼排的,是不是方正且pdf是怎麼轉出來的),非漢字複製起來沒壓力。我猜測是和這些符號的字體有關係?可是為什麼看可以看複製出來就亂碼呢?謝謝!


方正書版對西文的處理一直都是個奇葩,我曾經深入地研究過。

書版生成的大樣,或者也叫二掃文件,無論西文還是漢字,都是用雙位元組方式來存儲,也就是取這個字元的 748 碼,然後將高低位元組倒過來,儲存在大樣文件里。

例如漢字「啊」編碼是 B0A1H,在早期書版 6.x 版本生成的 S2 文件中,儲存時就是 A1H、B0H 兩個位元組,在這兩個位元組前面又有兩個位元組,來表示這個「啊」字左邊緣的水平坐標,這樣的四個位元組一個一個串起來,在它們的最前面又有專門的標記表示這一串字元共同的垂直坐標、以及字體等信息,就構成了版面上的一行,許多個這樣的一行合在一起,就成了一整頁的文字了。

那麼對於西文如何處理呢?前面說到,任何字元都是雙位元組方式存儲,所以不可能是存儲半形 ASCII 編碼,而是這個字母對應的全形國標碼。因此字母「A」的編碼是 A3C1H,存儲時也是 C1H、A3H 兩個位元組,剩下的步驟也和前面的「啊」字一樣。

這種頁面描述語言被稱為 BDPDL,在書版 9.0 以前的版本(也就是 DOS 下輸入 「HG4」來運行的版本)被用來直接照排輸出。

接下來用一次具體操作來說明。

下面的小樣:

它的大樣結果(圖中以 11.0 版本、S10 為例):

用 6.02(方正網站至今仍可下載到,未加密,用 DOSBox 可運行使用)排版,將生成的 S2 大樣用十六進位編輯器打開,內容如下:

0X | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
---+------------------------------------------------
00 | 03 80 F8 11 03 80 BE 19 03 80 00 00 03 80 01 00
10 | 01 80 A8 00 02 80 A5 10 44 00 A1 B0 B0 00 F9 D7
20 | 01 80 4A 01 02 80 A5 10 01 80 4E 01 02 80 A5 10
30 | 42 00 C1 A3 95 00 C2 A3 D8 00 C3 A3 1E 01 C4 A3
40 | 6A 01 F7 A3 BB 01 F8 A3 F5 01 F9 A3 2C 02 FA A3
50 | 01 80 4A 01 02 80 A5 10 01 80 EC 01 02 80 A5 10
60 | 01 80 F0 01 02 80 A5 10 42 00 80 A0 92 00 81 A0
70 | DE 00 82 A0 22 01 83 A0 73 01 B0 A0 C6 01 B1 A0
80 | FB 01 B2 A0 37 02 B3 A0 01 80 EC 01 02 80 A5 10
90 | 72 80 00 00 04 80 01 00 05 80 00 00

可以看到:

偏移 18H 處開始的四個位元組 44H、00H、A1H、B0H 表示漢字「啊」,水平坐標 0044H,十進位為 68;

偏移 1CH 處開始的四個位元組 B0H、00H、F9H、D7H 表示漢字「座」,水平坐標 00B0H,十進位為 176;

兩個漢字都是五號字,水平坐標之差為 108。因為王選教授早期開始研製照排系統時使用 742 dpi 的輸出設備,五號字就恰好為 108×108 尺寸的點陣,這個習慣一直延續了下來。

同理,偏移 30H 處開始的四個位元組表示第二行的「A」,後面四個位元組表示「B」……2CH、02H、FAH、A3H 表示「z」。

但是,緊接著一個問題就出現了。

大樣中第三行開頭的字元也是「A」,為什麼在 S2 文件後面找不到 C1H、A3H 這兩個位元組呢?

其實它的數據位於偏移 68H 處開始的四個位元組:42H、00H、80H、A0H。

這個「A」只不過字體換成了白斜體,為什麼它的編碼會變成 A080H,而不是 A3C1H 呢?

這裡就要引出一個書版早期版本對不同字體的西文的處理方法。

書版 6.x 和以前的版本西文字體比較少(10 款左右),按照 748 編碼方案,整個符號庫的編碼空間從 8580H 開始,一直到 ADFEH,在這數千個碼位中放置了花邊、棋牌、樂譜、各種數字以及數學符號等各種非漢字字元,然而還是剩下很多空位,當時為了方便,就把白正體以外的西文字母放到這些空的碼位中去了。例如 A080H~A0EBH 放置白斜的拉丁、希臘字母,A180H~A19DH 放置黑正、方頭黑(FH,7.0 和以後的版本取消了此字體)、白斜的數字,A980H~A9E8H 放置黑正、黑斜的拉丁字母,等等。

當時的書版功能實在還很弱,弱到什麼程度?中文字體無論怎麼換,標點符號的字體都不會跟著變;俄文只有白正一種字體;另外,只有白正和黑正可以右旋 90°排版,其他西文字體都不行,為什麼?看了下面這張圖就知道了。

這種做法確實比較草率,但當時西文字體少,用一個字型檔的全部碼位來儲存多種西文字體完全夠用,另外大樣中只需要儲存漢字字體是哪種,而不需要記錄西文字體是哪種(反正怎麼換都當成白正),處理起來也方便。

但是到了書版 7.0 版本,這個方法就不行了。7.0 的西文字體擴充到 70 多種,各種漢字字體都有自己的標點,俄文也不再只有白正體了。符號也多了幾百個,不得不把 A0H~A5H 這幾個區的低位元組拓寬到 00H~FFH 來放置這些新增的符號,原有的幾千個碼位顯然放不下所有西文字體的各種字元,所以不能再是一個字型檔放多種字體,必須改成一個字體用一個字型檔了。CID 字型檔中關於 7.0 白正的字型檔有以下幾個:

E-BZ7:數字和拉丁字母

F-BZ7:希臘文、西里爾文、圈碼等

O7:字體不會變的符號,如數學符號等

但是這時候出現了一個我自己都解釋不了的現象,那就是,數字和拉丁字母不再像之前那樣取全形國標碼來存儲,而是移到了 A0H 區去了:

從書版 7.0 開始,到後來的 9.x 的 S92,再到現在 2008、11.0 的 S10,都採用這種做法。為什麼要這樣去處理我也弄不清原因,但可以肯定的是,這個做法是導致 PDF 文件出現亂碼的可能原因之一。

同樣是上面那個小樣,用 11.0 排版生成 S10,再輸出 PostScript 文件,裡面一段內容如下:

[108 0](啊座)4 4 Cxs/E-BZ9_106X106/E-BZ9 106 106 font0ERepSymbol def
E-BZ9_106X106 sf
[75 69 72 78 70 0](犃犅犆犇狑狓)-6 166 Cxs
(狔)414 172 Cs
(狕)464 166 Cs/E-BX9 106 106 false 18.690 fontERepSymbol
[77 73 76 83 74 0](犃犅犆犇狑狓)2 328 Cxs
(狔)447 335 Cs
(狕)505 328 Cs 0 setgray

看到了嗎?那個漢字「犃」的編碼正好就是 A0C1H,再看上圖,這個碼位上就放著字母「A」。

「狑」、「狓」的編碼分別是 A0F7H、A0F8H,表示字母「w」、「x」。大樣第三行同理,只是前面將字體改成「E-BX9」,也就是白斜。

把這些「ABCDwxyz」複製出去,看到的就是「犃犅犆犇狑狓狔狕」,這就是出現亂碼的原因。

字母「y」的編碼是 A0F9H,對應於漢字「狔」。熟悉 PostScript 語言的知友會發現,這個字元的垂直位置比其他七個字母要靠下一些。這是什麼原因呢?

7.0 的符號字型檔延續了之前的矢量輪廓方法,在 96×96 的方框上描述,要求每一個節點都不能越出方框以外,如果「y」的位置和其他字母平齊,它的底部就要越出方框了,所以在字型檔中只能提高它的位置來存儲,排版時再將它下移,看起來就和別的字母位置一樣高了。9.0 開始雖然改用 CID 格式並曲線平滑了字體,但是這種處理方式仍然保留了下來。

綜上所述,書版採用非常奇葩的方式處理西文,才會導致它的 PDF 文件出現亂碼現象。


首先,從PDF複製出來的不是文字元號的情況是與字體下載有關,但至於在哪個環節下載字體,由於描述的不清楚所以不好確定。建議使用書版11.0直接生成PDF,或在書版11.0中使用大樣轉PDF,看結果是否正確。

建議您登錄方正飛翔雲服務平台:http://www.founderfx.cn,下載書版11.0雲授權版本並進行試用。


為了兼容過去的版本問題,不是他們不知道,是不能改,不然過去的文件都有問題。要知道,當年NPM是FOR DOS的,功能如此完善,那是創造歷史的。


推薦閱讀:

在地名、人名上加下劃線的做法是從什麼時候開始的?為什麼要棄用?
如何在印象筆記中插入數學符號?
多大的「字型大小」、「行距」和「段距」是最易於閱讀的?西文和中文是否有不同的標準和最優值?
在沒有電腦,沒有PS,沒有激光印表機的年代,這種海報效果是如何製作的?
書籍排版設計需要掌握什麼知識?

TAG:字體 | 排版 |