From f408016c6ff6c3fe02f7b43125e6adb587a34bdb Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Fri, 4 Jun 2021 02:16:31 -0400 Subject: [PATCH] Rewrite how Doom scales font-size The previous approach only resized `doom-font`. Now it resizes `doom-variable-pitch-font` and `doom-serif-font` too, so variable-pitch, mixed-pitch, and fixed-serif users can enjoy dynamic font scaling. --- core/autoload/fonts.el | 164 ++++++++++++++++++++++++----------------- 1 file changed, 98 insertions(+), 66 deletions(-) diff --git a/core/autoload/fonts.el b/core/autoload/fonts.el index 93610bc668b..1eb0a923a9e 100644 --- a/core/autoload/fonts.el +++ b/core/autoload/fonts.el @@ -7,9 +7,9 @@ or `doom/decrease-font-size' are invoked.") ;;;###autoload (defvar doom-big-font nil - "The font to use for `doom-big-font-mode'. If nil, `doom-font' will be used, -scaled up by `doom-big-font-increment'. See `doom-font' for details on -acceptable values for this variable.") + "The font to use for `doom-big-font-mode'. +If nil, `doom-font' will be used, scaled up by `doom-big-font-increment'. See +`doom-font' for details on acceptable values for this variable.") ;;;###autoload (defvar doom-big-font-increment 4 @@ -20,47 +20,81 @@ acceptable values for this variable.") ;; ;;; Library -(defun doom--font-name (fontname) - (when (query-fontset fontname) - (when-let (ascii (assq 'ascii (aref (fontset-info fontname) 2))) - (setq fontname (nth 2 ascii)))) - (or (x-decompose-font-name fontname) - (error "Cannot decompose font name"))) +(defun doom--font2xlfd (font) + (cond ((stringp font) (aref (font-info font) 0)) + ((fontp font) (font-xlfd-name font)) + ((vectorp font) font))) -(defvar doom--font-scale nil) ;;;###autoload -(defun doom-adjust-font-size (increment) +(defun doom-adjust-font-size (increment &optional fixed-size-p font-alist) "Increase size of font in FRAME by INCREMENT. -FRAME parameter defaults to current frame." - (if (null increment) - (progn - (set-frame-font doom-font 'keep-size t) - (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))))) - t) - (let* ((font (frame-parameter nil 'font)) - (font (doom--font-name font)) - (increment (* increment doom-font-increment)) - (zoom-factor (or doom--font-scale 0))) - (let ((new-size (+ (string-to-number (aref font xlfd-regexp-pixelsize-subnum)) - increment))) - (unless (> new-size 0) - (error "Font is too small at %d" new-size)) - (aset font xlfd-regexp-pixelsize-subnum (number-to-string new-size))) - ;; Set point size & width to "*", so frame width will adjust to new font size - (aset font xlfd-regexp-pointsize-subnum "*") - (aset font xlfd-regexp-avgwidth-subnum "*") - (setq font (x-compose-font-name font)) - (unless (x-list-fonts font) - (error "Cannot change font size")) - (set-frame-font font 'keep-size t) - (setf (alist-get 'font default-frame-alist) font) - (setq doom--font-scale (+ zoom-factor increment)) - ;; Unlike `set-frame-font', `set-frame-parameter' won't trigger this - (run-hooks 'after-setting-font-hook)))) + +If FIXED-SIZE-P is non-nil, treat INCREMENT as a font size, rather than a +scaling factor. + +FONT-ALIST is an alist give temporary values to certain Doom font variables, +like `doom-font' or `doom-variable-pitch-font'. e.g. + + `((doom-font . ,(font-spec :family \"Sans Serif\" :size 12))) + +Doesn't work in terminal Emacs." + (unless (display-multi-font-p) + (user-error "Cannot resize fonts in terminal Emacs")) + (condition-case-unless-debug e + (let (changed) + (dolist (sym '((doom-font . default) + (doom-serif-font . fixed-pitch-serif) + (doom-variable-pitch-font . variable-pitch)) + (when changed + (doom-init-fonts-h 'reload) + t)) + (cl-destructuring-bind (var . face) sym + (if (null increment) + (when (get var 'initial-value) + (set var (get var 'initial-value)) + (put var 'new-size nil) + (put var 'initial-value nil) + (setq changed t)) + (let* ((orig-font (or (symbol-value var) + (face-font face t) + (with-temp-buffer (face-font face)))) + (font (doom--font2xlfd orig-font)) + (font (or (and (query-fontset font) + (if-let (ascii (assq 'ascii (aref (fontset-info font) 2))) + (nth 2 ascii) + font)) + font)) + (dfont (and (stringp font) (x-decompose-font-name font))) + (dfont (if-let* ((remap-font (alist-get var font-alist)) + (remap-xlfd (if (stringp remap-font) + (aref (font-info remap-font) 0) + (font-xlfd-name remap-font)))) + (x-decompose-font-name remap-xlfd) + dfont))) + (unless (get var 'initial-value) + (put var 'initial-value orig-font)) + (unless (vectorp dfont) + (error "Could not decompose %S font: %S" var font)) + (let* ((step (if fixed-size-p 0 (* increment doom-font-increment))) + (orig-size (string-to-number (aref dfont xlfd-regexp-pixelsize-subnum))) + (new-size (if fixed-size-p increment (+ orig-size step)))) + (unless (> new-size 0) + (error "`%s' font is too small to be reszied (%d)" var new-size)) + (if (= orig-size new-size) + (message "Could not resize `%s' for some reason" var) + (put var 'new-size new-size) + (aset dfont xlfd-regexp-pixelsize-subnum (number-to-string new-size)) + ;; Set point size & width to "*", so frame width will adjust to new font size + (aset dfont xlfd-regexp-pointsize-subnum "*") + (aset dfont xlfd-regexp-avgwidth-subnum "*") + (setq font (x-compose-font-name dfont)) + (unless (x-list-fonts font) + (error "Cannot change font size")) + (set var font) + (setq changed t)))))))) + (error + (ignore-errors (doom-adjust-font-size nil)) + (signal (car e) (cdr e))))) ;; @@ -74,16 +108,16 @@ See `doom-init-fonts-h'." (doom-init-fonts-h 'reload)) ;;;###autoload -(defun doom/increase-font-size (count) +(defun doom/increase-font-size (count &optional increment) "Enlargens the font size across the current and child frames." (interactive "p") - (doom-adjust-font-size count)) + (doom-adjust-font-size (* count (or increment doom-font-increment)))) ;;;###autoload -(defun doom/decrease-font-size (count) +(defun doom/decrease-font-size (count &optional increment) "Shrinks the font size across the current and child frames." (interactive "p") - (doom-adjust-font-size (- count))) + (doom-adjust-font-size (* (- count) (or increment doom-font-increment)))) ;;;###autoload (defun doom/reset-font-size () @@ -97,34 +131,32 @@ Assuming it has been adjusted via `doom/increase-font-size' and (/= text-scale-mode-amount 0)) (text-scale-set 0) (setq success t)) - (when (doom-adjust-font-size nil) - (setq success t)) + (cond (doom-big-font-mode + (message "Disabling `doom-big-font-mode'") + (doom-big-font-mode -1) + (setq success t)) + ((doom-adjust-font-size nil) + (setq success t))) (unless success (user-error "The font hasn't been resized")))) ;;;###autoload (define-minor-mode doom-big-font-mode - "A global mode that resizes the font, for streams, screen-sharing and -presentations. + "Globally resizes your fonts for streams, screen-sharing or presentations. + +Uses `doom-big-font' if its set, otherwise uses `doom-font' (falling back to +your system font). -This uses `doom/increase-font-size' under the hood, and enlargens the font by -`doom-big-font-increment'." +Also resizees `doom-variable-pitch-font' and `doom-serif-font'." :init-value nil :lighter " BIG" :global t - (unless doom-font - (or (setq doom-font (face-attribute 'default :font)) - (user-error "`doom-font' must be set to a valid font"))) (if doom-big-font - (let ((font (if doom-big-font-mode doom-big-font doom-font))) - (set-frame-font font 'keep-size t) - (setf (alist-get 'font default-frame-alist) - (cond ((stringp doom-font) font) - ((fontp font) (font-xlfd-name font)) - ((signal 'wrong-type-argument (list '(fontp stringp) - font)))))) - (doom-adjust-font-size - (and doom-big-font-mode - (integerp doom-big-font-increment) - (/= doom-big-font-increment 0) - doom-big-font-increment)))) + ;; Use `doom-big-font' in lieu of `doom-font' + (doom-adjust-font-size + (and doom-big-font-mode + (aref (x-decompose-font-name (doom--font2xlfd font)) + xlfd-regexp-pixelsize-subnum)) + t `((doom-font . ,doom-big-font))) + ;; Resize the current font + (doom-adjust-font-size (if doom-big-font-mode doom-big-font-increment))))