首页 > 其他分享 >CSS自定义字体 竖向偏移怎么办?聊聊字体文件的字体度量、上升、下降

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

时间:2022-10-17 12:32:16浏览次数:54  
标签:联机 自定义 Windows win 竖向 字体 typo 度量


背景

昨天我发布了联机象棋《联机象棋发布!打开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>

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

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

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

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

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

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

问题

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

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

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

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

如何解决问题

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

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

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

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

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

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

我立马导出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自定义字体 竖向偏移怎么办?聊聊字体文件的字体度量、上升、下降_CSS_06

表格中描述是:

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

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

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

写在最后

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

标签:联机,自定义,Windows,win,竖向,字体,typo,度量
From: https://blog.51cto.com/hullqin/5762215

相关文章

  • 自定义异常和练习自定义异常
    自定义异常java中不同的异常类,分别表示着某一种具体的异常情况那么在开发中总是有些异常情况是SUN没有定义好的此时我们根据自己业务的异常情况来定义异常类例如年龄......
  • SE73 上传字体
    有时候smartforms打印需要第三方字体SE73上传字体:(自行准备ttf格式的字体文件)之后在style创建的时候就可以选此字体了其他信息可以参考note:1605966-UploadTrueTypef......
  • Docker | 自定义网络(网关、子网地址)
    了解dockernetwork通过下面的命令来获取帮助dockernetwork--helpCommands:connectConnectacontainertoanetworkcreateCreateanetwork......
  • 四、WinUI3下TitleBar的自定义
    WinUI3下TitleBar的自定义对于Windows软件开发者来说重写标题栏样式是一个很重要的事情,在WPF阶段很多人写出来性能很差的窗口,而且为了适配Win11系统的Snaplayout后性能就......
  • 2022-10-16 字体颜色渐变
    background-image:-webkit-linear-gradient(bottom,red,#fd8403,yellow);-webkit-background-clip:text;-webkit-text-fill-color:transparent;这里只记录最简......
  • python新类似乎违背了广度优先的执行顺序, 对象自定义计数实例化的多少
    classTSSS():deff1(self):print('fromTSSS')classSSS(TSSS):deff1(self):print('fromSSS')classSS():deff1(self):......
  • Spring Boot:自定义 Whitelabel 错误页面
    一、概述在本文中,我们将研究如何禁用和自定义SpringBoot应用程序的默认错误页面,因为正确的错误处理描述了专业性和质量工作。2.禁用白标错误页面首先,让我们看看如何通......
  • Qt自定义类使用QSS换肤
    文章目录​​一、前言​​​​二、效果展示​​​​三、具体步骤​​​​3.1、自定义继承自QWidget的类​​​​3.2、自定义类添加自定义属性及接口​​​​3.3、完整的时钟......
  • ES 自定义分析器
    分析器的组成一个分析器由三部分组成:CharacterFilter/Tokenizer/TokenFilerCharacterFilters在Tokenizer之前对文本进行处理,可以配置多个CharacterFilter。ES自带......
  • 自定义动画
    defbfi(a):#只能在xxp()中使用li=[]foriina:i.set(sheen_direction=d)......