aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorGerd Moellmann1999-07-21 21:43:52 +0000
committerGerd Moellmann1999-07-21 21:43:52 +0000
commit5f5c8ee54adcf263da9c3dcc1db243b26724c04d (patch)
treef18b5a842b4abf31ec7c4480e8c0df7cacec99b3 /lisp
parent7eb0330213eae25cac6204a2c97a737e7c501bf8 (diff)
downloademacs-5f5c8ee54adcf263da9c3dcc1db243b26724c04d.tar.gz
emacs-5f5c8ee54adcf263da9c3dcc1db243b26724c04d.zip
Complete rewrite.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/faces.el2758
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.
46Each of the four symbols `:width', `:height', `:weight', and `:slant'
47must appear once in the list, and the list must not contain any other
48elements. Font selection tries to find a best matching font for
49those face attributes first that appear first in the list. For
50example, if `:slant' appears before `:height', font selection first
51tries to find a font with a suitable slant, even if this results in
52a 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.
64Each element has the the form (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...).
65If fonts of family FAMILY can't be loaded, try ALTERNATIVE1, then
66ALTERNATIVE2 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.
89NO-INIT-FROM-RESOURCES non-nil means don't initialize frame-local
90variants of FACE from X resources. (X resources recognized are found
91in the global variable `face-x-resources'.) If FACE is already known
92as 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.
109If 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
117If NEW-FACE already exists as a face, it is modified to be like
118OLD-FACE. If it doesn't already exist, it is created.
119
120If the optional argument FRAME is given as a frame, NEW-FACE is
121changed on FRAME only.
122If FRAME is t, the frame-independent default specification for OLD-FACE
123is copied to NEW-FACE.
124If FRAME is nil, copying is done for the frame-independent defaults
125and for each existing frame.
126
127If the optional fourth argument NEW-FRAME is given,
128copy the information from face OLD-FACE on frame FRAME
129to 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.
151Return nil if there is no such face.
152If the optional argument FRAME is given, this gets the face NAME for
153that frame; otherwise, it uses the selected frame.
154If FRAME is the symbol t, then the global, non-frame face is returned.
155If NAME is already a face, it is simply returned.
156
157This function is defined for compatibility with Emacs 20.2. It
158should 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.
164If the optional argument FRAME is given, this gets the face NAME for
165that frame; otherwise, it uses the selected frame.
166If FRAME is the symbol t, then the global, non-frame face is returned.
167If NAME is already a face, it is simply returned.
168
169This function is defined for compatibility with Emacs 20.2. It
170should 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.
187Value 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.
199If 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.
206Faces are considered equal if all their attributes are equal.
207If the optional argument FRAME is given, report on face FACE in that frame.
208If FRAME is t, report on the defaults for face FACE (for new frames).
209If 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.
215If the optional argument FRAME is given, report on face FACE in that frame.
216If FRAME is t, report on the defaults for face FACE (for new frames).
217If FRAME is omitted or nil, use the selected frame.
218A face is considered to be ``the same'' as the default face if it is
219actually specified in the same way (equal attributes) or if it is
220fully-unspecified, and thus inherits the attributes of any face it
221is 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.
228If the optional argument FRAME is given, report on face FACE in that frame.
229If FRAME is t, report on the defaults for face FACE (for new frames).
230If 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.
260Each element has the form (ATTRIBUTE ENTRY1 ENTRY2...) where ATTRIBUTE is
261the 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
263X 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.
270Value is the attribute value specified by the resource, or nil
271if not present. This function displays a message if the resource
272specifies 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.
298FRAME 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.
77If the optional argument FRAME is given, report on face FACE in that frame. 317If the optional argument FRAME is given, report on face FACE in that frame.
78If FRAME is t, report on the defaults for face FACE (for new frames). 318If 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).
81If FRAME is omitted or nil, use the selected frame." 319If 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.
86If the optional argument FRAME is given, report on face FACE in that frame. 325If the optional argument FRAME is given, report on face FACE in that frame.
87If FRAME is t, report on the defaults for face FACE (for new frames). 326If FRAME is t, report on the defaults for face FACE (for new frames).
88If FRAME is omitted or nil, use the selected frame." 327If 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.
93If the optional argument FRAME is given, report on face FACE in that frame. 333If the optional argument FRAME is given, report on face FACE in that frame.
94If FRAME is t, report on the defaults for face FACE (for new frames). 334If FRAME is t, report on the defaults for face FACE (for new frames).
95If FRAME is omitted or nil, use the selected frame." 335If 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.
100If the optional argument FRAME is given, report on face FACE in that frame. 341If the optional argument FRAME is given, report on face FACE in that frame.
101If FRAME is t, report on the defaults for face FACE (for new frames). 342If FRAME is t, report on the defaults for face FACE (for new frames).
102If FRAME is omitted or nil, use the selected frame." 343If 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.
109If the optional argument FRAME is given, report on face FACE in that frame. 352If the optional argument FRAME is given, report on face FACE in that frame.
110If FRAME is t, report on the defaults for face FACE (for new frames). 353If FRAME is t, report on the defaults for face FACE (for new frames).
111If FRAME is omitted or nil, use the selected frame." 354If 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.
116If the optional argument FRAME is given, report on face FACE in that frame. 360If the optional argument FRAME is given, report on face FACE in that frame.
117If FRAME is t, report on the defaults for face FACE (for new frames). 361If FRAME is t, report on the defaults for face FACE (for new frames).
118If FRAME is omitted or nil, use the selected frame." 362If 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.
127If the optional argument FRAME is given, report on face FACE in that frame. 368If the optional argument FRAME is given, report on face FACE in that frame.
128If FRAME is t, report on the defaults for face FACE (for new frames). 369If FRAME is t, report on the defaults for face FACE (for new frames).
129If FRAME is omitted or nil, use the selected frame." 370If FRAME is omitted or nil, use the selected frame.
130 (aref (internal-get-face face frame) 10)) 371Use `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.
134If the optional argument FRAME is given, report on face FACE in that frame. 378If the optional argument FRAME is given, report on face FACE in that frame.
135If FRAME is t, report on the defaults for face FACE (for new frames). 379If FRAME is t, report on the defaults for face FACE (for new frames).
136If FRAME is omitted or nil, use the selected frame." 380If FRAME is omitted or nil, use the selected frame.
137 (aref (internal-get-face face frame) 11)) 381Use `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
416FRAME nil means change attributes on all frames. FRAME t means change
417the default for new frames (this is done automatically each time an
418attribute is changed on all frames).
419
420ARGS must come in pairs ATTRIBUTE VALUE. ATTRIBUTE must be a valid
421face attribute name. All attributes can be set to `unspecified';
422this fact is not further mentioned below.
423
424The following attributes are recognized:
425
426`:family'
427
428VALUE must be a string specifying the font family, e.g. ``courier'',
429or a fontset alias name. If a font family is specified, wild-cards `*'
430and `?' are allowed.
431
432`:width'
433
434VALUE specifies the relative proportionate width of the font to use.
435It 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
441VALUE must be an integer specifying the height of the font to use in
4421/10 pt.
443
444`:weight'
445
446VALUE specifies the weight of the font to use. It must be one of the
447symbols `ultra-bold', `extra-bold', `bold', `semi-bold', `normal',
448`semi-light', `light', `extra-light', `ultra-light'.
449
450`:slant'
451
452VALUE specifies the slant of the font to use. It must be one of the
453symbols `italic', `oblique', `normal', `reverse-italic', or
454`reverse-oblique'.
455
456`:foreground', `:background'
457
458VALUE must be a color name, a string.
459
460`:underline'
461
462VALUE specifies whether characters in FACE should be underlined. If
463VALUE is t, underline with foreground color of the face. If VALUE is
464a string, underline with that color. If VALUE is nil, explicitly
465don't underline.
466
467`:overline'
468
469VALUE specifies whether characters in FACE should be overlined. If
470VALUE is t, overline with foreground color of the face. If VALUE is a
471string, overline with that color. If VALUE is nil, explicitly don't
472overline.
473
474`:strike-through'
475
476VALUE specifies whether characters in FACE should be drawn with a line
477striking through them. If VALUE is t, use the foreground color of the
478face. If VALUE is a string, strike-through with that color. If VALUE
479is nil, explicitly don't strike through.
480
481`:box'
482
483VALUE specifies whether characters in FACE should have a box drawn
484around them. If VALUE is nil, explicitly don't draw boxes. If
485VALUE is t, draw a box with lines of width 1 in the foreground color
486of the face. If VALUE is a string, the string must be a color name,
487and the box is drawn in that color with a line width of 1. Otherwise,
488VALUE must be a property list of the form `(:line-width WIDTH
489:color COLOR :style STYLE)'. If a keyword/value pair is missing from
490the property list, a default value will be used for the value, as
491specified below. WIDTH specifies the width of the lines to draw; it
492defaults to 1. COLOR is the name of the color to draw in, default is
493the foreground color of the face for simple boxes, and the background
494color of the face for 3D boxes. STYLE specifies whether a 3D box
495should be draw. If STYLE is `released-button', draw a box looking
496like a released 3D button. If STYLE is `pressed-button' draw a box
497that appears like a pressed button. If STYLE is nil, the default if
498the property list doesn't contain a style specification, draw a 2D
499box.
500
501`:inverse-video'
502
503VALUE specifies whether characters in FACE should be displayed in
504inverse video. VALUE must be one of t or nil.
505
506`:stipple'
507
508If VALUE is a string, it must be the name of a file of pixmap data.
509The directories listed in the `x-bitmap-file-path' variable are
510searched. Alternatively, VALUE may be a list of the form (WIDTH
511HEIGHT DATA) where WIDTH and HEIGHT are the size in pixels, and DATA
512is a string containing the raw bits of the bitmap. VALUE nil means
513explicitly don't use a stipple pattern.
514
515For convenience, attributes `:family', `:width', `:height', `:weight',
516and `:slant' may also be set in one step from an X font name:
517
518`:font'
519
520Set font-related face attributes from VALUE. VALUE must be a valid
521XLFD font name. If it is a font name pattern, the first matching font
522will be used.
523
524For compatibility with Emacs 20, keywords `:bold' and `:italic' can
525be used to specify that a bold or italic font should be used. VALUE
526must 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.
542FRAME nil or not specified means change face on all frames.
543Use `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.
550FRAME 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.
557FRAME nil or not specified means change face on all frames.
558Use `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.
565FRAME 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.
572FRAME nil or not specified means change face on all frames.
573Use `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).
148If the optional FRAME argument is provided, change only 580FRAME nil or not specified means change face on all frames.
149in that frame; otherwise change each frame." 581This sets the attributes `:family', `:width', `:height', `:weight',
150 (interactive (internal-face-interactive "font")) 582and `: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.
161An automatic change means that we don't change the \"explicit\" flag;
162if the font was derived from the frame font before, it is now.
163If the optional FRAME argument is provided, change only
164in 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.
173If the optional FRAME argument is provided, change only
174in 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
179If the optional FRAME argument is provided, change only 588;; stipple pattern is now part of the face realization process, and is
180in 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.
186This stipple pattern is used on monochrome displays
187instead of shades of gray for a face background color.
188See `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).
192FRAME 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).
204If the optional FRAME argument is provided, change only 593FRAME nil or not specified means change face on all frames.
205in that frame; otherwise change each frame." 594When 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 601FRAME nil or not specified means change face on all frames.
213 ;; because we are supposed to use stipple for them! 602When 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))) 609FRAME nil or not specified means change face on all frames.
221 (set-face-background face color t) 610STIPPLE. 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.
227PIXMAP should be a string, the name of a file of pixmap data.
228The directories listed in the `x-bitmap-file-path' variable are searched. 611The directories listed in the `x-bitmap-file-path' variable are searched.
229 612
230Alternatively, PIXMAP may be a list of the form (WIDTH HEIGHT DATA) 613Alternatively, STIPPLE may be a list of the form (WIDTH HEIGHT DATA)
231where WIDTH and HEIGHT are the size in pixels, 614where WIDTH and HEIGHT are the size in pixels,
232and DATA is a string, containing the raw bits of the bitmap. 615and 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.
622UNDERLINE nil means FACE explicitly doesn't underline.
623UNDERLINE non-nil means FACE explicitly does underlining
624with the same of the foreground color.
625If UNDERLINE is a string, underline with the color named UNDERLINE.
626FRAME nil or not specified means change face on all frames.
627Use `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
234If the optional FRAME argument is provided, change only
235in 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.
243If the optional FRAME argument is provided, change only 636UNDERLINE-P nil means FACE explicitly doesn't underline.
244in that frame; otherwise change each frame." 637UNDERLINE-P non-nil means FACE explicitly does underlining.
245 (interactive (internal-face-interactive "underline-p" "underlined")) 638FRAME nil or not specified means change face on all frames.
246 (internal-set-face-1 face 'underline underline-p 7 frame)) 639Use `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.) 648INVERSE-VIDEO-P non-nil means FACE displays explicitly in inverse video.
251If the optional FRAME argument is provided, change only 649INVERSE-VIDEO-P nil means FACE explicitly is not in inverse video.
252in that frame; otherwise change each frame." 650FRAME nil or not specified means change face on all frames.
253 (interactive (internal-face-interactive "inverse-video-p" "inverse-video")) 651Use `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.
258If the optional FRAME argument is provided, change only 660BOLD-P non-nil means FACE should explicitly display bold.
259in that frame; otherwise change each frame." 661BOLD-P nil means FACE should explicitly display non-bold.
260 (cond ((eq bold-p nil) (make-face-unbold face frame t)) 662FRAME nil or not specified means change face on all frames.
261 (t (make-face-bold face frame t)))) 663Use `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.
265If the optional FRAME argument is provided, change only 671ITALIC-P non-nil means FACE should explicitly display italic.
266in that frame; otherwise change each frame." 672ITALIC-P nil means FACE should explicitly display non-italic.
267 (cond ((eq italic-p nil) (make-face-unitalic face frame t)) 673FRAME nil or not specified means change face on all frames.
268 (t (make-face-italic face frame t)))) 674Use `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.
685FRAME nil or not specified means change face on all frames.
686If FACE specifies neither foreground nor background color,
687set its foreground and background to the background and foreground
688of 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)) 708Value 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. 718The optional argument FRAME is used to determine available fonts
292If the optional FRAME argument is provided, change only 719and colors. If it is nil or not specified, the selected frame is
293in that frame; otherwise change each frame. 720used. Value is an alist of (NAME . VALUE) if ATTRIBUTE expects a value
294 721out of a set of discrete values. Value is `integerp' if ATTRIBUTE expects
295FOREGROUND and BACKGROUND should be a colour name string (or list of strings to 722an integer value."
296try) or nil. STIPPLE should be a stipple pattern name string or nil. 723 (case attribute
297If nil, means do not change the display attribute corresponding to that arg. 724 (:family
298If (nil), that means clear out the attribute. 725 (if window-system
299 726 (mapcar #'(lambda (x) (cons (car x) (car x)))
300BOLD-P, ITALIC-P, UNDERLINE-P, and INVERSE-P specify whether 727 (x-font-family-list))
301the face should be set bold, italic, underlined or in inverse-video, 728 ;; Only one font on TTYs.
302respectively. If one of these arguments is neither nil or t, it means do not 729 (cons "default" "default")))
303change the display attribute corresponding to that argument. 730 ((:width :weight :slant :inverse-video)
304 731 (mapcar #'(lambda (x) (cons (symbol-name x) x))
305If 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 771Each element has the form (ATTRIBUTE-NAME . DESCRIPTION) where
345 (mapconcat 'identity 772ATTRIBUTE-NAME is a face attribute name (a keyword symbol), and
346 (delq nil 773DESCRIPTION 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") 783FACE is the face whose attribute is read. DEFAULT is the default
357 (and inverse-p "inverse") 784value to return if no new value is entered. NAME is a descriptive
358 (and underline-p "underline"))) ", ")) 785name of the attribute for prompting. COMPLETION-ALIST is an alist
359 (list (intern face) foreground background stipple 786of valid values, if non-nil.
360 bold-p italic-p underline-p inverse-p 787
361 (if all-frames-p nil (selected-frame))))) 788Entering ``none'' as attribute value means an unspecified attribute
362 ;; Clear this before we install the new foreground and background; 789value. 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)) 791Value 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) 808FACE is the face whose attribute is read. DEFAULT is the default
382 (if (face-font face frame) 809value to return if no new value is entered. NAME is a descriptive
383 (make-face-unbold face frame t))) 810name 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.
820Optional argument FRAME nil or unspecified means read an attribute value
821of 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.
856If 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.
864If optional argument FRAME Is nil or omitted, use the selected frame.
865Value 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.
875If optional argument FRAME is nil or omitted, modify the face used
876for 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.
885ATTRIBUTE is the attribute whose new value is read.
886FRAME nil or unspecified means read attribute value of global face.
887Value 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"
398This is an alist associating face names with the default values for 909 "*Text string to display as the sample text for `list-faces-display'.")
399their 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.
407If the optional argument FRAME is given, this gets the face NAME for
408that frame; otherwise, it uses the selected frame.
409If FRAME is the symbol t, then the global, non-frame face is returned.
410If 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.
423If the optional argument FRAME is given, this gets the face NAME for 917The sample text is a string that comes from the variable
424that frame; otherwise, it uses the selected frame. 918`list-faces-sample-text'."
425If FRAME is the symbol t, then the global, non-frame face is returned. 919 (interactive)
426If 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) 959If the optional argument FRAME is given, report on face FACE in that frame.
434 (let ((frames (frame-list))) 960If FRAME is t, report on the defaults for face FACE (for new frames).
435 (while frames 961If 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.
515You can modify the font, color, etc of this face with the set-face- functions.
516If NO-RESOURCES is non-nil, then we ignore X resources
517and always make a face whose attributes are all nil.
518
519If 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.
549You can modify the font, color, etc of this face with the set-face- functions. 1002Value is a property list of pairs ATTRIBUTE VALUE for all specified
550If the face already exists, it is unmodified." 1003face attributes of FACE where ATTRIBUTE is the attribute name and
551 (interactive "SMake empty face: ") 1004VALUE 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) 1015DISPLAY is part of a spec such as can be used in `defface'.
557 (cond ((null frame) 1016If 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.
633If NEW-FACE already exists as a face, it is modified to be like OLD-FACE.
634If it doesn't already exist, it is created.
635 1042
636If the optional argument FRAME is given as a frame, 1043(defun face-spec-choose (spec &optional frame)
637NEW-FACE is changed on FRAME only. 1044 "Choose the proper attributes for FRAME, out of SPEC."
638If FRAME is t, the frame-independent default specification for OLD-FACE 1045 (unless frame
639is copied to NEW-FACE. 1046 (setq frame (selected-frame)))
640If FRAME is nil, copying is done for the frame-independent defaults 1047 (let ((tail spec)
641and for each existing frame. 1048 result)
642If the optional fourth argument NEW-FRAME is given, 1049 (while tail
643copy the information from face OLD-FACE on frame FRAME 1050 (let* ((entry (car tail))
644to 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."
687A face is considered to be ``the same'' as the default face if it is 1061 (let ((attrs face-attribute-name-alist)
688actually specified in the same way (equivalent fonts, etc) or if it is 1062 params)
689fully unspecified, and thus inherits the attributes of any face it 1063 (while attrs
690is displayed on top of. 1064 (let ((attr-and-name (car attrs)))
691 1065 (setq params (cons (car attr-and-name) (cons 'unspecified params))))
692The optional argument FRAME specifies which frame to test; 1066 (setq attrs (cdr attrs)))
693if FRAME is t, test the default for new frames. 1067 (apply #'set-face-attribute face frame params)))
694If 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.
717The optional argument FRAME specifies which frame to test;
718if FRAME is t, test the default for new frames.
719If 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.
1072FRAME is the frame whose frame-local face is set. FRAME nil means
1073do 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)
730If the face doesn't specify both foreground and background, then 1090 "Value is non-nil if attributes of FACE match values in plist ATTRS.
731set its foreground and background to the default background and foreground." 1091Optional parameter FRAME is the frame whose definition of FACE
732 (interactive (list (read-face-name "Invert face: "))) 1092is 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.
1119Set this to the symbol `dark' if your background color is dark, `light' if
1120your background is light, or nil (default) if you want Emacs to
1121examine 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.
1184Value 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.
1231Parameters not specified by PARAMETERS are taken from
1232`default-frame-alist'. If PARAMETERS specify a frame name,
1233handle X geometry resources for that name. If either PARAMETERS
1234or `default-frame-alist' contains a `reverse' parameter, or
1235the X resource ``reverseVideo'' is present, handle that.
1236Value 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.
1270Parameters not specified by PARAMETERS are taken from
1271`default-frame-alist'. If either PARAMETERS or `default-frame-alist'
1272contains a `reverse' parameter, handle that. Value is the new frame
1273created."
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.
808All wildcards in PATTERN become substantiated. 1505All 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.
877If that can't be done, return nil." 1577If 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.
882If that can't be done, return nil." 1583If 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.
887If that can't be done, return nil." 1589If 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.
892If that can't be done, return nil." 1595If 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.
897If that can't be done, return nil." 1601If 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.
902If that can't be done, return nil." 1607If 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.
907If that can't be done, return nil." 1613If 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.
915If 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.
954If 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.
993If 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.
1047If 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.
1079If 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.
1117The sample text is a string that comes from the variable
1118`list-faces-sample-text'.
1119
1120It is possible to give a particular face name different appearances in
1121different frames. This command shows the appearance in the
1122selected 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.
1280If optional FRAME is non-nil, set it for that frame only.
1281If it is nil, then apply SPEC to each frame individually.
1282See `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.
1317DISPLAY is part of a spec such as can be used in `defface'.
1318If 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.
1459Set this to the symbol dark if your background color is dark, light if
1460your background is light, or nil (default) if you want Emacs to
1461examine 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