我从使用Ghostscript 9.19创建PDF / A兼容PDF(1.4)的客户那里得到的PDF有一个奇怪的问题。我想使用LocationTextExtractionStrategy从中提取文本,但我以相反的顺序获得大部分文本并使用其他空格:
期待:abc
获得:c b a
在内容流中,这可能是[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是流,顺便提一下也是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))
不是。然后输入下一个其他分支:
PdfName encodingName = font.GetAsName(PdfName.ENCODING);
if (encodingName == null)
但由于编码是作为间接引用给出的,因此encodingName为null。因此,永远不会处理这种Type0字体。
我在库代码中更改了这一位,但即使调用方法ProcessType0(字体),宽度值也从未使其成为字体定义 - 即全部保持为零。这可能是预期的。最后,我得到了填充的度量哈希映射,但我没有涵盖所有使用过的字符。即情况有所改善,但并非一切都好:
代替:abc - > c b a
我现在得到了:abc - > ACB
我唯一能解决当前问题但是hacky解决方案是破解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销售团队收到一条消息,表示这不在路线图上。他们声称这个问题是一个奇怪的异常值,大多数人都不需要支持字体编码流。因此,如果你们中的任何人在阅读本文时确实存在缺少支持的问题,请通过电子邮件告知他们。