如何以健壮的方式设置字体后备?


16

TL; DR:一种简单的可靠说法是:将Consolas用作默认字体,将FreeMono用于Consolas不支持的字符,将Symbola用作两者均不支持的字符?

由于我的主要编程字体未涵盖我需要的所有数学符号,因此我最初设置字体后备,如下所示:

(set-fontset-font t 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font t 'unicode (font-spec :name "Symbola") nil 'append)

不幸的是,这也改变了我主要字体支持的某些字符的字体,因此我将其更改为

(set-fontset-font t 'unicode (font-spec :name "Consolas") nil)
(set-fontset-font t 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font t 'unicode (font-spec :name "Symbola") nil 'append)

如果我的理解是正确的,这应该确保Consolas无法处理的字符由FreeMono处理,除非FreeMono没有它们,在这种情况下,应使用Symbola显示它们。我的理解t也与"fontset-default"上述相同。

不幸的是,仍然有一些情况没有选择正确的字体。我发现更改为

(set-fontset-font t 'unicode (font-spec :name "Consolas") nil)
(set-fontset-font t 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font t 'unicode (font-spec :name "Symbola") nil 'append)
(set-fontset-font "fontset-startup" 'unicode (font-spec :name "Consolas") nil)
(set-fontset-font "fontset-startup" 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font "fontset-startup" 'unicode (font-spec :name "Symbola") nil 'append)

效果更好,但并非总是如此:使用更改字体大小

(set-face-attribute 'default nil :height some-size)

由于创建了新的字体集,导致后备时间被忽略。

我目前的解决方案是

(set-fontset-font fontset 'unicode (font-spec :name "Consolas") nil)
(set-fontset-font fontset 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font fontset 'unicode (font-spec :name "Symbola") nil 'append)

在每个字体集(fontset-list)上更改每个字体大小之后。

设置字体后备的正确方法是什么?

注意:出于测试目的,这里有一些数学字符:ℕ𝓟⧺×≠≥≤±¬∨∧∃∀λ⟿⟹⊥⊤⊢
参考:有关字体集修改字体集的 Emacs手册


2
我有一个想法不能真正解决您的问题,但是–如果您需要用于理论和科学文档的数学等符号,那么为什么不使用TeX和AucTeX呢?它将避免使用X(或Mac或Windows,取决于您运行的软件)的字体回退,并为您提供高质量的文档和摘录(例如,用于组织模式)。

事后思考:具有完整字符集的UTF-8字体应完全解决您的问题(例如GNU Unifont),并且当需要在花哨字体和所需字形之间进行选择时,我选择后者。

2
@kuli你太悲观了。见 github.com/cpitclaudel/monospacifier
Ista

我不记得在哪里读过它,但我相信Eli Zaretskii在某个地方回答了类似的问题。您正在fontset以错误的方式思考。Emacs实际上并不会检查它显示的每个字符,不管字体是否知道如何显示。这将在计算上过于密集。因此,本身就没有“后备”机制。您应该设置默认字体,然后在特定范围内手动修改默认字体集以使用不同的字体显示。此过程是手动的,或者包装unicode可以提供帮助。
GenaU

@GenaU我可能会误会,但是Emacs会检查;并非所有字体,只有字体集中显示的字体。
克莱门特

Answers:


0

对于那些无法阅读Emacs文档的人。

字体选择

在Emacs可以在图形显示上绘制字符之前,它必须为该字符选择一个“字体”。通常,Emacs会根据分配给该字符的面部自动选择字体,特别是面部属性':family',':weight',':slant'和':width'。 字体的选​​择还取决于要显示的字符。有些字体只能显示有限的字符集。如果没有可用字体完全符合要求,则Emacs将寻找“最接近的匹配字体”。 本节中的变量控制Emacs如何进行选择。

face-font-family-alternatives

使用问题中的字符进行了专门测试,并使用来检查字符
describe-character。每个字符都使用一种免费字体:Consolas,FreeMono,Symbol。通过设置框架字体为Consola set-frame-font

到目前为止,有14票赞成票,对票数反对的票数仍然没有答案,而欧盟科学仍然无法解决这一难题。


谢谢!您是否考虑过将其发布为对我上面的评论的回应,而不是单独的答案?
克莱门特

1
(我要澄清,我测试过,在Emacs的26,而你的答案似乎没有工作时:我使用(setq face-font-family-alternatives '(("Consolas" "FreeMono" "Symbola"))),然后M-x set-frame-font RET Consolas RET,字符使用索拉和UI的Segoe符号的组合)
克莱门特

我在Manjaro Arch Linux上测试了以下序列:ℕ𝓟⧺×≠≥≤±¬∨∧∃∀λ∨∧∃∀;我没有测试如果未安装某些字体会发生什么情况。有可能。因为字体名称是手动输入的,而不是从现有名称列表中输入的。
亚历山大·卡比夫尼奇

我对中安装的列表中的所有字体进行了测试emacs -Q
克莱门特

@Clémentemacs -Q选项带来了很多麻烦:--no-x-resources。也许问题出在其中。对我而言,Consolas仅从以下字符开始:“×”。还有前两个“ℕ𝓟” FreeMono和Symbola。
亚历山大·卡比夫尼奇

-1

M-x customize-variable face-font-family-alternatives

有一个看起来像这样的列表:

(("Monospace" "courier" "fixed")
 ("Monospace Serif" "Courier 10 Pitch" "Consolas" "Courier Std" "FreeMono" "courier" "fixed")
 ("courier" "CMU Typewriter Text" "fixed")
 ("Sans Serif" "helv" "helvetica" "arial" "fixed")
 ("helv" "helvetica" "arial" "fixed"))

customize缓冲区接口中添加序列:

("Consolas" "FreeMono" "Symbola")

如果指定了给定的字体系列,但不存在,则此变量指定要尝试的替代字体系列。每个元素应具有以下形式:

 (FAMILY ALTERNATE-FAMILIES...)

如果指定了FAMILY,但不可用,Emacs将逐个尝试ALTERNATE-FAMILIES中给定的其他家庭,直到找到确实存在的家庭。

如何使用 face-font-family-alternatives

在您的缓冲区中: M-x set-frame-font

从列表中选择一种字体。选择的字体将定义face-font-family-alternatives要使用的字体搜索顺序。在此示例中,Consolas

要检查用于显示字符的字体系列: M-x describe-char


谢谢!但是我认为这不能回答问题。AFAICT,如果Consolas字体不可用,建议的配置将使用FreeMono,但是对于Consolas不支持的字符,它不会回退到FreeMono。
克莱门特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.