前言

本文主要介绍如果使用Python第三方库fontTools提取OpenType字体文件中的TrueType轮廓坐标以及如何构建基于TrueType的Glyph实例

TrueType轮廓坐标的获取

对于TrueType轮廓描述的OpenType文件,除了前文提到的利用ttx组件将表结构转化为XML文件方法,利用如下代码也可以直接获取具体的轮廓数据:

from fontTools.ttLib import TTFont

font = TTFont("Resources/simsun.ttf")
glyph = font.getGlyphSet()["uni70E0"] # 获取_TTGlyph实例
print(glyph._glyph.coordinates) # 坐标
print(glyph._glyph.endPtsOfContours) # 轮廓结束点
print(list(glyph._glyph.flags)) # 点类型flag

运行结果如下:

GlyphCoordinates([(138, 118),(138, 86),(206, 86),(206, 118),(138, 80),(138, 49),(206, 49),(206, 80),(138, 43),(138, -19),(123, -26),(124, -5),(124, 16),(124, 99),(110, 81),(86, 67),(84, 70),(118, 100),(142, 158),(125, 158),(112, 158),(101, 155),(92, 164),(144, 164),(154, 192),(156, 209),(176, 197),(169, 192),(161, 170),(159, 164),(207, 164),(221, 177),(238, 158),(157, 158),(151, 142),(140, 124),(205, 124),(214, 134),(229, 119),(220, 114),(220, 1),(220, -17),(199, -25),(197, -9),(168, -4),(168, 0),(195, -2),(206, 0),(206, 8),(206, 43),(52, 206),(74, 194),(67, 187),(67, 123),(87, 148),(91, 161),(105, 147),(99, 146),(90, 137),(81, 128),(67, 115),(67, 91),(64, 57),(87, 46),(103, 29),(103, 22),(103, 18),(99, 7),(92, 9),(87, 22),(82, 34),(63, 52),(56, 8),(12, -26),(11, -23),(41, 13),(53, 74),(53, 149),(33, 140),(34, 126),(33, 104),(25, 92),(13, 88),(10, 95),(10, 97),(10, 102),(14, 105),(19, 109),(28, 128),(29, 140)])
[3, 7, 49, 77, 89]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1]

描述TrueType轮廓的数据主要由坐标、轮廓结束点以及各点的类型flag组成。其中,轮廓结束点为各轮廓的最后一个点的坐标;点类型flag则和坐标一一对应,说明该点是普通点还是贝塞尔曲线的控制点,0为控制点,1为普通点(注意,TrueType轮廓只包含二次贝塞尔曲线)。

相比之下,我个人更倾向将数据转化为如下由三元组组成的二维数组的形式,更方便理解和处理:

coordinates = list(glyph._glyph.coordinates)
endPts = glyph._glyph.endPtsOfContours
flags = list(glyph._glyph.flags) contours = []
contour = []
for i, (x,y) in enumerate(coordinates):
contour.append((x,y,flags[i]))
if i in endPts:
contours.append(contour)
contour = [] print(contours)

运行结果如下:

[[(138, 118, 1), (138, 86, 1), (206, 86, 1), (206, 118, 1)],
[(138, 80, 1), (138, 49, 1), (206, 49, 1), (206, 80, 1)],
[(138, 43, 1), (138, -19, 1), (123, -26, 1), (124, -5, 0), (124, 16, 1), (124, 99, 1), (110, 81, 0), (86, 67, 1), (84, 70, 1), (118, 100, 0), (142, 158, 1), (125, 158, 1), (112, 158, 0), (101, 155, 1), (92, 164, 1), (144, 164, 1), (154, 192, 0), (156, 209, 1), (176, 197, 1), (169, 192, 1), (161, 170, 0), (159, 164, 1), (207, 164, 1), (221, 177, 1), (238, 158, 1), (157, 158, 1), (151, 142, 0), (140, 124, 1), (205, 124, 1), (214, 134, 1), (229, 119, 1), (220, 114, 1), (220, 1, 1), (220, -17, 0), (199, -25, 1), (197, -9, 0), (168, -4, 1), (168, 0, 1), (195, -2, 0), (206, 0, 0), (206, 8, 1), (206, 43, 1)],
[(52, 206, 1), (74, 194, 1), (67, 187, 1), (67, 123, 1), (87, 148, 0), (91, 161, 1), (105, 147, 1), (99, 146, 0), (90, 137, 1), (81, 128, 0), (67, 115, 1), (67, 91, 0), (64, 57, 1), (87, 46, 0), (103, 29, 0), (103, 22, 1), (103, 18, 0), (99, 7, 0), (92, 9, 0), (87, 22, 1), (82, 34, 0), (63, 52, 1), (56, 8, 0), (12, -26, 1), (11, -23, 1), (41, 13, 0), (53, 74, 0), (53, 149, 0)],
[(33, 140, 1), (34, 126, 0), (33, 104, 0), (25, 92, 0), (13, 88, 0), (10, 95, 0), (10, 97, 1), (10, 102, 0), (14, 105, 1), (19, 109, 0), (28, 128, 0), (29, 140, 1)]]

基于TrueType的Glyph实例的构建

构建fontTools中的Glyph实例主要可以用于后续建立新的基于TrueType轮廓的字体文件。所采用的方法是基于前文所提到的Pen对象的子类TTGlyphPointPen,输入坐标、轮廓结束点以及各点的类型flag三项数据,输出Glyph实例:

from fontTools.pens.ttGlyphPen import TTGlyphPointPen

coordinates = [(138, 118),(138, 86),(206, 86),(206, 118),(138, 80),(138, 49),(206, 49),(206, 80),(138, 43),(138, -19),(123, -26),(124, -5),(124, 16),(124, 99),(110, 81),(86, 67),(84, 70),(118, 100),(142, 158),(125, 158),(112, 158),(101, 155),(92, 164),(144, 164),(154, 192),(156, 209),(176, 197),(169, 192),(161, 170),(159, 164),(207, 164),(221, 177),(238, 158),(157, 158),(151, 142),(140, 124),(205, 124),(214, 134),(229, 119),(220, 114),(220, 1),(220, -17),(199, -25),(197, -9),(168, -4),(168, 0),(195, -2),(206, 0),(206, 8),(206, 43),(52, 206),(74, 194),(67, 187),(67, 123),(87, 148),(91, 161),(105, 147),(99, 146),(90, 137),(81, 128),(67, 115),(67, 91),(64, 57),(87, 46),(103, 29),(103, 22),(103, 18),(99, 7),(92, 9),(87, 22),(82, 34),(63, 52),(56, 8),(12, -26),(11, -23),(41, 13),(53, 74),(53, 149),(33, 140),(34, 126),(33, 104),(25, 92),(13, 88),(10, 95),(10, 97),(10, 102),(14, 105),(19, 109),(28, 128),(29, 140)]
endPts = [3, 7, 49, 77, 89]
flags = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1] pen = TTGlyphPointPen(None)
beginflag = 0
for i, pt in enumerate(coordinates):
if pen._isClosed():
pen.beginPath()
if flags[i] == 1:
pen.addPoint(pt,segmentType="line")
else:
pen.addPoint(pt)
if i in endPts:
pen.endPath()
glyph = pen.glyph()

返回的glyph即为Glyph实例,可直接用于构建基于TrueType轮廓的字体文件。注意,Glyph对象只包含字形轮廓数据,属于glyf表,对应前一节提到的_TTGlyph中的_glyph属性,_TTGlyph中的字宽和上下沿等数据则来自在字体文件的其他表格。

最新文章

  1. session 安全相关
  2. PowerDesigner V16.5 安装文件
  3. Spring 数据库配置用户名和密码加密
  4. json不支持中文写入的问题解决
  5. 股票自用指标 boll 菜刀
  6. JVM垃圾回收机制总结(1) :一些概念
  7. C专家编程 总结
  8. codeforces 339C Xenia and Weights(dp或暴搜)
  9. PHP学习笔记5-类的继承/方法重写
  10. 【图像识别】 图像处理和图像分析(leptonica)leptonica-1.68安装配置 (vs2008)
  11. XAMPP on Mac 组态 Virual Host
  12. Mapreduce 反向索引
  13. Promise基础
  14. EntityFramework Core 1.1有哪些新特性呢?我们需要知道
  15. Mybatis-Generator生成Mapper文件中<if test="criteria.valid">的问题解答
  16. R语言学习 第十一篇:日期和时间
  17. 【原创】大叔经验分享(47)yarn开启日志归集
  18. js的回调函数
  19. JS脚本计算从某日凌晨开始,经过了多长时间
  20. esxI开启虚拟化

热门文章

  1. 【LeetCode】528. Random Pick with Weight 解题报告(Python)
  2. GCD (hdu 5726)
  3. Monkey工具之fastbot-iOS实践
  4. Jmeter性能测试场景的创建和运行
  5. springboot中word转pdf,加盖电子印章
  6. CapstoneCS5210|HDMI转VGA音视频转接线|CS5210转换器方案芯片
  7. Capstone CS5218|CS5218参数|CS5218电路
  8. Layui的本地存储方法-Layui.data的基本使用
  9. .net core系列源码地址介绍
  10. python_接口自动化测试_处理参数替换