xeCJK: 思源宋体的间隔号宽度过窄
\documentclass{article}
\usepackage{xeCJK}
\begin{document}
凡朵·宋体 \par
{\CJKfontspec{Source Han Serif SC} 思源·宋体} \par
{\CJKfontspec{Source Han Sans SC} 思源·黑体}
\xeCJKsetup{PunctStyle=kaiming}
凡朵·宋体 \par
{\CJKfontspec{Source Han Serif SC} 思源·宋体} \par
{\CJKfontspec{Source Han Sans SC} 思源·黑体}
\end{document}
感觉这个在一定程度上是思源宋体自身的锅。思源宋体的开发进程似乎远远落后于思源黑体,最后一次 Release 还是在四年前。而思源宋体的间隔号 (U+00B7) 本身做的就比汉字宽度的一半还要窄,也没有提供任何“有效”的 OpenType Feature。xeCJK 的标点调整算法我不是很清楚,但感觉默认状况下没有考虑这种情况,大概只做了“挤压”而没有“拉伸”。
(凡朵宋体是个什么东西?想了半天,最后才发现是 Fandol……)
啊这,就在昨天,思源宋体更新了……
不过似乎还是没有修复这个问题。
xeCJK 的算法大致如下:
- 将
·(U+00B7)的字框视为全宽; - 均等抹掉其左右两边的空白,设抹掉值为 x,一般来讲 x 等于四分(这样中间留下的点恰好占据二分),但是 x 不会大于 U+00B7 本身在两边留下的空白,即 x = min(¼em, left side-bearing, right side-bearing);
PunctStyle=quanjiao时会给两边补上可以收缩的弹性间距(自然宽度为 x),而PunctStyle=banjiao或者PunctStyle=kaiming时则不会补上弹性间距。
举一个例子:设 U+00B7 字框宽度为 600,中间圆点占据宽度为 400,本身的留白就是左右各 100。按照 PunctStyle=quanjiao 就是「抹掉 100 再补上 100」,效果是 U+00B7 正常占据 600、但可以收缩到只占据 400。而 PunctStyle=banjiao 或者 PunctStyle=kaiming 时,只抹不补,效果是 U+00B7 完全没有两侧留白、占据 400。
这个算法的第一步其实就跟 GB 有冲突了,按照 GB 的意思 U+00B7 应该做成半宽……但是国内字体厂商其实也无视 GB,把 U+00B7 做成全宽……我在 newxeCJK 提出来的概念(Closing_MiddleHalf、Closing_Full)就是为了解决这个尴尬的问题,全宽的 U+00B7 归类为 Closing_MiddleHalf、半宽或者比例宽的 U+00B7 归类为 Closing_Full。
另附思源系列有关中点的问题:
- https://github.com/adobe-fonts/source-han-serif/issues/93
- https://github.com/adobe-fonts/source-han-sans/issues/295
搞到我现在装的都是 J 版本的,然后用 Language=Chinese Simplified 调用 GB 字形。
思源字体可以通过设置 CharacterWidth=Full 来获得全角间隔号,但是 xeCJK 内部用于获取标点度量信息的 \fontcharwd 和 \XeTeXglyphbounds 返回的还是半角的信息。可以设置 \xeCJKsetwidth{·}{1em} 手动校正信息。