Pdfclown-很少有不同的 pdf 文件字体无法识别,而且我也遇到异常

Pdfclown-Few different fonts of pdf files are not recognizing and also i am getting exceptions

我经常遇到 pdfclown 的问题,因为很少有 pdf 文件是非英语的,而且他们的字体无法识别,而且我也低于 exception.Please 找到 pdf path and code path。加载编码方法失败CompositeFont.java 和 SimpleFont.java。是否需要使用任何特定版本的 jar 来解决此问题。请提供您的意见以支持此类 pdf 文件。

java.lang.NullPointerException
    at org.pdfclown.documents.contents.fonts.CompositeFont.loadEncoding(CompositeFont.java:178)
    at org.pdfclown.documents.contents.fonts.CompositeFont.onLoad(CompositeFont.java:202)
    at org.pdfclown.documents.contents.fonts.Font.load(Font.java:878)
    at org.pdfclown.documents.contents.fonts.Font.<init>(Font.java:368)
    at org.pdfclown.documents.contents.fonts.CompositeFont.<init>(CompositeFont.java:114)
    at org.pdfclown.documents.contents.fonts.Type0Font.<init>(Type0Font.java:62)
    at org.pdfclown.documents.contents.fonts.Font.wrap(Font.java:268)
    at org.pdfclown.documents.contents.FontResources.wrap(FontResources.java:72)
    at org.pdfclown.documents.contents.FontResources.wrap(FontResources.java:1)
    at org.pdfclown.documents.contents.ResourceItems.get(ResourceItems.java:119)
    at org.pdfclown.documents.contents.objects.SetFont.getResource(SetFont.java:119)
    at org.pdfclown.documents.contents.objects.SetFont.getFont(SetFont.java:83)
    at org.pdfclown.documents.contents.objects.SetFont.scan(SetFont.java:97)
    at org.pdfclown.documents.contents.ContentScanner.moveNext(ContentScanner.java:1360)
    at org.pdfclown.documents.contents.ContentScanner$TextWrapper.extract(ContentScanner.java:819)
    at org.pdfclown.documents.contents.ContentScanner$TextWrapper.<init>(ContentScanner.java:771)
    at org.pdfclown.documents.contents.ContentScanner$TextWrapper.<init>(ContentScanner.java:764)
    at org.pdfclown.documents.contents.ContentScanner$GraphicsObjectWrapper.get(ContentScanner.java:684)
    at org.pdfclown.documents.contents.ContentScanner$GraphicsObjectWrapper.access[=10=](ContentScanner.java:676)
    at org.pdfclown.documents.contents.ContentScanner.getCurrentWrapper(ContentScanner.java:1184)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:636)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:653)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:299)
    at pdfclown2.highlight(pdfclown2.java:89)
    at pdfclown2.main(pdfclown2.java:48)

******************************其他 pdf 问题*************** *********************************

java.lang.NullPointerException
    at org.pdfclown.documents.contents.fonts.SimpleFont.loadEncoding(SimpleFont.java:150)
    at org.pdfclown.documents.contents.fonts.SimpleFont.onLoad(SimpleFont.java:170)
    at org.pdfclown.documents.contents.fonts.Font.load(Font.java:878)
    at org.pdfclown.documents.contents.fonts.Font.<init>(Font.java:368)
    at org.pdfclown.documents.contents.fonts.SimpleFont.<init>(SimpleFont.java:65)
    at org.pdfclown.documents.contents.fonts.TrueTypeFont.<init>(TrueTypeFont.java:47)
    at org.pdfclown.documents.contents.fonts.Font.wrap(Font.java:262)
    at org.pdfclown.documents.contents.FontResources.wrap(FontResources.java:72)
    at org.pdfclown.documents.contents.FontResources.wrap(FontResources.java:1)
    at org.pdfclown.documents.contents.ResourceItems.get(ResourceItems.java:119)
    at org.pdfclown.documents.contents.objects.SetFont.getResource(SetFont.java:119)
    at org.pdfclown.documents.contents.objects.SetFont.getFont(SetFont.java:83)
    at org.pdfclown.documents.contents.objects.SetFont.scan(SetFont.java:97)
    at org.pdfclown.documents.contents.ContentScanner.moveNext(ContentScanner.java:1360)
    at org.pdfclown.documents.contents.ContentScanner$TextWrapper.extract(ContentScanner.java:819)
    at org.pdfclown.documents.contents.ContentScanner$TextWrapper.<init>(ContentScanner.java:771)
    at org.pdfclown.documents.contents.ContentScanner$TextWrapper.<init>(ContentScanner.java:764)
    at org.pdfclown.documents.contents.ContentScanner$GraphicsObjectWrapper.get(ContentScanner.java:684)
    at org.pdfclown.documents.contents.ContentScanner$GraphicsObjectWrapper.access[=11=](ContentScanner.java:676)
    at org.pdfclown.documents.contents.ContentScanner.getCurrentWrapper(ContentScanner.java:1184)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:636)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:653)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:653)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:653)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:645)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:653)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:653)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:653)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:653)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:653)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:653)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:653)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:299)
    at pdfclown2.highlight(pdfclown2.java:89)
    at pdfclown2.main(pdfclown2.java:48)

************************************另一个问题************ ****************************

java.lang.RuntimeException: Odd number of characters.
    at org.pdfclown.util.ConvertUtils.hexToByteArray(ConvertUtils.java:106)
    at org.pdfclown.objects.PdfString.setValue(PdfString.java:287)
    at org.pdfclown.objects.PdfString.<init>(PdfString.java:126)
    at org.pdfclown.objects.PdfByteString.<init>(PdfByteString.java:58)
    at org.pdfclown.documents.contents.tokens.ContentParser.parsePdfObject(ContentParser.java:182)
    at org.pdfclown.documents.contents.tokens.ContentParser.parseOperation(ContentParser.java:164)
    at org.pdfclown.documents.contents.tokens.ContentParser.parseContentObject(ContentParser.java:98)
    at org.pdfclown.documents.contents.tokens.ContentParser.parseContentObjects(ContentParser.java:134)
    at org.pdfclown.documents.contents.tokens.ContentParser.parseContentObject(ContentParser.java:112)
    at org.pdfclown.documents.contents.tokens.ContentParser.parseContentObjects(ContentParser.java:134)
    at org.pdfclown.documents.contents.tokens.ContentParser.parseContentObject(ContentParser.java:112)
    at org.pdfclown.documents.contents.tokens.ContentParser.parseContentObjects(ContentParser.java:134)
    at org.pdfclown.documents.contents.tokens.ContentParser.parseContentObject(ContentParser.java:112)
    at org.pdfclown.documents.contents.tokens.ContentParser.parseContentObjects(ContentParser.java:134)
    at org.pdfclown.documents.contents.Contents.load(Contents.java:598)
    at org.pdfclown.documents.contents.Contents.<init>(Contents.java:372)
    at org.pdfclown.documents.contents.Contents.wrap(Contents.java:351)
    at org.pdfclown.documents.Page.getContents(Page.java:585)
    at org.pdfclown.documents.contents.ContentScanner.<init>(ContentScanner.java:1056)
    at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:300)
    at pdfclown2.highlight(pdfclown2.java:3124)
    at pdfclown2.main(pdfclown2.java:50)

NullPointerExceptionSimpleFont.loadEncoding

我可以使用您的示例文件“Sample_Report.pdf”在 SimpleFont.loadEncoding 中重现 NullPointerException。这是由 PDF 中的错误引起的,其中的一些字体词典缺少必需的条目。

不过,我无法使用“Sample_Report.pdf”重现其他两个异常。因此,我将专注于可重现的问题。

原因

在您的示例 PDF 中,有一些简单的字体缺少所需的 FirstChar 条目,例如:

32 0 obj
<<
  /Name /EvoPdf_meeaimambhggkplibeicinfbamefiocn
  /Subtype /TrueType
  /FontDescriptor 37 0 R
  /Widths [0 507 507 507 507 507 507 507 507 507 507 507 507 0 507 507 507 507 507 507 507 507 507 507 507 507 507 507 507 507 507 507 226 326 401 498 507 715 682 221 303 303 498 498 250 306 252 386 507 507 507 507 507 507 507 507 507 507 268 268 498 498 498 463 894 579 544 533 615 488 459 631 623 252 319 520 420 855 646 662 517 673 543 459 487 642 567 890 519 487 468 307 386 307 498 498 291 479 525 423 525 498 305 471 525 230 239 455 230 799 525 527 525 525 349 391 335 525 452 715 433 453 395 314 460 314 498 507 507 507 250 305 418 690 498 498 395 1038 459 339 867 507 468 507 507 250 250 418 418 498 498 905 450 705 391 339 850 507 395 487 226 326 498 507 498 507 498 498 393 834 402 512 498 306 507 394 339 498 336 334 292 550 586 252 307 246 422 512 636 671 675 463 579 579 579 579 579 579 763 533 488 488 488 488 252 252 252 252 625 646 662 662 662 662 662 498 664 642 642 642 642 487 517 527 479 479 479 479 479 479 773 423 498 498 498 498 230 230 230 230 525 525 527 527 527 527 527 498 529 525 525 525 525 453 525 453 ]
  /Encoding /WinAnsiEncoding
  /Type /Font
  /BaseFont /Calibri
  /LastChar 255 >>
endobj 

根据 PDF 规范 ISO 32000-1(以及类似的 ISO 32000-2),TrueType 字体词典包含与 Type1[ 相同的条目=90=] 字体词典(某些差异与手头的情况无关),Type1 字体部分指定:

FirstChar integer (Required except for the standard 14 fonts) The first character code defined in the font’s Widths array.

上面的字体不是标准的14号字体。因此,需要有一个 FirstChar 条目。它不是。因此,此字体定义已损坏。

另一方面,PDF Clown 希望 PDF 遵循规范。所以它只是从字体中检索 FirstChar 值并立即使用它,从而导致 NullPointerException.

解决方法

可以通过在其 SimpleFont FirstChar 查找中将其默认设置为 0 来使 PDF Clown 更加宽松一些。有两个这样的查找。

SimpleFont.loadEncoding()中替换

ByteArray charCode = new ByteArray(new byte[]{(byte)((PdfInteger)getBaseDataObject().get(PdfName.FirstChar)).getIntValue()});

来自

PdfInteger firstCharObject = (PdfInteger)getBaseDataObject().get(PdfName.FirstChar);
ByteArray charCode = new ByteArray(new byte[]{(byte)(firstCharObject != null ? firstCharObject.getIntValue() : 0)});

并在 SimpleFont.onLoad() 中类似地替换

ByteArray charCode = new ByteArray(
    new byte[]
        {(byte)((PdfInteger)getBaseDataObject().get(PdfName.FirstChar)).getIntValue()}
);

来自

PdfInteger firstCharObject = (PdfInteger)getBaseDataObject().get(PdfName.FirstChar);
ByteArray charCode = new ByteArray(
    new byte[]
        {(byte)(firstCharObject != null ? firstCharObject.getIntValue() : 0)}
);

因为已经完成了 here

NullPointerExceptionCompositeFont.loadEncoding

我可以使用您的示例文件“UnicodeTest.pdf”在 CompositeFont.loadEncoding 中重现 NullPointerException。这些异常是由于 PDF Clown 中缺少编码 CMap 造成的。

有许多 编码 主要用于 CJK 语言,符合标准的 PDF 处理器应该支持这些语言,但 PDF 库(特别是那些在欧洲或美洲开发的库)通常不支持开箱即用。

PDF 小丑希望在 /fonts/cmap/ pdfclown.jar 中将此类编码 CMap 作为资源;不过,默认情况下,只有通用 CMap Identity-HIdentity-V 存在,而特定 [=] 的 none 105=] CMap.

您可以将所需的 CMap 添加到 pdfclown.jar,方法是将它们添加到 PDF Clown 项目的 main\res\pkg\fonts\cmap\ 文件夹并构建 jar 文件。

您可以从 github 上的 adobe-type-tools/cmap-resources 项目中检索所有 CMap,只需遍历该项目的文件夹结构并从 CMap 子文件夹中收集文件。

对于您的示例文件,CMaps UniCNS-UTF16-HUniGB-UTF16-H UniJIS-UTF16-HUniKS-UTF16-H 就足够了,但是对于处理任意 PDF 文件的应用程序,您可能应该添加所有编码 CMap。