3.8 KiB
author | title | date | tags | category | toc | ||
---|---|---|---|---|---|---|---|
SouthFox | 中文网页字体动态裁剪 | 2021-03-12 21:28:56 |
|
技术 | true |
首先,我先在放个【矣】在这里。
比起字母系统语言,汉语在计算机世界上有着天然的弱势,锟斤拷和锘锘锘这些编码问题本身就令人头大了,尤其对于互联网这个寸土寸金之地,想要在网页内展现自定义字体,首先就要先加载个几兆大小的字体文件,要这么做那就是极度的浪费和折磨了。
所以字体裁剪是必要的,有两种方向:
-
提前准备常用字集进行裁剪
-
提前计算出需要展示的字集再进行裁剪
第一种方式就是突出一个极致的懒,只需要做一次,就能不用再管了。缺点就是总会有不在常用字体里的“常用字”,这样网页加载出来的效果就会形成“犬牙交错”之感,看起来非常辣眼(要是选用的字体和默认字体差别非常大的话)。而且常用字内其实也不是每个字都用上了,所以还是会有浪费。
第二种方式就更优雅一点了,能保证字体里的每个字都是用上的。缺点就是麻烦了点儿,不过只要写个自动化脚本,这点麻烦也不算麻烦了。
压缩方案
当选 fonttools ,至少这项目现在还活跃着,其他类似的字体项目都停滞了蛮久时间的了……好像。
要使用直接通过 pip install
安装 fonttools
就行了,要是还想压成 woff2
这种压缩率更高的格式还得再安装个 brotli
。
使用命令:
pyftsubset <字体>.ttf --text-file=<字符集文件>
当然,也可用 --text=
的选项来直接后面跟所需字符。
要压成 woff2
格式可以用 fonttools ttLib.woff2 compress <压缩后字体>.woff2 <被压字体>.ttf
的方式。
脚本代码
反正一个简单粗暴的循环怼上去就得了,去重可以用集合来去。
import os
path = os.getcwd()
filelist = []
for root, dirs, files in os.walk(path + '/source'):
for name in files :
filelist.append(os.path.join(root, name))
strset = set([])
for filename in filelist:
if '.md' not in filename:
continue
with open(filename, "r",encoding='utf-8') as f:
for subset in f.read():
strset.add(subset)
str_ = ''
a = 0
with open('strdb.txt', "w") as f:
for i in list(strset):
str_ += i
a += 1
print('%d Characters in all files.'%a)
print(str_)
f.write(str_)
将 source
下的 md
文件的字符提出来,再写入到 strdb.txt
以带后续使用。当然直接用 --text=
选项直接塞进命令里也可以,反正我是喜欢先写进文件的。
最后生成的字体文件在 80kb 左右,对于网页来说,已经是可以接受的程度了,当然这跟我选择的字体有关,是一款像素字体,不怎么占空间,如果是常规字体的话,大概会在上两三百左右吧。
坑
- 首先是
Travis
部署上得用python3
环境,要特别声明一下,二环境下会输出个零蛋,应该是版本之间语法的锅? - 代码里没有解析配置文件里的中文语句,所以标语口号这种,可能就会没被解析到,不过我懒地再一个一个引入配置文件,所以还不如……
我先在放个【矣】在这里。 - 确保文本在网页字体加载期间保持可见状态,即设置
font-display: swap
选项 在@font-face
内,要不然的话字体没加载出来文本会消失掉。