2

我从使用 Ghostscript 9.19 创建 PDF/A 兼容 PDF (1.4) 的客户那里获得的 PDF 存在特殊问题。我想使用 LocationTextExtractionStrategy 从中提取文本,但我以相反的顺序获取大部分文本并带有额外的空格:

期待:abc

获得:cba

在内容流中,这可能是 [a,1,b,1,c] TJ

这个问题之前已经发布到 Stackoverflow,但是我比破解我自己的提取策略更进一步解决了这个问题。我意识到所使用字体的字体宽度全为零,并且度量值和 hMetrics 映射均未填充。我使用的是 iTextSharp 5.5.4,但 5.5.9 仍然有同样的问题。

这是字体:

/Subtype    /Type0  
/BaseFont   /VGOQEA+SegoeUI 
/Type   /Font   
/Encoding   33 0 R  
/ToUnicode  48 0 R  
/DescendantFonts    [35 0 R]    

对象 33 是​​一个 CMap:

/CIDSystemInfo  32 0 R  
/Filter /FlateDecode    
/Length 266 
/CMapName   /OneByteIdentityH   
/Type   /CMap   

对象 48 是一个 Stream,顺便说一下也是一个 CMap

对象 35 终于有了一些宽度定义

/DW 539 
/CIDSystemInfo  32 0 R  
/Subtype    /CIDFontType2   
/BaseFont   /VGOQEA+SegoeUI 
/FontDescriptor 26 0 R  
/Type   /Font   
/W  [0, [646], 32, [274], 40, [302, 302], 44, [217, 400, 217], 48, [539, 539, 539, 539], 53, [539, 539, 539, 539], 58, [217], 64, [955, 645, 573], 68, [701, 506], 72, [710, 266], 75, [580, 471, 898], 80, [560], 82, [598, 531], 85, [687], 87, [934], 90, [570], 97, [509, 588, 462, 589, 523, 313, 589, 566, 242], 107, [497, 242, 861, 566, 586, 588], 114, [348, 424, 339, 566], 119, [723], 122, [452], 220, [687], 228, [509], 246, [586], 252, [566]]  
/CIDToGIDMap    47 0 R  

按照 iTextSharp 初始化 CMapAwareDocumentFont 的顺序,首先初始化基本 DocumentFont。然后构造函数检查:

if (PdfName.TYPE1.Equals(subType) || PdfName.TRUETYPE.Equals(subType))

两者都不是。

else if (PdfName.TYPE3.Equals(subType))

它不是。然后进入下一个else分支:

PdfName encodingName = font.GetAsName(PdfName.ENCODING);
if (encodingName == null)

但由于编码是作为间接引用给出的,因此 encodingName 为空。因此,永远不会处理此 Type0 字体的处理。

我在库代码中更改了这一点,但即使调用了 ProcessType0(font) 方法,宽度值也从未进入字体定义 - 即全部保持为零。这可能是意料之中的。最后我得到了填充的指标哈希映射,但我没有涵盖所有使用的字符。即情况有所好转,但并非一切都好:

而不是: abc -> cba

我现在得到: abc -> acb

对于当前问题,我唯一可行但很老套的解决方案是破解 processor.DisplayPdfString((PdfString)entryObj) 以将 textMatrix 调整固定数量。然而,这不是一般的解决方案,我宁愿字体能正常工作。任何其他建议我应该尝试什么?

编辑:我使用 iText 7 .Net 重新审视了我的问题,现在在尝试从我的测试文件中读取文本时出现 NullReferenceException。

var reader = new iText.Kernel.Pdf.PdfReader(@"itextsharp_sample_locationtext_extraction_reversing_characters(1).pdf");
var extractionStrategy = new LocationTextExtractionStrategy();
var doc = new PdfDocument(reader);
var page = doc.GetFirstPage();
var test = PdfTextExtractor.GetTextFromPage(doc.GetFirstPage());
Console.WriteLine(test);

这是我使用的文件:https ://drive.google.com/file/d/0B1RdIg0_Pbd_aTlOT2VmbnFlaTQ/view?usp=sharing

该代码适用于其他 PDF 文件,但不适用于这个。

更新 感谢 mkl,我现在知道了一段时间,根本问题是字体编码流。遗憾的是,我刚刚通过 iText 销售团队收到一条消息,说这不在路线图上。他们声称这是一个奇怪的异常值,大多数其他人不需要对字体编码流的支持。因此,如果您在阅读本文时确实遇到了缺少支持的问题,请通过电子邮件告知他们。

4

0 回答 0