百木园-与人分享,
就是让自己快乐。

字的研究(2)fontTools-字体文件的解析

前言

本文主要介绍如果使用Python第三方库fontTools对OpenType字体文件(包括TrueType轮廓和Postscript轮廓)的解析操作。

fontTools简介

fontTools是由一组操作字体的库和组件组成的Python第三方库,要求Python3.6以及更高的版本。其中包括merge(字体合并)、subset(取字体子集)以及ttx(将OpenType转化为XML)等。

安装

pip install fontTools

本文中使用的版本为4.28.5

字体文件的解析

读取

如前文所述,OpenType字体文件标准是有sfnt结构封装的,基于sfnt的表结构,OpenType格式的字体文件可以分为多个表结构。

创建TTFont实例,通过keys()可以查看字体文件的所有表名:

from fontTools.ttLib.ttFont import TTFont
font = TTFont(\"Resources/simsun.ttf\")
print(font.keys())

运行结果如下:

[\'GlyphOrder\', \'head\', \'hhea\', \'maxp\', \'OS/2\', \'hmtx\', \'cmap\', \'fpgm\', \'prep\', \'cvt \', \'loca\', \'glyf\', \'name\', \'post\', \'gasp\', \'EBDT\', \'EBLC\', \'GDEF\', \'GPOS\', \'GSUB\', \'MERG\', \'meta\', \'vhea\', \'vmtx\']

表名中包含‘glyf‘,所以simsun.ttf是一个使用TrueType轮廓的字体文件。

换成使用Postscript轮廓的字体文件:

font = TTFont(\"Resources/AdobeSongStd-Light.otf\")
print(font.keys())

运行结果如下:

[\'GlyphOrder\', \'head\', \'hhea\', \'maxp\', \'OS/2\', \'name\', \'cmap\', \'post\', \'CFF \', \'BASE\', \'GPOS\', \'GSUB\', \'VORG\', \'hmtx\', \'vhea\', \'vmtx\', \'DSIG\']

表名中没有\'glyf\'而存在\'CFF \',后者是存储Postscript信息的表格。

对于TrueType Collection文件则可以使用如下方法读取,返回一个TTFont实例的列表

from fontTools.ttLib.ttCollection import TTCollection
collection = TTCollection(\"Resources/simsun.ttc\")
print(list(collection))

运行结果如下:

[<fontTools.ttLib.ttFont.TTFont object at 0x000001F8BA66A700>, <fontTools.ttLib.ttFont.TTFont object at 0x000001F8BE072AF0>]

直接从这些表格提取到具体信息是复杂的,但TTFont提供了一些方法以方便地获取信息:

font.getGlyphOrder() # 返回一个字形名称列表,以其在文件中的顺序排序
font.getGlyphNames() # 返回一个字形名称列表,以字母顺序排序
font.getBestCmap() # 返回一个字形ID为键、字形名称为值的字典
font.getReverseGlyphMap() # 返回一个字形名称为键、字形ID为值的字典
font.getGlyphName(10000) # 输入字形ID返回字形名称
font.getGlyphID(\"uni70E0\") # 输入字形名称返回字形ID
font.getGlyphSet() # 返回一个_TTGlyphSet对象,包含字形轮廓数据

上述方法中,最后一项与轮廓数据有关的方法是最重要的。可惜的是,官方文档似乎并没有对这个对象做进一步解释,故下文是我读源码及其中注释后的分析,如有错漏,敬请指教。

Pen与_TTGlyphset

我认为,作者设计这一部分时的难点在于OpenType字体文件标准存在两种不同轮廓描述方式。Pen和_TTGlyphset的存在使得两种不同的轮廓描述方式可以用同一套方法解析和显示。

The Pen Protocol

基于TrueType轮廓的字体文件和基于Postscript轮廓是两种截然不同的数据格式。Pen是一个用于标准化的”画\"出轮廓的对象,或者是数据和实际轮廓间的媒介。

具体来说,Pen对象的子类包含将上述两种轮廓数据转化为画线、移动等模拟实际轮廓的方法。在fontTools的pen库中包含将轮廓数据转化为qt、reportLab等第三方库中实例的Pen子类。

_TTGlpyhset

_TTGlyphset是一个类似字典的,以字形名称为键、_TTGlyph为值的对象。_TTGlyph中包含字形数据轮廓数据并可以通过draw方法“画”出。_TTGlyph的两个子类_TTGlyphGlyf和_TTGlyphCFF分别对应TrueType轮廓和Postscript轮廓。具体使用方法如下:

font = TTFont(\"Resources/simsun.ttf\")
glyph = font.getGlyphSet()[\"uni70E0\"]
glyph.draw(pen) # pen为实例化后的Pen子类

freetypePen

以freetype-py库为例,使用freetypePen首先需要安装freetype-py:

pip install freetype-py

以下代码修改自自fontTools的官方文档提供的范例程序:

from fontTools.ttLib import TTFont
from fontTools.pens.freetypePen import FreeTypePen
from fontTools.misc.transform import Offset

pen = FreeTypePen(None) # 实例化Pen子类
font = TTFont(\"Resources/simsun.ttf\") # 实例化TTFont
glyph = font.getGlyphSet()[\"uni70E0\"] # 通过字形名称选择某一字形对象
glyph.draw(pen) # “画”出字形轮廓
width, ascender, descender = glyph.width, font[\'OS/2\'].usWinAscent, -font[\'OS/2\'].usWinDescent # 获取字形的宽度和上沿以及下沿
height = ascender - descender # 利用上沿和下沿计算字形高度
pen.show(width=width, height=height, transform=Offset(0, -descender)) # 显示以及矫正

运行结果如下:

注意,可能由于fontTools==4.28.5版本问题,通过pip安装后freetypePen.py并没有包含在pens文件夹下,需要使用的可以从fontTools的GitHub仓库中下载,放到site-packages\\fontTools\\pens文件夹下,下载路径为https://github.com/fonttools/fonttools/blob/main/Lib/fontTools/pens/freetypePen.py。该问题可能在后续版本中修复。

ttx

最后是我个人认为fontTools中最为实用的一个组件ttx,其功能为将TTFont实例转化为XML格式以及将XML文件转化为TTFont。基于这一组件,我们可以较为方便的实现对字体文件内容的修改。

from fontTools.ttLib import TTFont

font = TTFont(\"Resources/simsun.ttf\") # 实例化TTFont
font.saveXML(\"simsun.xml\") # TTFont实例转化为XML文件,参数为XML文件路径
font.importXML(\"simsun1.xml\") # XML文件转化为TTFont实例,参数为XML文件路径

除了将整个字体文件转化为XML文件,ttx还可以将文件中的单个表转化为XML文件,避免多余的存储和时间消耗:

from fontTools.ttLib.ttFont import TTFont

font = TTFont(\"Resources/simsun.ttf\")
font.saveXML(\"temp2.xml\",tables=[\"glyf\"]) # tables为需要转化的表名组成列表

单个表的XML文件直接导入TTFont时,只会影响XML文件存在的表,而其他表不变:

font.importXML(\"temp2.xml\")

参考

https://fonttools.readthedocs.io/en/latest/index.html

https://github.com/fonttools/fonttools

来源:https://www.cnblogs.com/yc0806/p/15842529.html
图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » 字的研究(2)fontTools-字体文件的解析

相关推荐

  • 暂无文章