1

我正在使用 pdfclown 库突出显示 pdf 文件中的一些文本,但由于某种原因,当我运行 TextHighlightSample 时出现 nullpointerexception 错误。

 [java] java.lang.NullPointerException
 [java]     at java.util.Hashtable.hash(Hashtable.java:239)
 [java]     at java.util.Hashtable.put(Hashtable.java:519)
 [java]     at org.pdfclown.documents.contents.fonts.SimpleFont.onLoad(SimpleFont.java:139)
 [java]     at org.pdfclown.documents.contents.fonts.Font.load(Font.java:738)
 [java]     at org.pdfclown.documents.contents.fonts.Font.<init>(Font.java:351)
 [java]     at org.pdfclown.documents.contents.fonts.SimpleFont.<init>(SimpleFont.java:62)
 [java]     at org.pdfclown.documents.contents.fonts.TrueTypeFont.<init>(TrueTypeFont.java:68)
 [java]     at org.pdfclown.documents.contents.fonts.Font.wrap(Font.java:253)
 [java]     at org.pdfclown.documents.contents.FontResources.wrap(FontResources.java:72)
 [java]     at org.pdfclown.documents.contents.FontResources.wrap(FontResources.java:1)
 [java]     at org.pdfclown.documents.contents.ResourceItems.get(ResourceItems.java:119)
 [java]     at org.pdfclown.documents.contents.objects.SetFont.getResource(SetFont.java:119)
 [java]     at org.pdfclown.documents.contents.objects.SetFont.getFont(SetFont.java:83)
 [java]     at org.pdfclown.documents.contents.objects.SetFont.scan(SetFont.java:97)
 [java]     at org.pdfclown.documents.contents.ContentScanner.moveNext(ContentScanner.java:1330)
 [java]     at org.pdfclown.documents.contents.ContentScanner$TextWrapper.extract(ContentScanner.java:811)
 [java]     at org.pdfclown.documents.contents.ContentScanner$TextWrapper.<init>(ContentScanner.java:777)
 [java]     at org.pdfclown.documents.contents.ContentScanner$TextWrapper.<init>(ContentScanner.java:770)
 [java]     at org.pdfclown.documents.contents.ContentScanner$GraphicsObjectWrapper.get(ContentScanner.java:690)
 [java]     at org.pdfclown.documents.contents.ContentScanner$GraphicsObjectWrapper.access$0(ContentScanner.java:682)
 [java]     at org.pdfclown.documents.contents.ContentScanner.getCurrentWrapper(ContentScanner.java:1154)
 [java]     at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:633)
 [java]     at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:647)
 [java]     at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:647)
 [java]     at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:296)
 [java]     at org.pdfclown.samples.cli.TextHighlightSample.run(TextHighlightSample.java:56)
 [java]     at org.pdfclown.samples.cli.SampleLoader.run(SampleLoader.java:140)
 [java]     at org.pdfclown.samples.cli.SampleLoader.main(SampleLoader.java:56)

有谁知道如何解决这个问题?

4

1 回答 1

2

前台问题

前景问题是 PdfClown in SimpleFont.onLoad()(同时从字体字典中读取Widths到它自己的结构中)假设它对于Widths数组中基于FirstChar的索引中的键glyphIndexes的每个codes值都有一个条目:

  if(glyphWidthObjects != null)
  {
    ByteArray charCode = new ByteArray(
      new byte[]
      {(byte)((PdfInteger)getBaseDataObject().get(PdfName.FirstChar)).getIntValue()}
      );
    for(PdfDirectObject glyphWidthObject : glyphWidthObjects)
    {
      int glyphWidth = ((PdfNumber<?>)glyphWidthObject).getIntValue();
      if(glyphWidth > 0)
      {
        Integer code = codes.get(charCode);
        if(code != null)
        {
          glyphWidths.put(
            glyphIndexes.get(code),         //<<<<<<<<<<<<<<<<<<<<<<
            glyphWidth
            );
        }
      }
      charCode.data[0]++;
    }
  }

如果您在null这里检查,例如更换

        if(code != null)

经过

        if(code != null && glyphIndexes.get(code) != null)

你会摆脱NullPointerException.

通常所有这些值都有glyphIndexes条目。因此,通常你不会得到NullPointerException这里。但是 PdfClown 在尝试尽可能多地提取时使用了来自 PDF 对象和嵌入字体对象的信息的混合,并且在这些信息的协调方面似乎仍然存在一些缺点,例如在您的文档的情况下:

背景问题

在为SourceSansPro-Regular PdfClownTrueTypeFont字体构建对象时

  • ( Font.load) 尝试读取一个ToUnicode映射以获取从字符代码到 Unicode 的映射并将其放入codes; 不幸的是,该字体没有ToUnicode映射;因此,codes仍然存在null
  • (最初调用的OpenFontParser构造)尝试从嵌入的字体文件中读取信息;在其他数据中,它检索到映射 32..213 -> 0..44 将字符代码映射到字体字形索引;TrueTypeFont.loadEncodingSimpleFont.onLoad
  • (仍然在TrueTypeFont.loadEncoding最初由 调用SimpleFont.onLoad)将字体对象的glyphIndexes成员设置为该映射;如果现在已经有codes映射,这里将使用它来将映射更改为映射 Unicode -> 0..44;但是codesnull(见上文),所以glyphIndexes保持原样;
  • (仍然TrueTypeFont.loadEncoding最初由 调用SimpleFont.onLoad)因为还没有codes映射,它会根据PDF 字体字典中的MacRomanEncoding条目创建一个映射;
  • (仍然在TrueTypeFont.loadEncoding最初由 调用SimpleFont.onLoad)如果还没有glyphIndexes,它将从当前codes映射和Widths数组中派生一个;但是我们已经有了一个,所以它保持原样;
  • ( SimpleFont.onLoad) 最后,它尝试将 PDF 字体字典的Widths数组的内容放入其glyphWidths映射中。代码(见上文)假定这glyphIndexes是 Unicode 代码的映射,因此codes首先使用转换它们。不幸的是glyphIndexes,这里不是来自 Unicode 代码,而是来自字符代码。因此发生了上面观察到的故障。

PdfClown 0.1.3 中的字体提取需要清理。它试图利用来自 PDF 对象和嵌入字体的信息(这是一个好主意),但对于像这里这样的某些情况,它会自取其辱。

但它毕竟还是一个早期的 0.x 版本,所以一些问题是可以预料的......

于 2014-06-30T13:48:40.297 回答