为什么要了解 #
编码确保了信息被准确的传输
字体确保了(文字)信息被准确的表达
某种角度上,我们也在做类似的,抽象纬度更高的工作
字符编码 #
https://baidu.com
可以将上述链接复制到地址栏打开测试
编码集 #
定义字符和数字(码点)之间的映射关系
ASCII #
最早的标准, 定义 128 个字符, 仅支持英文
Unicode #
支持多种语言(CJKV..), 特殊符号, emoji, … 上例的零宽空格符的 Unicode 值为 U+200B, 可通过 String.fromCodePoint(0x200B) 观察
Others #
这期间还有我国推出的 GB(K), 早期标准 ISO-8859-1, 早期事实标准 windows-1252 等… 网页编码标准 Tip: 标准是标准,实现看各家..可以试验下修改网页编码后的表现(通过 document.charset 获取)
字符编码 UTF - Unicode Transformation Format #
至今 Unicode 15.1 含 149813 个字符, UTF 对其进行二进制编码
UTF-8 #
普适, 事实上的标准(尤其是Web领域)
UTF-16(BE / LE) #
适合 CJKV 场景
UTF-32 #
适合随机读取字符场景
字体 #
首先介绍一些基础概念:
字形 glyph, 字的形体
字型 font, 某套具有同样样式、尺寸的字形. 如“12号常规宋体字"
字体 typeface, 也称 font family, 一个或多个字型组成的集合,每个字型具有共同设计特征,如“宋体”
字体的发展历史 #
这里暂时不讨论排版印刷(typography)时期的概念,直接讨论计算机字体
计算机字体 #
- 点阵字体:位图,适合小字体场景
- 矢量字体:
- PostScript 字体(特别指代 Adoble 最早使用 PostScript 格式(3次贝塞尔曲线)私有封装的字体)
- TrueType(TTF, 主要使用 2次贝塞尔曲线)
- OpenType(TTF/OTF)
- Web font(Woff)
一些不那么常用的字体特性 #
Hinting - 渲染提示
思考一下为什么浏览器默认不允许设置 12px 以下的字体大小?
rn m
Ligature - 连字
Kerning - (连字)间距
Bidi
在国际化场景中,有时候我们会通过 logic direction 进行 RTL 适配(虽然一般不这么做)
语言实际上也存在 logical order 和 visual order, 两者不一致的时候就是 Bidirectional 文本
如何准确显示字体 #
以上场景在在 HTML 中浏览器都会处理好(大部分也支持我们通过 CSS 设置) 如果在 Canvas 中,就需要我们自己处理,这里简单介绍下:
- 解析字体的 PostScript 信息(hhea/vhea/(os/2)..), 拿到 font-Mertrics (注意是 font 不是字体)
- 排版: line-breaking, Bidi 等
- 字形选择(Shaping/reShaping): harfbuzz (处理 hinting, ligature, kerning…)
- 渲染: fillText (一切都交给 chromium 了) 实际上 chrome 大概也是这么做的, 只不过它使用了 skia 作为底层渲染器 这也一定程度上解释了为什么 google 推出了 flutter
了解这些后,可以做些什么 #
做一款字体 #
为了不干扰其他字符的正常展示,这里使用的 Unicode 中的私有区
直接/安装字体后 点击测试
实际上企业发展到一定体量后,为了保障用户体验,自研字体是必经之路(然后就是自研浏览器)