中文屏幕字体在 12 到 16 像素这一段要锐利,传统做法是做内嵌点阵。轮廓与点阵并存之后,两边的度量必须一致,否则同一个字在点阵档与轮廓档之间切换时会出现跳动。
做这份字体,先定度量,再画字形。
unitsPerEm 取 256
这个值与 16×16 的点阵档对齐,所有坐标因此都是小整数,点阵与轮廓共用同一套格线。
宽度只有两种:ASCII 一律半角 128 单位(0.5 em),全角一律 256 单位。拉丁字形原本是比例宽度,这里重塑为半角,并施加逐边的笔画粗细补偿。不做补偿的话,横向压缩会让竖笔变细,整段拉丁比汉字轻一档。
单倍行距 1.141 em,与星霞黑体相同,两款可以混排,也可以互换。十个阿拉伯数字在同一字号下底边与高度一致。11 到 28px 逐字号量过,与 Arial、Times New Roman、Consolas、Tahoma 一致。
系统里的中文也逐字号量过:度量与 Windows 预装的中易宋体、中易黑体一致。所以这两款可以顶替系统那两款,混排时行高不会因为一行里有没有星霞的字而改变。
制表符与方块元素的笔画由 39/千单位加粗到 70 与 66,端点与相邻字形对齐。拼起来后笔画连成一条不断的线,htop、mc、ncurses 对话框这类全框界面不再断口,也不再粗细跳变。
点阵只有五档,但请求区间更宽
内嵌点阵只有 12、13、14、15、16 五个档位。FreeType 按半像素取整,因此真正落到点阵的请求范围是 11.5 至 16.5。区间只写一侧的话,区间外的字号会被套上为点阵准备的那套反锯齿设置。
区间之外走轮廓。轮廓含 Chlorophytum 生成的 TrueType 指令,收益集中在 12px 及以下的密集汉字:横画不粘连,笔画数可辨。如果只用在大字号,或者在意体积,可以用拼合工具里的 --strip 去掉指令,轮廓、度量、字符映射与命名都不受影响。
轮廓简化的逐字验收
轮廓经过大幅几何简化以压缩体积:曲线降精度,共线点消除,浅弧压平。
简化后的形状要逐字比对。每个字形在简化前后各渲染一次,逐像素比对;形状偏差超过 1% 的拟合退回更保守的一档,三档都不合格就保留未简化的原轮廓。这一步依赖 FontForge 与两个 Python 库,缺了就整步跳过,不放宽标准。
来源是思源宋体 SC Regular 与 Liberation Serif,两者都是 SIL 开放字体许可 1.1。字体、源码与发行版在 https://github.com/lunzima/GlowSong,配套的黑体在 https://github.com/lunzima/GlowHei。
等宽版是派生的独立文件
比例版与等宽版的字形与度量完全相同,差别只有三处:族名、post.isFixedPitch、PANOSE。
等宽版的做法是从比例版派生出独立文件,而不是让应用把拼合后的族名认作等宽变体。字体选择框读的是文件本身列出的 family,fontconfig 事后加的别名不在其列。fc-list 看得到那些别名,但选择框里没有。
先定规格,再造字形
unitsPerEm、两种宽度、行距、数字的底边与高度、接缝的笔画宽度,都先有规格,再让字形去满足。
代价是前期工作量大:点阵每一档要重画,轮廓简化每一字要渲染比对,拉丁重塑半角要逐边补笔画。好处是拼合关系在造字阶段就对齐。字形要与另一款字体、相邻字形、拉丁数字拼在一起,规格不对就无法事后修正。
评论
点击下面的按钮加载评论框。评论提交后需经确认,不会立即显示。
已提交,确认后会显示。