about summary refs log tree commit diff stats
path: root/lisp/acdw-fonts.el
blob: 0fce172eeb0ad6ad8b27822308eb4283445460d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
;;; acdw-fonts.el -- font setup -*- lexical-binding: t; coding: utf-8-unix -*-

;; Author: Case Duckworth <(rot13-string "npqj@npqj.arg")>
;; Created: Sometime during Covid-19, 2020
;; Keywords: configuration
;; URL: https://tildegit.org/acdw/emacs

;; This file is NOT part of GNU Emacs.

;; Everyone is permitted to do whatever with this software, without
;; limitation.  This software comes without any warranty whatsoever,
;; but with two pieces of advice:
;; - Don't hurt yourself.
;; - Make good choices.

;;; Commentary:
;; This code is based heavily on (and in fact, until I am able to tweak it,
;; will be a copy of) Oliver Taylor's code, available here:
;; https://github.com/olivertaylor/olivertaylor.github.io
;; /blob/master/notes/20210324_emacs-optical-font-adjustment.org

;;; Code:


;; Variables

(defvar acdw-fonts/monospace nil
  "Monospace font to be used for `default' and `fixed-pitch' faces.")

(defvar acdw-fonts/variable nil
  "Variable font to be used for the `variable-pitch' face.")

(defvar acdw-fonts/monospace-size 11
  "Font size, an integer, to be used for the `default' and `fixed-pitch' faces.

This value is multiplied by 10, so 12 becomes 120, in order to
comply with Emacs's `set-face-attribute' requirements.")

(defvar acdw-fonts/variable-size 12
  "Font size, an integer, to be used for the `variable-pitch' face.

This value will be used to determine a relative (float) size
based on the default size.  So if your default size is 12 and
your variable size is 14, the computed relative size will be
1.16.")


;; Functions

(defun acdw-fonts/set ()
  "Set fonts according to `acdw-fonts' variables."
  (interactive)
  (set-face-attribute 'default nil
                      :family acdw-fonts/monospace
                      :height (* acdw-fonts/monospace-size 10))
  (set-face-attribute 'fixed-pitch nil
                      :family acdw-fonts/monospace
                      :height 1.0)
  (set-face-attribute 'variable-pitch nil
                      :family acdw-fonts/variable
                      :height 1.0))


;;; Larger Variable Pitch Mode


;; A minor mode to scale the variable-pitch face up to the height defined in
;; `acdw-fonts/variable-size' and the fixed-pitch face down to the height
;; defined in `acdw-fonts/monospace-size', buffer locally. This mode should
;; be enabled wherever you want to adjust face sizes, perhaps with a hook.

(make-variable-buffer-local
 (defvar larger-variable-pitch-mode-status nil
   "Status of the larger-variable-pitch-mode"))

(make-variable-buffer-local
 (defvar variable-pitch-remapping nil
   "variable-pitch remapping cookie for larger-variable-pitch-mode."))

(make-variable-buffer-local
 (defvar fixed-pitch-remapping nil
   "fixed-pitch remapping cookie for larger-variable-pitch-mode"))

(defun larger-variable-pitch-mode-toggle ()
  (setq larger-variable-pitch-mode-status
        (not larger-variable-pitch-mode-status))
  (if larger-variable-pitch-mode-status
      (progn
        (setq variable-pitch-remapping
              (face-remap-add-relative
               'variable-pitch :height (/ (float acdw-fonts/variable-size)
                                          (float acdw-fonts/monospace-size))))
        (setq fixed-pitch-remapping
              (face-remap-add-relative
               'fixed-pitch :height (/ (float acdw-fonts/monospace-size)
                                       (float acdw-fonts/variable-size))))
        (force-window-update (current-buffer)))
    (progn
      (face-remap-remove-relative variable-pitch-remapping)
      (face-remap-remove-relative fixed-pitch-remapping))))

(define-minor-mode larger-variable-pitch-mode
  "Minor mode to scale the variable- and fixed-pitch faces up and down."
  :init-value nil
  :lighter " V+"
  (larger-variable-pitch-mode-toggle))

(defun acdw-fonts/buffer-face-hook ()
  "Activate and deactivate larger-variable-pitch-mode minor mode."
  (if buffer-face-mode
      (larger-variable-pitch-mode 1)
    (larger-variable-pitch-mode -1)))

(add-hook 'buffer-face-mode-hook #'acdw-fonts/buffer-face-hook)


;;; Emoji fonts
;; from https://old.reddit.com/r/emacs/comments/mvlid5/

(defun acdw-fonts/setup-emoji-fonts (&rest emoji-fonts)
  "For all EMOJI-FONTS that exist, add them to the symbol fontset.

This is for emoji fonts."
  (let ((ffl (font-family-list)))
    (dolist (font emoji-fonts)
      (when (member font ffl)
        (set-fontset-font t 'symbol
                          (font-spec :family font) nil 'append)))))


;;; Variable-pitch
;; from https://github.com/turbana/emacs-config#variable-pitch

(defcustom acdw-fonts/fixed-pitch-faces '(linum
                                          org-block
                                          org-block-begin-line
                                          org-block-end-line
                                          org-checkbox
                                          org-code
                                          org-date
                                          org-document-info-keyword
                                          org-hide
                                          org-indent
                                          org-link
                                          org-meta-line
                                          org-special-keyword
                                          org-table
                                          whitespace-space)
  "Faces to keep fixed-pitch in `acdw/variable-pitch-mode'."
  :type 'sexp
  :group 'faces)

(defun acdw-fonts//variable-pitch-add-inherit (attrs parent)
  "Add `:inherit PARENT' to ATTRS unless already present.
Handles cases where `:inherit' is already specified."
  (let ((current-parent (plist-get attrs :inherit)))
    (unless (or (eq parent current-parent)
                (and (listp current-parent)
                     (member parent current-parent)))
      (plist-put attrs :inherit (if current-parent
                                    (list current-parent parent)
                                  parent)))))

(defun acdw-fonts/adapt-variable-pitch ()
  "Adapt `variable-pitch-mode' to keep some fonts fixed-pitch."
  (when variable-pitch-mode
    (mapc (lambda (face)
            (when (facep face)
              (apply #'set-face-attribute
                     face nil (acdw-fonts//variable-pitch-add-inherit
                               (face-attr-construct face)
                               'fixed-pitch))))
          acdw-fonts/fixed-pitch-faces)))

(provide 'acdw-fonts)
;;; acdw-fonts.el ends here