diff options
| author | Jim Blandy | 1993-03-24 02:48:44 +0000 |
|---|---|---|
| committer | Jim Blandy | 1993-03-24 02:48:44 +0000 |
| commit | 7b7739b106f3995e4015fdb2068c2b75fd4709a6 (patch) | |
| tree | 26c132543dfba790b004ef7c9e5aea4fcf5f46bd /src | |
| parent | 6afb1d07c238306fd75c6141ac0d565559a4ff3a (diff) | |
| download | emacs-7b7739b106f3995e4015fdb2068c2b75fd4709a6.tar.gz emacs-7b7739b106f3995e4015fdb2068c2b75fd4709a6.zip | |
*** empty log message ***
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfaces.c | 180 |
1 files changed, 176 insertions, 4 deletions
diff --git a/src/xfaces.c b/src/xfaces.c index 4c1f0df13ce..8f17bcce7e3 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -1,9 +1,14 @@ | |||
| 1 | /* Must define frame->faces, frame->n_faces, | ||
| 2 | FRAME_NORMAL_FACE, FRAME_MODELINE_FACE. */ | ||
| 3 | |||
| 1 | /* "Face" primitives | 4 | /* "Face" primitives |
| 5 | Copyright (C) 1992, 1993 Free Software Foundation. | ||
| 6 | |||
| 2 | This file is part of GNU Emacs. | 7 | This file is part of GNU Emacs. |
| 3 | 8 | ||
| 4 | GNU Emacs is free software; you can redistribute it and/or modify | 9 | GNU Emacs is free software; you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
| 6 | the Free Software Foundation; either version 1, or (at your option) | 11 | the Free Software Foundation; either version 2, or (at your option) |
| 7 | any later version. | 12 | any later version. |
| 8 | 13 | ||
| 9 | GNU Emacs is distributed in the hope that it will be useful, | 14 | GNU Emacs is distributed in the hope that it will be useful, |
| @@ -15,6 +20,19 @@ You should have received a copy of the GNU General Public License | |||
| 15 | along with GNU Emacs; see the file COPYING. If not, write to | 20 | along with GNU Emacs; see the file COPYING. If not, write to |
| 16 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | 21 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ |
| 17 | 22 | ||
| 23 | struct face | ||
| 24 | { | ||
| 25 | unsigned char underline; | ||
| 26 | unsigned char hilited; | ||
| 27 | unsigned char modif; | ||
| 28 | GC facegc; | ||
| 29 | XFontStruct * font; | ||
| 30 | unsigned long foreground; | ||
| 31 | unsigned long background; | ||
| 32 | Pixmap back_pixmap; | ||
| 33 | unsigned int pixmap_w, pixmap_h /* , pixmap_depth */; | ||
| 34 | }; | ||
| 35 | |||
| 18 | #include <sys/types.h> | 36 | #include <sys/types.h> |
| 19 | #include <sys/stat.h> | 37 | #include <sys/stat.h> |
| 20 | 38 | ||
| @@ -23,8 +41,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 23 | 41 | ||
| 24 | #include "xterm.h" | 42 | #include "xterm.h" |
| 25 | #include "buffer.h" | 43 | #include "buffer.h" |
| 26 | #include "extents.h" | 44 | #include "frame.h" |
| 27 | #include "screen.h" | ||
| 28 | #include "window.h" | 45 | #include "window.h" |
| 29 | #include "indent.h" | 46 | #include "indent.h" |
| 30 | 47 | ||
| @@ -34,6 +51,24 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 34 | #include <X11/Xmu/Drawing.h> | 51 | #include <X11/Xmu/Drawing.h> |
| 35 | #include <X11/Xos.h> | 52 | #include <X11/Xos.h> |
| 36 | 53 | ||
| 54 | /* We use face structures in two ways: | ||
| 55 | At the frame level, each frame has a vector of faces. (f->faces). | ||
| 56 | Face number 0 is the normal face (for normal text). | ||
| 57 | Face number 1 is the mode line face. | ||
| 58 | Higher face numbers have no built-in meaning. | ||
| 59 | The faces in these vectors are called "frame faces". | ||
| 60 | |||
| 61 | Faces number 0 and 1 have graphics contexts. | ||
| 62 | They can be user in the redisplay code directly. | ||
| 63 | Higher numbered frame faces do not have graphics contexts. | ||
| 64 | |||
| 65 | There are also "cached faces". They have graphics contexts. | ||
| 66 | They are kept in a C vector called face_vector. | ||
| 67 | |||
| 68 | A "display face" is a face with a graphics context. | ||
| 69 | It is either a frame face number 0 or 1, | ||
| 70 | or a cached face. */ | ||
| 71 | |||
| 37 | /* A table of display faces. */ | 72 | /* A table of display faces. */ |
| 38 | struct face **face_vector; | 73 | struct face **face_vector; |
| 39 | /* The length in use of the table. */ | 74 | /* The length in use of the table. */ |
| @@ -44,6 +79,8 @@ int nfaces_allocated; | |||
| 44 | /* The number of face-id's in use (same for all frames). */ | 79 | /* The number of face-id's in use (same for all frames). */ |
| 45 | int next_face_id; | 80 | int next_face_id; |
| 46 | 81 | ||
| 82 | #define FACE_DEFAULT (~0) | ||
| 83 | |||
| 47 | static struct face *allocate_face (); | 84 | static struct face *allocate_face (); |
| 48 | static void build_face (); | 85 | static void build_face (); |
| 49 | 86 | ||
| @@ -81,7 +118,7 @@ face_eql (face1, face2) | |||
| 81 | put it in. */ | 118 | put it in. */ |
| 82 | 119 | ||
| 83 | static struct face * | 120 | static struct face * |
| 84 | get_vector_face (f, face) | 121 | get_cached_face (f, face) |
| 85 | struct frame *f; | 122 | struct frame *f; |
| 86 | struct face *face; | 123 | struct face *face; |
| 87 | { | 124 | { |
| @@ -170,6 +207,131 @@ build_face (f, face) | |||
| 170 | face->facegc = gc; | 207 | face->facegc = gc; |
| 171 | } | 208 | } |
| 172 | 209 | ||
| 210 | /* Modify face TO by copying from FROM all properties which have | ||
| 211 | nondefault settings. */ | ||
| 212 | |||
| 213 | static void | ||
| 214 | merge_faces (from, to) | ||
| 215 | struct face *from, *to; | ||
| 216 | { | ||
| 217 | if (from->font != (XFontStruct *)FACE_DEFAULT) | ||
| 218 | { | ||
| 219 | to->font = from->font; | ||
| 220 | } | ||
| 221 | if (from->foreground != FACE_DEFAULT) | ||
| 222 | to->foreground = from->foreground; | ||
| 223 | if (from->background != FACE_DEFAULT) | ||
| 224 | to->background = from->background; | ||
| 225 | if (from->back_pixmap != FACE_DEFAULT) | ||
| 226 | to->back_pixmap = from->back_pixmap; | ||
| 227 | if (from->underline) | ||
| 228 | to->underline = from->underline; | ||
| 229 | } | ||
| 230 | |||
| 231 | /* Return the display face associated with a buffer position POS. | ||
| 232 | Store into *ENDPTR the position at which a different face is needed. | ||
| 233 | This does not take account of glyphs that specify their own face codes. | ||
| 234 | F is the frame in use for display. */ | ||
| 235 | |||
| 236 | struct face * | ||
| 237 | compute_char_face (f, pos, endptr) | ||
| 238 | struct frame *f; | ||
| 239 | int pos; | ||
| 240 | int *endptr; | ||
| 241 | { | ||
| 242 | struct face face; | ||
| 243 | Lisp_Object prop, position, length; | ||
| 244 | Lisp_Object overlay, start, end; | ||
| 245 | int i, j, noverlays; | ||
| 246 | int facecode; | ||
| 247 | int endpos; | ||
| 248 | Lisp_Object *overlay_vec; | ||
| 249 | int len; | ||
| 250 | |||
| 251 | XFASTINT (position) = pos; | ||
| 252 | prop = Fget_text_property (position, Qface); | ||
| 253 | |||
| 254 | len = 10; | ||
| 255 | overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object)); | ||
| 256 | noverlays = overlays_at (pos, &overlay_vec, &len, &endpos); | ||
| 257 | |||
| 258 | /* Optimize the default case. */ | ||
| 259 | if (noverlays == 0 && NILP (prop)) | ||
| 260 | return FRAME_NORMAL_FACE (f); | ||
| 261 | |||
| 262 | bcopy (FRAME_NORMAL_FACE (f), &face, sizeof (struct face)); | ||
| 263 | |||
| 264 | if (!NILP (prop)) | ||
| 265 | { | ||
| 266 | facecode = Fface_name_id_number (prop); | ||
| 267 | if (facecode >= 0 && facecode < f->n_faces && f->faces[facecode] != 0) | ||
| 268 | merge_faces (f->faces[facecode], &face); | ||
| 269 | } | ||
| 270 | |||
| 271 | /* Discard invalid overlays from the vector. */ | ||
| 272 | for (i = 0, j = 0; i < noverlays; i++) | ||
| 273 | { | ||
| 274 | overlay = overlay_vec[i]; | ||
| 275 | |||
| 276 | if (OVERLAY_VALID (overlay) | ||
| 277 | && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0 | ||
| 278 | && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0) | ||
| 279 | overlay_vec[j++] = overlay; | ||
| 280 | } | ||
| 281 | noverlays = j; | ||
| 282 | |||
| 283 | /* Sort the overlays into the proper order. */ | ||
| 284 | |||
| 285 | /* Now merge the overlay data in that order. */ | ||
| 286 | |||
| 287 | for (i = 0; i < noverlays; i++) | ||
| 288 | { | ||
| 289 | prop = Foverlay_get (overlay_vec[i], Qface); | ||
| 290 | if (!NILP (prop)) | ||
| 291 | { | ||
| 292 | Lisp_Object oend; | ||
| 293 | int oendpos; | ||
| 294 | |||
| 295 | facecode = Fface_name_id_number (prop); | ||
| 296 | if (facecode >= 0 && facecode < f->n_faces | ||
| 297 | && f->faces[facecode] != 0) | ||
| 298 | merge_faces (f->faces[facecode], &face); | ||
| 299 | |||
| 300 | oend = OVERLAY_END (overlay_vec[i]); | ||
| 301 | oendpos = OVERLAY_POSITION (oend); | ||
| 302 | if (oendpos > endpos) | ||
| 303 | endpos = oendpos; | ||
| 304 | } | ||
| 305 | } | ||
| 306 | |||
| 307 | xfree (overlay_vec); | ||
| 308 | |||
| 309 | *endptr = endpos; | ||
| 310 | |||
| 311 | return get_display_face (f, &face); | ||
| 312 | } | ||
| 313 | |||
| 314 | /* Return the display face to use to display a special glyph | ||
| 315 | which selects FACE_CODE as the face ID, | ||
| 316 | assuming that ordinarily the face would be BASIC_FACE. | ||
| 317 | F is the frame. */ | ||
| 318 | |||
| 319 | struct face * | ||
| 320 | compute_glyph_face (f, basic_face, face_code) | ||
| 321 | struct frame *f; | ||
| 322 | struct face *basic_face; | ||
| 323 | int face_code; | ||
| 324 | { | ||
| 325 | struct face face; | ||
| 326 | |||
| 327 | bcopy (basic_face, &face, sizeof (struct face)); | ||
| 328 | |||
| 329 | if (face_code >= 0 && face_code < f->n_faces && f->faces[face_code] != 0) | ||
| 330 | merge_faces (f->faces[face_code], &face); | ||
| 331 | |||
| 332 | return get_display_face (f, &face); | ||
| 333 | } | ||
| 334 | |||
| 173 | /* Given a frame face, return an equivalent display face | 335 | /* Given a frame face, return an equivalent display face |
| 174 | (one which has a graphics context). */ | 336 | (one which has a graphics context). */ |
| 175 | 337 | ||
| @@ -219,6 +381,10 @@ allocate_face () | |||
| 219 | { | 381 | { |
| 220 | struct face *result = (struct face *) xmalloc (sizeof (struct face)); | 382 | struct face *result = (struct face *) xmalloc (sizeof (struct face)); |
| 221 | bzero (result, sizeof (struct face)); | 383 | bzero (result, sizeof (struct face)); |
| 384 | result->font = (XFontStruct *) FACE_DEFAULT; | ||
| 385 | result->foreground = FACE_DEFAULT; | ||
| 386 | result->background = FACE_DEFAULT; | ||
| 387 | result->back_pixmap = FACE_DEFAULT; | ||
| 222 | return result; | 388 | return result; |
| 223 | } | 389 | } |
| 224 | 390 | ||
| @@ -256,6 +422,9 @@ load_font (f, name) | |||
| 256 | { | 422 | { |
| 257 | XFontStruct *font; | 423 | XFontStruct *font; |
| 258 | 424 | ||
| 425 | if (NILP (name)) | ||
| 426 | return (XFontStruct *) FACE_DEFAULT; | ||
| 427 | |||
| 259 | CHECK_STRING (name, 0); | 428 | CHECK_STRING (name, 0); |
| 260 | BLOCK_INPUT; | 429 | BLOCK_INPUT; |
| 261 | font = XLoadQueryFont (x_current_display, (char *) XSTRING (name)->data); | 430 | font = XLoadQueryFont (x_current_display, (char *) XSTRING (name)->data); |
| @@ -287,6 +456,9 @@ load_color (f, name) | |||
| 287 | XColor color; | 456 | XColor color; |
| 288 | int result; | 457 | int result; |
| 289 | 458 | ||
| 459 | if (NILP (name)) | ||
| 460 | return FACE_DEFAULT; | ||
| 461 | |||
| 290 | cmap = DefaultColormapOfScreen (x_screen); | 462 | cmap = DefaultColormapOfScreen (x_screen); |
| 291 | 463 | ||
| 292 | CHECK_STRING (name, 0); | 464 | CHECK_STRING (name, 0); |