【硬核教程】网页浏览器字体设置及优化

此教程不仅限于浏览器设置,还包括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>显然不符合规范。

解决方案:

  1. 修正Unicode平台子表的platEncID
  2. 增加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 的应用》。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
锦鲤林林_的头像 - 宋马
评论 抢沙发

请登录后发表评论

    暂无评论内容