天天看點

CSS自定義字型 豎向偏移怎麼辦?聊聊字型檔案的字型度量、上升、下降

背景

昨天我釋出了聯機象棋《聯機象棋釋出!打開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自定義字型 豎向偏移怎麼辦?聊聊字型檔案的字型度量、上升、下降

另外,值得一提的是,由于不是所有裝置都安裝了隸書字型,我使用了自定義的字型,保證了多個裝置的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。

寫在最後