PDFKitten выделяет неправильную позицию

Я использую PDFKitten для поиска строк в документах PDF с подсветкой результатов. FastPDFKit или любая другая коммерческая библиотека - не вариант, поэтому я выбрал самую близкую для моих требований.

Неправильная координата

Как вы можете видеть на скриншоте, я искал строку "in", которая всегда правильно выделена, кроме последней. Я получил более сложный PDF-документ, в котором выделенное поле "in" почти на 40% неверно.

Я прочитал весь синтаксис и проверил трекер проблем, но, кроме проблем с высотой строки, я ничего не нашел относительно расчета ширины. На данный момент я не вижу какой-либо схемы, где расчет идет или может быть неправильным, и я надеюсь, что, возможно, кто-то еще имел близкую проблему с моей.

В настоящее время я ожидаю, что координаты и ширина символов неверно рассчитаны где-то в классах шрифтов или RenderingState.m. Проект очень сложный, и, возможно, у кого-то из вас была подобная проблема с PDFKitten в прошлом.

Я использовал оригинальный образец PDF документа из PDFKitten для моего скриншота.

1 ответ

Решение

Это может быть ошибкой в ​​PDFKitten при расчете ширины символов, чей символьный идентификатор не совпадает с его кодом Unicode.

При обработке некоторых строковых данных appendPDFString в StringDetector работает с двумя строками:

// Use CID string for font-related computations.
NSString *cidString = [font stringWithPDFString:string];

// Use Unicode string to compare with user input.
NSString *unicodeString = [[font stringWithPDFString:string] lowercaseString];

stringWithPDFString в Font преобразует последовательность символьных идентификаторов своего аргумента в строку Unicode.

Таким образом, несмотря на имя переменной, cidString является не последовательностью символьных идентификаторов, а вместо символов unicode. Тем не менее, его записи используются в качестве аргумента didScanCharacter, который в Scanner реализован для пересылки позиции на ширину символа: он использует значение в качестве параметра widthOfCharacter в Font для определения ширины символа и этот метод (согласно комментарию "Ширина"). данного символа (CID) масштабируется до размера шрифта ") ожидает, что его аргумент будет идентификатором символа.

Таким образом, если CID и код символа Unicode не совпадают, определяется неправильная ширина символа, и позиция любого следующего символа не может быть доверенной. В данном случае лигатура /fi имеет CID 12, который сильно отличается от кода Unicode 0xfb01.

Я бы предложил усовершенствовать PDFKitten, чтобы он также определял метод didScanCID в StringDetector, который в appendPDFString должен вызываться рядом с didScanCharacter для каждого обработанного символа, пересылающего свой CID. Сканер затем должен использовать этот новый метод вместо того, чтобы вычислить ширину, чтобы переместить его курсор.

Это должно быть проверено в первую очередь, хотя. Возможно, некоторые реализации widthOfCharacter (есть разные для разных типов шрифтов), несмотря на комментарий, ожидают, что аргумент будет в конце концов кодом Unicode...

(Извините, если я использовал неправильный словарь здесь или там, я - парень из Java...:))

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