likes
comments
collection
share

CSS自定义字体 竖向偏移怎么办?聊聊字体文件的字体度量、上升、下降

作者站长头像
站长
· 阅读数 60

背景

昨天我发布了联机象棋《联机象棋发布!打开URL就能联机对战!观战!单机演练!分享残局!》,有玩家试玩,截图如下:

CSS自定义字体 竖向偏移怎么办?聊聊字体文件的字体度量、上升、下降

通过截图大小以及里面的emoji我推断出:这是一台Windows PC。

之前我在Android、iOS、MacOS上都测试过,表现正常,唯独没有测试Windows,结果真的出问题了。那就尝试修复下吧!

现状

我是用SVG展示的文字,并且用了自定义字体。我使用React开发的,下面是JSX语法:

<g>
  <use xlinkHref="#piece-red" x={x} y={y} />
  <text className="piece-text" x={x} y={y} fontSize="5" fill="white" textAnchor="middle" alignmentBaseline="central">{text}</text>
</g>

其中use就是棋子的圆圈⭕️,没有字的那种,text就是文字。

我给他们设置了一样的的x和y,棋子圆圈的x和y就是圆心的坐标,文字的x和y通过textAnchor="middle" alignmentBaseline="central"保证它垂直水平中心位于x、y处。这样文字就一定处于棋子圆圈中心了,而不需要我人肉计算坐标,比较方便。效果如图:

CSS自定义字体 竖向偏移怎么办?聊聊字体文件的字体度量、上升、下降

另外,值得一提的是,由于不是所有设备都安装了隶书字体,我使用了自定义的字体,保证了多个设备的UI统一,并且由于字体文件非常小,只有6kb,所以体验也很好。

@font-face {
  font-family: "CentralLiShu";
  src: url("/CentralLiShu.ttf");
}
.piece-text {
  font-family: CentralLiShu, fangsong;
}

如果想了解我是如何压缩字体文件的,你可以阅读文章《基于svg和ttf(字体文件),我仅用6kb就画完了象棋所有棋子》

问题

之前我是通过FontEditor这个在线网站编辑字体的,其实当时遇到过在MacOS上字体不居中的问题,我手动调整了每个字体的位置解决了。下图是文章内容截图:

CSS自定义字体 竖向偏移怎么办?聊聊字体文件的字体度量、上升、下降

我通过Google搜索了为什么文字不居中,结果相关的问题都非常少,怀疑是跟自定义字体有关。最终,我找到了“字体度量”这个名词。

现在我才知道了文字不居中的根本原因:字体度量

如何解决问题

在字体编辑器上,点「设置」,可以打开「字体度量」。包括如下属性:

CSS自定义字体 竖向偏移怎么办?聊聊字体文件的字体度量、上升、下降

重点关注前3行的属性:上升、下降、win上升、win下降、typo上升、typo下降。

我发现win下降的值明显大于其他值,也许这就是导致windows下字体向下偏移的原因吧。

我发现右侧有个“计算”按钮,点击后,这些上升、下降值重新计算了:

CSS自定义字体 竖向偏移怎么办?聊聊字体文件的字体度量、上升、下降

我立马导出ttf文件,去MacOS和Windows上验证,发现字体都居中了!现在,问题解决!

但是,为什么呢?

字体度量

字体度量主要包括:

  • ascent: 顶部参考线(不推荐字体超出)。
  • capHeight: 大写字母H的高度的参考线。
  • xHeight: 小写字母x的高度的参考线。
  • Baseline: 大小不同的文字排列一行时,默认是以他们的Baseline对齐的(不能用底部参考线对齐,例如pP如果底部对齐,你都难以区分大小写了)。
  • descent: 底部参考线(不推荐字体超出)。

出于历史原因,至少有三组数值是用来处理字体度量的。它们名为 hhea、typo(又名 sTypo 或 OS/2)和 win(或称 usWin)量度。取决于在何种操作系统上使用的哪一款软件,在屏幕上渲染字体时,会使用不同的度量。

hhea 指 OpenType 表 hhea。Apple 设备使用这些值来渲染。typo 和 win 的值是 OpenType OS/2 表的一部分,包括sTypoAscender sTypoDescender sTypoLineGap usWinAscent usWinDescent。Windows会使用win值。

——引用自Glyphs字体软件的科普文章。

也就是说,我们的字体文件中,哪怕你定义了一个字体的矢量图,但是它的垂直坐标偏移还是要额外设定的。在OS/2中,我找到了详细的规范。如下图:

CSS自定义字体 竖向偏移怎么办?聊聊字体文件的字体度量、上升、下降

表格中描述是:

  • 在hhea表中,不需要定义typo值。
  • Windows 的上升指标 usWinAscent 计算为 Windows ANSI 字符集中所有字符的 yMax。
  • Windows 的下降指标 usWinDescent 计算为 Windows ANSI 字符集中所有字符的 -yMin。

也就是说这些值是可以计算出来的,把所有字体的最高点和最低点选出来,最高点作为winAscent,最低点的相反数作为winDescent。

我终于明白,为什么字体度量是可以计算出来的~ 而且,win值的下降确实跟其他2个下降互为相反数~

写在最后

我是HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,联系我,交个朋友),转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋、象棋等游戏,不收费无广告。还独立开发了《合成大西瓜重制版》。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我噢~我有空了会分享做游戏的相关技术,会在这2个专栏里分享:《教你做小游戏》《极致用户体验》

转载自:https://juejin.cn/post/7153656063240175624
评论
请登录