狠狠地折腾了一把Emacs中文字体
1 Emacs中文字体的最基本问题
从23版开始,Emacs的中文显示可以说很轻松就可以基本解决。比如网上这位 强者(强是他的名字) 的配置方法,可以自动适配当前机器上已有的中文字体,有好的就用好的,没 有就将就一点。我最近也把他的配置抄过来了。
但这么一抄抄出问题来了(其实问题以前也一直存在,但折腾一开始就停不下来,必须把问题解决为止。这是身为Emacs狂粉儿必须付的代价?)。
2 等高还是等宽?
我以前的配置一直都是等高。估计大部分同学的选择是等宽。其实它们都各有缺点。
2.1 等宽不等高的问题
我用的是自己写的输入法SDIM,跟其他Emacs自带的输入法一样,它的候选词是在 echo area里显示的,如果不等高的话,echo area的高度会不断跳动,在上下两 个窗口的时候,第二个窗口中的输入会很痛苦:echo area的高度变化会导致第二 窗口的位置也发生变化,从而产生抖动,眼睛吃不消。
2.2 等高不等宽的问题
org-mode里的中英文混排、尤其是在表格中,如果不选等宽(指的是一个中文字 符与两个英文字符等宽),表格就没法看了。邮件程序gnus的排版也会大受影响, 导致不够美观。
2.3 等高或者等宽共有的问题
不管你选的是等高还是等宽,只要你选,估计在放大、缩小的时候( C-x C-+
和 C-x C--
),英文可以缩放,中文不会;你用 put-text-property
等都
只会对英文有效,中文无效!搞什么嘛!除非你不选,这样出来的结果可能既不
等高也不等宽,从而表格排版问题和输入抖动问题同时存在,囧死算了……
3 解决的方法
问题的关键出在下面的 :size
参数。以我的英文字体为Monaco-14为例,中文
字体为 Microsoft Yahei 为例,如果我要等高的话,我需要把 :size
设为16,
如果我要等宽的话,要设为一个较小的值。
(set-fontset-font t 'han (font-spec :family "Microsoft Yahei" :size 16)
但只要你一设,等高还是等宽你只能选一个,附加赠送上面说的缩放的问题。如 果不设,则中文字体跟英文字体的size保持一致,也是14,根据不同中文字体可 能既不等高又不等宽。
解决的方法是不设 :size
,而是修改另一个变量:
(setq face-font-rescale-alist '(("Microsoft Yahei" . 1.2) ("WenQuanYi Zen Hei" . 1.2)))
并且一定要重启Emacs(见 这个坑爹的bug ,浪费我N多时间,都准备上gdb了)!
改完之后由于缩放对中文也有效,我只要把输入法的中文字体设小一点就可以了。见图:
配置脚本见 github 。
另外,这个设置在Windows上也可以用,但是好像不是很可靠(我见到它有时候不
起作用,不明白怎么回事),并且在我的Win7系统上必须把 微软雅黑
给加到
face-font-rescale-alist
里去(可以用 C-u C-x =
来看当前汉字是用什么字体显示的,从而决定应该在这个变量里加什么。另一个有用的函数是 describe-fontset
):
(setq face-font-rescale-alist '(("微软雅黑" . 1.2) ("Microsoft Yahei" . 1.2) ("WenQuanYi Zen Hei" . 1.2)))
见图:
4 全局缩放
见 这篇博客 。
5 完美英文斜体
先贴一下效果:
当初在水木Emacs版的 这个贴子 里提了一下,这里自己再转一遍:
发信人: flonk (flonk), 信区: Emacs 标 题: 完美搞定Emacs英文斜体 发信站: 水木社区 (Fri May 10 11:39:06 2013), 转信 [累计积分奖励: 100/0] 所谓完美,就是跟正体保持等高等宽,并且一起(全局)缩放 提供斜体的等宽字体好像只知道Courier New。 要点在于一定要用浮点数指定point size,而不是整数指定pixel size。 代码见:https://github.com/baohaojun/system-config/raw/master/.emacs_d/lisp/bhj-fonts.el 全局放到最大后效果图:http://baohaojun.github.io/images/post/italic-font.png
6 Mac和Linux下的不同参数
在不同的系统下和不同的字体尺寸下,要达到中英文等宽,中文的scale参数要设成不一样。所以我后来增加了相应的变参机制,见代码:
;; On different platforms, I need to set different scaling rate for ;; differnt font size. (cond ((and (boundp '*is-a-mac*) *is-a-mac*) (setq chinese-font-size-scale-alist '((10.5 . 1.3) (11.5 . 1.3) (16 . 1.3) (18 . 1.25)))) ((and (boundp '*is-a-win*) *is-a-win*) (setq chinese-font-size-scale-alist '((11.5 . 1.25) (16 . 1.25)))) (t ;; is a linux😊 (setq chinese-font-size-scale-alist '((16 . 1.25)))))