2011-08-21 271 views
2

呈現由PDFCreator 0.9.x生成的PDF文件。我注意到它在字符映射中包含一個錯誤。現在,PDF文件中的錯誤毫無疑問,Acrobat在渲染錯誤的PDF文件方面有奇效,因此很多PDF生成器都會創建不完全符合PDF標準的PDF文件。PDF字體映射錯誤

我trief創建一個小例子文件:http://test.continuit.nl/temp/Document.pdf

單頁面呈現使用TJ命令單個字形(大寫的A)(參見流5 0 OBJ)。選中的字體(7 0 obj)包含嵌入單個字形的字體。到現在爲止還挺好。 char被char#1引用。鑑於字體的編碼,它包含一個差異部分:[1/A]。因此char 1 - >字符/ A。現在在嵌入子集字體中有一個與字符65不匹配字形的cmap(例如大寫字母A),字體的cmap部分確實按照PDF文件Font - > Encoding - > Differences array中的順序定義字符。

它看起來像字符映射/編碼是兩次。只有來自PDFCreator 0.9.x的文件似乎受到影響。

我的問題是:這是正確的(或者我犯了一個錯誤,是PDF正確的),你會做什麼來檢測這種情況,以解決渲染問題。

注:我確實需要能夠使這些PDF ..

解決方案

在ISO32000文件存在的話是象徵性的TrueType字體(標誌位3是在字體描述符)編碼是不允許的,你應該忽略它,總是使用簡單的1on1編碼。總之,如果它是一種符號字體,我完全忽略了Encoding對象,這就解決了這個問題。

+0

你用什麼渲染文件? – userx

+0

@userx:用Delphi編寫的我自己的PDF渲染器。它將內存中的PDF呈現爲GDI設備(通常是位圖,但也可以是打印機或任何其他GDI設備上下文)。 –

回答

2

第一點是該文件在Acrobat中打開並正確呈現,因此幾乎可以確定該文件是正確的。事實上,它可以在各種PDF使用者中正確打開並呈現,所以實際上它是正確的。

有問題的字體是TrueType字體,所以實際上是的,有兩種'編碼'。首先是PDF/PostScript編碼。這將字符代碼映射爲字形名稱。在你的情況下,它將字符代碼1映射到字形名稱/ A。

在PostScript字體中,我們將查找CharStrings字典中的名稱/ A,這會給我們字符描述,然後我們將執行該字符。不過,Tru​​eType字體的情況有所不同。

您可以將1.7 PDF參考手冊,它規定的430頁上找到此說:

「TrueType字體程序的內置編碼直接從字符代碼映射通過內部數據的手段字形描述稱爲「cmap」的結構(不要與第5.6.4節「CMaps」中描述的CMap混淆)。「

我相信你的情況,你只需要直接在CMAP子表中使用字符代碼(0x01)。這會給你一個36的GID。

+0

關於你的第一點:現在創建PDF渲染器一年後,我可以告訴你:Acrobat在支持渲染錯誤的PDF格式方面非常出色。大多數PDF對象中缺少鍵。特別是在字體處理中,你會看到這些問題 –

+0

我看到的是相同的減去最後一段:在內容是繪製字符0x01的突擊隊。給定字體編碼這是Postscript字符/ A。 TT字體在POST部分中沒有填充字段,我像使用TT字體(不是typ0)的任何其他PDF一樣使用TT cmap,並且我需要在給出Acrobat轉換表格格式名稱爲Unicode代碼的情況下查找字符65。大多數PDF的工作是正確的,只有使用PDFCreator創建的onse(據我現在看到的)不需要這個。請注意,TT字體中的Mac和MS cmap都使用相同的映射。其他人確實需要PDF中的編碼。 –

+0

請注意,在PDF 1.7標準的第431頁上,它聲明您應該首先使用Endoding Dictionary和Differences,然後如果存在(3,1)「cmap」子表(Microsoft Unicode),則首先映射到PS名稱,然後轉換爲Unicode值,然後使用(3,1)子表。這正是渲染器不工作的方式,併產生錯誤的結果(在PDFCreateor 0.9.x文件的情況下)。 –