itextsharp,当 space 在视觉上很明显时,为什么 GetSingleSpaceWidth() 返回 0?
itextsharp , why is GetSingleSpaceWidth() returning 0 when a space is visually obvious?
大家好,
这是一个与 itextsharp 版本 5.5.13.1 有关的问题。我正在使用自定义 LocationTextExtractionStrategy 实现从 PDF 文档中提取有意义的词。我正在调用 TextRenderInfo 的方法 GetSingleSpaceWidth 来确定何时
根据 SFO link 将两个相邻的字符块连接成一个单词
itext java pdf to text creation
这种方法通常效果很好。但是,如果您查看附件,“Credit”和“Extended”这两个词给我带来了一些问题。
为什么屏幕截图中显示的所有字符都为 GetSingleSpaceWidth 返回零值?这就造成了一个问题。而不是两个单独的词,我的逻辑 returns 我一个词“CreditExtended”。
我了解到不再支持 itextsharp5。任何建议将不胜感激?
示例文档
https://drive.google.com/open?id=1pPyNRXvnUyIA2CeRrv05-H9q0sTUN97d
正如评论中已经推测的那样,原因是所讨论的字体不包含常规 space 字形,或者更准确地说,没有将其任何字形映射到 Unicode 值 U+ 0020 在其 ToUnicode 映射中。
如果字体有 ToUnicode 映射,iText 仅使用来自该映射的信息。因此,iText 无法识别该字体中的 space 字形,因此它无法提供实际的 SingleSpaceWidth
值,而是 returns 0。
有问题的字体名为 F5 并具有此 ToUnicode 映射:
/CIDInit /ProcSet findresource begin
14 dict begin
begincmap
/CIDSystemInfo
<< /Registry (Adobe)
/Ordering (UCS)
/Supplement 0
>> def
/CMapName /Adobe-Identity-UCS def
/CMapType 2 def
1 begincodespacerange
<0000> <FFFF>
endcodespacerange
4 beginbfchar
<0004> <0041>
<0012> <0043>
<001C> <0045>
<002F> <0049>
endbfchar
1 beginbfrange
<0044> <0045> <004D>
endbfrange
13 beginbfchar
<0102> <0061>
<0110> <0063>
<011A> <0064>
<011E> <0065>
<0150> <0067>
<015D> <0069>
<016F> <006C>
<0176> <006E>
<017D> <006F>
<0189> <0070>
<018C> <0072>
<0190> <0073>
<019A> <0074>
endbfchar
5 beginbfrange
<01C0> <01C1> <0076>
<01C6> <01C7> <0078>
<0359> <0359> [<2026>]
<035A> <035B> <2018>
<035E> <035F> <201C>
endbfrange
1 beginbfchar
<0374> <2013>
endbfchar
endcmap
CMapName currentdict /CMap defineresource pop
end
end
如您所见,没有映射到 <0020>
。
这个PDF页面中字体的使用还挺搞笑的,顺便说一句:
它的主体(大部分)是使用 Calibri 绘制的,但它为此使用了两个不同的 PDF 字体对象,F4,它使用 WinAnsiEncoding从字符 32 到 122,即 包括 space 字形 ,以及使用 Identity-H 的 F5 并提供上面引用的 ToUnicode 映射 没有 space 字形 。每个没有间隙的最大字形序列被单独绘制;如果可以使用 F4 绘制整个序列,则使用该字体,否则使用 F5。
因此,CMI
、(Credit
和sub-indexes
是使用F4绘制的,而I’ve
、“Credit
, 和 Extended”
使用 F5.
绘制
因此,在您的问题字符串 “Credit Extended”
中,我们看到使用 F5 绘制的两个连续序列。因此,“Credit
t 和 Extended”
E 都将得到 0 SingleSpaceWidth
.
乍一看,这些是使用 F5 的仅有的两个连续序列,所以你只在那里有那个问题。
因此,您应该针对两个连续字符都带有 0 SingleSpaceWidth
的情况制定回退策略,例如使用大约三分之一的字体大小。
大家好,
这是一个与 itextsharp 版本 5.5.13.1 有关的问题。我正在使用自定义 LocationTextExtractionStrategy 实现从 PDF 文档中提取有意义的词。我正在调用 TextRenderInfo 的方法 GetSingleSpaceWidth 来确定何时 根据 SFO link 将两个相邻的字符块连接成一个单词 itext java pdf to text creation
这种方法通常效果很好。但是,如果您查看附件,“Credit”和“Extended”这两个词给我带来了一些问题。 为什么屏幕截图中显示的所有字符都为 GetSingleSpaceWidth 返回零值?这就造成了一个问题。而不是两个单独的词,我的逻辑 returns 我一个词“CreditExtended”。
我了解到不再支持 itextsharp5。任何建议将不胜感激?
示例文档
https://drive.google.com/open?id=1pPyNRXvnUyIA2CeRrv05-H9q0sTUN97d
正如评论中已经推测的那样,原因是所讨论的字体不包含常规 space 字形,或者更准确地说,没有将其任何字形映射到 Unicode 值 U+ 0020 在其 ToUnicode 映射中。
如果字体有 ToUnicode 映射,iText 仅使用来自该映射的信息。因此,iText 无法识别该字体中的 space 字形,因此它无法提供实际的 SingleSpaceWidth
值,而是 returns 0。
有问题的字体名为 F5 并具有此 ToUnicode 映射:
/CIDInit /ProcSet findresource begin
14 dict begin
begincmap
/CIDSystemInfo
<< /Registry (Adobe)
/Ordering (UCS)
/Supplement 0
>> def
/CMapName /Adobe-Identity-UCS def
/CMapType 2 def
1 begincodespacerange
<0000> <FFFF>
endcodespacerange
4 beginbfchar
<0004> <0041>
<0012> <0043>
<001C> <0045>
<002F> <0049>
endbfchar
1 beginbfrange
<0044> <0045> <004D>
endbfrange
13 beginbfchar
<0102> <0061>
<0110> <0063>
<011A> <0064>
<011E> <0065>
<0150> <0067>
<015D> <0069>
<016F> <006C>
<0176> <006E>
<017D> <006F>
<0189> <0070>
<018C> <0072>
<0190> <0073>
<019A> <0074>
endbfchar
5 beginbfrange
<01C0> <01C1> <0076>
<01C6> <01C7> <0078>
<0359> <0359> [<2026>]
<035A> <035B> <2018>
<035E> <035F> <201C>
endbfrange
1 beginbfchar
<0374> <2013>
endbfchar
endcmap
CMapName currentdict /CMap defineresource pop
end
end
如您所见,没有映射到 <0020>
。
这个PDF页面中字体的使用还挺搞笑的,顺便说一句:
它的主体(大部分)是使用 Calibri 绘制的,但它为此使用了两个不同的 PDF 字体对象,F4,它使用 WinAnsiEncoding从字符 32 到 122,即 包括 space 字形 ,以及使用 Identity-H 的 F5 并提供上面引用的 ToUnicode 映射 没有 space 字形 。每个没有间隙的最大字形序列被单独绘制;如果可以使用 F4 绘制整个序列,则使用该字体,否则使用 F5。
因此,CMI
、(Credit
和sub-indexes
是使用F4绘制的,而I’ve
、“Credit
, 和 Extended”
使用 F5.
因此,在您的问题字符串 “Credit Extended”
中,我们看到使用 F5 绘制的两个连续序列。因此,“Credit
t 和 Extended”
E 都将得到 0 SingleSpaceWidth
.
乍一看,这些是使用 F5 的仅有的两个连续序列,所以你只在那里有那个问题。
因此,您应该针对两个连续字符都带有 0 SingleSpaceWidth
的情况制定回退策略,例如使用大约三分之一的字体大小。