diff options
| author | Gerd Moellmann | 1999-07-21 21:43:52 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 1999-07-21 21:43:52 +0000 |
| commit | 5f5c8ee54adcf263da9c3dcc1db243b26724c04d (patch) | |
| tree | f18b5a842b4abf31ec7c4480e8c0df7cacec99b3 /lisp | |
| parent | 7eb0330213eae25cac6204a2c97a737e7c501bf8 (diff) | |
| download | emacs-5f5c8ee54adcf263da9c3dcc1db243b26724c04d.tar.gz emacs-5f5c8ee54adcf263da9c3dcc1db243b26724c04d.zip | |
Complete rewrite.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/faces.el | 2758 |
1 files changed, 1347 insertions, 1411 deletions
diff --git a/lisp/faces.el b/lisp/faces.el index dfc6cf025d9..bc90e7203b2 100644 --- a/lisp/faces.el +++ b/lisp/faces.el | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | ;;; faces.el --- Lisp interface to the c "face" structure | 1 | ;;; faces.el --- Lisp faces |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998 |
| 4 | ;; Free Software Foundation, Inc. | ||
| 4 | 5 | ||
| 5 | ;; This file is part of GNU Emacs. | 6 | ;; This file is part of GNU Emacs. |
| 6 | 7 | ||
| @@ -21,740 +22,1435 @@ | |||
| 21 | 22 | ||
| 22 | ;;; Commentary: | 23 | ;;; Commentary: |
| 23 | 24 | ||
| 24 | ;; Mostly derived from Lucid. | ||
| 25 | |||
| 26 | ;;; Code: | 25 | ;;; Code: |
| 27 | 26 | ||
| 28 | (eval-when-compile | 27 | (eval-when-compile |
| 29 | ;; These used to be defsubsts, now they're subrs. Avoid losing if we're | 28 | (require 'custom) |
| 30 | ;; being compiled with an old Emacs that still has defsubrs in it. | 29 | (require 'cl)) |
| 31 | (put 'face-name 'byte-optimizer nil) | 30 | |
| 32 | (put 'face-id 'byte-optimizer nil) | 31 | (require 'cus-face) |
| 33 | (put 'face-font 'byte-optimizer nil) | 32 | |
| 34 | (put 'face-font-explicit 'byte-optimizer nil) | 33 | |
| 35 | (put 'face-foreground 'byte-optimizer nil) | 34 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 36 | (put 'face-background 'byte-optimizer nil) | 35 | ;;; Font selection. |
| 37 | (put 'face-stipple 'byte-optimizer nil) | 36 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 38 | (put 'face-underline-p 'byte-optimizer nil) | 37 | |
| 39 | (put 'set-face-font 'byte-optimizer nil) | 38 | (defgroup font-selection nil |
| 40 | (put 'set-face-font-auto 'byte-optimizer nil) | 39 | "Influencing face font selection." |
| 41 | (put 'set-face-foreground 'byte-optimizer nil) | 40 | :group 'faces) |
| 42 | (put 'set-face-background 'byte-optimizer nil) | 41 | |
| 43 | (put 'set-face-stipple 'byte-optimizer nil) | 42 | |
| 44 | (put 'set-face-underline-p 'byte-optimizer nil)) | 43 | (defcustom face-font-selection-order |
| 44 | '(:width :height :weight :slant) | ||
| 45 | "*A list specifying how face font selection chooses fonts. | ||
| 46 | Each of the four symbols `:width', `:height', `:weight', and `:slant' | ||
| 47 | must appear once in the list, and the list must not contain any other | ||
| 48 | elements. Font selection tries to find a best matching font for | ||
| 49 | those face attributes first that appear first in the list. For | ||
| 50 | example, if `:slant' appears before `:height', font selection first | ||
| 51 | tries to find a font with a suitable slant, even if this results in | ||
| 52 | a font height that isn't optimal." | ||
| 53 | :tag "Font selection order." | ||
| 54 | :group 'font-selection | ||
| 55 | :set #'(lambda (symbol value) | ||
| 56 | (set-default symbol value) | ||
| 57 | (internal-set-font-selection-order value))) | ||
| 58 | |||
| 59 | |||
| 60 | (defcustom face-font-family-alternatives | ||
| 61 | '(("courier" "fixed") | ||
| 62 | ("helv" "helvetica" "fixed")) | ||
| 63 | "*Alist of alternative font family names. | ||
| 64 | Each element has the the form (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...). | ||
| 65 | If fonts of family FAMILY can't be loaded, try ALTERNATIVE1, then | ||
| 66 | ALTERNATIVE2 etc." | ||
| 67 | :tag "Alternative font families to try." | ||
| 68 | :group 'font-selection | ||
| 69 | :set #'(lambda (symbol value) | ||
| 70 | (set-default symbol value) | ||
| 71 | (internal-set-alternative-font-family-alist value))) | ||
| 72 | |||
| 73 | |||
| 74 | |||
| 75 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 76 | ;;; Creation, copying. | ||
| 77 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 78 | |||
| 79 | |||
| 80 | (defun face-list () | ||
| 81 | "Return a list of all defined face names." | ||
| 82 | (mapcar #'car face-new-frame-defaults)) | ||
| 83 | |||
| 84 | |||
| 85 | ;;; ### If not frame-local initialize by what X resources? | ||
| 86 | |||
| 87 | (defun make-face (face &optional no-init-from-resources) | ||
| 88 | "Define a new face with name FACE, a symbol. | ||
| 89 | NO-INIT-FROM-RESOURCES non-nil means don't initialize frame-local | ||
| 90 | variants of FACE from X resources. (X resources recognized are found | ||
| 91 | in the global variable `face-x-resources'.) If FACE is already known | ||
| 92 | as a face, leave it unmodified. Value is FACE." | ||
| 93 | (interactive "SMake face: ") | ||
| 94 | (unless (facep face) | ||
| 95 | ;; Make frame-local faces (this also makes the global one). | ||
| 96 | (dolist (frame (frame-list)) | ||
| 97 | (internal-make-lisp-face face frame)) | ||
| 98 | ;; Add the face to the face menu. | ||
| 99 | (when (fboundp 'facemenu-add-new-face) | ||
| 100 | (facemenu-add-new-face face)) | ||
| 101 | ;; Define frame-local faces for all frames from X resources. | ||
| 102 | (unless no-init-from-resources | ||
| 103 | (make-face-x-resource-internal face))) | ||
| 104 | face) | ||
| 105 | |||
| 106 | |||
| 107 | (defun make-empty-face (face) | ||
| 108 | "Define a new, empty face with name FACE. | ||
| 109 | If the face already exists, it is left unmodified. Value is FACE." | ||
| 110 | (interactive "SMake empty face: ") | ||
| 111 | (make-face face 'no-init-from-resources)) | ||
| 112 | |||
| 113 | |||
| 114 | (defun copy-face (old-face new-face &optional frame new-frame) | ||
| 115 | "Define a face just like OLD-FACE, with name NEW-FACE. | ||
| 116 | |||
| 117 | If NEW-FACE already exists as a face, it is modified to be like | ||
| 118 | OLD-FACE. If it doesn't already exist, it is created. | ||
| 119 | |||
| 120 | If the optional argument FRAME is given as a frame, NEW-FACE is | ||
| 121 | changed on FRAME only. | ||
| 122 | If FRAME is t, the frame-independent default specification for OLD-FACE | ||
| 123 | is copied to NEW-FACE. | ||
| 124 | If FRAME is nil, copying is done for the frame-independent defaults | ||
| 125 | and for each existing frame. | ||
| 126 | |||
| 127 | If the optional fourth argument NEW-FRAME is given, | ||
| 128 | copy the information from face OLD-FACE on frame FRAME | ||
| 129 | to NEW-FACE on frame NEW-FRAME." | ||
| 130 | (let ((inhibit-quit t)) | ||
| 131 | (if (null frame) | ||
| 132 | (progn | ||
| 133 | (dolist (frame (frame-list)) | ||
| 134 | (copy-face old-face new-face frame)) | ||
| 135 | (copy-face old-face new-face t)) | ||
| 136 | (internal-copy-lisp-face old-face new-face frame new-frame)) | ||
| 137 | new-face)) | ||
| 138 | |||
| 139 | |||
| 140 | |||
| 141 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 142 | ;;; Obsolete functions | ||
| 143 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 144 | |||
| 145 | ;; The functions in this section are defined because Lisp packages use | ||
| 146 | ;; them, despite the prefix `internal-' suggesting that they are | ||
| 147 | ;; private to the face implementation. | ||
| 148 | |||
| 149 | (defun internal-find-face (name &optional frame) | ||
| 150 | "Retrieve the face named NAME. | ||
| 151 | Return nil if there is no such face. | ||
| 152 | If the optional argument FRAME is given, this gets the face NAME for | ||
| 153 | that frame; otherwise, it uses the selected frame. | ||
| 154 | If FRAME is the symbol t, then the global, non-frame face is returned. | ||
| 155 | If NAME is already a face, it is simply returned. | ||
| 156 | |||
| 157 | This function is defined for compatibility with Emacs 20.2. It | ||
| 158 | should not be used anymore." | ||
| 159 | (facep name)) | ||
| 160 | |||
| 161 | |||
| 162 | (defun internal-get-face (name &optional frame) | ||
| 163 | "Retrieve the face named NAME; error if there is none. | ||
| 164 | If the optional argument FRAME is given, this gets the face NAME for | ||
| 165 | that frame; otherwise, it uses the selected frame. | ||
| 166 | If FRAME is the symbol t, then the global, non-frame face is returned. | ||
| 167 | If NAME is already a face, it is simply returned. | ||
| 168 | |||
| 169 | This function is defined for compatibility with Emacs 20.2. It | ||
| 170 | should not be used anymore." | ||
| 171 | (or (internal-find-face name frame) | ||
| 172 | (check-face name))) | ||
| 173 | |||
| 174 | |||
| 175 | |||
| 176 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 177 | ;;; Predicates, type checks. | ||
| 178 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 179 | |||
| 180 | (defun facep (face) | ||
| 181 | "Return non-nil if FACE is a face name." | ||
| 182 | (internal-lisp-face-p face)) | ||
| 183 | |||
| 184 | |||
| 185 | (defun check-face (face) | ||
| 186 | "Signal an error if FACE doesn't name a face. | ||
| 187 | Value is FACE." | ||
| 188 | (unless (facep face) | ||
| 189 | (error "Not a face: %s" face)) | ||
| 190 | face) | ||
| 191 | |||
| 192 | |||
| 193 | ;; The ID returned is not to be confused with the internally used IDs | ||
| 194 | ;; of realized faces. The ID assigned to Lisp faces is used to | ||
| 195 | ;; support faces in display table entries. | ||
| 196 | |||
| 197 | (defun face-id (face &optional frame) | ||
| 198 | "Return the interNal ID of face with name FACE. | ||
| 199 | If optional argument FRAME is nil or omitted, use the selected frame." | ||
| 200 | (check-face face) | ||
| 201 | (get face 'face)) | ||
| 202 | |||
| 203 | |||
| 204 | (defun face-equal (face1 face2 &optional frame) | ||
| 205 | "Non-nil if faces FACE1 and FACE2 are equal. | ||
| 206 | Faces are considered equal if all their attributes are equal. | ||
| 207 | If the optional argument FRAME is given, report on face FACE in that frame. | ||
| 208 | If FRAME is t, report on the defaults for face FACE (for new frames). | ||
| 209 | If FRAME is omitted or nil, use the selected frame." | ||
| 210 | (internal-lisp-face-equal-p face1 face2 frame)) | ||
| 211 | |||
| 212 | |||
| 213 | (defun face-differs-from-default-p (face &optional frame) | ||
| 214 | "Non-nil if FACE displays differently from the default face. | ||
| 215 | If the optional argument FRAME is given, report on face FACE in that frame. | ||
| 216 | If FRAME is t, report on the defaults for face FACE (for new frames). | ||
| 217 | If FRAME is omitted or nil, use the selected frame. | ||
| 218 | A face is considered to be ``the same'' as the default face if it is | ||
| 219 | actually specified in the same way (equal attributes) or if it is | ||
| 220 | fully-unspecified, and thus inherits the attributes of any face it | ||
| 221 | is displayed on top of." | ||
| 222 | (or (internal-lisp-face-empty-p face frame) | ||
| 223 | (not (internal-lisp-face-equal-p face 'default frame)))) | ||
| 224 | |||
| 225 | |||
| 226 | (defun face-nontrivial-p (face &optional frame) | ||
| 227 | "True if face FACE has some non-nil attribute. | ||
| 228 | If the optional argument FRAME is given, report on face FACE in that frame. | ||
| 229 | If FRAME is t, report on the defaults for face FACE (for new frames). | ||
| 230 | If FRAME is omitted or nil, use the selected frame." | ||
| 231 | (not (internal-lisp-face-empty-p face frame))) | ||
| 232 | |||
| 233 | |||
| 45 | 234 | ||
| 46 | ;;;; Functions for manipulating face vectors. | 235 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 47 | 236 | ;;; Setting face attributes from X resources. | |
| 48 | ;;; A face vector is a vector of the form: | 237 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 49 | ;;; [face NAME ID FONT FOREGROUND BACKGROUND STIPPLE | 238 | |
| 50 | ;;; UNDERLINE-P INVERSE-VIDEO-P FONT-EXPLICIT-P BOLD-P ITALIC-P] | 239 | (defcustom face-x-resources |
| 51 | 240 | '((:family (".attributeFamily" . "Face.AttributeFamily")) | |
| 52 | ;;; Type checkers. | 241 | (:width (".attributeWidth" . "Face.AttributeWidth")) |
| 53 | (defsubst internal-facep (x) | 242 | (:height (".attributeHeight" . "Face.AttributeHeight")) |
| 54 | (and (vectorp x) (= (length x) 12) (eq (aref x 0) 'face))) | 243 | (:weight (".attributeWeight" . "Face.AttributeWeight")) |
| 55 | 244 | (:slant (".attributeSlant" . "Face.AttributeSlant")) | |
| 56 | (defun facep (x) | 245 | (:foreground (".attributeForeground" . "Face.AttributeForeground")) |
| 57 | "Return t if X is a face name or an internal face vector." | 246 | (:background (".attributeBackground" . "Face.AttributeBackground")) |
| 58 | (and (or (internal-facep x) | 247 | (:overline (".attributeOverline" . "Face.AttributeOverline")) |
| 59 | (and (symbolp x) (assq x global-face-data))) | 248 | (:strike-through (".attributeStrikeThrough" . "Face.AttributeStrikeThrough")) |
| 60 | t)) | 249 | (:box (".attributeBox" . "Face.AttributeBox")) |
| 61 | 250 | (:underline (".attributeUnderline" . "Face.AttributeUnderline")) | |
| 62 | (defmacro internal-check-face (face) | 251 | (:inverse-video (".attributeInverse" . "Face.AttributeInverse")) |
| 63 | (` (or (internal-facep (, face)) | 252 | (:stipple |
| 64 | (signal 'wrong-type-argument (list 'internal-facep (, face)))))) | 253 | (".attributeStipple" . "Face.AttributeStipple") |
| 65 | 254 | (".attributeBackgroundPixmap" . "Face.AttributeBackgroundPixmap")) | |
| 66 | ;;; Accessors. | 255 | (:font (".attributeFont" . "Face.AttributeFont")) |
| 256 | (:bold (".attributeBold" . "Face.AttributeBold")) | ||
| 257 | (:italic (".attributeItalic" . "Face.AttributeItalic")) | ||
| 258 | (:font (".attributeFont" . "Face.AttributeFont"))) | ||
| 259 | "*List of X resources and classes for face attributes. | ||
| 260 | Each element has the form (ATTRIBUTE ENTRY1 ENTRY2...) where ATTRIBUTE is | ||
| 261 | the name of a face attribute, and each ENTRY is a cons of the form | ||
| 262 | (RESOURCE . CLASS) with RESOURCE being the resource and CLASS being the | ||
| 263 | X resource class for the attribute." | ||
| 264 | :type 'sexp | ||
| 265 | :group 'faces) | ||
| 266 | |||
| 267 | |||
| 268 | (defun set-face-attribute-from-resource (face attribute resource class frame) | ||
| 269 | "Set FACE's ATTRIBUTE from X resource RESOURCE, class CLASS on FRAME. | ||
| 270 | Value is the attribute value specified by the resource, or nil | ||
| 271 | if not present. This function displays a message if the resource | ||
| 272 | specifies an invalid attribute." | ||
| 273 | (let* ((face-name (face-name face)) | ||
| 274 | (value (internal-face-x-get-resource (concat face-name resource) | ||
| 275 | class frame))) | ||
| 276 | (when value | ||
| 277 | (condition-case () | ||
| 278 | (internal-set-lisp-face-attribute-from-resource | ||
| 279 | face attribute (downcase value) frame) | ||
| 280 | (error | ||
| 281 | (message "Face %s, frame %s: invalid attribute %s %s from X resource" | ||
| 282 | face-name frame attribute value)))) | ||
| 283 | value)) | ||
| 284 | |||
| 285 | |||
| 286 | (defun set-face-attributes-from-resources (face frame) | ||
| 287 | "Set attributes of FACE from X resources for FRAME." | ||
| 288 | (when (memq (framep frame) '(x w32)) | ||
| 289 | (dolist (definition face-x-resources) | ||
| 290 | (let ((attribute (car definition))) | ||
| 291 | (dolist (entry (cdr definition)) | ||
| 292 | (set-face-attribute-from-resource face attribute (car entry) | ||
| 293 | (cdr entry) frame)))))) | ||
| 294 | |||
| 295 | |||
| 296 | (defun make-face-x-resource-internal (face &optional frame) | ||
| 297 | "Fill frame-local FACE on FRAME from X resources. | ||
| 298 | FRAME nil or not specified means do it for all frames." | ||
| 299 | (if (null frame) | ||
| 300 | (dolist (frame (frame-list)) | ||
| 301 | (set-face-attributes-from-resources face frame)) | ||
| 302 | (set-face-attributes-from-resources face frame))) | ||
| 303 | |||
| 304 | |||
| 305 | |||
| 306 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 307 | ;;; Retrieving face attributes. | ||
| 308 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 309 | |||
| 67 | (defun face-name (face) | 310 | (defun face-name (face) |
| 68 | "Return the name of face FACE." | 311 | "Return the name of face FACE." |
| 69 | (aref (internal-get-face face) 1)) | 312 | (symbol-name (check-face face))) |
| 70 | 313 | ||
| 71 | (defun face-id (face) | ||
| 72 | "Return the internal ID number of face FACE." | ||
| 73 | (aref (internal-get-face face) 2)) | ||
| 74 | 314 | ||
| 75 | (defun face-font (face &optional frame) | 315 | (defun face-attribute (face attribute &optional frame) |
| 76 | "Return the font name of face FACE, or nil if it is unspecified. | 316 | "Return the value of FACE's ATTRIBUTE on FRAME. |
| 77 | If the optional argument FRAME is given, report on face FACE in that frame. | 317 | If the optional argument FRAME is given, report on face FACE in that frame. |
| 78 | If FRAME is t, report on the defaults for face FACE (for new frames). | 318 | If FRAME is t, report on the defaults for face FACE (for new frames). |
| 79 | The font default for a face is either nil, or a list | ||
| 80 | of the form (bold), (italic) or (bold italic). | ||
| 81 | If FRAME is omitted or nil, use the selected frame." | 319 | If FRAME is omitted or nil, use the selected frame." |
| 82 | (aref (internal-get-face face frame) 3)) | 320 | (internal-get-lisp-face-attribute face attribute frame)) |
| 321 | |||
| 83 | 322 | ||
| 84 | (defun face-foreground (face &optional frame) | 323 | (defun face-foreground (face &optional frame) |
| 85 | "Return the foreground color name of face FACE, or nil if unspecified. | 324 | "Return the foreground color name of FACE, or nil if unspecified. |
| 86 | If the optional argument FRAME is given, report on face FACE in that frame. | 325 | If the optional argument FRAME is given, report on face FACE in that frame. |
| 87 | If FRAME is t, report on the defaults for face FACE (for new frames). | 326 | If FRAME is t, report on the defaults for face FACE (for new frames). |
| 88 | If FRAME is omitted or nil, use the selected frame." | 327 | If FRAME is omitted or nil, use the selected frame." |
| 89 | (aref (internal-get-face face frame) 4)) | 328 | (internal-get-lisp-face-attribute face :foreground frame)) |
| 329 | |||
| 90 | 330 | ||
| 91 | (defun face-background (face &optional frame) | 331 | (defun face-background (face &optional frame) |
| 92 | "Return the background color name of face FACE, or nil if unspecified. | 332 | "Return the background color name of FACE, or nil if unspecified. |
| 93 | If the optional argument FRAME is given, report on face FACE in that frame. | 333 | If the optional argument FRAME is given, report on face FACE in that frame. |
| 94 | If FRAME is t, report on the defaults for face FACE (for new frames). | 334 | If FRAME is t, report on the defaults for face FACE (for new frames). |
| 95 | If FRAME is omitted or nil, use the selected frame." | 335 | If FRAME is omitted or nil, use the selected frame." |
| 96 | (aref (internal-get-face face frame) 5)) | 336 | (internal-get-lisp-face-attribute face :background frame)) |
| 337 | |||
| 97 | 338 | ||
| 98 | (defun face-stipple (face &optional frame) | 339 | (defun face-stipple (face &optional frame) |
| 99 | "Return the stipple pixmap name of face FACE, or nil if unspecified. | 340 | "Return the stipple pixmap name of FACE, or nil if unspecified. |
| 100 | If the optional argument FRAME is given, report on face FACE in that frame. | 341 | If the optional argument FRAME is given, report on face FACE in that frame. |
| 101 | If FRAME is t, report on the defaults for face FACE (for new frames). | 342 | If FRAME is t, report on the defaults for face FACE (for new frames). |
| 102 | If FRAME is omitted or nil, use the selected frame." | 343 | If FRAME is omitted or nil, use the selected frame." |
| 103 | (aref (internal-get-face face frame) 6)) | 344 | (internal-get-lisp-face-attribute face :stipple frame)) |
| 345 | |||
| 104 | 346 | ||
| 105 | (defalias 'face-background-pixmap 'face-stipple) | 347 | (defalias 'face-background-pixmap 'face-stipple) |
| 106 | 348 | ||
| 349 | |||
| 107 | (defun face-underline-p (face &optional frame) | 350 | (defun face-underline-p (face &optional frame) |
| 108 | "Return t if face FACE is underlined. | 351 | "Return non-nil if FACE is underlined. |
| 109 | If the optional argument FRAME is given, report on face FACE in that frame. | 352 | If the optional argument FRAME is given, report on face FACE in that frame. |
| 110 | If FRAME is t, report on the defaults for face FACE (for new frames). | 353 | If FRAME is t, report on the defaults for face FACE (for new frames). |
| 111 | If FRAME is omitted or nil, use the selected frame." | 354 | If FRAME is omitted or nil, use the selected frame." |
| 112 | (aref (internal-get-face face frame) 7)) | 355 | (eq (face-attribute face :underline frame) t)) |
| 356 | |||
| 113 | 357 | ||
| 114 | (defun face-inverse-video-p (face &optional frame) | 358 | (defun face-inverse-video-p (face &optional frame) |
| 115 | "Return t if face FACE is in inverse video. | 359 | "Return non-nil if FACE is in inverse video on FRAME. |
| 116 | If the optional argument FRAME is given, report on face FACE in that frame. | 360 | If the optional argument FRAME is given, report on face FACE in that frame. |
| 117 | If FRAME is t, report on the defaults for face FACE (for new frames). | 361 | If FRAME is t, report on the defaults for face FACE (for new frames). |
| 118 | If FRAME is omitted or nil, use the selected frame." | 362 | If FRAME is omitted or nil, use the selected frame." |
| 119 | (aref (internal-get-face face frame) 8)) | 363 | (eq (face-attribute face :inverse-video frame) t)) |
| 120 | 364 | ||
| 121 | (defun face-font-explicit (face &optional frame) | ||
| 122 | "Return non-nil if this face's font was explicitly specified." | ||
| 123 | (aref (internal-get-face face frame) 9)) | ||
| 124 | 365 | ||
| 125 | (defun face-bold-p (face &optional frame) | 366 | (defun face-bold-p (face &optional frame) |
| 126 | "Return non-nil if the font of FACE is bold. | 367 | "Return non-nil if the font of FACE is bold on FRAME. |
| 127 | If the optional argument FRAME is given, report on face FACE in that frame. | 368 | If the optional argument FRAME is given, report on face FACE in that frame. |
| 128 | If FRAME is t, report on the defaults for face FACE (for new frames). | 369 | If FRAME is t, report on the defaults for face FACE (for new frames). |
| 129 | If FRAME is omitted or nil, use the selected frame." | 370 | If FRAME is omitted or nil, use the selected frame. |
| 130 | (aref (internal-get-face face frame) 10)) | 371 | Use `face-attribute' for finer control." |
| 372 | (let ((bold (face-attribute face :weight frame))) | ||
| 373 | (not (memq bold '(normal unspecified))))) | ||
| 374 | |||
| 131 | 375 | ||
| 132 | (defun face-italic-p (face &optional frame) | 376 | (defun face-italic-p (face &optional frame) |
| 133 | "Return non-nil if the font of FACE is italic. | 377 | "Return non-nil if the font of FACE is italic on FRAME. |
| 134 | If the optional argument FRAME is given, report on face FACE in that frame. | 378 | If the optional argument FRAME is given, report on face FACE in that frame. |
| 135 | If FRAME is t, report on the defaults for face FACE (for new frames). | 379 | If FRAME is t, report on the defaults for face FACE (for new frames). |
| 136 | If FRAME is omitted or nil, use the selected frame." | 380 | If FRAME is omitted or nil, use the selected frame. |
| 137 | (aref (internal-get-face face frame) 11)) | 381 | Use `face-attribute' for finer control." |
| 382 | (let ((italic (face-attribute face :slant frame))) | ||
| 383 | (not (memq italic '(normal unspecified))))) | ||
| 384 | |||
| 385 | |||
| 386 | |||
| 387 | |||
| 388 | |||
| 389 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 390 | ;;; Face documentation. | ||
| 391 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 138 | 392 | ||
| 139 | (defalias 'face-doc-string 'face-documentation) | ||
| 140 | (defun face-documentation (face) | 393 | (defun face-documentation (face) |
| 141 | "Get the documentation string for FACE." | 394 | "Get the documentation string for FACE." |
| 142 | (get face 'face-documentation)) | 395 | (get face 'face-documentation)) |
| 396 | |||
| 397 | |||
| 398 | (defun set-face-documentation (face string) | ||
| 399 | "Set the documentation string for FACE to STRING." | ||
| 400 | (put face 'face-documentation string)) | ||
| 401 | |||
| 402 | |||
| 403 | (defalias 'face-doc-string 'face-documentation) | ||
| 404 | (defalias 'set-face-doc-string 'set-face-documentation) | ||
| 405 | |||
| 406 | |||
| 143 | 407 | ||
| 144 | ;;; Mutators. | 408 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 409 | ;; Setting face attributes. | ||
| 410 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 411 | |||
| 412 | |||
| 413 | (defun set-face-attribute (face frame &rest args) | ||
| 414 | "Set attributes of FACE on FRAME from ARGS. | ||
| 415 | |||
| 416 | FRAME nil means change attributes on all frames. FRAME t means change | ||
| 417 | the default for new frames (this is done automatically each time an | ||
| 418 | attribute is changed on all frames). | ||
| 419 | |||
| 420 | ARGS must come in pairs ATTRIBUTE VALUE. ATTRIBUTE must be a valid | ||
| 421 | face attribute name. All attributes can be set to `unspecified'; | ||
| 422 | this fact is not further mentioned below. | ||
| 423 | |||
| 424 | The following attributes are recognized: | ||
| 425 | |||
| 426 | `:family' | ||
| 427 | |||
| 428 | VALUE must be a string specifying the font family, e.g. ``courier'', | ||
| 429 | or a fontset alias name. If a font family is specified, wild-cards `*' | ||
| 430 | and `?' are allowed. | ||
| 431 | |||
| 432 | `:width' | ||
| 433 | |||
| 434 | VALUE specifies the relative proportionate width of the font to use. | ||
| 435 | It must be one of the symbols `ultra-condensed', `extra-condensed', | ||
| 436 | `condensed', `semi-condensed', `normal', `semi-expanded', `expanded', | ||
| 437 | `extra-expanded', or `ultra-expanded'. | ||
| 438 | |||
| 439 | `:height' | ||
| 440 | |||
| 441 | VALUE must be an integer specifying the height of the font to use in | ||
| 442 | 1/10 pt. | ||
| 443 | |||
| 444 | `:weight' | ||
| 445 | |||
| 446 | VALUE specifies the weight of the font to use. It must be one of the | ||
| 447 | symbols `ultra-bold', `extra-bold', `bold', `semi-bold', `normal', | ||
| 448 | `semi-light', `light', `extra-light', `ultra-light'. | ||
| 449 | |||
| 450 | `:slant' | ||
| 451 | |||
| 452 | VALUE specifies the slant of the font to use. It must be one of the | ||
| 453 | symbols `italic', `oblique', `normal', `reverse-italic', or | ||
| 454 | `reverse-oblique'. | ||
| 455 | |||
| 456 | `:foreground', `:background' | ||
| 457 | |||
| 458 | VALUE must be a color name, a string. | ||
| 459 | |||
| 460 | `:underline' | ||
| 461 | |||
| 462 | VALUE specifies whether characters in FACE should be underlined. If | ||
| 463 | VALUE is t, underline with foreground color of the face. If VALUE is | ||
| 464 | a string, underline with that color. If VALUE is nil, explicitly | ||
| 465 | don't underline. | ||
| 466 | |||
| 467 | `:overline' | ||
| 468 | |||
| 469 | VALUE specifies whether characters in FACE should be overlined. If | ||
| 470 | VALUE is t, overline with foreground color of the face. If VALUE is a | ||
| 471 | string, overline with that color. If VALUE is nil, explicitly don't | ||
| 472 | overline. | ||
| 473 | |||
| 474 | `:strike-through' | ||
| 475 | |||
| 476 | VALUE specifies whether characters in FACE should be drawn with a line | ||
| 477 | striking through them. If VALUE is t, use the foreground color of the | ||
| 478 | face. If VALUE is a string, strike-through with that color. If VALUE | ||
| 479 | is nil, explicitly don't strike through. | ||
| 480 | |||
| 481 | `:box' | ||
| 482 | |||
| 483 | VALUE specifies whether characters in FACE should have a box drawn | ||
| 484 | around them. If VALUE is nil, explicitly don't draw boxes. If | ||
| 485 | VALUE is t, draw a box with lines of width 1 in the foreground color | ||
| 486 | of the face. If VALUE is a string, the string must be a color name, | ||
| 487 | and the box is drawn in that color with a line width of 1. Otherwise, | ||
| 488 | VALUE must be a property list of the form `(:line-width WIDTH | ||
| 489 | :color COLOR :style STYLE)'. If a keyword/value pair is missing from | ||
| 490 | the property list, a default value will be used for the value, as | ||
| 491 | specified below. WIDTH specifies the width of the lines to draw; it | ||
| 492 | defaults to 1. COLOR is the name of the color to draw in, default is | ||
| 493 | the foreground color of the face for simple boxes, and the background | ||
| 494 | color of the face for 3D boxes. STYLE specifies whether a 3D box | ||
| 495 | should be draw. If STYLE is `released-button', draw a box looking | ||
| 496 | like a released 3D button. If STYLE is `pressed-button' draw a box | ||
| 497 | that appears like a pressed button. If STYLE is nil, the default if | ||
| 498 | the property list doesn't contain a style specification, draw a 2D | ||
| 499 | box. | ||
| 500 | |||
| 501 | `:inverse-video' | ||
| 502 | |||
| 503 | VALUE specifies whether characters in FACE should be displayed in | ||
| 504 | inverse video. VALUE must be one of t or nil. | ||
| 505 | |||
| 506 | `:stipple' | ||
| 507 | |||
| 508 | If VALUE is a string, it must be the name of a file of pixmap data. | ||
| 509 | The directories listed in the `x-bitmap-file-path' variable are | ||
| 510 | searched. Alternatively, VALUE may be a list of the form (WIDTH | ||
| 511 | HEIGHT DATA) where WIDTH and HEIGHT are the size in pixels, and DATA | ||
| 512 | is a string containing the raw bits of the bitmap. VALUE nil means | ||
| 513 | explicitly don't use a stipple pattern. | ||
| 514 | |||
| 515 | For convenience, attributes `:family', `:width', `:height', `:weight', | ||
| 516 | and `:slant' may also be set in one step from an X font name: | ||
| 517 | |||
| 518 | `:font' | ||
| 519 | |||
| 520 | Set font-related face attributes from VALUE. VALUE must be a valid | ||
| 521 | XLFD font name. If it is a font name pattern, the first matching font | ||
| 522 | will be used. | ||
| 523 | |||
| 524 | For compatibility with Emacs 20, keywords `:bold' and `:italic' can | ||
| 525 | be used to specify that a bold or italic font should be used. VALUE | ||
| 526 | must be t or nil in that case. A value of `unspecified' is not allowed." | ||
| 527 | (cond ((null frame) | ||
| 528 | ;; Change face on all frames. | ||
| 529 | (dolist (frame (frame-list)) | ||
| 530 | (apply #'set-face-attribute face frame args)) | ||
| 531 | ;; Record that as a default for new frames. | ||
| 532 | (apply #'set-face-attribute face t args)) | ||
| 533 | (t | ||
| 534 | (while args | ||
| 535 | (internal-set-lisp-face-attribute face (car args) | ||
| 536 | (car (cdr args)) frame) | ||
| 537 | (setq args (cdr (cdr args))))))) | ||
| 538 | |||
| 539 | |||
| 540 | (defun make-face-bold (face &optional frame) | ||
| 541 | "Make the font of FACE be bold, if possible. | ||
| 542 | FRAME nil or not specified means change face on all frames. | ||
| 543 | Use `set-face-attribute' for finer control of the font weight." | ||
| 544 | (interactive (list (read-face-name "Make which face bold: "))) | ||
| 545 | (set-face-attribute face frame :weight 'bold)) | ||
| 546 | |||
| 547 | |||
| 548 | (defun make-face-unbold (face &optional frame) | ||
| 549 | "Make the font of FACE be non-bold, if possible. | ||
| 550 | FRAME nil or not specified means change face on all frames." | ||
| 551 | (interactive (list (read-face-name "Make which face non-bold: "))) | ||
| 552 | (set-face-attribute face frame :weight 'normal)) | ||
| 553 | |||
| 554 | |||
| 555 | (defun make-face-italic (face &optional frame) | ||
| 556 | "Make the font of FACE be italic, if possible. | ||
| 557 | FRAME nil or not specified means change face on all frames. | ||
| 558 | Use `set-face-attribute' for finer control of the font slant." | ||
| 559 | (interactive (list (read-face-name "Make which face italic: "))) | ||
| 560 | (set-face-attribute face frame :slant 'italic)) | ||
| 561 | |||
| 562 | |||
| 563 | (defun make-face-unitalic (face &optional frame) | ||
| 564 | "Make the font of FACE be non-italic, if possible. | ||
| 565 | FRAME nil or not specified means change face on all frames." | ||
| 566 | (interactive (list (read-face-name "Make which face non-italic: "))) | ||
| 567 | (set-face-attribute face frame :slant 'normal)) | ||
| 568 | |||
| 569 | |||
| 570 | (defun make-face-bold-italic (face &optional frame) | ||
| 571 | "Make the font of FACE be bold and italic, if possible. | ||
| 572 | FRAME nil or not specified means change face on all frames. | ||
| 573 | Use `set-face-attribute' for finer control of font weight and slant." | ||
| 574 | (interactive (list (read-face-name "Make which face bold-italic: "))) | ||
| 575 | (set-face-attribute face frame :weight 'bold :slant 'italic)) | ||
| 576 | |||
| 145 | 577 | ||
| 146 | (defun set-face-font (face font &optional frame) | 578 | (defun set-face-font (face font &optional frame) |
| 147 | "Change the font of face FACE to FONT (a string). | 579 | "Change font-related attributes of FACE to those of FONT (a string). |
| 148 | If the optional FRAME argument is provided, change only | 580 | FRAME nil or not specified means change face on all frames. |
| 149 | in that frame; otherwise change each frame." | 581 | This sets the attributes `:family', `:width', `:height', `:weight', |
| 150 | (interactive (internal-face-interactive "font")) | 582 | and `:slant'. When called interactively, prompt for the face and font." |
| 151 | (if (stringp font) | 583 | (interactive (read-face-and-attribute :font)) |
| 152 | (setq font (or (resolve-fontset-name font) | 584 | (set-face-attribute face frame :font font)) |
| 153 | (x-resolve-font-name font 'default frame)))) | ||
| 154 | (internal-set-face-1 face 'font font 3 frame) | ||
| 155 | ;; Record that this face's font was set explicitly, not automatically, | ||
| 156 | ;; unless we are setting it to nil. | ||
| 157 | (internal-set-face-1 face nil (not (null font)) 9 frame)) | ||
| 158 | |||
| 159 | (defun set-face-font-auto (face font &optional frame) | ||
| 160 | "Change the font of face FACE to FONT (a string), for an automatic change. | ||
| 161 | An automatic change means that we don't change the \"explicit\" flag; | ||
| 162 | if the font was derived from the frame font before, it is now. | ||
| 163 | If the optional FRAME argument is provided, change only | ||
| 164 | in that frame; otherwise change each frame." | ||
| 165 | (interactive (internal-face-interactive "font")) | ||
| 166 | (if (stringp font) | ||
| 167 | (setq font (or (resolve-fontset-name font) | ||
| 168 | (x-resolve-font-name font 'default frame)))) | ||
| 169 | (internal-set-face-1 face 'font font 3 frame)) | ||
| 170 | |||
| 171 | (defun set-face-font-explicit (face flag &optional frame) | ||
| 172 | "Set the explicit-font flag of face FACE to FLAG. | ||
| 173 | If the optional FRAME argument is provided, change only | ||
| 174 | in that frame; otherwise change each frame." | ||
| 175 | (internal-set-face-1 face nil flag 9 frame)) | ||
| 176 | 585 | ||
| 177 | (defun set-face-foreground (face color &optional frame) | 586 | |
| 178 | "Change the foreground color of face FACE to COLOR (a string). | 587 | ;; Implementation note: Emulating gray background colors with a |
| 179 | If the optional FRAME argument is provided, change only | 588 | ;; stipple pattern is now part of the face realization process, and is |
| 180 | in that frame; otherwise change each frame." | 589 | ;; done in C depending on the frame on which the face is realized. |
| 181 | (interactive (internal-face-interactive "foreground" 'color)) | ||
| 182 | (internal-set-face-1 face 'foreground color 4 frame)) | ||
| 183 | |||
| 184 | (defvar face-default-stipple "gray3" | ||
| 185 | "Default stipple pattern used on monochrome displays. | ||
| 186 | This stipple pattern is used on monochrome displays | ||
| 187 | instead of shades of gray for a face background color. | ||
| 188 | See `set-face-stipple' for possible values for this variable.") | ||
| 189 | |||
| 190 | (defun face-color-gray-p (color &optional frame) | ||
| 191 | "Return t if COLOR is a shade of gray (or white or black). | ||
| 192 | FRAME specifies the frame and thus the display for interpreting COLOR." | ||
| 193 | (let* ((values (x-color-values color frame)) | ||
| 194 | (r (nth 0 values)) | ||
| 195 | (g (nth 1 values)) | ||
| 196 | (b (nth 2 values))) | ||
| 197 | (and values | ||
| 198 | (< (abs (- r g)) (/ (max 1 (abs r) (abs g)) 20)) | ||
| 199 | (< (abs (- g b)) (/ (max 1 (abs g) (abs b)) 20)) | ||
| 200 | (< (abs (- b r)) (/ (max 1 (abs b) (abs r)) 20))))) | ||
| 201 | 590 | ||
| 202 | (defun set-face-background (face color &optional frame) | 591 | (defun set-face-background (face color &optional frame) |
| 203 | "Change the background color of face FACE to COLOR (a string). | 592 | "Change the background color of face FACE to COLOR (a string). |
| 204 | If the optional FRAME argument is provided, change only | 593 | FRAME nil or not specified means change face on all frames. |
| 205 | in that frame; otherwise change each frame." | 594 | When called interactively, prompt for the face and color." |
| 206 | (interactive (internal-face-interactive "background" 'color)) | 595 | (interactive (read-face-and-attribute :background)) |
| 207 | ;; For a specific frame, use gray stipple instead of gray color | 596 | (set-face-attribute face frame :background color)) |
| 208 | ;; if the display does not support a gray color. | 597 | |
| 209 | (if (and frame (not (eq frame t)) color | 598 | |
| 210 | ;; Check for support for foreground, not for background! | 599 | (defun set-face-foreground (face color &optional frame) |
| 211 | ;; face-color-supported-p is smart enough to know | 600 | "Change the foreground color of face FACE to COLOR (a string). |
| 212 | ;; that grays are "supported" as background | 601 | FRAME nil or not specified means change face on all frames. |
| 213 | ;; because we are supposed to use stipple for them! | 602 | When called interactively, prompt for the face and color." |
| 214 | (not (face-color-supported-p frame color nil))) | 603 | (interactive (read-face-and-attribute :foreground)) |
| 215 | (set-face-stipple face face-default-stipple frame) | 604 | (set-face-attribute face frame :foreground color)) |
| 216 | (if (null frame) | 605 | |
| 217 | (let ((frames (frame-list))) | 606 | |
| 218 | (while frames | 607 | (defun set-face-stipple (face stipple &optional frame) |
| 219 | (set-face-background (face-name face) color (car frames)) | 608 | "Change the stipple pixmap of face FACE to STIPPLE. |
| 220 | (setq frames (cdr frames))) | 609 | FRAME nil or not specified means change face on all frames. |
| 221 | (set-face-background face color t) | 610 | STIPPLE. should be a string, the name of a file of pixmap data. |
| 222 | color) | ||
| 223 | (internal-set-face-1 face 'background color 5 frame)))) | ||
| 224 | |||
| 225 | (defun set-face-stipple (face pixmap &optional frame) | ||
| 226 | "Change the stipple pixmap of face FACE to PIXMAP. | ||
| 227 | PIXMAP should be a string, the name of a file of pixmap data. | ||
| 228 | The directories listed in the `x-bitmap-file-path' variable are searched. | 611 | The directories listed in the `x-bitmap-file-path' variable are searched. |
| 229 | 612 | ||
| 230 | Alternatively, PIXMAP may be a list of the form (WIDTH HEIGHT DATA) | 613 | Alternatively, STIPPLE may be a list of the form (WIDTH HEIGHT DATA) |
| 231 | where WIDTH and HEIGHT are the size in pixels, | 614 | where WIDTH and HEIGHT are the size in pixels, |
| 232 | and DATA is a string, containing the raw bits of the bitmap. | 615 | and DATA is a string, containing the raw bits of the bitmap." |
| 616 | (interactive (read-face-and-attribute :stipple)) | ||
| 617 | (set-face-attribute face frame :stipple stipple)) | ||
| 618 | |||
| 619 | |||
| 620 | (defun set-face-underline (face underline &optional frame) | ||
| 621 | "Specify whether face FACE is underlined. | ||
| 622 | UNDERLINE nil means FACE explicitly doesn't underline. | ||
| 623 | UNDERLINE non-nil means FACE explicitly does underlining | ||
| 624 | with the same of the foreground color. | ||
| 625 | If UNDERLINE is a string, underline with the color named UNDERLINE. | ||
| 626 | FRAME nil or not specified means change face on all frames. | ||
| 627 | Use `set-face-attribute' to ``unspecify'' underlining." | ||
| 628 | (interactive | ||
| 629 | (let ((list (read-face-and-attribute :underline))) | ||
| 630 | (list (car list) (eq (car (cdr list)) t)))) | ||
| 631 | (set-face-attribute face frame :underline underline)) | ||
| 233 | 632 | ||
| 234 | If the optional FRAME argument is provided, change only | ||
| 235 | in that frame; otherwise change each frame." | ||
| 236 | (interactive (internal-face-interactive-stipple "stipple")) | ||
| 237 | (internal-set-face-1 face 'background-pixmap pixmap 6 frame)) | ||
| 238 | |||
| 239 | (defalias 'set-face-background-pixmap 'set-face-stipple) | ||
| 240 | 633 | ||
| 241 | (defun set-face-underline-p (face underline-p &optional frame) | 634 | (defun set-face-underline-p (face underline-p &optional frame) |
| 242 | "Specify whether face FACE is underlined. (Yes if UNDERLINE-P is non-nil.) | 635 | "Specify whether face FACE is underlined. |
| 243 | If the optional FRAME argument is provided, change only | 636 | UNDERLINE-P nil means FACE explicitly doesn't underline. |
| 244 | in that frame; otherwise change each frame." | 637 | UNDERLINE-P non-nil means FACE explicitly does underlining. |
| 245 | (interactive (internal-face-interactive "underline-p" "underlined")) | 638 | FRAME nil or not specified means change face on all frames. |
| 246 | (internal-set-face-1 face 'underline underline-p 7 frame)) | 639 | Use `set-face-attribute' to ``unspecify'' underlining." |
| 640 | (interactive | ||
| 641 | (let ((list (read-face-and-attribute :underline))) | ||
| 642 | (list (car list) (eq (car (cdr list)) t)))) | ||
| 643 | (set-face-attribute face frame :underline underline-p)) | ||
| 644 | |||
| 247 | 645 | ||
| 248 | (defun set-face-inverse-video-p (face inverse-video-p &optional frame) | 646 | (defun set-face-inverse-video-p (face inverse-video-p &optional frame) |
| 249 | "Specify whether face FACE is in inverse video. | 647 | "Specify whether face FACE is in inverse video. |
| 250 | \(Yes if INVERSE-VIDEO-P is non-nil.) | 648 | INVERSE-VIDEO-P non-nil means FACE displays explicitly in inverse video. |
| 251 | If the optional FRAME argument is provided, change only | 649 | INVERSE-VIDEO-P nil means FACE explicitly is not in inverse video. |
| 252 | in that frame; otherwise change each frame." | 650 | FRAME nil or not specified means change face on all frames. |
| 253 | (interactive (internal-face-interactive "inverse-video-p" "inverse-video")) | 651 | Use `set-face-attribute' to ``unspecify'' the inverse video attribute." |
| 254 | (internal-set-face-1 face 'inverse-video inverse-video-p 8 frame)) | 652 | (interactive |
| 653 | (let ((list (read-face-and-attribute :inverse-video))) | ||
| 654 | (list (car list) (eq (car (cdr list)) t)))) | ||
| 655 | (set-face-attribute face frame :inverse-video inverse-video-p)) | ||
| 656 | |||
| 255 | 657 | ||
| 256 | (defun set-face-bold-p (face bold-p &optional frame) | 658 | (defun set-face-bold-p (face bold-p &optional frame) |
| 257 | "Specify whether face FACE is bold. (Yes if BOLD-P is non-nil.) | 659 | "Specify whether face FACE is bold. |
| 258 | If the optional FRAME argument is provided, change only | 660 | BOLD-P non-nil means FACE should explicitly display bold. |
| 259 | in that frame; otherwise change each frame." | 661 | BOLD-P nil means FACE should explicitly display non-bold. |
| 260 | (cond ((eq bold-p nil) (make-face-unbold face frame t)) | 662 | FRAME nil or not specified means change face on all frames. |
| 261 | (t (make-face-bold face frame t)))) | 663 | Use `set-face-attribute' or `modify-face' for finer control." |
| 664 | (if (null bold-p) | ||
| 665 | (make-face-unbold face frame) | ||
| 666 | (make-face-bold face frame))) | ||
| 667 | |||
| 262 | 668 | ||
| 263 | (defun set-face-italic-p (face italic-p &optional frame) | 669 | (defun set-face-italic-p (face italic-p &optional frame) |
| 264 | "Specify whether face FACE is italic. (Yes if ITALIC-P is non-nil.) | 670 | "Specify whether face FACE is italic. |
| 265 | If the optional FRAME argument is provided, change only | 671 | ITALIC-P non-nil means FACE should explicitly display italic. |
| 266 | in that frame; otherwise change each frame." | 672 | ITALIC-P nil means FACE should explicitly display non-italic. |
| 267 | (cond ((eq italic-p nil) (make-face-unitalic face frame t)) | 673 | FRAME nil or not specified means change face on all frames. |
| 268 | (t (make-face-italic face frame t)))) | 674 | Use `set-face-attribute' or `modify-face' for finer control." |
| 675 | (if (null italic-p) | ||
| 676 | (make-face-unitalic face frame) | ||
| 677 | (make-face-italic face frame))) | ||
| 678 | |||
| 679 | |||
| 680 | (defalias 'set-face-background-pixmap 'set-face-stipple) | ||
| 681 | |||
| 682 | |||
| 683 | (defun invert-face (face &optional frame) | ||
| 684 | "Swap the foreground and background colors of FACE. | ||
| 685 | FRAME nil or not specified means change face on all frames. | ||
| 686 | If FACE specifies neither foreground nor background color, | ||
| 687 | set its foreground and background to the background and foreground | ||
| 688 | of the default face. Value is FACE." | ||
| 689 | (interactive (list (read-face-name "Invert face: "))) | ||
| 690 | (let ((fg (face-attribute face :foreground frame)) | ||
| 691 | (bg (face-attribute face :background frame))) | ||
| 692 | (if (or fg bg) | ||
| 693 | (set-face-attribute face frame :foreground bg :background fg) | ||
| 694 | (set-face-attribute face frame | ||
| 695 | :foreground | ||
| 696 | (face-attribute 'default :background frame) | ||
| 697 | :background | ||
| 698 | (face-attribute 'default :foreground frame)))) | ||
| 699 | face) | ||
| 269 | 700 | ||
| 270 | (defalias 'set-face-doc-string 'set-face-documentation) | ||
| 271 | (defun set-face-documentation (face string) | ||
| 272 | "Set the documentation string for FACE to STRING." | ||
| 273 | (put face 'face-documentation string)) | ||
| 274 | 701 | ||
| 275 | (defun modify-face-read-string (face default name alist) | 702 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 276 | (let ((value | 703 | ;;; Interactively modifying faces. |
| 277 | (completing-read | 704 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 278 | (if default | 705 | |
| 279 | (format "Set face %s %s (default %s): " | 706 | (defun read-face-name (prompt) |
| 280 | face name (downcase default)) | 707 | "Read and return a face symbol, prompting with PROMPT. |
| 281 | (format "Set face %s %s: " face name)) | 708 | Value is a symbol naming a known face." |
| 282 | alist))) | 709 | (let ((face-list (mapcar #'(lambda (x) (cons (symbol-name x) x)) |
| 283 | (cond ((equal value "none") | 710 | (face-list))) |
| 284 | '(nil)) | 711 | face) |
| 285 | ((equal value "") | 712 | (while (equal "" (setq face (completing-read prompt face-list nil t)))) |
| 286 | default) | 713 | (intern face))) |
| 287 | (t value)))) | 714 | |
| 288 | 715 | ||
| 289 | (defun modify-face (face foreground background stipple | 716 | (defun face-valid-attribute-values (attribute &optional frame) |
| 290 | bold-p italic-p underline-p &optional inverse-p frame) | 717 | "Return valid values for face attribute ATTRIBUTE. |
| 291 | "Change the display attributes for face FACE. | 718 | The optional argument FRAME is used to determine available fonts |
| 292 | If the optional FRAME argument is provided, change only | 719 | and colors. If it is nil or not specified, the selected frame is |
| 293 | in that frame; otherwise change each frame. | 720 | used. Value is an alist of (NAME . VALUE) if ATTRIBUTE expects a value |
| 294 | 721 | out of a set of discrete values. Value is `integerp' if ATTRIBUTE expects | |
| 295 | FOREGROUND and BACKGROUND should be a colour name string (or list of strings to | 722 | an integer value." |
| 296 | try) or nil. STIPPLE should be a stipple pattern name string or nil. | 723 | (case attribute |
| 297 | If nil, means do not change the display attribute corresponding to that arg. | 724 | (:family |
| 298 | If (nil), that means clear out the attribute. | 725 | (if window-system |
| 299 | 726 | (mapcar #'(lambda (x) (cons (car x) (car x))) | |
| 300 | BOLD-P, ITALIC-P, UNDERLINE-P, and INVERSE-P specify whether | 727 | (x-font-family-list)) |
| 301 | the face should be set bold, italic, underlined or in inverse-video, | 728 | ;; Only one font on TTYs. |
| 302 | respectively. If one of these arguments is neither nil or t, it means do not | 729 | (cons "default" "default"))) |
| 303 | change the display attribute corresponding to that argument. | 730 | ((:width :weight :slant :inverse-video) |
| 304 | 731 | (mapcar #'(lambda (x) (cons (symbol-name x) x)) | |
| 305 | If called interactively, prompts for a face name and face attributes." | 732 | (internal-lisp-face-attribute-values attribute))) |
| 306 | (interactive | 733 | ((:underline :overline :strike-through :box) |
| 307 | (let* ((completion-ignore-case t) | 734 | (if window-system |
| 308 | (face (symbol-name (read-face-name "Modify face: "))) | 735 | (nconc (mapcar #'(lambda (x) (cons (symbol-name x) x)) |
| 309 | (colors (mapcar 'list x-colors)) | 736 | (internal-lisp-face-attribute-values attribute)) |
| 310 | (stipples (mapcar 'list (apply 'nconc | 737 | (mapcar #'(lambda (c) (cons c c)) |
| 311 | (mapcar 'directory-files | 738 | (x-defined-colors frame))) |
| 312 | x-bitmap-file-path)))) | 739 | (mapcar #'(lambda (x) (cons (symbol-name x) x)) |
| 313 | (foreground (modify-face-read-string | 740 | (internal-lisp-face-attribute-values attribute)))) |
| 314 | face (face-foreground (intern face)) | 741 | ((:foreground :background) |
| 315 | "foreground" colors)) | 742 | (mapcar #'(lambda (c) (cons c c)) |
| 316 | (background (modify-face-read-string | 743 | (or (and window-system (x-defined-colors frame)) |
| 317 | face (face-background (intern face)) | 744 | (tty-defined-colors)))) |
| 318 | "background" colors)) | 745 | ((:height) |
| 319 | ;; If the stipple value is a list (WIDTH HEIGHT DATA), | 746 | 'integerp) |
| 320 | ;; represent that as a string by printing it out. | 747 | (:stipple |
| 321 | (old-stipple-string | 748 | (and window-system |
| 322 | (if (stringp (face-stipple (intern face))) | 749 | (mapcar #'list |
| 323 | (face-stipple (intern face)) | 750 | (apply #'nconc (mapcar #'directory-files |
| 324 | (if (face-stipple (intern face)) | 751 | x-bitmap-file-path))))) |
| 325 | (prin1-to-string (face-stipple (intern face)))))) | 752 | (t |
| 326 | (new-stipple-string | 753 | (error "Internal error")))) |
| 327 | (modify-face-read-string | 754 | |
| 328 | face old-stipple-string | 755 | |
| 329 | "stipple" stipples)) | 756 | (defvar face-attribute-name-alist |
| 330 | ;; Convert the stipple value text we read | 757 | '((:family . "font family") |
| 331 | ;; back to a list if it looks like one. | 758 | (:width . "character set width") |
| 332 | ;; This makes the assumption that a pixmap file name | 759 | (:height . "height in 1/10 pt") |
| 333 | ;; won't start with an open-paren. | 760 | (:weight . "weight") |
| 334 | (stipple | 761 | (:slant . "slant") |
| 335 | (and new-stipple-string | 762 | (:underline . "underline") |
| 336 | (if (string-match "^(" new-stipple-string) | 763 | (:overline . "overline") |
| 337 | (read new-stipple-string) | 764 | (:strike-through . "strike-through") |
| 338 | new-stipple-string))) | 765 | (:box . "box") |
| 339 | (bold-p (y-or-n-p (concat "Should face " face " be bold "))) | 766 | (:inverse-video . "inverse-video display") |
| 340 | (italic-p (y-or-n-p (concat "Should face " face " be italic "))) | 767 | (:foreground . "foreground color") |
| 341 | (underline-p (y-or-n-p (concat "Should face " face " be underlined "))) | 768 | (:background . "background color") |
| 342 | (inverse-p (y-or-n-p (concat "Should face " face " be inverse-video "))) | 769 | (:stipple . "background stipple")) |
| 343 | (all-frames-p (y-or-n-p (concat "Modify face " face " in all frames ")))) | 770 | "An alist of descriptive names for face attributes. |
| 344 | (message "Face %s: %s" face | 771 | Each element has the form (ATTRIBUTE-NAME . DESCRIPTION) where |
| 345 | (mapconcat 'identity | 772 | ATTRIBUTE-NAME is a face attribute name (a keyword symbol), and |
| 346 | (delq nil | 773 | DESCRIPTION is a descriptive name for ATTRIBUTE-NAME.") |
| 347 | (list (if (equal foreground '(nil)) | 774 | |
| 348 | " no foreground" | 775 | |
| 349 | (and foreground (concat (downcase foreground) " foreground"))) | 776 | (defun face-descriptive-attribute-name (attribute) |
| 350 | (if (equal background '(nil)) | 777 | "Return a descriptive name for ATTRIBUTE." |
| 351 | " no background" | 778 | (cdr (assq attribute face-attribute-name-alist))) |
| 352 | (and background (concat (downcase background) " background"))) | 779 | |
| 353 | (if (equal stipple '(nil)) | 780 | |
| 354 | " no stipple" | 781 | (defun face-read-string (face default name &optional completion-alist) |
| 355 | (and stipple (concat (downcase new-stipple-string) " stipple"))) | 782 | "Interactively read a face attribute string value. |
| 356 | (and bold-p "bold") (and italic-p "italic") | 783 | FACE is the face whose attribute is read. DEFAULT is the default |
| 357 | (and inverse-p "inverse") | 784 | value to return if no new value is entered. NAME is a descriptive |
| 358 | (and underline-p "underline"))) ", ")) | 785 | name of the attribute for prompting. COMPLETION-ALIST is an alist |
| 359 | (list (intern face) foreground background stipple | 786 | of valid values, if non-nil. |
| 360 | bold-p italic-p underline-p inverse-p | 787 | |
| 361 | (if all-frames-p nil (selected-frame))))) | 788 | Entering ``none'' as attribute value means an unspecified attribute |
| 362 | ;; Clear this before we install the new foreground and background; | 789 | value. Entering nothing accepts the default value DEFAULT. |
| 363 | ;; otherwise, clearing it after would swap them! | 790 | |
| 364 | (when (and (or foreground background) (face-inverse-video-p face)) | 791 | Value is the new attribute value." |
| 365 | (set-face-inverse-video-p face nil frame) | 792 | (let* ((completion-ignore-case t) |
| 366 | ;; Arrange to restore it after, if we are not setting it now. | 793 | (value (completing-read |
| 367 | (or (memq inverse-p '(t nil)) | 794 | (if default |
| 368 | (setq inverse-p t))) | 795 | (format "Set face %s %s (default %s): " |
| 369 | (condition-case nil | 796 | face name (downcase (if (symbolp default) |
| 370 | (face-try-color-list 'set-face-foreground face foreground frame) | 797 | (symbol-name default) |
| 371 | (error nil)) | 798 | default))) |
| 372 | (condition-case nil | 799 | (format "Set face %s %s: " face name)) |
| 373 | (face-try-color-list 'set-face-background face background frame) | 800 | completion-alist))) |
| 374 | (error nil)) | 801 | (if (equal value "none") |
| 375 | (condition-case nil | 802 | nil |
| 376 | (set-face-stipple face stipple frame) | 803 | (if (equal value "") default value)))) |
| 377 | (error nil)) | 804 | |
| 378 | ;; Now that we have the new colors, | 805 | |
| 379 | (if (memq inverse-p '(nil t)) | 806 | (defun face-read-integer (face default name) |
| 380 | (set-face-inverse-video-p face inverse-p frame)) | 807 | "Interactively read an integer face attribute value. |
| 381 | (cond ((eq bold-p nil) | 808 | FACE is the face whose attribute is read. DEFAULT is the default |
| 382 | (if (face-font face frame) | 809 | value to return if no new value is entered. NAME is a descriptive |
| 383 | (make-face-unbold face frame t))) | 810 | name of the attribute for prompting. Value is the new attribute value." |
| 384 | ((eq bold-p t) | 811 | (let ((new-value (face-read-string face |
| 385 | (make-face-bold face frame t))) | 812 | (and default (int-to-string default)) |
| 386 | (cond ((eq italic-p nil) | 813 | name))) |
| 387 | (if (face-font face frame) | 814 | (and new-value |
| 388 | (make-face-unitalic face frame t))) | 815 | (string-to-int new-value)))) |
| 389 | ((eq italic-p t) (make-face-italic face frame t))) | 816 | |
| 390 | (if (memq underline-p '(nil t)) | 817 | |
| 391 | (set-face-underline-p face underline-p frame)) | 818 | (defun read-face-attribute (face attribute &optional frame) |
| 392 | (and (interactive-p) (redraw-display))) | 819 | "Interactively read a new value for FACE's ATTRIBUTE. |
| 820 | Optional argument FRAME nil or unspecified means read an attribute value | ||
| 821 | of a global face. Value is the new attribute value." | ||
| 822 | (let* ((old-value (face-attribute face attribute frame)) | ||
| 823 | (attribute-name (face-descriptive-attribute-name attribute)) | ||
| 824 | (valid (face-valid-attribute-values attribute frame)) | ||
| 825 | new-value) | ||
| 826 | ;; Represent complex attribute values as strings by printing them | ||
| 827 | ;; out. Stipple can be a vector; (WIDTH HEIGHT DATA). Box can be | ||
| 828 | ;; a list `(:width WIDTH :color COLOR)' or `(:width WIDTH :shadow | ||
| 829 | ;; SHADOW)'. | ||
| 830 | (when (and (or (eq attribute :stipple) | ||
| 831 | (eq attribute :box)) | ||
| 832 | (or (consp old-value) | ||
| 833 | (vectorp old-value))) | ||
| 834 | (setq old-value (prin1-to-string old-value))) | ||
| 835 | (cond ((listp valid) | ||
| 836 | (setq new-value | ||
| 837 | (cdr (assoc (face-read-string face old-value | ||
| 838 | attribute-name valid) | ||
| 839 | valid)))) | ||
| 840 | ((eq valid 'integerp) | ||
| 841 | (setq new-value (face-read-integer face old-value attribute-name))) | ||
| 842 | (t (error "Internal error"))) | ||
| 843 | ;; Convert stipple and box value text we read back to a list or | ||
| 844 | ;; vector if it looks like one. This makes the assumption that a | ||
| 845 | ;; pixmap file name won't start with an open-paren. | ||
| 846 | (when (and (or (eq attribute :stipple) | ||
| 847 | (eq attribute :box)) | ||
| 848 | (stringp new-value) | ||
| 849 | (string-match "^[[(]" new-value)) | ||
| 850 | (setq new-value (read new-value))) | ||
| 851 | new-value)) | ||
| 852 | |||
| 853 | |||
| 854 | (defun read-face-font (face &optional frame) | ||
| 855 | "Read the name of a font for FACE on FRAME. | ||
| 856 | If optional argument FRAME Is nil or omitted, use the selected frame." | ||
| 857 | (let ((completion-ignore-case t)) | ||
| 858 | (completing-read "Set font attributes of face %s from font: " | ||
| 859 | face (x-list-fonts "*" nil frame)))) | ||
| 860 | |||
| 861 | |||
| 862 | (defun read-all-face-attributes (face &optional frame) | ||
| 863 | "Interactively read all attributes for FACE. | ||
| 864 | If optional argument FRAME Is nil or omitted, use the selected frame. | ||
| 865 | Value is a property list of attribute names and new values." | ||
| 866 | (let (result) | ||
| 867 | (dolist (attribute face-attribute-name-alist result) | ||
| 868 | (setq result (cons (car attribute) | ||
| 869 | (cons (read-face-attribute face (car attribute) frame) | ||
| 870 | result)))))) | ||
| 871 | |||
| 872 | |||
| 873 | (defun modify-face (&optional frame) | ||
| 874 | "Modify attributes of faces interactively. | ||
| 875 | If optional argument FRAME is nil or omitted, modify the face used | ||
| 876 | for newly created frame, i.e. the global face." | ||
| 877 | (interactive) | ||
| 878 | (let ((face (read-face-name "Modify face: "))) | ||
| 879 | (apply #'set-face-attribute face frame | ||
| 880 | (read-all-face-attributes face frame)))) | ||
| 881 | |||
| 882 | |||
| 883 | (defun read-face-and-attribute (attribute &optional frame) | ||
| 884 | "Read face name and face attribute value. | ||
| 885 | ATTRIBUTE is the attribute whose new value is read. | ||
| 886 | FRAME nil or unspecified means read attribute value of global face. | ||
| 887 | Value is a list (FACE NEW-VALUE) where FACE is the face read | ||
| 888 | (a symbol), and NEW-VALUE is value read." | ||
| 889 | (cond ((eq attribute :font) | ||
| 890 | (let* ((prompt (format "Set font-related attributes of face: ")) | ||
| 891 | (face (read-face-name prompt)) | ||
| 892 | (font (read-face-font face frame))) | ||
| 893 | (list face font))) | ||
| 894 | (t | ||
| 895 | (let* ((attribute-name (face-descriptive-attribute-name attribute)) | ||
| 896 | (prompt (format "Set %s of face: " attribute-name)) | ||
| 897 | (face (read-face-name prompt)) | ||
| 898 | (new-value (read-face-attribute face attribute frame))) | ||
| 899 | (list face new-value))))) | ||
| 900 | |||
| 901 | |||
| 393 | 902 | ||
| 394 | ;;;; Associating face names (symbols) with their face vectors. | 903 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 904 | ;;; Listing faces. | ||
| 905 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 395 | 906 | ||
| 396 | (defvar global-face-data nil | 907 | (defvar list-faces-sample-text |
| 397 | "Internal data for face support functions. Not for external use. | 908 | "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 398 | This is an alist associating face names with the default values for | 909 | "*Text string to display as the sample text for `list-faces-display'.") |
| 399 | their parameters. Newly created frames get their data from here.") | ||
| 400 | 910 | ||
| 401 | (defun face-list () | ||
| 402 | "Returns a list of all defined face names." | ||
| 403 | (mapcar 'car global-face-data)) | ||
| 404 | 911 | ||
| 405 | (defun internal-find-face (name &optional frame) | 912 | ;; The name list-faces would be more consistent, but let's avoid a |
| 406 | "Retrieve the face named NAME. Return nil if there is no such face. | 913 | ;; conflict with Lucid, which uses that name differently. |
| 407 | If the optional argument FRAME is given, this gets the face NAME for | ||
| 408 | that frame; otherwise, it uses the selected frame. | ||
| 409 | If FRAME is the symbol t, then the global, non-frame face is returned. | ||
| 410 | If NAME is already a face, it is simply returned." | ||
| 411 | (if (and (eq frame t) (not (symbolp name))) | ||
| 412 | (setq name (face-name name))) | ||
| 413 | (if (symbolp name) | ||
| 414 | (cdr (assq name | ||
| 415 | (if (eq frame t) | ||
| 416 | global-face-data | ||
| 417 | (frame-face-alist (or frame (selected-frame)))))) | ||
| 418 | (internal-check-face name) | ||
| 419 | name)) | ||
| 420 | 914 | ||
| 421 | (defun internal-get-face (name &optional frame) | 915 | (defun list-faces-display () |
| 422 | "Retrieve the face named NAME; error if there is none. | 916 | "List all faces, using the same sample text in each. |
| 423 | If the optional argument FRAME is given, this gets the face NAME for | 917 | The sample text is a string that comes from the variable |
| 424 | that frame; otherwise, it uses the selected frame. | 918 | `list-faces-sample-text'." |
| 425 | If FRAME is the symbol t, then the global, non-frame face is returned. | 919 | (interactive) |
| 426 | If NAME is already a face, it is simply returned." | 920 | (let ((faces (sort (face-list) #'string-lessp)) |
| 427 | (or (internal-find-face name frame) | 921 | (face nil) |
| 428 | (internal-check-face name))) | 922 | (frame (selected-frame)) |
| 923 | disp-frame window) | ||
| 924 | (with-output-to-temp-buffer "*Faces*" | ||
| 925 | (save-excursion | ||
| 926 | (set-buffer standard-output) | ||
| 927 | (setq truncate-lines t) | ||
| 928 | (while faces | ||
| 929 | (setq face (car faces)) | ||
| 930 | (setq faces (cdr faces)) | ||
| 931 | (insert (format "%25s " (face-name face))) | ||
| 932 | (let ((beg (point))) | ||
| 933 | (insert list-faces-sample-text) | ||
| 934 | (insert "\n") | ||
| 935 | (put-text-property beg (1- (point)) 'face face) | ||
| 936 | ;; If the sample text has multiple lines, line up all of them. | ||
| 937 | (goto-char beg) | ||
| 938 | (forward-line 1) | ||
| 939 | (while (not (eobp)) | ||
| 940 | (insert " ") | ||
| 941 | (forward-line 1)))) | ||
| 942 | (goto-char (point-min))) | ||
| 943 | (print-help-return-message)) | ||
| 944 | ;; If the *Faces* buffer appears in a different frame, | ||
| 945 | ;; copy all the face definitions from FRAME, | ||
| 946 | ;; so that the display will reflect the frame that was selected. | ||
| 947 | (setq window (get-buffer-window (get-buffer "*Faces*") t)) | ||
| 948 | (setq disp-frame (if window (window-frame window) | ||
| 949 | (car (frame-list)))) | ||
| 950 | (or (eq frame disp-frame) | ||
| 951 | (let ((faces (face-list))) | ||
| 952 | (while faces | ||
| 953 | (copy-face (car faces) (car faces) frame disp-frame) | ||
| 954 | (setq faces (cdr faces))))))) | ||
| 429 | 955 | ||
| 430 | 956 | ||
| 431 | (defun internal-set-face-1 (face name value index frame) | 957 | (defun describe-face (face &optional frame) |
| 432 | (let ((inhibit-quit t)) | 958 | "Display the properties of face FACE on FRAME. |
| 433 | (if (null frame) | 959 | If the optional argument FRAME is given, report on face FACE in that frame. |
| 434 | (let ((frames (frame-list))) | 960 | If FRAME is t, report on the defaults for face FACE (for new frames). |
| 435 | (while frames | 961 | If FRAME is omitted or nil, use the selected frame." |
| 436 | (internal-set-face-1 (face-name face) name value index (car frames)) | 962 | (interactive (list (read-face-name "Describe face: "))) |
| 437 | (setq frames (cdr frames))) | 963 | (let* ((attrs '((:family . "Family") |
| 438 | (aset (internal-get-face (if (symbolp face) face (face-name face)) t) | 964 | (:width . "Width") |
| 439 | index value) | 965 | (:height . "Height") |
| 440 | value) | 966 | (:weight . "Weight") |
| 441 | (let ((internal-face (internal-get-face face frame))) | 967 | (:slant . "Slant") |
| 442 | (or (eq frame t) | 968 | (:foreground . "Foreground") |
| 443 | (if (eq name 'inverse-video) | 969 | (:background . "Background") |
| 444 | (or (eq value (aref internal-face index)) | 970 | (:underline . "Underline") |
| 445 | (invert-face face frame)) | 971 | (:overline . "Overline") |
| 446 | (and name (fboundp 'set-face-attribute-internal) | 972 | (:strike-through . "Strike-through") |
| 447 | (set-face-attribute-internal (face-id face) | 973 | (:box . "Box") |
| 448 | name value frame)))) | 974 | (:inverse-video . "Inverse") |
| 449 | (aset internal-face index value))))) | 975 | (:stipple . "Stipple"))) |
| 976 | (max-width (apply #'max (mapcar #'(lambda (x) (length (cdr x))) | ||
| 977 | attrs)))) | ||
| 978 | (with-output-to-temp-buffer "*Help*" | ||
| 979 | (save-excursion | ||
| 980 | (set-buffer standard-output) | ||
| 981 | (dolist (a attrs) | ||
| 982 | (let ((attr (face-attribute face (car a) frame))) | ||
| 983 | (insert (make-string (- max-width (length (cdr a))) ?\ ) | ||
| 984 | (cdr a) ": " (format "%s" attr) "\n"))) | ||
| 985 | (insert "\nDocumentation:\n\n" | ||
| 986 | (or (face-documentation face) | ||
| 987 | "not documented as a face."))) | ||
| 988 | (print-help-return-message)))) | ||
| 989 | |||
| 450 | 990 | ||
| 451 | 991 | ||
| 452 | (defun read-face-name (prompt) | 992 | |
| 453 | (let (face) | 993 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 454 | (while (= (length face) 0) | 994 | ;;; Face specifications (defface). |
| 455 | (setq face (completing-read prompt | 995 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 456 | (mapcar '(lambda (x) (list (symbol-name x))) | ||
| 457 | (face-list)) | ||
| 458 | nil t))) | ||
| 459 | (intern face))) | ||
| 460 | 996 | ||
| 461 | (defun internal-face-interactive (what &optional bool) | 997 | ;; Parameter FRAME Is kept for call compatibility to with previous |
| 462 | (let* ((fn (intern (concat "face-" what))) | 998 | ;; face implementation. |
| 463 | (prompt (concat "Set " what " of face")) | ||
| 464 | (face (read-face-name (concat prompt ": "))) | ||
| 465 | (default (if (fboundp fn) | ||
| 466 | (or (funcall fn face (selected-frame)) | ||
| 467 | (funcall fn 'default (selected-frame))))) | ||
| 468 | value) | ||
| 469 | (setq value | ||
| 470 | (cond ((eq bool 'color) | ||
| 471 | (completing-read (concat prompt " " (symbol-name face) " to: ") | ||
| 472 | (mapcar (function (lambda (color) | ||
| 473 | (cons color color))) | ||
| 474 | x-colors) | ||
| 475 | nil nil nil nil default)) | ||
| 476 | (bool | ||
| 477 | (y-or-n-p (concat "Should face " (symbol-name face) | ||
| 478 | " be " bool "? "))) | ||
| 479 | (t | ||
| 480 | (read-string (concat prompt " " (symbol-name face) " to: ") | ||
| 481 | nil nil default)))) | ||
| 482 | (list face (if (equal value "") nil value)))) | ||
| 483 | |||
| 484 | (defun internal-face-interactive-stipple (what) | ||
| 485 | (let* ((fn (intern (concat "face-" what))) | ||
| 486 | (prompt (concat "Set " what " of face")) | ||
| 487 | (face (read-face-name (concat prompt ": "))) | ||
| 488 | (default (if (fboundp fn) | ||
| 489 | (or (funcall fn face (selected-frame)) | ||
| 490 | (funcall fn 'default (selected-frame))))) | ||
| 491 | ;; If the stipple value is a list (WIDTH HEIGHT DATA), | ||
| 492 | ;; represent that as a string by printing it out. | ||
| 493 | (old-stipple-string | ||
| 494 | (if (stringp (face-stipple face)) | ||
| 495 | (face-stipple face) | ||
| 496 | (if (null (face-stipple face)) | ||
| 497 | nil | ||
| 498 | (prin1-to-string (face-stipple face))))) | ||
| 499 | (new-stipple-string | ||
| 500 | (read-string | ||
| 501 | (concat prompt " " (symbol-name face) " to: ") | ||
| 502 | old-stipple-string)) | ||
| 503 | ;; Convert the stipple value text we read | ||
| 504 | ;; back to a list if it looks like one. | ||
| 505 | ;; This makes the assumption that a pixmap file name | ||
| 506 | ;; won't start with an open-paren. | ||
| 507 | (stipple | ||
| 508 | (if (string-match "^(" new-stipple-string) | ||
| 509 | (read new-stipple-string) | ||
| 510 | new-stipple-string))) | ||
| 511 | (list face (if (equal stipple "") nil stipple)))) | ||
| 512 | |||
| 513 | (defun make-face (name &optional no-resources) | ||
| 514 | "Define a new FACE on all frames. | ||
| 515 | You can modify the font, color, etc of this face with the set-face- functions. | ||
| 516 | If NO-RESOURCES is non-nil, then we ignore X resources | ||
| 517 | and always make a face whose attributes are all nil. | ||
| 518 | |||
| 519 | If the face already exists, it is unmodified." | ||
| 520 | (interactive "SMake face: ") | ||
| 521 | (or (internal-find-face name) | ||
| 522 | (let ((face (make-vector 12 nil))) | ||
| 523 | (aset face 0 'face) | ||
| 524 | (aset face 1 name) | ||
| 525 | (let* ((frames (frame-list)) | ||
| 526 | (inhibit-quit t) | ||
| 527 | (id (internal-next-face-id))) | ||
| 528 | (if (fboundp 'make-face-internal) | ||
| 529 | (make-face-internal id)) | ||
| 530 | (aset face 2 id) | ||
| 531 | (while frames | ||
| 532 | (set-frame-face-alist (car frames) | ||
| 533 | (cons (cons name (copy-sequence face)) | ||
| 534 | (frame-face-alist (car frames)))) | ||
| 535 | (setq frames (cdr frames))) | ||
| 536 | (setq global-face-data (cons (cons name face) global-face-data))) | ||
| 537 | ;; When making a face after frames already exist | ||
| 538 | (or no-resources | ||
| 539 | (if (memq window-system '(x w32)) | ||
| 540 | (make-face-x-resource-internal face))) | ||
| 541 | ;; Add to menu of faces. | ||
| 542 | (if (fboundp 'facemenu-add-new-face) | ||
| 543 | (facemenu-add-new-face name)) | ||
| 544 | face)) | ||
| 545 | name) | ||
| 546 | 999 | ||
| 547 | (defun make-empty-face (face) | 1000 | (defun face-attr-construct (face &optional frame) |
| 548 | "Define a new FACE on all frames, which initially reflects the defaults. | 1001 | "Return a defface-style attribute list for FACE on FRAME. |
| 549 | You can modify the font, color, etc of this face with the set-face- functions. | 1002 | Value is a property list of pairs ATTRIBUTE VALUE for all specified |
| 550 | If the face already exists, it is unmodified." | 1003 | face attributes of FACE where ATTRIBUTE is the attribute name and |
| 551 | (interactive "SMake empty face: ") | 1004 | VALUE is the specified value of that attribute." |
| 552 | (make-face face t)) | 1005 | (let (result) |
| 1006 | (dolist (entry face-attribute-name-alist result) | ||
| 1007 | (let* ((attribute (car entry)) | ||
| 1008 | (value (face-attribute face attribute))) | ||
| 1009 | (unless (eq value 'unspecified) | ||
| 1010 | (setq result (nconc (list attribute value) result))))))) | ||
| 1011 | |||
| 553 | 1012 | ||
| 554 | ;; Fill in a face by default based on X resources, for all existing frames. | 1013 | (defun face-spec-set-match-display (display frame) |
| 555 | ;; This has to be done when a new face is made. | 1014 | "Non-nil if DISPLAY matches FRAME. |
| 556 | (defun make-face-x-resource-internal (face &optional frame set-anyway) | 1015 | DISPLAY is part of a spec such as can be used in `defface'. |
| 557 | (cond ((null frame) | 1016 | If FRAME is nil, the current FRAME is used." |
| 558 | (let ((frames (frame-list))) | 1017 | (let* ((conjuncts display) |
| 559 | (while frames | 1018 | conjunct req options |
| 560 | (if (memq (framep (car frames)) '(x w32)) | 1019 | ;; t means we have succeeded against all the conjuncts in |
| 561 | (make-face-x-resource-internal (face-name face) | 1020 | ;; DISPLAY that have been tested so far. |
| 562 | (car frames) set-anyway)) | 1021 | (match t)) |
| 563 | (setq frames (cdr frames))))) | 1022 | (if (eq conjuncts t) |
| 564 | (t | 1023 | (setq conjuncts nil)) |
| 565 | (setq face (internal-get-face (face-name face) frame)) | 1024 | (while (and conjuncts match) |
| 566 | ;; | 1025 | (setq conjunct (car conjuncts) |
| 567 | ;; These are things like "attributeForeground" instead of simply | 1026 | conjuncts (cdr conjuncts) |
| 568 | ;; "foreground" because people tend to do things like "*foreground", | 1027 | req (car conjunct) |
| 569 | ;; which would cause all faces to be fully qualified, making faces | 1028 | options (cdr conjunct) |
| 570 | ;; inherit attributes in a non-useful way. So we've made them slightly | 1029 | match (cond ((eq req 'type) |
| 571 | ;; less obvious to specify in order to make them work correctly in | 1030 | (or (memq window-system options) |
| 572 | ;; more random environments. | 1031 | (and (null window-system) |
| 573 | ;; | 1032 | (memq 'tty options)))) |
| 574 | ;; I think these should be called "face.faceForeground" instead of | 1033 | ((eq req 'class) |
| 575 | ;; "face.attributeForeground", but they're the way they are for | 1034 | (memq (frame-parameter frame 'display-type) options)) |
| 576 | ;; hysterical reasons. | 1035 | ((eq req 'background) |
| 577 | ;; | 1036 | (memq (frame-parameter frame 'background-mode) |
| 578 | (let* ((name (symbol-name (face-name face))) | 1037 | options)) |
| 579 | (fn (or (x-get-resource (concat name ".attributeFont") | 1038 | (t (error "Unknown req `%S' with options `%S'" |
| 580 | "Face.AttributeFont") | 1039 | req options))))) |
| 581 | (and set-anyway (face-font face)))) | 1040 | match)) |
| 582 | (fg (or (x-get-resource (concat name ".attributeForeground") | ||
| 583 | "Face.AttributeForeground") | ||
| 584 | (and set-anyway (face-foreground face)))) | ||
| 585 | (bg (or (x-get-resource (concat name ".attributeBackground") | ||
| 586 | "Face.AttributeBackground") | ||
| 587 | (and set-anyway (face-background face)))) | ||
| 588 | (bgp (or (x-get-resource (concat name ".attributeStipple") | ||
| 589 | "Face.AttributeStipple") | ||
| 590 | (x-get-resource (concat name ".attributeBackgroundPixmap") | ||
| 591 | "Face.AttributeBackgroundPixmap") | ||
| 592 | (and set-anyway (face-stipple face)))) | ||
| 593 | (ulp (let ((resource (x-get-resource | ||
| 594 | (concat name ".attributeUnderline") | ||
| 595 | "Face.AttributeUnderline"))) | ||
| 596 | (if resource | ||
| 597 | (member (downcase resource) '("on" "true")) | ||
| 598 | (and set-anyway (face-underline-p face))))) | ||
| 599 | ) | ||
| 600 | (if fn | ||
| 601 | (condition-case () | ||
| 602 | (cond ((string= fn "italic") | ||
| 603 | (make-face-italic face)) | ||
| 604 | ((string= fn "bold") | ||
| 605 | (make-face-bold face)) | ||
| 606 | ((string= fn "bold-italic") | ||
| 607 | (make-face-bold-italic face)) | ||
| 608 | (t | ||
| 609 | (set-face-font face fn frame))) | ||
| 610 | (error | ||
| 611 | (if (member fn '("italic" "bold" "bold-italic")) | ||
| 612 | (message "no %s version found for face `%s'" fn name) | ||
| 613 | (message "font `%s' not found for face `%s'" fn name))))) | ||
| 614 | (if fg | ||
| 615 | (condition-case () | ||
| 616 | (set-face-foreground face fg frame) | ||
| 617 | (error (message "color `%s' not allocated for face `%s'" fg name)))) | ||
| 618 | (if bg | ||
| 619 | (condition-case () | ||
| 620 | (set-face-background face bg frame) | ||
| 621 | (error (message "color `%s' not allocated for face `%s'" bg name)))) | ||
| 622 | (if bgp | ||
| 623 | (condition-case () | ||
| 624 | (set-face-stipple face bgp frame) | ||
| 625 | (error (message "pixmap `%s' not found for face `%s'" bgp name)))) | ||
| 626 | (if (or ulp set-anyway) | ||
| 627 | (set-face-underline-p face ulp frame)) | ||
| 628 | ))) | ||
| 629 | face) | ||
| 630 | 1041 | ||
| 631 | (defun copy-face (old-face new-face &optional frame new-frame) | ||
| 632 | "Define a face just like OLD-FACE, with name NEW-FACE. | ||
| 633 | If NEW-FACE already exists as a face, it is modified to be like OLD-FACE. | ||
| 634 | If it doesn't already exist, it is created. | ||
| 635 | 1042 | ||
| 636 | If the optional argument FRAME is given as a frame, | 1043 | (defun face-spec-choose (spec &optional frame) |
| 637 | NEW-FACE is changed on FRAME only. | 1044 | "Choose the proper attributes for FRAME, out of SPEC." |
| 638 | If FRAME is t, the frame-independent default specification for OLD-FACE | 1045 | (unless frame |
| 639 | is copied to NEW-FACE. | 1046 | (setq frame (selected-frame))) |
| 640 | If FRAME is nil, copying is done for the frame-independent defaults | 1047 | (let ((tail spec) |
| 641 | and for each existing frame. | 1048 | result) |
| 642 | If the optional fourth argument NEW-FRAME is given, | 1049 | (while tail |
| 643 | copy the information from face OLD-FACE on frame FRAME | 1050 | (let* ((entry (car tail)) |
| 644 | to NEW-FACE on frame NEW-FRAME." | 1051 | (display (nth 0 entry)) |
| 645 | (or new-frame (setq new-frame frame)) | 1052 | (attrs (nth 1 entry))) |
| 646 | (let ((inhibit-quit t)) | 1053 | (setq tail (cdr tail)) |
| 647 | (if (null frame) | 1054 | (when (face-spec-set-match-display display frame) |
| 648 | (let ((frames (frame-list))) | 1055 | (setq result attrs tail nil)))) |
| 649 | (while frames | 1056 | result)) |
| 650 | (copy-face old-face new-face (car frames)) | ||
| 651 | (setq frames (cdr frames))) | ||
| 652 | (copy-face old-face new-face t)) | ||
| 653 | (setq old-face (internal-get-face old-face frame)) | ||
| 654 | (setq new-face (or (internal-find-face new-face new-frame) | ||
| 655 | (make-face new-face))) | ||
| 656 | (condition-case nil | ||
| 657 | ;; A face that has a global symbolic font modifier such as `bold' | ||
| 658 | ;; might legitimately get an error here. | ||
| 659 | ;; Use the frame's default font in that case. | ||
| 660 | (set-face-font new-face (face-font old-face frame) new-frame) | ||
| 661 | (error | ||
| 662 | (set-face-font new-face nil new-frame))) | ||
| 663 | (set-face-font-explicit new-face (face-font-explicit old-face frame) | ||
| 664 | new-frame) | ||
| 665 | (set-face-foreground new-face (face-foreground old-face frame) new-frame) | ||
| 666 | (set-face-background new-face (face-background old-face frame) new-frame) | ||
| 667 | (set-face-stipple new-face | ||
| 668 | (face-stipple old-face frame) | ||
| 669 | new-frame) | ||
| 670 | (set-face-underline-p new-face (face-underline-p old-face frame) | ||
| 671 | new-frame)) | ||
| 672 | new-face)) | ||
| 673 | 1057 | ||
| 674 | (defun face-equal (face1 face2 &optional frame) | ||
| 675 | "True if the faces FACE1 and FACE2 display in the same way." | ||
| 676 | (setq face1 (internal-get-face face1 frame) | ||
| 677 | face2 (internal-get-face face2 frame)) | ||
| 678 | (and (equal (face-foreground face1 frame) (face-foreground face2 frame)) | ||
| 679 | (equal (face-background face1 frame) (face-background face2 frame)) | ||
| 680 | (equal (face-font face1 frame) (face-font face2 frame)) | ||
| 681 | (eq (face-underline-p face1 frame) (face-underline-p face2 frame)) | ||
| 682 | (equal (face-stipple face1 frame) | ||
| 683 | (face-stipple face2 frame)))) | ||
| 684 | 1058 | ||
| 685 | (defun face-differs-from-default-p (face &optional frame) | 1059 | (defun face-spec-reset-face (face &optional frame) |
| 686 | "True if face FACE displays differently from the default face, on FRAME. | 1060 | "Reset all attributes of FACE on FRAME to unspecified." |
| 687 | A face is considered to be ``the same'' as the default face if it is | 1061 | (let ((attrs face-attribute-name-alist) |
| 688 | actually specified in the same way (equivalent fonts, etc) or if it is | 1062 | params) |
| 689 | fully unspecified, and thus inherits the attributes of any face it | 1063 | (while attrs |
| 690 | is displayed on top of. | 1064 | (let ((attr-and-name (car attrs))) |
| 691 | 1065 | (setq params (cons (car attr-and-name) (cons 'unspecified params)))) | |
| 692 | The optional argument FRAME specifies which frame to test; | 1066 | (setq attrs (cdr attrs))) |
| 693 | if FRAME is t, test the default for new frames. | 1067 | (apply #'set-face-attribute face frame params))) |
| 694 | If FRAME is nil or omitted, test the selected frame." | ||
| 695 | (let ((default (internal-get-face 'default frame))) | ||
| 696 | (setq face (internal-get-face face frame)) | ||
| 697 | (not (and (or (equal (face-foreground default frame) | ||
| 698 | (face-foreground face frame)) | ||
| 699 | (null (face-foreground face frame))) | ||
| 700 | (or (equal (face-background default frame) | ||
| 701 | (face-background face frame)) | ||
| 702 | (null (face-background face frame))) | ||
| 703 | (or (null (face-font face frame)) | ||
| 704 | (equal (face-font face frame) | ||
| 705 | (or (face-font default frame) | ||
| 706 | (downcase | ||
| 707 | (cdr (assq 'font (frame-parameters frame))))))) | ||
| 708 | (or (equal (face-stipple default frame) | ||
| 709 | (face-stipple face frame)) | ||
| 710 | (null (face-stipple face frame))) | ||
| 711 | (equal (face-underline-p default frame) | ||
| 712 | (face-underline-p face frame)) | ||
| 713 | )))) | ||
| 714 | 1068 | ||
| 715 | (defun face-nontrivial-p (face &optional frame) | ||
| 716 | "True if face FACE has some non-nil attribute. | ||
| 717 | The optional argument FRAME specifies which frame to test; | ||
| 718 | if FRAME is t, test the default for new frames. | ||
| 719 | If FRAME is nil or omitted, test the selected frame." | ||
| 720 | (setq face (internal-get-face face frame)) | ||
| 721 | (or (face-foreground face frame) | ||
| 722 | (face-background face frame) | ||
| 723 | (face-font face frame) | ||
| 724 | (face-stipple face frame) | ||
| 725 | (face-underline-p face frame))) | ||
| 726 | 1069 | ||
| 1070 | (defun face-spec-set (face spec &optional frame) | ||
| 1071 | "Set FACE's attributes according to the first matching entry in SPEC. | ||
| 1072 | FRAME is the frame whose frame-local face is set. FRAME nil means | ||
| 1073 | do it on all frames. See `defface' for information about SPEC." | ||
| 1074 | (let ((attrs (face-spec-choose spec frame)) | ||
| 1075 | params) | ||
| 1076 | (while attrs | ||
| 1077 | (let ((attribute (car attrs)) | ||
| 1078 | (value (car (cdr attrs)))) | ||
| 1079 | ;; Support some old-style attribute names and values. | ||
| 1080 | (case attribute | ||
| 1081 | (:bold (setq attribute :weight value (if value 'bold 'normal))) | ||
| 1082 | (:italic (setq attribute :slant value (if value 'italic 'normal)))) | ||
| 1083 | (setq params (cons attribute (cons value params)))) | ||
| 1084 | (setq attrs (cdr (cdr attrs)))) | ||
| 1085 | (face-spec-reset-face face frame) | ||
| 1086 | (apply #'set-face-attribute face frame params))) | ||
| 727 | 1087 | ||
| 728 | (defun invert-face (face &optional frame) | 1088 | |
| 729 | "Swap the foreground and background colors of face FACE. | 1089 | (defun face-attr-match-p (face attrs &optional frame) |
| 730 | If the face doesn't specify both foreground and background, then | 1090 | "Value is non-nil if attributes of FACE match values in plist ATTRS. |
| 731 | set its foreground and background to the default background and foreground." | 1091 | Optional parameter FRAME is the frame whose definition of FACE |
| 732 | (interactive (list (read-face-name "Invert face: "))) | 1092 | is used. If nil or omitted, use the selected frame." |
| 733 | (setq face (internal-get-face face frame)) | 1093 | (unless frame |
| 734 | (let ((fg (face-foreground face frame)) | 1094 | (setq frame (selected-frame))) |
| 735 | (bg (face-background face frame))) | 1095 | (let ((list face-attribute-name-alist) |
| 736 | (if (or fg bg) | 1096 | (match t)) |
| 1097 | (while (and match (not (null list))) | ||
| 1098 | (let* ((attr (car (car list))) | ||
| 1099 | (specified-value (plist-get attrs attr)) | ||
| 1100 | (value-now (face-attribute face attr frame))) | ||
| 1101 | (when specified-value | ||
| 1102 | (setq match (equal specified-value value-now))) | ||
| 1103 | (setq list (cdr list)))) | ||
| 1104 | match)) | ||
| 1105 | |||
| 1106 | |||
| 1107 | (defun face-spec-match-p (face spec &optional frame) | ||
| 1108 | "Return t if FACE, on FRAME, matches what SPEC says it should look like." | ||
| 1109 | (face-attr-match-p face (face-spec-choose spec frame) frame)) | ||
| 1110 | |||
| 1111 | |||
| 1112 | |||
| 1113 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 1114 | ;;; Background mode. | ||
| 1115 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 1116 | |||
| 1117 | (defcustom frame-background-mode nil | ||
| 1118 | "*The brightness of the background. | ||
| 1119 | Set this to the symbol `dark' if your background color is dark, `light' if | ||
| 1120 | your background is light, or nil (default) if you want Emacs to | ||
| 1121 | examine the brightness for you." | ||
| 1122 | :group 'faces | ||
| 1123 | :set #'(lambda (var value) | ||
| 1124 | (set var value) | ||
| 1125 | (mapcar 'frame-set-background-mode (frame-list))) | ||
| 1126 | :initialize 'custom-initialize-changed | ||
| 1127 | :type '(choice (choice-item dark) | ||
| 1128 | (choice-item light) | ||
| 1129 | (choice-item :tag "default" nil))) | ||
| 1130 | |||
| 1131 | |||
| 1132 | (defun frame-set-background-mode (frame) | ||
| 1133 | "Set up the `background-mode' and `display-type' frame parameters for FRAME." | ||
| 1134 | (let* ((bg-resource | ||
| 1135 | (and window-system | ||
| 1136 | (x-get-resource ".backgroundMode" "BackgroundMode"))) | ||
| 1137 | (params (frame-parameters frame)) | ||
| 1138 | (bg-mode (cond (frame-background-mode) | ||
| 1139 | ((null window-system) | ||
| 1140 | ;; No way to determine this automatically (?). | ||
| 1141 | 'dark) | ||
| 1142 | (bg-resource | ||
| 1143 | (intern (downcase bg-resource))) | ||
| 1144 | ((< (apply '+ (x-color-values | ||
| 1145 | (cdr (assq 'background-color | ||
| 1146 | params)) | ||
| 1147 | frame)) | ||
| 1148 | ;; Just looking at the screen, colors whose | ||
| 1149 | ;; values add up to .6 of the white total | ||
| 1150 | ;; still look dark to me. | ||
| 1151 | (* (apply '+ (x-color-values "white" frame)) .6)) | ||
| 1152 | 'dark) | ||
| 1153 | (t 'light))) | ||
| 1154 | (display-type (cond ((null window-system) | ||
| 1155 | (if (tty-display-color-p) 'color 'mono)) | ||
| 1156 | ((x-display-color-p frame) | ||
| 1157 | 'color) | ||
| 1158 | ((x-display-grayscale-p frame) | ||
| 1159 | 'grayscale) | ||
| 1160 | (t 'mono)))) | ||
| 1161 | (modify-frame-parameters frame | ||
| 1162 | (list (cons 'background-mode bg-mode) | ||
| 1163 | (cons 'display-type display-type)))) | ||
| 1164 | |||
| 1165 | ;; For all named faces, choose face specs matching the new frame | ||
| 1166 | ;; parameters. | ||
| 1167 | (let ((face-list (face-list))) | ||
| 1168 | (while face-list | ||
| 1169 | (let* ((face (car face-list)) | ||
| 1170 | (spec (get face 'face-defface-spec))) | ||
| 1171 | (when spec | ||
| 1172 | (face-spec-set face spec frame)) | ||
| 1173 | (setq face-list (cdr face-list)))))) | ||
| 1174 | |||
| 1175 | |||
| 1176 | |||
| 1177 | |||
| 1178 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 1179 | ;;; Frame creation. | ||
| 1180 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 1181 | |||
| 1182 | (defun x-handle-named-frame-geometry (parameters) | ||
| 1183 | "Add geometry parameters for a named frame to parameter list PARAMETERS. | ||
| 1184 | Value is the new parameter list." | ||
| 1185 | (let* ((name (or (cdr (assq 'name parameters)) | ||
| 1186 | (cdr (assq 'name default-frame-alist)))) | ||
| 1187 | (x-resource-name name) | ||
| 1188 | (res-geometry (if name (x-get-resource "geometry" "Geometry")))) | ||
| 1189 | (when res-geometry | ||
| 1190 | (let ((parsed (x-parse-geometry res-geometry))) | ||
| 1191 | ;; If the resource specifies a position, call the position | ||
| 1192 | ;; and size "user-specified". | ||
| 1193 | (when (or (assq 'top parsed) | ||
| 1194 | (assq 'left parsed)) | ||
| 1195 | (setq parsed (append '((user-position . t) (user-size . t)) parsed))) | ||
| 1196 | ;; Put the geometry parameters at the end. Copy | ||
| 1197 | ;; default-frame-alist so that they go after it. | ||
| 1198 | (setq parameters (append parameters default-frame-alist parsed)))) | ||
| 1199 | parameters)) | ||
| 1200 | |||
| 1201 | |||
| 1202 | (defun x-handle-reverse-video (frame parameters) | ||
| 1203 | "Handle the reverse-video frame parameter and X resource. | ||
| 1204 | `x-create-frame' does not handle this one." | ||
| 1205 | (when (cdr (or (assq 'reverse parameters) | ||
| 1206 | (assq 'reverse default-frame-alist) | ||
| 1207 | (let ((resource (x-get-resource "reverseVideo" | ||
| 1208 | "ReverseVideo"))) | ||
| 1209 | (if resource | ||
| 1210 | (cons nil (member (downcase resource) | ||
| 1211 | '("on" "true"))))))) | ||
| 1212 | (let* ((params (frame-parameters frame)) | ||
| 1213 | (bg (cdr (assq 'foreground-color params))) | ||
| 1214 | (fg (cdr (assq 'background-color params)))) | ||
| 1215 | (modify-frame-parameters frame | ||
| 1216 | (list (cons 'foreground-color fg) | ||
| 1217 | (cons 'background-color bg))) | ||
| 1218 | (if (equal bg (cdr (assq 'border-color params))) | ||
| 1219 | (modify-frame-parameters frame | ||
| 1220 | (list (cons 'border-color fg)))) | ||
| 1221 | (if (equal bg (cdr (assq 'mouse-color params))) | ||
| 1222 | (modify-frame-parameters frame | ||
| 1223 | (list (cons 'mouse-color fg)))) | ||
| 1224 | (if (equal bg (cdr (assq 'cursor-color params))) | ||
| 1225 | (modify-frame-parameters frame | ||
| 1226 | (list (cons 'cursor-color fg))))))) | ||
| 1227 | |||
| 1228 | |||
| 1229 | (defun x-create-frame-with-faces (&optional parameters) | ||
| 1230 | "Create a frame from optional frame parameters PARAMETERS. | ||
| 1231 | Parameters not specified by PARAMETERS are taken from | ||
| 1232 | `default-frame-alist'. If PARAMETERS specify a frame name, | ||
| 1233 | handle X geometry resources for that name. If either PARAMETERS | ||
| 1234 | or `default-frame-alist' contains a `reverse' parameter, or | ||
| 1235 | the X resource ``reverseVideo'' is present, handle that. | ||
| 1236 | Value is the new frame created." | ||
| 1237 | (setq parameters (x-handle-named-frame-geometry parameters)) | ||
| 1238 | (let ((visibility-spec (assq 'visibility parameters)) | ||
| 1239 | (frame-list (frame-list)) | ||
| 1240 | (frame (x-create-frame (cons '(visibility . nil) parameters))) | ||
| 1241 | success) | ||
| 1242 | (unwind-protect | ||
| 737 | (progn | 1243 | (progn |
| 738 | (set-face-foreground face bg frame) | 1244 | (x-handle-reverse-video frame parameters) |
| 739 | (set-face-background face fg frame)) | 1245 | (frame-set-background-mode frame) |
| 740 | (let* ((frame-bg (cdr (assq 'background-color (frame-parameters frame)))) | 1246 | (face-set-after-frame-default frame) |
| 741 | (default-bg (or (face-background 'default frame) | 1247 | (if (or (null frame-list) (null visibility-spec)) |
| 742 | frame-bg)) | 1248 | (make-frame-visible frame) |
| 743 | (frame-fg (cdr (assq 'foreground-color (frame-parameters frame)))) | 1249 | (modify-frame-parameters frame (list visibility-spec))) |
| 744 | (default-fg (or (face-foreground 'default frame) | 1250 | (setq success t)) |
| 745 | frame-fg))) | 1251 | (unless success |
| 746 | (set-face-foreground face default-bg frame) | 1252 | (delete-frame frame))) |
| 747 | (set-face-background face default-fg frame)))) | 1253 | frame)) |
| 748 | face) | 1254 | |
| 1255 | |||
| 1256 | (defun face-set-after-frame-default (frame) | ||
| 1257 | "Set frame-local faces of FRAME from face specs and resources." | ||
| 1258 | (dolist (face (face-list)) | ||
| 1259 | (let ((spec (or (get face 'saved-face) | ||
| 1260 | (get face 'face-defface-spec)))) | ||
| 1261 | (when spec | ||
| 1262 | (face-spec-set face spec frame)) | ||
| 1263 | (internal-merge-in-global-face face frame) | ||
| 1264 | (when window-system | ||
| 1265 | (make-face-x-resource-internal face frame))))) | ||
| 1266 | |||
| 1267 | |||
| 1268 | (defun tty-create-frame-with-faces (&optional parameters) | ||
| 1269 | "Create a frame from optional frame parameters PARAMETERS. | ||
| 1270 | Parameters not specified by PARAMETERS are taken from | ||
| 1271 | `default-frame-alist'. If either PARAMETERS or `default-frame-alist' | ||
| 1272 | contains a `reverse' parameter, handle that. Value is the new frame | ||
| 1273 | created." | ||
| 1274 | (let ((frame (make-terminal-frame parameters)) | ||
| 1275 | success) | ||
| 1276 | (unwind-protect | ||
| 1277 | (progn | ||
| 1278 | (frame-set-background-mode frame) | ||
| 1279 | (face-set-after-frame-default frame) | ||
| 1280 | (setq success t)) | ||
| 1281 | (unless success | ||
| 1282 | (delete-frame frame))) | ||
| 1283 | frame)) | ||
| 1284 | |||
| 1285 | |||
| 1286 | ;; Called from C function init_display to initialize faces of the | ||
| 1287 | ;; dumped terminal frame on startup. | ||
| 1288 | |||
| 1289 | (defun tty-set-up-initial-frame-faces () | ||
| 1290 | (let ((frame (selected-frame))) | ||
| 1291 | (frame-set-background-mode frame) | ||
| 1292 | (face-set-after-frame-default frame))) | ||
| 1293 | |||
| 1294 | |||
| 1295 | |||
| 1296 | |||
| 1297 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 1298 | ;;; Compatiblity with 20.2 | ||
| 1299 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 1300 | |||
| 1301 | ;; Update a frame's faces when we change its default font. | ||
| 1302 | |||
| 1303 | (defun frame-update-faces (frame) | ||
| 1304 | nil) | ||
| 1305 | |||
| 1306 | |||
| 1307 | ;; Update the colors of FACE, after FRAME's own colors have been | ||
| 1308 | ;; changed. | ||
| 1309 | |||
| 1310 | (defun frame-update-face-colors (frame) | ||
| 1311 | (frame-set-background-mode frame)) | ||
| 1312 | |||
| 1313 | |||
| 1314 | |||
| 1315 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 1316 | ;;; Standard faces. | ||
| 1317 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 1318 | |||
| 1319 | ;; Make the standard faces. The C code knows faces `default', | ||
| 1320 | ;; `modeline', `toolbar' and `region', so they must be the first faces | ||
| 1321 | ;; made. Unspecified attributes of these three faces are filled-in | ||
| 1322 | ;; from frame parameters in the C code. | ||
| 1323 | |||
| 1324 | (defgroup basic-faces nil | ||
| 1325 | "The standard faces of Emacs." | ||
| 1326 | :group 'faces) | ||
| 1327 | |||
| 1328 | |||
| 1329 | (defface default | ||
| 1330 | '((t nil)) | ||
| 1331 | "Basic default face." | ||
| 1332 | :group 'basic-faces) | ||
| 1333 | |||
| 1334 | |||
| 1335 | (defface modeline | ||
| 1336 | '((((type x) (class color)) | ||
| 1337 | (:box (:line-width 2 :style released-button) :background "grey75")) | ||
| 1338 | (t | ||
| 1339 | (:inverse-video t))) | ||
| 1340 | "Basic mode line face." | ||
| 1341 | :group 'basic-faces) | ||
| 1342 | |||
| 1343 | |||
| 1344 | (defface top-line | ||
| 1345 | '((((type x) (class color)) | ||
| 1346 | (:box (:line-width 2 :style released-button) :background "grey75")) | ||
| 1347 | (t | ||
| 1348 | (:inverse-video t))) | ||
| 1349 | "Basic top line face." | ||
| 1350 | :group 'basic-faces) | ||
| 1351 | |||
| 1352 | |||
| 1353 | (defface toolbar | ||
| 1354 | '((((type x) (class color)) | ||
| 1355 | (:box (:line-width 1 :style released-button) :background "grey75")) | ||
| 1356 | (t | ||
| 1357 | ())) | ||
| 1358 | "Basic toolbar face." | ||
| 1359 | :group 'basic-faces) | ||
| 1360 | |||
| 1361 | |||
| 1362 | (defface region | ||
| 1363 | '((((type tty) (class color)) | ||
| 1364 | (:background "blue" :foreground "white")) | ||
| 1365 | (((type tty) (class mono)) | ||
| 1366 | (:inverse-video t)) | ||
| 1367 | (((class color) (background dark)) | ||
| 1368 | (:background "blue")) | ||
| 1369 | (((class color) (background light)) | ||
| 1370 | (:background "lightblue")) | ||
| 1371 | (t (:background "gray"))) | ||
| 1372 | "Basic face for highlight the region." | ||
| 1373 | :group 'basic-faces) | ||
| 1374 | |||
| 1375 | |||
| 1376 | (defface bitmap-area | ||
| 1377 | '((((class color)) | ||
| 1378 | (:background "grey95")) | ||
| 1379 | (t (:background "gray"))) | ||
| 1380 | "Basic face for bitmap areas under X." | ||
| 1381 | :group 'basic-faces) | ||
| 1382 | |||
| 1383 | |||
| 1384 | (defface bold '((t (:weight bold))) | ||
| 1385 | "Basic bold face." | ||
| 1386 | :group 'basic-faces) | ||
| 1387 | |||
| 1388 | |||
| 1389 | (defface italic '((t (:slant italic))) | ||
| 1390 | "Basic italic font." | ||
| 1391 | :group 'basic-faces) | ||
| 1392 | |||
| 1393 | |||
| 1394 | (defface bold-italic '((t (:weight bold :slant italic))) | ||
| 1395 | "Basic bold-italic face." | ||
| 1396 | :group 'basic-faces) | ||
| 1397 | |||
| 1398 | |||
| 1399 | (defface underline '((t (:underline t))) | ||
| 1400 | "Basic underlined face." | ||
| 1401 | :group 'basic-faces) | ||
| 1402 | |||
| 1403 | |||
| 1404 | (defface highlight | ||
| 1405 | '((((type tty) (class color)) | ||
| 1406 | (:background "green")) | ||
| 1407 | (((class color) (background light)) | ||
| 1408 | (:background "darkseagreen2")) | ||
| 1409 | (((class color) (background dark)) | ||
| 1410 | (:background "darkolivegreen")) | ||
| 1411 | (t (:inverse-video t))) | ||
| 1412 | "Basic face for highlighting.") | ||
| 1413 | |||
| 1414 | |||
| 1415 | (defface secondary-selection | ||
| 1416 | '((((type tty) (class color)) | ||
| 1417 | (:background "cyan")) | ||
| 1418 | (((class color) (background light)) | ||
| 1419 | (:background "paleturquoise")) | ||
| 1420 | (((class color) (background dark)) | ||
| 1421 | (:background "darkslateblue")) | ||
| 1422 | (t (:inverse-video t))) | ||
| 1423 | "Basic face for displaying the secondary selection.") | ||
| 1424 | |||
| 1425 | |||
| 1426 | (defface fixed-pitch '((t (:family "courier*"))) | ||
| 1427 | "The basic fixed-pitch face." | ||
| 1428 | :group 'basic-faces) | ||
| 1429 | |||
| 1430 | |||
| 1431 | (defface variable-pitch '((t (:family "helv*"))) | ||
| 1432 | "The basic variable-pitch face." | ||
| 1433 | :group 'basic-faces) | ||
| 1434 | |||
| 1435 | |||
| 1436 | (defface trailing-whitespace | ||
| 1437 | '((((class color) (background light)) | ||
| 1438 | (:background "red")) | ||
| 1439 | (((class color) (background dark)) | ||
| 1440 | (:background "red")) | ||
| 1441 | (t (:inverse-video t))) | ||
| 1442 | "Basic face for highlighting trailing whitespace.") | ||
| 749 | 1443 | ||
| 750 | 1444 | ||
| 751 | (defun internal-try-face-font (face font &optional frame) | ||
| 752 | "Like set-face-font, but returns nil on failure instead of an error." | ||
| 753 | (condition-case () | ||
| 754 | (set-face-font-auto face font frame) | ||
| 755 | (error nil))) | ||
| 756 | 1445 | ||
| 757 | ;; Manipulating font names. | 1446 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 1447 | ;;; Manipulating font names. | ||
| 1448 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 1449 | |||
| 1450 | ;; This is here for compatibilty with Emacs 20.2. For example, | ||
| 1451 | ;; international/fontset.el uses these functions to manipulate font | ||
| 1452 | ;; names. The following functions are not used in the face | ||
| 1453 | ;; implementation itself. | ||
| 758 | 1454 | ||
| 759 | (defvar x-font-regexp nil) | 1455 | (defvar x-font-regexp nil) |
| 760 | (defvar x-font-regexp-head nil) | 1456 | (defvar x-font-regexp-head nil) |
| @@ -803,6 +1499,7 @@ set its foreground and background to the default background and foreground." | |||
| 803 | (setq x-font-regexp-weight (concat - weight -)) | 1499 | (setq x-font-regexp-weight (concat - weight -)) |
| 804 | nil) | 1500 | nil) |
| 805 | 1501 | ||
| 1502 | |||
| 806 | (defun x-resolve-font-name (pattern &optional face frame) | 1503 | (defun x-resolve-font-name (pattern &optional face frame) |
| 807 | "Return a font name matching PATTERN. | 1504 | "Return a font name matching PATTERN. |
| 808 | All wildcards in PATTERN become substantiated. | 1505 | All wildcards in PATTERN become substantiated. |
| @@ -832,6 +1529,7 @@ also the same size as FACE on FRAME, or fail." | |||
| 832 | (car fonts)) | 1529 | (car fonts)) |
| 833 | (cdr (assq 'font (frame-parameters (selected-frame)))))) | 1530 | (cdr (assq 'font (frame-parameters (selected-frame)))))) |
| 834 | 1531 | ||
| 1532 | |||
| 835 | (defun x-frob-font-weight (font which) | 1533 | (defun x-frob-font-weight (font which) |
| 836 | (let ((case-fold-search t)) | 1534 | (let ((case-fold-search t)) |
| 837 | (cond ((string-match x-font-regexp font) | 1535 | (cond ((string-match x-font-regexp font) |
| @@ -852,6 +1550,7 @@ also the same size as FACE on FRAME, or fail." | |||
| 852 | (concat (substring font 0 (match-beginning 1)) which | 1550 | (concat (substring font 0 (match-beginning 1)) which |
| 853 | (substring font (match-end 1))))))) | 1551 | (substring font (match-end 1))))))) |
| 854 | 1552 | ||
| 1553 | |||
| 855 | (defun x-frob-font-slant (font which) | 1554 | (defun x-frob-font-slant (font which) |
| 856 | (let ((case-fold-search t)) | 1555 | (let ((case-fold-search t)) |
| 857 | (cond ((string-match x-font-regexp font) | 1556 | (cond ((string-match x-font-regexp font) |
| @@ -872,813 +1571,50 @@ also the same size as FACE on FRAME, or fail." | |||
| 872 | (concat (substring font 0 (match-beginning 1)) which | 1571 | (concat (substring font 0 (match-beginning 1)) which |
| 873 | (substring font (match-end 1))))))) | 1572 | (substring font (match-end 1))))))) |
| 874 | 1573 | ||
| 1574 | |||
| 875 | (defun x-make-font-bold (font) | 1575 | (defun x-make-font-bold (font) |
| 876 | "Given an X font specification, make a bold version of it. | 1576 | "Given an X font specification, make a bold version of it. |
| 877 | If that can't be done, return nil." | 1577 | If that can't be done, return nil." |
| 878 | (x-frob-font-weight font "bold")) | 1578 | (x-frob-font-weight font "bold")) |
| 879 | 1579 | ||
| 1580 | |||
| 880 | (defun x-make-font-demibold (font) | 1581 | (defun x-make-font-demibold (font) |
| 881 | "Given an X font specification, make a demibold version of it. | 1582 | "Given an X font specification, make a demibold version of it. |
| 882 | If that can't be done, return nil." | 1583 | If that can't be done, return nil." |
| 883 | (x-frob-font-weight font "demibold")) | 1584 | (x-frob-font-weight font "demibold")) |
| 884 | 1585 | ||
| 1586 | |||
| 885 | (defun x-make-font-unbold (font) | 1587 | (defun x-make-font-unbold (font) |
| 886 | "Given an X font specification, make a non-bold version of it. | 1588 | "Given an X font specification, make a non-bold version of it. |
| 887 | If that can't be done, return nil." | 1589 | If that can't be done, return nil." |
| 888 | (x-frob-font-weight font "medium")) | 1590 | (x-frob-font-weight font "medium")) |
| 889 | 1591 | ||
| 1592 | |||
| 890 | (defun x-make-font-italic (font) | 1593 | (defun x-make-font-italic (font) |
| 891 | "Given an X font specification, make an italic version of it. | 1594 | "Given an X font specification, make an italic version of it. |
| 892 | If that can't be done, return nil." | 1595 | If that can't be done, return nil." |
| 893 | (x-frob-font-slant font "i")) | 1596 | (x-frob-font-slant font "i")) |
| 894 | 1597 | ||
| 1598 | |||
| 895 | (defun x-make-font-oblique (font) ; you say tomayto... | 1599 | (defun x-make-font-oblique (font) ; you say tomayto... |
| 896 | "Given an X font specification, make an oblique version of it. | 1600 | "Given an X font specification, make an oblique version of it. |
| 897 | If that can't be done, return nil." | 1601 | If that can't be done, return nil." |
| 898 | (x-frob-font-slant font "o")) | 1602 | (x-frob-font-slant font "o")) |
| 899 | 1603 | ||
| 1604 | |||
| 900 | (defun x-make-font-unitalic (font) | 1605 | (defun x-make-font-unitalic (font) |
| 901 | "Given an X font specification, make a non-italic version of it. | 1606 | "Given an X font specification, make a non-italic version of it. |
| 902 | If that can't be done, return nil." | 1607 | If that can't be done, return nil." |
| 903 | (x-frob-font-slant font "r")) | 1608 | (x-frob-font-slant font "r")) |
| 904 | 1609 | ||
| 1610 | |||
| 905 | (defun x-make-font-bold-italic (font) | 1611 | (defun x-make-font-bold-italic (font) |
| 906 | "Given an X font specification, make a bold and italic version of it. | 1612 | "Given an X font specification, make a bold and italic version of it. |
| 907 | If that can't be done, return nil." | 1613 | If that can't be done, return nil." |
| 908 | (and (setq font (x-make-font-bold font)) | 1614 | (and (setq font (x-make-font-bold font)) |
| 909 | (x-make-font-italic font))) | 1615 | (x-make-font-italic font))) |
| 910 | |||
| 911 | ;;; non-X-specific interface | ||
| 912 | |||
| 913 | (defun make-face-bold (face &optional frame noerror) | ||
| 914 | "Make the font of the given face be bold, if possible. | ||
| 915 | If NOERROR is non-nil, return nil on failure." | ||
| 916 | (interactive (list (read-face-name "Make which face bold: "))) | ||
| 917 | ;; Set the bold-p flag, first of all. | ||
| 918 | (internal-set-face-1 face nil t 10 frame) | ||
| 919 | (if (and (eq frame t) (listp (face-font face t))) | ||
| 920 | (set-face-font face (if (memq 'italic (face-font face t)) | ||
| 921 | '(bold italic) '(bold)) | ||
| 922 | t) | ||
| 923 | (let (font) | ||
| 924 | (if (null frame) | ||
| 925 | (let ((frames (frame-list))) | ||
| 926 | ;; Make this face bold in global-face-data. | ||
| 927 | (make-face-bold face t noerror) | ||
| 928 | ;; Make this face bold in each frame. | ||
| 929 | (while frames | ||
| 930 | (make-face-bold face (car frames) noerror) | ||
| 931 | (setq frames (cdr frames)))) | ||
| 932 | (setq face (internal-get-face face frame)) | ||
| 933 | (setq font (or (face-font face frame) | ||
| 934 | (face-font face t))) | ||
| 935 | (if (listp font) | ||
| 936 | (setq font nil)) | ||
| 937 | (setq font (or font | ||
| 938 | (face-font 'default frame) | ||
| 939 | (cdr (assq 'font (frame-parameters frame))))) | ||
| 940 | (or (and font (make-face-bold-internal face frame font)) | ||
| 941 | ;; We failed to find a bold version of the font. | ||
| 942 | noerror | ||
| 943 | (error "No bold version of %S" font)))))) | ||
| 944 | |||
| 945 | (defun make-face-bold-internal (face frame font) | ||
| 946 | (let (f2) | ||
| 947 | (or (and (setq f2 (x-make-font-bold font)) | ||
| 948 | (internal-try-face-font face f2 frame)) | ||
| 949 | (and (setq f2 (x-make-font-demibold font)) | ||
| 950 | (internal-try-face-font face f2 frame))))) | ||
| 951 | |||
| 952 | (defun make-face-italic (face &optional frame noerror) | ||
| 953 | "Make the font of the given face be italic, if possible. | ||
| 954 | If NOERROR is non-nil, return nil on failure." | ||
| 955 | (interactive (list (read-face-name "Make which face italic: "))) | ||
| 956 | ;; Set the italic-p flag, first of all. | ||
| 957 | (internal-set-face-1 face nil t 11 frame) | ||
| 958 | (if (and (eq frame t) (listp (face-font face t))) | ||
| 959 | (set-face-font face (if (memq 'bold (face-font face t)) | ||
| 960 | '(bold italic) '(italic)) | ||
| 961 | t) | ||
| 962 | (let (font) | ||
| 963 | (if (null frame) | ||
| 964 | (let ((frames (frame-list))) | ||
| 965 | ;; Make this face italic in global-face-data. | ||
| 966 | (make-face-italic face t noerror) | ||
| 967 | ;; Make this face italic in each frame. | ||
| 968 | (while frames | ||
| 969 | (make-face-italic face (car frames) noerror) | ||
| 970 | (setq frames (cdr frames)))) | ||
| 971 | (setq face (internal-get-face face frame)) | ||
| 972 | (setq font (or (face-font face frame) | ||
| 973 | (face-font face t))) | ||
| 974 | (if (listp font) | ||
| 975 | (setq font nil)) | ||
| 976 | (setq font (or font | ||
| 977 | (face-font 'default frame) | ||
| 978 | (cdr (assq 'font (frame-parameters frame))))) | ||
| 979 | (or (and font (make-face-italic-internal face frame font)) | ||
| 980 | ;; We failed to find an italic version of the font. | ||
| 981 | noerror | ||
| 982 | (error "No italic version of %S" font)))))) | ||
| 983 | |||
| 984 | (defun make-face-italic-internal (face frame font) | ||
| 985 | (let (f2) | ||
| 986 | (or (and (setq f2 (x-make-font-italic font)) | ||
| 987 | (internal-try-face-font face f2 frame)) | ||
| 988 | (and (setq f2 (x-make-font-oblique font)) | ||
| 989 | (internal-try-face-font face f2 frame))))) | ||
| 990 | |||
| 991 | (defun make-face-bold-italic (face &optional frame noerror) | ||
| 992 | "Make the font of the given face be bold and italic, if possible. | ||
| 993 | If NOERROR is non-nil, return nil on failure." | ||
| 994 | (interactive (list (read-face-name "Make which face bold-italic: "))) | ||
| 995 | ;; Set the bold-p and italic-p flags, first of all. | ||
| 996 | (internal-set-face-1 face nil t 10 frame) | ||
| 997 | (internal-set-face-1 face nil t 11 frame) | ||
| 998 | (if (and (eq frame t) (listp (face-font face t))) | ||
| 999 | (set-face-font face '(bold italic) t) | ||
| 1000 | (let (font) | ||
| 1001 | (if (null frame) | ||
| 1002 | (let ((frames (frame-list))) | ||
| 1003 | ;; Make this face bold-italic in global-face-data. | ||
| 1004 | (make-face-bold-italic face t noerror) | ||
| 1005 | ;; Make this face bold in each frame. | ||
| 1006 | (while frames | ||
| 1007 | (make-face-bold-italic face (car frames) noerror) | ||
| 1008 | (setq frames (cdr frames)))) | ||
| 1009 | (setq face (internal-get-face face frame)) | ||
| 1010 | (setq font (or (face-font face frame) | ||
| 1011 | (face-font face t))) | ||
| 1012 | (if (listp font) | ||
| 1013 | (setq font nil)) | ||
| 1014 | (setq font (or font | ||
| 1015 | (face-font 'default frame) | ||
| 1016 | (cdr (assq 'font (frame-parameters frame))))) | ||
| 1017 | (or (and font (make-face-bold-italic-internal face frame font)) | ||
| 1018 | ;; We failed to find a bold italic version. | ||
| 1019 | noerror | ||
| 1020 | (error "No bold italic version of %S" font)))))) | ||
| 1021 | |||
| 1022 | (defun make-face-bold-italic-internal (face frame font) | ||
| 1023 | (let (f2 f3) | ||
| 1024 | (or (and (setq f2 (x-make-font-italic font)) | ||
| 1025 | (not (equal font f2)) | ||
| 1026 | (setq f3 (x-make-font-bold f2)) | ||
| 1027 | (not (equal f2 f3)) | ||
| 1028 | (internal-try-face-font face f3 frame)) | ||
| 1029 | (and (setq f2 (x-make-font-oblique font)) | ||
| 1030 | (not (equal font f2)) | ||
| 1031 | (setq f3 (x-make-font-bold f2)) | ||
| 1032 | (not (equal f2 f3)) | ||
| 1033 | (internal-try-face-font face f3 frame)) | ||
| 1034 | (and (setq f2 (x-make-font-italic font)) | ||
| 1035 | (not (equal font f2)) | ||
| 1036 | (setq f3 (x-make-font-demibold f2)) | ||
| 1037 | (not (equal f2 f3)) | ||
| 1038 | (internal-try-face-font face f3 frame)) | ||
| 1039 | (and (setq f2 (x-make-font-oblique font)) | ||
| 1040 | (not (equal font f2)) | ||
| 1041 | (setq f3 (x-make-font-demibold f2)) | ||
| 1042 | (not (equal f2 f3)) | ||
| 1043 | (internal-try-face-font face f3 frame))))) | ||
| 1044 | |||
| 1045 | (defun make-face-unbold (face &optional frame noerror) | ||
| 1046 | "Make the font of the given face be non-bold, if possible. | ||
| 1047 | If NOERROR is non-nil, return nil on failure." | ||
| 1048 | (interactive (list (read-face-name "Make which face non-bold: "))) | ||
| 1049 | ;; Clear the bold-p flag, first of all. | ||
| 1050 | (internal-set-face-1 face nil nil 10 frame) | ||
| 1051 | (if (and (eq frame t) (listp (face-font face t))) | ||
| 1052 | (set-face-font face (if (memq 'italic (face-font face t)) | ||
| 1053 | '(italic) nil) | ||
| 1054 | t) | ||
| 1055 | (let (font font1) | ||
| 1056 | (if (null frame) | ||
| 1057 | (let ((frames (frame-list))) | ||
| 1058 | ;; Make this face unbold in global-face-data. | ||
| 1059 | (make-face-unbold face t noerror) | ||
| 1060 | ;; Make this face unbold in each frame. | ||
| 1061 | (while frames | ||
| 1062 | (make-face-unbold face (car frames) noerror) | ||
| 1063 | (setq frames (cdr frames)))) | ||
| 1064 | (setq face (internal-get-face face frame)) | ||
| 1065 | (setq font1 (or (face-font face frame) | ||
| 1066 | (face-font face t))) | ||
| 1067 | (if (listp font1) | ||
| 1068 | (setq font1 nil)) | ||
| 1069 | (setq font1 (or font1 | ||
| 1070 | (face-font 'default frame) | ||
| 1071 | (cdr (assq 'font (frame-parameters frame))))) | ||
| 1072 | (setq font (and font1 (x-make-font-unbold font1))) | ||
| 1073 | (or (if font (internal-try-face-font face font frame)) | ||
| 1074 | noerror | ||
| 1075 | (error "No unbold version of %S" font1)))))) | ||
| 1076 | |||
| 1077 | (defun make-face-unitalic (face &optional frame noerror) | ||
| 1078 | "Make the font of the given face be non-italic, if possible. | ||
| 1079 | If NOERROR is non-nil, return nil on failure." | ||
| 1080 | (interactive (list (read-face-name "Make which face non-italic: "))) | ||
| 1081 | ;; Clear the italic-p flag, first of all. | ||
| 1082 | (internal-set-face-1 face nil nil 11 frame) | ||
| 1083 | (if (and (eq frame t) (listp (face-font face t))) | ||
| 1084 | (set-face-font face (if (memq 'bold (face-font face t)) | ||
| 1085 | '(bold) nil) | ||
| 1086 | t) | ||
| 1087 | (let (font font1) | ||
| 1088 | (if (null frame) | ||
| 1089 | (let ((frames (frame-list))) | ||
| 1090 | ;; Make this face unitalic in global-face-data. | ||
| 1091 | (make-face-unitalic face t noerror) | ||
| 1092 | ;; Make this face unitalic in each frame. | ||
| 1093 | (while frames | ||
| 1094 | (make-face-unitalic face (car frames) noerror) | ||
| 1095 | (setq frames (cdr frames)))) | ||
| 1096 | (setq face (internal-get-face face frame)) | ||
| 1097 | (setq font1 (or (face-font face frame) | ||
| 1098 | (face-font face t))) | ||
| 1099 | (if (listp font1) | ||
| 1100 | (setq font1 nil)) | ||
| 1101 | (setq font1 (or font1 | ||
| 1102 | (face-font 'default frame) | ||
| 1103 | (cdr (assq 'font (frame-parameters frame))))) | ||
| 1104 | (setq font (and font1 (x-make-font-unitalic font1))) | ||
| 1105 | (or (if font (internal-try-face-font face font frame)) | ||
| 1106 | noerror | ||
| 1107 | (error "No unitalic version of %S" font1)))))) | ||
| 1108 | |||
| 1109 | (defvar list-faces-sample-text | ||
| 1110 | "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ" | ||
| 1111 | "*Text string to display as the sample text for `list-faces-display'.") | ||
| 1112 | |||
| 1113 | ;; The name list-faces would be more consistent, but let's avoid a conflict | ||
| 1114 | ;; with Lucid, which uses that name differently. | ||
| 1115 | (defun list-faces-display () | ||
| 1116 | "List all faces, using the same sample text in each. | ||
| 1117 | The sample text is a string that comes from the variable | ||
| 1118 | `list-faces-sample-text'. | ||
| 1119 | |||
| 1120 | It is possible to give a particular face name different appearances in | ||
| 1121 | different frames. This command shows the appearance in the | ||
| 1122 | selected frame." | ||
| 1123 | (interactive) | ||
| 1124 | (let ((faces (sort (face-list) (function string-lessp))) | ||
| 1125 | (face nil) | ||
| 1126 | (frame (selected-frame)) | ||
| 1127 | disp-frame window | ||
| 1128 | (face-name-max-length | ||
| 1129 | (car (sort (mapcar (function string-width) | ||
| 1130 | (mapcar (function symbol-name) (face-list))) | ||
| 1131 | (function >))))) | ||
| 1132 | (with-output-to-temp-buffer "*Faces*" | ||
| 1133 | (save-excursion | ||
| 1134 | (set-buffer standard-output) | ||
| 1135 | (setq truncate-lines t) | ||
| 1136 | (while faces | ||
| 1137 | (setq face (car faces)) | ||
| 1138 | (setq faces (cdr faces)) | ||
| 1139 | (insert (format | ||
| 1140 | (format "%%-%ds " | ||
| 1141 | face-name-max-length) | ||
| 1142 | (symbol-name face))) | ||
| 1143 | (let ((beg (point))) | ||
| 1144 | (insert list-faces-sample-text) | ||
| 1145 | (insert "\n") | ||
| 1146 | (put-text-property beg (1- (point)) 'face face) | ||
| 1147 | ;; If the sample text has multiple lines, line up all of them. | ||
| 1148 | (goto-char beg) | ||
| 1149 | (forward-line 1) | ||
| 1150 | (while (not (eobp)) | ||
| 1151 | (insert-char ? (1+ face-name-max-length)) | ||
| 1152 | (forward-line 1)))) | ||
| 1153 | (goto-char (point-min))) | ||
| 1154 | (print-help-return-message)) | ||
| 1155 | ;; If the *Faces* buffer appears in a different frame, | ||
| 1156 | ;; copy all the face definitions from FRAME, | ||
| 1157 | ;; so that the display will reflect the frame that was selected. | ||
| 1158 | (setq window (get-buffer-window (get-buffer "*Faces*") t)) | ||
| 1159 | (setq disp-frame (if window (window-frame window) | ||
| 1160 | (car (frame-list)))) | ||
| 1161 | (or (eq frame disp-frame) | ||
| 1162 | (let ((faces (face-list))) | ||
| 1163 | (while faces | ||
| 1164 | (copy-face (car faces) (car faces) frame disp-frame) | ||
| 1165 | (setq faces (cdr faces))))))) | ||
| 1166 | |||
| 1167 | (defun describe-face (face) | ||
| 1168 | "Display the properties of face FACE." | ||
| 1169 | (interactive (list (read-face-name "Describe face: "))) | ||
| 1170 | (with-output-to-temp-buffer "*Help*" | ||
| 1171 | (princ "Properties of face `") | ||
| 1172 | (princ (face-name face)) | ||
| 1173 | (princ "':") (terpri) | ||
| 1174 | (princ "Foreground: ") (princ (face-foreground face)) (terpri) | ||
| 1175 | (princ "Background: ") (princ (face-background face)) (terpri) | ||
| 1176 | (princ " Font: ") (princ (face-font face)) (terpri) | ||
| 1177 | (princ "Underlined: ") (princ (if (face-underline-p face) "yes" "no")) (terpri) | ||
| 1178 | (princ " Stipple: ") (princ (or (face-stipple face) "none")) (terpri) | ||
| 1179 | (terpri) | ||
| 1180 | (princ "Documentation:") (terpri) | ||
| 1181 | (let ((doc (face-documentation face))) | ||
| 1182 | (if doc | ||
| 1183 | (princ doc) | ||
| 1184 | (princ "not documented as a face."))) | ||
| 1185 | (print-help-return-message))) | ||
| 1186 | |||
| 1187 | ;;; Setting a face based on a SPEC. | ||
| 1188 | |||
| 1189 | (defun face-attr-match-p (face attrs &optional frame) | ||
| 1190 | (or frame (setq frame (selected-frame))) | ||
| 1191 | (and (face-attr-match-1 face frame attrs ':inverse-video | ||
| 1192 | 'face-inverse-video-p) | ||
| 1193 | (if (face-inverse-video-p face frame) | ||
| 1194 | (and | ||
| 1195 | (face-attr-match-1 face frame attrs | ||
| 1196 | ':foreground 'face-background | ||
| 1197 | (cdr (assq 'foreground-color | ||
| 1198 | (frame-parameters frame)))) | ||
| 1199 | (face-attr-match-1 face frame attrs | ||
| 1200 | ':background 'face-foreground | ||
| 1201 | (cdr (assq 'background-color | ||
| 1202 | (frame-parameters frame))))) | ||
| 1203 | (and | ||
| 1204 | (face-attr-match-1 face frame attrs ':foreground 'face-foreground) | ||
| 1205 | (face-attr-match-1 face frame attrs ':background 'face-background))) | ||
| 1206 | (face-attr-match-1 face frame attrs ':stipple 'face-stipple) | ||
| 1207 | (face-attr-match-1 face frame attrs ':bold 'face-bold-p) | ||
| 1208 | (face-attr-match-1 face frame attrs ':italic 'face-italic-p) | ||
| 1209 | (face-attr-match-1 face frame attrs ':underline 'face-underline-p) | ||
| 1210 | )) | ||
| 1211 | |||
| 1212 | (defun face-attr-match-1 (face frame plist property function | ||
| 1213 | &optional defaultval) | ||
| 1214 | (while (and plist (not (eq (car plist) property))) | ||
| 1215 | (setq plist (cdr (cdr plist)))) | ||
| 1216 | (eq (funcall function face frame) | ||
| 1217 | (if plist | ||
| 1218 | (nth 1 plist) | ||
| 1219 | (or defaultval | ||
| 1220 | (funcall function 'default frame))))) | ||
| 1221 | |||
| 1222 | (defun face-spec-match-p (face spec &optional frame) | ||
| 1223 | "Return t if FACE, on FRAME, matches what SPEC says it should look like." | ||
| 1224 | (face-attr-match-p face (face-spec-choose spec frame) frame)) | ||
| 1225 | |||
| 1226 | (defun face-attr-construct (face &optional frame) | ||
| 1227 | "Return a defface-style attribute list for FACE, as it exists on FRAME." | ||
| 1228 | (let (result) | ||
| 1229 | (if (face-inverse-video-p face frame) | ||
| 1230 | (progn | ||
| 1231 | (setq result (cons ':inverse-video (cons t result))) | ||
| 1232 | (or (face-attr-match-1 face frame nil | ||
| 1233 | ':foreground 'face-background | ||
| 1234 | (cdr (assq 'foreground-color | ||
| 1235 | (frame-parameters frame)))) | ||
| 1236 | (setq result (cons ':foreground | ||
| 1237 | (cons (face-foreground face frame) result)))) | ||
| 1238 | (or (face-attr-match-1 face frame nil | ||
| 1239 | ':background 'face-foreground | ||
| 1240 | (cdr (assq 'background-color | ||
| 1241 | (frame-parameters frame)))) | ||
| 1242 | (setq result (cons ':background | ||
| 1243 | (cons (face-background face frame) result))))) | ||
| 1244 | (if (face-foreground face frame) | ||
| 1245 | (setq result (cons ':foreground | ||
| 1246 | (cons (face-foreground face frame) result)))) | ||
| 1247 | (if (face-background face frame) | ||
| 1248 | (setq result (cons ':background | ||
| 1249 | (cons (face-background face frame) result))))) | ||
| 1250 | (if (face-stipple face frame) | ||
| 1251 | (setq result (cons ':stipple | ||
| 1252 | (cons (face-stipple face frame) result)))) | ||
| 1253 | (if (face-bold-p face frame) | ||
| 1254 | (setq result (cons ':bold | ||
| 1255 | (cons (face-bold-p face frame) result)))) | ||
| 1256 | (if (face-italic-p face frame) | ||
| 1257 | (setq result (cons ':italic | ||
| 1258 | (cons (face-italic-p face frame) result)))) | ||
| 1259 | (if (face-underline-p face frame) | ||
| 1260 | (setq result (cons ':underline | ||
| 1261 | (cons (face-underline-p face frame) result)))) | ||
| 1262 | result)) | ||
| 1263 | |||
| 1264 | ;; Choose the proper attributes for FRAME, out of SPEC. | ||
| 1265 | (defun face-spec-choose (spec &optional frame) | ||
| 1266 | (or frame (setq frame (selected-frame))) | ||
| 1267 | (let ((tail spec) | ||
| 1268 | result) | ||
| 1269 | (while tail | ||
| 1270 | (let* ((entry (car tail)) | ||
| 1271 | (display (nth 0 entry)) | ||
| 1272 | (attrs (nth 1 entry))) | ||
| 1273 | (setq tail (cdr tail)) | ||
| 1274 | (when (face-spec-set-match-display display frame) | ||
| 1275 | (setq result attrs tail nil)))) | ||
| 1276 | result)) | ||
| 1277 | |||
| 1278 | (defun face-spec-set (face spec &optional frame) | ||
| 1279 | "Set FACE's face attributes according to the first matching entry in SPEC. | ||
| 1280 | If optional FRAME is non-nil, set it for that frame only. | ||
| 1281 | If it is nil, then apply SPEC to each frame individually. | ||
| 1282 | See `defface' for information about SPEC." | ||
| 1283 | (if frame | ||
| 1284 | (let ((attrs (face-spec-choose spec frame))) | ||
| 1285 | (when attrs | ||
| 1286 | ;; If the font was set automatically, clear it out | ||
| 1287 | ;; to allow it to be set it again. | ||
| 1288 | (unless (face-font-explicit face frame) | ||
| 1289 | (set-face-font face nil frame)) | ||
| 1290 | (modify-face face '(nil) '(nil) nil nil nil nil nil frame) | ||
| 1291 | (face-spec-set-1 face frame attrs ':foreground 'set-face-foreground) | ||
| 1292 | (face-spec-set-1 face frame attrs ':background 'set-face-background) | ||
| 1293 | (face-spec-set-1 face frame attrs ':stipple 'set-face-stipple) | ||
| 1294 | (face-spec-set-1 face frame attrs ':bold 'set-face-bold-p) | ||
| 1295 | (face-spec-set-1 face frame attrs ':italic 'set-face-italic-p) | ||
| 1296 | (face-spec-set-1 face frame attrs ':underline 'set-face-underline-p) | ||
| 1297 | (face-spec-set-1 face frame attrs ':inverse-video | ||
| 1298 | 'set-face-inverse-video-p))) | ||
| 1299 | (let ((frames (frame-list)) | ||
| 1300 | frame) | ||
| 1301 | (while frames | ||
| 1302 | (setq frame (car frames) | ||
| 1303 | frames (cdr frames)) | ||
| 1304 | (face-spec-set face (or (get face 'saved-face) | ||
| 1305 | (get face 'face-defface-spec)) | ||
| 1306 | frame) | ||
| 1307 | (face-spec-set face spec frame))))) | ||
| 1308 | |||
| 1309 | (defun face-spec-set-1 (face frame plist property function) | ||
| 1310 | (while (and plist (not (eq (car plist) property))) | ||
| 1311 | (setq plist (cdr (cdr plist)))) | ||
| 1312 | (if plist | ||
| 1313 | (funcall function face (nth 1 plist) frame))) | ||
| 1314 | |||
| 1315 | (defun face-spec-set-match-display (display frame) | ||
| 1316 | "Non-nil iff DISPLAY matches FRAME. | ||
| 1317 | DISPLAY is part of a spec such as can be used in `defface'. | ||
| 1318 | If FRAME is nil, the current FRAME is used." | ||
| 1319 | (let* ((conjuncts display) | ||
| 1320 | conjunct req options | ||
| 1321 | ;; t means we have succeeded against all | ||
| 1322 | ;; the conjunts in DISPLAY that have been tested so far. | ||
| 1323 | (match t)) | ||
| 1324 | (if (eq conjuncts t) | ||
| 1325 | (setq conjuncts nil)) | ||
| 1326 | (while (and conjuncts match) | ||
| 1327 | (setq conjunct (car conjuncts) | ||
| 1328 | conjuncts (cdr conjuncts) | ||
| 1329 | req (car conjunct) | ||
| 1330 | options (cdr conjunct) | ||
| 1331 | match (cond ((eq req 'type) | ||
| 1332 | (memq window-system options)) | ||
| 1333 | ((eq req 'class) | ||
| 1334 | (memq (frame-parameter frame 'display-type) options)) | ||
| 1335 | ((eq req 'background) | ||
| 1336 | (memq (frame-parameter frame 'background-mode) | ||
| 1337 | options)) | ||
| 1338 | (t | ||
| 1339 | (error "Unknown req `%S' with options `%S'" | ||
| 1340 | req options))))) | ||
| 1341 | match)) | ||
| 1342 | |||
| 1343 | ;; Like x-create-frame but also set up the faces. | ||
| 1344 | |||
| 1345 | (defun x-create-frame-with-faces (&optional parameters) | ||
| 1346 | ;; Read this frame's geometry resource, if it has an explicit name, | ||
| 1347 | ;; and put the specs into PARAMETERS. | ||
| 1348 | (let* ((name (or (cdr (assq 'name parameters)) | ||
| 1349 | (cdr (assq 'name default-frame-alist)))) | ||
| 1350 | (x-resource-name name) | ||
| 1351 | (res-geometry (if name (x-get-resource "geometry" "Geometry")))) | ||
| 1352 | (if res-geometry | ||
| 1353 | (let ((parsed (x-parse-geometry res-geometry))) | ||
| 1354 | ;; If the resource specifies a position, | ||
| 1355 | ;; call the position and size "user-specified". | ||
| 1356 | (if (or (assq 'top parsed) (assq 'left parsed)) | ||
| 1357 | (setq parsed (append '((user-position . t) (user-size . t)) | ||
| 1358 | parsed))) | ||
| 1359 | ;; Put the geometry parameters at the end. | ||
| 1360 | ;; Copy default-frame-alist so that they go after it. | ||
| 1361 | (setq parameters (append parameters default-frame-alist parsed))))) | ||
| 1362 | |||
| 1363 | (if default-enable-multibyte-characters | ||
| 1364 | ;; If an ASCII font is specified in PARAMETERS, we try to create | ||
| 1365 | ;; a fontset from it, and use it for the new frame. | ||
| 1366 | (condition-case nil | ||
| 1367 | (let ((font (cdr (assq 'font parameters)))) | ||
| 1368 | (if (and font | ||
| 1369 | (not (query-fontset font))) | ||
| 1370 | (setq parameters | ||
| 1371 | (cons (cons 'font (create-fontset-from-ascii-font font)) | ||
| 1372 | parameters)))) | ||
| 1373 | (error nil))) | ||
| 1374 | |||
| 1375 | (let (frame) | ||
| 1376 | (if (null global-face-data) | ||
| 1377 | (progn | ||
| 1378 | (setq frame (x-create-frame parameters)) | ||
| 1379 | (frame-set-background-mode frame)) | ||
| 1380 | (let* ((visibility-spec (assq 'visibility parameters)) | ||
| 1381 | success faces rest) | ||
| 1382 | (setq frame (x-create-frame (cons '(visibility . nil) parameters))) | ||
| 1383 | (unwind-protect | ||
| 1384 | (progn | ||
| 1385 | ;; Copy the face alist, copying the face vectors | ||
| 1386 | ;; and emptying out their attributes. | ||
| 1387 | (setq faces | ||
| 1388 | (mapcar '(lambda (elt) | ||
| 1389 | (cons (car elt) | ||
| 1390 | (vector 'face | ||
| 1391 | (face-name (cdr elt)) | ||
| 1392 | (face-id (cdr elt)) | ||
| 1393 | nil | ||
| 1394 | nil nil nil nil | ||
| 1395 | nil nil nil nil))) | ||
| 1396 | global-face-data)) | ||
| 1397 | (set-frame-face-alist frame faces) | ||
| 1398 | |||
| 1399 | ;; Handle the reverse-video frame parameter | ||
| 1400 | ;; and X resource. x-create-frame does not handle this one. | ||
| 1401 | (if (cdr (or (assq 'reverse parameters) | ||
| 1402 | (assq 'reverse default-frame-alist) | ||
| 1403 | (let ((resource (x-get-resource "reverseVideo" | ||
| 1404 | "ReverseVideo"))) | ||
| 1405 | (if resource | ||
| 1406 | (cons nil (member (downcase resource) | ||
| 1407 | '("on" "true"))))))) | ||
| 1408 | (let* ((params (frame-parameters frame)) | ||
| 1409 | (bg (cdr (assq 'foreground-color params))) | ||
| 1410 | (fg (cdr (assq 'background-color params)))) | ||
| 1411 | (modify-frame-parameters frame | ||
| 1412 | (list (cons 'foreground-color fg) | ||
| 1413 | (cons 'background-color bg))) | ||
| 1414 | (if (equal bg (cdr (assq 'border-color params))) | ||
| 1415 | (modify-frame-parameters frame | ||
| 1416 | (list (cons 'border-color fg)))) | ||
| 1417 | (if (equal bg (cdr (assq 'mouse-color params))) | ||
| 1418 | (modify-frame-parameters frame | ||
| 1419 | (list (cons 'mouse-color fg)))) | ||
| 1420 | (if (equal bg (cdr (assq 'cursor-color params))) | ||
| 1421 | (modify-frame-parameters frame | ||
| 1422 | (list (cons 'cursor-color fg)))))) | ||
| 1423 | |||
| 1424 | (frame-set-background-mode frame) | ||
| 1425 | |||
| 1426 | (face-set-after-frame-default frame) | ||
| 1427 | |||
| 1428 | ;; Make the frame visible, if desired. | ||
| 1429 | (if (null visibility-spec) | ||
| 1430 | (make-frame-visible frame) | ||
| 1431 | (modify-frame-parameters frame (list visibility-spec))) | ||
| 1432 | (setq success t)) | ||
| 1433 | (or success | ||
| 1434 | (delete-frame frame))))) | ||
| 1435 | frame)) | ||
| 1436 | |||
| 1437 | ;; Update a frame's faces after the frame font changes. | ||
| 1438 | ;; This is called from modify-frame-parameters | ||
| 1439 | ;; as well as from elsewhere in this file. | ||
| 1440 | (defun face-set-after-frame-default (frame) | ||
| 1441 | (let ((rest (frame-face-alist frame))) | ||
| 1442 | (while rest | ||
| 1443 | ;; Set up each face, first from the defface information, | ||
| 1444 | ;; then the global face data, and then the X resources. | ||
| 1445 | (let* ((face (car (car rest))) | ||
| 1446 | (spec (or (get face 'customized-face) | ||
| 1447 | (get face 'saved-face) | ||
| 1448 | (get face 'face-defface-spec))) | ||
| 1449 | (global (cdr (assq face global-face-data))) | ||
| 1450 | (local (cdr (car rest)))) | ||
| 1451 | (when spec | ||
| 1452 | (face-spec-set face spec frame)) | ||
| 1453 | (face-fill-in face global frame) | ||
| 1454 | (make-face-x-resource-internal local frame)) | ||
| 1455 | (setq rest (cdr rest))))) | ||
| 1456 | |||
| 1457 | (defcustom frame-background-mode nil | ||
| 1458 | "*The brightness of the background. | ||
| 1459 | Set this to the symbol dark if your background color is dark, light if | ||
| 1460 | your background is light, or nil (default) if you want Emacs to | ||
| 1461 | examine the brightness for you." | ||
| 1462 | :group 'faces | ||
| 1463 | :set #'(lambda (var value) | ||
| 1464 | (set var value) | ||
| 1465 | (mapcar 'frame-set-background-mode (frame-list))) | ||
| 1466 | :initialize 'custom-initialize-changed | ||
| 1467 | :type '(choice (choice-item dark) | ||
| 1468 | (choice-item light) | ||
| 1469 | (choice-item :tag "default" nil))) | ||
| 1470 | |||
| 1471 | (defun frame-set-background-mode (frame) | ||
| 1472 | "Set up the `background-mode' and `display-type' frame parameters for FRAME." | ||
| 1473 | (unless (eq (framep frame) t) | ||
| 1474 | (let ((bg-resource (x-get-resource ".backgroundMode" | ||
| 1475 | "BackgroundMode")) | ||
| 1476 | (params (frame-parameters frame)) | ||
| 1477 | (bg-mode)) | ||
| 1478 | (setq bg-mode | ||
| 1479 | (cond (frame-background-mode) | ||
| 1480 | (bg-resource (intern (downcase bg-resource))) | ||
| 1481 | ((< (apply '+ (x-color-values | ||
| 1482 | (cdr (assq 'background-color params)) | ||
| 1483 | frame)) | ||
| 1484 | ;; Just looking at the screen, | ||
| 1485 | ;; colors whose values add up to .6 of the white total | ||
| 1486 | ;; still look dark to me. | ||
| 1487 | (* (apply '+ (x-color-values "white" frame)) .6)) | ||
| 1488 | 'dark) | ||
| 1489 | (t 'light))) | ||
| 1490 | (modify-frame-parameters frame | ||
| 1491 | (list (cons 'background-mode bg-mode) | ||
| 1492 | (cons 'display-type | ||
| 1493 | (cond ((x-display-color-p frame) | ||
| 1494 | 'color) | ||
| 1495 | ((x-display-grayscale-p frame) | ||
| 1496 | 'grayscale) | ||
| 1497 | (t 'mono)))))))) | ||
| 1498 | |||
| 1499 | ;; Update a frame's faces when we change its default font. | ||
| 1500 | (defun frame-update-faces (frame) nil) | ||
| 1501 | |||
| 1502 | ;; Update the colors of FACE, after FRAME's own colors have been changed. | ||
| 1503 | ;; This applies only to faces with global color specifications | ||
| 1504 | ;; that are not simple constants. | ||
| 1505 | (defun frame-update-face-colors (frame) | ||
| 1506 | (frame-set-background-mode frame) | ||
| 1507 | (let ((faces global-face-data)) | ||
| 1508 | (while faces | ||
| 1509 | (condition-case nil | ||
| 1510 | (let* ((data (cdr (car faces))) | ||
| 1511 | (face (car (car faces))) | ||
| 1512 | (foreground (face-foreground data)) | ||
| 1513 | (background (face-background data))) | ||
| 1514 | ;; If the global spec is a specific color, | ||
| 1515 | ;; which doesn't depend on the frame's attributes, | ||
| 1516 | ;; we don't need to recalculate it now. | ||
| 1517 | (or (listp foreground) | ||
| 1518 | (setq foreground nil)) | ||
| 1519 | (or (listp background) | ||
| 1520 | (setq background nil)) | ||
| 1521 | ;; If we are going to frob this face at all, | ||
| 1522 | ;; reinitialize it first. | ||
| 1523 | (if (or foreground background) | ||
| 1524 | (progn (set-face-foreground face nil frame) | ||
| 1525 | (set-face-background face nil frame))) | ||
| 1526 | (if foreground | ||
| 1527 | (face-try-color-list 'set-face-foreground | ||
| 1528 | face foreground frame)) | ||
| 1529 | (if background | ||
| 1530 | (face-try-color-list 'set-face-background | ||
| 1531 | face background frame))) | ||
| 1532 | (error nil)) | ||
| 1533 | (setq faces (cdr faces))))) | ||
| 1534 | |||
| 1535 | ;; Fill in the face FACE from frame-independent face data DATA. | ||
| 1536 | ;; DATA should be the non-frame-specific ("global") face vector | ||
| 1537 | ;; for the face. FACE should be a face name or face object. | ||
| 1538 | ;; FRAME is the frame to act on; it must be an actual frame, not nil or t. | ||
| 1539 | (defun face-fill-in (face data frame) | ||
| 1540 | (condition-case nil | ||
| 1541 | (let ((foreground (face-foreground data)) | ||
| 1542 | (background (face-background data)) | ||
| 1543 | (font (face-font data)) | ||
| 1544 | (stipple (face-stipple data))) | ||
| 1545 | (if (face-underline-p data) | ||
| 1546 | (set-face-underline-p face (face-underline-p data) frame)) | ||
| 1547 | (if foreground | ||
| 1548 | (face-try-color-list 'set-face-foreground | ||
| 1549 | face foreground frame)) | ||
| 1550 | (if background | ||
| 1551 | (face-try-color-list 'set-face-background | ||
| 1552 | face background frame)) | ||
| 1553 | (if (listp font) | ||
| 1554 | (let ((bold (memq 'bold font)) | ||
| 1555 | (italic (memq 'italic font))) | ||
| 1556 | (cond ((and bold italic) | ||
| 1557 | (make-face-bold-italic face frame)) | ||
| 1558 | (bold | ||
| 1559 | (make-face-bold face frame)) | ||
| 1560 | (italic | ||
| 1561 | (make-face-italic face frame)))) | ||
| 1562 | (if font | ||
| 1563 | (set-face-font face font frame))) | ||
| 1564 | (if stipple | ||
| 1565 | (set-face-stipple face stipple frame))) | ||
| 1566 | (error nil))) | ||
| 1567 | |||
| 1568 | ;; Assuming COLOR is a valid color name, | ||
| 1569 | ;; return t if it can be displayed on FRAME. | ||
| 1570 | (defun face-color-supported-p (frame color background-p) | ||
| 1571 | (and window-system | ||
| 1572 | (or (x-display-color-p frame) | ||
| 1573 | ;; A black-and-white display can implement these. | ||
| 1574 | (member color '("black" "white")) | ||
| 1575 | ;; A black-and-white display can fake gray for background. | ||
| 1576 | (and background-p | ||
| 1577 | (face-color-gray-p color frame)) | ||
| 1578 | ;; A grayscale display can implement colors that are gray (more or less). | ||
| 1579 | (and (x-display-grayscale-p frame) | ||
| 1580 | (face-color-gray-p color frame))))) | ||
| 1581 | |||
| 1582 | ;; Use FUNCTION to store a color in FACE on FRAME. | ||
| 1583 | ;; COLORS is either a single color or a list of colors. | ||
| 1584 | ;; If it is a list, try the colors one by one until one of them | ||
| 1585 | ;; succeeds. We signal an error only if all the colors failed. | ||
| 1586 | ;; t as COLORS or as an element of COLORS means to invert the face. | ||
| 1587 | ;; That can't fail, so any subsequent elements after the t are ignored. | ||
| 1588 | (defun face-try-color-list (function face colors frame) | ||
| 1589 | (if (stringp colors) | ||
| 1590 | (if (face-color-supported-p frame colors | ||
| 1591 | (eq function 'set-face-background)) | ||
| 1592 | (funcall function face colors frame)) | ||
| 1593 | (if (eq colors t) | ||
| 1594 | (set-face-inverse-video-p face t frame) | ||
| 1595 | (let (done) | ||
| 1596 | (while (and colors (not done)) | ||
| 1597 | (if (or (memq (car colors) '(t underline nil)) | ||
| 1598 | (face-color-supported-p frame (car colors) | ||
| 1599 | (eq function 'set-face-background))) | ||
| 1600 | (if (cdr colors) | ||
| 1601 | ;; If there are more colors to try, catch errors | ||
| 1602 | ;; and set `done' if we succeed. | ||
| 1603 | (condition-case nil | ||
| 1604 | (progn | ||
| 1605 | (cond ((eq (car colors) t) | ||
| 1606 | (set-face-inverse-video-p face t frame)) | ||
| 1607 | ((eq (car colors) 'underline) | ||
| 1608 | (set-face-underline-p face t frame)) | ||
| 1609 | (t | ||
| 1610 | (funcall function face (car colors) frame))) | ||
| 1611 | (setq done t)) | ||
| 1612 | (error nil)) | ||
| 1613 | ;; If this is the last color, let the error get out if it fails. | ||
| 1614 | ;; If it succeeds, we will exit anyway after this iteration. | ||
| 1615 | (cond ((eq (car colors) t) | ||
| 1616 | (set-face-inverse-video-p face t frame)) | ||
| 1617 | ((eq (car colors) 'underline) | ||
| 1618 | (set-face-underline-p face t frame)) | ||
| 1619 | (t | ||
| 1620 | (funcall function face (car colors) frame))))) | ||
| 1621 | (setq colors (cdr colors))))))) | ||
| 1622 | |||
| 1623 | ;;; Make the standard faces. | ||
| 1624 | ;;; The C code knows the default and modeline faces as faces 0 and 1, | ||
| 1625 | ;;; so they must be the first two faces made. | ||
| 1626 | (make-face 'default) | ||
| 1627 | (make-face 'modeline) | ||
| 1628 | (make-face 'highlight) | ||
| 1629 | |||
| 1630 | ;; These aren't really special in any way, but they're nice to have around. | ||
| 1631 | |||
| 1632 | (make-face 'bold) | ||
| 1633 | (make-face 'italic) | ||
| 1634 | (make-face 'bold-italic) | ||
| 1635 | (make-face 'region) | ||
| 1636 | (make-face 'secondary-selection) | ||
| 1637 | (make-face 'underline) | ||
| 1638 | |||
| 1639 | (setq region-face (face-id 'region)) | ||
| 1640 | |||
| 1641 | (defgroup basic-faces nil | ||
| 1642 | "The standard faces of Emacs." | ||
| 1643 | :prefix "huh" | ||
| 1644 | :group 'faces) | ||
| 1645 | 1616 | ||
| 1646 | ;; Specify how these faces look, and their documentation. | ||
| 1647 | (let ((all '((bold "Use bold font." ((t (:bold t)))) | ||
| 1648 | (bold-italic "Use bold italic font." ((t (:bold t :italic t)))) | ||
| 1649 | (italic "Use italic font." ((t (:italic t)))) | ||
| 1650 | (underline "Underline text." ((t (:underline t)))) | ||
| 1651 | (default "Used for text not covered by other faces." ((t nil))) | ||
| 1652 | (highlight "Highlight text in some way." | ||
| 1653 | ((((class color) (background light)) | ||
| 1654 | (:background "darkseagreen2")) | ||
| 1655 | (((class color) (background dark)) | ||
| 1656 | (:background "darkolivegreen")) | ||
| 1657 | (t (:inverse-video t)))) | ||
| 1658 | (modeline "Used for displaying the modeline." | ||
| 1659 | ((t (:inverse-video t)))) | ||
| 1660 | (region "Used for displaying the region." | ||
| 1661 | ((((class color) (background dark)) | ||
| 1662 | (:background "blue")) | ||
| 1663 | (t (:background "gray")))) | ||
| 1664 | (secondary-selection | ||
| 1665 | "Used for displaying the secondary selection." | ||
| 1666 | ((((class color) (background light)) | ||
| 1667 | (:background "paleturquoise")) | ||
| 1668 | (((class color) (background dark)) | ||
| 1669 | (:background "darkslateblue")) | ||
| 1670 | (t (:inverse-video t)))))) | ||
| 1671 | entry symbol doc spec) | ||
| 1672 | (while all | ||
| 1673 | (setq entry (car all) | ||
| 1674 | all (cdr all) | ||
| 1675 | symbol (nth 0 entry) | ||
| 1676 | doc (nth 1 entry) | ||
| 1677 | spec (nth 2 entry)) | ||
| 1678 | (custom-add-to-group 'basic-faces symbol 'custom-face) | ||
| 1679 | (put symbol 'face-documentation doc) | ||
| 1680 | (put symbol 'face-defface-spec spec))) | ||
| 1681 | 1617 | ||
| 1682 | (provide 'faces) | 1618 | (provide 'faces) |
| 1683 | 1619 | ||
| 1684 | ;;; faces.el ends here | 1620 | ;;; end of faces.el |