原始文本宽度通常以typographer's points计算,但由于字体定义的点定义为1/72英寸,因此可以轻松地将其转换为任何其他单位。在
要获得字符的设计宽度(用em单位表示),您需要访问字体的底层数据。最简单的方法是^{},它可以在尽可能低的字体定义级别上工作。在
安装fontTools后,您可以:加载字体数据–这需要实际字体文件的路径
字符宽度存储为glyph宽度,这意味着您必须检索“字符到glyph”映射;这在字体的cmap表中:
a.为你的字体加载cmap。最有用的是Unicode映射——字体可能包含其他字体。
b、 加载字体的字形集。这是该字体中字形的名称列表。
然后,对于每个Unicode字符,首先查找其名称,然后使用该名称以设计单位检索其宽度。
别忘了“设计单位”是基于字体的总体“设计宽度”。这可以是标准值1000(典型的type1字体)、2048(TrueType字体的典型值)或任何其他值。在
这就产生了这个功能:from fontTools.ttLib import TTFont
from fontTools.ttLib.tables._c_m_a_p import CmapSubtable
font = TTFont('/Library/Fonts/Arial.ttf')
cmap = font['cmap']
t = cmap.getcmap(3,1).cmap
s = font.getGlyphSet()
units_per_em = font['head'].unitsPerEm
def getTextWidth(text,pointSize):
total = 0
for c in text:
if ord(c) in t and t[ord(c)] in s:
total += s[t[ord(c)]].width
else:
total += s['.notdef'].width
total = total*float(pointSize)/units_per_em;
return total
text = 'This is a test'
width = getTextWidth(text,12)
print ('Text: "%s"' % text)
print ('Width in points: %f' % width)
print ('Width in inches: %f' % (width/72))
print ('Width in cm: %f' % (width*2.54/72))
print ('Width in WP Units: %f' % (width*1200/72))
结果是:
^{pr2}$
与adobeindesign的报告相比是正确的。(请注意,这里不应用逐字符紧排(per character字距调整)!这需要更多的代码。)
未在字体中定义的字符将被静默忽略,并且通常会使用.notdef字形的宽度。如果要将此报告为错误,请删除函数中的if测试。在
函数getTextWidth中对float的强制转换在Python2.7和3.5下都适用,但请注意,如果使用Python2.7和更大值的Unicode字符(而不是纯ASCII),则需要重写该函数以正确使用UTF8字符。在