问个Linux下中文字体等宽调整的问题(同设置Mac下没问题)

下面设置在Mac下是没问题的,字体会放大1.2倍,从而和default face下用的英文字体“近似”等宽 (2个英文字符宽度等于1个中文字符)。但是,在Linux下,我发现face-font-rescale-alist不起作用。

也可能和我加载方式有关?但mac没问题呀。所以我后面也附上整个init-ui.el。字体设定由zyue-init-ui来加载。注:应该和daemon无关,已测试在直接启动方式下也不行。

请问,有没有人在Linux用face-font-rescale-alist调整(中文)字体大小生效的?谢谢!

欢迎各种猜想式分析或排查建议 :slight_smile:

版本:

  • Emacs:26.2
  • Linux: 5.2.6-arch1-1-ARCH

中文字体设置:

  ;; Specify font for Chinese
  (catch 'loop
    (dolist (font '("Sarasa Mono SC" "WenQuanYi Micro Hei"
                    "PingFang SC" "Microsoft Yahei"))
      (when (find-font (font-spec :name font))
        ;; font-family-list not working in Linux for Chinese fonts
        (dolist (charset '(kana han cjk-misc bopomofo))  ;; remove "symbol"
          (set-fontset-font (frame-parameter nil 'font)
  		                    charset
  		                    (font-spec :family font :size size-n)))
        ;; rescale to equal widths (2 EN = 1 SC); NOT working in Linux
        (setq face-font-rescale-alist
              '(("WenQuanYi Micro Hei" . 1.2) ("Sarasa Mono SC"  . 1.2)
                ("PingFang SC"      . 1.2)    ("Microsoft Yahei" . 1.2)))
        (throw 'loop t)))))

全ui设置文件:(中文字体设置位于98-112行)

这很奇怪啊,你写的 font-family-listface-font-rescale-alist 不工作的问题,在我的 Linux 机器上都是好的。

我的想法:

(set-fontset-font (frame-parameter nil 'font)
  		          charset
  		          (font-spec :family font :size size-n)))

试试不要设置 :size,它应该会跟随你之前在

(set-face-attribute 'default frame :font zyue-font)

这一句里指定的字号。

或者你抄一下我的配置,看看行不行,我觉得我这个在字体上做得挺完备了:

;; 默认字体,给西文用的
(defvar toki-default-font
  (cond
   (toki-linux-p
    "DejaVu Sans Mono")
   (toki-mac-p
    "Menlo")
   (toki-win-p
    "Consolas")))

;; 默认字号
(defvar toki-default-font-size 20)

;; 特定字符集的配置。这个列表每一项的格式是
;; (字符集 . (列表 1 . 列表 2))
;; 列表 1 的字体会先被扫描,找到系统中有的,
;; 然后让它在这个字符集下覆盖掉默认字体。
;; 列表 2 的字体会作为优先级比默认字体低的 fallback,
;; 一个一个接到后面去。
(defvar toki-charset-font-alist
  (cond
   (toki-linux-p
    '((unicode  . (nil . ("Droid Sans" "Symbola")))))
   (toki-win-p
    '((unicode  . (nil . ("Arial Unicode MS" "Lucida Sans Unicode")))
      (han      . (nil . ("Microsoft YaHei UI" "Meiryo" "Malgun Gothic")))
      (kana     . (nil . ("Meiryo")))
      (hangul   . (nil . ("Malgun Gothic")))
      (bopomofo . (nil . ("Microsoft YaHei UI")))
      (cjk-misc . (nil . ("Microsoft YaHei UI" "Meiryo" "Malgun Gothic")))))
   (toki-mac-p
    '((han      . (nil . ("PingFang SC" "Heiti SC")))
      (kana     . (nil . ("Hiragino Sans")))
      (hangul   . (nil . ("Apple SD Gothic Neo" "Apple Gothic")))
      (bopomofo . (nil . ("PingFang SC" "Heiti SC")))
      (cjk-misc . (nil . ("PingFang SC" "Heiti SC" "Hiragino Sans" "Apple SD Gothic Neo" "Apple Gothic")))))))

;; font-rescale-alist 的配置还没有做,之后有空做

;; 设定默认字体
(defun toki/set-default-font ()
  (when (member toki-default-font (font-family-list))
    (set-face-attribute
     'default nil
     :font (font-spec :family toki-default-font :size toki-default-font-size))))

;; 设定各字符集的字体
(defun toki/set-charset-font ()
  (dolist (pair toki-charset-font-alist)
    ;; This goes before default font.
    (let ((found-flag nil)
          (i 0)
          (charset (car pair))
          (font-list (cadr pair)))
      (while (and (not found-flag) (< i (length font-list)))
        (when (member (elt font-list i) (font-family-list))
          (setq found-flag t)
          (set-fontset-font t charset (font-spec :family (elt font-list i))))
        (setq i (1+ i)))
      (if (and (not found-flag) (member toki-default-font (font-family-list)))
          (set-fontset-font t charset (font-spec :family toki-default-font))))    
    ;; This goes after default font.
    (let ((charset (car pair)))
      (dolist (font (cddr pair))
        (when (member font (font-family-list))
          (set-fontset-font t charset (font-spec :family font) nil 'append))))))

(defun toki/set-font ()
  (when toki-gui-p
    (toki/set-default-font)
    (toki/set-charset-font)
    ;; 这句就单纯给你看下效果
    (add-to-list 'face-font-rescale-alist '("Droid Sans" . 3.0)))
  (run-hooks 'toki-after-set-font-hook))

(add-hook 'after-init-hook 'toki/set-font)

效果:

2019-09-21-161118_158x151_scrot

2 个赞

谢谢!

font-family-list在Linux下不工作原因我倒是搞清楚了。我的LC_CTYPEzh_CN.UTF-8(别的都还是英文),为了默认fcitx输入法可以在各个app中用,不然还得加前缀env LC_CTYPE=zh_CN.UTF-8。但这个导致了font-family-list里,中文字体名称显示为中文字体名的unicode码,而不是字体的英文名,这就无法像我设英文字体那样用font-family-list判断字体有没安装了(也可以,但太麻烦了),所以我换了用find-font方式,区别不大。

face-font-rescale-alist你的可以用啊?谢谢!这样我就知道是自己的问题,而不是对linux不生效了。我再研究下。

我的环境是英文的,为了 fcitx 能用,只对 Emacs 动了 LC_CTYPE,用这样一个启动脚本:

#!/bin/sh

export LC_CTYPE="zh_CN.UTF-8"
/usr/bin/emacs "$@"

然后直接用 font-family-list 还是可以的。

1 个赞

非常感谢!! 还真是locale的问题,把.profile中的LC_CTYPE为中文的设置去掉后,face-font-rescale-alist生效了。。。image

不过突然发现,不用改LC_CTYPE="zh_CN.UTF-8"启动emacs也能输入中文了,神奇(最近Arch升级了什么嘛image )

.profile 中的 LC_CTYPE 为中文的设置去掉后, face-font-rescale-alist 生效了。。。

听起来就够坑爹的(((

不用改 LC_CTYPE="zh_CN.UTF-8" 启动emacs也能输入中文了

这个我记得应该是 Emacs 自己的一个陈年 bug。我用的 manjaro,刚刚试了一下还是需要改 LC_CTYPE 的,如果 Arch 行的话大概过一阵子俺也能享受到了((

1 个赞