fix: set face :font instead of frame font parameter

Information is lost when converting font-spec's to xlfd strings (mainly,
DPI), in order to make them compatible with the face frame parameter. To
avoid this, we set the faces' :font attribute instead, which natively
accept font specs, xlfd strings, font objects, and xft strings; no
conversion necessary.

Fix: #6131
This commit is contained in:
Henrik Lissner 2022-02-20 03:36:56 +01:00
parent f51a2cdd3a
commit 8c03fa0e3d
No known key found for this signature in database
GPG key ID: B60957CA074D39A3

View file

@ -17,7 +17,8 @@ This affects the `default' and `fixed-pitch' faces.
Examples:
(setq doom-font (font-spec :family \"Fira Mono\" :size 12))
(setq doom-font \"Terminus (TTF):pixelsize=12:antialias=off\")")
(setq doom-font \"Terminus (TTF):pixelsize=12:antialias=off\")
(setq doom-font \"Fira Code-14\")")
(defvar doom-variable-pitch-font nil
"The default font to use for variable-pitch text.
@ -523,8 +524,41 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
(cons 'custom-theme-directory
(delq 'custom-theme-directory custom-theme-load-path)))
(defun doom--make-font-specs (face font &optional base-specs)
(let* ((base-specs (cadr (assq 'user (get face 'theme-face))))
(base-specs (or base-specs '((t nil))))
(attrs '(:family :foundry :slant :weight :height :width))
(new-specs nil))
(dolist (spec base-specs)
;; Each SPEC has the form (DISPLAY ATTRIBUTE-PLIST)
(let ((display (car spec))
(plist (copy-tree (nth 1 spec))))
;; Alter only DISPLAY conditions matching this frame.
(when (or (memq display '(t default))
(face-spec-set-match-display display this-frame))
(dolist (attr attrs)
(setq plist (plist-put plist attr (face-attribute face attr)))))
(push (list display plist) new-specs)))
(nreverse new-specs)))
(defun doom-init-fonts-h (&optional reload)
"Loads `doom-font'."
(dolist (map `((default . ,doom-font)
(fixed-pitch . ,doom-font)
(fixed-pitch-serif . ,doom-serif-font)
(variable-pitch . ,doom-variable-pitch-font)))
(when-let* ((face (car map))
(font (cdr map)))
(dolist (frame (frame-list))
(when (display-multi-font-p frame)
(set-face-attribute face frame
:width 'normal :weight 'normal
:slant 'normal :font font)))
(let ((new-specs (doom--make-font-specs face font)))
;; Don't save to `customized-face' so it's omitted from `custom-file'
;;(put face 'customized-face new-specs)
(custom-push-theme 'theme-face face 'user 'set new-specs)
(put face 'face-modified nil))))
(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))
@ -533,31 +567,7 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
(set-fontset-font t 'unicode font))
(when doom-unicode-font
(set-fontset-font t 'unicode doom-unicode-font))))
(apply #'custom-set-faces
(let ((attrs '(:weight unspecified :slant unspecified :width unspecified)))
(append (when doom-font
`((fixed-pitch ((t (:font ,doom-font ,@attrs))))))
(when doom-serif-font
`((fixed-pitch-serif ((t (:font ,doom-serif-font ,@attrs))))))
(when doom-variable-pitch-font
`((variable-pitch ((t (:font ,doom-variable-pitch-font ,@attrs)))))))))
;; Never save these settings to `custom-file'
(dolist (sym '(fixed-pitch fixed-pitch-serif variable-pitch))
(put sym 'saved-face nil))
(cond
(doom-font
(when (or reload (daemonp))
(set-frame-font doom-font t t))
;; I avoid `set-frame-font' at startup because it is expensive; doing extra,
;; unnecessary work we can avoid by setting the frame parameter directly.
(setf (alist-get 'font default-frame-alist)
(cond ((stringp doom-font) doom-font)
((fontp doom-font) (font-xlfd-name doom-font))
((signal 'wrong-type-argument
(list '(fontp stringp) doom-font))))))
((display-graphic-p)
(setq font-use-system-font t)))
;; Give users a chance to inject their own font logic.
;; Users should inject their own font logic in `after-setting-font-hook'
(run-hooks 'after-setting-font-hook))
(defun doom-init-theme-h (&rest _)