Подсветка 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 в конце концов, поэтому следует ожидать некоторых проблем...