2011-05-15 196 views
1

解析PDF時,給定一個使用Identity-H編碼的字符串(從Tj或TJ運算符回調中彈出),如何將該字符串映射爲Unicode(如UTF8)表示?文本搜索PDF

如果我需要一個CMap爲此,我如何創建(或檢索)並應用CMap?

回答

2

您可能必須解析字體數據本身。 Identity-H只是意味着「將字節用作原始字形索引到指定字體中」。這就是爲什麼在使用Identity-H時必須嵌入字體......相同字體的不同版本不必具有相同的字形順序。

這裏有一些示例代碼,說明如何在幾個不同的開源項目中做這種事情。 iText,例如(是的,我有偏見)。


你剛纔提到了CMap。 Identity-H字體可以有一個CMap,但不需要這樣做。/ToUnicode條目將是一個CMap流,正如某些adobe規範中所定義的那樣。他們並不是那麼複雜:

/CIDInit /ProcSet findresource begin 
12 dict begin 
begincmap 
/CIDSystemInfo 
<< /Registry (TTX+0) 
/Ordering (T42UV) 
/Supplement 0 
>> def 
/CMapName /TTX+0 def 
/CMapType 2 def 
1 begincodespacerange 
<0000><FFFF> 
endcodespacerange 
80 beginbfrange 
<0003><0003><0020> 
<0024><0024><0041> 
<0025><0025><0042> 
<0026><0026><0043> 
<0027><0027><0044> 
<0028><0028><0045> 
<0029><0029><0046> 
<002a><002a><0047> 
<002b><002b><0048> 
<002c><002c><0049> 
<002d><002d><004a> 
<002e><002e><004b> 
<002f><002f><004c> 
<0030><0030><004d> 
<0031><0031><004e> 
<0032><0032><004f> 
<0033><0033><0050> 
<0034><0034><0051> 
<0035><0035><0052> 
<0036><0036><0053> 
<0037><0037><0054> 
<0038><0038><0055> 
<0039><0039><0056> 
<003a><003a><0057> 
<003b><003b><0058> 
<003c><003c><0059> 
<003d><003d><005a> 
<0065><0065><00c9> 
<00c8><00c8><00c1> 
<00cb><00cb><00cd> 
<00cf><00cf><00d3> 
<00d2><00d2><00da> 
<00e2><00e2><0160> 
<00e4><00e4><017d> 
<00e9><00e9><00dd> 
<00fd><00fd><010c> 
<0104><0104><0104> 
<0106><0106><010e> 
<0109><0109><0118> 
<010b><010b><011a> 
<0115><0115><0147> 
<011b><011b><0158> 
<0121><0121><0164> 
<0123><0123><016e> 
<01a0><01a0><0116> 
<01b2><01b2><012e> 
<01cb><01cb><016a> 
<01cf><01cf><0172> 
<022c><022c><0401> 
<023b><023b><0411> 
<023c><023c><0412> 
<023d><023d><0413> 
<023e><023e><0414> 
<023f><023f><0415> 
<0240><0240><0416> 
<0241><0241><0417> 
<0242><0242><0418> 
<0243><0243><0419> 
<0244><0244><041a> 
<0245><0245><041b> 
<0246><0246><041c> 
<0247><0247><041d> 
<0248><0248><041e> 
<0249><0249><041f> 
<024a><024a><0420> 
<024b><024b><0421> 
<024c><024c><0422> 
<024d><024d><0423> 
<024e><024e><0424> 
<024f><024f><0425> 
<0250><0250><0426> 
<0251><0251><0427> 
<0252><0252><0428> 
<0253><0253><0429> 
<0254><0254><042a> 
<0255><0255><042b> 
<0256><0256><042c> 
<0257><0257><042d> 
<0258><0258><042e> 
<0259><0259><042f> 
endbfrange 
endcmap 
CMapName currentdict /CMap defineresource pop 
end end 

哇。那個特定的CMap非常低效。 A「bfrange」從參數1開始,並且前進到,並且包括參數2,馬平值開始在參數3(和在繼續,直到沒有更多的東西來映射

,例如:

<0003><0003><0020> 
<0024><0024><0041> 
<0025><0025><0042> 
<0026><0026><0043> 
<0027><0027><0044> 
<0028><0028><0045> 
<0029><0029><0046> 
<002a><002a><0047> 
<002b><002b><0048> 
<002c><002c><0049> 
<002d><002d><004a> 
<002e><002e><004b> 
<002f><002f><004c> 
<0030><0030><004d> 
<0031><0031><004e> 
<0032><0032><004f> 

可以表示爲

<0003><0003><0020> 
<0024><0032><0041> 

A quick google search turned up the CMap/CID font spec

還有beginbfchar/endbfchar其中菊st需要兩個參數(src和dest值,沒有範圍),基於CID的版本(在這一點上,您需要訪問Adobe的字符ID表。它們是Acrobat/Reader安裝程序的一部分,但Reader需要被推動下載各種語言包(或套件或任何他們稱之爲的))以及您真正閱讀該規範以瞭解有關的其他各種內容。

+0

在我的情況下,當前字體編碼爲「Identity-H」時,嵌入字體有一個FontDescriptor,它的流具有帶「Filter」鍵和值「FlateDecode」的字典。這是否意味着我只需要使用zLib解壓縮(比如說)在'Tj'中找到的文本來獲取unicode字符串? (當然不是......) – SK9 2011-05-18 13:46:49

+0

正確。字體文件(或其一部分)使用zLib進行壓縮。你需要解壓縮它並閱讀字體的字形 - >字符表來找出Tj中的哪些字符表示什麼。只是爲了好玩,字體子集不需要包含這些信息......在這一點上它是「OCR或胸圍」。 – 2011-05-18 16:01:03

+0

「正確」,如「不,這不行」。 – 2011-05-18 16:47:25

1

這種數據可能有多種編碼方式(一些使用CMAP)。您也可以使用自定義編碼(http://www.jpedal.org/PDFblog/2011/04/understanding-the-pdf-file-format-%E2%80%93-custom-font-encodings/)。您還需要了解CID字體(http://www.jpedal.org/PDFblog/2011/03/understanding-the-pdf-file-format-%E2%80%93-what-are-cid-fonts/)

+0

非常感謝您的回覆。我有PDF的官方指南,我已閱讀了一些內容,並決定進行詳細閱讀。我正在瀏覽你的鏈接 - 感謝這些。 – SK9 2011-05-15 14:24:33