2015-05-04 51 views
2

我正试图计算矢量PDF中每个文本字形的确切边界框。精确的PDF中字形的边界框?

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

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

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

而且,请注意,我定义边框为“可以包含字形的全部取材部位最小的盒子。”没有必要忽略上行/下行/等。这可能被认为是在其他应用程序的边界框“外部”。

很多移动部件在这里,我发现它很难调试。所以这里是我最喜欢的帮助:

  1. This example PDF I've created有10个字形。设备空间中这10个字形的“基本事实”边界框定位是什么?我目前的代码产生以下内容,但这是不正确的。我知道这是不正确,因为它说的第一个字形(” &‘)水平相交的第二(’\ u02d9" ),你可以看到当您查看PDF阅读器PDF格式是不正确的。
'&'  (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的复杂性,我意识到这是一个很重要的问题)。这将对演练有巨大的帮助,我相信这对将来的其他人会有帮助。

  • 是否有一个工具,这是否下架?

  • +1

    恐怕** A ** PDF说明书中的描述已经相当不错了。您可能想要提出具体问题或分享您的(整理)代码进行分析,而不是等待某人重新制定规范。而** B **你的起始位置看起来不太远(差异可能是由于目标坐标系或选定的起始点不同),但是你从这些坐标系跨出的矩形看起来很奇怪。 – mkl

    回答

    4

    我相信获得真正准确的信息的唯一方法是实际渲染给定点大小的字形并收集得到的位图的范围。

    即使提取描述字形路径不会给你完全准确的信息,因为暗示可以巧妙地(或在某些情况下,不那么巧妙地)改变字形呈现方式。在任何情况下提取的路径是一样多的工作,甚至更多,渲染位图.....

    有广泛的三类字体的PDF格式:

    1. 字体以PostScript概要
    2. 使用TrueType字体轮廓
    3. 用户定义的字体。

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

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

    请注意,字体可以按照2种方式组织,常规字体和CIDFonts,以及获取与字符代码对应的字形数据的方法在两者之间不同,但我认为您已经准备好在您的现有的代码。

    在您的情况下,您有可能会限制您可能看到的字体种类的工作流程,因此您可能不需要全部实现所有这些。例如,我看到您正在使用带有TrueType轮廓的CIDFonts,但CIDToGIDMap为/Identity,这可以减少问题的范围。

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

    请记住,PDF可以为字形指定不同的宽度,以符合在字体中定义的宽度,并且您的字体都包含/W数组,用于修改字体中定义的宽度。

    如果考虑到左侧轴承和前进宽度作为字形的一部分,但其数值小于提前宽度,则可能是两个字形会“碰撞”,但实际上仍然存在它们之间有空白区域。所有/Widths所做的工作是从前进宽度减少空白,以使字形比正常情况更接近。

    我在此使用MuPDF快速的bash这给了答案:

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

    以及物品是否完整,这里是从Ghostscript的使用txtwrite设备相同的信息与-dTextFormat=0

    <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> 
    

    它看起来好像还有一个错误,但在char bbox中的urx值是不正确的,但在跨度bbox中是正确的。

    +0

    “您需要考虑代表'边界框'的内容” - 感谢您指出了这一点。我刚刚编辑了这个问题来澄清。 –

    3

    你可能也想看看这个的Adobe GitHub的库:

    afdko子目录中包含了大量的命令行工具,可以有效地用于检测,检查并转换字体文件。我从这次回购的tx工具,以打印约从PDF samplemutool extract提取的字体文件的一些信息:

    $ 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}} 
    

    也许这或其他28之一在这个回购命​​令行工具,也可能对你有用...