Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[solved] 中文省略号显示宽度不正确 #64

Closed
yangsheng6810 opened this issue Apr 10, 2017 · 41 comments
Closed

[solved] 中文省略号显示宽度不正确 #64

yangsheng6810 opened this issue Apr 10, 2017 · 41 comments

Comments

@yangsheng6810
Copy link

问题如图:
1

“……”在emacs里查看属于symbol,而且似乎计算距离的时候是按照中文字体计算的,但在实际显示的时候,却显示的是英文字体。用describe-cha查得他的unicode是#x2026。我尝试用设置symbol和直接设置字符的方式改变字体,但是都没有用。

    (defun my-set-symbol-fonts (fontsizes-list)
      (let* ((fontname "思源黑体 CN")
             (fontsize (nth 0 fontsizes-list))
             (fontspec (font-spec :name fontname
                                  :size fontsize
                                  :weight 'normal
                                  :slant 'normal)))
        (if (cfs--fontspec-valid-p fontspec)
            (set-fontset-font "fontset-default" 'symbol fontspec nil 'append)
          (message "字体 %S 不存在!" fontname))))

    (defun my-set-exta-fonts (fontsizes-list)
      (let* ((fontname "思源黑体 CN")
             (fontsize (nth 1 fontsizes-list))
             (fontspec (font-spec :name fontname
                                  :size fontsize
                                  :weight 'normal
                                  :slant 'normal)))
        (if (cfs--fontspec-valid-p fontspec)
            (set-fontset-font "fontset-default" '(#x2026 . #x2026) fontspec nil 'append)
          (message "字体 %S 不存在!" fontname))))
@tumashu
Copy link
Owner

tumashu commented Apr 11, 2017

(add-hook 'cfs-set-font-finish-hook 'my-set-exta-fonts) 这个执行没?

@yangsheng6810
Copy link
Author

两个函数都挂上hook了。之前复制代码的时候漏了。

    (add-hook 'cfs-set-font-finish-hook 'my-set-symbol-fonts)
    (add-hook 'cfs-set-font-finish-hook 'my-set-exta-fonts)

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

这个有问题在开,我先关了

@tumashu tumashu closed this as completed Apr 22, 2017
@yangsheng6810
Copy link
Author

能给个upstream的链接吗?

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

upstream 是什么东东?

@yangsheng6810
Copy link
Author

上游。或者说,既然有同样的问题在开,给个链接?

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

... 我的意思是, 你好长时间没有反馈细节, 我以为你已经解决这个问题了, 所以我准备关了这个issue, 你再有类似的问题, 就 reopen 这个 issue

@yangsheng6810
Copy link
Author

我在你问hook有没有挂的当天就回复了……

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

两个函数都挂上hook了。之前复制代码的时候漏了。

    (add-hook 'cfs-set-font-finish-hook 'my-set-symbol-fonts)
    (add-hook 'cfs-set-font-finish-hook 'my-set-exta-fonts)

你不是说你开始漏了嘛....

@yangsheng6810
Copy link
Author

啊……是我没说清楚。我的意思是,我实际有这两行代码,在往github上贴的时候贴漏了。

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

咱们的中文水平有待提高, 是这麽回事, chinese-fonts-setup 一般是不设置 符号 字体的, 所以chinese-fonts-setup 添加了一个 hook, 让用户通过 hook 自己设置 符号字体的名称和大小, 你可以将 (fontsize (nth 0 fontsizes-list)) 更改为 (fontsize 50) 来看看 hook 有没有生效, 然后就慢慢调整 这个 fontsize 就可以了

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

另外 "思源黑体 CN" 这个字体名称是怎么来的? cfs-insert-fontname 命令运行后, 备选项里面有这个名字没?

@yangsheng6810
Copy link
Author

我这两天也研究了一下,symbol 的字体确实应该保持原样,因为有大量其他字体需要用到英文字体大小的symbol字符。我希望手工把“…”这个字符设置成汉字的字体,这样“……”就占两个格子的位置。而且事实上emacs进行字体宽度计算的时候,也把“…”当成汉字的字体大小,这样就导致org-mode里的table对齐有问题。
我确认了一下,我已经手工安装并配置好了思源黑体,cfs-insert-fontname运行后,备选项里有这个名字。

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

也许这是字体的bug, 我这里试验了一下, 可以对齐, 我用 微米黑

@yangsheng6810
Copy link
Author

文泉驿等宽微米黑?我试了一下,不行。能给张截图吗?

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017 via email

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

我机子不知道怎么回事, github 无法上传图片, 我给那发邮件了

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

英文我使用 PragmataPro

@yangsheng6810
Copy link
Author

这个字体我没有,似乎也不是很好找。

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

你可以试试其他英文字体, 看看对齐效果, 确定是不是你当前使用的字体有问题

@yangsheng6810
Copy link
Author

我试了,没有用。而且在这个字符上运行(describe-char),里面的xft会显示英文字体

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

我这边也显示是英文字符, 你吧hook去掉再试试

@yangsheng6810
Copy link
Author

试过了,现在就是没有hook的,没有用。

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

英文字号和中文字体分别是什么?

@yangsheng6810
Copy link
Author

Monaco, Free Mono, DejaVu Sans Mono, Droid Sans Mono和
思源黑体,微软雅黑,文泉驿等宽微米黑,Hiragino Sans GB的各种组合

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

我这边Monaco 和 微米黑都没有问题, discribe-char 显示是使用 Monaco,

@yangsheng6810
Copy link
Author

能想办法给个截图吗?邮件也可以

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017 via email

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

另外一个可能就是 spacemacs 在捣乱

@yangsheng6810
Copy link
Author

我读了spacemacs设置字体的代码,以及org-mode处理字符串宽度和table对齐的代码。简单来说:应该是spacemacs的字体设置问题,spacemacs的字体设置是这样的:先用default字体,然后如果default字体找不到,再用其他字体。在这个过程中,set-fontset-font的功能似乎受到一定的影响,无法完全正常工作。

我考虑过是不是hack一下字符宽度,但是org-mode调用的string-width函数是内置用C写的函数,并不适合修改。对于spacemacs的字体设置代码我还没有完全弄清楚,需要一点时间。暂时先把这个issue关掉吧。

@tumashu
Copy link
Owner

tumashu commented Apr 22, 2017

OK

@tumashu tumashu reopened this Apr 22, 2017
@tumashu tumashu closed this as completed Apr 22, 2017
@yangsheng6810
Copy link
Author

yangsheng6810 commented Apr 23, 2017

终于把问题完全解决了,总结如下:

  1. 出现无法对齐的原因是字符宽度问题。org-table通过(char-width char)(string-width str)来获取字符和字符串的显示的宽度,而这两个函数通过查阅char-width-table来返回每个字符的宽度。如果使用的是非CJK的locale,那么诸如“”…之类的字符都是宽度为1,但如果使用的是CJK的locale (我之测试了zh_CN和ja_JP),在/usr/share/emacs/25.2/lisp/international/characters.elc里(不同平台的位置可能不一样),会对一些字符的宽度进行设置,导致“”…的宽度变成2。
  2. 无法指定某些字符使用特定字体的原因是我用的是emacs 25.1。在25.1里,有这样一个新feature,就是当default font有某个字符的时候,优先使用这个字体,而无视fontsets。在25.2里,添加了一个variable,use-default-font-for-symbols,默认为t,为无视fontsets。可以设为nil来重新支持fontsets里的调整和自定义。参考邮件列表

解决方案:

  1. 因为很多中文字体的“”…这些字符都不等宽,所以要想对齐,最好直接使用英文等宽字体里的这些字符。而这正是默认的做法。对于非CJK的locale,这时已经可以正确对齐了,但对CJK的locale,由于emacs将“”…等字符定义为宽字符,所以还不能正确对齐,需要手工设置宽度,才能正确对齐。以下是我找到并修改的代码
  (defun blaenk/set-char-widths (alist)
    (while (char-table-parent char-width-table)
      (setq char-width-table (char-table-parent char-width-table)))
    (dolist (pair alist)
      (let ((width (car pair))
            (chars (cdr pair))
            (table (make-char-table nil)))
        (dolist (char chars)
          (set-char-table-range table char width))
        (optimize-char-table table)
        (set-char-table-parent table char-width-table)
        (setq char-width-table table))))

  (blaenk/set-char-widths
   `((1 . (,(string-to-char "")
           ,(string-to-char "")
           ,(string-to-char "")
           ))))
  1. 对于自定义fontsets无效的问题,只会对emacs 25.1及后续版本用户产生影响。对于emacs 25.2及之后的用户,设置
  (setq use-default-font-for-symbols nil)

即可。对于emacs 25.1用户,请降级/升级您的emacs。

最后,本issue终于解决,把它标成solved吧!另外,建议考虑把以上两个解决方案收入README。

@tumashu tumashu changed the title 中文省略号显示宽度不正确 [solved] 中文省略号显示宽度不正确 Apr 23, 2017
@tumashu
Copy link
Owner

tumashu commented Apr 23, 2017

我靠, 不容易呀....

@yangsheng6810
Copy link
Author

都是泪……都是泪……

@tumashu
Copy link
Owner

tumashu commented Apr 23, 2017

我在README添加了这个issue的链接: 40fb782

@yangsheng6810
Copy link
Author

这个issue不是spacemacs的问题,而是emacs本身的问题,是不是可以换一个措辞,更有针对性一点?比如1. 在“Chinese-fonts-setup 高级功能”的注意事项里加一条:如果遇到部分符号无法正确对齐,而且以上代码无效,可以参考。。。
2. 如果部分符号无法正确对齐,请参考。。。

@tumashu
Copy link
Owner

tumashu commented Apr 23, 2017

OK

@yangsheng6810
Copy link
Author

赞!

@tumashu
Copy link
Owner

tumashu commented Apr 23, 2017

你厉害, 也不知道你怎么找出这个bug的, 脑细胞都消耗不少吧.....

@yangsheng6810
Copy link
Author

恩……弄到凌晨3点,读了一堆代码,然后放弃了。起床之后运气比较好,接连搜到有用的页面,然后解决起来就快了。

@tumashu
Copy link
Owner

tumashu commented Apr 23, 2017

:-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants