Mercurial > hg > xemacs-beta
comparison lisp/custom/cus-face.el @ 197:acd284d43ca1 r20-3b25
Import from CVS: tag r20-3b25
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:00:02 +0200 |
parents | a2f645c6b9f8 |
children | 169c0442b401 |
comparison
equal
deleted
inserted
replaced
196:58e0786448ca | 197:acd284d43ca1 |
---|---|
21 | 21 |
22 ;; To elude the warnings for font functions. | 22 ;; To elude the warnings for font functions. |
23 (eval-when-compile | 23 (eval-when-compile |
24 (require 'font)) | 24 (require 'font)) |
25 | 25 |
26 ;;;###autoload | |
27 (defcustom frame-background-mode nil | |
28 "*The brightness of the background. | |
29 Set this to the symbol dark if your background color is dark, light if | |
30 your background is light, or nil (default) if you want Emacs to | |
31 examine the brightness for you." | |
32 :group 'faces | |
33 :type '(choice (choice-item dark) | |
34 (choice-item light) | |
35 (choice-item :tag "Auto" nil))) | |
36 | |
37 | |
38 ;; Originally, this did much more stuff, and cached the results. The | |
39 ;; trouble is that, if user changes the bg color of a frame's default | |
40 ;; face, the cache wouldn't get updated. This version should be fast | |
41 ;; enough for use without caching, I think. | |
42 (defun get-frame-background-mode (frame) | |
43 "Detect background mode for FRAME." | |
44 (let* ((color-instance (face-background-instance 'default frame)) | |
45 (mode (condition-case nil | |
46 (if (< (apply '+ (color-instance-rgb-components | |
47 color-instance)) 65536) | |
48 'dark | |
49 'light) | |
50 ;; We'll get an error on a TTY; TTY-s are generally dark. | |
51 (error 'dark)))) | |
52 ;(set-frame-property 'background-mode mode) | |
53 mode)) | |
54 | |
55 ;;;###autoload | |
56 (defcustom initialize-face-resources t | |
57 "If non nil, allow X resources to initialize face properties. | |
58 This only affects faces declared with `defface', and only X11 frames." | |
59 :group 'faces | |
60 :type 'boolean) | |
61 | |
62 (defun initialize-face-resources (face &optional frame) | |
63 "Initialize face according to the X11 resources. | |
64 This might overwrite existing face properties. | |
65 Does nothing when the variable initialize-face-resources is nil." | |
66 (when initialize-face-resources | |
67 (make-face-x-resource-internal face frame t))) | |
68 | |
69 ;;(if (string-match "XEmacs" emacs-version) | |
70 ;; ;; Xemacs. | |
71 ;; (defun custom-invert-face (face &optional frame) | |
72 ;; "Swap the foreground and background colors of face FACE. | |
73 ;;If the colors are not specified in the face, use the default colors." | |
74 ;; (interactive (list (read-face-name "Reverse face: "))) | |
75 ;; (let ((fg (color-name (face-foreground face frame) frame)) | |
76 ;; (bg (color-name (face-background face frame) frame))) | |
77 ;; (set-face-foreground face bg frame) | |
78 ;; (set-face-background face fg frame))) | |
79 ;; ;; Emacs. | |
80 ;; (defun custom-invert-face (face &optional frame) | |
81 ;; "Swap the foreground and background colors of face FACE. | |
82 ;;If the colors are not specified in the face, use the default colors." | |
83 ;; (interactive (list (read-face-name "Reverse face: "))) | |
84 ;; (let ((fg (or (face-foreground face frame) | |
85 ;; (face-foreground 'default frame) | |
86 ;; (frame-property (or frame (selected-frame)) | |
87 ;; 'foreground-color) | |
88 ;; "black")) | |
89 ;; (bg (or (face-background face frame) | |
90 ;; (face-background 'default frame) | |
91 ;; (frame-property (or frame (selected-frame)) | |
92 ;; 'background-color) | |
93 ;; "white"))) | |
94 ;; (set-face-foreground face bg frame) | |
95 ;; (set-face-background face fg frame)))) | |
96 | |
97 (defun custom-extract-frame-properties (frame) | |
98 "Return a plist with the frame properties of FRAME used by custom." | |
99 (list 'type (device-type (frame-device frame)) | |
100 'class (device-class (frame-device frame)) | |
101 'background (or frame-background-mode | |
102 (frame-property frame 'background-mode) | |
103 (get-frame-background-mode frame)))) | |
104 | |
105 ;;; Declaring a face. | 26 ;;; Declaring a face. |
106 | 27 |
107 ;;;###autoload | 28 ;;;###autoload |
108 (defun custom-declare-face (face spec doc &rest args) | 29 (defun custom-declare-face (face spec doc &rest args) |
109 "Like `defface', but FACE is evaluated as a normal argument." | 30 "Like `defface', but FACE is evaluated as a normal argument." |
110 (when (fboundp 'load-gc) | 31 ;; (when (fboundp 'load-gc) |
111 ;; This should be allowed, using specifiers. | 32 ;; (error "Attempt to declare a face during dump")) |
112 (error "Attempt to declare a face during dump")) | |
113 (unless (get face 'face-defface-spec) | 33 (unless (get face 'face-defface-spec) |
114 (put face 'face-defface-spec spec) | 34 (put face 'face-defface-spec spec) |
115 (unless (find-face face) | 35 (unless (find-face face) |
116 ;; If the user has already created the face, respect that. | 36 ;; If the user has already created the face, respect that. |
117 (let ((value (or (get face 'saved-face) spec)) | 37 (let ((value (or (get face 'saved-face) spec)) |
118 (frames (custom-relevant-frames)) | 38 (frames (relevant-custom-frames)) |
119 frame) | 39 frame) |
120 ;; Create global face. | 40 ;; Create global face. |
121 (make-empty-face face) | 41 (make-empty-face face) |
122 (custom-face-display-set face value) | 42 (face-display-set face value) |
123 ;; Create frame local faces | 43 ;; Create frame local faces |
124 (while frames | 44 (while frames |
125 (setq frame (car frames) | 45 (setq frame (car frames) |
126 frames (cdr frames)) | 46 frames (cdr frames)) |
127 (custom-face-display-set face value frame)) | 47 (face-display-set face value frame)) |
128 (initialize-face-resources face))) | 48 (init-face-from-resources face))) |
129 (when (and doc (null (face-doc-string face))) | 49 (when (and doc (null (face-doc-string face))) |
130 (set-face-doc-string face doc)) | 50 (set-face-doc-string face doc)) |
131 (custom-handle-all-keywords face args 'custom-face) | 51 (custom-handle-all-keywords face args 'custom-face) |
132 (run-hooks 'custom-define-hook)) | 52 (run-hooks 'custom-define-hook)) |
133 face) | 53 face) |
134 | 54 |
135 (defun custom-face-background (face &optional frame) | |
136 "Return the background color name of face FACE, or nil if unspecified." | |
137 (color-instance-name (specifier-instance (face-background face) frame))) | |
138 | |
139 (defun custom-face-foreground (face &optional frame) | |
140 "Return the background color name of face FACE, or nil if unspecified." | |
141 (color-instance-name (specifier-instance (face-foreground face) frame))) | |
142 | |
143 ;;; Font Attributes. | 55 ;;; Font Attributes. |
144 | 56 |
145 (defconst custom-face-attributes | 57 (defconst custom-face-attributes |
146 '((:bold (boolean :tag "Bold" | 58 '((:bold (boolean :tag "Bold" |
147 :help-echo "Control whether a bold font should be used.") | 59 :help-echo "Control whether a bold font should be used.") |
148 custom-set-face-bold | 60 custom-set-face-bold custom-face-bold) |
149 custom-face-bold) | |
150 (:italic (boolean :tag "Italic" | 61 (:italic (boolean :tag "Italic" |
151 :help-echo "\ | 62 :help-echo "\ |
152 Control whether an italic font should be used.") | 63 Control whether an italic font should be used.") |
153 custom-set-face-italic | 64 custom-set-face-italic custom-face-italic) |
154 custom-face-italic) | |
155 (:underline (boolean :tag "Underline" | 65 (:underline (boolean :tag "Underline" |
156 :help-echo "\ | 66 :help-echo "\ |
157 Control whether the text should be underlined.") | 67 Control whether the text should be underlined.") |
158 set-face-underline-p | 68 set-face-underline-p face-underline-p) |
159 face-underline-p) | |
160 (:foreground (color :tag "Foreground" | 69 (:foreground (color :tag "Foreground" |
161 :value "" | 70 :value "" |
162 :help-echo "Set foreground color.") | 71 :help-echo "Set foreground color.") |
163 set-face-foreground | 72 set-face-foreground custom-face-foreground) |
164 custom-face-foreground) | |
165 (:background (color :tag "Background" | 73 (:background (color :tag "Background" |
166 :value "" | 74 :value "" |
167 :help-echo "Set background color.") | 75 :help-echo "Set background color.") |
168 set-face-background | 76 set-face-background custom-face-background) |
169 custom-face-background) | 77 ;; (:reverse-video (boolean :tag "Reverse" |
170 ;; (:invert (const :format "Invert Face\n" | 78 ;; :help-echo "\ |
171 ;; :sibling-args (:help-echo " | 79 ;;Control whether the text should be inverted.") |
172 ;;Reverse the foreground and background color. | 80 ;; custom-reverse-face custom-face-reverse) |
173 ;;If you haven't specified them for the face, the default colors will be used.") | |
174 ;; t) | |
175 ;; (lambda (face value &optional frame) | |
176 ;; ;; We don't use VALUE. | |
177 ;; (custom-invert-face face frame))) | |
178 (:stipple (editable-field :format "Stipple: %v" | 81 (:stipple (editable-field :format "Stipple: %v" |
179 :help-echo "Name of background bitmap file.") | 82 :help-echo "Name of background bitmap file.") |
180 set-face-stipple custom-face-stipple)) | 83 set-face-background-pixmap custom-face-stipple) |
84 (:family (editable-field :format "Font Family: %v" | |
85 :help-echo "\ | |
86 Name of font family to use (e.g. times).") | |
87 custom-set-face-font-family custom-face-font-family) | |
88 (:size (editable-field :format "Size: %v" | |
89 :help-echo "\ | |
90 Text size (e.g. 9pt or 2mm).") | |
91 custom-set-face-font-size custom-face-font-size) | |
92 (:strikethru (toggle :format "%[Strikethru%]: %v\n" | |
93 :help-echo "\ | |
94 Control whether the text should be strikethru.") | |
95 set-face-strikethru-p face-strikethru-p)) | |
181 "Alist of face attributes. | 96 "Alist of face attributes. |
182 | 97 |
183 The elements are of the form (KEY TYPE SET GET) where KEY is a symbol | 98 The elements are of the form (KEY TYPE SET GET) where KEY is a symbol |
184 identifying the attribute, TYPE is a widget type for editing the | 99 identifying the attribute, TYPE is a widget type for editing the |
185 attibute, SET is a function for setting the attribute value, and GET is a function for getiing the attribute value. | 100 attibute, SET is a function for setting the attribute value, and GET is a function for getiing the attribute value. |
189 be changed. | 104 be changed. |
190 | 105 |
191 The GET function should take two arguments, the face to examine, and | 106 The GET function should take two arguments, the face to examine, and |
192 optonally the frame where the face should be examined.") | 107 optonally the frame where the face should be examined.") |
193 | 108 |
194 (defun custom-face-attributes-set (face frame &rest atts) | 109 (defun face-custom-attributes-set (face frame &rest atts) |
195 "For FACE on FRAME set the attributes [KEYWORD VALUE].... | 110 "For FACE on FRAME set the attributes [KEYWORD VALUE].... |
196 Each keyword should be listed in `custom-face-attributes'. | 111 Each keyword should be listed in `custom-face-attributes'. |
197 | 112 |
198 If FRAME is nil, set the default face." | 113 If FRAME is nil, set the default face." |
199 (while atts | 114 (while atts |
200 (let* ((name (nth 0 atts)) | 115 (let* ((name (nth 0 atts)) |
201 (value (nth 1 atts)) | 116 (value (nth 1 atts)) |
202 (fun (nth 2 (assq name custom-face-attributes)))) | 117 (fun (nth 2 (assq name custom-face-attributes)))) |
203 (setq atts (cdr (cdr atts))) | 118 (setq atts (cdr (cdr atts))) |
204 (condition-case nil | 119 (condition-case nil |
205 (funcall fun face value frame) | 120 (funcall fun face value frame) |
206 (error nil))))) | 121 (error nil))))) |
207 | 122 |
208 (defun custom-face-attributes-get (face frame) | 123 (defun face-custom-attributes-get (face frame) |
209 "For FACE on FRAME get the attributes [KEYWORD VALUE].... | 124 "For FACE on FRAME get the attributes [KEYWORD VALUE].... |
210 Each keyword should be listed in `custom-face-attributes'. | 125 Each keyword should be listed in `custom-face-attributes'. |
211 | 126 |
212 If FRAME is nil, use the default face." | 127 If FRAME is nil, use the default face." |
213 (condition-case nil | 128 (condition-case nil |
234 "Set the bold property of FACE to VALUE." | 149 "Set the bold property of FACE to VALUE." |
235 (if value | 150 (if value |
236 (make-face-bold face frame) | 151 (make-face-bold face frame) |
237 (make-face-unbold face frame))) | 152 (make-face-unbold face frame))) |
238 | 153 |
154 ;; Really, we should get rid of these font.el dependencies... They | |
155 ;; are still presenting a problem with dumping the faces (font.el is | |
156 ;; too bloated for us to dump). I am thinking about hacking up | |
157 ;; font-like functionality myself for the sake of this file. It will | |
158 ;; probably be to-the-point and more efficient. | |
159 | |
239 (defun custom-face-bold (face &rest args) | 160 (defun custom-face-bold (face &rest args) |
240 "Return non-nil if the font of FACE is bold." | 161 "Return non-nil if the font of FACE is bold." |
241 (let* ((font (apply 'face-font-name face args)) | 162 (let* ((font (apply 'face-font-name face args)) |
163 ;; Gag | |
242 (fontobj (font-create-object font))) | 164 (fontobj (font-create-object font))) |
243 (font-bold-p fontobj))) | 165 (font-bold-p fontobj))) |
244 | 166 |
245 (defun custom-set-face-italic (face value &optional frame) | 167 (defun custom-set-face-italic (face value &optional frame) |
246 "Set the italic property of FACE to VALUE." | 168 "Set the italic property of FACE to VALUE." |
249 (make-face-unitalic face frame))) | 171 (make-face-unitalic face frame))) |
250 | 172 |
251 (defun custom-face-italic (face &rest args) | 173 (defun custom-face-italic (face &rest args) |
252 "Return non-nil if the font of FACE is italic." | 174 "Return non-nil if the font of FACE is italic." |
253 (let* ((font (apply 'face-font-name face args)) | 175 (let* ((font (apply 'face-font-name face args)) |
176 ;; Gag | |
254 (fontobj (font-create-object font))) | 177 (fontobj (font-create-object font))) |
255 (font-italic-p fontobj))) | 178 (font-italic-p fontobj))) |
256 | 179 |
257 (defun custom-face-stipple (face &rest args) | 180 (defun custom-face-stipple (face &rest args) |
258 "Return the name of the stipple file used for FACE." | 181 "Return the name of the stipple file used for FACE." |
262 (image-instance-file-name image)))) | 185 (image-instance-file-name image)))) |
263 | 186 |
264 (defun custom-set-face-font-size (face size &rest args) | 187 (defun custom-set-face-font-size (face size &rest args) |
265 "Set the font of FACE to SIZE" | 188 "Set the font of FACE to SIZE" |
266 (let* ((font (apply 'face-font-name face args)) | 189 (let* ((font (apply 'face-font-name face args)) |
190 ;; Gag | |
267 (fontobj (font-create-object font))) | 191 (fontobj (font-create-object font))) |
268 (set-font-size fontobj size) | 192 (set-font-size fontobj size) |
269 (apply 'font-set-face-font face fontobj args))) | 193 (apply 'font-set-face-font face fontobj args))) |
270 | 194 |
271 (defun custom-face-font-size (face &rest args) | 195 (defun custom-face-font-size (face &rest args) |
272 "Return the size of the font of FACE as a string." | 196 "Return the size of the font of FACE as a string." |
273 (let* ((font (apply 'face-font-name face args)) | 197 (let* ((font (apply 'face-font-name face args)) |
198 ;; Gag | |
274 (fontobj (font-create-object font))) | 199 (fontobj (font-create-object font))) |
275 (format "%s" (font-size fontobj)))) | 200 (format "%s" (font-size fontobj)))) |
276 | 201 |
277 (defun custom-set-face-font-family (face family &rest args) | 202 (defun custom-set-face-font-family (face family &rest args) |
278 "Set the font of FACE to FAMILY." | 203 "Set the font of FACE to FAMILY." |
279 (let* ((font (apply 'face-font-name face args)) | 204 (let* ((font (apply 'face-font-name face args)) |
205 ;; Gag | |
280 (fontobj (font-create-object font))) | 206 (fontobj (font-create-object font))) |
281 (set-font-family fontobj family) | 207 (set-font-family fontobj family) |
282 (apply 'font-set-face-font face fontobj args))) | 208 (apply 'font-set-face-font face fontobj args))) |
283 | 209 |
284 (defun custom-face-font-family (face &rest args) | 210 (defun custom-face-font-family (face &rest args) |
285 "Return the name of the font family of FACE." | 211 "Return the name of the font family of FACE." |
286 (let* ((font (apply 'face-font-name face args)) | 212 (let* ((font (apply 'face-font-name face args)) |
213 ;; Gag | |
287 (fontobj (font-create-object font))) | 214 (fontobj (font-create-object font))) |
288 (font-family fontobj))) | 215 (font-family fontobj))) |
289 | 216 |
290 (setq custom-face-attributes | 217 ;;(defun custom-reverse-face (face value &optional frame) |
291 (append '((:family (editable-field :format "Font Family: %v" | 218 ;; "Swap the foreground and background colors of face FACE. |
292 :help-echo "\ | 219 ;;If the colors are not specified in the face, use the default colors." |
293 Name of font family to use (e.g. times).") | 220 ;; (interactive (list (read-face-name "Reverse face: "))) |
294 custom-set-face-font-family | 221 ;; (when value |
295 custom-face-font-family) | 222 ;; (if (eq (frame-type) 'tty) |
296 (:size (editable-field :format "Size: %v" | 223 ;; (set-face-reverse-p face value frame) |
297 :help-echo "\ | 224 ;; (let ((fg (face-foreground-instance face frame)) |
298 Text size (e.g. 9pt or 2mm).") | 225 ;; (bg (face-background-instance face frame))) |
299 custom-set-face-font-size | 226 ;; (set-face-foreground face bg frame) |
300 custom-face-font-size) | 227 ;; (set-face-background face fg frame))))) |
301 (:strikethru (toggle :format "%[Strikethru%]: %v\n" | 228 |
302 :help-echo "\ | 229 ;;(defun custom-face-reverse (face &optional frame) |
303 Control whether the text should be strikethru.") | 230 ;; "Returns non-nil if the face is reverse." |
304 set-face-strikethru-p | 231 ;; (if (eq (frame-type) 'tty) |
305 face-strikethru-p)) | 232 ;; (face-reverse-p face frame) |
306 custom-face-attributes)) | 233 ;; ;;; ### Implement me |
307 ;;; Frames. | 234 ;; )) |
308 | |
309 (defun face-spec-set (face spec &optional frame) | |
310 "Set FACE to the attributes to the first matching entry in SPEC. | |
311 Iff optional FRAME is non-nil, set it for that frame only. | |
312 See `defface' for information about SPEC. | |
313 | |
314 Clear all existing attributes first." | |
315 (copy-face 'custom-face-empty face frame) | |
316 (custom-face-display-set face spec frame)) | |
317 | |
318 (defun custom-face-display-set (face spec &optional frame) | |
319 "Set FACE to the attributes to the first matching entry in SPEC. | |
320 Iff optional FRAME is non-nil, set it for that frame only. | |
321 See `defface' for information about SPEC." | |
322 (while spec | |
323 (let* ((entry (car spec)) | |
324 (display (nth 0 entry)) | |
325 (atts (nth 1 entry))) | |
326 (setq spec (cdr spec)) | |
327 (when (face-spec-set-match-display display frame) | |
328 ;; Avoid creating frame local duplicates of the global face. | |
329 (unless (and frame (eq display (get face 'custom-face-display))) | |
330 (apply 'custom-face-attributes-set face frame atts)) | |
331 (unless frame | |
332 (put face 'custom-face-display display)) | |
333 (setq spec nil))))) | |
334 | |
335 (defvar custom-default-frame-properties nil | |
336 "The frame properties used for the global faces. | |
337 Frames who doesn't match these propertiess should have frame local faces. | |
338 The value should be nil, if uninitialized, or a plist otherwise. | |
339 See `defface' for a list of valid keys and values for the plist.") | |
340 | |
341 (defun custom-get-frame-properties (&optional frame) | |
342 "Return a plist with the frame properties of FRAME used by custom. | |
343 If FRAME is nil, return the default frame properties." | |
344 (cond (frame | |
345 ;; Try to get from cache. | |
346 (let ((cache (frame-property frame 'custom-properties))) | |
347 (unless cache | |
348 ;; Oh well, get it then. | |
349 (setq cache (custom-extract-frame-properties frame)) | |
350 ;; and cache it... | |
351 (modify-frame-parameters frame | |
352 (list (cons 'custom-properties cache)))) | |
353 cache)) | |
354 (custom-default-frame-properties) | |
355 (t | |
356 (setq custom-default-frame-properties | |
357 (custom-extract-frame-properties (selected-frame)))))) | |
358 | |
359 (defun face-spec-set-match-display (display frame) | |
360 "Non-nil iff DISPLAY matches FRAME. | |
361 If FRAME is nil, the current FRAME is used." | |
362 ;; This is a kludge to get started, we really should use specifiers! | |
363 (if (eq display t) | |
364 t | |
365 (let* ((props (custom-get-frame-properties frame)) | |
366 (type (plist-get props 'type)) | |
367 (class (plist-get props 'class)) | |
368 (background (plist-get props 'background)) | |
369 (match t) | |
370 (entries display) | |
371 entry req options) | |
372 (while (and entries match) | |
373 (setq entry (car entries) | |
374 entries (cdr entries) | |
375 req (car entry) | |
376 options (cdr entry) | |
377 match (cond ((eq req 'type) | |
378 (memq type options)) | |
379 ((eq req 'class) | |
380 (memq class options)) | |
381 ((eq req 'background) | |
382 (memq background options)) | |
383 (t | |
384 (warn "Unknown req `%S' with options `%S'" | |
385 req options) | |
386 nil)))) | |
387 match))) | |
388 | |
389 (defun custom-relevant-frames () | |
390 "List of frames whose custom properties differ from the default." | |
391 (let ((relevant nil) | |
392 (default (custom-get-frame-properties)) | |
393 (frames (frame-list)) | |
394 frame) | |
395 (while frames | |
396 (setq frame (car frames) | |
397 frames (cdr frames)) | |
398 (unless (equal default (custom-get-frame-properties frame)) | |
399 (push frame relevant))) | |
400 relevant)) | |
401 | |
402 (defun custom-initialize-faces (&optional frame) | |
403 "Initialize all custom faces for FRAME. | |
404 If FRAME is nil or omitted, initialize them for all frames." | |
405 (mapc (lambda (symbol) | |
406 (let ((spec (or (get symbol 'saved-face) | |
407 (get symbol 'face-defface-spec)))) | |
408 (when spec | |
409 (custom-face-display-set symbol spec frame) | |
410 (initialize-face-resources symbol frame)))) | |
411 (face-list))) | |
412 | |
413 ;;;###autoload | |
414 (defun custom-initialize-frame (&optional frame) | |
415 "Initialize local faces for FRAME if necessary. | |
416 If FRAME is missing or nil, the first member of (frame-list) is used." | |
417 (unless frame | |
418 (setq frame (car (frame-list)))) | |
419 (unless (equal (custom-get-frame-properties) | |
420 (custom-get-frame-properties frame)) | |
421 (custom-initialize-faces frame))) | |
422 | 235 |
423 ;;; Initializing. | 236 ;;; Initializing. |
424 | |
425 (make-face 'custom-face-empty) | |
426 | 237 |
427 ;;;###autoload | 238 ;;;###autoload |
428 (defun custom-set-faces (&rest args) | 239 (defun custom-set-faces (&rest args) |
429 "Initialize faces according to user preferences. | 240 "Initialize faces according to user preferences. |
430 The arguments should be a list where each entry has the form: | 241 The arguments should be a list where each entry has the form: |