Initial revision
[emacs.git] / src / xfaces.c
blobc033911e1de3d190a2bf280168b5627fefa56b51
1 /* "Face" primitives.
2 Copyright (C) 1993, 1994 Free Software Foundation.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* This is derived from work by Lucid (some parts very loosely so). */
23 #include <sys/types.h>
24 #include <sys/stat.h>
26 #include <config.h>
27 #include "lisp.h"
29 #include "charset.h"
31 #ifdef HAVE_FACES
33 #ifdef HAVE_X_WINDOWS
34 #include "xterm.h"
35 #include "fontset.h"
36 #endif
37 #ifdef MSDOS
38 #include "dosfns.h"
39 #endif
40 #include "buffer.h"
41 #include "dispextern.h"
42 #include "frame.h"
43 #include "blockinput.h"
44 #include "window.h"
45 #include "intervals.h"
47 #ifdef HAVE_X_WINDOWS
48 /* Compensate for bug in Xos.h on some systems, on which it requires
49 time.h. On some such systems, Xos.h tries to redefine struct
50 timeval and struct timezone if USG is #defined while it is
51 #included. */
52 #ifdef XOS_NEEDS_TIME_H
54 #include <time.h>
55 #undef USG
56 #include <X11/Xos.h>
57 #define USG
58 #define __TIMEVAL__
60 #else
62 #include <X11/Xos.h>
64 #endif
65 #endif /* HAVE_X_WINDOWS */
67 /* An explanation of the face data structures. */
69 /* ========================= Face Data Structures =========================
71 Let FACE-NAME be a symbol naming a face.
73 Let FACE-VECTOR be (assq FACE-NAME (frame-face-alist FRAME))
74 FACE-VECTOR is either nil, or a vector of the form
75 [face NAME ID FONT FOREGROUND BACKGROUND BACKGROUND-PIXMAP UNDERLINE-P]
76 where
77 face is the symbol `face',
78 NAME is the symbol with which this vector is associated (a backpointer),
79 ID is the face ID, an integer used internally by the C code to identify
80 the face,
81 FONT, FOREGROUND, and BACKGROUND are strings naming the fonts and colors
82 to use with the face, FONT may name fontsets,
83 BACKGROUND-PIXMAP is the name of an x bitmap filename, which we don't
84 use right now, and
85 UNDERLINE-P is non-nil if the face should be underlined.
86 If any of these elements are nil, that parameter is considered
87 unspecified; parameters from faces specified by lower-priority
88 overlays or text properties, or the parameters of the frame itself,
89 can show through. (lisp/faces.el maintains these lists.)
91 (assq FACE-NAME global-face-data) returns a vector describing the
92 global parameters for that face.
94 Let PARAM-FACE be FRAME->output_data.x->param_faces[Faref (FACE-VECTOR, 2)].
95 PARAM_FACE is a struct face whose members are the Xlib analogues of
96 the parameters in FACE-VECTOR. If an element of FACE-VECTOR is
97 nil, then the corresponding member of PARAM_FACE is FACE_DEFAULT.
98 These faces are called "parameter faces", because they're the ones
99 lisp manipulates to control what gets displayed. Elements 0 and 1
100 of FRAME->output_data.x->param_faces are special - they describe the
101 default and mode line faces. None of the faces in param_faces have
102 GC's. (See src/dispextern.h for the definition of struct face.
103 lisp/faces.el maintains the isomorphism between face_alist and
104 param_faces.)
106 The functions compute_char_face and compute_glyph_face find and
107 combine the parameter faces associated with overlays and text
108 properties. The resulting faces are called "computed faces"; none
109 of their members are FACE_DEFAULT; they are completely specified.
110 They then call intern_compute_face to search
111 FRAME->output_data.x->computed_faces for a matching face, add one if
112 none is found, and return the index into
113 FRAME->output_data.x->computed_faces. FRAME's glyph matrices use these
114 indices to record the faces of the matrix characters, and the X
115 display hooks consult compute_faces to decide how to display these
116 characters. Elements 0 and 1 of computed_faces always describe the
117 default and mode-line faces.
119 Each computed face belongs to a particular frame.
121 Computed faces have graphics contexts some of the time.
122 intern_face builds a GC for a specified computed face
123 if it doesn't have one already.
124 clear_face_cache clears out the GCs of all computed faces.
125 This is done from time to time so that we don't hold on to
126 lots of GCs that are no longer needed.
128 If a computed face has 0 as its font,
129 it is unused, and can be reused by new_computed_face.
131 Constraints:
133 Symbols naming faces must have associations on all frames; for any
134 FRAME, for all FACE-NAME, if (assq FACE-NAME (frame-face-alist
135 FRAME)) is non-nil, it must be non-nil for all frames.
137 Analogously, indices into param_faces must be valid on all frames;
138 if param_faces[i] is a non-zero face pointer on one frame, then it
139 must be filled in on all frames. Code assumes that face ID's can
140 be used on any frame.
142 Some subtleties:
144 Why do we keep param_faces and computed_faces separate?
145 computed_faces contains an element for every combination of facial
146 parameters we have ever displayed. indices into param_faces have
147 to be valid on all frames. If they were the same array, then that
148 array would grow very large on all frames, because any facial
149 combination displayed on any frame would need to be a valid entry
150 on all frames. */
152 /* Definitions and declarations. */
154 /* The number of face-id's in use (same for all frames). */
155 static int next_face_id;
157 /* The number of the face to use to indicate the region. */
158 static int region_face;
160 /* This is what appears in a slot in a face to signify that the face
161 does not specify that display aspect. */
162 #define FACE_DEFAULT (~0)
164 Lisp_Object Qface, Qmouse_face;
165 Lisp_Object Qpixmap_spec_p;
167 int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ );
169 struct face *intern_face ( /* FRAME_PTR, struct face * */ );
170 static int new_computed_face ( /* FRAME_PTR, struct face * */ );
171 static int intern_computed_face ( /* FRAME_PTR, struct face * */ );
172 static void ensure_face_ready ( /* FRAME_PTR, int id */ );
173 void recompute_basic_faces ( /* FRAME_PTR f */ );
175 /* Allocating, copying, and comparing struct faces. */
177 /* Allocate a new face */
178 static struct face *
179 allocate_face ()
181 struct face *result = (struct face *) xmalloc (sizeof (struct face));
182 bzero (result, sizeof (struct face));
183 result->font = (XFontStruct *) FACE_DEFAULT;
184 result->fontset = -1;
185 result->foreground = FACE_DEFAULT;
186 result->background = FACE_DEFAULT;
187 result->stipple = FACE_DEFAULT;
188 return result;
191 /* Make a new face that's a copy of an existing one. */
192 static struct face *
193 copy_face (face)
194 struct face *face;
196 struct face *result = allocate_face ();
198 result->font = face->font;
199 result->fontset = face->fontset;
200 result->foreground = face->foreground;
201 result->background = face->background;
202 result->stipple = face->stipple;
203 result->underline = face->underline;
204 result->pixmap_h = face->pixmap_h;
205 result->pixmap_w = face->pixmap_w;
207 return result;
210 static int
211 face_eql (face1, face2)
212 struct face *face1, *face2;
214 return ( face1->font == face2->font
215 && face1->fontset == face2->fontset
216 && face1->foreground == face2->foreground
217 && face1->background == face2->background
218 && face1->stipple == face2->stipple
219 && face1->underline == face2->underline);
222 /* Managing graphics contexts of faces. */
224 #ifdef HAVE_X_WINDOWS
225 /* Given a computed face, construct its graphics context if necessary. */
227 struct face *
228 intern_face (f, face)
229 struct frame *f;
230 struct face *face;
232 GC gc;
233 XGCValues xgcv;
234 unsigned long mask;
236 if (face->gc)
237 return face;
239 BLOCK_INPUT;
241 if (face->foreground != FACE_DEFAULT)
242 xgcv.foreground = face->foreground;
243 else
244 xgcv.foreground = f->output_data.x->foreground_pixel;
246 if (face->background != FACE_DEFAULT)
247 xgcv.background = face->background;
248 else
249 xgcv.background = f->output_data.x->background_pixel;
251 if (face->font && face->font != (XFontStruct *) FACE_DEFAULT)
252 xgcv.font = face->font->fid;
253 else
254 xgcv.font = f->output_data.x->font->fid;
256 xgcv.graphics_exposures = 0;
258 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
259 if (face->stipple && face->stipple != FACE_DEFAULT)
261 xgcv.fill_style = FillStippled;
262 xgcv.stipple = x_bitmap_pixmap (f, face->stipple);
263 mask |= GCFillStyle | GCStipple;
266 gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
267 mask, &xgcv);
269 face->gc = gc;
270 /* We used the following GC for all non-ASCII characters by changing
271 only GCfont each time. */
272 face->non_ascii_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
273 mask, &xgcv);
275 UNBLOCK_INPUT;
277 return face;
280 /* Clear out all graphics contexts for all computed faces
281 except for the default and mode line faces.
282 This should be done from time to time just to avoid
283 keeping too many graphics contexts that are no longer needed. */
285 void
286 clear_face_cache ()
288 Lisp_Object tail, frame;
290 BLOCK_INPUT;
291 FOR_EACH_FRAME (tail, frame)
293 FRAME_PTR f = XFRAME (frame);
294 if (FRAME_X_P (f))
296 int i;
297 Display *dpy = FRAME_X_DISPLAY (f);
299 for (i = 2; i < FRAME_N_COMPUTED_FACES (f); i++)
301 struct face *face = FRAME_COMPUTED_FACES (f) [i];
302 if (face->gc)
304 XFreeGC (dpy, face->gc);
305 XFreeGC (dpy, face->non_ascii_gc);
307 face->gc = 0;
312 UNBLOCK_INPUT;
315 /* Allocating, freeing, and duplicating fonts, colors, and pixmaps.
317 These functions operate on param faces only.
318 Computed faces get their fonts, colors and pixmaps
319 by merging param faces. */
321 static XFontStruct *
322 load_font (f, name)
323 struct frame *f;
324 Lisp_Object name;
326 XFontStruct *font;
328 if (NILP (name))
329 return (XFontStruct *) FACE_DEFAULT;
331 CHECK_STRING (name, 0);
332 BLOCK_INPUT;
333 font = XLoadQueryFont (FRAME_X_DISPLAY (f), (char *) XSTRING (name)->data);
334 UNBLOCK_INPUT;
336 if (! font)
337 Fsignal (Qerror, Fcons (build_string ("undefined font"),
338 Fcons (name, Qnil)));
339 return font;
342 static void
343 unload_font (f, font)
344 struct frame *f;
345 XFontStruct *font;
347 int len = FRAME_N_COMPUTED_FACES (f);
348 int i;
350 if (!font || font == ((XFontStruct *) FACE_DEFAULT))
351 return;
353 BLOCK_INPUT;
354 /* Invalidate any computed faces which use this font,
355 and free their GC's if they have any. */
356 for (i = 2; i < len; i++)
358 struct face *face = FRAME_COMPUTED_FACES (f)[i];
359 if (face->font == font)
361 Display *dpy = FRAME_X_DISPLAY (f);
362 if (face->gc)
363 XFreeGC (dpy, face->gc);
364 face->gc = 0;
365 /* This marks the computed face as available to reuse. */
366 face->font = 0;
370 XFreeFont (FRAME_X_DISPLAY (f), font);
371 UNBLOCK_INPUT;
374 static unsigned long
375 load_color (f, name)
376 struct frame *f;
377 Lisp_Object name;
379 XColor color;
380 int result;
382 if (NILP (name))
383 return FACE_DEFAULT;
385 CHECK_STRING (name, 0);
386 /* if the colormap is full, defined_color will return a best match
387 to the values in an an existing cell. */
388 result = defined_color(f, (char *) XSTRING (name)->data, &color, 1);
389 if (! result)
390 Fsignal (Qerror, Fcons (build_string ("undefined color"),
391 Fcons (name, Qnil)));
392 return (unsigned long) color.pixel;
395 static void
396 unload_color (f, pixel)
397 struct frame *f;
398 unsigned long pixel;
400 Colormap cmap;
401 Display *dpy = FRAME_X_DISPLAY (f);
402 int class = FRAME_X_DISPLAY_INFO (f)->visual->class;
404 if (pixel == FACE_DEFAULT
405 || pixel == BLACK_PIX_DEFAULT (f)
406 || pixel == WHITE_PIX_DEFAULT (f))
407 return;
408 cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (dpy));
410 /* If display has an immutable color map, freeing colors is not
411 necessary and some servers don't allow it. So don't do it. */
412 if (! (class == StaticColor || class == StaticGray || class == TrueColor))
414 int len = FRAME_N_COMPUTED_FACES (f);
415 int i;
417 BLOCK_INPUT;
418 /* Invalidate any computed faces which use this color,
419 and free their GC's if they have any. */
420 for (i = 2; i < len; i++)
422 struct face *face = FRAME_COMPUTED_FACES (f)[i];
423 if (face->foreground == pixel
424 || face->background == pixel)
426 Display *dpy = FRAME_X_DISPLAY (f);
427 if (face->gc)
428 XFreeGC (dpy, face->gc);
429 face->gc = 0;
430 /* This marks the computed face as available to reuse. */
431 face->font = 0;
435 XFreeColors (dpy, cmap, &pixel, 1, (unsigned long)0);
436 UNBLOCK_INPUT;
440 DEFUN ("pixmap-spec-p", Fpixmap_spec_p, Spixmap_spec_p, 1, 1, 0,
441 "Return t if OBJECT is a valid pixmap specification.")
442 (object)
443 Lisp_Object object;
445 Lisp_Object height, width;
447 return ((STRINGP (object)
448 || (CONSP (object)
449 && CONSP (XCONS (object)->cdr)
450 && CONSP (XCONS (XCONS (object)->cdr)->cdr)
451 && NILP (XCONS (XCONS (XCONS (object)->cdr)->cdr)->cdr)
452 && (width = XCONS (object)->car, INTEGERP (width))
453 && (height = XCONS (XCONS (object)->cdr)->car, INTEGERP (height))
454 && STRINGP (XCONS (XCONS (XCONS (object)->cdr)->cdr)->car)
455 && XINT (width) > 0
456 && XINT (height) > 0
457 /* The string must have enough bits for width * height. */
458 && ((XSTRING (XCONS (XCONS (XCONS (object)->cdr)->cdr)->car)->size
459 * (BITS_PER_INT / sizeof (int)))
460 >= XFASTINT (width) * XFASTINT (height))))
461 ? Qt : Qnil);
464 /* Load a bitmap according to NAME (which is either a file name
465 or a pixmap spec). Return the bitmap_id (see xfns.c)
466 or get an error if NAME is invalid.
468 Store the bitmap width in *W_PTR and height in *H_PTR. */
470 static long
471 load_pixmap (f, name, w_ptr, h_ptr)
472 FRAME_PTR f;
473 Lisp_Object name;
474 unsigned int *w_ptr, *h_ptr;
476 int bitmap_id;
477 Lisp_Object tem;
479 if (NILP (name))
480 return FACE_DEFAULT;
482 tem = Fpixmap_spec_p (name);
483 if (NILP (tem))
484 wrong_type_argument (Qpixmap_spec_p, name);
486 BLOCK_INPUT;
488 if (CONSP (name))
490 /* Decode a bitmap spec into a bitmap. */
492 int h, w;
493 Lisp_Object bits;
495 w = XINT (Fcar (name));
496 h = XINT (Fcar (Fcdr (name)));
497 bits = Fcar (Fcdr (Fcdr (name)));
499 bitmap_id = x_create_bitmap_from_data (f, XSTRING (bits)->data,
500 w, h);
502 else
504 /* It must be a string -- a file name. */
505 bitmap_id = x_create_bitmap_from_file (f, name);
507 UNBLOCK_INPUT;
509 if (bitmap_id < 0)
510 Fsignal (Qerror, Fcons (build_string ("invalid or undefined bitmap"),
511 Fcons (name, Qnil)));
513 *w_ptr = x_bitmap_width (f, bitmap_id);
514 *h_ptr = x_bitmap_height (f, bitmap_id);
516 return bitmap_id;
519 #else /* !HAVE_X_WINDOWS */
521 /* Stubs for MSDOS when not under X. */
523 struct face *
524 intern_face (f, face)
525 struct frame *f;
526 struct face *face;
528 return face;
531 void
532 clear_face_cache ()
534 /* No action. */
537 #ifdef MSDOS
538 unsigned long
539 load_color (f, name)
540 FRAME_PTR f;
541 Lisp_Object name;
543 Lisp_Object result;
545 if (NILP (name))
546 return FACE_DEFAULT;
548 CHECK_STRING (name, 0);
549 result = call1 (Qmsdos_color_translate, name);
550 if (INTEGERP (result))
551 return XINT (result);
552 else
553 Fsignal (Qerror, Fcons (build_string ("undefined color"),
554 Fcons (name, Qnil)));
556 #endif
557 #endif /* !HAVE_X_WINDOWS */
560 /* Managing parameter face arrays for frames. */
562 void
563 init_frame_faces (f)
564 FRAME_PTR f;
566 ensure_face_ready (f, 0);
567 ensure_face_ready (f, 1);
569 FRAME_N_COMPUTED_FACES (f) = 0;
570 FRAME_SIZE_COMPUTED_FACES (f) = 0;
572 new_computed_face (f, FRAME_PARAM_FACES (f)[0]);
573 new_computed_face (f, FRAME_PARAM_FACES (f)[1]);
574 recompute_basic_faces (f);
576 /* Find another X frame. */
578 Lisp_Object tail, frame, result;
580 result = Qnil;
581 FOR_EACH_FRAME (tail, frame)
582 if ((FRAME_MSDOS_P (XFRAME (frame)) || FRAME_X_P (XFRAME (frame)))
583 && XFRAME (frame) != f)
585 result = frame;
586 break;
589 /* If we didn't find any X frames other than f, then we don't need
590 any faces other than 0 and 1, so we're okay. Otherwise, make
591 sure that all faces valid on the selected frame are also valid
592 on this new frame. */
593 if (FRAMEP (result))
595 int i;
596 int n_faces = FRAME_N_PARAM_FACES (XFRAME (result));
597 struct face **faces = FRAME_PARAM_FACES (XFRAME (result));
599 for (i = 2; i < n_faces; i++)
600 if (faces[i])
601 ensure_face_ready (f, i);
607 /* Called from Fdelete_frame. */
609 void
610 free_frame_faces (f)
611 struct frame *f;
613 Display *dpy = FRAME_X_DISPLAY (f);
614 int i;
616 BLOCK_INPUT;
618 for (i = 0; i < FRAME_N_PARAM_FACES (f); i++)
620 struct face *face = FRAME_PARAM_FACES (f) [i];
621 if (face)
623 if (face->fontset < 0)
624 unload_font (f, face->font);
625 unload_color (f, face->foreground);
626 unload_color (f, face->background);
627 x_destroy_bitmap (f, face->stipple);
628 xfree (face);
631 xfree (FRAME_PARAM_FACES (f));
632 FRAME_PARAM_FACES (f) = 0;
633 FRAME_N_PARAM_FACES (f) = 0;
635 /* All faces in FRAME_COMPUTED_FACES use resources copied from
636 FRAME_PARAM_FACES; we can free them without fuss.
637 But we do free the GCs and the face objects themselves. */
638 for (i = 0; i < FRAME_N_COMPUTED_FACES (f); i++)
640 struct face *face = FRAME_COMPUTED_FACES (f) [i];
641 if (face)
643 if (face->gc)
645 XFreeGC (dpy, face->gc);
646 XFreeGC (dpy, face->non_ascii_gc);
648 xfree (face);
651 xfree (FRAME_COMPUTED_FACES (f));
652 FRAME_COMPUTED_FACES (f) = 0;
653 FRAME_N_COMPUTED_FACES (f) = 0;
655 UNBLOCK_INPUT;
658 /* Interning faces in a frame's face array. */
660 static int
661 new_computed_face (f, new_face)
662 struct frame *f;
663 struct face *new_face;
665 int len = FRAME_N_COMPUTED_FACES (f);
666 int i;
668 /* Search for an unused computed face in the middle of the table. */
669 for (i = 0; i < len; i++)
671 struct face *face = FRAME_COMPUTED_FACES (f)[i];
672 if (face->font == 0)
674 FRAME_COMPUTED_FACES (f)[i] = copy_face (new_face);
675 return i;
679 if (i >= FRAME_SIZE_COMPUTED_FACES (f))
681 int new_size = i + 32;
683 FRAME_COMPUTED_FACES (f)
684 = (struct face **) (FRAME_SIZE_COMPUTED_FACES (f) == 0
685 ? xmalloc (new_size * sizeof (struct face *))
686 : xrealloc (FRAME_COMPUTED_FACES (f),
687 new_size * sizeof (struct face *)));
688 FRAME_SIZE_COMPUTED_FACES (f) = new_size;
691 i = FRAME_N_COMPUTED_FACES (f)++;
692 FRAME_COMPUTED_FACES (f)[i] = copy_face (new_face);
693 return i;
697 /* Find a match for NEW_FACE in a FRAME's computed face array, and add
698 it if we don't find one. */
699 static int
700 intern_computed_face (f, new_face)
701 struct frame *f;
702 struct face *new_face;
704 int len = FRAME_N_COMPUTED_FACES (f);
705 int i;
707 /* Search for a computed face already on F equivalent to FACE. */
708 for (i = 0; i < len; i++)
710 if (! FRAME_COMPUTED_FACES (f)[i])
711 abort ();
712 if (face_eql (new_face, FRAME_COMPUTED_FACES (f)[i]))
713 return i;
716 /* We didn't find one; add a new one. */
717 return new_computed_face (f, new_face);
720 /* Make parameter face id ID valid on frame F. */
722 static void
723 ensure_face_ready (f, id)
724 struct frame *f;
725 int id;
727 if (FRAME_N_PARAM_FACES (f) <= id)
729 int n = id + 10;
730 int i;
731 if (!FRAME_N_PARAM_FACES (f))
732 FRAME_PARAM_FACES (f)
733 = (struct face **) xmalloc (sizeof (struct face *) * n);
734 else
735 FRAME_PARAM_FACES (f)
736 = (struct face **) xrealloc (FRAME_PARAM_FACES (f),
737 sizeof (struct face *) * n);
739 bzero (FRAME_PARAM_FACES (f) + FRAME_N_PARAM_FACES (f),
740 (n - FRAME_N_PARAM_FACES (f)) * sizeof (struct face *));
741 FRAME_N_PARAM_FACES (f) = n;
744 if (FRAME_PARAM_FACES (f) [id] == 0)
745 FRAME_PARAM_FACES (f) [id] = allocate_face ();
748 #ifdef HAVE_X_WINDOWS
749 /* Return non-zero if FONT1 and FONT2 have the same width.
750 We do not check the height, because we can now deal with
751 different heights.
752 We assume that they're both character-cell fonts. */
755 same_size_fonts (font1, font2)
756 XFontStruct *font1, *font2;
758 XCharStruct *bounds1 = &font1->min_bounds;
759 XCharStruct *bounds2 = &font2->min_bounds;
761 return (bounds1->width == bounds2->width);
764 /* Update the line_height of frame F according to the biggest font in
765 any face. Return nonzero if if line_height changes. */
768 frame_update_line_height (f)
769 FRAME_PTR f;
771 int i;
772 int fontset = f->output_data.x->fontset;
773 int biggest = (fontset > 0
774 ? FRAME_FONTSET_DATA (f)->fontset_table[fontset]->height
775 : FONT_HEIGHT (f->output_data.x->font));
777 for (i = 0; i < f->output_data.x->n_param_faces; i++)
778 if (f->output_data.x->param_faces[i] != 0
779 && f->output_data.x->param_faces[i]->font != (XFontStruct *) FACE_DEFAULT)
781 int height = ((fontset = f->output_data.x->param_faces[i]->fontset) > 0
782 ? FRAME_FONTSET_DATA (f)->fontset_table[fontset]->height
783 : FONT_HEIGHT (f->output_data.x->param_faces[i]->font));
785 if (height > biggest)
786 biggest = height;
789 if (biggest == f->output_data.x->line_height)
790 return 0;
792 f->output_data.x->line_height = biggest;
793 return 1;
795 #endif /* not HAVE_X_WINDOWS */
797 /* Modify face TO by copying from FROM all properties which have
798 nondefault settings. */
800 static void
801 merge_faces (from, to)
802 struct face *from, *to;
804 /* Only merge the font if it's the same width as the base font.
805 Otherwise ignore it, since we can't handle it properly. */
806 if (from->font != (XFontStruct *) FACE_DEFAULT
807 && same_size_fonts (from->font, to->font))
808 to->font = from->font;
809 if (from->fontset != -1)
810 to->fontset = from->fontset;
811 if (from->foreground != FACE_DEFAULT)
812 to->foreground = from->foreground;
813 if (from->background != FACE_DEFAULT)
814 to->background = from->background;
815 if (from->stipple != FACE_DEFAULT)
817 to->stipple = from->stipple;
818 to->pixmap_h = from->pixmap_h;
819 to->pixmap_w = from->pixmap_w;
821 if (from->underline)
822 to->underline = from->underline;
825 /* Set up the basic set of facial parameters, based on the frame's
826 data; all faces are deltas applied to this. */
828 static void
829 compute_base_face (f, face)
830 FRAME_PTR f;
831 struct face *face;
833 face->gc = 0;
834 face->foreground = FRAME_FOREGROUND_PIXEL (f);
835 face->background = FRAME_BACKGROUND_PIXEL (f);
836 face->font = FRAME_FONT (f);
837 face->fontset = -1;
838 face->stipple = 0;
839 face->underline = 0;
842 /* Return the face ID to use to display a special glyph which selects
843 FACE_CODE as the face ID, assuming that ordinarily the face would
844 be CURRENT_FACE. F is the frame. */
847 compute_glyph_face (f, face_code, current_face)
848 struct frame *f;
849 int face_code, current_face;
851 struct face face;
853 face = *FRAME_COMPUTED_FACES (f)[current_face];
855 if (face_code >= 0 && face_code < FRAME_N_PARAM_FACES (f)
856 && FRAME_PARAM_FACES (f) [face_code] != 0)
857 merge_faces (FRAME_PARAM_FACES (f) [face_code], &face);
859 return intern_computed_face (f, &face);
862 /* Return the face ID to use to display a special glyph which selects
863 FACE_CODE as the face ID, assuming that ordinarily the face would
864 be CURRENT_FACE. F is the frame. */
867 compute_glyph_face_1 (f, face_name, current_face)
868 struct frame *f;
869 Lisp_Object face_name;
870 int current_face;
872 struct face face;
874 face = *FRAME_COMPUTED_FACES (f)[current_face];
876 if (!NILP (face_name))
878 int facecode = face_name_id_number (f, face_name);
879 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
880 && FRAME_PARAM_FACES (f) [facecode] != 0)
881 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
884 return intern_computed_face (f, &face);
887 /* Return the face ID associated with a buffer position POS.
888 Store into *ENDPTR the position at which a different face is needed.
889 This does not take account of glyphs that specify their own face codes.
890 F is the frame in use for display, and W is a window displaying
891 the current buffer.
893 REGION_BEG, REGION_END delimit the region, so it can be highlighted.
895 LIMIT is a position not to scan beyond. That is to limit
896 the time this function can take.
898 If MOUSE is nonzero, use the character's mouse-face, not its face. */
901 compute_char_face (f, w, pos, region_beg, region_end, endptr, limit, mouse)
902 struct frame *f;
903 struct window *w;
904 int pos;
905 int region_beg, region_end;
906 int *endptr;
907 int limit;
908 int mouse;
910 struct face face;
911 Lisp_Object prop, position;
912 int i, j, noverlays;
913 int facecode;
914 Lisp_Object *overlay_vec;
915 Lisp_Object frame;
916 int endpos;
917 Lisp_Object propname;
919 /* W must display the current buffer. We could write this function
920 to use the frame and buffer of W, but right now it doesn't. */
921 if (XBUFFER (w->buffer) != current_buffer)
922 abort ();
924 XSETFRAME (frame, f);
926 endpos = ZV;
927 if (pos < region_beg && region_beg < endpos)
928 endpos = region_beg;
930 XSETFASTINT (position, pos);
932 if (mouse)
933 propname = Qmouse_face;
934 else
935 propname = Qface;
937 prop = Fget_text_property (position, propname, w->buffer);
940 Lisp_Object limit1, end;
942 XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
943 end = Fnext_single_property_change (position, propname, w->buffer, limit1);
944 if (INTEGERP (end))
945 endpos = XINT (end);
949 int next_overlay;
950 int len;
952 /* First try with room for 40 overlays. */
953 len = 40;
954 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
956 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
957 &next_overlay, (int *) 0);
959 /* If there are more than 40,
960 make enough space for all, and try again. */
961 if (noverlays > len)
963 len = noverlays;
964 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
965 noverlays = overlays_at (pos, 0, &overlay_vec, &len,
966 &next_overlay, (int *) 0);
969 if (next_overlay < endpos)
970 endpos = next_overlay;
973 *endptr = endpos;
975 /* Optimize the default case. */
976 if (noverlays == 0 && NILP (prop)
977 && !(pos >= region_beg && pos < region_end))
978 return 0;
980 compute_base_face (f, &face);
982 if (CONSP (prop))
984 /* We have a list of faces, merge them in reverse order */
985 Lisp_Object length;
986 int len;
987 Lisp_Object *faces;
989 length = Fsafe_length (prop);
990 len = XFASTINT (length);
992 /* Put them into an array */
993 faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
994 for (j = 0; j < len; j++)
996 faces[j] = Fcar (prop);
997 prop = Fcdr (prop);
999 /* So that we can merge them in the reverse order */
1000 for (j = len - 1; j >= 0; j--)
1002 facecode = face_name_id_number (f, faces[j]);
1003 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
1004 && FRAME_PARAM_FACES (f) [facecode] != 0)
1005 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
1008 else if (!NILP (prop))
1010 facecode = face_name_id_number (f, prop);
1011 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
1012 && FRAME_PARAM_FACES (f) [facecode] != 0)
1013 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
1016 noverlays = sort_overlays (overlay_vec, noverlays, w);
1018 /* Now merge the overlay data in that order. */
1019 for (i = 0; i < noverlays; i++)
1021 prop = Foverlay_get (overlay_vec[i], propname);
1022 if (CONSP (prop))
1024 /* We have a list of faces, merge them in reverse order */
1025 Lisp_Object length;
1026 int len;
1027 Lisp_Object *faces;
1029 length = Fsafe_length (prop);
1030 len = XFASTINT (length);
1032 /* Put them into an array */
1033 faces = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
1034 for (j = 0; j < len; j++)
1036 faces[j] = Fcar (prop);
1037 prop = Fcdr (prop);
1039 /* So that we can merge them in the reverse order */
1040 for (j = len - 1; j >= 0; j--)
1042 facecode = face_name_id_number (f, faces[j]);
1043 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
1044 && FRAME_PARAM_FACES (f) [facecode] != 0)
1045 merge_faces (FRAME_PARAM_FACES (f) [facecode], &face);
1048 else if (!NILP (prop))
1050 Lisp_Object oend;
1051 int oendpos;
1053 facecode = face_name_id_number (f, prop);
1054 if (facecode >= 0 && facecode < FRAME_N_PARAM_FACES (f)
1055 && FRAME_PARAM_FACES (f) [facecode] != 0)
1056 merge_faces (FRAME_PARAM_FACES (f)[facecode], &face);
1058 oend = OVERLAY_END (overlay_vec[i]);
1059 oendpos = OVERLAY_POSITION (oend);
1060 if (oendpos < endpos)
1061 endpos = oendpos;
1065 if (pos >= region_beg && pos < region_end)
1067 if (region_end < endpos)
1068 endpos = region_end;
1069 if (region_face >= 0 && region_face < next_face_id)
1070 merge_faces (FRAME_PARAM_FACES (f)[region_face], &face);
1073 *endptr = endpos;
1075 return intern_computed_face (f, &face);
1078 /* Recompute the GC's for the default and modeline faces.
1079 We call this after changing frame parameters on which those GC's
1080 depend. */
1082 void
1083 recompute_basic_faces (f)
1084 FRAME_PTR f;
1086 /* If the frame's faces haven't been initialized yet, don't worry about
1087 this stuff. */
1088 if (FRAME_N_PARAM_FACES (f) < 2)
1089 return;
1091 BLOCK_INPUT;
1093 if (FRAME_DEFAULT_FACE (f)->gc)
1095 XFreeGC (FRAME_X_DISPLAY (f), FRAME_DEFAULT_FACE (f)->gc);
1096 XFreeGC (FRAME_X_DISPLAY (f), FRAME_DEFAULT_FACE (f)->non_ascii_gc);
1098 if (FRAME_MODE_LINE_FACE (f)->gc)
1100 XFreeGC (FRAME_X_DISPLAY (f), FRAME_MODE_LINE_FACE (f)->gc);
1101 XFreeGC (FRAME_X_DISPLAY (f), FRAME_MODE_LINE_FACE (f)->non_ascii_gc);
1103 compute_base_face (f, FRAME_DEFAULT_FACE (f));
1104 compute_base_face (f, FRAME_MODE_LINE_FACE (f));
1106 merge_faces (FRAME_DEFAULT_PARAM_FACE (f), FRAME_DEFAULT_FACE (f));
1107 merge_faces (FRAME_MODE_LINE_PARAM_FACE (f), FRAME_MODE_LINE_FACE (f));
1109 intern_face (f, FRAME_DEFAULT_FACE (f));
1110 intern_face (f, FRAME_MODE_LINE_FACE (f));
1112 UNBLOCK_INPUT;
1117 /* Lisp interface. */
1119 DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist, 1, 1, 0,
1121 (frame)
1122 Lisp_Object frame;
1124 CHECK_FRAME (frame, 0);
1125 return XFRAME (frame)->face_alist;
1128 DEFUN ("set-frame-face-alist", Fset_frame_face_alist, Sset_frame_face_alist,
1129 2, 2, 0, "")
1130 (frame, value)
1131 Lisp_Object frame, value;
1133 CHECK_FRAME (frame, 0);
1134 XFRAME (frame)->face_alist = value;
1135 return value;
1139 DEFUN ("make-face-internal", Fmake_face_internal, Smake_face_internal, 1, 1, 0,
1140 "Create face number FACE-ID on all frames.")
1141 (face_id)
1142 Lisp_Object face_id;
1144 Lisp_Object rest, frame;
1145 int id = XINT (face_id);
1147 CHECK_NUMBER (face_id, 0);
1148 if (id < 0 || id >= next_face_id)
1149 error ("Face id out of range");
1151 FOR_EACH_FRAME (rest, frame)
1153 if (FRAME_MSDOS_P (XFRAME (frame)) || FRAME_X_P (XFRAME (frame)))
1154 ensure_face_ready (XFRAME (frame), id);
1156 return Qnil;
1160 DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal,
1161 Sset_face_attribute_internal, 4, 4, 0, "")
1162 (face_id, attr_name, attr_value, frame)
1163 Lisp_Object face_id, attr_name, attr_value, frame;
1165 struct face *face;
1166 struct frame *f;
1167 int magic_p;
1168 int id;
1169 int garbaged = 0;
1171 CHECK_FRAME (frame, 0);
1172 CHECK_NUMBER (face_id, 0);
1173 CHECK_SYMBOL (attr_name, 0);
1175 f = XFRAME (frame);
1176 id = XINT (face_id);
1177 if (id < 0 || id >= next_face_id)
1178 error ("Face id out of range");
1180 if (! FRAME_X_P (f) && ! FRAME_MSDOS_P (f))
1181 return Qnil;
1183 ensure_face_ready (f, id);
1184 face = FRAME_PARAM_FACES (f) [XFASTINT (face_id)];
1186 if (EQ (attr_name, intern ("font")))
1188 #if defined (MSDOS) && !defined (HAVE_X_WINDOWS)
1189 /* The one and only font. Must *not* be zero (which
1190 is taken to mean an unused face nowadays). */
1191 face->font = (XFontStruct *)1 ;
1192 #else
1193 XFontStruct *font;
1194 int fontset;
1196 if (NILP (attr_value))
1198 font = (XFontStruct *) FACE_DEFAULT;
1199 fontset = -1;
1201 else
1203 CHECK_STRING (attr_value, 0);
1204 fontset = fs_query_fontset (f, XSTRING (attr_value)->data);
1205 if (fontset >= 0)
1207 struct font_info *fontp;
1209 if (!(fontp = fs_load_font (f, FRAME_X_FONT_TABLE (f),
1210 CHARSET_ASCII, NULL, fontset)))
1211 Fsignal (Qerror,
1212 Fcons (build_string ("ASCII font can't be loaded"),
1213 Fcons (attr_value, Qnil)));
1214 font = (XFontStruct *) (fontp->font);
1216 else
1217 font = load_font (f, attr_value);
1220 if (face->fontset == -1 && face->font != f->output_data.x->font)
1221 unload_font (f, face->font);
1223 face->font = font;
1224 face->fontset = fontset;
1225 if (frame_update_line_height (f))
1226 x_set_window_size (f, 0, f->width, f->height);
1227 /* Must clear cache, since it might contain the font
1228 we just got rid of. */
1229 garbaged = 1;
1230 #endif
1232 else if (EQ (attr_name, intern ("foreground")))
1234 unsigned long new_color = load_color (f, attr_value);
1235 unload_color (f, face->foreground);
1236 face->foreground = new_color;
1237 garbaged = 1;
1239 else if (EQ (attr_name, intern ("background")))
1241 unsigned long new_color = load_color (f, attr_value);
1242 unload_color (f, face->background);
1243 face->background = new_color;
1244 garbaged = 1;
1246 else if (EQ (attr_name, intern ("background-pixmap")))
1248 unsigned int w, h;
1249 unsigned long new_pixmap = load_pixmap (f, attr_value, &w, &h);
1250 x_destroy_bitmap (f, face->stipple);
1251 face->stipple = new_pixmap;
1252 face->pixmap_w = w;
1253 face->pixmap_h = h;
1254 garbaged = 1;
1256 else if (EQ (attr_name, intern ("underline")))
1258 int new = !NILP (attr_value);
1259 face->underline = new;
1261 else
1262 error ("unknown face attribute");
1264 if (id == 0 || id == 1)
1265 recompute_basic_faces (f);
1267 /* We must redraw the frame whenever any face font or color changes,
1268 because it's possible that a merged (display) face
1269 contains the font or color we just replaced.
1270 And we must inhibit any Expose events until the redraw is done,
1271 since they would try to use the invalid display faces. */
1272 if (garbaged)
1274 SET_FRAME_GARBAGED (f);
1275 FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 1;
1278 return Qnil;
1281 DEFUN ("internal-next-face-id", Finternal_next_face_id, Sinternal_next_face_id,
1282 0, 0, 0, "")
1285 return make_number (next_face_id++);
1288 /* Return the face id for name NAME on frame FRAME.
1289 (It should be the same for all frames,
1290 but it's as easy to use the "right" frame to look it up
1291 as to use any other one.) */
1294 face_name_id_number (f, name)
1295 FRAME_PTR f;
1296 Lisp_Object name;
1298 Lisp_Object tem;
1300 tem = Fcdr (assq_no_quit (name, f->face_alist));
1301 if (NILP (tem))
1302 return 0;
1303 CHECK_VECTOR (tem, 0);
1304 tem = XVECTOR (tem)->contents[2];
1305 CHECK_NUMBER (tem, 0);
1306 return XINT (tem);
1309 /* Emacs initialization. */
1311 void
1312 syms_of_xfaces ()
1314 Qface = intern ("face");
1315 staticpro (&Qface);
1316 Qmouse_face = intern ("mouse-face");
1317 staticpro (&Qmouse_face);
1318 Qpixmap_spec_p = intern ("pixmap-spec-p");
1319 staticpro (&Qpixmap_spec_p);
1321 DEFVAR_INT ("region-face", &region_face,
1322 "Face number to use to highlight the region\n\
1323 The region is highlighted with this face\n\
1324 when Transient Mark mode is enabled and the mark is active.");
1326 #ifdef HAVE_X_WINDOWS
1327 defsubr (&Spixmap_spec_p);
1328 #endif
1329 defsubr (&Sframe_face_alist);
1330 defsubr (&Sset_frame_face_alist);
1331 defsubr (&Smake_face_internal);
1332 defsubr (&Sset_face_attribute_internal);
1333 defsubr (&Sinternal_next_face_id);
1336 #endif /* HAVE_FACES */