emacs devel 上请求支援,字体中英文等宽相关

这两天 emacs devel 上讨论字体的问题,因为 font 处理 medium 宽度的变更导致一些问题,趁着这个机会,我又把中英文等宽登高的问题甩出来了,看看emacs核心开发者有没有新的思路解决这个问题,或者提供某个接口简化这个问题,但我本人英文太渣,没法很好的讨论,所以请求支援,中英文对齐这个问题太恶心了,困扰一代又一代的中文 emacser

https://mail.gnu.org/archive/html/emacs-devel/2021-11/msg00959.html

14 个赞

哪位同学知道,哪个编辑器处理中英文对齐处理的最好,用的什么原理。在这里介绍一下

之前你上的那个博客节目EmacsTalk有位嘉宾是专门做编辑器的,请教一下?

007. 编辑器专家的 Emacs 世界 – EmacsTalk

我一般自己写不出来就用母语写好,再扔去 deepl.com 翻译。我觉得多数情况比我自己写的通顺。

其实这个问题很早以前在 BBS 时代就有解决办法,比如各种 Term 的实现。一般有两种解决方法。

第一种原理大概是以一种字体为主,比如中文字体,在某个大小下的高度和宽度,然后以这个大小去算出其他字体应该设置的大小,保证两个 ASCII 字符是和一个中文是一样的,而高度一致。所以宽度是对齐的, 高度以较高的为准。但我记得有一个坏处,非中文显得会大一些。这个应该就是 cn-fonts 的解决方法,不过 cn-fonts 不是全自动,而是让用户手动选择合适的,而且没法控制高度。

第二种方法就是加空了。不管多少种字体和大小(用户设定为准),高度取最大的,宽度取最宽的,两个 ASCII 字符对应一个中文字。画的时候的 baseline 要调整,然后左右必要的时候加空。这个坏处就是可能空会太大,不好看,但这是用户选择问题。另一个坏处是计算会多些。好像是叫调整 tracking.

不知道 Emacs 里面是如何做的,理论上是可以做到的。

比如 QTerm: qterm/qtermscreen.cpp at master · qterm/qterm · GitHub Screen::getFontMetrics(),就算是是第二种方法(加空)。

百度翻译之后发到 emacs-devel 了 :crazy_face:

有次英语 pre 讲稿这样子做,结果发现“新冠”翻译成了“new crown”:joy:

咳,没打算让你发上去的,只是讨论讨论。第一种方法一般不会采用,看起来不好的结果还是要调整,不如第二种灵活。

第二种的话好多字体本身的特性就没有了,比如 kerning、ligature 等等,当然很多这些都是针对非等宽字体的,不知道 Emacs 用户有没有使用非等宽字体的。要真实现起来还是要考虑很多东西的, 比如一行中大小不同、不同字符集对应不同字体、性能等等。Term 中的实现不需要考虑这些问题。

Linux下所有图形字体绘制都和 Pango 这个库有关系,方法和你上面说的差不多,要不就是字体制作,要不就是英文字符增加margin。

@tumashu 其实我觉得这个问题无解,原因如下:

  1. 字体融合,取决于字体作者根据中文重新设计英文,强制等宽会导致英文比较肥大
  2. 字体加margin, 会导致英文单词的整体性缺乏

从我十多年Linux图形编程经验看,中英文字体等宽的目标本来就是错误的,因为两种字体本来就不一样宽,即使类似 Pango 加margin的技术也会导致英文很难看,原因是中文字体和英文字体不一定匹配。

这个问题的根本原因是Emacs发展太早了,那时候Qt/Gtk/X11不存在,Emacs天然没有图形控件和逻辑像素(就是垂直画线,不受前面文字影响),所以本质问题是像素对齐,和中文是否对齐无相关。

@ casouri 的 align-to 是一种解决方法,但无法解决更广泛的对齐问题。Emacs本身历史包袱太重了,底层图形机制改动太大都会破坏兼容性,这也是为啥我直接采用EAF的方案。

4 个赞

这个感觉并不需要知道其它编辑器是怎样处理中英文对齐的吧,其它编辑器应该大多数都是用的js写插件,如vsc就是基于chrome的electron,只要知道浏览器里是怎么处理中英文对齐的,用的什么原理就行。然后在看emacs能否用上,不知道这个理解对不对。

我英文更渣帮不上忙

如果英文用等宽字体的话是可以的。中文反正本来就都是等宽字体。 等宽字体的字符之间无非是一个个矩形之间的关系。可以用各种方法来对其,并不会太影响观感。 不能解决的是那些复杂的英文字体,但是那些我觉得根本就不需要放在考虑范围之内,因为中文字体不支持这些特征,反正混合起来无论如何也不可能自然。

所以我觉得如果把目标定在将等宽英文字体和中文字体进行行高和/或字符宽度的对其,是可以实现的。

大家思考一个问题,emacs里为啥需要中英文对齐?如果不对齐哪些使用场景很难受?

1 个赞

一般都是在表格有关的应用:

org-mode表格,不对齐完全没法看

代码注释有时会包含一些表格,如果又含有中文就会破坏格式

对,我的意思是表格的对齐应该是像素对齐,即使上下表格之间内容不一样宽,表格分割线一样也应该对齐,想想excel。

所以我的问题是emacs因为不支持图形控件,用字符模仿表格分割线才造成这个问题的。

正确的解决方式是引入像素级分割线绘制API和逻辑判断,不管内容是否一样宽,都用像素逻辑去对齐,而不是字符宽度去算。

因为我们没法控制每个字体一样宽,字体之所以叫字体就是它有文化属性,理论上会有三个或者多个字体混合的情况。

3 个赞

你这样只能解决真正的图形化表格,代码注释里就经常会有依赖等宽字体的表格。有时有表格线,更经常是没有表格线,只依赖上下行在同一列上。

其实是有解的,你看valign这个插件的align-to原理。

只不过需要让表格代码(包括注释)要每处都要考虑align-to的逻辑,现在emacs核心开发者大部分是老外,理解不了为啥要用像素对齐。

// English:  do this
// 中文   :  那样做

这样的注释怎么能让冒号对齐?你怎么知道用户是想在冒号处对齐?

align-to原理可以用到任意字符,包括针对冒号这种情况,先了解一下align-to原理吧。

已经把链接发给他了

1 个赞

我知道它可以针对任何字符,但是毕竟需要一个制表字符列表,你无法预料用户想要用什么字符,是否必然包含在这个表里。如果需要针对每个文件定制,那就太麻烦。如果用户什么特殊字符也不用,只用空格来对齐,你就没法子了。