此教程不仅限于浏览器设置,还包括Mac平台字体与Windows平台字体之间的相互转换。教程实例选择的是Windows系统自带的Edge浏览器,由于不同浏览器的内置字体渲染方式存在差异,非Chromium内核的浏览器未经测试适用性不明,请自行斟酌按需服用。
浏览器设置
第一,打开浏览器自定义字体设置界面,具体设置参考下图:
图1 Edge浏览器自定义字体设置示例
需要明确的是,以上设置仅在强制使用自定义字体,以及网页未指定字体的情况下生效。在未强制使用自定义字体的情况下,浏览器会自动执行网页前端代码,按照指定字体的先后排序调用字体,这就是为什么浏览器自定义字体失效的缘由。
图2 B站官网前端字体调用的优先顺序示例
图2中网页端指定的中文字体优先排序依次是PingFang SC、Hiragino Sans GB、Microsoft YaHei,在系统没有安装PingFang SC、Hiragino Sans GB字体的情况下,网页端才会调用Microsoft YaHei字体。
在简体中文网站中,常用的中文字体主要包括苹方、思源黑体和微软雅黑。其中,苹方作为Apple产品的自带字体,因屏显效果出色,备受好评。
苹方字体只能从macOS或iOS系统中提取,由于Mac平台与Windows平台的字体文件规范不同,作为品牌定制字体的苹方恰巧未做多平台适配,所以提取出来的苹方字体不能被Windows系统识别,因此我们需要增加符合Windows平台字体文件规范的字表,也就是咱们下文重点要讲的cmap(字符映射表)以及name(名称表)。
“cmap” 表
- cmap子表的结构:
Unicode平台cmap表由platEncID 3或platEncID 4一个子表构成,platEncID 3仅支持Unicode BMP字符,platEncID 4支持Unicode补充平面字符。platEncID 3与format_4或format_6结合使用,platEncID 4与format_10 或format_12结合使用。应用程序在子表搜索时只能选择并使用一个子表,而忽略其他子表。子表搜索的顺序是:支持Unicode补充平面字符的子表优先于仅支持Unicode BMP字符的子表,所以Unicode平台子表只保留一个platEncID 4的子表即可正确映射。
Windows平台cmap表由platEncID 1和编码platEncID 10两个子表构成,platEncID 1仅支持Unicode BMP字符,platEncID 10支持Unicode补充平面字符(platEncID 10是一个超集,它包含platEncID 1内所有的字符)。platEncID 1与format_4结合使用,platEncID 10与format_12结合使用。具有platEncID 10子表的字体,必须同时具有一个platEncID 1的子表,platEncID 1的子表主要是Windows平台为了兼容Windows 7或更老的系统所保留。
Unicode平台 platformID=0;Mac平台 platformID=1;Windows平台 platformID=3。
- cmap子表的排序:
第一按platformID(平台ID)排序,然后按特定平台的platEncID(编码ID)排序,再按相应子表中的语言字段排序 (语言<language>字段一般设置为<language=0>)。每个platformID、特定平台的platEncID和子表语言组合在cmap表中只能出现一次。
- cmap子表字符码的提取:
Unicode平台format_4或format_12的子表与Windows平台format_4或format_12的子表字符码一样,直接复制对应的子表内容,更改表头platformID和platEncID即可。
从format_12的子表中提取format_4子表的字符码,详细的说明可参考OpenType规范,再此只推荐简单粗暴、通俗易懂的区分与提取方法。记住以下重点:format_4的子表字符码至”0xffff”结束;format_12的子表起始字符码从”0x10000″开始,再直观一点就是format_4的子表字符码0x后面最大不超过4位数;format_12的子表字符码0x后面由5位数组成。
- 提取与修正cmap表:
未安装Python及afdko的小伙伴请移步《Windows 系统字体优化》,输入以下命令提取苹方字体cmap表:
ttx -t cmap PingFangSC-Regular.otf
提取出的cmap表如下:
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="x00x01x00x00" ttLibVersion="4.43">
<cmap>
<tableVersion version="0"/>
<cmap_format_12 platformID="0" platEncID="3" format="12" reserved="0" length="151504" language="0" nGroups="12624">
<map code="0x0" name="uni0000"/><!-- ???? -->
<map code="0xffe5" name="uniFFE5"/><!-- FULLWIDTH YEN SIGN -->
<map code="0x20016" name="u20016"/><!-- CJK UNIFIED IDEOGRAPH-20016 -->
<map code="0x2a6c7" name="u2A6C7"/><!-- CJK UNIFIED IDEOGRAPH-2A6C7 -->
</cmap>
</ttFont>
该cmap表存在问题:
cmap表中只有一个Unicode平台format_12的子表,缺少Windows平台对应的子表。
cmap子表的platEncID不符合规范。根据最新版的OpenType规范,Unicode平台format_12的子表应该和platEncID 4结合使用,platEncID 3应该和format_4结合使用,根据子表内容可以看出该子表支持Unicode补充平面字符,此处设置为<platEncID=3>显然不符合规范。
解决方案:
- 修正Unicode平台子表的platEncID
- 增加Windows平台platEncID 1和platEncID 10两个子表
修正后的cmap表如下:
<cmap>
<tableVersion version="0"/>
<cmap_format_12 platformID="0" platEncID="4" format="12" reserved="0" length="151504" language="0" nGroups="12624">
<map code="0x0" name="uni0000"/><!-- ???? -->
<map code="0xffe5" name="uniFFE5"/><!-- FULLWIDTH YEN SIGN -->
<map code="0x20016" name="u20016"/><!-- CJK UNIFIED IDEOGRAPH-20016 -->
<map code="0x2a6c7" name="u2A6C7"/><!-- CJK UNIFIED IDEOGRAPH-2A6C7 -->
<cmap_format_4 platformID="3" platEncID="1" language="0">
<map code="0x0" name="uni0000"/><!-- ???? -->
<map code="0xffe5" name="uniFFE5"/><!-- FULLWIDTH YEN SIGN -->
<cmap_format_12 platformID="3" platEncID="10" format="12" reserved="0" length="151504" language="0" nGroups="12624">
<map code="0x0" name="uni0000"/><!-- ???? -->
<map code="0xffe5" name="uniFFE5"/><!-- FULLWIDTH YEN SIGN -->
<map code="0x20016" name="u20016"/><!-- CJK UNIFIED IDEOGRAPH-20016 -->
<map code="0x2a6c7" name="u2A6C7"/><!-- CJK UNIFIED IDEOGRAPH-2A6C7 -->
</cmap>
“name” 表
- name表的详细描述如下:
NameID |
Description |
描述 |
0 |
Copyright notice |
版权声明 |
1 |
Font Family |
字体家族 |
2 |
Font Subfamily |
字体子系列 |
3 |
Unique subfamily identification |
唯一字体标识符 |
4 |
Full name of the font |
字体名称 |
5 |
Version of the name table |
版本号 |
6 |
PostScript name of the font |
PostScript 名称 |
7 |
Trademark notice |
商标 |
8 |
Manufacturer name |
制造商 |
16 |
Preferred Family |
首选字体家族 |
17 |
Preferred Subfamily |
首选字体子系列 |
Mac平台同一家族字体都包含在nameID 1 (Font Family)里面,命名忽略nameID 16 (Preferred Family)、nameID 17 (Preferred Subfamily)。
Windows平台nameID 1只包含常规、粗体、斜体、粗斜体这四个子系列,其它字重需要扩展到nameID 16与nameID 17,Office等应用程序的字体列表才能正确显示家族字体。
Windows平台语言ID<langID=”0x404″>指代中文-台湾,<langID=”0x409″>指代英语-美国,<langID=”0x804″>指代中文-中国,<langID=”0xC04″>指代中文-香港。
<langID=”0x409″>的name行包含字体供应商提供的所有name信息,其他语言地区name行只增加该地区语言的值即可,与<langID=”0x409″>中name行一致的值可以忽略。
- 提取与修正name表:
输入以下命令提取苹方字体name表:
ttx -t name PingFangSC-Regular.otf
提取出的name表如下:
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="x00x01x00x00" ttLibVersion="4.43">
<name>
<namerecord nameID="0" platformID="1" platEncID="0" langID="0x0" unicode="True">
Copyright notice 版权声明
</namerecord>
<namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True">
PingFang SC
</namerecord>
<namerecord nameID="2" platformID="1" platEncID="0" langID="0x0" unicode="True">
Regular
</namerecord>
<namerecord nameID="3" platformID="1" platEncID="0" langID="0x0" unicode="True">
PingFang SC Regular; 20.0d3e1; 2024-05-17
</namerecord>
<namerecord nameID="4" platformID="1" platEncID="0" langID="0x0" unicode="True">
PingFang SC Regular
</namerecord>
<namerecord nameID="5" platformID="1" platEncID="0" langID="0x0" unicode="True">
20.0d3e1
</namerecord>
<namerecord nameID="6" platformID="1" platEncID="0" langID="0x0" unicode="True">
PingFangSC-Regular
</namerecord>
<namerecord nameID="7" platformID="1" platEncID="0" langID="0x0" unicode="True">
Trademark notice 商标
</namerecord>
<namerecord nameID="8" platformID="1" platEncID="0" langID="0x0" unicode="True">
Manufacturer name 制造商
</namerecord>
</name>
</ttFont>
存在的问题及解决方案:name表内缺少Windows平台的name行,需要在name表中增加Windows平台对应的name行。
修正后的name表如下:
<name>
<namerecord nameID="0" platformID="1" platEncID="0" langID="0x0" unicode="True">
Copyright notice 版权声明
</namerecord>
<namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True">
PingFang SC
</namerecord>
<namerecord nameID="2" platformID="1" platEncID="0" langID="0x0" unicode="True">
Regular
</namerecord>
<namerecord nameID="3" platformID="1" platEncID="0" langID="0x0" unicode="True">
PingFang SC Regular; 20.0d3e1; 2024-05-17
</namerecord>
<namerecord nameID="4" platformID="1" platEncID="0" langID="0x0" unicode="True">
PingFang SC Regular
</namerecord>
<namerecord nameID="5" platformID="1" platEncID="0" langID="0x0" unicode="True">
20.0d3e1
</namerecord>
<namerecord nameID="6" platformID="1" platEncID="0" langID="0x0" unicode="True">
PingFangSC-Regular
</namerecord>
<namerecord nameID="7" platformID="1" platEncID="0" langID="0x0" unicode="True">
Trademark notice 商标
</namerecord>
<namerecord nameID="8" platformID="1" platEncID="0" langID="0x0" unicode="True">
Manufacturer name 制造商
</namerecord>
<namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
Copyright notice 版权声明
</namerecord>
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
PingFang SC
</namerecord>
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
PingFang SC Regular; 20.0d3e1; 2024-05-17
</namerecord>
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
PingFang SC Regular
</namerecord>
<namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
20.0d3e1
</namerecord>
<namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
PingFangSC-Regular
</namerecord>
<namerecord nameID="7" platformID="3" platEncID="1" langID="0x409">
Trademark notice 商标
</namerecord>
<namerecord nameID="8" platformID="3" platEncID="1" langID="0x409">
Manufacturer name 制造商
</namerecord>
<namerecord nameID="16" platformID="3" platEncID="1" langID="0x409">
PingFang SC
</namerecord>
<namerecord nameID="17" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x804">
苹方-简
</namerecord>
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x804">
常规体
</namerecord>
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x804">
苹方-简 常规体
</namerecord>
<namerecord nameID="16" platformID="3" platEncID="1" langID="0x804">
苹方-简
</namerecord>
<namerecord nameID="17" platformID="3" platEncID="1" langID="0x804">
常规体
</namerecord>
</name>
有关字体命名的文章网上有许多,有兴趣深入了解小伙伴,可自行搜索关键词,在这我就不再详细说明。接下来额外讲两个在字体识别与调用过程中起到关键作用的字表,分别是head和OS/2。
“head”和”OS/2”
输入以下命令提取苹方字体head和OS/2表:
ttx -t head -t OS/2 PingFangSC-Regular.otf
head和OS/2表内重大参数详细描述如下:
<head>
<!-- Most of this table will be recalculated by the compiler -->
<macStyle value="00000000 00000000"/> ——第1位是"粗体",第2位是"斜体",其他类型都设置为0
</head>
<OS_2>
<!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
will be recalculated by the compiler -->
<usWeightClass value="300"/> ——这行描述的是字重参数
<fsSelection value="00000000 00000000"/> ——第7位是"常规",第6位是"粗体",第1位是"斜体",其他类型都设置为0
</OS_2>
<00000000 00000000>按照从右到左顺序,根据实际情况补充或修改数值,除常规、粗体、斜体、粗斜体外,家族字体内的其它字重均设置为”0″。详细用法如下:
<fsSelection value="00000000 01000000"/> ——常规
<macStyle value="00000000 00000001"/> ——粗体
<fsSelection value="00000000 00100000"/> ——粗体
<macStyle value="00000000 00000010"/> ——斜体
<fsSelection value="00000000 00000001"/> ——斜体
<macStyle value="00000000 00000011"/> ——粗斜体
<fsSelection value="00000000 00100001"/> ——粗斜体
在使用afdko中FontTools组件合并苹方字体的时候,如出现”WARNING: Some CFF FDArray/FontDict keys were ignored upon compile: PaintType”的错误提示,是因CFF表内”CFFFont name”、”FullName value”、”FontName value”行的字体名称错误导致,把它更正成实际的字体名称即可,如把”PingFangMO-Regular”改成”PingFangSC-Regular”。
<CFF>
<CFFFont name="PingFangSC-Regular">
<FullName value="PingFangSC-Regular"/>
</Private>
<FontName value="PingFangSC-Regular-Proportional"/>
</Private>
后记:在实际的操作中,一般都是一次性导出相关字表,命令如下:
ttx -t head -t OS/2 -t cmap -t name -t CFF PingFangSC-Regular.otf
修改完毕后,输入以下命令倒入即可:
ttx -b -m PingFangSC-Regular.otf PingFangSC-Regular.ttx
Windows系统字体渲染设置转:《Windows 系统字体渲染组件 ClearType 的应用》。
暂无评论内容