字的研究(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))

运行结果如下:

[, ]

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

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

在上述方法中,最后一种与等高线数据相关的方法是最重要的。遗憾的是,官方文件似乎没有对这个对象做出任何进一步的解释,所以以下是我在阅读源代码及其评论后的分析。如果有任何错误或遗漏,请让我知道。

[En]

Of the above methods, the last one related to contour data is the most important. Unfortunately, the official document does not seem to give any further explanation to this object, so the following is my analysis after reading the source code and its comments. If there are any mistakes or omissions, please let me know.

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)) # 显示以及矫正

运行结果如下:

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

注意,可能由于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

Original: https://www.cnblogs.com/yc0806/p/15842529.html
Author: 多事鬼间人
Title: 字的研究(2)fontTools-字体文件的解析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/510146/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球