当前位置: 首页 > 知识库问答 >
问题:

PDF中字形的精确边界框?

申屠健
2023-03-14

我试图计算矢量PDF中每个文本图示符的精确边界框。

这包括跟踪CTM,绘制/定位PDF指令等。,但也计算字形空间中每个特定字形的边界(使用嵌入式字体中GLYF表中的信息)。

我意识到PDF字体描述符包括每个嵌入式字体的粗略边界框,但这是字体中所有字形的组合——即适合字体中所有字形的最小边界框。为了我的目的,我需要更精确的定位。

我的具体应用是从乐谱的矢量PDF中提取音乐语义。因此,一个很好的约束是,我可以假设glyph不是在同一个Tj/Tj操作符中绘制在一起的。每个图示符都是独立绘制的。

另外,请注意,我将边界框定义为“可以包含图示符所有绘制部分的最小框”没有必要忽略升序/降序等。在其他应用程序中,这些升序/降序可能被视为“在”边界框之外。

这里有很多活动部件,我发现调试起来很困难。下面是我想要帮助的:

  1. 我创建的这个示例PDF有10个标志符号。在设备空间中,这10个标志符号的“地面真相”边界框定位是什么?我当前的代码生成以下内容,但它是不正确的。我知道这是不正确的,因为它说的是第一个雕文(“
'&'      ( 57.2799755477664, 600.7092061684704,  86.7452642315424, 677.1570718099680)
'\u02d9' ( 82.0030393188000, 633.6851606704608,  96.3090818379936, 644.6969866323168)
'\u0153' (144.7841941848000, 623.9630080194528, 158.6735558539200, 634.5581702962656)
'\u0153' (181.6778111184000, 619.0027260546528, 195.5671727875200, 629.5978883314656)
'w'      (226.1671727148000, 611.3638918288608, 245.0765465300448, 622.3161944071392)
'w'      (320.1063822180000, 631.2050196880608, 339.0157560332448, 642.1573222663392)
'\u0153' (414.0455917212000, 641.3239948962528, 427.9349533903200, 651.9191571730656)
'\u0153' (450.9392086548000, 636.3637129314528, 464.8285703239200, 646.9588752082656)
'\u0153' (487.9878407856000, 631.4034309666528, 501.8772024547200, 641.9985932434656)
'\u0153' (524.8814577192000, 628.9232899842528, 538.7708193883200, 639.5184522610656)

你是如何计算这些位置的?(考虑到PDF的复杂性,我意识到这是一个很大的要求。)走查将是一个巨大的帮助,我相信它将在未来帮助其他人。

有现成的工具可以做到这一点吗?

共有2个答案

袁开宇
2023-03-14

您可能还想看看这个Adobe GitHub存储库:

  • github。com/adobe类型的工具

afdko子目录包含许多命令行工具,可以用来测试、检查和转换字体文件。我使用了本回购协议中的tx工具,以打印有关使用mutool extract从您的PDF样本中提取的字体文件的一些信息:

$ mutool extract pdf_example.pdf

 extracting font QNAAAA+PlantinMTStd-Regular-0013.ttf
 extracting font QSAAAA+OpusStd-0018.ttf

然后:

$  tx -mtx  QSAAAA+OpusStd-0018.ttf 

 tx: --- QSAAAA+OpusStd-0018.ttf
 tx: (ttr) cmap table missing
 ### glyph[tag] {gname,enc,width,{left,bottom,right,top}}
 glyph[0] {.notdef,-,0,{0,0,0,0}}
 glyph[1] {g1,-,1640,{4,-1313,1489,2540}}
 glyph[2] {g2,-,891,{0,-276,721,279}}
 glyph[3] {g3,-,866,{0,-266,700,268}}
 glyph[4] {g4,-,1106,{0,-276,953,276}}

也许这个,或者这个repo中的其他28个命令行工具之一,也可能对你有用。。。

笪涛
2023-03-14

我认为获得真正准确信息的唯一方法是以给定的点大小渲染轮廓,并收集结果位图的范围。

即使提取描述字形的路径也无法提供完全准确的信息,因为暗示可以微妙地(或在某些情况下,不那么微妙地)改变字形的渲染方式。在任何情况下,提取路径的工作量与渲染位图的工作量一样大,可能更多。。。。。

PDF中大致有三类字体:

  1. 带有PostScript轮廓的字体
  2. 带有TrueType轮廓的字体
  3. 用户定义的字体

您可以使用FreeType从带有PostScript和TrueType轮廓的字体渲染字形(如果您愿意使用,也可以让它返回路径)。

用户定义(类型3)字体必须视为一系列PDF操作,按文本矩阵缩放。所以你需要自己去做。

请注意,字体可以有两种组织方式,常规字体和CIDFonts,获取字符代码对应的字形数据的方法在这两种方式中有所不同,但我假设您已经准备好在现有代码中处理这一问题。

在你的情况下,你可能有一个工作流,它限制了你可能看到的字体的种类,所以你可能不需要所有这些的完整实现。例如,我看到您正在使用带有TrueType轮廓的CIDFonts,但CIDToGIDMap是/Identity,这减少了问题的范围。

对于额外的复杂性,您需要考虑代表字形的“边界框”的内容。你认为前进的宽度和左侧的轴承是包围盒的一部分,还是只是标记的区域?

请记住,PDF可以为字形指定与字体中定义的字形不同的宽度,并且两种字体都包含修改字体中定义的宽度的数组。

如果你把左边的方位和前进的宽度当作字形的一部分,但是有一个<>代码>宽度>代码>数组,它的值比前进宽度要小,可能是两个字形会出现“碰撞”,但实际上它们之间仍然有空格。所有的/Widths都是减少前进宽度的空白,这样字形就比通常情况下更接近了。

我用MuPDF对此进行了快速的抨击,给出了以下答案:

<span bbox="39.21884 163.68216 42.53509 163.99687" font="PlantinMTStd-Regular" size="11.935925">
<char bbox="39.21884 163.68216 42.53509 163.99687" x="39.21884" y="163.99687" c=" "/>

<span bbox="57.200607 163.69899 73.08967 165.2394" font="OpusStd" size="19.841537">
<char bbox="57.200607 163.69899 73.08967 165.2394" x="57.200607" y="165.2394" c="&amp;"/>

<char bbox="82.003044 151.29828 90.63545 152.83868" x="82.003044" y="152.83868" c="&#x2d9;"/>

<char bbox="144.7842 161.21884 153.1744 162.75925" x="144.7842" y="162.75925" c="&#x153;"/>

<char bbox="181.67781 166.17912 190.06801 167.71953" x="181.67781" y="167.71953" c="&#x153;"/>

<char bbox="226.16718 173.61955 236.8826 175.15996" x="226.16718" y="175.15996" c="w"/>

<char bbox="320.10638 153.77843 330.8218 155.31883" x="320.10638" y="155.31883" c="w"/>

<char bbox="414.0456 143.85785 422.4358 145.39825" x="414.0456" y="145.39825" c="&#x153;"/>

<char bbox="450.9392 148.81815 459.3294 150.35855" x="450.9392" y="150.35855" c="&#x153;"/>

<char bbox="487.98785 153.77843 496.37805 155.31883" x="487.98785" y="155.31883" c="&#x153;"/>

<char bbox="524.8815 156.25856 533.27167 157.79897" x="524.8815" y="157.79897" c="&#x153;"/>

为了完整起见,以下是使用-dTextFormat=0txtwite设备从Ghostscript获得的相同信息:

<page>
<span bbox="39 164 43 164" font="PlantinMTStd-Regular" size="11.9357">
<char bbox="39 164 39 164" c=" "/>
</span>
<span bbox="57 165 73 165" font="OpusStd" size="19.8411">
<char bbox="57 165 57 165" c="&amp;"/>
</span>
<span bbox="82 153 91 153" font="OpusStd" size="19.8411">
<char bbox="82 153 82 153" c="&#x2d9;"/>
</span>
<span bbox="145 163 153 163" font="OpusStd" size="19.8411">
<char bbox="145 163 145 163" c="&#x153;"/>
</span>
<span bbox="182 168 190 168" font="OpusStd" size="19.8411">
<char bbox="182 168 182 168" c="&#x153;"/>
</span>
<span bbox="226 175 237 175" font="OpusStd" size="19.8411">
<char bbox="226 175 226 175" c="w"/>
</span>
<span bbox="320 155 331 155" font="OpusStd" size="19.8411">
<char bbox="320 155 320 155" c="w"/>
</span>
<span bbox="414 145 422 145" font="OpusStd" size="19.8411">
<char bbox="414 145 414 145" c="&#x153;"/>
</span>
<span bbox="451 150 459 150" font="OpusStd" size="19.8411">
<char bbox="451 150 451 150" c="&#x153;"/>
</span>
<span bbox="488 155 496 155" font="OpusStd" size="19.8411">
<char bbox="488 155 488 155" c="&#x153;"/>
</span>
<span bbox="525 158 533 158" font="OpusStd" size="19.8411">
<char bbox="525 158 525 158" c="&#x153;"/>
</span>
</page>

不过,看起来确实有一个bug,在char bbox中urx值是不正确的,但在wide bbox中是正确的。

 类似资料:
  • 有什么regex我可以用来匹配正好10位数的块吗?例如,我有以下内容: 当给定时,这与匹配,但当给定时,这也与匹配,这是我不想要的。

  • 多边形精灵(Polygon Sprite) 也是一个精灵,同样是为了展示一个可以被控制的图像,但是和普通精灵的区别是,普通精灵在绘图处理中被分为了两个三角形,多边形精灵则是被分为了一系列三角形。 为什么要使用多边形精灵 提高性能! 要深入分析这个是如何提高性能的,会需要很多和像素填充率有关的技术术语。幸好本节是入门性质的文档,能让大家理解多边形精灵比普通精灵性能好就可以了,不用讨论特定宽高矩形绘制

  • 我有一个关于libGDX碰撞检测的问题。因为这是一个相当具体的问题,我还没有在互联网上找到任何好的解决方案。 因此,我已经创建了由不同身体部位组成的“人类”,每个部位都有矩形碰撞检测。 现在我想实现武器和技能,例如看起来像这样: 技能示例图像 问题 当有这样的技能时,在碰撞检测中使用矩形会让玩家非常沮丧:他们会成功躲避技能,但碰撞检测器仍然会伤害他们。 方法 1: 在我开始使用Libgdx之前,我

  • 我需要将matplotlib图形保存到pdf。我遵循Matplotlib howto上的说明,只是不显示结果,而是将其保存为pdf。奇怪的是,pdf画布不受画布大小的影响。相反,保存为png可以在放大的画布上正常工作。 pdf图像的截屏 更新 对标题和轴标记执行此操作,但如果图例位于框架外部,则忽略图例,如下图所示。请注意,我将图例放置在图形的右侧。

  • 我正在为我的播放器和bullet类创建一些围绕精灵的矩形,以使用LibGDX的Intersector类中的重叠方法检测碰撞。 我有一个问题: 当我实例化Player和Bullet时,我使用sprite.getBoundingRectangle()在精灵周围创建一个边界框,它返回一个Rectangle对象。我在主类的其他地方更新这些的移动。 当我更新子弹/玩家精灵的移动时,我是否也需要更新子弹/玩家

  • 我想计算一个随机多边形的面积和一个随机多面体的体积。谷歌搜索让我找到了镶嵌和蒙特卡罗方法。然而,我只感兴趣的是一个精确的计算,而不是通过收敛的近似值。可能有人知道确切的公式,或有一个网页的链接,这样的公式被描述? 对于奇异多边形或多面体,不需要用到这些公式。如果它们适用于简单的(不相交的边)凸形状,我已经很满意了。我只想使用一个顶点坐标列表或(可能按特定顺序排列)。 我能够阅读、、和。因此,用这些