3

There are two widely used interfaces that can change fonts in Emacs:

  • set-face-attribute
  • set-fontset-font.

If I understand correctly set-face-attribute can set main font (or default font) and set-fontset-font sets alternative fonts (or font fallback) for specific code range.

The problem is that if there is a code point that has a glyph in main font, that code point will never be overridden by set-fontset-font.

The following is the example (in Emacs 29.3):

;; init.el

;; Set main font
(set-face-attribute 'default nil :font (font-spec :family "Courier New" :size 14))

;; Set alternative font for symbols
(set-fontset-font t 'symbol (font-spec :family "Segoe UI Symbol" :size 24) nil nil)

;; Test characters display:
;; ∀
;; ∑

enter image description here

Notice that

  • Both '∀' and '∑' are in Emacs' symbol script.

  • '∀' is bigger than '∑'. This is because '∀' is using (font-spec :family "Segoe UI Symbol" :size 24) while '∑' is using (font-spec :family "Courier New" :size 14).

It is obviously not a good thing, since (1) breaks symbol script semantics (2) it makes symbol characters display inconsistent!

  • If you open Courier New by some font tool, you will see that it has a glyph for '∑' in Mathematical Operators block (17/256), but has not '∀'.

  • If you open Segoe UI Symbol by some font tool, you will see that it has both glyphs for '∑' and '∀' in Mathematical Operators block (256/256).

The expected behavior for (set-fontset-font t script (font-spec :family "Segoe UI Symbol" :size 24) nil nil) is that it can override all glyphs for code points in symbol script. However, the current behavior only overrides glyphs for those who are not in main font (so it's really just a fallback?).

How to achieve the expected behavior? i.e. make all characters in symbol script use Segoe UI Symbol (including those are in main font, e.g. '∑')?

P.s. I have tried to remove some glyphs in font Courier New via some font tool (only keeps ASCII characters) and it works:

;; init.el

;; Set main font which is ASCII Only 
(set-face-attribute 'default nil :font (font-spec :family "ASCII Only Courier New" :size 14))

;; Set alternative font for symbols
(set-fontset-font t 'symbol (font-spec :family "Segoe UI Symbol" :size 24) nil nil)

;; Test characters display:
;; ∀
;; ∑

enter image description here

But it is obviously not a good way. Also, the ASCII characters would show more lighter than before (it is may be an side effect caused by editing Courier New, I haven't looked into it deeper though).

2
  • What happens if you do (setq use-default-font-for-symbols nil)?
    – rpluim
    Commented Apr 18 at 11:54
  • @rpluim It solved the problem! I wasn't aware of this variable before. Could you kindly provide a formal answer? Thank you so much.
    – chansey
    Commented Apr 18 at 16:38

1 Answer 1

2

Emacs will ignore a fontset configured for characters in the symbol script that can be displayed by the default face's font, unless you set use-default-font-for-symbols to nil.

C-h v use-default-font-for-symbols

use-default-font-for-symbols is a variable defined in `C source code'.

Its value is t

If non-nil, use the default face's font for symbols and punctuation.

By default, Emacs will try to use the default face's font for displaying symbol and punctuation characters, disregarding the fontsets, if the default font can display the character. Set this to nil to make Emacs honor the fontsets instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.