拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

FontForge 高级排版表支持详解:GPOS、GSUB、GDEF、BASE 与 Apple AAT 的互转全指南

FontForge 高级排版表支持详解:GPOS、GSUB、GDEF、BASE 与 Apple AAT 的互转全指南 桌面应用图形学【免费下载链接】fontforgeFree (libre) font editor for Windows, Mac OS X and GNULinux项目地址https://gitcode.com/gh_mirrors/fo/fontforge点击查看免费下载FontForge 是跨平台的开源字体编辑器在字体排版引擎方面它需要同时面对 OpenType源自 TrueType Open与 Apple Advanced TypographyAAT或称 GX两套截然不同的体系。本文围绕 doc/sphinx/techref/gposgsub.rst 展开系统梳理 FontForge 对 GPOS/GSUB/GDEF/BASE 四张 OpenType 表的读写能力、对 Apple bsln/kern/lcar/morx/mort/opbd/prop 等表的支持现状、两套格式间的互转规则与限制并辅以源码级实现证据。读完你将掌握哪些高级排版能力 FontForge 原生支持、哪些子表只能读取不能生成、OpenType 与 AAT 之间哪些特性可以安全互转、以及为什么某些上下文类替换永远无法在两种格式间无损转换。OpenType 与 AAT两套排版表体系的总体格局文档开篇就点明了核心事实OpenType最初叫 TrueType Open与 Apple 的 GX / AATApple Advanced Typography是两套差异巨大的排版表体系FontForge 对两者的支持都不完整。这决定了本文所有讨论的基调——FontForge 不是全能排版表工具而是一套有明确边界、边界处又有精细设计的选择性实现。OpenType 一侧的核心表是GPOS字形定位、GSUB字形替换、GDEF字形分类与连字插入符、BASE基线放置与行高Apple 一侧对应的是 kern字距、morx/mort字形变形、lcar连字插入符、bsln基线、opbd光学边界、prop字形属性等表。两种体系的设计哲学完全不同OpenType 用脚本/语言 → 特性feature→ lookup的三级结构组织排版行为而 AAT 依赖特性类型/设置编号 状态机来描述字形流的变化。FontForge 对两类表的读写能力各有取舍且两套表之间存在大量可转换与不可转换的边界这正是本文要逐一展开的内容。基本概念脚本、特性与 Lookup 的三层结构理解 GPOS/GSUB 的前提是掌握 OpenType 的基础数据模型。文档给出了清晰的三层关系脚本Script如 latn拉丁、arab阿拉伯、hani汉字等四字符标签标识排版行为适用的文字系统。FontForge 在 fontforge/tottfgpos.c 中内置了一张庞大的脚本 → Unicode 码位范围映射表scripts[][117]覆盖 Adlam、阿拉伯、天城体、汉字等上百种脚本用于在生成 OpenType 表时自动判定脚本覆盖范围。特性Feature如 kern提供字形对间的字距调整、init把一组字形转换为词首形态等同样以四字符标签标识是排版行为的最小命名单元。Lookup特性所关联的数据容器真正存放替换或定位规则。一个特性可以关联多个 lookup一个 lookup 也可以被多个特性引用。文档特别提示了两条底层约束在 fontforge/tottfgpos.c 的注释中也有明确记载ATM旧版 Word 中负责 OTF 字距的引擎无法处理带多个 lookup 的特性每个脚本/语言下同一特性标签只能出现一次因此多个同标签 lookup 必须合并进一个含多个 lookup 的特性。这两条Undocumented fact直接影响了 FontForge 生成 GPOS/GSUB 时对特性与 lookup 的组织策略也是理解后续特性顺序保留承诺的前提。GPOS 表八种子表的读写支持全景GPOS 负责字形定位涵盖字距、重音定位、连写连接等能力。文档逐一列出了 FontForge 支持读取/写入的 GPOS 子表子表类型读取支持写入支持创建途径Single Adjustment单字形调整支持支持元素 → 字符信息Element-Char Info→ Position 命令Pair Adjustment对字形调整支持支持Metrics 视图创建 kernMetrics-VKern From HKern 创建 vkrnCursive Attachment连写连接支持支持仅 curs 特性点 → 添加锚点Points-Add AnchorMark to Base标记到基底支持支持Points-Add AnchorMark to Ligature标记到连字支持支持Points-Add AnchorMark to Mark标记到标记支持支持Points-Add AnchorContextual Positioning上下文定位支持支持元素 → 字体信息 → ContextualChaining Contextual Positioning链式上下文定位支持支持元素 → 字体信息 → ContextualExtension Positioning扩展定位支持需要时自动使用无需手工干预保留子表reserved不支持不支持—各子表的语义要点Single Adjustment允许设计者修改单个字形的度量。典型例子是 tnum表格数字特性——把一个比例数字的进给宽度advance width调整为设定值再通过调整左边距left side bearing把数字在新的宽度内居中。Pair Adjustment最常见的用途是字距调整kerning——根据后续字形改变前一字形的进给宽度。文档特意指出该子表比字距更通用理论上也能支撑标记重音/元音在基底字形上定位但那用 Mark to Base 子表会更高效。kern 特性可在 Metrics 视图创建vkrn垂直字距可通过 Metrics-VKern From HKern 命令从水平字距生成。Cursive Attachment强制相邻字形在指定点连接用于生成乌尔都语等斜体手写风格所需的字形衔接。Mark to Base / Mark to Ligature / Mark to Mark三个同族子表解决标记类字形重音、元音符号如何挂在其他字形上的问题。区别在于基底分别是普通字形、连字同一重音可能有多个放置点、以及标记本身如一个字形叠加两个重音时第二个重音相对第一个定位而非相对基底。三者都通过 Points-Add Anchor 命令创建。Contextual / Chaining Contextual Positioning把定位行为限制在特定字符串或字符串类上下文中。例如当看到数字后跟 th 时把 th 提升为 superscript 位置。通过元素 → 字体信息 → Contextual 命令创建。Extension Positioning用于突破 64k 的表大小上限对设计者完全透明。FontForge 在需要时自动使用见 fontforge/tottfgpos.c 中otf_dumpgpos()的生成逻辑。值得注意的实现细节文档还强调了两点FontForge 内置了对部分使用这些表的特性的默认值知识FontForge 会保留 GPOS 表中特性的原始顺序生成字体时特性顺序与读取时一致。从源码看GPOS 的生成入口是 fontforge/tottfgpos.c 的otf_dumpgpos()第 3526 行其注释形象地吐槽了 OpenType 的设计Open Type愿你它烦人的小心脏安康它不把字距信息存在 kern 表中——当然不存我居然会以为它保持一致真傻。它把字距存在复杂得多的 gpos 表中。这句注释精确点出了 OpenType 与 Apple 在设计哲学上的本质差异而 FontForge 必须同时伺候两套体系。GSUB 表九种子表的读写支持全景GSUB 负责字形替换涵盖连字、阿拉伯语形态、竖排旋转、小型大写转换、印度系字形重排等能力。文档列出的子表支持情况如下子表类型读取支持写入支持创建途径Single Substitution单字形替换支持支持Element-Char Info → SubstitutionMultiple Substitution多字形替换支持支持Element-Char Info → Multiple SubstitutionAlternate Substitution可选字形替换支持支持Element-Char Info → Alternate SubstitutionLigature Substitution连字替换支持支持Element-Char Info → LigatureContextual Substitution上下文替换支持支持Element-Font Info → ContextualChaining Contextual Substitution链式上下文替换支持支持Element-Font Info → ContextualExtension Substitution扩展替换支持需要时自动使用—Reverse Chaining Contextual Single Substitution反向链式上下文单替换支持支持Element-Font Info → Contextual保留子表reserved不支持不支持—各子表的语义要点Single Substitution一个字形替换为另一个字形由特性标签提供上下文。文档给出的经典例子是词尾形态——阿拉伯语的每个字母、希伯来语的多个字母、希腊语的小写 sigma、文艺复兴拉丁语的长 s/短 s 对都有词内/词尾两种形态。fina 特性把常规形态映射为词尾形态文字处理程序在每个词尾执行一次 lookup 判断是否需要转换。Multiple Substitution一个字形替换为一串字形一般用于比较专业的排版问题。文档提到 GSUB 的该子表与 Apple 的 Glyph Insertion 有相似性但有两点关键区别详见互转章节。Alternate Substitution每个字形提供一组替换候选。典型例子是斜体字体中每个大写字母有几个花饰swash变体由文字处理程序让用户选择。Ligature Substitution把一串字形替换为另一个字形如 fi → fi 连字。文档中该处引用了两张插图fi.png 与 fi.png位于 doc/sphinx/images 目录下直观展示连字替换前后的字形序列。Contextual / Chaining Contextual Substitution允许一串字形或一串字形类替换为另一串链式版本逻辑更清晰但能力相同。Reverse Chaining Contextual Single Substitution以反向顺序对字形流执行替换是链式上下文子表的变体。Extension Substitution同 GPOS 的扩展子表突破 64k 限制对设计者透明。两个重要的全局承诺文档在 GSUB 部分末尾给出两个关键承诺FontForge 内置对部分特性的默认值知识可通过各个 lookup 子表对话框中的[Populate]按钮利用GSUB 特性的顺序会被保留且用户可通过 元素 → 字体信息doc/sphinx/ui/dialogs/lookups.rst命令调整顺序。同时文档明确了一个责任边界FontForge 只负责把这些表写进字体文件实际的字形重排工作必须由文字排版/文字处理程序在运行时查表并执行。字体编辑器生成的是规则数据不是排版引擎。源码侧GSUB 的生成入口是otf_dumpgsub()fontforge/tottfgpos.c 第 3543 行其注释列举了典型应用场景替换如连字、CJK 竖排旋转替换、阿拉伯形态、小型大写……并在生成前后调用SFLigaturePrepare/SFLigatureCleanup保证连字数据的一致性。GDEF 表字形分类与连字插入符GDEF 表承担两类任务字形类别定义子表glyph class definition对字形进行分类如基底字形、标记、连字、复合字形供 GPOS/GSUB 的上下文匹配使用连字插入符子表ligature caret记录连字字形的插入符caret位置供文本编辑时正确放置光标。文档说明 FontForge 对 GDEF 的支持策略是读取从 GDEF 表读取连字插入符生成仅在需要时生成 GDEF 表——如果存在锚点数据则生成字形类别定义子表如果存在连字插入符数据则生成连字插入符子表。源码佐证otf_dumpgdef()fontforge/tottfgpos.c 第 3705 行与DumpLigCarets()第 3577 行共同实现了 GDEF 的生成逻辑其中LigCaretCnt()遍历每个字形的possub链表统计插入符数量并在lig_caret_cnt_fixed标志下决定输出策略。从生成侧看四张表的输出条件在 fontforge/tottf.c 中四张表的生成条件被一句话概括GPOS当字体包含 kern、锚点anchor数据时生成GSUB当字体包含连字及其他替换数据时生成GDEF当字体包含锚点数据时生成。这段注释第 109-111 行与文档的按需生成策略完全一致可以作为判断什么数据会触发哪些表输出的实用参考。值得注意的是GPOS 的 size 特性会以类似 Mac 的方式使用 name 表因此 GPOS 表的处理必须安排在 name 表相关处理之后fontforge/tottf.c 第 5374 行附近的注释有明确说明。Apple Advanced TypographyAAT 表的支持现状FontForge 会读写哪些 Apple 表文档以大致对应关系为线索梳理了 FontForge 对 AAT 表的支持前提生成时需在字体设置中开启 Apple modeApple 表大致对应的 OpenType 表读取支持写入支持bsln基线BASE读取基线数据Apple 的表意文字居中基线除外因为 OpenType 无对应物若用户指定了 Apple 支持的基线数据则生成lcar连字插入符GDEF读取连字插入符若用户指定了连字插入符则生成prop字形属性GDEF读取以识别希伯来/阿拉伯字形及带 r2la 替换的字形若字体含从右到左字形则生成kern字距GPOS读取水平/垂直字距对与字距类上下文字距信息可读入状态机若字体含字距数据字距对、按类字距、状态机字距则生成opbd光学边界GPOS读取光学边界若用户把左右边界指定为简单位置lfbd/rtbd则生成mort 与 morx字形变形表fontforge 对 mort旧版和 morx扩展字形变形表均有支持它们大致对应 GSUB。一个重要的自动行为是任何能直接对应 OpenType 特性的特性类型/设置组合在读取时都会被转换为 OpenType 标签生成 Apple 字体时再转换回特性/设置。用户可以通过 文件 → 偏好设置File-Preferences扩展 FontForge 从特性类型/设置到 OpenType 标签的映射。morx/mort 的五个子表及其支持情况子表读取支持写入支持Indic 式重排Indic style rearrangement读入为状态机可用 Font Info 的 state machine 编辑任何 Indic 状态机都会输出到生成的字体上下文字形替换contextual glyph substitution读入为状态机若字体含状态机则输出否则在满足条件时进行 OpenType → Apple 的转换详见下文连字替换ligature substitution读取无条件信息并存储为 OpenType 连字若存在带 Apple 特性/设置或可转换的 OpenType 标签的连字则输出非上下文字形替换non-contextual glyph substitution读入并存储为 OpenType 简单替换若存在可转换的替换则输出上下文字形插入contextual glyph insertion读入为状态机任何字形插入状态机都会输出其中上下文字形替换的写入逻辑尤其值得展开文档给出了两条转换规则若字体含 init、medi、fina 或 isol 简单替换FontForge 会用此子表生成一个 cursive connection 特性这正是阿拉伯语词首/词中/词尾/独立形态在 Apple 体系中的落点在少数情况下见下文专门章节FontForge 能把 OpenType 的 Contextual/Chaining 替换表转换为 Apple 的上下文字形替换表。源码侧morx/mort 的生成集中在 fontforge/tottfaat.c如aat_dumpmorx_substitutions、aat_dumpmorx_ligatures、aat_dumpmorx_asm等函数读取集中在 fontforge/parsettfatt.c如_readttfmort、readttf_mortx_lig、readttf_mortx_asm、read_statetable等函数——后者把 morx 的状态机结构完整解析进 FontForge 的内部状态机模型并支持在 Font Info 对话框中直接编辑。OpenType 与 AAT 的互转哪些能转、哪些不能转表级对应关系GDEF ↔ lcar两边存储的连字插入符信息本质上一致FontForge 读取与互转都没有障碍。BASE ↔ bsln两边基线数据略有差异——bsln 不提供 extent 信息bsln 为每个字形提供基线而 BASE 为每个脚本提供基线希望同一脚本的字形共享基线但并不保证且两者的基线标签集合不完全一致FontForge 只支持 OpenType 一侧的标签Apple 的表意文字居中基线ideographic centered baseline在转换中会丢失。GPOS ↔ kern大多数字距信息可在两格式间转换。两边都支持垂直字距、从右到左字距、按字形对与按类的字距。但上下文链式特性的字距OpenType与状态机控制的字距Apple之间FontForge 支持两者但不做互转。GPOS ↔ opbdGPOS 的 lfbd 与 rtbd 特性提供了生成 Apple opbd 表所需的信息。读取带 opbd 表的字体时会生成相应的 lfbd/rtbd 特性在 Apple 模式下生成含这些特性的字体时会创建 opbd 表。这是双向可转换的。GPOS → 其他文档明确表示没有已知方法把其他 GPOS 特性转换为 AAT。GSUB ↔ morx/mortmort 与 morx 能力相同前者是旧格式Apple 建议使用 morx。FontForge 能读取两者但只生成 morx。互转能力取决于具体特性类型与子表格式详见下文逐项分析。子表级互转分析文档用GSUB 有 7 种子表格式morx 有 5 种开篇然后逐一对照GSUB 子表morx 子表转换可行性Single单替换Non-Contextual Glyph非上下文字形替换能力几乎完全一致都能一对一替换字形差异morx 允许删除字形GSUB 不允许Multiple多替换—与 Apple 的 Glyph Insertion 有相似性但有两点关键差异见下—Glyph Insertion字形插入在当前字形前/后插入一串字形当前字形始终保留是上下文敏感的与 GSUB Multiple 有相似但不等价Alternate可选替换—morx 中没有对应物如多花饰变体在 Apple 体系无处安放Ligature连字Ligature连字GSUB 版本无条件嵌入 Context/Chaining Context 子表可使其条件化morx 版本可以上下文化但实际字体中通常无条件。FontForge 只支持无条件连字能读取 morx 中所有无条件连字会丢失所有上下文连字—Contextual Glyph上下文字形替换看似能转成 OpenType Context 子表但实际极少可行详见下节Chaining / Chaining Context—看似可配合嵌套替换转成 morx 的上下文替换/连字/插入但实际极少可行Reverse Chaining Context反向链式上下文—morx 中没有对应物—Indic RearrangementIndic 重排GSUB乃至 GPOS中都没有对应物关于 Multiple 与 Glyph Insertion 的两点关键差异文档的表述很精确morx 的字形插入子表始终把当前字形保留在字形流中而 GSUB 的 Multiple 子表不必如此morx 的字形插入天生是上下文敏感的而 GSUB 的 Multiple 子表永远不是——但若把 Multiple 子表包进 Context 或 Chaining Context 子表结果可以变成上下文敏感的。此外文档还给出了一个重要的生成行为当一个 OpenType 连字特性/设置能转换到 Apple 体系时连字表才会输出到 morx反之亦然。这套对应关系由 FontForge 内置的特性类型/设置 ↔ OpenType 标签映射驱动见文末映射表。为什么上下文替换的互转有时可行、经常不行文档用专门的两节Why do contextual glyph substitutions only sometimes get generated in AAT?与Why cant all contextual/chaining tables be converted?深入剖析了这个问题的根源OpenType 与 AAT 在上下文匹配能力上是不相交的——AAT 在某些方面更强OpenType 在另一些方面更强。FontForge 只有在能检测出OpenType 替换未使用超出 AAT 的能力时才把它转换为 AAT。当前判定条件为存在匹配该 OpenType 标签的 Apple 特性且满足以下任一条件子表为 coverage 格式且要么只含恰好一个嵌套的单字形替换要么含恰好两个单字形替换且其中一个指向最后匹配的字形另一个不指向或子表为 glyph 或 class 格式若为 class 格式则 backtrack 与 lookahead 类必须与主类相同或不被使用若一条规则在某个字形位置有替换则所有与该规则匹配到该位置的规则也必须有该位置的替换单替换规则可接受一个内部替换 一个末尾替换的规则可接受更多替换只有在存在一条与该规则在内部替换处完全匹配的规则时才被接受。文档给出了两个具体例证来阐明合法与不合法合法规则集规则 3 匹配 ab 并转换为 AB——一个内部替换加一个末尾替换合法若 ab 后跟 cd规则 2 把 cd 转为 CD若再跟 ef则转为 EFabcdef规则 1abcdef规则 2abcd规则 3ab替换ABCDEF不合法规则集两条规则在同一字形位置上的替换位置不同无法用 Apple 状态机表达因为它们共享相同字形abc规则 1abc替换 1B规则 2ab替换 2A为什么所有上下文/链式表都能转换是不可能的文档给出一个深刻而巧妙的论证。以 glyph 列表格式的上下文替换为例abcd初始序列abcd替换为BC在 OpenType 中这表示若找到序列 abcd则把 b 换成 B、c 换成 C。但这无法用 Apple 状态机表达OpenType 是先完成匹配再做替换而状态机必须在匹配的同时几乎执行替换——因此替换是否发生取决于末尾的 d 是否出现这在状态机里做不到同样的困难也存在于 class 和 coverage 格式中。第二个例子展示了二选一的不可表达性abcd初始序列abcd替换为B初始序列abce替换为C即若末尾是 d 则替换 b否则替换 c同样无法用状态机表达。第三个例子展示了回溯问题的本质abcd初始序列abcd替换为C初始序列bce替换为B给定序列 abce 时AAT 读入 a 后开始沿 abcd 分支前进直到寻找 d 时发现 e 才失败——此时已来不及切换到本可匹配的 bce 分支因为 b 未被标记为替换位置。反过来AAT 状态机也有 OpenType 无法表达的能力输入/输出边界OpenType 的上下文/链式上下文无法表达输入开头或输入末尾而 Apple 状态机可以。例如词首花饰字形——词首定义为输入开头或紧跟空白字符——在 OpenType 中无法表达AAT 可以。删除字形Apple 的字形替换可以删除字形因此一个上下文替换表就能造出双字符连字一个字形转成连字、另一个被删除OpenType 必须用连字替换子表才能实现。正则表达式能力AAT 状态机可匹配一般正则表达式OpenType 表只能匹配定长字符串。文档给出的例子是数学排版——把变量后的任意数字串转成下标x23 → x₂₃状态机可以持续替换直到不再出现数字而 OpenType 需要无限多条规则才能等价。这些例子除词首花饰外确实显得有些刻意但它们的价值在于证明一个硬结论两种格式的表达能力差异巨大任何转换器都不可能把一种格式的任意输入转换成另一种的等价输出。文档最终给出的判断是OpenType 在上下文定位上独有AAT 完全没有 contextual positioningIndic 重排则是 AAT 独有对于两者看似都支持的上下文替换语义模型先匹配后替换 vs 边匹配边替换的根本差异决定了不可能通用转换。一个需要警惕的细微缺陷文档专门给出警告把链式上下文替换转换为 Apple 上下文字形替换存在一个隐蔽 bug——AAT 没有回溯列表backtrack list的概念因此替换可能以不同的顺序发生。这是设计转换器时不可忽视的语义差异。Apple 与 OpenType 特性对应表FontForge 支持互转的 Apple 特性/设置与 OpenType 特性的完整对应关系如下这张表直接来自文档是判断能否互转的最终依据Apple Feature SettingOpenType Feature NameOpenType TagRequired LigaturesRequired LigaturesrligCommon LigaturesStandard LigaturesligaRare LigaturesDiscretionarydligFractionsFractionsfracContextual AlternativesCursive connectioncaltVertical FormsVertical Rotation 2vrt2Monospace numbersTabular numberstnumSuperscriptSuperscriptsupsSubscriptSubscriptsubsProportional TextProportional WidthspwidHalf-width TextHalf WidthhwidFull-width TextFull WidthfwidTraditional CharactersTraditionaltradSimplified CharactersSimplifiedsmplJIS 1978 CharactersJIS 1978 Charactersjp78JIS 1983 CharactersJIS 1983 Charactersjp83JIS 1990 CharactersJIS 1990 Charactersjp90两个配套要点特性顺序保留同样适用于 morxFontForge 保留 morx 表中特性的顺序用户可通过 元素 → 字体信息 → Lookups 命令调整与 GSUB 使用同一列表。不匹配即忽略GSUB 中不对应任何 Mac 特性的特性会被忽略。这份映射表同时是文档FontForge 内置默认值知识与 [Populate] 按钮的底层数据来源之一也是 fontforge/parsettfatt.c 与 fontforge/tottfaat.c 中特性转换逻辑的依据。明确不支持的内容文档在最后总结了 FontForge 尚未支持的高级排版能力是排查问题时的反向清单OpenType 侧GDEF 表不提供 attachment list 子表与 MarkAttachClassDef 子表不支持 VORG垂直原点与 JUST对齐表完整的支持表清单见 doc/sphinx/techref/TrueOpenTables.rst。Apple Advanced Typography 侧永远不会生成 mort 表可以读取 mort但只生成 morx无法解析上下文连字能找到从状态 0 出发的连字但找不到从其他状态出发的即上下文连字不支持以下 Apple 专有表acnt重音附着、bsln基线、fdsc字体描述符、fmtx字体度量、hsty水平风格、just对齐、trak字距跟踪、Zapf字形引用。文档也提醒FontForge 对这些表尚未提供支持意味着支持状态是动态演进的。实操建议围绕这些能力的工作流综合文档与源码可以提炼出几条实用的工作流结论判定字体能否完整处理先对照上文 GPOS/GSUB 子表支持矩阵与不支持清单快速判断目标字体用到的排版特性是否落在 FontForge 的能力圈内。若字体依赖 GDEF 的 MarkAttachClassDef、VORG/JUST 表或 Apple 的上下文连字FontForge 处理时会有能力缺口。字距与锚点是 GPOS 生成的主要触发源在 fontforge/tottf.c 的生成注释中GPOS 的生成条件就是字体含 kern 或锚点数据。因此编辑锚点Points-Add Anchor与字距Metrics 视图时就是在直接驱动 GPOS 表的内容。连字与替换数据驱动 GSUBGSUB 的生成条件是字体含连字或其他替换数据。在 Char Info 对话框的 Substitution/Multiple Substitution/Alternate Substitution/Ligature 命令中创建的数据最终都会落入 GSUB。Apple 目标字体必须开启 Apple mode只有生成时设置 Apple modeFontForge 才会输出 bsln、kern、lcar、morx、opbd、prop 等表且即便开启mort 也永远不会被生成只会生成 morx。转换前先查对应表OpenType ↔ AAT 的互转可行性先对照文末的Apple Feature Setting ↔ OpenType Tag映射表不在表内的特性基本没有转换路径。上下文类替换的转换还需满足本文所述的严格判定条件否则会被静默放弃或产生顺序差异。小结FontForge 对高级排版表的支持是一套精心设计、边界清晰的能力集对 OpenType 的 GPOS/GSUB/GDEF/BASE 与 Apple 的 AAT 表都有较为完整的读取能力写入能力按子表类型分档完全支持、按需生成、仅生成部分特性、完全不支持两套体系之间的互转遵循表级/子表级/特性级三层判定规则其中 GDEF↔lcar、BASE↔bsln、GPOS 字距↔kern、GPOS 的 lfbd/rtbd↔opbd 是可双向转换的而上下文类替换由于先匹配后替换与边匹配边替换的语义鸿沟绝大多数情况下无法等价互转。理解这些边界是在 FontForge 中正确规划多平台字体生产流程的前提。赞分享桌面应用图形学【免费下载链接】fontforgeFree (libre) font editor for Windows, Mac OS X and GNULinux项目地址https://gitcode.com/gh_mirrors/fo/fontforge点击查看免费下载相关推荐es-toolkit/compat 的 every 函数Lodash 兼容的全量条件判断指南es toolkit/compat 的 every 函数Lodash 兼容的全量条件判断指南 导读 every 是 es toolkit 兼容层 es to桌面应用图形学终极指南掌握HarfBuzz的AAT和Graphite排版引擎高级特性终极指南掌握HarfBuzz的AAT和Graphite排版引擎高级特性 HarfBuzz作为现代国际化基础设施的核心文本排版引擎支持多种字体格式和排版系统图形学RichEditor for Android高级功能表格插入与复杂排版支持终极指南RichEditor for Android高级功能表格插入与复杂排版支持终极指南 RichEditor for Android是一款功能强大的富文本编辑器移动开发UI组件上一篇mORMot2框架Delphi和FreePascal开发者的终极ORM解决方案下一篇幻兽帕鲁存档迁移终极指南告别角色丢失实现服务器无缝切换创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表