pdf打印亂碼問題


問題:

使用Adobe Reader將一份pdf文件通過我的虛擬打印機輸出后(輸出的是中間文件,等同於EMF文件),查看的時候發現有時候是亂碼。最簡單的必現步驟:

1、使用Adobe Reader打開pdf文件,選擇我的虛擬打印機打印(取消掉adobe打印高級選項中“作為圖像打印”),生成中間文件。

2、此時可以通過工具查看這個中間文件(EMF),發現並沒有亂碼。

3、關閉剛才打印的Adobe Reader打開的Pdf文件,再次查看中間文件,這時候就亂碼了。

分析:

根據上面的必現步驟,再測試使用FoxitReader、JisuPdf打開pdf文件然后選擇我的虛擬打印機打印,都沒有復現。此外,生成中間文件后,即使重新用Adobe Reader打開pdf,查看中間文件的時候,仍然是亂碼。

根據上述現象,去對比使用JisuPdf和Adobe Reader執行打印后生成的中間文件的區別,發現存在比較大的區別。猜測Adobe Reader在打印輸出的時候為不存在的字體創建了臨時字體文件,所以Adobe Reader在沒關閉的時候查看不會亂碼,一旦關閉了就刪掉了臨時文件,所以就亂碼了。

比如我第一次輸出的是中文文件A,不關閉Adobe Reader,查看A正常。關閉Adobe Reader查看A亂碼,再次打開Adobe Reader並打印出B,查看A亂碼,B不亂碼。由此說明,創建的這個臨時字體文件,還是和對應的中間文件相關聯的,並不是所有的都一樣。

我分別比較上述A和B文件內容上的區別,發現其中一個區別就是EMR_EXTCREATEFONTINDIRECTW結構中的字段不一樣,而且有個比較明顯的字段內容lfFaceName不一樣。

image

查看MSDN上對EMR_EXTCREATEFONTINDIRECTW的介紹,基本可以確定就是Adobe Reader在打印輸出這個pdf文件的時候創建了臨時字體文件,所以一旦Adobe Reader進程關閉了,就會刪除臨時字體文件導致中間文件亂碼。這也說明了為什么直接輸出到打印機時不會,而通過我的虛擬打印機輸出中間文件,如果在同一台機器上不關閉Adobe Reader進程時將中間文件輸出到真實打印機不會亂碼,而在另一台機器上輸出會亂碼。

為了確認這個問題,我使用JisuPdf和FoxitReader再分別打印出中間文件C和D。用A和C、A和D比較,發現C和D中都不存在EXTCREATEFONTINDIRECTW這個記錄,由此證明以上結論。

也就是說,我這個pdf文件中使用了非內嵌並且系統尚未安裝的字體,pdf閱讀器在打開的時候使用了相關的字體去替換顯示。

image

進一步分析:

現在問題轉變成,為什么Adobe Reader在打印時會調用CreateFontIndirect(生成EXTCREATEFONTINDIRECTW記錄),而JisuPdf和FoxitReader卻不會?

另外如果生成的EMF中有EXTCREATEFONTINDIRECTW記錄,如何根據這個記錄創建好需要的字體從而不亂碼顯示呢?

經過自己解析EMF中的記錄進行繪制,發現是可以通過調用CreateFontIndirect函數去實現這條EXTCREATEFONTINDIRECTW記錄的,但是仍然是亂碼,也就是說無法找到實際能與之匹配上的字體。

解決方案:

問題拖了比較久,最終也沒找到好的解決方案,目前采用的辦法是對於這種情況,要么直接使用勾選上adobe reader的矢量圖打印(這種方式比較萬能,原理是將每頁文檔都轉變成一張圖片,相應的占據的空間也大,並且慢很多),要么就干脆換一個pdf閱讀器,比如國產的foxit。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM