尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
fonttools mtiLib 全解析:读取 Monotype FontDame 文本格式的 OpenType 布局表
开发工具【免费下载链接】fonttoolsA library to manipulate font files from Python.项目地址https://gitcode.com/gh_mirrors/fo/fonttools点击查看免费下载导读fontTools.mtiLib是 FontTools 中负责读取 Monotype FontDame 与 Font Chef 字体编辑器所产出的 OpenType 布局源文件的模块。这类源文件用简单的制表符分隔文本描述 GSUB、GPOS、GDEF 与 cmap 等表格mtiLib将其解析为 FontTools 的标准表对象并可直接编译进 TTF/OTF。读完本文你将掌握 FontDame 文本格式的行结构与关键字约定、build()与fonttools mtiLib命令行两种用法、各类 lookup 的文本语法与对应的源码解析路径以及测试套件如何验证文本 → 对象 → 二进制 → TTX的完整闭环。mtiLib 的背景与定位根据 Doc/source/mtiLib.rst 的说明FontTools 为 Monotype 的 FontDame 与 Font Chef 两款字体编辑器生成的 OpenType Layout 表提供读取支持。这些编辑器以简单文本格式即 OpenType Table Source源自 Monotype 的开放规范书写布局数据mtiLib库负责解析这些文本文件创建表示其内容的表对象table_G_S_U_B_、table_G_P_O_S_、table_G_D_E_F_、table_c_m_a_p_等通过fonttools mtiLib子命令把文本文件直接转换为 TTX XML 输出。模块本身只有两个文件核心实现 与 CLI 入口。__main__.py只是把控制权转交给main()from fontTools.mtiLib import main if __name__ __main__: sys.exit(main())命令入口fonttools mtiLibfonttools采用 git 风格的多子命令分发机制见 Lib/fontTools/main.py它把第一个参数当作模块名fontTools.subcommand用runpy.run_module运行。因此执行fonttools mtiLib ...实际等价于运行python -m fontTools.mtiLib ...最终调用 main()。main()的完整命令行参数如下由argparse定义参数短选项含义--font FILE-f输入的 TTF/OTF 字体文件用于提供 glyph 顺序、排序 coverage 表不提供时使用内置MockFont--table TABLE-t指定要填充的表格标签如GSUB未提供时从文件头部嗅探sniffinputs—一个或多个 FontDame.txt输入文件位置参数必填处理流程对应 main()for f in args.inputs: with open(f, rt, encodingutf-8-sig) as f: table build(f, font, tableTagargs.tableTag) blob table.compile(font) # 先编译为二进制确认可编译 decompiled table.__class__() decompiled.decompile(blob, font) # 再反编译确认可反编译 # 用 xmlWriter 把 decompiled 表输出为 TTX XML 到 stdout即每个输入文件都先经过编译→反编译往返校验再输出 TTX XML 到标准输出。注意输入文件以utf-8-sig编码读取兼容带 BOM 的文本。典型用法# 自动嗅探表格类型从文件头部的 FontDame/Font Chef 声明行 fonttools mtiLib Tests/mtiLib/data/mti/gsubsingle.txt # 显式指定表格类型 fonttools mtiLib --table GSUB Tests/mtiLib/data/mti/gsubsingle.txt # 提供真实字体让 coverage 按字体 glyph 顺序排序 fonttools mtiLib --font path/to/font.ttf --table GPOS layout.txt文本源文件的行结构Tokenizer 规则mtiLib使用自定义的 Tokenizer 类 读取源文件核心规则如下制表符分隔字段每一行按\t切分成字段列表并去除空白空行直接跳过注释以%开头的行被跳过但% subtable是合法的结构化标记用于分隔子表不会被当作注释行尾多余制表符会触发 warning 并被清理通过between(tag)匹配tag begin/tag end与until(tags)读到任一 stopper 为止两个上下文管理器实现块结构解析expect/expectendswith用于严格断言关键字。例如gsubsingle.txt中的行onehalf onehalf.alt会被解析为两个字段的替换规则。查看 Tests/mtiLib/data/mti/gsubsingle.txtlookup alt-fractions single RightToLeft no IgnoreBaseGlyphs no IgnoreLigatures no IgnoreMarks no onehalf onehalf.alt onequarter onequarter.alt threequarters threequarters.alt lookup end支持的表格与顶层结构parseTable()源码位置支持四种表格GSUB、GPOS、GDEF、cmap。文件头部有两种声明形式FontDame TAG第一字段以FontDame开头第二个词为表标签Font Chef Table TAG前三个词为Font Chef Table第四个词为表标签。见 cmap.txt 测试数据 的Font Chef Table cmap声明。若未提供表标签且文件头无声明解析器会直接断言失败Dont know what table to parse and data doesnt specify。GSUB / GPOS 顶层字段parseGSUBGPOS()源码位置按顺序处理三类顶层块忽略其他未知行行起始关键字生成的属性解析函数script table beginScriptListparseScriptListfeature table beginFeatureListparseFeatureListlookupLookupList追加parseLookup三者可以在同一文件中以任意顺序混合出现测试用例mixed-toplevels即为此场景见 Tests/mtiLib/data/mixed-toplevels.txt。Script List脚本表parseScriptList()源码位置中每行四个字段scriptTag、langSysTag、defaultFeature、features逗号分隔的 feature 索引列表。langSysTag为default时设置该脚本的DefaultLangSys否则登记为具名LangSysRecord。表头标签不足 4 字符时用空格补齐ljust(4)。真实示例 scripttable.txtscript table begin cyrl default 3, 4, 1 grek default 3, 4, 2 latn default 3, 4, 0 latn DEU 3, 4, 0 latn ROM 3, 4, 0 latn TRK 3, 4, 0 latn VIT 3, 4, 5, 0 script table endFeature List特性表parseFeatureList()源码位置每行三个字段name、featureTag、lookups逗号分隔。name可以是整数索引此时会断言int(name) 当前记录序号也可以是字符串名称登记进featureMap。特性可以按名称引用 lookup见 featurename-forward.txtfeature table begin f0 akhn l1 1 akh2 l1 feature table end lookup l1 single a b lookup endLookup 与 Lookup FlagsparseLookup()源码位置以lookup 名称 类型开头随后解析可选的 lookup flags 行再进入子表解析直到lookup end。lookup 类型到 OpenType lookup type 的映射如下GSUB类型 1–6、8single、multiple、alternate、ligature、context、chained、reversechainedGPOS类型 1–8single、pair、kernset、cursive、mark to base、mark to ligature、mark to mark、context、chained。每个 lookup 可含多个子表用% subtable/subtable end分隔参见parseLookup中的lines.until((% subtable, subtable end))逻辑。Lookup flagsparseLookupFlags()源码位置支持以下关键字行取值yes/no或整数关键字对应位/含义RightToLeft0x0001IgnoreBaseGlyphs0x0002IgnoreLigatures0x0004IgnoreMarks0x0008MarkAttachmentType n类型号左移 8 位MarkFilterType n置 0x0010并记录MarkFilteringSet引用解析机制名称、索引与前向引用FontDame 文本中 lookup 与 feature 既可以按数字索引引用也可以按名称引用。mtiLib通过两套映射函数处理源码位置mapLookup(sym, mapping)优先用mapping[sym]查名称映射查不到抛出LookupNotFoundError无映射时直接解析为整数索引mapFeature(sym, mapping)若符号能转成整数则直接用索引否则查名称映射失败抛FeatureNotFoundError。当源文件先引用后定义即前向引用时setReference()会借助DeferredMapping源码位置把设置操作登记为延迟回调等解析完所有 lookup/feature 后由applyDeferredMappings()统一回填——这正是featurename-backward、lookupnames-backward等测试用例所覆盖的场景参见 Tests/mtiLib/data 中的*-backward.txt。若延迟映射最终仍无法解析则重新抛出原始的ReferenceNotFoundError。异常层级源码位置MtiLibError └── ReferenceNotFoundError ├── FeatureNotFoundError └── LookupNotFoundErrorglyph 名称语法makeGlyph()源码位置支持三种 glyph 写法写法含义示例普通名称直接使用含空格或为空则断言失败onehalfU hex/u hex按 Unicode 码点生成 glyph 名u 0041→uni0041# n按顺序编号生成glyph%05d# 12→glyph00012makeGlyphs(l)对列表整体应用该转换。cmap 测试数据中还能看到\#1、\#2这类转义形式见 cmap.txt。GSUB lookup 详解与示例各 GSUB 解析器把行数据收集成映射后最终交由fontTools.otlLib.builder生成子表对象对应 源码single单替换每行两个 glyph原 glyph → 替换 glyph如onehalf onehalf.altmultiple多替换每行原 glyph → 多个 glyph空格分隔的字段如 gsubmultiple.txt 中的kassevoweltelugu kaivoweltelugu ssasubscripttelugualternate交替每行原 glyph → 候选列表ligature连字每行连字 glyph → 组成 glyph 序列至少两个字段context / chained上下文/链式上下文替换行以glyph、class或coverage开头选择 Format 1/2/3后接lookup 序号,lookup名形式的LookupRecord序号从 1 开始解析时SequenceIndex idx - 1见parseLookupRecords()源码位置reversechained反向链式替换支持backtrackcoverage/lookaheadcoverage块与多个% subtable分隔的子表完整示例见 gsubreversechanined.txt。链式上下文 class 格式示例 mixed-toplevels.txtlookup 0 chained backtrackclass definition begin pakannada 1 ... class definition end class definition begin uvowelsignkannada 1 ... class definition end class-chain 1 1 1,1 lookup end其中class-chain一行各字段依次为 backtrack 类序列、input 类序列、lookahead 类序列与序号,lookup名记录。GPOS lookup 详解与示例single单定位每行三个字段value格式 glyph 数值。value 格式由首字段转换而来title()去掉空格例如y placement→YPlacement该名字必须存在于valueRecordFormatDict源码位置。示例 gpossingle.txty placement asuperior -560pair双定位首字段以left或right开头表示 Value1/Value2 的值记录格式随后格式 glyph1 glyph2 数值若行类型以class结尾则走 Format 2需先提供firstclass/secondclass definition块再写格式 类1 类2 数值。见 gpospairglyph.txtkernsetpair 的特例别名解析器在遇到firstclass definition begin/secondclass definition begin前先收集例外exception行再解析 class 值见 gposkernset.txtleft x advance Acircumflex V -10 % Below are the class definitions. Above are the exceptions. ... firstclass definition begin A 1 ... class definition end ... left x advance 1 1 -50cursive连笔定位每行entry|exit glyph x,y [锚点编号]见parseCursive()与makeAnchor()Format 1 无锚点、Format 2 带AnchorPointmark to base / mark to ligature / mark to mark每行mark|base|ligature glyph [组件索引...] 类号 x,y [锚点编号]由MarkToBaseHelper/MarkToLigatureHelper/MarkToMarkHelper三个辅助类统一驱动parseMarkToSomething()源码位置。真实示例 gposmarktobase.txtmark bindigurmukhi 0 -184, 1183 16 base ngagurmukhi 0 816, 1183 41context / chained与 GSUB 的 context 语法一致只是目标表不同。GDEF 与 cmap 解析parseGDEF()源码位置支持的块及其生成的属性块关键字属性class definition beginGlyphClassDefattachment list beginAttachList每行glyph 点序号...carets beginLigCaretList每行glyph 数量 值...mark attachment class definition beginMarkAttachClassDefmarkfilter set definition beginMarkGlyphSetsDef每行glyph 集合号当存在MarkGlyphSetsDef时GDEF版本自动置为 0x00010002否则 0x00010000。示例见 gdefligcaret.txt 与 gdefmarkfilter.txt。parseCmap()源码位置解析cmap subtable 序号块每块依次声明platformID、encodingID、format、language随后是0x十六进制码点 glyph名映射行直到end subtable。完整示例见 cmap.txt。测试套件如何验证正确性Tests/mtiLib/mti_test.py 提供了非常完整的验证闭环。每个用例check_mti_file()都执行用mtiLib.build()解析data/*.txt得到表对象table.compile(font)编译为二进制再decompile()反编译——确认二进制往返一致把 build 出的对象与反编译对象的 XML 输出对比二者必须一致与data/*.ttx[.GSUB/.GPOS/.GDEF]期望文件逐行 diff用xmlReader从期望 TTX 读回表对象再次输出 XML 对比——确认文本 → 对象 → XML闭环。测试覆盖范围MtiTest.TESTScmap、GSUB含 forward/backward 名称引用、mixed-toplevels、single/multiple/alternate/ligature/reverse-chained、GPOScursive/kernset/mark-to-base/pair-class/pair-glyph/single/mark-to-ligature、GDEFattach/classes/ligcaret/markattach/markfilter。测试数据目录位于 Tests/mtiLib/data/mti其 README 注明这些.txt导入自 Monotype 官方 OpenType_Table_Source 仓库的downloads目录。使用建议与限制必须提供字体对象build()的font参数虽然可以是 dummyMockFont但真实字体用于确定 glyph 顺序、排序 coverage 表与 reverse glyph map命令行下用--font传入 TTF 可获得与目标字体一致的输出。表标签嗅探文件头部若写有FontDame TAG或Font Chef Table TAG声明行可省略--table否则必须显式给出。调试模块通过logging.getLogger(fontTools.mtiLib)输出解析日志在 main() 中取消注释log.setLevel(logging.DEBUG)可查看每个 script/feature/lookup 的解析过程。若设置了fontTools.feaLib.lookupDebugInfo.LOOKUP_DEBUG_ENV_VAR环境变量还会为每个 lookup 写入Debg调试表源码位置。断言严格解析器大量使用assert检查重复定义、字段数量、前后一致性遇到不符合规范的源文件会直接报错便于尽早发现问题。mtiLib 是 FontDame / Font Chef 文本布局源文件接入 FontTools 生态的桥梁文本经 build() 转成标准表对象后即可复用 FontTools 的编译、子集化、变异等全部能力而 main() 提供的命令行则让文本 → TTX XML的转换一键完成是迁移遗留字体工作流时的高效工具。赞分享开发工具【免费下载链接】fonttoolsA library to manipulate font files from Python.项目地址https://gitcode.com/gh_mirrors/fo/fonttools点击查看免费下载相关推荐fontTools 的 CFF 表模块详解table_C_F_F_ 如何读取与写入 OpenType 的 CFF 表fontTools 的 CFF 表模块详解table_C_F_F_ 如何读取与写入 OpenType 的 CFF 表 本文围绕 fontTools.ttLib开发工具FontTools终极指南10个OpenType布局表处理技巧FontTools终极指南10个OpenType布局表处理技巧 FontTools是一个强大的Python库专为处理字体文件而设计。它提供了完整的工具集来操开发工具fontTools name 表详解OpenType 名称记录的读写、编码与多语言支持fontTools name 表详解OpenType 名称记录的读写、编码与多语言支持 name 表是 OpenType 字体中存放面向用户的字体信息字开发工具上一篇如何快速解决CK2中文显示问题十字军之王2双字节补丁完整指南下一篇OpenMed 临床笔记 SDOH 提取与 ICD-10-CM Z 码映射实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Grafana Mimir Overview resources 仪表盘:组件级资源利用率监控实战指南

Grafana Mimir Overview resources 仪表盘:组件级资源利用率监控实战指南

时序数据库后端数据存储可观测性云原生 【免费下载链接】mimir Grafana Mimir provides horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus. 项目地址: https://gitcode.com/gh_mirrors/mimir/mimir 点击查看 免费下载 Gr…

📅 2026/10/13 6:37:25
Grin 合约思想解析:无脚本链上的原子互换、闪电网络与密码学合约构造

Grin 合约思想解析:无脚本链上的原子互换、闪电网络与密码学合约构造

区块链Web3 【免费下载链接】grin Minimal implementation of the Mimblewimble protocol. 项目地址: https://gitcode.com/gh_mirrors/gr/grin 点击查看 免费下载 导读 Grin 区块链不支持脚本语言,但这并不意味着它无法承载复杂的链上合约。本文以仓库…

📅 2026/10/13 6:37:25
jackson-databind 升到 2.21.4 就安全了吗?不够,2.21.5 也不够了:现在要 2.21.7 / 2.18.11(2026-10-12 更正)

jackson-databind 升到 2.21.4 就安全了吗?不够,2.21.5 也不够了:现在要 2.21.7 / 2.18.11(2026-10-12 更正)

2026-10-12 更正 本文写于 2026-08-07,当时官方一共 11 条公告,结论是升到 2.18.9 / 2.21.5 / 3.1.5。**这组版本号已经过时。**之后官方又发了几批公告,截至 2026-10-12,jackson-databind 与 jackson-core 合计 26 条,一次修完要升到 2.18.11 / 2.21.7 / 2.22.3 / 3.1.7 / 3.2…

📅 2026/10/13 6:37:25
MORE NEWS

更多资讯

📰

Godot SocketServer 基类完全指南:构建 TCP 与 Unix Domain Socket 服务端

文档教程游戏开发 【免费下载链接】godot-docs Godot Engine official documentation 项目地址: https://gitcode.com/GitHub_Trending/go/godot-docs 点击查看 免费下载 SocketServer 是 Godot 引擎中所有基于 Socket 的服务端的抽象基类,它定义了服务…

📰

3D打印文件格式全解析与Bambu Studio实战指南

1. 从零开始认识3D打印文件格式第一次接触3D打印时,我被各种文件格式搞得晕头转向。STL、3MF、OBJ、G-code...这些看似简单的后缀名背后,其实藏着影响打印质量的关键秘密。经过两年多的实践,我发现文件格式的选择会直接影响模型细节呈现、打印…

📰

Spring Boot防疫物资管理系统:管理员功能与权限实战解析

最近在给某高校后勤处做一套基于Spring Boot的防疫物资调用归还管理系统,业务本身不算复杂——口罩、消毒液、防护服这些物资要有台账,各院系要能在线提交调用申请,用完剩下部分还能归还入库。但项目推进到第二周,需求方突然追加了…

📰

模具水路清洗的温度与流速优化技术解析

1. 模具水路清洗的核心痛点与优化方向模具水路系统在长期使用过程中,冷却水中的矿物质、微生物和杂质会逐渐沉积在管道内壁,形成水垢和生物膜。这些沉积物不仅会缩小水路截面积,还会显著降低热传导效率。根据实测数据,0.5mm厚的水…

📰

Spring Boot CRM系统实战:从数据模型到智能提醒的设计与落地

1. 这个CRM项目是从一个很现实的问题开始的之前在某家做企业服务的公司带后端团队的时候,接到一个特别典型的诉求:销售团队手里有几千个客户线索,但管理方式全靠Excel和微信聊天记录。销售离职的时候,客户资料跟着聊天记录一起消失…

📰

Remeda 迁移指南:从 Lodash `range` 到 Remeda `range` 的完整对照与差异解析

开发工具 【免费下载链接】remeda A utility library for JavaScript and TypeScript. 项目地址: https://gitcode.com/gh_mirrors/re/remeda 点击查看 免费下载 range 是 Lodash 与 Remeda 中都提供的数值序列生成工具,用于以 start 为起点、按固定 st…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬