]> code.delx.au - gnu-emacs/blobdiff - src/xfaces.c
Bump version to 24.1.
[gnu-emacs] / src / xfaces.c
index 5833633c2e763129e159ec9efac7112416b7d639..476fb1e03667dbd9ffb99ce363f0710e64c9d960 100644 (file)
@@ -1,6 +1,6 @@
 /* xfaces.c -- "Face" primitives.
 
-Copyright (C) 1993-1994, 1998-2011  Free Software Foundation, Inc.
+Copyright (C) 1993-1994, 1998-2012  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -27,7 +27,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
    1. Font family name.
 
-   2. Font foundary name.
+   2. Font foundry name.
 
    3. Relative proportionate width, aka character set width or set
    width (swidth), e.g. `semi-compressed'.
@@ -66,7 +66,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    attributes (1st thru 5th) are updated from the spec.
 
    On the other hand, if one of the other font-related attributes are
-   specified, the correspoinding specs in this attribute is set to nil.
+   specified, the corresponding specs in this attribute is set to nil.
 
    15. A face name or list of face names from which to inherit attributes.
 
@@ -293,7 +293,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Non-zero if face attribute ATTR is `ignore-defface'.  */
 
-#define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), Qignore_defface)
+#define IGNORE_DEFFACE_P(ATTR) EQ ((ATTR), QCignore_defface)
 
 /* Value is the number of elements of VECTOR.  */
 
@@ -332,14 +332,14 @@ static Lisp_Object Qultra_expanded;
 static Lisp_Object Qreleased_button, Qpressed_button;
 static Lisp_Object QCstyle, QCcolor, QCline_width;
 Lisp_Object Qunspecified;      /* used in dosfns.c */
-static Lisp_Object Qignore_defface;
+static Lisp_Object QCignore_defface;
 
 char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
 
 /* The name of the function to call when the background of the frame
    has changed, frame_set_background_mode.  */
 
-Lisp_Object Qframe_set_background_mode;
+static Lisp_Object Qframe_set_background_mode;
 
 /* Names of basic faces.  */
 
@@ -403,7 +403,7 @@ static int next_lface_id;
 /* A vector mapping Lisp face Id's to face names.  */
 
 static Lisp_Object *lface_id_to_name;
-static int lface_id_to_name_size;
+static ptrdiff_t lface_id_to_name_size;
 
 /* TTY color-related functions (defined in tty-colors.el).  */
 
@@ -458,11 +458,11 @@ struct table_entry;
 struct named_merge_point;
 
 static void map_tty_color (struct frame *, struct face *,
-                           enum lface_attribute_index, int *);
+                          enum lface_attribute_index, int *);
 static Lisp_Object resolve_face_name (Lisp_Object, int);
 static void set_font_frame_param (Lisp_Object, Lisp_Object);
 static int get_lface_attributes (struct frame *, Lisp_Object, Lisp_Object *,
-                                 int, struct named_merge_point *);
+                                int, struct named_merge_point *);
 static ptrdiff_t load_pixmap (struct frame *, Lisp_Object,
                              unsigned *, unsigned *);
 static struct frame *frame_or_selected_frame (Lisp_Object, int);
@@ -470,9 +470,9 @@ static void load_face_colors (struct frame *, struct face *, Lisp_Object *);
 static void free_face_colors (struct frame *, struct face *);
 static int face_color_gray_p (struct frame *, const char *);
 static struct face *realize_face (struct face_cache *, Lisp_Object *,
-                                  int);
+                                 int);
 static struct face *realize_non_ascii_face (struct frame *, Lisp_Object,
-                                            struct face *);
+                                           struct face *);
 static struct face *realize_x_face (struct face_cache *, Lisp_Object *);
 static struct face *realize_tty_face (struct face_cache *, Lisp_Object *);
 static int realize_basic_faces (struct frame *);
@@ -488,11 +488,11 @@ static void clear_face_gcs (struct face_cache *);
 static void free_face_cache (struct face_cache *);
 static int face_fontset (Lisp_Object *);
 static void merge_face_vectors (struct frame *, Lisp_Object *, Lisp_Object*,
-                                struct named_merge_point *);
+                               struct named_merge_point *);
 static int merge_face_ref (struct frame *, Lisp_Object, Lisp_Object *,
-                           int, struct named_merge_point *);
+                          int, struct named_merge_point *);
 static int set_lface_from_font (struct frame *, Lisp_Object, Lisp_Object,
-                                int);
+                               int);
 static Lisp_Object lface_from_face_name (struct frame *, Lisp_Object, int);
 static struct face *make_realized_face (Lisp_Object *);
 static void cache_face (struct face_cache *, struct face *, unsigned);
@@ -536,8 +536,7 @@ int color_count[256];
 /* Register color PIXEL as allocated.  */
 
 void
-register_color (pixel)
-     unsigned long pixel;
+register_color (unsigned long pixel)
 {
   xassert (pixel < 256);
   ++color_count[pixel];
@@ -547,8 +546,7 @@ register_color (pixel)
 /* Register color PIXEL as deallocated.  */
 
 void
-unregister_color (pixel)
-     unsigned long pixel;
+unregister_color (unsigned long pixel)
 {
   xassert (pixel < 256);
   if (color_count[pixel] > 0)
@@ -561,9 +559,7 @@ unregister_color (pixel)
 /* Register N colors from PIXELS as deallocated.  */
 
 void
-unregister_colors (pixels, n)
-     unsigned long *pixels;
-     int n;
+unregister_colors (unsigned long *pixels, int n)
 {
   int i;
   for (i = 0; i < n; ++i)
@@ -627,7 +623,8 @@ x_free_colors (struct frame *f, long unsigned int *pixels, int npixels)
    is called.  */
 
 void
-x_free_dpy_colors (Display *dpy, Screen *screen, Colormap cmap, long unsigned int *pixels, int npixels)
+x_free_dpy_colors (Display *dpy, Screen *screen, Colormap cmap,
+                  long unsigned int *pixels, int npixels)
 {
   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
   int class = dpyinfo->visual->class;
@@ -702,8 +699,8 @@ x_free_gc (struct frame *f, GC gc)
 
 static inline GC
 x_create_gc (struct frame *f,
-             unsigned long mask,
-             XGCValues *xgcv)
+            unsigned long mask,
+            XGCValues *xgcv)
 {
   GC gc = xmalloc (sizeof (*gc));
   if (gc)
@@ -796,7 +793,7 @@ init_frame_faces (struct frame *f)
   if (!FRAME_NS_P (f) || FRAME_NS_WINDOW (f))
 #endif
     if (!realize_basic_faces (f))
-        abort ();
+       abort ();
 }
 
 
@@ -944,11 +941,13 @@ the pixmap.  Bits are stored row by row, each row occupies
            }
        }
 
-      if (NATNUMP (width) && NATNUMP (height) && STRINGP (data))
+      if (STRINGP (data)
+         && INTEGERP (width) && 0 < XINT (width)
+         && INTEGERP (height) && 0 < XINT (height))
        {
-         int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1)
-                              / BITS_PER_CHAR);
-         if (SBYTES (data) >= bytes_per_row * XINT (height))
+         EMACS_INT bytes_per_row = ((XINT (width) + BITS_PER_CHAR - 1)
+                                    / BITS_PER_CHAR);
+         if (XINT (height) <= SBYTES (data) / bytes_per_row)
            pixmap_p = 1;
        }
     }
@@ -965,7 +964,8 @@ the pixmap.  Bits are stored row by row, each row occupies
    if these pointers are not null.  */
 
 static ptrdiff_t
-load_pixmap (FRAME_PTR f, Lisp_Object name, unsigned int *w_ptr, unsigned int *h_ptr)
+load_pixmap (FRAME_PTR f, Lisp_Object name, unsigned int *w_ptr,
+            unsigned int *h_ptr)
 {
   ptrdiff_t bitmap_id;
 
@@ -1059,7 +1059,8 @@ parse_rgb_list (Lisp_Object rgb_list, XColor *color)
    returned in it.  */
 
 static int
-tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color, XColor *std_color)
+tty_lookup_color (struct frame *f, Lisp_Object color, XColor *tty_color,
+                 XColor *std_color)
 {
   Lisp_Object frame, color_desc;
 
@@ -1155,7 +1156,8 @@ tty_defined_color (struct frame *f, const char *color_name,
    This does the right thing for any type of frame.  */
 
 static int
-defined_color (struct frame *f, const char *color_name, XColor *color_def, int alloc)
+defined_color (struct frame *f, const char *color_name, XColor *color_def,
+              int alloc)
 {
   if (!FRAME_WINDOW_P (f))
     return tty_defined_color (f, color_name, color_def, alloc);
@@ -1221,7 +1223,7 @@ face_color_gray_p (struct frame *f, const char *color_name)
   int gray_p;
 
   if (defined_color (f, color_name, &color, 0))
-    gray_p = (/* Any color sufficiently close to black counts as grey.  */
+    gray_p = (/* Any color sufficiently close to black counts as gray.  */
              (color.red < 5000 && color.green < 5000 && color.blue < 5000)
              ||
              ((eabs (color.red - color.green)
@@ -1242,7 +1244,8 @@ face_color_gray_p (struct frame *f, const char *color_name)
    color.  */
 
 static int
-face_color_supported_p (struct frame *f, const char *color_name, int background_p)
+face_color_supported_p (struct frame *f, const char *color_name,
+                       int background_p)
 {
   Lisp_Object frame;
   XColor not_used;
@@ -1315,7 +1318,8 @@ COLOR must be a valid color name.  */)
    these colors.  */
 
 unsigned long
-load_color (struct frame *f, struct face *face, Lisp_Object name, enum lface_attribute_index target_index)
+load_color (struct frame *f, struct face *face, Lisp_Object name,
+           enum lface_attribute_index target_index)
 {
   XColor color;
 
@@ -1723,7 +1727,8 @@ fonts to match.  The first MAXIMUM fonts are reported.
 The optional fifth argument WIDTH, if specified, is a number of columns
 occupied by a character of a font.  In that case, return only fonts
 the WIDTH times as wide as FACE on FRAME.  */)
-  (Lisp_Object pattern, Lisp_Object face, Lisp_Object frame, Lisp_Object maximum, Lisp_Object width)
+  (Lisp_Object pattern, Lisp_Object face, Lisp_Object frame,
+   Lisp_Object maximum, Lisp_Object width)
 {
   struct frame *f;
   int size, avgwidth IF_LINT (= 0);
@@ -1922,7 +1927,8 @@ check_lface_attrs (Lisp_Object *attrs)
           || IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX])
           || FONTP (attrs[LFACE_FONT_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX])
-          || STRINGP (attrs[LFACE_FONTSET_INDEX]));
+          || STRINGP (attrs[LFACE_FONTSET_INDEX])
+          || NILP (attrs[LFACE_FONTSET_INDEX]));
 #endif
 }
 
@@ -2060,7 +2066,8 @@ resolve_face_name (Lisp_Object face_name, int signal_p)
    signal an error if FACE_NAME is not a valid face name.  If SIGNAL_P
    is zero, value is nil if FACE_NAME is not a valid face name.  */
 static inline Lisp_Object
-lface_from_face_name_no_resolve (struct frame *f, Lisp_Object face_name, int signal_p)
+lface_from_face_name_no_resolve (struct frame *f, Lisp_Object face_name,
+                                int signal_p)
 {
   Lisp_Object lface;
 
@@ -2102,7 +2109,8 @@ lface_from_face_name (struct frame *f, Lisp_Object face_name, int signal_p)
    Otherwise, value is zero if FACE_NAME is not a face.  */
 
 static inline int
-get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name, Lisp_Object *attrs, int signal_p)
+get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name,
+                              Lisp_Object *attrs, int signal_p)
 {
   Lisp_Object lface;
 
@@ -2123,7 +2131,9 @@ get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name, Lisp_Obje
    Otherwise, value is zero if FACE_NAME is not a face.  */
 
 static inline int
-get_lface_attributes (struct frame *f, Lisp_Object face_name, Lisp_Object *attrs, int signal_p, struct named_merge_point *named_merge_points)
+get_lface_attributes (struct frame *f, Lisp_Object face_name,
+                     Lisp_Object *attrs, int signal_p,
+                     struct named_merge_point *named_merge_points)
 {
   Lisp_Object face_remapping;
 
@@ -2166,7 +2176,7 @@ lface_fully_specified_p (Lisp_Object *attrs)
   for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
     if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX)
       if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i])))
-        break;
+       break;
 
   return i == LFACE_VECTOR_SIZE;
 }
@@ -2179,7 +2189,8 @@ lface_fully_specified_p (Lisp_Object *attrs)
    of FORCE_P.  */
 
 static int
-set_lface_from_font (struct frame *f, Lisp_Object lface, Lisp_Object font_object, int force_p)
+set_lface_from_font (struct frame *f, Lisp_Object lface,
+                    Lisp_Object font_object, int force_p)
 {
   Lisp_Object val;
   struct font *font = XFONT_OBJECT (font_object);
@@ -2289,7 +2300,8 @@ merge_face_heights (Lisp_Object from, Lisp_Object to, Lisp_Object invalid)
    other places.  */
 
 static inline void
-merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to, struct named_merge_point *named_merge_points)
+merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to,
+                   struct named_merge_point *named_merge_points)
 {
   int i;
 
@@ -2356,7 +2368,8 @@ merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to, struct
    merging succeeded.  */
 
 static int
-merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, struct named_merge_point *named_merge_points)
+merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to,
+                 struct named_merge_point *named_merge_points)
 {
   struct named_merge_point named_merge_point;
 
@@ -2406,7 +2419,8 @@ merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, struc
    specifications.  */
 
 static int
-merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to, int err_msgs, struct named_merge_point *named_merge_points)
+merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to,
+               int err_msgs, struct named_merge_point *named_merge_points)
 {
   int ok = 1;                  /* Succeed without an error? */
 
@@ -2565,7 +2579,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to, int err_
                }
              else if (EQ (keyword, QCstipple))
                {
-#if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
+#if defined (HAVE_X_WINDOWS) || defined (HAVE_NS)
                  Lisp_Object pixmap_p = Fbitmap_spec_p (value);
                  if (!NILP (pixmap_p))
                    to[LFACE_STIPPLE_INDEX] = value;
@@ -2668,12 +2682,10 @@ Value is a vector of face attributes.  */)
         The mapping from Lisp face to Lisp face id is given by the
         property `face' of the Lisp face name.  */
       if (next_lface_id == lface_id_to_name_size)
-       {
-         int new_size = max (50, 2 * lface_id_to_name_size);
-         int sz = new_size * sizeof *lface_id_to_name;
-         lface_id_to_name = (Lisp_Object *) xrealloc (lface_id_to_name, sz);
-         lface_id_to_name_size = new_size;
-       }
+       lface_id_to_name =
+         xpalloc (lface_id_to_name, &lface_id_to_name_size, 1,
+                  min (INT_MAX, MOST_POSITIVE_FIXNUM),
+                  sizeof *lface_id_to_name);
 
       lface_id_to_name[next_lface_id] = face;
       Fput (face, Qface, make_number (next_lface_id));
@@ -2839,7 +2851,7 @@ FRAME 0 means change the face on all frames, and change the default
         The value of that attribute will be inherited from some other
         face during face merging.  See internal_merge_in_global_face. */
       if (UNSPECIFIEDP (value))
-       value = Qignore_defface;
+       value = QCignore_defface;
     }
   else
     {
@@ -2886,7 +2898,8 @@ FRAME 0 means change the face on all frames, and change the default
            {
              /* The default face must have an absolute size.  */
              if (!INTEGERP (value) || XINT (value) <= 0)
-               signal_error ("Default face height not absolute and positive", value);
+               signal_error ("Default face height not absolute and positive",
+                             value);
            }
          else
            {
@@ -2896,7 +2909,8 @@ FRAME 0 means change the face on all frames, and change the default
                                                     make_number (10),
                                                     Qnil);
              if (!INTEGERP (test) || XINT (test) <= 0)
-               signal_error ("Face height does not produce a positive integer", value);
+               signal_error ("Face height does not produce a positive integer",
+                             value);
            }
        }
 
@@ -2975,7 +2989,7 @@ FRAME 0 means change the face on all frames, and change the default
       int valid_p;
 
       /* Allow t meaning a simple box of width 1 in foreground color
-         of the face.  */
+        of the face.  */
       if (EQ (value, Qt))
        value = make_number (1);
 
@@ -3081,7 +3095,7 @@ FRAME 0 means change the face on all frames, and change the default
     }
   else if (EQ (attr, QCstipple))
     {
-#if defined(HAVE_X_WINDOWS) || defined(HAVE_NS)
+#if defined (HAVE_X_WINDOWS) || defined (HAVE_NS)
       if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)
          && !NILP (value)
          && NILP (Fbitmap_spec_p (value)))
@@ -3320,7 +3334,8 @@ FRAME 0 means change the face on all frames, and change the default
    has been assigned the value NEW_VALUE.  */
 
 void
-update_face_from_frame_parameter (struct frame *f, Lisp_Object param, Lisp_Object new_value)
+update_face_from_frame_parameter (struct frame *f, Lisp_Object param,
+                                 Lisp_Object new_value)
 {
   Lisp_Object face = Qnil;
   Lisp_Object lface;
@@ -3345,7 +3360,7 @@ update_face_from_frame_parameter (struct frame *f, Lisp_Object param, Lisp_Objec
 
       /* Changing the background color might change the background
         mode, so that we have to load new defface specs.
-        Call frame-update-face-colors to do that.  */
+        Call frame-set-background-mode to do that.  */
       XSETFRAME (frame, f);
       call1 (Qframe_set_background_mode, frame);
 
@@ -3534,6 +3549,8 @@ x_update_menu_appearance (struct frame *f)
          rdb != NULL))
     {
       char line[512];
+      char *buf = line;
+      ptrdiff_t bufsize = sizeof line;
       Lisp_Object lface = lface_from_face_name (f, Qmenu, 1);
       struct face *face = FACE_FROM_ID (f, MENU_FACE_ID);
       const char *myname = SSDATA (Vx_resource_name);
@@ -3546,24 +3563,25 @@ x_update_menu_appearance (struct frame *f)
 
       if (STRINGP (LFACE_FOREGROUND (lface)))
        {
-         sprintf (line, "%s.%s*foreground: %s",
-                  myname, popup_path,
-                  SDATA (LFACE_FOREGROUND (lface)));
+         exprintf (&buf, &bufsize, line, -1, "%s.%s*foreground: %s",
+                   myname, popup_path,
+                   SDATA (LFACE_FOREGROUND (lface)));
          XrmPutLineResource (&rdb, line);
-         sprintf (line, "%s.pane.menubar*foreground: %s",
-                  myname, SDATA (LFACE_FOREGROUND (lface)));
+         exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*foreground: %s",
+                   myname, SDATA (LFACE_FOREGROUND (lface)));
          XrmPutLineResource (&rdb, line);
          changed_p = 1;
        }
 
       if (STRINGP (LFACE_BACKGROUND (lface)))
        {
-         sprintf (line, "%s.%s*background: %s",
-                  myname, popup_path,
-                  SDATA (LFACE_BACKGROUND (lface)));
+         exprintf (&buf, &bufsize, line, -1, "%s.%s*background: %s",
+                   myname, popup_path,
+                   SDATA (LFACE_BACKGROUND (lface)));
          XrmPutLineResource (&rdb, line);
-         sprintf (line, "%s.pane.menubar*background: %s",
-                  myname, SDATA (LFACE_BACKGROUND (lface)));
+
+         exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*background: %s",
+                   myname, SDATA (LFACE_BACKGROUND (lface)));
          XrmPutLineResource (&rdb, line);
          changed_p = 1;
        }
@@ -3601,11 +3619,12 @@ x_update_menu_appearance (struct frame *f)
 #else
              char *fontsetname = SSDATA (xlfd);
 #endif
-             sprintf (line, "%s.pane.menubar*font%s: %s",
-                      myname, suffix, fontsetname);
+             exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*font%s: %s",
+                       myname, suffix, fontsetname);
              XrmPutLineResource (&rdb, line);
-             sprintf (line, "%s.%s*font%s: %s",
-                      myname, popup_path, suffix, fontsetname);
+
+             exprintf (&buf, &bufsize, line, -1, "%s.%s*font%s: %s",
+                       myname, popup_path, suffix, fontsetname);
              XrmPutLineResource (&rdb, line);
              changed_p = 1;
              if (fontsetname != SSDATA (xlfd))
@@ -3615,6 +3634,9 @@ x_update_menu_appearance (struct frame *f)
 
       if (changed_p && f->output_data.x->menubar_widget)
        free_frame_menubar (f);
+
+      if (buf != line)
+       xfree (buf);
     }
 }
 
@@ -3634,7 +3656,7 @@ the only relative value that users see is `unspecified'.
 However, for :height, floating point values are also relative.  */)
   (Lisp_Object attribute, Lisp_Object value)
 {
-  if (EQ (value, Qunspecified) || (EQ (value, Qignore_defface)))
+  if (EQ (value, Qunspecified) || (EQ (value, QCignore_defface)))
     return Qt;
   else if (EQ (attribute, QCheight))
     return INTEGERP (value) ? Qnil : Qt;
@@ -3649,7 +3671,7 @@ If VALUE1 or VALUE2 are absolute (see `face-attribute-relative-p'), then
 the result will be absolute, otherwise it will be relative.  */)
   (Lisp_Object attribute, Lisp_Object value1, Lisp_Object value2)
 {
-  if (EQ (value1, Qunspecified) || EQ (value1, Qignore_defface))
+  if (EQ (value1, Qunspecified) || EQ (value1, QCignore_defface))
     return value2;
   else if (EQ (attribute, QCheight))
     return merge_face_heights (value1, value2, value1);
@@ -3813,6 +3835,18 @@ Default face attributes override any local face attributes.  */)
              Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, name),
                                                      Qnil));
            }
+
+         if (STRINGP (gvec[LFACE_FOREGROUND_INDEX]))
+           Fmodify_frame_parameters (frame,
+                                     Fcons (Fcons (Qforeground_color,
+                                                   gvec[LFACE_FOREGROUND_INDEX]),
+                                            Qnil));
+
+         if (STRINGP (gvec[LFACE_BACKGROUND_INDEX]))
+           Fmodify_frame_parameters (frame,
+                                     Fcons (Fcons (Qbackground_color,
+                                                   gvec[LFACE_BACKGROUND_INDEX]),
+                                            Qnil));
        }
     }
 
@@ -4041,7 +4075,7 @@ lface_same_font_attributes_p (Lisp_Object *lface1, Lisp_Object *lface2)
   xassert (lface_fully_specified_p (lface1)
           && lface_fully_specified_p (lface2));
   return (xstrcasecmp (SSDATA (lface1[LFACE_FAMILY_INDEX]),
-                       SSDATA (lface2[LFACE_FAMILY_INDEX])) == 0
+                      SSDATA (lface2[LFACE_FAMILY_INDEX])) == 0
          && xstrcasecmp (SSDATA (lface1[LFACE_FOUNDRY_INDEX]),
                          SSDATA (lface2[LFACE_FOUNDRY_INDEX])) == 0
          && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
@@ -4053,7 +4087,7 @@ lface_same_font_attributes_p (Lisp_Object *lface1, Lisp_Object *lface2)
              || (STRINGP (lface1[LFACE_FONTSET_INDEX])
                  && STRINGP (lface2[LFACE_FONTSET_INDEX])
                  && ! xstrcasecmp (SSDATA (lface1[LFACE_FONTSET_INDEX]),
-                                    SSDATA (lface2[LFACE_FONTSET_INDEX]))))
+                                   SSDATA (lface2[LFACE_FONTSET_INDEX]))))
          );
 }
 
@@ -4155,13 +4189,13 @@ prepare_face_for_display (struct frame *f, struct face *face)
 static int
 color_distance (XColor *x, XColor *y)
 {
-  /* This formula is from a paper title `Colour metric' by Thiadmer Riemersma.
+  /* This formula is from a paper titled `Colour metric' by Thiadmer Riemersma.
      Quoting from that paper:
 
-         This formula has results that are very close to L*u*v* (with the
-         modified lightness curve) and, more importantly, it is a more even
-         algorithm: it does not have a range of colours where it suddenly
-         gives far from optimal results.
+        This formula has results that are very close to L*u*v* (with the
+        modified lightness curve) and, more importantly, it is a more even
+        algorithm: it does not have a range of colors where it suddenly
+        gives far from optimal results.
 
      See <http://www.compuphase.com/cmetric.htm> for more info.  */
 
@@ -4399,15 +4433,8 @@ cache_face (struct face_cache *c, struct face *face, unsigned int hash)
   if (i == c->used)
     {
       if (c->used == c->size)
-       {
-         int new_size, sz;
-         new_size = min (2 * c->size, MAX_FACE_ID);
-         if (new_size == c->size)
-           abort ();  /* Alternatives?  ++kfs */
-         sz = new_size * sizeof *c->faces_by_id;
-         c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz);
-         c->size = new_size;
-       }
+       c->faces_by_id = xpalloc (c->faces_by_id, &c->size, 1, MAX_FACE_ID,
+                                 sizeof *c->faces_by_id);
       c->used++;
     }
 
@@ -4691,7 +4718,8 @@ face_with_height (struct frame *f, int face_id, int height)
    default face.  FACE_ID is assumed to be already realized.  */
 
 int
-lookup_derived_face (struct frame *f, Lisp_Object symbol, int face_id, int signal_p)
+lookup_derived_face (struct frame *f, Lisp_Object symbol, int face_id,
+                    int signal_p)
 {
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
   Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
@@ -4747,7 +4775,8 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector,
     \(2) `close in spirit' to what the attributes specify, if not exact.  */
 
 static int
-x_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, struct face *def_face)
+x_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs,
+                             struct face *def_face)
 {
   Lisp_Object *def_attrs = def_face->lface;
 
@@ -4848,7 +4877,8 @@ x_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, struct face *
    substitution of a `dim' face for italic.  */
 
 static int
-tty_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, struct face *def_face)
+tty_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs,
+                               struct face *def_face)
 {
   int weight;
   Lisp_Object val, fg, bg;
@@ -5000,7 +5030,8 @@ tty_supports_face_attributes_p (struct frame *f, Lisp_Object *attrs, struct face
   /* See if the capabilities we selected above are supported, with the
      given colors.  */
   if (test_caps != 0 &&
-      ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel, bg_tty_color.pixel))
+      ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel,
+                      bg_tty_color.pixel))
     return 0;
 
 
@@ -5272,8 +5303,8 @@ realize_basic_faces (struct frame *f)
        {
          FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
 #ifdef USE_X_TOOLKIT
-          if (FRAME_WINDOW_P (f))
-            x_update_menu_appearance (f);
+         if (FRAME_WINDOW_P (f))
+           x_update_menu_appearance (f);
 #endif
        }
 
@@ -5393,14 +5424,14 @@ realize_default_face (struct frame *f)
   if (FRAME_X_P (f) && face->font != FRAME_FONT (f))
     {
       /* This can happen when making a frame on a display that does
-        not support the default font.  */
+        not support the default font.  */
       if (!face->font)
-       return 0;
+       return 0;
 
       /* Otherwise, the font specified for the frame was not
-        acceptable as a font for the default face (perhaps because
-        auto-scaled fonts are rejected), so we must adjust the frame
-        font.  */
+        acceptable as a font for the default face (perhaps because
+        auto-scaled fonts are rejected), so we must adjust the frame
+        font.  */
       x_set_font (f, LFACE_FONT (lface), Qnil);
     }
 #endif /* HAVE_X_WINDOWS */
@@ -5491,7 +5522,8 @@ realize_face (struct face_cache *cache, Lisp_Object *attrs, int former_face_id)
    no-font.  */
 
 static struct face *
-realize_non_ascii_face (struct frame *f, Lisp_Object font_object, struct face *base_face)
+realize_non_ascii_face (struct frame *f, Lisp_Object font_object,
+                       struct face *base_face)
 {
   struct face_cache *cache = FRAME_FACE_CACHE (f);
   struct face *face;
@@ -5610,7 +5642,7 @@ realize_x_face (struct face_cache *cache, Lisp_Object *attrs)
   else if (INTEGERP (box))
     {
       /* Simple box of specified line width in foreground color of the
-         face.  */
+        face.  */
       xassert (XINT (box) != 0);
       face->box = FACE_SIMPLE_BOX;
       face->box_line_width = XINT (box);
@@ -5732,7 +5764,8 @@ realize_x_face (struct face_cache *cache, Lisp_Object *attrs)
    default foreground/background colors.  */
 
 static void
-map_tty_color (struct frame *f, struct face *face, enum lface_attribute_index idx, int *defaulted)
+map_tty_color (struct frame *f, struct face *face,
+              enum lface_attribute_index idx, int *defaulted)
 {
   Lisp_Object frame, color, def;
   int foreground_p = idx == LFACE_FOREGROUND_INDEX;
@@ -5788,7 +5821,7 @@ map_tty_color (struct frame *f, struct face *face, enum lface_attribute_index id
              face->lface[idx] = tty_color_name (f, pixel);
              *defaulted = 1;
            }
-        }
+       }
 #endif /* MSDOS */
     }
 
@@ -5973,9 +6006,18 @@ face_at_buffer_position (struct window *w, EMACS_INT pos,
 
   *endptr = endpos;
 
-  default_face = FACE_FROM_ID (f, base_face_id >= 0 ? base_face_id
-                              : NILP (Vface_remapping_alist) ? DEFAULT_FACE_ID
-                              : lookup_basic_face (f, DEFAULT_FACE_ID));
+  {
+    int face_id;
+
+    if (base_face_id >= 0)
+      face_id = base_face_id;
+    else if (NILP (Vface_remapping_alist))
+      face_id = DEFAULT_FACE_ID;
+    else
+      face_id = lookup_basic_face (f, DEFAULT_FACE_ID);
+
+    default_face = FACE_FROM_ID (f, face_id);
+  }
 
   /* Optimize common cases where we can use the default face.  */
   if (noverlays == 0
@@ -6393,153 +6435,82 @@ DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
 void
 syms_of_xfaces (void)
 {
-  Qface = intern_c_string ("face");
-  staticpro (&Qface);
-  Qface_no_inherit = intern_c_string ("face-no-inherit");
-  staticpro (&Qface_no_inherit);
-  Qbitmap_spec_p = intern_c_string ("bitmap-spec-p");
-  staticpro (&Qbitmap_spec_p);
-  Qframe_set_background_mode = intern_c_string ("frame-set-background-mode");
-  staticpro (&Qframe_set_background_mode);
+  DEFSYM (Qface, "face");
+  DEFSYM (Qface_no_inherit, "face-no-inherit");
+  DEFSYM (Qbitmap_spec_p, "bitmap-spec-p");
+  DEFSYM (Qframe_set_background_mode, "frame-set-background-mode");
 
   /* Lisp face attribute keywords.  */
-  QCfamily = intern_c_string (":family");
-  staticpro (&QCfamily);
-  QCheight = intern_c_string (":height");
-  staticpro (&QCheight);
-  QCweight = intern_c_string (":weight");
-  staticpro (&QCweight);
-  QCslant = intern_c_string (":slant");
-  staticpro (&QCslant);
-  QCunderline = intern_c_string (":underline");
-  staticpro (&QCunderline);
-  QCinverse_video = intern_c_string (":inverse-video");
-  staticpro (&QCinverse_video);
-  QCreverse_video = intern_c_string (":reverse-video");
-  staticpro (&QCreverse_video);
-  QCforeground = intern_c_string (":foreground");
-  staticpro (&QCforeground);
-  QCbackground = intern_c_string (":background");
-  staticpro (&QCbackground);
-  QCstipple = intern_c_string (":stipple");
-  staticpro (&QCstipple);
-  QCwidth = intern_c_string (":width");
-  staticpro (&QCwidth);
-  QCfont = intern_c_string (":font");
-  staticpro (&QCfont);
-  QCfontset = intern_c_string (":fontset");
-  staticpro (&QCfontset);
-  QCbold = intern_c_string (":bold");
-  staticpro (&QCbold);
-  QCitalic = intern_c_string (":italic");
-  staticpro (&QCitalic);
-  QCoverline = intern_c_string (":overline");
-  staticpro (&QCoverline);
-  QCstrike_through = intern_c_string (":strike-through");
-  staticpro (&QCstrike_through);
-  QCbox = intern_c_string (":box");
-  staticpro (&QCbox);
-  QCinherit = intern_c_string (":inherit");
-  staticpro (&QCinherit);
+  DEFSYM (QCfamily, ":family");
+  DEFSYM (QCheight, ":height");
+  DEFSYM (QCweight, ":weight");
+  DEFSYM (QCslant, ":slant");
+  DEFSYM (QCunderline, ":underline");
+  DEFSYM (QCinverse_video, ":inverse-video");
+  DEFSYM (QCreverse_video, ":reverse-video");
+  DEFSYM (QCforeground, ":foreground");
+  DEFSYM (QCbackground, ":background");
+  DEFSYM (QCstipple, ":stipple");
+  DEFSYM (QCwidth, ":width");
+  DEFSYM (QCfont, ":font");
+  DEFSYM (QCfontset, ":fontset");
+  DEFSYM (QCbold, ":bold");
+  DEFSYM (QCitalic, ":italic");
+  DEFSYM (QCoverline, ":overline");
+  DEFSYM (QCstrike_through, ":strike-through");
+  DEFSYM (QCbox, ":box");
+  DEFSYM (QCinherit, ":inherit");
 
   /* Symbols used for Lisp face attribute values.  */
-  QCcolor = intern_c_string (":color");
-  staticpro (&QCcolor);
-  QCline_width = intern_c_string (":line-width");
-  staticpro (&QCline_width);
-  QCstyle = intern_c_string (":style");
-  staticpro (&QCstyle);
-  Qreleased_button = intern_c_string ("released-button");
-  staticpro (&Qreleased_button);
-  Qpressed_button = intern_c_string ("pressed-button");
-  staticpro (&Qpressed_button);
-  Qnormal = intern_c_string ("normal");
-  staticpro (&Qnormal);
-  Qultra_light = intern_c_string ("ultra-light");
-  staticpro (&Qultra_light);
-  Qextra_light = intern_c_string ("extra-light");
-  staticpro (&Qextra_light);
-  Qlight = intern_c_string ("light");
-  staticpro (&Qlight);
-  Qsemi_light = intern_c_string ("semi-light");
-  staticpro (&Qsemi_light);
-  Qsemi_bold = intern_c_string ("semi-bold");
-  staticpro (&Qsemi_bold);
-  Qbold = intern_c_string ("bold");
-  staticpro (&Qbold);
-  Qextra_bold = intern_c_string ("extra-bold");
-  staticpro (&Qextra_bold);
-  Qultra_bold = intern_c_string ("ultra-bold");
-  staticpro (&Qultra_bold);
-  Qoblique = intern_c_string ("oblique");
-  staticpro (&Qoblique);
-  Qitalic = intern_c_string ("italic");
-  staticpro (&Qitalic);
-  Qreverse_oblique = intern_c_string ("reverse-oblique");
-  staticpro (&Qreverse_oblique);
-  Qreverse_italic = intern_c_string ("reverse-italic");
-  staticpro (&Qreverse_italic);
-  Qultra_condensed = intern_c_string ("ultra-condensed");
-  staticpro (&Qultra_condensed);
-  Qextra_condensed = intern_c_string ("extra-condensed");
-  staticpro (&Qextra_condensed);
-  Qcondensed = intern_c_string ("condensed");
-  staticpro (&Qcondensed);
-  Qsemi_condensed = intern_c_string ("semi-condensed");
-  staticpro (&Qsemi_condensed);
-  Qsemi_expanded = intern_c_string ("semi-expanded");
-  staticpro (&Qsemi_expanded);
-  Qexpanded = intern_c_string ("expanded");
-  staticpro (&Qexpanded);
-  Qextra_expanded = intern_c_string ("extra-expanded");
-  staticpro (&Qextra_expanded);
-  Qultra_expanded = intern_c_string ("ultra-expanded");
-  staticpro (&Qultra_expanded);
-  Qbackground_color = intern_c_string ("background-color");
-  staticpro (&Qbackground_color);
-  Qforeground_color = intern_c_string ("foreground-color");
-  staticpro (&Qforeground_color);
-  Qunspecified = intern_c_string ("unspecified");
-  staticpro (&Qunspecified);
-  Qignore_defface = intern_c_string (":ignore-defface");
-  staticpro (&Qignore_defface);
-
-  Qface_alias = intern_c_string ("face-alias");
-  staticpro (&Qface_alias);
-  Qdefault = intern_c_string ("default");
-  staticpro (&Qdefault);
-  Qtool_bar = intern_c_string ("tool-bar");
-  staticpro (&Qtool_bar);
-  Qregion = intern_c_string ("region");
-  staticpro (&Qregion);
-  Qfringe = intern_c_string ("fringe");
-  staticpro (&Qfringe);
-  Qheader_line = intern_c_string ("header-line");
-  staticpro (&Qheader_line);
-  Qscroll_bar = intern_c_string ("scroll-bar");
-  staticpro (&Qscroll_bar);
-  Qmenu = intern_c_string ("menu");
-  staticpro (&Qmenu);
-  Qcursor = intern_c_string ("cursor");
-  staticpro (&Qcursor);
-  Qborder = intern_c_string ("border");
-  staticpro (&Qborder);
-  Qmouse = intern_c_string ("mouse");
-  staticpro (&Qmouse);
-  Qmode_line_inactive = intern_c_string ("mode-line-inactive");
-  staticpro (&Qmode_line_inactive);
-  Qvertical_border = intern_c_string ("vertical-border");
-  staticpro (&Qvertical_border);
-  Qtty_color_desc = intern_c_string ("tty-color-desc");
-  staticpro (&Qtty_color_desc);
-  Qtty_color_standard_values = intern_c_string ("tty-color-standard-values");
-  staticpro (&Qtty_color_standard_values);
-  Qtty_color_by_index = intern_c_string ("tty-color-by-index");
-  staticpro (&Qtty_color_by_index);
-  Qtty_color_alist = intern_c_string ("tty-color-alist");
-  staticpro (&Qtty_color_alist);
-  Qscalable_fonts_allowed = intern_c_string ("scalable-fonts-allowed");
-  staticpro (&Qscalable_fonts_allowed);
+  DEFSYM (QCcolor, ":color");
+  DEFSYM (QCline_width, ":line-width");
+  DEFSYM (QCstyle, ":style");
+  DEFSYM (Qreleased_button, "released-button");
+  DEFSYM (Qpressed_button, "pressed-button");
+  DEFSYM (Qnormal, "normal");
+  DEFSYM (Qultra_light, "ultra-light");
+  DEFSYM (Qextra_light, "extra-light");
+  DEFSYM (Qlight, "light");
+  DEFSYM (Qsemi_light, "semi-light");
+  DEFSYM (Qsemi_bold, "semi-bold");
+  DEFSYM (Qbold, "bold");
+  DEFSYM (Qextra_bold, "extra-bold");
+  DEFSYM (Qultra_bold, "ultra-bold");
+  DEFSYM (Qoblique, "oblique");
+  DEFSYM (Qitalic, "italic");
+  DEFSYM (Qreverse_oblique, "reverse-oblique");
+  DEFSYM (Qreverse_italic, "reverse-italic");
+  DEFSYM (Qultra_condensed, "ultra-condensed");
+  DEFSYM (Qextra_condensed, "extra-condensed");
+  DEFSYM (Qcondensed, "condensed");
+  DEFSYM (Qsemi_condensed, "semi-condensed");
+  DEFSYM (Qsemi_expanded, "semi-expanded");
+  DEFSYM (Qexpanded, "expanded");
+  DEFSYM (Qextra_expanded, "extra-expanded");
+  DEFSYM (Qultra_expanded, "ultra-expanded");
+  DEFSYM (Qbackground_color, "background-color");
+  DEFSYM (Qforeground_color, "foreground-color");
+  DEFSYM (Qunspecified, "unspecified");
+  DEFSYM (QCignore_defface, ":ignore-defface");
+
+  DEFSYM (Qface_alias, "face-alias");
+  DEFSYM (Qdefault, "default");
+  DEFSYM (Qtool_bar, "tool-bar");
+  DEFSYM (Qregion, "region");
+  DEFSYM (Qfringe, "fringe");
+  DEFSYM (Qheader_line, "header-line");
+  DEFSYM (Qscroll_bar, "scroll-bar");
+  DEFSYM (Qmenu, "menu");
+  DEFSYM (Qcursor, "cursor");
+  DEFSYM (Qborder, "border");
+  DEFSYM (Qmouse, "mouse");
+  DEFSYM (Qmode_line_inactive, "mode-line-inactive");
+  DEFSYM (Qvertical_border, "vertical-border");
+  DEFSYM (Qtty_color_desc, "tty-color-desc");
+  DEFSYM (Qtty_color_standard_values, "tty-color-standard-values");
+  DEFSYM (Qtty_color_by_index, "tty-color-by-index");
+  DEFSYM (Qtty_color_alist, "tty-color-alist");
+  DEFSYM (Qscalable_fonts_allowed, "scalable-fonts-allowed");
 
   Vparam_value_alist = Fcons (Fcons (Qnil, Qnil), Qnil);
   staticpro (&Vparam_value_alist);
@@ -6628,20 +6599,22 @@ ignore.  */);
               doc: /* Alist of face remappings.
 Each element is of the form:
 
-   (FACE REPLACEMENT...),
+   (FACE . REPLACEMENT),
+
+which causes display of the face FACE to use REPLACEMENT instead.
+REPLACEMENT is a face specification, i.e. one of the following:
 
-which causes display of the face FACE to use REPLACEMENT... instead.
-REPLACEMENT... is interpreted the same way as the value of a `face'
-text property: it may be (1) A face name, (2) A list of face names,
-(3) A property-list of face attribute/value pairs, or (4) A list of
-face names or lists containing face attribute/value pairs.
+  (1) a face name
+  (2) a property list of attribute/value pairs, or
+  (3) a list in which each element has the form of (1) or (2).
 
-Multiple entries in REPLACEMENT... are merged together to form the final
-result, with faces or attributes earlier in the list taking precedence
-over those that are later.
+List values for REPLACEMENT are merged to form the final face
+specification, with earlier entries taking precedence, in the same as
+as in the `face' text property.
 
-Face-name remapping cycles are suppressed; recursive references use the
-underlying face instead of the remapped face.  So a remapping of the form:
+Face-name remapping cycles are suppressed; recursive references use
+the underlying face instead of the remapped face.  So a remapping of
+the form:
 
    (FACE EXTRA-FACE... FACE)
 
@@ -6649,16 +6622,16 @@ or:
 
    (FACE (FACE-ATTR VAL ...) FACE)
 
-will cause EXTRA-FACE... or (FACE-ATTR VAL ...) to be _merged_ with the
-existing definition of FACE.  Note that for the default face, this isn't
-necessary, as every face inherits from the default face.
+causes EXTRA-FACE... or (FACE-ATTR VAL ...) to be _merged_ with the
+existing definition of FACE.  Note that this isn't necessary for the
+default face, since every face inherits from the default face.
 
-Making this variable buffer-local is a good way to allow buffer-specific
-face definitions.  For instance, the mode my-mode could define a face
-`my-mode-default', and then in the mode setup function, do:
+If this variable is made buffer-local, the face remapping takes effect
+only in that buffer.  For instance, the mode my-mode could define a
+face `my-mode-default', and then in the mode setup function, do:
 
    (set (make-local-variable 'face-remapping-alist)
-        '((default my-mode-default)))).
+       '((default my-mode-default)))).
 
 Because Emacs normally only redraws screen areas when the underlying
 buffer contents change, you may need to call `redraw-display' after