Подсветка pdfclown не работает для некоторых файлов PDF

Я использую библиотеку pdfclown для выделения текста внутри файла pdf, но по какой-то причине я получаю ошибку nullpointerexception при запуске TextHighlightSample.

 [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)

кто-нибудь знает, как решить эту проблему?

1 ответ

Решение

Проблема на переднем плане

Проблема на переднем плане в том, что PdfClown в SimpleFont.onLoad() (при чтении ширины из словаря шрифтов в свои собственные структуры) предполагает, что он имеет glyphIndexes запись для каждого codes значение для ключа из индексов FirstChar в массиве Widths:

  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 и объектов встроенных шрифтов, и все же, как представляется, существуют некоторые недостатки в координации этой информации, например, в случае вашего документа.:

Фоновая проблема

При построении TrueTypeFont объект для шрифта SourceSansPro-Regular PdfClown

  • (Font.load) пытается прочитать карту ToUnicode, чтобы получить сопоставление из кодов символов в Unicode и поместить его в codes; к сожалению, у шрифта нет карты ToUnicode; Таким образом, codes остатки null;
  • (OpenFontParser строительство в TrueTypeFont.loadEncoding изначально вызывается SimpleFont.onLoad) пытается прочитать информацию из файла встроенного шрифта; среди других данных он получил отображение 32..213 -> 0..44, сопоставляющее коды символов с индексами глифа в шрифте;
  • (до сих пор внутри TrueTypeFont.loadEncoding изначально вызывается SimpleFont.onLoad) устанавливает объект шрифта glyphIndexes участник этой карты; если бы был codes отображение уже сейчас, это будет использоваться здесь, чтобы изменить отображение на отображение Unicode -> 0..44; но codes является null (см. выше), так glyphIndexes остается как есть;
  • (до сих пор внутри TrueTypeFont.loadEncoding изначально вызывается SimpleFont.onLoad) как нет codes пока сопоставляя, он создает один на основе записи MacRomanEncoding из словаря шрифтов PDF;
  • (до сих пор внутри TrueTypeFont.loadEncoding изначально вызывается SimpleFont.onLoad) если бы не было glyphIndexes тем не менее, он будет выведен из текущего codes отображение и массив ширины; но у нас уже есть один, так что он остается как есть;
  • (SimpleFont.onLoad) наконец, он пытается поместить содержимое массива Widths словаря шрифтов PDF в свой glyphWidths карта. Код (см. Выше) предполагает, что glyphIndexes является отображением кодов Unicode и, следовательно, переводит их, используя codes первый. к несчастью glyphIndexes здесь не из кодов Unicode, а из кодов символов. Таким образом происходит сбой, наблюдаемый выше.

Извлечение шрифта в PdfClown 0.1.3 нуждается в очистке. Он пытается использовать информацию как из объектов PDF, так и из встроенных шрифтов (что является хорошей идеей), но в некоторых ситуациях, таких как здесь, стреляет себе в ногу.

Но это все еще ранняя версия 0.x в конце концов, поэтому следует ожидать некоторых проблем...

Другие вопросы по тегам