5

我正在使用PDFKitten在 PDF 文档中搜索字符串并突出显示结果。FastPDFKit 或任何其他商业库是没有选择的,所以我坚持使用最接近我的要求的库。

坐标错误

正如您在屏幕截图中看到的那样,我搜索了字符串“in”,除了最后一个之外,它始终正确突出显示。我得到了一个更复杂的 PDF 文档,其中突出显示的“in”框几乎有 40% 错误。

我阅读了整个语法并检查了问题跟踪器,但除了行高问题之外,我没有发现关于宽度计算的任何信息。目前我没有看到任何计算方式或可能出错的模式,我希望也许其他人有一个与我密切相关的问题。

我目前的期望是在字体类或 RenderingState.m 中某处计算的坐标和字符宽度是错误的。该项目非常复杂,也许你们中的某些人过去曾遇到过与 PDFKitten 类似的问题。

我使用了来自 PDFKitten 的原始示例 PDF 文档作为我的截图。

4

1 回答 1

4

在计算字符标识符与其 unicode 字符代码不一致的字符宽度时,这可能是 PDFKitten 中的一个错误。

StringDetector 中的 appendPDFString 在处理一些字符串数据时使用两个字符串:

// 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];

Font 中的 stringWithPDFString 将其参数的字符标识符序列转换为 unicode 字符串。

因此,尽管有变量名,cidString 不是字符标识符序列,而是 unicode 字符。尽管如此,它的条目被用作 didScanCharacter 的参数,在 Scanner 中实现了通过字符宽度转发位置:它使用值作为字体中 widthOfCharacter 的参数来确定字符宽度,以及该方法(根据评论“宽度给定字符 (CID) 的缩放到 fontsize") 期望其参数是字符标识符。

因此,如果 CID 和 unicode 字符代码不重合,则会确定错误的字符宽度,并且无法信任任何后续字符的位置。在本例中,/fi 连字的 CID 为 12,这与其 Unicode 代码 0xfb01 大不相同。

我建议对 PDFKitten 进行增强,以便在 StringDetector 中定义一个 didScanCID 方法,对于转发其 CID 的每个已处理字符,应在 appendPDFString 旁边调用该方法。然后扫描仪应该使用这种新方法来计算向前光标的宽度。

不过,这应该首先进行三重检查。尽管有注释,但可能有一些 widthOfCharacter 实现(对于不同的字体类型有不同的实现)期望参数毕竟是一个 unicode 代码......

(对不起,如果我在这里或那里使用了错误的词汇,我是一个'Java人...... :))

于 2012-10-17T10:49:27.730 回答