我有兴趣了解字体回退在字体整形/渲染堆栈中的位置。换句话说,在什么时候缺少检测到的字形以及它们如何被替换?
我在this文档中看到,FontConfig工具可以透明地基于字形覆盖进行字体回退。"
所以问题是:
编辑:我找到了this文件,其中解释了"什么" FontConfig,但不是"如何。"问题1是关于"如何。"
总结一下 - 这篇文章只与一件事有关 - 当字体中缺少字形时,字体回退是如何工作的。
答案 0 :(得分:9)
浏览器中的字体后备(与操作系统相反)基于两件事:
CSS规范在这方面相当简单,只是使用系统名称给出字体列表,但是几种可能的“catch all”字体在计算机之间不能保证是相同的(没有)例如,假设serif
映射到Times
或Times New Roman
的原因。
文本引擎使用的回退算法完全取决于引擎,但通常在字形查找步骤中启动:文本引擎看到一串代码点,并尝试使用字体来整形该字符串。对于序列中的每个点,它检查字体是否具有匹配的字形(通过查询CMAP表和子表),或者一个规则告诉引擎可能只有在跟随更多代码点时才使用字形,通过GSUB机制(例如,单个字母e
,t
和c
没有字形的字体,但带有&
的字形和说明序列的GSUB规则e
+ t
+ c
应该使用单个字形&
替换文字内容,并且当它完成累积此类“点数单位”时,它会形成将文本交给任何要求它塑造文本的文本。
如果在字形查找过程中,事实证明字体不包含任何让引擎形成特定代码点的内容(即通过CMAP数据运行以及GSUB规则仍然显示“没有字形”)然后文本引擎可以做两件事:
.notdef
轮廓,并且通常为您提供带有可爱空盒子的文本(由字体伙伴亲切地称为“豆腐”)或问号。当使用回退时,引擎可以向下移动替代字体列表,直到:(a)找到字形,或(b)列表耗尽,此时引擎 放弃,并将使用.notdef
字形。引擎是从原始字体还是从列表中的最后一个字体抓取.notdef
字形,完全取决于引擎(尽管通常它会使用第一种字体,但易读性)
在任何地方都没有“标准”算法; font fallback基本上是文本引擎作者提供的一种便利机制,就像浏览器带有书签管理器一样(方便,而不是任何规范的一部分)。就OpenType而言,没有要求引擎在找不到字形时是否应该只提供.notdef
,或者它是否应该提供它可以形成的部分,然后在其他地方找到缺少的字形,并以这种方式呈现文本。 CSS意味着你的文本引擎应至少具有某种形式的字体回退,但它没有指定它应该如何工作,或者何时应该启动。
答案 1 :(得分:1)
在Windows上:
Firefox对于CJK字形和非CJK字形具有不同的算法:
非CJK算法非常简单:尝试使用给定html语言配置的所有字体。其中包括配置font.name.{generic}.{language}
和配置font.name-list.{generic}.{language}
的列表。
由于字形的剪切数,编码和语言变化,CJK本质上很复杂。 Firefox使用动态搜索算法来解析字形。
ja
)字体。ko
)字体。zh-CN
)字体。zh-HK
)字体。zh-TW
)字体。该算法当前在GetLangPrefs()中实现。在CJK和非CJK情况下,要搜索的字体数量都有限制(32)。脚本搜索顺序是硬编码的,因此目前无法由用户配置。
Firefox的后备算法的优势在于,由于其动态特性,可以搜索更多字体,从而最大程度地减少了用户遇到缺少字形的机会。此外,通过了解搜索顺序,用户可以操纵配置以为缺少的字形选择所需的字体。
缺点是不一致:由于搜索列表是硬编码的,因此所有网页的优先级都来自特定语言的字体。例如,日语优化字体可能会在缺少标签的韩国网页中使用。另外,由于尝试了更多的字体,因此性能可能会降低。
与Firefox不同,Chromium选择了一种更加静态的搜索字体方法。 Chromium不必为CJK大小写划分大小和字体列表,而是为每个脚本硬编码几种“核心”字体。 Chromium假定这些字体应始终可用,因此仅搜索这些字体。脚本到字体的映射可以在InitializeScriptFontMap()中找到。此映射目前无法由用户配置。
该算法的优点是简单,一致和高性能,但以灵活性和可配置性为代价。
将来实现可能会更改。在https://gist.github.com/CrendKing/c162f5a16507d2163d58ee0cf542e695中有更多详细信息。