Improve unicode, emoji, & symbol font support

+ Adds doom-emoji-fallback-font-families
+ Adds doom-symbol-fallback-font-families
+ Gives doom-unicode-font higher precedence (and sets it to nil by
  default, since Emacs defaults to symbola already).
+ Store custom face settings in psuedo theme, rather than crowding the
  user theme (which may be immortalized to custom-file, which we want to
  avoid).
+ Now, after-setting-font-hook is guaranteed to fire after *all* fonts
  are set, giving you a more reliable interface to add your own
  font(set) modifications.

More testing is needed to ensure the patched fonts our ligatures modules
don't conflict with this change.
This commit is contained in:
Henrik Lissner 2021-05-06 04:06:19 -04:00
parent b63441387b
commit d4dec35658
3 changed files with 56 additions and 52 deletions

View file

@ -73,8 +73,7 @@ See `doom-init-fonts-h'."
(interactive) (interactive)
(when doom-font (when doom-font
(set-frame-font doom-font t)) (set-frame-font doom-font t))
(doom-init-fonts-h) (doom-init-fonts-h))
(mapc #'doom-init-extra-fonts-h (frame-list)))
;;;###autoload ;;;###autoload
(defun doom/increase-font-size (count) (defun doom/increase-font-size (count)
@ -116,7 +115,8 @@ This uses `doom/increase-font-size' under the hood, and enlargens the font by
:lighter " BIG" :lighter " BIG"
:global t :global t
(unless doom-font (unless doom-font
(user-error "`doom-font' must be set to a valid font")) (or (setq doom-font (face-attribute 'default :font))
(user-error "`doom-font' must be set to a valid font")))
(if doom-big-font (if doom-big-font
(let ((font (if doom-big-font-mode doom-big-font doom-font))) (let ((font (if doom-big-font-mode doom-big-font doom-font)))
(set-frame-font font 'keep-size t) (set-frame-font font 'keep-size t)

View file

@ -35,10 +35,7 @@ Must be a `font-spec', a font object, an XFT font string, or an XLFD string. See
An omitted font size means to inherit `doom-font''s size.") An omitted font size means to inherit `doom-font''s size.")
(defvar doom-unicode-font (defvar doom-unicode-font nil
(if IS-MAC
(font-spec :family "Apple Color Emoji")
(font-spec :family "Symbola"))
"Fallback font for Unicode glyphs. "Fallback font for Unicode glyphs.
Must be a `font-spec', a font object, an XFT font string, or an XLFD string. See Must be a `font-spec', a font object, an XFT font string, or an XLFD string. See
`doom-font' for examples. `doom-font' for examples.
@ -47,8 +44,17 @@ The defaults on macOS and Linux are Apple Color Emoji and Symbola, respectively.
An omitted font size means to inherit `doom-font''s size.") An omitted font size means to inherit `doom-font''s size.")
(defvar doom-unicode-extra-fonts nil (defvar doom-emoji-fallback-font-families
"Fonts to inject into the Unicode charset before `doom-unicode-font'.") '("Apple Color Emoji"
"Segoe UI Emoji"
"Noto Color Emoji"
"Noto Emoji")
"A list of fallback font families to use for emojis.")
(defvar doom-symbol-fallback-font-families
'("Segoe UI Symbol"
"Apple Symbols")
"A list of fallback font families for general symbol glyphs.")
;; ;;
@ -484,13 +490,15 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
all-the-icons-material all-the-icons-material
all-the-icons-alltheicon) all-the-icons-alltheicon)
:preface :preface
(setq doom-unicode-extra-fonts (add-hook! 'after-setting-font-hook
(list "Weather Icons" (defun doom-init-all-the-icons-fonts-h ()
"github-octicons" (dolist (font (list "Weather Icons"
"FontAwesome" "github-octicons"
"all-the-icons" "FontAwesome"
"file-icons" "all-the-icons"
"Material Icons")) "file-icons"
"Material Icons"))
(set-fontset-font t 'unicode font nil 'append))))
:config :config
(cond ((daemonp) (cond ((daemonp)
(defadvice! doom--disable-all-the-icons-in-tty-a (orig-fn &rest args) (defadvice! doom--disable-all-the-icons-in-tty-a (orig-fn &rest args)
@ -575,44 +583,34 @@ behavior). Do not set this directly, this is let-bound in `doom-init-theme-h'.")
(defun doom-init-fonts-h () (defun doom-init-fonts-h ()
"Loads `doom-font'." "Loads `doom-font'."
(when (fboundp 'set-fontset-font)
(let ((fn (doom-rpartial #'member (font-family-list))))
(when-let (font (cl-find-if fn doom-symbol-fallback-font-families))
(set-fontset-font t 'symbol font))
(when-let (font (cl-find-if fn doom-emoji-fallback-font-families))
(set-fontset-font t 'unicode font))
(when doom-unicode-font
(set-fontset-font t 'unicode doom-unicode-font))))
(apply #'custom-theme-set-faces 'doom
(append (when doom-font
`((fixed-pitch ((t (:font ,doom-font))))))
(when doom-serif-font
`((fixed-pitch-serif ((t (:font ,doom-serif-font))))))
(when doom-variable-pitch-font
`((variable-pitch ((t (:font ,doom-variable-pitch-font))))))))
(cond (cond
(doom-font (doom-font
(cl-pushnew ;; I avoid `set-frame-font' because it does a lot of extra, expensive work
;; Avoiding `set-frame-font' because it does a lot of extra, expensive ;; we can avoid by setting the font frame parameter directly.
;; work we can avoid by setting the font frame parameter instead. (setf (alist-get 'font default-frame-alist)
(cons 'font (cond ((stringp doom-font) doom-font)
(cond ((stringp doom-font) doom-font) ((fontp doom-font) (font-xlfd-name doom-font))
((fontp doom-font) (font-xlfd-name doom-font)) ((signal 'wrong-type-argument (list '(fontp stringp)
((signal 'wrong-type-argument (list '(fontp stringp) doom-font))))))
doom-font)))))
default-frame-alist
:key #'car :test #'eq))
((display-graphic-p) ((display-graphic-p)
;; We try our best to record your system font, so `doom-big-font-mode' (setq font-use-system-font t)))
;; can still use it to compute a larger font size with. ;; Give users a chance to inject their own font logic.
(setq font-use-system-font t (run-hooks 'after-setting-font-hook))
doom-font (face-attribute 'default :font)))))
(defun doom-init-extra-fonts-h (&optional frame)
"Loads `doom-variable-pitch-font',`doom-serif-font' and `doom-unicode-font'."
(condition-case e
(with-selected-frame (or frame (selected-frame))
(when doom-font
(set-face-attribute 'fixed-pitch nil :font doom-font))
(when doom-serif-font
(set-face-attribute 'fixed-pitch-serif nil :font doom-serif-font))
(when doom-variable-pitch-font
(set-face-attribute 'variable-pitch nil :font doom-variable-pitch-font))
(when (fboundp 'set-fontset-font)
(dolist (font (remq nil (cons doom-unicode-font doom-unicode-extra-fonts)))
(set-fontset-font t 'unicode font nil 'prepend)))
(run-hooks 'after-setting-font-hook))
((debug error)
(if (string-prefix-p "Font not available: " (error-message-string e))
(lwarn 'doom-ui :warning
"Could not find the '%s' font on your system, falling back to system font"
(font-get (caddr e) :family))
(signal 'doom-error e)))))
(defun doom-init-theme-h (&optional frame) (defun doom-init-theme-h (&optional frame)
"Load the theme specified by `doom-theme' in FRAME." "Load the theme specified by `doom-theme' in FRAME."
@ -701,7 +699,6 @@ This offers a moderate boost in startup (or theme switch) time, so long as
;; Apply `doom-font' et co ;; Apply `doom-font' et co
(add-hook 'doom-after-init-modules-hook #'doom-init-fonts-h) (add-hook 'doom-after-init-modules-hook #'doom-init-fonts-h)
(add-hook 'doom-load-theme-hook #'doom-init-extra-fonts-h)
;; Apply `doom-theme' ;; Apply `doom-theme'
(add-hook (if (daemonp) (add-hook (if (daemonp)

View file

@ -61,6 +61,13 @@ envvar will enable this at startup.")
(define-error 'doom-private-error "Error in private config" 'doom-error) (define-error 'doom-private-error "Error in private config" 'doom-error)
(define-error 'doom-package-error "Error with packages" 'doom-error) (define-error 'doom-package-error "Error with packages" 'doom-error)
;;; Declare a psuedo theme to store faces and variables in, with no risk of it
;;; getting saved to `custom-file', or accidentally overwritten by user config.
(custom-declare-theme 'doom nil)
(enable-theme 'doom)
;; But immediately hide it, because it's not a real theme.
(setq custom-enabled-themes (remq 'doom custom-enabled-themes))
;; ;;
;;; Directory variables ;;; Directory variables