changeset 28960:f2d0a3341577

Obsolete. Use xfaces.c instead.
author Jason Rumney <jasonr@gnu.org>
date Wed, 17 May 2000 19:24:55 +0000
parents 44fce819e7b1
children 8092e0d9d8b9
files src/w32faces.c
diffstat 1 files changed, 0 insertions(+), 6515 deletions(-) [+]
line wrap: on
line diff
--- a/src/w32faces.c	Wed May 17 15:58:11 2000 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6515 +0,0 @@
-/* xfaces.c -- "Face" primitives.
-   Copyright (C) 1993, 1994, 1998, 1999 Free Software Foundation.
-
-This file is part of GNU Emacs.
-
-GNU Emacs is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-/* New face implementation by Gerd Moellmann <gerd@gnu.org>.  */
-
-/* Faces.
-
-   When using Emacs with X, the display style of characters can be
-   changed by defining `faces'.  Each face can specify the following
-   display attributes:
-
-   1. Font family or fontset alias name.
-   
-   2. Relative proportionate width, aka character set width or set
-   width (swidth), e.g. `semi-compressed'.
-   
-   3. Font height in 1/10pt
-   
-   4. Font weight, e.g. `bold'.
-   
-   5. Font slant, e.g. `italic'.
-   
-   6. Foreground color.
-   
-   7. Background color.
-
-   8. Whether or not characters should be underlined, and in what color.
-
-   9. Whether or not characters should be displayed in inverse video.
-
-   10. A background stipple, a bitmap.
-
-   11. Whether or not characters should be overlined, and in what color.
-
-   12. Whether or not characters should be strike-through, and in what
-   color.
-
-   13. Whether or not a box should be drawn around characters, the box
-   type, and, for simple boxes, in what color.
-
-   Faces are frame-local by nature because Emacs allows to define the
-   same named face (face names are symbols) differently for different
-   frames.  Each frame has an alist of face definitions for all named
-   faces.  The value of a named face in such an alist is a Lisp vector
-   with the symbol `face' in slot 0, and a slot for each each of the
-   face attributes mentioned above.
-
-   There is also a global face alist `Vface_new_frame_defaults'.  Face
-   definitions from this list are used to initialize faces of newly
-   created frames.
-   
-   A face doesn't have to specify all attributes.  Those not specified
-   have a value of `unspecified'.  Faces specifying all attributes are
-   called `fully-specified'.
-
-
-   Face merging.
-
-   The display style of a given character in the text is determined by
-   combining several faces.  This process is called `face merging'.
-   Any aspect of the display style that isn't specified by overlays or
-   text properties is taken from the `default' face.  Since it is made
-   sure that the default face is always fully-specified, face merging
-   always results in a fully-specified face.
-
-
-   Face realization.
-   
-   After all face attributes for a character have been determined by
-   merging faces of that character, that face is `realized'.  The
-   realization process maps face attributes to what is physically
-   available on the system where Emacs runs.  The result is a
-   `realized face' in form of a struct face which is stored in the
-   face cache of the frame on which it was realized.
-
-   Face realization is done in the context of the charset of the
-   character to display because different fonts and encodings are used
-   for different charsets.  In other words, for characters of
-   different charsets, different realized faces are needed to display
-   them.
-
-   Faces are always realized for a specific character set and contain
-   a specific font, even if the face being realized specifies a
-   fontset (see `font selection' below).  The reason is that the
-   result of the new font selection stage is better than what can be
-   done with statically defined font name patterns in fontsets.
-
-
-   Unibyte text.
-
-   In unibyte text, Emacs' charsets aren't applicable; function
-   `char-charset' reports CHARSET_ASCII for all characters, including
-   those > 0x7f.  The X registry and encoding of fonts to use is
-   determined from the variable `x-unibyte-registry-and-encoding' in
-   this case.  The variable is initialized at Emacs startup time from
-   the font the user specified for Emacs.
-
-   Currently all unibyte text, i.e. all buffers with
-   enable_multibyte_characters nil are displayed with fonts of the
-   same registry and encoding `x-unibyte-registry-and-encoding'.  This
-   is consistent with the fact that languages can also be set
-   globally, only.
-   
-
-   Font selection.
-
-   Font selection tries to find the best available matching font for a
-   given (charset, face) combination.  This is done slightly
-   differently for faces specifying a fontset, or a font family name.
-
-   If the face specifies a fontset alias name, that fontset determines
-   a pattern for fonts of the given charset.  If the face specifies a
-   font family, a font pattern is constructed.  Charset symbols have a
-   property `x-charset-registry' for that purpose that maps a charset
-   to an XLFD registry and encoding in the font pattern constructed.
-
-   Available fonts on the system on which Emacs runs are then matched
-   against the font pattern.  The result of font selection is the best
-   match for the given face attributes in this font list.
-
-   Font selection can be influenced by the user.
-
-   1. The user can specify the relative importance he gives the face
-   attributes width, height, weight, and slant by setting
-   face-font-selection-order (faces.el) to a list of face attribute
-   names.  The default is '(:width :height :weight :slant), and means
-   that font selection first tries to find a good match for the font
-   width specified by a face, then---within fonts with that
-   width---tries to find a best match for the specified font height,
-   etc.
-
-   2. Setting face-alternative-font-family-alist allows the user to
-   specify alternative font families to try if a family specified by a
-   face doesn't exist.
-
-
-   Composite characters.  
-   
-   Realized faces for composite characters are the only ones having a
-   fontset id >= 0.  When a composite character is encoded into a
-   sequence of non-composite characters (in xterm.c), a suitable font
-   for the non-composite characters is then selected and realized,
-   i.e.  the realization process is delayed but in principle the same.
-
-   
-   Initialization of basic faces.
-
-   The faces `default', `modeline' are considered `basic faces'.
-   When redisplay happens the first time for a newly created frame,
-   basic faces are realized for CHARSET_ASCII.  Frame parameters are
-   used to fill in unspecified attributes of the default face.  */
-
-/* Define SCALABLE_FONTS to a non-zero value to enable scalable
-   font use. Define it to zero to disable scalable font use.
-
-   Use of too many or too large scalable fonts can crash XFree86
-   servers.  That's why I've put the code dealing with scalable fonts
-   in #if's.  */
-
-#define SCALABLE_FONTS 1
-
-#include <config.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "lisp.h"
-#include "charset.h"
-#include "frame.h"
-
-#ifdef HAVE_X_WINDOWS
-#include "xterm.h"
-#include "fontset.h"
-#ifdef USE_MOTIF
-#include <Xm/Xm.h>
-#include <Xm/XmStrDefs.h>
-#endif /* USE_MOTIF */
-#endif
-
-#ifdef MSDOS
-#include "dosfns.h"
-#endif
-
-#ifdef WINDOWSNT
-#include "w32term.h"
-#include "fontset.h"
-#endif
-
-#include "buffer.h"
-#include "dispextern.h"
-#include "blockinput.h"
-#include "window.h"
-#include "intervals.h"
-
-#ifdef HAVE_X_WINDOWS
-
-/* Compensate for a bug in Xos.h on some systems, on which it requires
-   time.h.  On some such systems, Xos.h tries to redefine struct
-   timeval and struct timezone if USG is #defined while it is
-   #included.  */
-
-#ifdef XOS_NEEDS_TIME_H
-#include <time.h>
-#undef USG
-#include <X11/Xos.h>
-#define USG
-#define __TIMEVAL__
-#else /* not XOS_NEEDS_TIME_H */
-#include <X11/Xos.h>
-#endif /* not XOS_NEEDS_TIME_H */
-
-#endif /* HAVE_X_WINDOWS */
-
-#include <stdio.h>
-#include <ctype.h>
-#include "keyboard.h"
-
-#ifndef max
-#define max(A, B)	((A) > (B) ? (A) : (B))
-#define min(A, B)	((A) < (B) ? (A) : (B))
-#define abs(X)		((X) < 0 ? -(X) : (X))
-#endif
-
-/* Non-zero if face attribute ATTR is unspecified.  */
-
-#define UNSPECIFIEDP(ATTR) EQ ((ATTR), Qunspecified)
-
-/* Value is the number of elements of VECTOR.  */
-
-#define DIM(VECTOR) (sizeof (VECTOR) / sizeof *(VECTOR))
-
-/* Make a copy of string S on the stack using alloca.  Value is a pointer 
-   to the copy.  */
-
-#define STRDUPA(S) strcpy ((char *) alloca (strlen ((S)) + 1), (S))
-
-/* Make a copy of the contents of Lisp string S on the stack using
-   alloca.  Value is a pointer to the copy.  */
-
-#define LSTRDUPA(S) STRDUPA (XSTRING ((S))->data)
-
-/* Size of hash table of realized faces in face caches (should be a 
-   prime number).  */
-
-#define FACE_CACHE_BUCKETS_SIZE 1001
-
-/* A definition of XColor for non-X frames.  */
-#ifndef HAVE_X_WINDOWS
-typedef struct {
-  unsigned long pixel;
-  unsigned short red, green, blue;
-  char flags;
-  char pad;
-} XColor;
-#endif
-
-/* Keyword symbols used for face attribute names.  */
-
-Lisp_Object QCfamily, QCheight, QCweight, QCslant, QCunderline;
-Lisp_Object QCinverse_video, QCforeground, QCbackground, QCstipple;
-Lisp_Object QCwidth, QCfont, QCbold, QCitalic;
-Lisp_Object QCreverse_video;
-Lisp_Object QCoverline, QCstrike_through, QCbox;
-
-/* Symbols used for attribute values.  */
-
-Lisp_Object Qnormal, Qbold, Qultra_light, Qextra_light, Qlight;
-Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
-Lisp_Object Qoblique, Qitalic, Qreverse_oblique, Qreverse_italic;
-Lisp_Object Qultra_condensed, Qextra_condensed, Qcondensed;
-Lisp_Object Qsemi_condensed, Qsemi_expanded, Qexpanded, Qextra_expanded;
-Lisp_Object Qultra_expanded;
-Lisp_Object Qreleased_button, Qpressed_button;
-Lisp_Object QCstyle, QCcolor, QCline_width;
-Lisp_Object Qunspecified;
-
-char unspecified_fg[] = "unspecified-fg", unspecified_bg[] = "unspecified-bg";
-
-/* The symbol `x-charset-registry'.  This property of charsets defines
-   the X registry and encoding that fonts should have that are used to
-   display characters of that charset.  */
-
-Lisp_Object Qx_charset_registry;
-
-/* The name of the function to call when the background of the frame
-   has changed, frame_update_face_colors.  */
-
-Lisp_Object Qframe_update_face_colors;
-
-/* Names of basic faces.  */
-
-Lisp_Object Qdefault, Qtool_bar, Qregion, Qfringe;
-Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse, Qmenu;
-extern Lisp_Object Qmode_line;
-
-/* The symbol `face-alias'.  A symbols having that property is an
-   alias for another face.  Value of the property is the name of
-   the aliased face.  */
-
-Lisp_Object Qface_alias;
-
-/* Names of frame parameters related to faces.  */
-
-extern Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
-extern Lisp_Object Qborder_color, Qcursor_color, Qmouse_color;
-
-/* Default stipple pattern used on monochrome displays.  This stipple
-   pattern is used on monochrome displays instead of shades of gray
-   for a face background color.  See `set-face-stipple' for possible
-   values for this variable.  */
-
-Lisp_Object Vface_default_stipple;
-
-/* Default registry and encoding to use for charsets whose charset
-   symbols don't specify one.  */
-
-Lisp_Object Vface_default_registry;
-
-/* Alist of alternative font families.  Each element is of the form
-   (FAMILY FAMILY1 FAMILY2 ...).  If fonts of FAMILY can't be loaded,
-   try FAMILY1, then FAMILY2, ...  */
-
-Lisp_Object Vface_alternative_font_family_alist;
-
-/* Allowed scalable fonts.  A value of nil means don't allow any
-   scalable fonts.  A value of t means allow the use of any scalable
-   font.  Otherwise, value must be a list of regular expressions.  A
-   font may be scaled if its name matches a regular expression in the
-   list.  */
-
-#if SCALABLE_FONTS
-Lisp_Object Vscalable_fonts_allowed;
-#endif
-
-/* Maximum number of fonts to consider in font_list.  If not an
-   integer > 0, DEFAULT_FONT_LIST_LIMIT is used instead.  */
-
-Lisp_Object Vfont_list_limit;
-#define DEFAULT_FONT_LIST_LIMIT 100
-
-/* The symbols `foreground-color' and `background-color' which can be
-   used as part of a `face' property.  This is for compatibility with
-   Emacs 20.2.  */
-
-Lisp_Object Qforeground_color, Qbackground_color;
-
-/* The symbols `face' and `mouse-face' used as text properties.  */
-
-Lisp_Object Qface;
-extern Lisp_Object Qmouse_face;
-
-/* Error symbol for wrong_type_argument in load_pixmap.  */
-
-Lisp_Object Qbitmap_spec_p;
-
-/* Alist of global face definitions.  Each element is of the form
-   (FACE . LFACE) where FACE is a symbol naming a face and LFACE
-   is a Lisp vector of face attributes.  These faces are used
-   to initialize faces for new frames.  */
-
-Lisp_Object Vface_new_frame_defaults;
-
-/* The next ID to assign to Lisp faces.  */
-
-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;
-
-/* tty color-related functions (defined on lisp/term/tty-colors.el).  */
-Lisp_Object Qtty_color_desc, Qtty_color_by_index;
-
-/* Counter for calls to clear_face_cache.  If this counter reaches
-   CLEAR_FONT_TABLE_COUNT, and a frame has more than
-   CLEAR_FONT_TABLE_NFONTS load, unused fonts are freed.  */
-
-static int clear_font_table_count;
-#define CLEAR_FONT_TABLE_COUNT	100
-#define CLEAR_FONT_TABLE_NFONTS	10
-
-/* Non-zero means face attributes have been changed since the last
-   redisplay.  Used in redisplay_internal.  */
-
-int face_change_count;
-
-/* The total number of colors currently allocated.  */
-
-#if GLYPH_DEBUG
-static int ncolors_allocated;
-static int npixmaps_allocated;
-static int ngcs;
-#endif
-
-
-
-/* Function prototypes.  */
-
-struct font_name;
-struct table_entry;
-
-static Lisp_Object resolve_face_name P_ ((Lisp_Object));
-static int may_use_scalable_font_p P_ ((struct font_name *, char *));
-static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object));
-static int better_font_p P_ ((int *, struct font_name *, struct font_name *,
-			      int));
-static int first_font_matching P_ ((struct frame *f, char *,
-				    struct font_name *));
-static int x_face_list_fonts P_ ((struct frame *, char *,
-				  struct font_name *, int, int, int));
-static int font_scalable_p P_ ((struct font_name *));
-static Lisp_Object deduce_unibyte_registry P_ ((struct frame *, char *));
-static int get_lface_attributes P_ ((struct frame *, Lisp_Object, Lisp_Object *, int));
-static int load_pixmap P_ ((struct frame *, Lisp_Object, unsigned *, unsigned *));
-static char *xstrdup P_ ((char *));
-static unsigned char *xstrlwr P_ ((unsigned char *));
-static void signal_error P_ ((char *, Lisp_Object));
-static struct frame *frame_or_selected_frame P_ ((Lisp_Object, int));
-static void load_face_font_or_fontset P_ ((struct frame *, struct face *, char *, int));
-static void load_face_colors P_ ((struct frame *, struct face *, Lisp_Object *));
-static void free_face_colors P_ ((struct frame *, struct face *));
-static int face_color_gray_p P_ ((struct frame *, char *));
-static char *build_font_name P_ ((struct font_name *));
-static void free_font_names P_ ((struct font_name *, int));
-static int sorted_font_list P_ ((struct frame *, char *,
-				 int (*cmpfn) P_ ((const void *, const void *)),
-				 struct font_name **));
-static int font_list P_ ((struct frame *, char *, char *, char *, struct font_name **));
-static int try_font_list P_ ((struct frame *, Lisp_Object *, char *, char *, char *,
-			      struct font_name **));
-static int cmp_font_names P_ ((const void *, const void *));
-static struct face *realize_face P_ ((struct face_cache *,
-				      Lisp_Object *, int));
-static struct face *realize_x_face P_ ((struct face_cache *,
-					Lisp_Object *, int));
-static struct face *realize_tty_face P_ ((struct face_cache *,
-					  Lisp_Object *, int));
-static int realize_basic_faces P_ ((struct frame *));
-static int realize_default_face P_ ((struct frame *));
-static void realize_named_face P_ ((struct frame *, Lisp_Object, int));
-static int lface_fully_specified_p P_ ((Lisp_Object *));
-static int lface_equal_p P_ ((Lisp_Object *, Lisp_Object *));
-static unsigned hash_string_case_insensitive P_ ((Lisp_Object));
-static unsigned lface_hash P_ ((Lisp_Object *));
-static int lface_same_font_attributes_p P_ ((Lisp_Object *, Lisp_Object *));
-static struct face_cache *make_face_cache P_ ((struct frame *));
-static void free_realized_face P_ ((struct frame *, struct face *));
-static void clear_face_gcs P_ ((struct face_cache *));
-static void free_face_cache P_ ((struct face_cache *));
-static int face_numeric_weight P_ ((Lisp_Object));
-static int face_numeric_slant P_ ((Lisp_Object));
-static int face_numeric_swidth P_ ((Lisp_Object));
-static int face_fontset P_ ((struct frame *, Lisp_Object *));
-static char *choose_face_font P_ ((struct frame *, Lisp_Object *, int,
-				   Lisp_Object));
-static char *choose_face_fontset_font P_ ((struct frame *, Lisp_Object *,
-					   int, int));
-static void merge_face_vectors P_ ((Lisp_Object *from, Lisp_Object *));
-static void merge_face_vector_with_property P_ ((struct frame *, Lisp_Object *,
-						 Lisp_Object));
-static int set_lface_from_font_name P_ ((struct frame *, Lisp_Object, char *,
-					 int, int));
-static Lisp_Object lface_from_face_name P_ ((struct frame *, Lisp_Object, int));
-static struct face *make_realized_face P_ ((Lisp_Object *, int, Lisp_Object));
-static void free_realized_faces P_ ((struct face_cache *));
-static char *best_matching_font P_ ((struct frame *, Lisp_Object *,
-				     struct font_name *, int));
-static void cache_face P_ ((struct face_cache *, struct face *, unsigned));
-static void uncache_face P_ ((struct face_cache *, struct face *));
-static int xlfd_numeric_slant P_ ((struct font_name *));
-static int xlfd_numeric_weight P_ ((struct font_name *));
-static int xlfd_numeric_swidth P_ ((struct font_name *));
-static Lisp_Object xlfd_symbolic_slant P_ ((struct font_name *));
-static Lisp_Object xlfd_symbolic_weight P_ ((struct font_name *));
-static Lisp_Object xlfd_symbolic_swidth P_ ((struct font_name *));
-static int xlfd_fixed_p P_ ((struct font_name *));
-static int xlfd_numeric_value P_ ((struct table_entry *, int, struct font_name *,
-				   int, int));
-static Lisp_Object xlfd_symbolic_value P_ ((struct table_entry *, int,
-					    struct font_name *, int, int));
-static struct table_entry *xlfd_lookup_field_contents P_ ((struct table_entry *, int,
-							   struct font_name *, int));
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-static int split_font_name P_ ((struct frame *, struct font_name *, int));
-static int xlfd_point_size P_ ((struct frame *, struct font_name *));
-static void sort_fonts P_ ((struct frame *, struct font_name *, int,
-			       int (*cmpfn) P_ ((const void *, const void *))));
-static GC x_create_gc P_ ((struct frame *, unsigned long, XGCValues *));
-static void x_free_gc P_ ((struct frame *, GC));
-static void clear_font_table P_ ((struct frame *));
-
-#ifdef WINDOWSNT
-extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
-#endif /* WINDOWSNT */
-
-#endif /* HAVE_WINDOW_SYSTEM */
-
-
-/***********************************************************************
-			      Utilities
- ***********************************************************************/
-
-/* Create and return a GC for use on frame F.  GC values and mask
-   are given by XGCV and MASK.  */
-
-static INLINE GC
-x_create_gc (f, mask, xgcv)
-     struct frame *f;
-     unsigned long mask;
-     XGCValues *xgcv;
-{
-  GC gc;
-  BLOCK_INPUT;
-  gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, xgcv);
-  UNBLOCK_INPUT;
-  IF_DEBUG (++ngcs);
-  return gc;
-}
-
-
-/* Free GC which was used on frame F.  */
-
-static INLINE void
-x_free_gc (f, gc)
-     struct frame *f;
-     GC gc;
-{
-  BLOCK_INPUT;
-  xassert (--ngcs >= 0);
-  xfree (gc);
-  UNBLOCK_INPUT;
-}
-
-
-/* Like strdup, but uses xmalloc.  */
-
-static char *
-xstrdup (s)
-     char *s;
-{
-  int len = strlen (s) + 1;
-  char *p = (char *) xmalloc (len);
-  bcopy (s, p, len);
-  return p;
-}
-
-
-/* Like stricmp.  Used to compare parts of font names which are in
-   ISO8859-1.  */
-
-int
-xstricmp (s1, s2)
-     unsigned char *s1, *s2;
-{
-  while (*s1 && *s2)
-    {
-      unsigned char c1 = tolower (*s1);
-      unsigned char c2 = tolower (*s2);
-      if (c1 != c2)
-	return c1 < c2 ? -1 : 1;
-      ++s1, ++s2;
-    }
-
-  if (*s1 == 0)
-    return *s2 == 0 ? 0 : -1;
-  return 1;
-}
-
-
-/* Like strlwr, which might not always be available.  */
-
-static unsigned char *
-xstrlwr (s)
-     unsigned char *s;
-{
-  unsigned char *p = s;
-
-  for (p = s; *p; ++p)
-    *p = tolower (*p);
-
-  return s;
-}
-
-
-/* Signal `error' with message S, and additional argument ARG.  */
-
-static void
-signal_error (s, arg)
-     char *s;
-     Lisp_Object arg;
-{
-  Fsignal (Qerror, Fcons (build_string (s), Fcons (arg, Qnil)));
-}
-
-
-/* If FRAME is nil, return a pointer to the selected frame.
-   Otherwise, check that FRAME is a live frame, and return a pointer
-   to it.  NPARAM is the parameter number of FRAME, for
-   CHECK_LIVE_FRAME.  This is here because it's a frequent pattern in
-   Lisp function definitions.  */
-
-static INLINE struct frame *
-frame_or_selected_frame (frame, nparam)
-     Lisp_Object frame;
-     int nparam;
-{
-  if (NILP (frame))
-    frame = selected_frame;
-
-  CHECK_LIVE_FRAME (frame, nparam);
-  return XFRAME (frame);
-}
-
-
-/***********************************************************************
-			   Frames and faces
- ***********************************************************************/
-
-/* Initialize face cache and basic faces for frame F.  */
-
-void
-init_frame_faces (f)
-     struct frame *f;
-{
-  /* Make a face cache, if F doesn't have one.  */
-  if (FRAME_FACE_CACHE (f) == NULL)
-    FRAME_FACE_CACHE (f) = make_face_cache (f);
-      
-#ifdef HAVE_WINDOW_SYSTEM
-  /* Make the image cache.  */
-  if (FRAME_WINDOW_P (f))
-    {
-      if (FRAME_X_IMAGE_CACHE (f) == NULL)
-	FRAME_X_IMAGE_CACHE (f) = make_image_cache ();
-      ++FRAME_X_IMAGE_CACHE (f)->refcount;
-    }
-#endif /* HAVE_WINDOW_SYSTEM */
-
-  /* Realize basic faces.  Must have enough information in frame 
-     parameters to realize basic faces at this point.  */
-#ifdef HAVE_X_WINDOWS
-  if (!FRAME_X_P (f) || FRAME_X_WINDOW (f))
-#endif
-#ifdef WINDOWSNT
-  if (!FRAME_WINDOW_P (f) || FRAME_W32_WINDOW (f))
-#endif
-    if (!realize_basic_faces (f))
-      abort ();
-}
-
-
-/* Free face cache of frame F.  Called from Fdelete_frame.  */
-
-void
-free_frame_faces (f)
-     struct frame *f;
-{
-  struct face_cache *face_cache = FRAME_FACE_CACHE (f);
-  
-  if (face_cache)
-    {
-      free_face_cache (face_cache);
-      FRAME_FACE_CACHE (f) = NULL;
-    }
-
-#ifdef HAVE_WINDOW_SYSTEM
-  if (FRAME_WINDOW_P (f))
-    {
-      struct image_cache *image_cache = FRAME_X_IMAGE_CACHE (f);
-      if (image_cache)
-	{
-	  --image_cache->refcount;
-	  if (image_cache->refcount == 0)
-	    free_image_cache (f);
-	}
-    }
-#endif /* HAVE_WINDOW_SYSTEM */
-}
-
-
-/* Clear face caches, and recompute basic faces for frame F.  Call
-   this after changing frame parameters on which those faces depend,
-   or when realized faces have been freed due to changing attributes
-   of named faces. */
-
-void
-recompute_basic_faces (f)
-     struct frame *f;
-{
-  if (FRAME_FACE_CACHE (f))
-    {
-      clear_face_cache (0);
-      if (!realize_basic_faces (f))
-	abort ();
-    }
-}
-
-
-/* Clear the face caches of all frames.  CLEAR_FONTS_P non-zero means
-   try to free unused fonts, too.  */
-
-void
-clear_face_cache (clear_fonts_p)
-     int clear_fonts_p;
-{
-#ifdef HAVE_WINDOW_SYSTEM
-  Lisp_Object tail, frame;
-  struct frame *f;
-
-  if (clear_fonts_p
-      || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT)
-    {
-      /* From time to time see if we can unload some fonts.  This also
-	 frees all realized faces on all frames.  Fonts needed by
-	 faces will be loaded again when faces are realized again.  */
-      clear_font_table_count = 0;
-
-      FOR_EACH_FRAME (tail, frame)
-	{
-	  f = XFRAME (frame);
-	  if (FRAME_WINDOW_P (f)
-	      && FRAME_W32_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
-	    {
-	      free_all_realized_faces (frame);
-	      clear_font_table (f);
-	    }
-	}
-    }
-  else
-    {
-      /* Clear GCs of realized faces.  */
-      FOR_EACH_FRAME (tail, frame)
-	{
-	  f = XFRAME (frame);
-	  if (FRAME_WINDOW_P (f))
-	    {
-	      clear_face_gcs (FRAME_FACE_CACHE (f));
-	      clear_image_cache (f, 0);
-	    }
-	}
-    }
-#endif /* HAVE_WINDOW_SYSTEM */
-}
-
-
-DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0,
-  "Clear face caches on all frames.\n\
-Optional THOROUGHLY non-nil means try to free unused fonts, too.")
-  (thorougly)
-     Lisp_Object thorougly;
-{
-  clear_face_cache (!NILP (thorougly));
-  return Qnil;
-}
-
-
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-
-/* Remove those fonts from the font table of frame F that are not used
-   by fontsets.  Called from clear_face_cache from time to time.  */
-
-static void
-clear_font_table (f)
-     struct frame *f;
-{
-  struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
-  char *used;
-  Lisp_Object rest, frame;
-  int i;
-
-  xassert (FRAME_WINDOW_P (f));
-
-  used = (char *) alloca (dpyinfo->n_fonts * sizeof *used);
-  bzero (used, dpyinfo->n_fonts * sizeof *used);
-
-  /* For all frames with the same w32_display_info as F, record
-     in `used' those fonts that are in use by fontsets.  */
-  FOR_EACH_FRAME (rest, frame)
-    if (FRAME_W32_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
-      {
-	struct frame *f = XFRAME (frame);
-	struct fontset_data *fontset_data = FRAME_FONTSET_DATA (f);
-
-	for (i = 0; i < fontset_data->n_fontsets; ++i)
-	  {
-	    struct fontset_info *info = fontset_data->fontset_table[i];
-	    int j;
-	    
-	    for (j = 0; j <= MAX_CHARSET; ++j)
-	      {
-		int idx = info->font_indexes[j];
-		if (idx >= 0)
-		  used[idx] = 1;
-	      }
-	  }
-      }
-
-  /* Free those fonts that are not used by fontsets.  */
-  for (i = 0; i < dpyinfo->n_fonts; ++i)
-    if (used[i] == 0 && dpyinfo->font_table[i].name)
-      {
-	struct font_info *font_info = dpyinfo->font_table + i;
-
-	/* Free names.  In xfns.c there is a comment that full_name
-	   should never be freed because it is always shared with
-	   something else.  I don't think this is true anymore---see
-	   x_load_font.  It's either equal to font_info->name or
-	   allocated via xmalloc, and there seems to be no place in
-	   the source files where full_name is transferred to another
-	   data structure.  */
-	if (font_info->full_name != font_info->name)
-	  xfree (font_info->full_name);
-	xfree (font_info->name);
-
-	/* Free the font.  */
-	BLOCK_INPUT;
-	w32_unload_font (dpyinfo, font_info->font);
-	UNBLOCK_INPUT;
-
-	/* Mark font table slot free.  */
-	font_info->font = NULL;
-	font_info->name = font_info->full_name = NULL;
-      }
-}
-
-
-#endif /* HAVE_WINDOW_SYSTEM */
-
-
-
-/***********************************************************************
-			      X Pixmaps
- ***********************************************************************/
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-DEFUN ("bitmap-spec-p", Fbitmap_spec_p, Sbitmap_spec_p, 1, 1, 0,
-  "Value is non-nil if OBJECT is a valid bitmap specification.\n\
-A bitmap specification is either a string, a filename, or a list\n\
-(WIDTH HEIGHT DATA) where WIDTH is the pixel width of the bitmap,\n\
-HEIGHT is its height, and DATA is a string containing the bits of the\n\
-bitmap. Bits are stored row by row, each row occupies\n\
-(WIDTH + 7) / 8 bytes.")
-  (object)
-     Lisp_Object object;
-{
-  int pixmap_p = 0;
-  
-  if (STRINGP (object))
-    /* If OBJECT is a string, it's a file name.  */
-    pixmap_p = 1;
-  else if (CONSP (object))
-    {
-      /* Otherwise OBJECT must be (WIDTH HEIGHT DATA), WIDTH and
-	 HEIGHT must be integers > 0, and DATA must be string large
-	 enough to hold a bitmap of the specified size.  */
-      Lisp_Object width, height, data;
-
-      height = width = data = Qnil;
-      
-      if (CONSP (object))
-	{
-	  width = XCAR (object);
-	  object = XCDR (object);
-	  if (CONSP (object))
-	    {
-	      height = XCAR (object);
-	      object = XCDR (object);
-	      if (CONSP (object))
-		data = XCAR (object);
-	    }
-	}
-
-      if (NATNUMP (width) && NATNUMP (height) && STRINGP (data))
-	{
-	  int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1)
-			       / BITS_PER_CHAR);
-	  if (STRING_BYTES (XSTRING (data)) >= bytes_per_row * height)
-	    pixmap_p = 1;
-	}
-    }
-
-  return pixmap_p ? Qt : Qnil;
-}
-
-
-/* Load a bitmap according to NAME (which is either a file name or a
-   pixmap spec) for use on frame F.  Value is the bitmap_id (see
-   xfns.c).  If NAME is nil, return with a bitmap id of zero.  If
-   bitmap cannot be loaded, display a message saying so, and return
-   zero.  Store the bitmap width in *W_PTR and its height in *H_PTR,
-   if these pointers are not null.  */
-
-static int
-load_pixmap (f, name, w_ptr, h_ptr)
-     FRAME_PTR f;
-     Lisp_Object name;
-     unsigned int *w_ptr, *h_ptr;
-{
-  int bitmap_id;
-  Lisp_Object tem;
-
-  if (NILP (name))
-    return 0;
-
-  tem = Fbitmap_spec_p (name);
-  if (NILP (tem))
-    wrong_type_argument (Qbitmap_spec_p, name);
-
-  BLOCK_INPUT;
-  if (CONSP (name))
-    {
-      /* Decode a bitmap spec into a bitmap.  */
-
-      int h, w;
-      Lisp_Object bits;
-
-      w = XINT (Fcar (name));
-      h = XINT (Fcar (Fcdr (name)));
-      bits = Fcar (Fcdr (Fcdr (name)));
-
-      bitmap_id = x_create_bitmap_from_data (f, XSTRING (bits)->data,
-					     w, h);
-    }
-  else
-    {
-      /* It must be a string -- a file name.  */
-      bitmap_id = x_create_bitmap_from_file (f, name);
-    }
-  UNBLOCK_INPUT;
-
-  if (bitmap_id < 0)
-    {
-      add_to_log ("Invalid or undefined bitmap %s", name, Qnil);
-      bitmap_id = 0;
-
-      if (w_ptr)
-	*w_ptr = 0;
-      if (h_ptr)
-	*h_ptr = 0;
-    }
-  else
-    {
-#if GLYPH_DEBUG
-      ++npixmaps_allocated;
-#endif
-      if (w_ptr)
-	*w_ptr = x_bitmap_width (f, bitmap_id);
-
-      if (h_ptr)
-	*h_ptr = x_bitmap_height (f, bitmap_id);
-    }
-
-  return bitmap_id;
-}
-
-#endif /* HAVE_WINDOW_SYSTEM */
-
-
-
-/***********************************************************************
-			 Minimum font bounds
- ***********************************************************************/
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-/* Update the line_height of frame F.  Return non-zero if line height
-   changes.  */
-
-int
-frame_update_line_height (f)
-     struct frame *f;
-{
-  int fontset, line_height, changed_p;
-  
-  fontset = FRAME_FONTSET (f);
-  if (fontset > 0)
-    line_height = FRAME_FONTSET_DATA (f)->fontset_table[fontset]->height;
-  else
-    line_height = FONT_HEIGHT (FRAME_FONT (f));
-  
-  changed_p = line_height != FRAME_LINE_HEIGHT (f);
-  FRAME_LINE_HEIGHT (f) = line_height;
-  return changed_p;
-}
-
-#endif /* HAVE_WINDOW_SYSTEM */
-
-
-/***********************************************************************
-				Fonts
- ***********************************************************************/
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-/* Load font or fontset of face FACE which is used on frame F.
-   FONTSET is the fontset FACE should use or -1, if FACE doesn't use a
-   fontset.  FONT_NAME is the name of the font to load, if no fontset
-   is used.  It is null if no suitable font name could be determined
-   for the face.  */
-
-static void
-load_face_font_or_fontset (f, face, font_name, fontset)
-     struct frame *f;
-     struct face *face;
-     char *font_name;
-     int fontset;
-{
-  struct font_info *font_info = NULL;
-
-  face->font_info_id = -1;
-  face->fontset = fontset;
-  face->font = NULL;
-  
-  BLOCK_INPUT;
-  if (fontset >= 0)
-    font_info = FS_LOAD_FONT (f, FRAME_W32_FONT_TABLE (f), CHARSET_ASCII,
-			      NULL, fontset);
-  else if (font_name)
-    font_info = FS_LOAD_FONT (f, FRAME_W32_FONT_TABLE (f), face->charset,
-			      font_name, -1);
-  UNBLOCK_INPUT;
-
-  if (font_info)
-    {
-      char *s;
-      int i;
-      
-      face->font_info_id = FONT_INFO_ID (f, font_info);
-      face->font = font_info->font;
-      face->font_name = font_info->full_name;
-
-      /* Make the registry part of the font name readily accessible.
-	 The registry is used to find suitable faces for unibyte text.  */
-      s = font_info->full_name + strlen (font_info->full_name);
-      i = 0;
-      while (i < 2 && --s >= font_info->full_name)
-	if (*s == '-')
-	  ++i;
-
-      if (!STRINGP (face->registry)
-	  || xstricmp (XSTRING (face->registry)->data, s + 1) != 0)
-	{
-	  if (STRINGP (Vface_default_registry)
-	      && !xstricmp (XSTRING (Vface_default_registry)->data, s + 1))
-	    face->registry = Vface_default_registry;
-	  else
-	    face->registry = build_string (s + 1);
-	}
-    }
-  else if (fontset >= 0)
-    add_to_log ("Unable to load ASCII font of fontset %d",
-                make_number (fontset), Qnil);
-  else if (font_name)
-    add_to_log ("Unable to load font %s",
-                build_string (font_name), Qnil);
-}
-
-#endif /* HAVE_WINDOW_SYSTEM */
-
-
-
-/***********************************************************************
-				X Colors
- ***********************************************************************/
-
-/* A version of defined_color for non-X frames.  */
-int
-tty_defined_color (f, color_name, color_def, alloc)
-     struct frame *f;
-     char *color_name;
-     XColor *color_def;
-     int alloc;
-{
-  Lisp_Object color_desc;
-  unsigned long color_idx = FACE_TTY_DEFAULT_COLOR;
-  unsigned long red = 0, green = 0, blue = 0;
-  int status = 1;
-
-  if (*color_name && !NILP (Ffboundp (Qtty_color_desc)))
-    {
-      Lisp_Object frame;
-
-      XSETFRAME (frame, f);
-      status = 0;
-      color_desc = call2 (Qtty_color_desc, build_string (color_name), frame);
-      if (CONSP (color_desc) && CONSP (XCDR (color_desc)))
-	{
-	  color_idx = XINT (XCAR (XCDR (color_desc)));
-	  if (CONSP (XCDR (XCDR (color_desc))))
-	    {
-	      red = XINT (XCAR (XCDR (XCDR (color_desc))));
-	      green = XINT (XCAR (XCDR (XCDR (XCDR (color_desc)))));
-	      blue = XINT (XCAR (XCDR (XCDR (XCDR (XCDR (color_desc))))));
-	    }
-	  status = 1;
-	}
-      else if (NILP (Fsymbol_value (intern ("tty-defined-color-alist"))))
-	/* We were called early during startup, and the colors are not
-	   yet set up in tty-defined-color-alist.  Don't return a failure
-	   indication, since this produces the annoying "Unable to
-	   load color" messages in the *Messages* buffer.  */
-	status = 1;
-    }
-  if (color_idx == FACE_TTY_DEFAULT_COLOR && *color_name)
-    {
-      if (strcmp (color_name, "unspecified-fg") == 0)
-	color_idx = FACE_TTY_DEFAULT_FG_COLOR;
-      else if (strcmp (color_name, "unspecified-bg") == 0)
-	color_idx = FACE_TTY_DEFAULT_BG_COLOR;
-    }
-
-  if (color_idx != FACE_TTY_DEFAULT_COLOR)
-    status = 1;
-
-  color_def->pixel = color_idx;
-  color_def->red = red;
-  color_def->green = green;
-  color_def->blue = blue;
-
-  return status;
-}
-
-/* Decide if color named COLOR is valid for the display associated
-   with the frame F; if so, return the rgb values in COLOR_DEF.  If
-   ALLOC is nonzero, allocate a new colormap cell.
-
-   This does the right thing for any type of frame.  */
-int
-defined_color (f, color_name, color_def, alloc)
-     struct frame *f;
-     char *color_name;
-     XColor *color_def;
-     int alloc;
-{
-  if (!FRAME_WINDOW_P (f))
-    return tty_defined_color (f, color_name, color_def, alloc);
-#ifdef HAVE_X_WINDOWS
-  else if (FRAME_X_P (f))
-    return x_defined_color (f, color_name, color_def, alloc);
-#endif
-#ifdef WINDOWSNT
-  else if (FRAME_W32_P (f))
-    return w32_defined_color (f, color_name, color_def, alloc);
-#endif
-#ifdef macintosh
-  else if (FRAME_MAC_P (f))
-    /* FIXME: mac_defined_color doesn't exist!  */
-    return mac_defined_color (f, color_name, color_def, alloc);
-#endif
-  else
-    abort ();
-}
-
-/* Given the index of the tty color, return its name, a Lisp string.  */
-
-Lisp_Object
-tty_color_name (f, idx)
-     struct frame *f;
-     int idx;
-{
-  char *color;
-
-  if (idx >= 0 && !NILP (Ffboundp (Qtty_color_by_index)))
-    {
-      Lisp_Object frame;
-      Lisp_Object coldesc;
-
-      XSETFRAME (frame, f);
-      coldesc = call2 (Qtty_color_by_index, make_number (idx), frame);
-
-      if (!NILP (coldesc))
-	return XCAR (coldesc);
-    }
-#ifdef MSDOS
-  /* We can have an MSDOG frame under -nw for a short window of
-     opportunity before internal_terminal_init is called.  DTRT.  */
-  if (FRAME_MSDOS_P (f) && !inhibit_window_system)
-    return msdos_stdcolor_name (idx);
-#endif
-
-  if (idx == FACE_TTY_DEFAULT_FG_COLOR)
-    return build_string (unspecified_fg);
-  if (idx == FACE_TTY_DEFAULT_BG_COLOR)
-    return build_string (unspecified_bg);
-
-#ifdef WINDOWSNT
-  return vga_stdcolor_name (idx);
-#endif
-
-  return Qunspecified;
-}
-
-/* Return non-zero if COLOR_NAME is a shade of gray (or white or
-   black) on frame F.  The algorithm is taken from 20.2 faces.el.  */
-
-static int
-face_color_gray_p (f, color_name)
-     struct frame *f;
-     char *color_name;
-{
-  XColor color;
-  int gray_p;
-
-  if (defined_color (f, color_name, &color, 0))
-    gray_p = ((abs (color.red - color.green)
-	       < max (color.red, color.green) / 20)
-	      && (abs (color.green - color.blue)
-		  < max (color.green, color.blue) / 20)
-	      && (abs (color.blue - color.red)
-		  < max (color.blue, color.red) / 20));
-  else
-    gray_p = 0;
-  
-  return gray_p;
-}
-
-
-/* Return non-zero if color COLOR_NAME can be displayed on frame F.
-   BACKGROUND_P non-zero means the color will be used as background
-   color.  */
-
-static int
-face_color_supported_p (f, color_name, background_p)
-     struct frame *f;
-     char *color_name;
-     int background_p;
-{
-  Lisp_Object frame;
-  XColor not_used;
-
-  XSETFRAME (frame, f);
-  return (FRAME_WINDOW_P (f)
-	  ? (!NILP (Fxw_display_color_p (frame))
-             || xstricmp (color_name, "black") == 0
-             || xstricmp (color_name, "white") == 0
-             || (background_p
-                 && face_color_gray_p (f, color_name))
-             || (!NILP (Fx_display_grayscale_p (frame))
-                 && face_color_gray_p (f, color_name)))
-          : tty_defined_color (f, color_name, &not_used, 0));
-}  
-
-
-DEFUN ("color-gray-p", Fcolor_gray_p, Scolor_gray_p, 1, 2, 0,
-  "Return non-nil if COLOR is a shade of gray (or white or black).\n\
-FRAME specifies the frame and thus the display for interpreting COLOR.\n\
-If FRAME is nil or omitted, use the selected frame.")
-   (color, frame)
-     Lisp_Object color, frame;
-{
-  struct frame *f;
-
-  CHECK_FRAME (frame, 0);
-  CHECK_STRING (color, 0);
-  f = XFRAME (frame);
-  return face_color_gray_p (f, XSTRING (color)->data) ? Qt : Qnil;
-}
-
-
-DEFUN ("color-supported-p", Fcolor_supported_p,
-       Scolor_supported_p, 2, 3, 0,
-  "Return non-nil if COLOR can be displayed on FRAME.\n\
-BACKGROUND-P non-nil means COLOR is used as a background.\n\
-If FRAME is nil or omitted, use the selected frame.\n\
-COLOR must be a valid color name.")
-   (color, frame, background_p)
-     Lisp_Object frame, color, background_p;
-{
-  struct frame *f;
-
-  CHECK_FRAME (frame, 0);
-  CHECK_STRING (color, 0);
-  f = XFRAME (frame);
-  if (face_color_supported_p (f, XSTRING (color)->data, !NILP (background_p)))
-    return Qt;
-  return Qnil;
-}
-
-/* Load color with name NAME for use by face FACE on frame F.
-   TARGET_INDEX must be one of LFACE_FOREGROUND_INDEX,
-   LFACE_BACKGROUND_INDEX, LFACE_UNDERLINE_INDEX, LFACE_OVERLINE_INDEX,
-   LFACE_STRIKE_THROUGH_INDEX, or LFACE_BOX_INDEX.  Value is the
-   pixel color.  If color cannot be loaded, display a message, and
-   return the foreground, background or underline color of F, but
-   record that fact in flags of the face so that we don't try to free
-   these colors.  */
-
-unsigned long
-load_color (f, face, name, target_index)
-     struct frame *f;
-     struct face *face;
-     Lisp_Object name;
-     enum lface_attribute_index target_index;
-{
-  XColor color;
-  
-  xassert (STRINGP (name));
-  xassert (target_index == LFACE_FOREGROUND_INDEX
-	   || target_index == LFACE_BACKGROUND_INDEX
-	   || target_index == LFACE_UNDERLINE_INDEX
-	   || target_index == LFACE_OVERLINE_INDEX
-	   || target_index == LFACE_STRIKE_THROUGH_INDEX
-	   || target_index == LFACE_BOX_INDEX);
-      
-  /* if the color map is full, defined_color will return a best match
-     to the values in an existing cell. */
-  if (!defined_color (f, XSTRING (name)->data, &color, 1))
-    {
-      add_to_log ("Unable to load color \"%s\"", name, Qnil);
-      
-      switch (target_index)
-	{
-	case LFACE_FOREGROUND_INDEX:
-	  face->foreground_defaulted_p = 1;
-	  color.pixel = FRAME_FOREGROUND_PIXEL (f);
-	  break;
-	  
-	case LFACE_BACKGROUND_INDEX:
-	  face->background_defaulted_p = 1;
-	  color.pixel = FRAME_BACKGROUND_PIXEL (f);
-	  break;
-	  
-	case LFACE_UNDERLINE_INDEX:
-	  face->underline_defaulted_p = 1;
-	  color.pixel = FRAME_FOREGROUND_PIXEL (f);
-	  break;
-	  
-	case LFACE_OVERLINE_INDEX:
-	  face->overline_color_defaulted_p = 1;
-	  color.pixel = FRAME_FOREGROUND_PIXEL (f);
-	  break;
-	  
-	case LFACE_STRIKE_THROUGH_INDEX:
-	  face->strike_through_color_defaulted_p = 1;
-	  color.pixel = FRAME_FOREGROUND_PIXEL (f);
-	  break;
-	  
-	case LFACE_BOX_INDEX:
-	  face->box_color_defaulted_p = 1;
-	  color.pixel = FRAME_FOREGROUND_PIXEL (f);
-	  break;
-
-	default:
-	  abort ();
-	}
-    }
-#if GLYPH_DEBUG
-  else
-    ++ncolors_allocated;
-#endif
-  
-  return color.pixel;
-}
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-/* Load colors for face FACE which is used on frame F.  Colors are
-   specified by slots LFACE_BACKGROUND_INDEX and LFACE_FOREGROUND_INDEX
-   of ATTRS.  If the background color specified is not supported on F,
-   try to emulate gray colors with a stipple from Vface_default_stipple.  */
-
-static void
-load_face_colors (f, face, attrs)
-     struct frame *f;
-     struct face *face;
-     Lisp_Object *attrs;
-{
-  Lisp_Object fg, bg;
-
-  bg = attrs[LFACE_BACKGROUND_INDEX];
-  fg = attrs[LFACE_FOREGROUND_INDEX];
-
-  /* Swap colors if face is inverse-video.  */
-  if (EQ (attrs[LFACE_INVERSE_INDEX], Qt))
-    {
-      Lisp_Object tmp;
-      tmp = fg;
-      fg = bg;
-      bg = tmp;
-    }
-
-  /* Check for support for foreground, not for background because
-     face_color_supported_p is smart enough to know that grays are
-     "supported" as background because we are supposed to use stipple
-     for them.  */
-  if (!face_color_supported_p (f, XSTRING (bg)->data, 0)
-      && !NILP (Fbitmap_spec_p (Vface_default_stipple)))
-    {
-      x_destroy_bitmap (f, face->stipple);
-      face->stipple = load_pixmap (f, Vface_default_stipple,
-				   &face->pixmap_w, &face->pixmap_h);
-    }
-
-  face->background = load_color (f, face, bg, LFACE_BACKGROUND_INDEX);
-  face->foreground = load_color (f, face, fg, LFACE_FOREGROUND_INDEX);
-}
-
-
-/* Free color PIXEL on frame F.  */
-
-void
-unload_color (f, pixel)
-     struct frame *f;
-     unsigned long pixel;
-{
-  /* Nothing to do on W32 */
-}
-
-
-/* Free colors allocated for FACE.  */
-
-static void
-free_face_colors (f, face)
-     struct frame *f;
-     struct face *face;
-{
-  /* Nothing to do on W32 */
-}
-#endif /* HAVE_WINDOW_SYSTEM */
-
-
-
-/***********************************************************************
-			   XLFD Font Names
- ***********************************************************************/
-
-/* An enumerator for each field of an XLFD font name.  */
-
-enum xlfd_field
-{
-  XLFD_FOUNDRY,
-  XLFD_FAMILY,
-  XLFD_WEIGHT,
-  XLFD_SLANT,
-  XLFD_SWIDTH,
-  XLFD_ADSTYLE,
-  XLFD_PIXEL_SIZE,
-  XLFD_POINT_SIZE,
-  XLFD_RESX,
-  XLFD_RESY,
-  XLFD_SPACING,
-  XLFD_AVGWIDTH,
-  XLFD_REGISTRY,
-  XLFD_ENCODING,
-  XLFD_LAST
-};
-
-/* An enumerator for each possible slant value of a font.  Taken from 
-   the XLFD specification.  */
-
-enum xlfd_slant
-{
-  XLFD_SLANT_UNKNOWN,
-  XLFD_SLANT_ROMAN,
-  XLFD_SLANT_ITALIC,
-  XLFD_SLANT_OBLIQUE,
-  XLFD_SLANT_REVERSE_ITALIC,
-  XLFD_SLANT_REVERSE_OBLIQUE,
-  XLFD_SLANT_OTHER
-};
-
-/* Relative font weight according to XLFD documentation.  */
-
-enum xlfd_weight
-{
-  XLFD_WEIGHT_UNKNOWN,
-  XLFD_WEIGHT_ULTRA_LIGHT,	/* 10 */
-  XLFD_WEIGHT_EXTRA_LIGHT,	/* 20 */
-  XLFD_WEIGHT_LIGHT,		/* 30 */
-  XLFD_WEIGHT_SEMI_LIGHT,	/* 40: SemiLight, Book, ...  */
-  XLFD_WEIGHT_MEDIUM,		/* 50: Medium, Normal, Regular, ...  */
-  XLFD_WEIGHT_SEMI_BOLD,	/* 60: SemiBold, DemiBold, ...  */
-  XLFD_WEIGHT_BOLD,		/* 70: Bold, ... */
-  XLFD_WEIGHT_EXTRA_BOLD,	/* 80: ExtraBold, Heavy, ...  */
-  XLFD_WEIGHT_ULTRA_BOLD	/* 90: UltraBold, Black, ...  */
-};
-
-/* Relative proportionate width.  */
-
-enum xlfd_swidth
-{
-  XLFD_SWIDTH_UNKNOWN,
-  XLFD_SWIDTH_ULTRA_CONDENSED,	/* 10 */
-  XLFD_SWIDTH_EXTRA_CONDENSED,	/* 20 */
-  XLFD_SWIDTH_CONDENSED,	/* 30: Condensed, Narrow, Compressed, ... */
-  XLFD_SWIDTH_SEMI_CONDENSED,	/* 40: semicondensed */
-  XLFD_SWIDTH_MEDIUM,		/* 50: Medium, Normal, Regular, ... */
-  XLFD_SWIDTH_SEMI_EXPANDED,	/* 60: SemiExpanded, DemiExpanded, ... */
-  XLFD_SWIDTH_EXPANDED,		/* 70: Expanded... */
-  XLFD_SWIDTH_EXTRA_EXPANDED,	/* 80: ExtraExpanded, Wide...  */
-  XLFD_SWIDTH_ULTRA_EXPANDED	/* 90: UltraExpanded... */
-};
-
-/* Structure used for tables mapping XLFD weight, slant, and width
-   names to numeric and symbolic values.  */
-
-struct table_entry
-{
-  char *name;
-  int numeric;
-  Lisp_Object *symbol;
-};
-
-/* Table of XLFD slant names and their numeric and symbolic
-   representations.  This table must be sorted by slant names in
-   ascending order.  */
-
-static struct table_entry slant_table[] =
-{
-  {"i",			XLFD_SLANT_ITALIC,		&Qitalic},
-  {"o",			XLFD_SLANT_OBLIQUE,		&Qoblique},
-  {"ot",		XLFD_SLANT_OTHER,		&Qitalic},
-  {"r",			XLFD_SLANT_ROMAN,		&Qnormal},
-  {"ri",		XLFD_SLANT_REVERSE_ITALIC,	&Qreverse_italic},
-  {"ro",		XLFD_SLANT_REVERSE_OBLIQUE,	&Qreverse_oblique}
-};
-
-/* Table of XLFD weight names.  This table must be sorted by weight
-   names in ascending order.  */
-
-static struct table_entry weight_table[] =
-{
-  {"black",		XLFD_WEIGHT_ULTRA_BOLD,		&Qultra_bold},
-  {"bold",		XLFD_WEIGHT_BOLD,		&Qbold},
-  {"book",		XLFD_WEIGHT_SEMI_LIGHT,		&Qsemi_light},
-  {"demibold",		XLFD_WEIGHT_SEMI_BOLD,		&Qsemi_bold},
-  {"extralight",	XLFD_WEIGHT_EXTRA_LIGHT,	&Qextra_light},
-  {"extrabold",		XLFD_WEIGHT_EXTRA_BOLD,		&Qextra_bold},
-  {"heavy",		XLFD_WEIGHT_EXTRA_BOLD,		&Qextra_bold},
-  {"light",		XLFD_WEIGHT_LIGHT,		&Qlight},
-  {"medium",		XLFD_WEIGHT_MEDIUM,		&Qnormal},
-  {"normal",		XLFD_WEIGHT_MEDIUM,		&Qnormal},
-  {"regular",		XLFD_WEIGHT_MEDIUM,		&Qnormal},
-  {"semibold",		XLFD_WEIGHT_SEMI_BOLD,		&Qsemi_bold},
-  {"semilight",		XLFD_WEIGHT_SEMI_LIGHT,		&Qsemi_light},
-  {"ultralight",	XLFD_WEIGHT_ULTRA_LIGHT,	&Qultra_light},
-  {"ultrabold",		XLFD_WEIGHT_ULTRA_BOLD,		&Qultra_bold}
-};
-
-/* Table of XLFD width names.  This table must be sorted by width
-   names in ascending order.  */
-
-static struct table_entry swidth_table[] =
-{
-  {"compressed",	XLFD_SWIDTH_CONDENSED,		&Qcondensed},
-  {"condensed",		XLFD_SWIDTH_CONDENSED,		&Qcondensed},
-  {"demiexpanded",	XLFD_SWIDTH_SEMI_EXPANDED,	&Qsemi_expanded},
-  {"expanded",		XLFD_SWIDTH_EXPANDED,		&Qexpanded},
-  {"extracondensed",	XLFD_SWIDTH_EXTRA_CONDENSED,	&Qextra_condensed},
-  {"extraexpanded",	XLFD_SWIDTH_EXTRA_EXPANDED,	&Qextra_expanded},
-  {"medium",		XLFD_SWIDTH_MEDIUM,		&Qnormal},
-  {"narrow",		XLFD_SWIDTH_CONDENSED,		&Qcondensed},
-  {"normal",		XLFD_SWIDTH_MEDIUM,		&Qnormal},
-  {"regular",		XLFD_SWIDTH_MEDIUM,		&Qnormal},
-  {"semicondensed",	XLFD_SWIDTH_SEMI_CONDENSED,	&Qsemi_condensed},
-  {"semiexpanded",	XLFD_SWIDTH_SEMI_EXPANDED,	&Qsemi_expanded},
-  {"ultracondensed",	XLFD_SWIDTH_ULTRA_CONDENSED,	&Qultra_condensed},
-  {"ultraexpanded",	XLFD_SWIDTH_ULTRA_EXPANDED,	&Qultra_expanded},
-  {"wide",		XLFD_SWIDTH_EXTRA_EXPANDED,	&Qextra_expanded}
-};
-
-/* Structure used to hold the result of splitting font names in XLFD
-   format into their fields.  */
-
-struct font_name
-{
-  /* The original name which is modified destructively by
-     split_font_name.  The pointer is kept here to be able to free it
-     if it was allocated from the heap.  */
-  char *name;
-
-  /* Font name fields.  Each vector element points into `name' above.
-     Fields are NUL-terminated.  */
-  char *fields[XLFD_LAST];
-
-  /* Numeric values for those fields that interest us.  See
-     split_font_name for which these are.  */
-  int numeric[XLFD_LAST];
-};
-
-/* The frame in effect when sorting font names.  Set temporarily in
-   sort_fonts so that it is available in font comparison functions.  */
-
-static struct frame *font_frame;
-
-/* Order by which font selection chooses fonts.  The default values
-   mean `first, find a best match for the font width, then for the
-   font height, then for weight, then for slant.'  This variable can be
-   set via set-face-font-sort-order.  */
-
-static int font_sort_order[4];
-
-
-/* Look up FONT.fields[FIELD_INDEX] in TABLE which has DIM entries.
-   TABLE must be sorted by TABLE[i]->name in ascending order.  Value
-   is a pointer to the matching table entry or null if no table entry
-   matches.  */
-
-static struct table_entry *
-xlfd_lookup_field_contents (table, dim, font, field_index)
-     struct table_entry *table;
-     int dim;
-     struct font_name *font;
-     int field_index;
-{
-  /* Function split_font_name converts fields to lower-case, so there
-     is no need to use xstrlwr or xstricmp here.  */
-  char *s = font->fields[field_index];
-  int low, mid, high, cmp;
-
-  low = 0;
-  high = dim - 1;
-
-  while (low <= high)
-    {
-      mid = (low + high) / 2;
-      cmp = strcmp (table[mid].name, s);
-      
-      if (cmp < 0)
-	low = mid + 1;
-      else if (cmp > 0)
-	high = mid - 1;
-      else
-	return table + mid;
-    }
-
-  return NULL;
-}
-
-
-/* Return a numeric representation for font name field
-   FONT.fields[FIELD_INDEX].  The field is looked up in TABLE which
-   has DIM entries.  Value is the numeric value found or DFLT if no
-   table entry matches.  This function is used to translate weight,
-   slant, and swidth names of XLFD font names to numeric values.  */
-
-static INLINE int
-xlfd_numeric_value (table, dim, font, field_index, dflt)
-     struct table_entry *table;
-     int dim;
-     struct font_name *font;
-     int field_index;
-     int dflt;
-{
-  struct table_entry *p;
-  p = xlfd_lookup_field_contents (table, dim, font, field_index);
-  return p ? p->numeric : dflt;
-}
-
-
-/* Return a symbolic representation for font name field
-   FONT.fields[FIELD_INDEX].  The field is looked up in TABLE which
-   has DIM entries.  Value is the symbolic value found or DFLT if no
-   table entry matches.  This function is used to translate weight,
-   slant, and swidth names of XLFD font names to symbols.  */
-
-static INLINE Lisp_Object
-xlfd_symbolic_value (table, dim, font, field_index, dflt)
-     struct table_entry *table;
-     int dim;
-     struct font_name *font;
-     int field_index;
-     int dflt;
-{
-  struct table_entry *p;
-  p = xlfd_lookup_field_contents (table, dim, font, field_index);
-  return p ? *p->symbol : dflt;
-}
-
-
-/* Return a numeric value for the slant of the font given by FONT.  */
-
-static INLINE int
-xlfd_numeric_slant (font)
-     struct font_name *font;
-{
-  return xlfd_numeric_value (slant_table, DIM (slant_table),
-			     font, XLFD_SLANT, XLFD_SLANT_ROMAN);
-}
-
-
-/* Return a symbol representing the weight of the font given by FONT.  */
-
-static INLINE Lisp_Object
-xlfd_symbolic_slant (font)
-     struct font_name *font;
-{
-  return xlfd_symbolic_value (slant_table, DIM (slant_table),
-			      font, XLFD_SLANT, Qnormal);
-}
-
-
-/* Return a numeric value for the weight of the font given by FONT.  */
-
-static INLINE int
-xlfd_numeric_weight (font)
-     struct font_name *font;
-{
-  return xlfd_numeric_value (weight_table, DIM (weight_table),
-			     font, XLFD_WEIGHT, XLFD_WEIGHT_MEDIUM);
-}
-
-
-/* Return a symbol representing the slant of the font given by FONT.  */
-
-static INLINE Lisp_Object
-xlfd_symbolic_weight (font)
-     struct font_name *font;
-{
-  return xlfd_symbolic_value (weight_table, DIM (weight_table),
-			      font, XLFD_WEIGHT, Qnormal);
-}
-
-
-/* Return a numeric value for the swidth of the font whose XLFD font
-   name fields are found in FONT.  */
-
-static INLINE int
-xlfd_numeric_swidth (font)
-     struct font_name *font;
-{
-  return xlfd_numeric_value (swidth_table, DIM (swidth_table),
-			     font, XLFD_SWIDTH, XLFD_SWIDTH_MEDIUM);
-}
-
-
-/* Return a symbolic value for the swidth of FONT.  */
-
-static INLINE Lisp_Object
-xlfd_symbolic_swidth (font)
-     struct font_name *font;
-{
-  return xlfd_symbolic_value (swidth_table, DIM (swidth_table),
-			      font, XLFD_SWIDTH, Qnormal);
-}
-     
-
-/* Look up the entry of SYMBOL in the vector TABLE which has DIM
-   entries.  Value is a pointer to the matching table entry or null if
-   no element of TABLE contains SYMBOL.  */
-
-static struct table_entry *
-face_value (table, dim, symbol)
-     struct table_entry *table;
-     int dim;
-     Lisp_Object symbol;
-{
-  int i;
-
-  xassert (SYMBOLP (symbol));
-  
-  for (i = 0; i < dim; ++i)
-    if (EQ (*table[i].symbol, symbol))
-      break;
-
-  return i < dim ? table + i : NULL;
-}
-
-
-/* Return a numeric value for SYMBOL in the vector TABLE which has DIM
-   entries.  Value is -1 if SYMBOL is not found in TABLE.  */
-
-static INLINE int
-face_numeric_value (table, dim, symbol)
-     struct table_entry *table;
-     int dim;
-     Lisp_Object symbol;
-{
-  struct table_entry *p = face_value (table, dim, symbol);
-  return p ? p->numeric : -1;
-}
-
-
-/* Return a numeric value representing the weight specified by Lisp
-   symbol WEIGHT.  Value is one of the enumerators of enum
-   xlfd_weight.  */
-
-static INLINE int
-face_numeric_weight (weight)
-     Lisp_Object weight;
-{
-  return face_numeric_value (weight_table, DIM (weight_table), weight);
-}
-
-
-/* Return a numeric value representing the slant specified by Lisp
-   symbol SLANT.  Value is one of the enumerators of enum xlfd_slant.  */
-
-static INLINE int
-face_numeric_slant (slant)
-     Lisp_Object slant;
-{
-  return face_numeric_value (slant_table, DIM (slant_table), slant);
-}
-
-
-/* Return a numeric value representing the swidth specified by Lisp
-   symbol WIDTH.  Value is one of the enumerators of enum xlfd_swidth.  */
-
-static int
-face_numeric_swidth (width)
-     Lisp_Object width;
-{
-  return face_numeric_value (swidth_table, DIM (swidth_table), width);
-}
-
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-/* Return non-zero if FONT is the name of a fixed-pitch font.  */
-
-static INLINE int
-xlfd_fixed_p (font)
-     struct font_name *font;
-{
-  /* Function split_font_name converts fields to lower-case, so there
-     is no need to use tolower here.  */
-  return *font->fields[XLFD_SPACING] != 'p';
-}
-
-
-/* Return the point size of FONT on frame F, measured in 1/10 pt.
-
-   The actual height of the font when displayed on F depends on the
-   resolution of both the font and frame.  For example, a 10pt font
-   designed for a 100dpi display will display larger than 10pt on a
-   75dpi display.  (It's not unusual to use fonts not designed for the
-   display one is using.  For example, some intlfonts are available in
-   72dpi versions, only.)
-
-   Value is the real point size of FONT on frame F, or 0 if it cannot
-   be determined.  */
-
-static INLINE int
-xlfd_point_size (f, font)
-     struct frame *f;
-     struct font_name *font;
-{
-  double resy = FRAME_W32_DISPLAY_INFO (f)->resy;
-  double font_resy = atoi (font->fields[XLFD_RESY]);
-  double font_pt = atoi (font->fields[XLFD_POINT_SIZE]);
-  int real_pt;
-
-  if (font_resy == 0 || font_pt == 0)
-    real_pt = 0;
-  else
-    real_pt = (font_resy / resy) * font_pt + 0.5;
-
-  return real_pt;
-}
-
-
-/* Split XLFD font name FONT->name destructively into NUL-terminated,
-   lower-case fields in FONT->fields.  NUMERIC_P non-zero means
-   compute numeric values for fields XLFD_POINT_SIZE, XLFD_SWIDTH,
-   XLFD_RESY, XLFD_SLANT, and XLFD_WEIGHT in FONT->numeric.  Value is
-   zero if the font name doesn't have the format we expect.  The
-   expected format is a font name that starts with a `-' and has
-   XLFD_LAST fields separated by `-'.  (The XLFD specification allows
-   forms of font names where certain field contents are enclosed in
-   square brackets.  We don't support that, for now.  */
-
-static int
-split_font_name (f, font, numeric_p)
-     struct frame *f;
-     struct font_name *font;
-     int numeric_p;
-{
-  int i = 0;
-  int success_p;
-
-  if (*font->name == '-')
-    {
-      char *p = xstrlwr (font->name) + 1;
-
-      while (i < XLFD_LAST)
-	{
-	  font->fields[i] = p;
-	  ++i;
-	  
-	  while (*p && *p != '-')
-	    ++p;
-	  
-	  if (*p != '-')
-	    break;
-	  
-	  *p++ = 0;
-	}
-    }
-
-  success_p = i == XLFD_LAST;
-
-  /* If requested, and font name was in the expected format,
-     compute numeric values for some fields.  */
-  if (numeric_p && success_p)
-    {
-      font->numeric[XLFD_POINT_SIZE] = xlfd_point_size (f, font);
-      font->numeric[XLFD_RESY] = atoi (font->fields[XLFD_RESY]);
-      font->numeric[XLFD_SLANT] = xlfd_numeric_slant (font);
-      font->numeric[XLFD_WEIGHT] = xlfd_numeric_weight (font);
-      font->numeric[XLFD_SWIDTH] = xlfd_numeric_swidth (font);
-    }
-
-  return success_p;
-}
-
-
-/* Build an XLFD font name from font name fields in FONT.  Value is a
-   pointer to the font name, which is allocated via xmalloc.  */
-   
-static char *
-build_font_name (font)
-     struct font_name *font;
-{
-  int i;
-  int size = 100;
-  char *font_name = (char *) xmalloc (size);
-  int total_length = 0;
-
-  for (i = 0; i < XLFD_LAST; ++i)
-    {
-      /* Add 1 because of the leading `-'.  */
-      int len = strlen (font->fields[i]) + 1;
-
-      /* Reallocate font_name if necessary.  Add 1 for the final
-         NUL-byte.  */
-      if (total_length + len + 1 >= size)
-	{
-	  int new_size = max (2 * size, size + len + 1);
-	  int sz = new_size * sizeof *font_name;
-	  font_name = (char *) xrealloc (font_name, sz);
-	  size = new_size;
-	}
-
-      font_name[total_length] = '-';
-      bcopy (font->fields[i], font_name + total_length + 1, len - 1);
-      total_length += len;
-    }
-
-  font_name[total_length] = 0;
-  return font_name;
-}
-
-
-/* Free an array FONTS of N font_name structures.  This frees FONTS
-   itself and all `name' fields in its elements.  */
-
-static INLINE void
-free_font_names (fonts, n)
-     struct font_name *fonts;
-     int n;
-{
-  while (n)
-    xfree (fonts[--n].name);
-  xfree (fonts);
-}
-
-
-/* Sort vector FONTS of font_name structures which contains NFONTS
-   elements using qsort and comparison function CMPFN.  F is the frame
-   on which the fonts will be used.  The global variable font_frame
-   is temporarily set to F to make it available in CMPFN.  */
-
-static INLINE void
-sort_fonts (f, fonts, nfonts, cmpfn)
-     struct frame *f;
-     struct font_name *fonts;
-     int nfonts;
-     int (*cmpfn) P_ ((const void *, const void *));
-{
-  font_frame = f;
-  qsort (fonts, nfonts, sizeof *fonts, cmpfn);
-  font_frame = NULL;
-}
-
-
-/* Get fonts matching PATTERN on frame F.  If F is null, use the first
-   display in x_display_list.  FONTS is a pointer to a vector of
-   NFONTS font_name structures.  TRY_ALTERNATIVES_P non-zero means try
-   alternative patterns from Valternate_fontname_alist if no fonts are
-   found matching PATTERN.  SCALABLE_FONTS_P non-zero means include
-   scalable fonts.
-
-   For all fonts found, set FONTS[i].name to the name of the font,
-   allocated via xmalloc, and split font names into fields.  Ignore
-   fonts that we can't parse.  Value is the number of fonts found.
-   
-   This is similar to x_list_fonts.  The differences are:
-
-   1. It avoids consing.
-   2. It never calls XLoadQueryFont.  */
-
-static int
-x_face_list_fonts (f, pattern, fonts, nfonts, try_alternatives_p,
-		   scalable_fonts_p)
-     struct frame *f;
-     char *pattern;
-     struct font_name *fonts;
-     int nfonts, try_alternatives_p;
-     int scalable_fonts_p;
-{
-  /* NTEMACS_TODO : currently this uses w32_list_fonts, but it may be
-     better to do it the other way around. */
-  int n = 0, i, j;
-  char **names = NULL;
-  Lisp_Object lfonts;
-  Lisp_Object lpattern, tem;
-
-  lpattern = build_string (pattern);
-
-  /* Get the list of fonts matching PATTERN.  */
-  BLOCK_INPUT;
-  lfonts = w32_list_fonts (f, lpattern, 0, nfonts);
-  UNBLOCK_INPUT;
-
-  /* Count fonts returned */
-  for (tem = lfonts; CONSP (tem); tem = XCDR (tem))
-    n++;
-
-  /* Allocate array.  */
-  if (n)
-    names = (char **) xmalloc (n * sizeof (char *));
-
-  /* Extract font names into char * array.  */
-  tem = lfonts;
-  for (i = 0; i < n; i++)
-    {
-      names[i] = XSTRING (XCAR (tem))->data;
-      tem = XCDR (tem);
-    }
-
-  if (names)
-    {
-      /* Make a copy of the font names we got from X, and
-	 split them into fields.  */
-      for (i = j = 0; i < n; ++i)
- 	{
-	  /* Make a copy of the font name.  */
-	  fonts[j].name = xstrdup (names[i]);
-
-	  /* Ignore fonts having a name that we can't parse.  */
-	  if (!split_font_name (f, fonts + j, 1))
-	    xfree (fonts[j].name);
-	  else if (font_scalable_p (fonts + j))
-	    {
-#if SCALABLE_FONTS
-	      if (!scalable_fonts_p
-		  || !may_use_scalable_font_p (fonts + j, names[i]))
-		xfree (fonts[j].name);
-	      else
-		++j;
-#else /* !SCALABLE_FONTS */
-	      /* Always ignore scalable fonts.  */
-	      xfree (fonts[j].name);
-#endif /* !SCALABLE_FONTS */
-	    }
-	  else
-	    ++j;
-	}
-
-      n = j;
-
-      /* Free font names.  */
-#if 0 /* NTEMACS_TODO : W32 equivalent? */
-      BLOCK_INPUT;
-      XFreeFontNames (names);
-      UNBLOCK_INPUT;
-#endif /* NTEMACS_TODO */
-    }
-
-
-  /* If no fonts found, try patterns from Valternate_fontname_alist.  */
-  if (n == 0 && try_alternatives_p)
-    {
-      Lisp_Object list = Valternate_fontname_alist;
-
-      while (CONSP (list))
-	{
-	  Lisp_Object entry = XCAR (list);
-	  if (CONSP (entry)
-	      && STRINGP (XCAR (entry))
-	      && strcmp (XSTRING (XCAR (entry))->data, pattern) == 0)
-	    break;
-	  list = XCDR (list);
-	}
-
-      if (CONSP (list))
-	{
-	  Lisp_Object patterns = XCAR (list);
-	  Lisp_Object name;
-      
-	  while (CONSP (patterns)
-		 /* If list is screwed up, give up.  */
-		 && (name = XCAR (patterns),
-		     STRINGP (name))
-		 /* Ignore patterns equal to PATTERN because we tried that
-		    already with no success.  */
-		 && (strcmp (XSTRING (name)->data, pattern) == 0
-		     || (n = x_face_list_fonts (f, XSTRING (name)->data,
-						fonts, nfonts, 0,
-						scalable_fonts_p),
-			 n == 0)))
-	    patterns = XCDR (patterns);
-	}
-    }
-  
-  return n;
-}
-  
-
-/* Determine the first font matching PATTERN on frame F.  Return in
-   *FONT the matching font name, split into fields.  Value is non-zero
-   if a match was found.  */
-
-static int
-first_font_matching (f, pattern, font)
-     struct frame *f;
-     char *pattern;
-     struct font_name *font;
-{
-  int nfonts = 100;
-  struct font_name *fonts;
-
-  fonts = (struct font_name *) xmalloc (nfonts * sizeof *fonts);
-  nfonts = x_face_list_fonts (f, pattern, fonts, nfonts, 1, 0);
-
-  if (nfonts > 0)
-    {
-      bcopy (&fonts[0], font, sizeof *font);
-      
-      fonts[0].name = NULL;
-      free_font_names (fonts, nfonts);
-    }
-
-  return nfonts > 0;
-}
-
-
-/* Determine fonts matching PATTERN on frame F.  Sort resulting fonts
-   using comparison function CMPFN.  Value is the number of fonts
-   found.  If value is non-zero, *FONTS is set to a vector of
-   font_name structures allocated from the heap containing matching
-   fonts.  Each element of *FONTS contains a name member that is also
-   allocated from the heap.  Font names in these structures are split
-   into fields.  Use free_font_names to free such an array.  */
-
-static int
-sorted_font_list (f, pattern, cmpfn, fonts)
-     struct frame *f;
-     char *pattern;
-     int (*cmpfn) P_ ((const void *, const void *));
-     struct font_name **fonts;
-{
-  int nfonts;
-  
-  /* Get the list of fonts matching pattern.  100 should suffice.  */
-  nfonts = DEFAULT_FONT_LIST_LIMIT;
-  if (INTEGERP (Vfont_list_limit) && XINT (Vfont_list_limit) > 0)
-    nfonts = XFASTINT (Vfont_list_limit);
-
-  *fonts = (struct font_name *) xmalloc (nfonts * sizeof **fonts);
-#if SCALABLE_FONTS
-  nfonts = x_face_list_fonts (f, pattern, *fonts, nfonts, 1, 1);
-#else
-  nfonts = x_face_list_fonts (f, pattern, *fonts, nfonts, 1, 0);
-#endif
-  
-  /* Sort the resulting array and return it in *FONTS.  If no 
-     fonts were found, make sure to set *FONTS to null.  */
-  if (nfonts)
-    sort_fonts (f, *fonts, nfonts, cmpfn);
-  else
-    {
-      xfree (*fonts);
-      *fonts = NULL;
-    }
-
-  return nfonts;
-}
-
-
-/* Compare two font_name structures *A and *B.  Value is analogous to
-   strcmp.  Sort order is given by the global variable
-   font_sort_order.  Font names are sorted so that, everything else
-   being equal, fonts with a resolution closer to that of the frame on
-   which they are used are listed first.  The global variable
-   font_frame is the frame on which we operate.  */
-
-static int
-cmp_font_names (a, b)
-     const void *a, *b;
-{
-  struct font_name *x = (struct font_name *) a;
-  struct font_name *y = (struct font_name *) b;
-  int cmp;
-
-  /* All strings have been converted to lower-case by split_font_name,
-     so we can use strcmp here.  */
-  cmp = strcmp (x->fields[XLFD_FAMILY], y->fields[XLFD_FAMILY]);
-  if (cmp == 0)
-    {
-      int i;
-      
-      for (i = 0; i < DIM (font_sort_order) && cmp == 0; ++i)
-	{
-	  int j = font_sort_order[i];
-	  cmp = x->numeric[j] - y->numeric[j];
-	}
-
-      if (cmp == 0)
-	{
-	  /* Everything else being equal, we prefer fonts with an
-	     y-resolution closer to that of the frame.  */
-	  int resy = FRAME_W32_DISPLAY_INFO (font_frame)->resy;
-	  int x_resy = x->numeric[XLFD_RESY];
-	  int y_resy = y->numeric[XLFD_RESY];
-	  cmp = abs (resy - x_resy) - abs (resy - y_resy);
-	}
-    }
-
-  return cmp;
-}
-
-
-/* Get a sorted list of fonts of family FAMILY on frame F.  If PATTERN
-   is non-null list fonts matching that pattern.  Otherwise, if
-   REGISTRY_AND_ENCODING is non-null return only fonts with that
-   registry and encoding, otherwise return fonts of any registry and
-   encoding.  Set *FONTS to a vector of font_name structures allocated
-   from the heap containing the fonts found.  Value is the number of
-   fonts found.  */
-
-static int
-font_list (f, pattern, family, registry_and_encoding, fonts)
-     struct frame *f;
-     char *pattern;
-     char *family;
-     char *registry_and_encoding;
-     struct font_name **fonts;
-{
-  if (pattern == NULL)
-    {
-      if (family == NULL)
-	family = "*";
-      
-      if (registry_and_encoding == NULL)
-	registry_and_encoding = "*";
-      
-      pattern = (char *) alloca (strlen (family)
-				 + strlen (registry_and_encoding)
-				 + 10);
-      if (index (family, '-'))
-	sprintf (pattern, "-%s-*-%s", family, registry_and_encoding);
-      else
-	sprintf (pattern, "-*-%s-*-%s", family, registry_and_encoding);
-    }
-  
-  return sorted_font_list (f, pattern, cmp_font_names, fonts);
-}
-
-
-/* Remove elements from LIST whose cars are `equal'.  Called from
-   x-family-fonts and x-font-family-list to remove duplicate font
-   entries.  */
-
-static void
-remove_duplicates (list)
-     Lisp_Object list;
-{
-  Lisp_Object tail = list;
-  
-  while (!NILP (tail) && !NILP (XCDR (tail)))
-    {
-      Lisp_Object next = XCDR (tail);
-      if (!NILP (Fequal (XCAR (next), XCAR (tail))))
-	XCDR (tail) = XCDR (next);
-      else
-	tail = XCDR (tail);
-    }
-}
-
-
-DEFUN ("x-family-fonts", Fx_family_fonts, Sx_family_fonts, 0, 2, 0,
-  "Return a list of available fonts of family FAMILY on FRAME.\n\
-If FAMILY is omitted or nil, list all families.\n\
-Otherwise, FAMILY must be a string, possibly containing wildcards\n\
-`?' and `*'.\n\
-If FRAME is omitted or nil, use the selected frame.\n\
-Each element of the result is a vector [FAMILY WIDTH POINT-SIZE WEIGHT\n\
-SLANT FIXED-P FULL REGISTRY-AND-ENCODING].\n\
-FAMILY is the font family name.  POINT-SIZE is the size of the\n\
-font in 1/10 pt.  WIDTH, WEIGHT, and SLANT are symbols describing the\n\
-width, weight and slant of the font.  These symbols are the same as for\n\
-face attributes.  FIXED-P is non-nil if the font is fixed-pitch.\n\
-FULL is the full name of the font, and REGISTRY-AND-ENCODING is a string\n\
-giving the registry and encoding of the font.\n\
-The result list is sorted according to the current setting of\n\
-the face font sort order.")
-  (family, frame)
-     Lisp_Object family, frame;
-{
-  struct frame *f = check_x_frame (frame);
-  struct font_name *fonts;
-  int i, nfonts;
-  Lisp_Object result;
-  struct gcpro gcpro1;
-  char *family_pattern;
-
-  if (NILP (family))
-    family_pattern = "*";
-  else
-    {
-      CHECK_STRING (family, 1);
-      family_pattern = LSTRDUPA (family);
-    }
-  
-  result = Qnil;
-  GCPRO1 (result);
-  nfonts = font_list (f, NULL, family_pattern, NULL, &fonts);
-  for (i = nfonts - 1; i >= 0; --i)
-    {
-      Lisp_Object v = Fmake_vector (make_number (8), Qnil);
-      char *tem;
-
-#define ASET(VECTOR, IDX, VAL) (XVECTOR (VECTOR)->contents[IDX] = (VAL))
-      
-      ASET (v, 0, build_string (fonts[i].fields[XLFD_FAMILY]));
-      ASET (v, 1, xlfd_symbolic_swidth (fonts + i));
-      ASET (v, 2, make_number (xlfd_point_size (f, fonts + i)));
-      ASET (v, 3, xlfd_symbolic_weight (fonts + i));
-      ASET (v, 4, xlfd_symbolic_slant (fonts + i));
-      ASET (v, 5, xlfd_fixed_p (fonts + i) ? Qt : Qnil);
-      tem = build_font_name (fonts + i);
-      ASET (v, 6, build_string (tem));
-      sprintf (tem, "%s-%s", fonts[i].fields[XLFD_REGISTRY],
-	       fonts[i].fields[XLFD_ENCODING]);
-      ASET (v, 7, build_string (tem));
-      xfree (tem);
-      
-      result = Fcons (v, result);
-      
-#undef ASET
-    }
-
-  remove_duplicates (result);
-  free_font_names (fonts, nfonts);
-  UNGCPRO;
-  return result;
-}
-
-
-DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list,
-       0, 1, 0,
-  "Return a list of available font families on FRAME.\n\
-If FRAME is omitted or nil, use the selected frame.\n\
-Value is a list of conses (FAMILY . FIXED-P) where FAMILY\n\
-is a font family, and FIXED-P is non-nil if fonts of that family\n\
-are fixed-pitch.")
-  (frame)
-     Lisp_Object frame;
-{
-  struct frame *f = check_x_frame (frame);
-  int nfonts, i;
-  struct font_name *fonts;
-  Lisp_Object result;
-  struct gcpro gcpro1;
-  int count = specpdl_ptr - specpdl;
-  int limit;
-
-  /* Let's consider all fonts.  Increase the limit for matching
-     fonts until we have them all.  */
-  for (limit = 500;;)
-    {
-      specbind (intern ("font-list-limit"), make_number (limit));
-      nfonts = font_list (f, NULL, "*", NULL, &fonts);
-      
-      if (nfonts == limit)
-	{
-	  free_font_names (fonts, nfonts);
-	  limit *= 2;
-	}
-      else
-	break;
-    }
-  
-  result = Qnil;
-  GCPRO1 (result);
-  for (i = nfonts - 1; i >= 0; --i)
-    result = Fcons (Fcons (build_string (fonts[i].fields[XLFD_FAMILY]),
-			   xlfd_fixed_p (fonts + i) ? Qt : Qnil),
-		    result);
-
-  remove_duplicates (result);
-  free_font_names (fonts, nfonts);
-  UNGCPRO;
-  return unbind_to (count, result);
-}
-
-
-DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0,
-  "Return a list of the names of available fonts matching PATTERN.\n\
-If optional arguments FACE and FRAME are specified, return only fonts\n\
-the same size as FACE on FRAME.\n\
-PATTERN is a string, perhaps with wildcard characters;\n\
-  the * character matches any substring, and\n\
-  the ? character matches any single character.\n\
-  PATTERN is case-insensitive.\n\
-FACE is a face name--a symbol.\n\
-\n\
-The return value is a list of strings, suitable as arguments to\n\
-set-face-font.\n\
-\n\
-Fonts Emacs can't use may or may not be excluded\n\
-even if they match PATTERN and FACE.\n\
-The optional fourth argument MAXIMUM sets a limit on how many\n\
-fonts to match.  The first MAXIMUM fonts are reported.\n\
-The optional fifth argument WIDTH, if specified, is a number of columns\n\
-occupied by a character of a font.  In that case, return only fonts\n\
-the WIDTH times as wide as FACE on FRAME.")
-  (pattern, face, frame, maximum, width)
-    Lisp_Object pattern, face, frame, maximum, width;
-{
-  struct frame *f;
-  int size;
-  int maxnames;
-
-  check_w32 ();
-  CHECK_STRING (pattern, 0);
-  
-  if (NILP (maximum))
-    maxnames = 2000;
-  else
-    {
-      CHECK_NATNUM (maximum, 0);
-      maxnames = XINT (maximum);
-    }
-
-  if (!NILP (width))
-    CHECK_NUMBER (width, 4);
-
-  /* We can't simply call check_x_frame because this function may be
-     called before any frame is created.  */
-  f = frame_or_selected_frame (frame, 2);
-  if (!FRAME_WINDOW_P (f))
-    {
-      /* Perhaps we have not yet created any frame.  */
-      f = NULL;
-      face = Qnil;
-    }
-
-  /* Determine the width standard for comparison with the fonts we find.  */
-
-  if (NILP (face))
-    size = 0;
-  else
-    {
-      /* This is of limited utility since it works with character
-	 widths.  Keep it for compatibility.  --gerd.  */
-      int face_id = lookup_named_face (f, face, CHARSET_ASCII);
-      struct face *face = FACE_FROM_ID (f, face_id);
-
-      if (face->font)
-	size = FONT_MAX_WIDTH (face->font);
-      else
-	size = FONT_MAX_WIDTH (FRAME_FONT (f));
-
-      if (!NILP (width))
-	size *= XINT (width);
-    }
-
-  {
-    Lisp_Object args[2];
-
-    args[0] = w32_list_fonts (f, pattern, size, maxnames);
-    if (f == NULL)
-      /* We don't have to check fontsets.  */
-      return args[0];
-    args[1] = list_fontsets (f, pattern, size);
-    return Fnconc (2, args);
-  }
-}
-
-#endif /* HAVE_WINDOW_SYSTEM */
-
-
-
-/***********************************************************************
-			      Lisp Faces
- ***********************************************************************/
-
-/* Access face attributes of face FACE, a Lisp vector.  */
-
-#define LFACE_FAMILY(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_FAMILY_INDEX]
-#define LFACE_HEIGHT(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_HEIGHT_INDEX]
-#define LFACE_WEIGHT(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_WEIGHT_INDEX]
-#define LFACE_SLANT(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_SLANT_INDEX]
-#define LFACE_UNDERLINE(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_UNDERLINE_INDEX]
-#define LFACE_INVERSE(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_INVERSE_INDEX]
-#define LFACE_FOREGROUND(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_FOREGROUND_INDEX]
-#define LFACE_BACKGROUND(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_BACKGROUND_INDEX]
-#define LFACE_STIPPLE(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_STIPPLE_INDEX]
-#define LFACE_SWIDTH(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_SWIDTH_INDEX]
-#define LFACE_OVERLINE(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_OVERLINE_INDEX]
-#define LFACE_STRIKE_THROUGH(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_STRIKE_THROUGH_INDEX]
-#define LFACE_BOX(LFACE) \
-     XVECTOR (LFACE)->contents[LFACE_BOX_INDEX]
-
-/* Non-zero if LFACE is a Lisp face.  A Lisp face is a vector of size
-   LFACE_VECTOR_SIZE which has the symbol `face' in slot 0.  */
-
-#define LFACEP(LFACE)					\
-     (VECTORP (LFACE)					\
-      && XVECTOR (LFACE)->size == LFACE_VECTOR_SIZE	\
-      && EQ (XVECTOR (LFACE)->contents[0], Qface))
-
-     
-#if GLYPH_DEBUG
-
-/* Check consistency of Lisp face attribute vector ATTRS.  */
-
-static void
-check_lface_attrs (attrs)
-     Lisp_Object *attrs;
-{
-  xassert (UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX])
-	   || STRINGP (attrs[LFACE_FAMILY_INDEX]));
-  xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
-	   || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
-  xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
-	   || INTEGERP (attrs[LFACE_HEIGHT_INDEX]));
-  xassert (UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
-	   || SYMBOLP (attrs[LFACE_WEIGHT_INDEX]));
-  xassert (UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
-	   || SYMBOLP (attrs[LFACE_SLANT_INDEX]));
-  xassert (UNSPECIFIEDP (attrs[LFACE_UNDERLINE_INDEX])
-	   || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX])
-	   || STRINGP (attrs[LFACE_UNDERLINE_INDEX]));
-  xassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX])
-	   || SYMBOLP (attrs[LFACE_OVERLINE_INDEX])
-	   || STRINGP (attrs[LFACE_OVERLINE_INDEX]));
-  xassert (UNSPECIFIEDP (attrs[LFACE_STRIKE_THROUGH_INDEX])
-	   || SYMBOLP (attrs[LFACE_STRIKE_THROUGH_INDEX])
-	   || STRINGP (attrs[LFACE_STRIKE_THROUGH_INDEX]));
-  xassert (UNSPECIFIEDP (attrs[LFACE_BOX_INDEX])
-	   || SYMBOLP (attrs[LFACE_BOX_INDEX])
-	   || STRINGP (attrs[LFACE_BOX_INDEX])
-	   || INTEGERP (attrs[LFACE_BOX_INDEX])
-	   || CONSP (attrs[LFACE_BOX_INDEX]));
-  xassert (UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX])
-	   || SYMBOLP (attrs[LFACE_INVERSE_INDEX]));
-  xassert (UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX])
-	   || STRINGP (attrs[LFACE_FOREGROUND_INDEX]));
-  xassert (UNSPECIFIEDP (attrs[LFACE_BACKGROUND_INDEX])
-	   || STRINGP (attrs[LFACE_BACKGROUND_INDEX]));
-#ifdef HAVE_WINDOW_SYSTEM
-  xassert (UNSPECIFIEDP (attrs[LFACE_STIPPLE_INDEX])
-	   || SYMBOLP (attrs[LFACE_STIPPLE_INDEX])
-	   || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX])));
-#endif
-}
-
-
-/* Check consistency of attributes of Lisp face LFACE (a Lisp vector).  */
-
-static void
-check_lface (lface)
-     Lisp_Object lface;
-{
-  if (!NILP (lface))
-    {
-      xassert (LFACEP (lface));
-      check_lface_attrs (XVECTOR (lface)->contents);
-    }
-}
-
-#else /* GLYPH_DEBUG == 0 */
-
-#define check_lface_attrs(attrs)	(void) 0
-#define check_lface(lface)		(void) 0
-
-#endif /* GLYPH_DEBUG == 0 */
-
-
-/* Resolve face name FACE_NAME.  If FACE_NAME Is a string, intern it
-   to make it a symvol.  If FACE_NAME is an alias for another face,
-   return that face's name.  */
-
-static Lisp_Object
-resolve_face_name (face_name)
-     Lisp_Object face_name;
-{
-  Lisp_Object aliased;
-  
-  if (STRINGP (face_name))
-    face_name = intern (XSTRING (face_name)->data);
-
-  for (;;)
-    {
-      aliased = Fget (face_name, Qface_alias);
-      if (NILP (aliased))
-	break;
-      else
-	face_name = aliased;
-    }
-
-  return face_name;
-}
-
-
-/* Return the face definition of FACE_NAME on frame F.  F null means
-   return the global definition.  FACE_NAME may be a string or a
-   symbol (apparently Emacs 20.2 allows strings as face names in face
-   text properties; ediff uses that).  If FACE_NAME is an alias for
-   another face, return that face's definition.  If SIGNAL_P is
-   non-zero, 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 (f, face_name, signal_p)
-     struct frame *f;
-     Lisp_Object face_name;
-     int signal_p;
-{
-  Lisp_Object lface;
-
-  face_name = resolve_face_name (face_name);
-
-  if (f)
-    lface = assq_no_quit (face_name, f->face_alist);
-  else
-    lface = assq_no_quit (face_name, Vface_new_frame_defaults);
-
-  if (CONSP (lface))
-    lface = XCDR (lface);
-  else if (signal_p)
-    signal_error ("Invalid face", face_name);
-
-  check_lface (lface);
-  return lface;
-}
-
-
-/* Get face attributes of face FACE_NAME from frame-local faces on
-   frame F.  Store the resulting attributes in ATTRS which must point
-   to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE.  If SIGNAL_P
-   is non-zero, signal an error if FACE_NAME does not name a face.
-   Otherwise, value is zero if FACE_NAME is not a face.  */
-
-static INLINE int
-get_lface_attributes (f, face_name, attrs, signal_p)
-     struct frame *f;
-     Lisp_Object face_name;
-     Lisp_Object *attrs;
-     int signal_p;
-{
-  Lisp_Object lface;
-  int success_p;
-
-  lface = lface_from_face_name (f, face_name, signal_p);
-  if (!NILP (lface))
-    {
-      bcopy (XVECTOR (lface)->contents, attrs,
-	     LFACE_VECTOR_SIZE * sizeof *attrs);
-      success_p = 1;
-    }
-  else
-    success_p = 0;
-
-  return success_p;
-}
-
-
-/* Non-zero if all attributes in face attribute vector ATTRS are
-   specified, i.e. are non-nil.  */
-
-static int
-lface_fully_specified_p (attrs)
-     Lisp_Object *attrs;
-{
-  int i;
-
-  for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
-    if (UNSPECIFIEDP (attrs[i]))
-      break;
-
-  return i == LFACE_VECTOR_SIZE;
-}
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-/* Set font-related attributes of Lisp face LFACE from XLFD font name
-   FONT_NAME.  If FORCE_P is zero, set only unspecified attributes of
-   LFACE.  MAY_FAIL_P non-zero means return 0 if FONT_NAME isn't a
-   valid font name; otherwise this function tries to use a reasonable
-   default font.
-
-   Ignore fields of FONT_NAME containing wildcards.  Value is zero if
-   not successful because FONT_NAME was not in a valid format and
-   MAY_FAIL_P was non-zero.  A valid format is one that is suitable
-   for split_font_name, see the comment there.  */
-   
-static int
-set_lface_from_font_name (f, lface, font_name, force_p, may_fail_p)
-     struct frame *f;
-     Lisp_Object lface;
-     char *font_name;
-     int force_p, may_fail_p;
-{
-  struct font_name font;
-  char *buffer;
-  int pt;
-  int free_font_name_p = 0;
-  int have_font_p = 0;
-
-  /* If FONT_NAME contains wildcards, use the first matching font.  */
-  if (index (font_name, '*') || index (font_name, '?'))
-    {
-      if (first_font_matching (f, font_name, &font))
-        free_font_name_p = have_font_p = 1;
-    }
-  else
-    {
-      font.name = STRDUPA (font_name);
-      if (split_font_name (f, &font, 1))
-        have_font_p = 1;
-      else
-	{
-	  /* The font name may be something like `6x13'.  Make
-	     sure we use the full name.  */
-	  struct font_info *font_info;
-
-	  BLOCK_INPUT;
-	  font_info = fs_load_font (f, FRAME_W32_FONT_TABLE (f),
-				    CHARSET_ASCII, font_name, -1);
-	  if (font_info)
-            {
-              font.name = STRDUPA (font_info->full_name);
-              split_font_name (f, &font, 1);
-              have_font_p = 1;
-            }
-	  UNBLOCK_INPUT;
-	}
-    }
-
-  /* If FONT_NAME is completely bogus try to use something reasonable
-     if this function must succeed.  Otherwise, give up.  */
-  if (!have_font_p)
-    {
-      if (may_fail_p)
-	return 0;
-      else if (first_font_matching (f, "-*-Courier New-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
-				    &font)
-	       || first_font_matching (f, "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
-				       &font)
-	       || first_font_matching (f, "-*-FixedSys-normal-r-*-*-12-*-*-*-c-*-iso8859-1",
-				       &font)
-	       || first_font_matching (f, "-*-*-normal-r-*-*-*-*-*-*-c-*-iso8859-1",
-				       &font)
-	       || first_font_matching (f, "FixedSys",
-				       &font))
-	free_font_name_p = 1;
-      else
-	abort ();
-    }
-
-
-  /* Set attributes only if unspecified, otherwise face defaults for
-     new frames would never take effect.  */
-  
-  if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
-    {
-      buffer = (char *) alloca (strlen (font.fields[XLFD_FAMILY])
-				+ strlen (font.fields[XLFD_FOUNDRY])
-				+ 2);
-      sprintf (buffer, "%s-%s", font.fields[XLFD_FOUNDRY],
-	       font.fields[XLFD_FAMILY]);
-      LFACE_FAMILY (lface) = build_string (buffer);
-    }
-
-  if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
-    {
-      pt = xlfd_point_size (f, &font);
-      xassert (pt > 0);
-      LFACE_HEIGHT (lface) = make_number (pt);
-    }
-
-  if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
-    LFACE_SWIDTH (lface) = xlfd_symbolic_swidth (&font);
-
-  if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
-    LFACE_WEIGHT (lface) = xlfd_symbolic_weight (&font);
-
-  if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
-    LFACE_SLANT (lface) = xlfd_symbolic_slant (&font);
-
-  if (free_font_name_p)
-    xfree (font.name);
-  
-  return 1;
-}
-#endif /* HAVE_WINDOW_SYSTEM */
-
-
-/* Merge two Lisp face attribute vectors FROM and TO and store the
-   resulting attributes in TO.  Every non-nil attribute of FROM
-   overrides the corresponding attribute of TO.  */
-
-static INLINE void
-merge_face_vectors (from, to)
-     Lisp_Object *from, *to;
-{
-  int i;
-  for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
-    if (!UNSPECIFIEDP (from[i]))
-      to[i] = from[i];
-}
-
-
-/* Given a Lisp face attribute vector TO and a Lisp object PROP that
-   is a face property, determine the resulting face attributes on
-   frame F, and store them in TO.  PROP may be a single face
-   specification or a list of such specifications.  Each face
-   specification can be
-
-   1. A symbol or string naming a Lisp face.
-
-   2. A property list of the form (KEYWORD VALUE ...) where each
-   KEYWORD is a face attribute name, and value is an appropriate value
-   for that attribute.
-
-   3. Conses or the form (FOREGROUND-COLOR . COLOR) or
-   (BACKGROUND-COLOR . COLOR) where COLOR is a color name.  This is
-   for compatibility with 20.2.
-
-   Face specifications earlier in lists take precedence over later
-   specifications.  */
-   
-static void
-merge_face_vector_with_property (f, to, prop)
-     struct frame *f;
-     Lisp_Object *to;
-     Lisp_Object prop;
-{
-  if (CONSP (prop))
-    {
-      Lisp_Object first = XCAR (prop);
-      
-      if (EQ (first, Qforeground_color)
-	  || EQ (first, Qbackground_color))
-	{
-	  /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR
-	     . COLOR).  COLOR must be a string.  */
-	  Lisp_Object color_name = XCDR (prop);
-	  Lisp_Object color = first;
-
-	  if (STRINGP (color_name))
-	    {
-	      if (EQ (color, Qforeground_color))
-		to[LFACE_FOREGROUND_INDEX] = color_name;
-	      else
-		to[LFACE_BACKGROUND_INDEX] = color_name;
-	    }
-	  else
-	    add_to_log ("Invalid face color", color_name, Qnil);
-	}
-      else if (SYMBOLP (first)
-	       && *XSYMBOL (first)->name->data == ':')
-	{
-	  /* Assume this is the property list form.  */
-	  while (CONSP (prop) && CONSP (XCDR (prop)))
-	    {
-	      Lisp_Object keyword = XCAR (prop);
-	      Lisp_Object value = XCAR (XCDR (prop));
-
-	      if (EQ (keyword, QCfamily))
-		{
-		  if (STRINGP (value))
-		    to[LFACE_FAMILY_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face font family", value, Qnil);
-		}
-	      else if (EQ (keyword, QCheight))
-		{
-		  if (INTEGERP (value))
-		    to[LFACE_HEIGHT_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face font height", value, Qnil);
-		}
-	      else if (EQ (keyword, QCweight))
-		{
-		  if (SYMBOLP (value)
-		      && face_numeric_weight (value) >= 0)
-		    to[LFACE_WEIGHT_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face weight", value, Qnil);
-		}
-	      else if (EQ (keyword, QCslant))
-		{
-		  if (SYMBOLP (value)
-		      && face_numeric_slant (value) >= 0)
-		    to[LFACE_SLANT_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face slant", value, Qnil);
-		}
-	      else if (EQ (keyword, QCunderline))
-		{
-		  if (EQ (value, Qt)
-		      || NILP (value)
-		      || STRINGP (value))
-		    to[LFACE_UNDERLINE_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face underline", value, Qnil);
-		}
-	      else if (EQ (keyword, QCoverline))
-		{
-		  if (EQ (value, Qt)
-		      || NILP (value)
-		      || STRINGP (value))
-		    to[LFACE_OVERLINE_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face overline", value, Qnil);
-		}
-	      else if (EQ (keyword, QCstrike_through))
-		{
-		  if (EQ (value, Qt)
-		      || NILP (value)
-		      || STRINGP (value))
-		    to[LFACE_STRIKE_THROUGH_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face strike-through", value, Qnil);
-		}
-	      else if (EQ (keyword, QCbox))
-		{
-		  if (EQ (value, Qt))
-		    value = make_number (1);
-		  if (INTEGERP (value)
-		      || STRINGP (value)
-		      || CONSP (value)
-		      || NILP (value))
-		    to[LFACE_BOX_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face box", value, Qnil);
-		}
-	      else if (EQ (keyword, QCinverse_video)
-		       || EQ (keyword, QCreverse_video))
-		{
-		  if (EQ (value, Qt) || NILP (value))
-		    to[LFACE_INVERSE_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face inverse-video", value, Qnil);
-		}
-	      else if (EQ (keyword, QCforeground))
-		{
-		  if (STRINGP (value))
-		    to[LFACE_FOREGROUND_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face foreground", value, Qnil);
-		}
-	      else if (EQ (keyword, QCbackground))
-		{
-		  if (STRINGP (value))
-		    to[LFACE_BACKGROUND_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face background", value, Qnil);
-		}
-	      else if (EQ (keyword, QCstipple))
-		{
-#ifdef HAVE_X_WINDOWS
-		  Lisp_Object pixmap_p = Fbitmap_spec_p (value);
-		  if (!NILP (pixmap_p))
-		    to[LFACE_STIPPLE_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face stipple", value, Qnil);
-#endif
-		}
-	      else if (EQ (keyword, QCwidth))
-		{
-		  if (SYMBOLP (value)
-		      && face_numeric_swidth (value) >= 0)
-		    to[LFACE_SWIDTH_INDEX] = value;
-		  else
-		    add_to_log ("Illegal face width", value, Qnil);
-		}
-	      else
-		add_to_log ("Invalid attribute %s in face property",
-                            keyword, Qnil);
-
-	      prop = XCDR (XCDR (prop));
-	    }
-	}
-      else
-	{
-	  /* This is a list of face specs.  Specifications at the
-	     beginning of the list take precedence over later
-	     specifications, so we have to merge starting with the
-	     last specification.  */
-	  Lisp_Object next = XCDR (prop);
-	  if (!NILP (next))
-	    merge_face_vector_with_property (f, to, next);
-	  merge_face_vector_with_property (f, to, first);
-	}
-    }
-  else
-    {
-      /* PROP ought to be a face name.  */
-      Lisp_Object lface = lface_from_face_name (f, prop, 0);
-      if (NILP (lface))
-	add_to_log ("Invalid face text property value: %s", prop, Qnil);
-      else
-	merge_face_vectors (XVECTOR (lface)->contents, to);
-    }
-}
-
-
-DEFUN ("internal-make-lisp-face", Finternal_make_lisp_face,
-       Sinternal_make_lisp_face, 1, 2, 0,
-  "Make FACE, a symbol, a Lisp face with all attributes nil.\n\
-If FACE was not known as a face before, create a new one.\n\
-If optional argument FRAME is specified, make a frame-local face\n\
-for that frame.  Otherwise operate on the global face definition.\n\
-Value is a vector of face attributes.")
-  (face, frame)
-     Lisp_Object face, frame;
-{
-  Lisp_Object global_lface, lface;
-  struct frame *f;
-  int i;
-
-  CHECK_SYMBOL (face, 0);
-  global_lface = lface_from_face_name (NULL, face, 0);
-  
-  if (!NILP (frame))
-    {
-      CHECK_LIVE_FRAME (frame, 1);
-      f = XFRAME (frame);
-      lface = lface_from_face_name (f, face, 0);
-    }
-  else
-    f = NULL, lface = Qnil;
-
-  /* Add a global definition if there is none.  */
-  if (NILP (global_lface))
-    {
-      global_lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
-				   Qunspecified);
-      XVECTOR (global_lface)->contents[0] = Qface;
-      Vface_new_frame_defaults = Fcons (Fcons (face, global_lface), 
-					Vface_new_frame_defaults);
-      
-      /* Assign the new Lisp face a unique ID.  The mapping from Lisp
-	 face id to Lisp face is given by the vector lface_id_to_name.
-	 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[next_lface_id] = face;
-      Fput (face, Qface, make_number (next_lface_id));
-      ++next_lface_id;
-    }
-  else if (f == NULL)
-    for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
-      XVECTOR (global_lface)->contents[i] = Qunspecified;
-    
-  /* Add a frame-local definition.  */
-  if (f)
-    {
-      if (NILP (lface))
-	{
-	  lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE),
-				Qunspecified);
-	  XVECTOR (lface)->contents[0] = Qface;
-	  f->face_alist = Fcons (Fcons (face, lface), f->face_alist);
-	}
-      else
-	for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
-	  XVECTOR (lface)->contents[i] = Qunspecified;
-    }
-  else
-    lface = global_lface;
-
-  xassert (LFACEP (lface));
-  check_lface (lface);
-  return lface;
-}
-
-
-DEFUN ("internal-lisp-face-p", Finternal_lisp_face_p,
-       Sinternal_lisp_face_p, 1, 2, 0,
-  "Return non-nil if FACE names a face.\n\
-If optional second parameter FRAME is non-nil, check for the\n\
-existence of a frame-local face with name FACE on that frame.\n\
-Otherwise check for the existence of a global face.")
-  (face, frame)
-     Lisp_Object face, frame;
-{
-  Lisp_Object lface;
-  
-  if (!NILP (frame))
-    {
-      CHECK_LIVE_FRAME (frame, 1);
-      lface = lface_from_face_name (XFRAME (frame), face, 0);
-    }
-  else
-    lface = lface_from_face_name (NULL, face, 0);
-
-  return lface;
-}
-
-
-DEFUN ("internal-copy-lisp-face", Finternal_copy_lisp_face,
-       Sinternal_copy_lisp_face, 4, 4, 0,
-  "Copy face FROM to TO.\n\
-If FRAME it t, copy the global face definition of FROM to the\n\
-global face definition of TO.  Otherwise, copy the frame-local\n\
-definition of FROM on FRAME to the frame-local definition of TO\n\
-on NEW-FRAME, or FRAME if NEW-FRAME is nil.\n\
-\n\
-Value is TO.")
-  (from, to, frame, new_frame)
-     Lisp_Object from, to, frame, new_frame;
-{
-  Lisp_Object lface, copy;
-  
-  CHECK_SYMBOL (from, 0);
-  CHECK_SYMBOL (to, 1);
-  if (NILP (new_frame))
-    new_frame = frame;
-
-  if (EQ (frame, Qt))
-    {
-      /* Copy global definition of FROM.  We don't make copies of
-	 strings etc. because 20.2 didn't do it either.  */
-      lface = lface_from_face_name (NULL, from, 1);
-      copy = Finternal_make_lisp_face (to, Qnil);
-    }
-  else
-    {
-      /* Copy frame-local definition of FROM.  */
-      CHECK_LIVE_FRAME (frame, 2);
-      CHECK_LIVE_FRAME (new_frame, 3);
-      lface = lface_from_face_name (XFRAME (frame), from, 1);
-      copy = Finternal_make_lisp_face (to, new_frame);
-    }
-  
-  bcopy (XVECTOR (lface)->contents, XVECTOR (copy)->contents,
-	 LFACE_VECTOR_SIZE * sizeof (Lisp_Object));
-  
-  return to;
-}
-
-
-DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
-       Sinternal_set_lisp_face_attribute, 3, 4, 0,
-  "Set attribute ATTR of FACE to VALUE.\n\
-If optional argument FRAME is given, set the face attribute of face FACE\n\
-on that frame.  If FRAME is t, set the attribute of the default for face\n\
-FACE (for new frames).  If FRAME is omitted or nil, use the selected\n\
-frame.")
-  (face, attr, value, frame)
-     Lisp_Object face, attr, value, frame;
-{
-  Lisp_Object lface;
-  Lisp_Object old_value = Qnil;
-  int font_related_attr_p = 0;
-  
-  CHECK_SYMBOL (face, 0);
-  CHECK_SYMBOL (attr, 1);
-
-  face = resolve_face_name (face);
-
-  /* Set lface to the Lisp attribute vector of FACE.  */
-  if (EQ (frame, Qt))
-    lface = lface_from_face_name (NULL, face, 1);
-  else
-    {
-      if (NILP (frame))
-	frame = selected_frame;
-      
-      CHECK_LIVE_FRAME (frame, 3);
-      lface = lface_from_face_name (XFRAME (frame), face, 0);
-      
-      /* If a frame-local face doesn't exist yet, create one.  */
-      if (NILP (lface))
-	lface = Finternal_make_lisp_face (face, frame);
-    }
-
-  if (EQ (attr, QCfamily))
-    {
-      if (!UNSPECIFIEDP (value))
-	{
-	  CHECK_STRING (value, 3);
-	  if (XSTRING (value)->size == 0)
-	    signal_error ("Invalid face family", value);
-	}
-      old_value = LFACE_FAMILY (lface);
-      LFACE_FAMILY (lface) = value;
-      font_related_attr_p = 1;
-    }
-  else if (EQ (attr, QCheight))
-    {
-      if (!UNSPECIFIEDP (value))
-	{
-	  CHECK_NUMBER (value, 3);
-	  if (XINT (value) <= 0)
-	    signal_error ("Invalid face height", value);
-	}
-      old_value = LFACE_HEIGHT (lface);
-      LFACE_HEIGHT (lface) = value;
-      font_related_attr_p = 1;
-    }
-  else if (EQ (attr, QCweight))
-    {
-      if (!UNSPECIFIEDP (value))
-	{
-	  CHECK_SYMBOL (value, 3);
-	  if (face_numeric_weight (value) < 0)
-	    signal_error ("Invalid face weight", value);
-	}
-      old_value = LFACE_WEIGHT (lface);
-      LFACE_WEIGHT (lface) = value;
-      font_related_attr_p = 1;
-    }
-  else if (EQ (attr, QCslant))
-    {
-      if (!UNSPECIFIEDP (value))
-	{
-	  CHECK_SYMBOL (value, 3);
-	  if (face_numeric_slant (value) < 0)
-	    signal_error ("Invalid face slant", value);
-	}
-      old_value = LFACE_SLANT (lface);
-      LFACE_SLANT (lface) = value;
-      font_related_attr_p = 1;
-    }
-  else if (EQ (attr, QCunderline))
-    {
-      if (!UNSPECIFIEDP (value))
-	if ((SYMBOLP (value)
-	     && !EQ (value, Qt)
-	     && !EQ (value, Qnil))
-	    /* Underline color.  */
-	    || (STRINGP (value)
-		&& XSTRING (value)->size == 0))
-	  signal_error ("Invalid face underline", value);
-      
-      old_value = LFACE_UNDERLINE (lface);
-      LFACE_UNDERLINE (lface) = value;
-    }
-  else if (EQ (attr, QCoverline))
-    {
-      if (!UNSPECIFIEDP (value))
-	if ((SYMBOLP (value)
-	     && !EQ (value, Qt)
-	     && !EQ (value, Qnil))
-	    /* Overline color.  */
-	    || (STRINGP (value)
-		&& XSTRING (value)->size == 0))
-	  signal_error ("Invalid face overline", value);
-      
-      old_value = LFACE_OVERLINE (lface);
-      LFACE_OVERLINE (lface) = value;
-    }
-  else if (EQ (attr, QCstrike_through))
-    {
-      if (!UNSPECIFIEDP (value))
-	if ((SYMBOLP (value)
-	     && !EQ (value, Qt)
-	     && !EQ (value, Qnil))
-	    /* Strike-through color.  */
-	    || (STRINGP (value)
-		&& XSTRING (value)->size == 0))
-	  signal_error ("Invalid face strike-through", value);
-      
-      old_value = LFACE_STRIKE_THROUGH (lface);
-      LFACE_STRIKE_THROUGH (lface) = value;
-    }
-  else if (EQ (attr, QCbox))
-    {
-      int valid_p;
-      
-      /* Allow t meaning a simple box of width 1 in foreground color
-         of the face.  */
-      if (EQ (value, Qt))
-	value = make_number (1);
-
-      if (UNSPECIFIEDP (value))
-	valid_p = 1;
-      else if (NILP (value))
-	valid_p = 1;
-      else if (INTEGERP (value))
-	valid_p = XINT (value) > 0;
-      else if (STRINGP (value))
-	valid_p = XSTRING (value)->size > 0;
-      else if (CONSP (value))
-	{
-	  Lisp_Object tem;
-	  
-	  tem = value;
-	  while (CONSP (tem))
-	    {
-	      Lisp_Object k, v;
-
-	      k = XCAR (tem);
-	      tem = XCDR (tem);
-	      if (!CONSP (tem))
-		break;
-	      v = XCAR (tem);
-	      tem = XCDR (tem);
-	      
-	      if (EQ (k, QCline_width))
-		{
-		  if (!INTEGERP (v) || XINT (v) <= 0)
-		    break;
-		}
-	      else if (EQ (k, QCcolor))
-		{
-		  if (!STRINGP (v) || XSTRING (v)->size == 0)
-		    break;
-		}
-	      else if (EQ (k, QCstyle))
-		{
-		  if (!EQ (v, Qpressed_button) && !EQ (v, Qreleased_button))
-		    break;
-		}
-	      else
-		break;
-	    }
-
-	  valid_p = NILP (tem);
-	}
-      else
-	valid_p = 0;
-
-      if (!valid_p)
-	signal_error ("Invalid face box", value);
-      
-      old_value = LFACE_BOX (lface);
-      LFACE_BOX (lface) = value;
-    }
-  else if (EQ (attr, QCinverse_video)
-	   || EQ (attr, QCreverse_video))
-    {
-      if (!UNSPECIFIEDP (value))
-	{
-	  CHECK_SYMBOL (value, 3);
-	  if (!EQ (value, Qt) && !NILP (value))
-	    signal_error ("Invalid inverse-video face attribute value", value);
-	}
-      old_value = LFACE_INVERSE (lface);
-      LFACE_INVERSE (lface) = value;
-    }
-  else if (EQ (attr, QCforeground))
-    {
-      if (!UNSPECIFIEDP (value))
-	{
-	  /* Don't check for valid color names here because it depends
-	     on the frame (display) whether the color will be valid
-	     when the face is realized.  */
-	  CHECK_STRING (value, 3);
-	  if (XSTRING (value)->size == 0)
-	    signal_error ("Empty foreground color value", value);
-	}
-      old_value = LFACE_FOREGROUND (lface);
-      LFACE_FOREGROUND (lface) = value;
-    }
-  else if (EQ (attr, QCbackground))
-    {
-      if (!UNSPECIFIEDP (value))
-	{
-	  /* Don't check for valid color names here because it depends
-	     on the frame (display) whether the color will be valid
-	     when the face is realized.  */
-	  CHECK_STRING (value, 3);
-	  if (XSTRING (value)->size == 0)
-	    signal_error ("Empty background color value", value);
-	}
-      old_value = LFACE_BACKGROUND (lface);
-      LFACE_BACKGROUND (lface) = value;
-    }
-  else if (EQ (attr, QCstipple))
-    {
-#ifdef HAVE_X_WINDOWS
-      if (!UNSPECIFIEDP (value)
-	  && !NILP (value)
-	  && NILP (Fbitmap_spec_p (value)))
-	signal_error ("Invalid stipple attribute", value);
-      old_value = LFACE_STIPPLE (lface);
-      LFACE_STIPPLE (lface) = value;
-#endif /* HAVE_X_WINDOWS */
-    }
-  else if (EQ (attr, QCwidth))
-    {
-      if (!UNSPECIFIEDP (value))
-	{
-	  CHECK_SYMBOL (value, 3);
-	  if (face_numeric_swidth (value) < 0)
-	    signal_error ("Invalid face width", value);
-	}
-      old_value = LFACE_SWIDTH (lface);
-      LFACE_SWIDTH (lface) = value;
-      font_related_attr_p = 1;
-    }
-  else if (EQ (attr, QCfont))
-    {
-#ifdef HAVE_WINDOW_SYSTEM
-      /* Set font-related attributes of the Lisp face from an
-	 XLFD font name.  */
-      struct frame *f;
-
-      CHECK_STRING (value, 3);
-      if (EQ (frame, Qt))
-	f = SELECTED_FRAME ();
-      else
-	f = check_x_frame (frame);
-      
-      if (!set_lface_from_font_name (f, lface, XSTRING (value)->data, 1, 1))
-	signal_error ("Invalid font name", value);
-      
-      font_related_attr_p = 1;
-#endif /* HAVE_WINDOW_SYSTEM */
-    }
-  else if (EQ (attr, QCbold))
-    {
-      old_value = LFACE_WEIGHT (lface);
-      LFACE_WEIGHT (lface) = NILP (value) ? Qnormal : Qbold;
-      font_related_attr_p = 1;
-    }
-  else if (EQ (attr, QCitalic))
-    {
-      old_value = LFACE_SLANT (lface);
-      LFACE_SLANT (lface) = NILP (value) ? Qnormal : Qitalic;
-      font_related_attr_p = 1;
-    }
-  else
-    signal_error ("Invalid face attribute name", attr);
-
-  /* Changing a named face means that all realized faces depending on
-     that face are invalid.  Since we cannot tell which realized faces
-     depend on the face, make sure they are all removed.  This is done
-     by incrementing face_change_count.  The next call to
-     init_iterator will then free realized faces.  */
-  if (!EQ (frame, Qt)
-      && (EQ (attr, QCfont)
-	  || NILP (Fequal (old_value, value))))
-    {
-      ++face_change_count;
-      ++windows_or_buffers_changed;
-    }
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-  if (!EQ (frame, Qt)
-      && !UNSPECIFIEDP (value)
-      && NILP (Fequal (old_value, value)))
-    {
-      Lisp_Object param;
-
-      param = Qnil;
-      
-      if (EQ (face, Qdefault))
-	{
-          /* Changed font-related attributes of the `default' face are
-             reflected in changed `font' frame parameters.  */
-	  if (font_related_attr_p
-	      && lface_fully_specified_p (XVECTOR (lface)->contents))
-            set_font_frame_param (frame, lface);
-	  else if (EQ (attr, QCforeground))
-	    param = Qforeground_color;
-	  else if (EQ (attr, QCbackground))
-	    param = Qbackground_color;
-	}
-#if 0  /* NTEMACS_TODO : Scroll bar colors on W32? */
-      else if (EQ (face, Qscroll_bar))
-	{
-	  /* Changing the colors of `scroll-bar' sets frame parameters
-	     `scroll-bar-foreground' and `scroll-bar-background'. */
-	  if (EQ (attr, QCforeground))
-	    param = Qscroll_bar_foreground;
-	  else if (EQ (attr, QCbackground))
-	    param = Qscroll_bar_background;
-	}
-#endif /* NTEMACS_TODO */
-      else if (EQ (face, Qborder))
-	{
-	  /* Changing background color of `border' sets frame parameter
-	     `border-color'.  */
-	  if (EQ (attr, QCbackground))
-	    param = Qborder_color;
-	}
-      else if (EQ (face, Qcursor))
-	{
-	  /* Changing background color of `cursor' sets frame parameter
-	     `cursor-color'.  */
-	  if (EQ (attr, QCbackground))
-	    param = Qcursor_color;
-	}
-      else if (EQ (face, Qmouse))
-	{
-	  /* Changing background color of `mouse' sets frame parameter
-	     `mouse-color'.  */
-	  if (EQ (attr, QCbackground))
-	    param = Qmouse_color;
-	}
-
-      if (SYMBOLP (param))
-	Fmodify_frame_parameters (frame, Fcons (Fcons (param, value), Qnil));
-    }
-
-#endif /* HAVE_WINDOW_SYSTEM */
-  
-  return face;
-}
-
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-/* Set the `font' frame parameter of FRAME according to `default' face
-   attributes LFACE.  */
-
-static void
-set_font_frame_param (frame, lface)
-     Lisp_Object frame, lface;
-{
-  struct frame *f = XFRAME (frame);
-  Lisp_Object frame_font;
-  int fontset;
-  char *font;
-
-  /* Get FRAME's font parameter.  */
-  frame_font = Fassq (Qfont, f->param_alist);
-  xassert (CONSP (frame_font) && STRINGP (XCDR (frame_font)));
-  frame_font = XCDR (frame_font);
-
-  fontset = fs_query_fontset (f, XSTRING (frame_font)->data);
-  if (fontset >= 0)
-    {
-      /* Frame parameter is a fontset name.  Modify the fontset so
-         that all its fonts reflect face attributes LFACE.  */
-      int charset;
-      struct fontset_info *fontset_info;
-
-      fontset_info = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
-      
-      for (charset = 0; charset < MAX_CHARSET; ++charset)
-	if (fontset_info->fontname[charset])
-	  {
-	    font = choose_face_fontset_font (f, XVECTOR (lface)->contents,
-					     fontset, charset);
-	    Fset_fontset_font (frame_font, CHARSET_SYMBOL (charset),
-			       build_string (font), frame);
-	    xfree (font);
-	  }
-    }
-  else
-    {
-      /* Frame parameter is an X font name.  I believe this can 
-         only happen in unibyte mode.  */
-      font = choose_face_font (f, XVECTOR (lface)->contents,
-			       -1, Vface_default_registry);
-      if (font)
-	{
-	  store_frame_param (f, Qfont, build_string (font));
-	  xfree (font);
-	}
-    }
-}
-
-
-/* Update the corresponding face when frame parameter PARAM on frame F
-   has been assigned the value NEW_VALUE.  */
-
-void
-update_face_from_frame_parameter (f, param, new_value)
-     struct frame *f;
-     Lisp_Object param, new_value;
-{
-  Lisp_Object lface;
-
-  /* If there are no faces yet, give up.  This is the case when called
-     from Fx_create_frame, and we do the necessary things later in
-     face-set-after-frame-defaults.  */
-  if (NILP (f->face_alist))
-    return;
-  
-  if (EQ (param, Qforeground_color))
-    {
-      lface = lface_from_face_name (f, Qdefault, 1);
-      LFACE_FOREGROUND (lface) = (STRINGP (new_value)
-				  ? new_value : Qunspecified);
-      realize_basic_faces (f);
-    }
-  else if (EQ (param, Qbackground_color))
-    {
-      Lisp_Object frame;
-
-      /* 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.  */
-      XSETFRAME (frame, f);
-      call1 (Qframe_update_face_colors, frame);
-      
-      lface = lface_from_face_name (f, Qdefault, 1);
-      LFACE_BACKGROUND (lface) = (STRINGP (new_value)
-				  ? new_value : Qunspecified);
-      realize_basic_faces (f);
-    }
-  if (EQ (param, Qborder_color))
-    {
-      lface = lface_from_face_name (f, Qborder, 1);
-      LFACE_BACKGROUND (lface) = (STRINGP (new_value)
-				  ? new_value : Qunspecified);
-    }
-  else if (EQ (param, Qcursor_color))
-    {
-      lface = lface_from_face_name (f, Qcursor, 1);
-      LFACE_BACKGROUND (lface) = (STRINGP (new_value)
-				  ? new_value : Qunspecified);
-    }
-  else if (EQ (param, Qmouse_color))
-    {
-      lface = lface_from_face_name (f, Qmouse, 1);
-      LFACE_BACKGROUND (lface) = (STRINGP (new_value)
-				  ? new_value : Qunspecified);
-    }
-}
-
-
-/* Get the value of X resource RESOURCE, class CLASS for the display
-   of frame FRAME.  This is here because ordinary `x-get-resource'
-   doesn't take a frame argument.  */
-
-DEFUN ("internal-face-x-get-resource", Finternal_face_x_get_resource,
-       Sinternal_face_x_get_resource, 3, 3, 0, "")
-  (resource, class, frame)
-     Lisp_Object resource, class, frame;
-{
-#if 0 /* NTEMACS_TODO : W32 resources */
-  Lisp_Object value;
-  CHECK_STRING (resource, 0);
-  CHECK_STRING (class, 1);
-  CHECK_LIVE_FRAME (frame, 2);
-  BLOCK_INPUT;
-  value = display_x_get_resource (FRAME_W32_DISPLAY_INFO (XFRAME (frame)),
-				  resource, class, Qnil, Qnil);
-  UNBLOCK_INPUT;
-  return value;
-#endif /* NTEMACS_TODO */
-  return Qnil;
-}
-
-
-/* Return resource string VALUE as a boolean value, i.e. nil, or t.
-   If VALUE is "on" or "true", return t.  If VALUE is "off" or
-   "false", return nil.  Otherwise, if SIGNAL_P is non-zero, signal an
-   error; if SIGNAL_P is zero, return 0.  */
-   
-static Lisp_Object
-face_boolean_x_resource_value (value, signal_p)
-     Lisp_Object value;
-     int signal_p;
-{
-  Lisp_Object result = make_number (0);
-
-  xassert (STRINGP (value));
-  
-  if (xstricmp (XSTRING (value)->data, "on") == 0
-      || xstricmp (XSTRING (value)->data, "true") == 0)
-    result = Qt;
-  else if (xstricmp (XSTRING (value)->data, "off") == 0
-	   || xstricmp (XSTRING (value)->data, "false") == 0)
-    result = Qnil;
-  else if (xstricmp (XSTRING (value)->data, "unspecified") == 0)
-    result = Qunspecified;
-  else if (signal_p)
-    signal_error ("Invalid face attribute value from X resource", value);
-
-  return result;
-}
-
-
-DEFUN ("internal-set-lisp-face-attribute-from-resource",
-       Finternal_set_lisp_face_attribute_from_resource,
-       Sinternal_set_lisp_face_attribute_from_resource,
-       3, 4, 0, "")
-  (face, attr, value, frame)
-     Lisp_Object face, attr, value, frame;
-{
-  CHECK_SYMBOL (face, 0);
-  CHECK_SYMBOL (attr, 1);
-  CHECK_STRING (value, 2);
-
-  if (xstricmp (XSTRING (value)->data, "unspecified") == 0)
-    value = Qunspecified;
-  else if (EQ (attr, QCheight))
-    {
-      value = Fstring_to_number (value, make_number (10));
-      if (XINT (value) <= 0)
-	signal_error ("Invalid face height from X resource", value);
-    }
-  else if (EQ (attr, QCbold) || EQ (attr, QCitalic))
-    value = face_boolean_x_resource_value (value, 1);
-  else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth))
-    value = intern (XSTRING (value)->data);
-  else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video))
-    value = face_boolean_x_resource_value (value, 1);
-  else if (EQ (attr, QCunderline)
-	   || EQ (attr, QCoverline)
-	   || EQ (attr, QCstrike_through)
-	   || EQ (attr, QCbox))
-    {
-      Lisp_Object boolean_value;
-
-      /* If the result of face_boolean_x_resource_value is t or nil,
-	 VALUE does NOT specify a color. */
-      boolean_value = face_boolean_x_resource_value (value, 0);
-      if (SYMBOLP (boolean_value))
-	value = boolean_value;
-    }
-
-  return Finternal_set_lisp_face_attribute (face, attr, value, frame);
-}
-
-#endif /* HAVE_WINDOW_SYSTEM */
-
-
-DEFUN ("internal-get-lisp-face-attribute", Finternal_get_lisp_face_attribute,
-       Sinternal_get_lisp_face_attribute,
-       2, 3, 0,
-  "Return face attribute KEYWORD of face SYMBOL.\n\
-If SYMBOL does not name a valid Lisp face or KEYWORD isn't a valid\n\
-face attribute name, signal an error.\n\
-If the optional argument FRAME is given, report on face FACE in that\n\
-frame.  If FRAME is t, report on the defaults for face FACE (for new\n\
-frames).  If FRAME is omitted or nil, use the selected frame.")
-  (symbol, keyword, frame)
-     Lisp_Object symbol, keyword, frame;
-{
-  Lisp_Object lface, value = Qnil;
-  
-  CHECK_SYMBOL (symbol, 0);
-  CHECK_SYMBOL (keyword, 1);
-
-  if (EQ (frame, Qt))
-    lface = lface_from_face_name (NULL, symbol, 1);
-  else
-    {
-      if (NILP (frame))
-	frame = selected_frame;
-      CHECK_LIVE_FRAME (frame, 2);
-      lface = lface_from_face_name (XFRAME (frame), symbol, 1);
-    }
-
-  if (EQ (keyword, QCfamily))
-    value = LFACE_FAMILY (lface);
-  else if (EQ (keyword, QCheight))
-    value = LFACE_HEIGHT (lface);
-  else if (EQ (keyword, QCweight))
-    value = LFACE_WEIGHT (lface);
-  else if (EQ (keyword, QCslant))
-    value = LFACE_SLANT (lface);
-  else if (EQ (keyword, QCunderline))
-    value = LFACE_UNDERLINE (lface);
-  else if (EQ (keyword, QCoverline))
-    value = LFACE_OVERLINE (lface);
-  else if (EQ (keyword, QCstrike_through))
-    value = LFACE_STRIKE_THROUGH (lface);
-  else if (EQ (keyword, QCbox))
-    value = LFACE_BOX (lface);
-  else if (EQ (keyword, QCinverse_video)
-	   || EQ (keyword, QCreverse_video))
-    value = LFACE_INVERSE (lface);
-  else if (EQ (keyword, QCforeground))
-    value = LFACE_FOREGROUND (lface);
-  else if (EQ (keyword, QCbackground))
-    value = LFACE_BACKGROUND (lface);
-  else if (EQ (keyword, QCstipple))
-    value = LFACE_STIPPLE (lface);
-  else if (EQ (keyword, QCwidth))
-    value = LFACE_SWIDTH (lface);
-  else
-    signal_error ("Invalid face attribute name", keyword);
-
-  return value;
-}
-
-
-DEFUN ("internal-lisp-face-attribute-values",
-       Finternal_lisp_face_attribute_values,
-       Sinternal_lisp_face_attribute_values, 1, 1, 0,
-  "Return a list of valid discrete values for face attribute ATTR.\n\
-Value is nil if ATTR doesn't have a discrete set of valid values.")
-  (attr)
-     Lisp_Object attr;
-{
-  Lisp_Object result = Qnil;
-  
-  CHECK_SYMBOL (attr, 0);
-  
-  if (EQ (attr, QCweight)
-      || EQ (attr, QCslant)
-      || EQ (attr, QCwidth))
-    {
-      /* Extract permissible symbols from tables.  */
-      struct table_entry *table;
-      int i, dim;
-      
-      if (EQ (attr, QCweight))
-	table = weight_table, dim = DIM (weight_table);
-      else if (EQ (attr, QCslant))
-	table = slant_table, dim = DIM (slant_table);
-      else
-	table = swidth_table, dim = DIM (swidth_table);
-
-      for (i = 0; i < dim; ++i)
-	{
-	  Lisp_Object symbol = *table[i].symbol;
-	  Lisp_Object tail = result;
-
-	  while (!NILP (tail)
-		 && !EQ (XCAR (tail), symbol))
-	    tail = XCDR (tail);
-
-	  if (NILP (tail))
-	    result = Fcons (symbol, result);
-	}
-    }
-  else if (EQ (attr, QCunderline))
-    result = Fcons (Qt, Fcons (Qnil, Qnil));
-  else if (EQ (attr, QCoverline))
-    result = Fcons (Qt, Fcons (Qnil, Qnil));
-  else if (EQ (attr, QCstrike_through))
-    result = Fcons (Qt, Fcons (Qnil, Qnil));
-  else if (EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video))
-    result = Fcons (Qt, Fcons (Qnil, Qnil));
-
-  return result;
-}
-  
-
-DEFUN ("internal-merge-in-global-face", Finternal_merge_in_global_face,
-       Sinternal_merge_in_global_face, 2, 2, 0, 
-  "Add attributes from frame-default definition of FACE to FACE on FRAME.")
-  (face, frame)
-     Lisp_Object face, frame;
-{
-  Lisp_Object global_lface, local_lface;
-  CHECK_LIVE_FRAME (frame, 1);
-  global_lface = lface_from_face_name (NULL, face, 1);
-  local_lface = lface_from_face_name (XFRAME (frame), face, 0);
-  if (NILP (local_lface))
-    local_lface = Finternal_make_lisp_face (face, frame);
-  merge_face_vectors (XVECTOR (global_lface)->contents,
-		      XVECTOR (local_lface)->contents);
-  return face;
-}
-
-
-/* The following function is implemented for compatibility with 20.2.
-   The function is used in x-resolve-fonts when it is asked to
-   return fonts with the same size as the font of a face.  This is
-   done in fontset.el.  */
-
-DEFUN ("face-font", Fface_font, Sface_font, 1, 2, 0, 
-  "Return the font name of face FACE, or nil if it is unspecified.\n\
-If the optional argument FRAME is given, report on face FACE in that frame.\n\
-If FRAME is t, report on the defaults for face FACE (for new frames).\n\
-  The font default for a face is either nil, or a list\n\
-  of the form (bold), (italic) or (bold italic).\n\
-If FRAME is omitted or nil, use the selected frame.")
-  (face, frame)
-     Lisp_Object face, frame;
-{
-  if (EQ (frame, Qt))
-    {
-      Lisp_Object result = Qnil;
-      Lisp_Object lface = lface_from_face_name (NULL, face, 1);
-
-      if (!UNSPECIFIEDP (LFACE_WEIGHT (lface))
-	  && !EQ (LFACE_WEIGHT (lface), Qnormal))
-	result = Fcons (Qbold, result);
-      
-      if (!NILP (LFACE_SLANT (lface))
-	  && !EQ (LFACE_SLANT (lface), Qnormal))
-	result = Fcons (Qitalic, result);
-      
-      return result;
-    }
-  else
-    {
-      struct frame *f = frame_or_selected_frame (frame, 1);
-      int face_id = lookup_named_face (f, face, CHARSET_ASCII);
-      struct face *face = FACE_FROM_ID (f, face_id);
-      return build_string (face->font_name);
-    }
-}
-
-
-/* Compare face vectors V1 and V2 for equality.  Value is non-zero if
-   all attributes are `equal'.  Tries to be fast because this function
-   is called quite often.  */
-
-static INLINE int
-lface_equal_p (v1, v2)
-     Lisp_Object *v1, *v2;
-{
-  int i, equal_p = 1;
-
-  for (i = 1; i < LFACE_VECTOR_SIZE && equal_p; ++i)
-    {
-      Lisp_Object a = v1[i];
-      Lisp_Object b = v2[i];
-
-      /* Type can differ, e.g. when one attribute is unspecified, i.e. nil,
-	 and the other is specified.  */
-      equal_p = XTYPE (a) == XTYPE (b);
-      if (!equal_p)
-	break;
-
-      if (!EQ (a, b))
-	{
-	  switch (XTYPE (a))
-	    {
-	    case Lisp_String:
-	      equal_p = (XSTRING (a)->size == XSTRING (b)->size
-			 && bcmp (XSTRING (a)->data, XSTRING (b)->data,
-				  XSTRING (a)->size) == 0);
-	      break;
-	  
-	    case Lisp_Int:
-	    case Lisp_Symbol:
-	      equal_p = 0;
-	      break;
-	  
-	    default:
-	      equal_p = !NILP (Fequal (a, b));
-	      break;
-	    }
-	}
-    }
-	  
-  return equal_p;
-}
-
-
-DEFUN ("internal-lisp-face-equal-p", Finternal_lisp_face_equal_p,
-       Sinternal_lisp_face_equal_p, 2, 3, 0,
-  "True if FACE1 and FACE2 are equal.\n\
-If the optional argument FRAME is given, report on face FACE in that frame.\n\
-If FRAME is t, report on the defaults for face FACE (for new frames).\n\
-If FRAME is omitted or nil, use the selected frame.")
-  (face1, face2, frame)
-     Lisp_Object face1, face2, frame;
-{
-  int equal_p;
-  struct frame *f;
-  Lisp_Object lface1, lface2;
-  
-  if (EQ (frame, Qt))
-    f = NULL;
-  else
-    /* Don't use check_x_frame here because this function is called
-       before frames exist.  At that time, if FRAME is nil,
-       selected_frame will be used which is the frame dumped with
-       Emacs.  That frame is not a GUI frame.  */
-    f = frame_or_selected_frame (frame, 2);
-
-  lface1 = lface_from_face_name (NULL, face1, 1);
-  lface2 = lface_from_face_name (NULL, face2, 1);
-  equal_p = lface_equal_p (XVECTOR (lface1)->contents,
-			   XVECTOR (lface2)->contents);
-  return equal_p ? Qt : Qnil;
-}
-
-  
-DEFUN ("internal-lisp-face-empty-p", Finternal_lisp_face_empty_p,
-       Sinternal_lisp_face_empty_p, 1, 2, 0,
-  "True if FACE has no attribute specified.\n\
-If the optional argument FRAME is given, report on face FACE in that frame.\n\
-If FRAME is t, report on the defaults for face FACE (for new frames).\n\
-If FRAME is omitted or nil, use the selected frame.")
-  (face, frame)
-     Lisp_Object face, frame;
-{
-  struct frame *f;
-  Lisp_Object lface;
-  int i;
-
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame, 0);
-  f = XFRAME (frame);
-  
-  if (EQ (frame, Qt))
-    lface = lface_from_face_name (NULL, face, 1);
-  else
-    lface = lface_from_face_name (f, face, 1);
-
-  for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
-    if (!UNSPECIFIEDP (XVECTOR (lface)->contents[i]))
-      break;
-  
-  return i == LFACE_VECTOR_SIZE ? Qt : Qnil;
-}
-
-
-DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist,
-       0, 1, 0, 
-  "Return an alist of frame-local faces defined on FRAME.\n\
-For internal use only.")
-  (frame)
-     Lisp_Object frame;
-{
-  struct frame *f = frame_or_selected_frame (frame, 0);
-  return f->face_alist;
-}
-
-
-/* Return a hash code for Lisp string STRING with case ignored.  Used
-   below in computing a hash value for a Lisp face.  */
-
-static INLINE unsigned
-hash_string_case_insensitive (string)
-     Lisp_Object string;
-{
-  unsigned char *s;
-  unsigned hash = 0;
-  xassert (STRINGP (string));
-  for (s = XSTRING (string)->data; *s; ++s)
-    hash = (hash << 1) ^ tolower (*s);
-  return hash;
-}
-
-
-/* Return a hash code for face attribute vector V.  */
-
-static INLINE unsigned
-lface_hash (v)
-     Lisp_Object *v;
-{
-  return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX])
-	  ^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX])
-	  ^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX])
-	  ^ (unsigned) v[LFACE_WEIGHT_INDEX]
-	  ^ (unsigned) v[LFACE_SLANT_INDEX]
-	  ^ (unsigned) v[LFACE_SWIDTH_INDEX]
-	  ^ XFASTINT (v[LFACE_HEIGHT_INDEX]));
-}
-
-
-/* Return non-zero if LFACE1 and LFACE2 specify the same font (without
-   considering charsets/registries).  They do if they specify the same
-   family, point size, weight, width and slant.  Both LFACE1 and
-   LFACE2 must be fully-specified.  */
-
-static INLINE int
-lface_same_font_attributes_p (lface1, lface2)
-     Lisp_Object *lface1, *lface2;
-{
-  xassert (lface_fully_specified_p (lface1)
-	   && lface_fully_specified_p (lface2));
-  return (xstricmp (XSTRING (lface1[LFACE_FAMILY_INDEX])->data,
-		    XSTRING (lface2[LFACE_FAMILY_INDEX])->data) == 0
-	  && (XFASTINT (lface1[LFACE_HEIGHT_INDEX])
-	      == XFASTINT (lface2[LFACE_HEIGHT_INDEX]))
-	  && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
-	  && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
-	  && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX]));
-}
-
-
-
-/***********************************************************************
-			    Realized Faces
- ***********************************************************************/
-
-/* Allocate and return a new realized face for Lisp face attribute
-   vector ATTR, charset CHARSET, and registry REGISTRY.  */
-
-static struct face *
-make_realized_face (attr, charset, registry)
-     Lisp_Object *attr;
-     int charset;
-     Lisp_Object registry;
-{
-  struct face *face = (struct face *) xmalloc (sizeof *face);
-  bzero (face, sizeof *face);
-  face->charset = charset;
-  face->registry = registry;
-  bcopy (attr, face->lface, sizeof face->lface);
-  return face;
-}
-
-
-/* Free realized face FACE, including its X resources.  FACE may
-   be null.  */
-
-static void
-free_realized_face (f, face)
-     struct frame *f;
-     struct face *face;
-{
-  if (face)
-    {
-#ifdef HAVE_WINDOW_SYSTEM
-      if (FRAME_WINDOW_P (f))
-	{
-	  if (face->gc)
-	    {
-	      x_free_gc (f, face->gc);
-	      face->gc = 0;
-	    }
-	  
-	  free_face_colors (f, face);
-	  x_destroy_bitmap (f, face->stipple);
-	}
-#endif /* HAVE_WINDOW_SYSTEM */
-
-      xfree (face);
-    }
-}
-
-
-/* Prepare face FACE for subsequent display on frame F.  This
-   allocated GCs if they haven't been allocated yet or have been freed
-   by clearing the face cache.  */
-
-void
-prepare_face_for_display (f, face)
-     struct frame *f;
-     struct face *face;
-{
-#ifdef HAVE_WINDOW_SYSTEM
-  xassert (FRAME_WINDOW_P (f));
-  
-  if (face->gc == 0)
-    {
-      XGCValues xgcv;
-      unsigned long mask = GCForeground | GCBackground;
-
-      xgcv.foreground = face->foreground;
-      xgcv.background = face->background;
-
-      /* The font of FACE may be null if we couldn't load it.  */
-      if (face->font)
-	{
-	  xgcv.font = face->font;
-	  mask |= GCFont;
-	}
-
-      BLOCK_INPUT;
-      if (face->stipple)
-	{
-#if 0 /* NTEMACS_TODO: XGCValues not fully simulated */
-	  xgcv.fill_style = FillOpaqueStippled;
-	  xgcv.stipple = x_bitmap_pixmap (f, face->stipple);
-	  mask |= GCFillStyle | GCStipple;
-#endif /* NTEMACS_TODO */
-	}
-
-      face->gc = x_create_gc (f, mask, &xgcv);
-      UNBLOCK_INPUT;
-    }
-#endif /* HAVE_WINDOW_SYSTEM */
-}
-
-
-/* Non-zero if FACE is suitable for displaying ISO8859-1.  Used in
-   macro FACE_SUITABLE_FOR_CHARSET_P to avoid realizing a new face for
-   ISO8859-1 if the ASCII face suffices.  */
-
-int
-face_suitable_for_iso8859_1_p (face)
-     struct face *face;
-{
-  int len = strlen (face->font_name);
-  return len >= 9 && xstricmp (face->font_name + len - 9, "iso8859-1") == 0;
-}
-
-
-/* Value is non-zero if FACE is suitable for displaying characters
-   of CHARSET.  CHARSET < 0 means unibyte text.  */
-
-INLINE int
-face_suitable_for_charset_p (face, charset)
-     struct face *face;
-     int charset;
-{
-  int suitable_p = 0;
-  
-  if (charset < 0)
-    {
-      if (EQ (face->registry, Vface_default_registry)
-	  || !NILP (Fequal (face->registry, Vface_default_registry)))
-	suitable_p = 1;
-    }
-  else if (face->charset == charset)
-    suitable_p = 1;
-  else if (face->charset == CHARSET_ASCII
-	   && charset == charset_latin_iso8859_1)
-    suitable_p = face_suitable_for_iso8859_1_p (face);
-  else if (face->charset == charset_latin_iso8859_1
-	   && charset == CHARSET_ASCII)
-    suitable_p = 1;
-
-  return suitable_p;
-}
-
-
-
-/***********************************************************************
-			      Face Cache
- ***********************************************************************/
-
-/* Return a new face cache for frame F.  */
-
-static struct face_cache *
-make_face_cache (f)
-     struct frame *f;
-{
-  struct face_cache *c;
-  int size;
-
-  c = (struct face_cache *) xmalloc (sizeof *c);
-  bzero (c, sizeof *c);
-  size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
-  c->buckets = (struct face **) xmalloc (size);
-  bzero (c->buckets, size);
-  c->size = 50;
-  c->faces_by_id = (struct face **) xmalloc (c->size * sizeof *c->faces_by_id);
-  c->f = f;
-  return c;
-}
-
-
-/* Clear out all graphics contexts for all realized faces, except for
-   the basic faces.  This should be done from time to time just to avoid
-   keeping too many graphics contexts that are no longer needed.  */
-
-static void
-clear_face_gcs (c)
-     struct face_cache *c;
-{
-  if (c && FRAME_WINDOW_P (c->f))
-    {
-#ifdef HAVE_WINDOW_SYSTEM
-      int i;
-      for (i = BASIC_FACE_ID_SENTINEL; i < c->used; ++i)
-	{
-	  struct face *face = c->faces_by_id[i];
-	  if (face && face->gc)
-	    {
-	      x_free_gc (c->f, face->gc);
-	      face->gc = 0;
-	    }
-	}
-#endif /* HAVE_WINDOW_SYSTEM */
-    }
-}
-
-
-/* Free all realized faces in face cache C, including basic faces.  C
-   may be null.  If faces are freed, make sure the frame's current
-   matrix is marked invalid, so that a display caused by an expose
-   event doesn't try to use faces we destroyed.  */
-
-static void
-free_realized_faces (c)
-     struct face_cache *c;
-{
-  if (c && c->used)
-    {
-      int i, size;
-      struct frame *f = c->f;
-
-      for (i = 0; i < c->used; ++i)
-	{
-	  free_realized_face (f, c->faces_by_id[i]);
-	  c->faces_by_id[i] = NULL;
-	}
-      
-      c->used = 0;
-      size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
-      bzero (c->buckets, size);
-
-      /* Must do a thorough redisplay the next time.  Mark current
-	 matrices as invalid because they will reference faces freed
-	 above.  This function is also called when a frame is
-	 destroyed.  In this case, the root window of F is nil.  */
-      if (WINDOWP (f->root_window))
-	{
-	  clear_current_matrices (f);
-	  ++windows_or_buffers_changed;
-	}
-    }
-}
-
-
-/* Free all realized faces on FRAME or on all frames if FRAME is nil.
-   This is done after attributes of a named face have been changed,
-   because we can't tell which realized faces depend on that face.  */
-
-void
-free_all_realized_faces (frame)
-     Lisp_Object frame;
-{
-  if (NILP (frame))
-    {
-      Lisp_Object rest;
-      FOR_EACH_FRAME (rest, frame)
-	free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
-    }
-  else
-    free_realized_faces (FRAME_FACE_CACHE (XFRAME (frame)));
-}
-
-
-/* Free face cache C and faces in it, including their X resources.  */
-
-static void
-free_face_cache (c)
-     struct face_cache *c;
-{
-  if (c)
-    {
-      free_realized_faces (c);
-      xfree (c->buckets);
-      xfree (c->faces_by_id);
-      xfree (c);
-    }
-}
-
-
-/* Cache realized face FACE in face cache C.  HASH is the hash value
-   of FACE.  If FACE->fontset >= 0, add the new face to the end of the
-   collision list of the face hash table of C.  This is done because
-   otherwise lookup_face would find FACE for every charset, even if
-   faces with the same attributes but for specific charsets exist.  */
-
-static void
-cache_face (c, face, hash)
-     struct face_cache *c;
-     struct face *face;
-     unsigned hash;
-{
-  int i = hash % FACE_CACHE_BUCKETS_SIZE;
-
-  face->hash = hash;
-
-  if (face->fontset >= 0)
-    {
-      struct face *last = c->buckets[i];
-      if (last)
-	{
-	  while (last->next)
-	    last = last->next;
-	  last->next = face;
-	  face->prev = last;
-	  face->next = NULL;
-	}
-      else
-	{
-	  c->buckets[i] = face;
-	  face->prev = face->next = NULL;
-	}
-    }
-  else
-    {
-      face->prev = NULL;
-      face->next = c->buckets[i];
-      if (face->next)
-	face->next->prev = face;
-      c->buckets[i] = face;
-    }
-
-  /* Find a free slot in C->faces_by_id and use the index of the free
-     slot as FACE->id.  */
-  for (i = 0; i < c->used; ++i)
-    if (c->faces_by_id[i] == NULL)
-      break;
-  face->id = i;
-  
-  /* Maybe enlarge C->faces_by_id.  */
-  if (i == c->used && c->used == c->size)
-    {
-      int new_size = 2 * c->size;
-      int sz = new_size * sizeof *c->faces_by_id;
-      c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz);
-      c->size = new_size;
-    }
-
-#if GLYPH_DEBUG
-  /* Check that FACE got a unique id.  */
-  {
-    int j, n;
-    struct face *face;
-
-    for (j = n = 0; j < FACE_CACHE_BUCKETS_SIZE; ++j)
-      for (face = c->buckets[j]; face; face = face->next)
-	if (face->id == i)
-	  ++n;
-
-    xassert (n == 1);
-  }
-#endif /* GLYPH_DEBUG */
-  
-  c->faces_by_id[i] = face;
-  if (i == c->used)
-    ++c->used;
-}
-
-
-/* Remove face FACE from cache C.  */
-
-static void
-uncache_face (c, face)
-     struct face_cache *c;
-     struct face *face;
-{
-  int i = face->hash % FACE_CACHE_BUCKETS_SIZE;
-  
-  if (face->prev)
-    face->prev->next = face->next;
-  else
-    c->buckets[i] = face->next;
-  
-  if (face->next)
-    face->next->prev = face->prev;
-  
-  c->faces_by_id[face->id] = NULL;
-  if (face->id == c->used)
-    --c->used;
-}
-
-
-/* Look up a realized face with face attributes ATTR in the face cache
-   of frame F.  The face will be used to display characters of
-   CHARSET.  CHARSET < 0 means the face will be used to display
-   unibyte text.  The value of face-default-registry is used to choose
-   a font for the face in that case.  Value is the ID of the face
-   found.  If no suitable face is found, realize a new one.  */
-
-INLINE int
-lookup_face (f, attr, charset)
-     struct frame *f;
-     Lisp_Object *attr;
-     int charset;
-{
-  struct face_cache *c = FRAME_FACE_CACHE (f);
-  unsigned hash;
-  int i;
-  struct face *face;
-
-  xassert (c != NULL);
-  check_lface_attrs (attr);
-
-  /* Look up ATTR in the face cache.  */
-  hash = lface_hash (attr);
-  i = hash % FACE_CACHE_BUCKETS_SIZE;
-  
-  for (face = c->buckets[i]; face; face = face->next)
-    if (face->hash == hash
-	&& (!FRAME_WINDOW_P (f)
-	    || FACE_SUITABLE_FOR_CHARSET_P (face, charset))
-	&& lface_equal_p (face->lface, attr))
-      break;
-
-  /* If not found, realize a new face.  */
-  if (face == NULL)
-    {
-      face = realize_face (c, attr, charset);
-      cache_face (c, face, hash);
-    }
-
-#if GLYPH_DEBUG
-  xassert (face == FACE_FROM_ID (f, face->id));
-  if (FRAME_WINDOW_P (f))
-    xassert (charset < 0 || FACE_SUITABLE_FOR_CHARSET_P (face, charset));
-#endif /* GLYPH_DEBUG */
-  
-  return face->id;
-}
-
-
-/* Return the face id of the realized face for named face SYMBOL on
-   frame F suitable for displaying characters from CHARSET.  CHARSET <
-   0 means unibyte text.  */
-
-int
-lookup_named_face (f, symbol, charset)
-     struct frame *f;
-     Lisp_Object symbol;
-     int charset;
-{
-  Lisp_Object attrs[LFACE_VECTOR_SIZE];
-  Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
-  struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
-
-  get_lface_attributes (f, symbol, symbol_attrs, 1);
-  bcopy (default_face->lface, attrs, sizeof attrs);
-  merge_face_vectors (symbol_attrs, attrs);
-  return lookup_face (f, attrs, charset);
-}
-
-
-/* Return the ID of the realized ASCII face of Lisp face with ID
-   LFACE_ID on frame F.  Value is -1 if LFACE_ID isn't valid.  */
-
-int
-ascii_face_of_lisp_face (f, lface_id)
-     struct frame *f;
-     int lface_id;
-{
-  int face_id;
-  
-  if (lface_id >= 0 && lface_id < lface_id_to_name_size)
-    {
-      Lisp_Object face_name = lface_id_to_name[lface_id];
-      face_id = lookup_named_face (f, face_name, CHARSET_ASCII);
-    }
-  else
-    face_id = -1;
-
-  return face_id;
-}
-
-
-/* Return a face for charset ASCII that is like the face with id
-   FACE_ID on frame F, but has a font that is STEPS steps smaller.
-   STEPS < 0 means larger.  Value is the id of the face.  */
-
-int
-smaller_face (f, face_id, steps)
-     struct frame *f;
-     int face_id, steps;
- {
-#ifdef HAVE_WINDOW_SYSTEM
-  struct face *face;
-  Lisp_Object attrs[LFACE_VECTOR_SIZE];
-  int pt, last_pt, last_height;
-  int delta;
-  int new_face_id;
-  struct face *new_face;
-
-  /* If not called for an X frame, just return the original face.  */
-  if (FRAME_TERMCAP_P (f))
-    return face_id;
-
-  /* Try in increments of 1/2 pt.  */
-  delta = steps < 0 ? 5 : -5;
-  steps = abs (steps);
-  
-  face = FACE_FROM_ID (f, face_id);
-  bcopy (face->lface, attrs, sizeof attrs);
-  pt = last_pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
-  new_face_id = face_id;
-  last_height = FONT_HEIGHT (face->font);
-
-  while (steps
-	 && pt + delta > 0
-	 /* Give up if we cannot find a font within 10pt.  */
-	 && abs (last_pt - pt) < 100)
-    {
-      /* Look up a face for a slightly smaller/larger font.  */
-      pt += delta;
-      attrs[LFACE_HEIGHT_INDEX] = make_number (pt);
-      new_face_id = lookup_face (f, attrs, CHARSET_ASCII);
-      new_face = FACE_FROM_ID (f, new_face_id);
-
-      /* If height changes, count that as one step.  */
-      if (FONT_HEIGHT (new_face->font) != last_height)
-	{
-	  --steps;
-	  last_height = FONT_HEIGHT (new_face->font);
-	  last_pt = pt;
-	}
-    }
-
-  return new_face_id;
-
-#else /* not HAVE_WINDOW_SYSTEM */
-
-  return face_id;
-  
-#endif /* not HAVE_WINDOW_SYSTEM */
-}
-
-
-/* Return a face for charset ASCII that is like the face with id
-   FACE_ID on frame F, but has height HEIGHT.  */
-
-int
-face_with_height (f, face_id, height)
-     struct frame *f;
-     int face_id;
-     int height;
-{
-#ifdef HAVE_WINDOW_SYSTEM
-  struct face *face;
-  Lisp_Object attrs[LFACE_VECTOR_SIZE];
-
-  if (FRAME_TERMCAP_P (f)
-      || height <= 0)
-    return face_id;
-
-  face = FACE_FROM_ID (f, face_id);
-  bcopy (face->lface, attrs, sizeof attrs);
-  attrs[LFACE_HEIGHT_INDEX] = make_number (height);
-  face_id = lookup_face (f, attrs, CHARSET_ASCII);
-#endif /* HAVE_WINDOW_SYSTEM */
-  
-  return face_id;
-}
-
-/* Return the face id of the realized face for named face SYMBOL on
-   frame F suitable for displaying characters from CHARSET (CHARSET <
-   0 means unibyte text), and use attributes of the face FACE_ID for
-   attributes that aren't completely specified by SYMBOL.  This is
-   like lookup_named_face, except that the default attributes come
-   from FACE_ID, not from the default face.  FACE_ID is assumed to
-   be already realized.  */
-
-int
-lookup_derived_face (f, symbol, charset, face_id)
-     struct frame *f;
-     Lisp_Object symbol;
-     int charset;
-     int face_id;
-{
-  Lisp_Object attrs[LFACE_VECTOR_SIZE];
-  Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
-  struct face *default_face = FACE_FROM_ID (f, face_id);
-
-  if (!default_face)
-    abort ();
-
-  get_lface_attributes (f, symbol, symbol_attrs, 1);
-  bcopy (default_face->lface, attrs, sizeof attrs);
-  merge_face_vectors (symbol_attrs, attrs);
-  return lookup_face (f, attrs, charset);
-}
-
-
-
-/***********************************************************************
-			    Font selection
- ***********************************************************************/
-
-DEFUN ("internal-set-font-selection-order",
-       Finternal_set_font_selection_order,
-       Sinternal_set_font_selection_order, 1, 1, 0,
-  "Set font selection order for face font selection to ORDER.\n\
-ORDER must be a list of length 4 containing the symbols `:width',\n\
-`:height', `:weight', and `:slant'.  Face attributes appearing\n\
-first in ORDER are matched first, e.g. if `:height' appears before\n\
-`:weight' in ORDER, font selection first tries to find a font with\n\
-a suitable height, and then tries to match the font weight.\n\
-Value is ORDER.")
-  (order)
-       Lisp_Object order;
-{
-  Lisp_Object list;
-  int i;
-  int indices[4];
-  
-  CHECK_LIST (order, 0);
-  bzero (indices, sizeof indices);
-  i = 0;
-
-  for (list = order;
-       CONSP (list) && i < DIM (indices);
-       list = XCDR (list), ++i)
-    {
-      Lisp_Object attr = XCAR (list);
-      int xlfd;
-
-      if (EQ (attr, QCwidth))
-	xlfd = XLFD_SWIDTH;
-      else if (EQ (attr, QCheight))
-	xlfd = XLFD_POINT_SIZE;
-      else if (EQ (attr, QCweight))
-	xlfd = XLFD_WEIGHT;
-      else if (EQ (attr, QCslant))
-	xlfd = XLFD_SLANT;
-      else
-	break;
-
-      if (indices[i] != 0)
-	break;
-      indices[i] = xlfd;
-    }
-
-  if (!NILP (list)
-      || i != DIM (indices)
-      || indices[0] == 0
-      || indices[1] == 0
-      || indices[2] == 0
-      || indices[3] == 0)
-    signal_error ("Invalid font sort order", order);
-
-  if (bcmp (indices, font_sort_order, sizeof indices) != 0)
-    {
-      bcopy (indices, font_sort_order, sizeof font_sort_order);
-      free_all_realized_faces (Qnil);
-    }
-  
-  return Qnil;
-}
-
-
-DEFUN ("internal-set-alternative-font-family-alist",
-       Finternal_set_alternative_font_family_alist,
-       Sinternal_set_alternative_font_family_alist, 1, 1, 0,
-  "Define alternative font families to try in face font selection.\n\
-ALIST is an alist of (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...) entries.\n\
-Each ALTERNATIVE is tried in order if no fonts of font family FAMILY can\n\
-be found.  Value is ALIST.")
-  (alist)
-     Lisp_Object alist;
-{
-  CHECK_LIST (alist, 0);
-  Vface_alternative_font_family_alist = alist;
-  free_all_realized_faces (Qnil);
-  return alist;
-}
-
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-/* Return the X registry and encoding of font name FONT_NAME on frame F.
-   Value is nil if not successful.  */
-
-static Lisp_Object
-deduce_unibyte_registry (f, font_name)
-     struct frame *f;
-     char *font_name;
-{
-  struct font_name font;
-  Lisp_Object registry = Qnil;
-  
-  font.name = STRDUPA (font_name);
-  if (split_font_name (f, &font, 0))
-    {
-      char *buffer;
-
-      /* Extract registry and encoding.  */
-      buffer = (char *) alloca (strlen (font.fields[XLFD_REGISTRY])
-				+ strlen (font.fields[XLFD_ENCODING])
-				+ 10);
-      strcpy (buffer, font.fields[XLFD_REGISTRY]);
-      strcat (buffer, "-");
-      strcat (buffer, font.fields[XLFD_ENCODING]);
-      registry = build_string (buffer);
-    }
-
-  return registry;
-}
-
-
-/* Value is non-zero if FONT is the name of a scalable font.  The
-   X11R6 XLFD spec says that point size, pixel size, and average width
-   are zero for scalable fonts.  Intlfonts contain at least one
-   scalable font ("*-muleindian-1") for which this isn't true, so we
-   just test average width.  Windows implementation of XLFD is
-   slightly broken for backward compatibility with previous broken
-   versions, so test for wildcards as well as 0.  */
-
-static int
-font_scalable_p (font)
-     struct font_name *font;
-{
-  char *s = font->fields[XLFD_AVGWIDTH];
-  return (*s == '0' && *(s + 1) == '\0') || *s == '*';
-}
-
-
-/* Value is non-zero if FONT1 is a better match for font attributes
-   VALUES than FONT2.  VALUES is an array of face attribute values in
-   font sort order.  COMPARE_PT_P zero means don't compare point
-   sizes.  */
-
-static int
-better_font_p (values, font1, font2, compare_pt_p)
-     int *values;
-     struct font_name *font1, *font2;
-     int compare_pt_p;
-{
-  int i;
-  
-  for (i = 0; i < 4; ++i)
-    {
-      int xlfd_idx = font_sort_order[i];
-
-      if (compare_pt_p || xlfd_idx != XLFD_POINT_SIZE)
-	{
-	  int delta1 = abs (values[i] - font1->numeric[xlfd_idx]);
-	  int delta2 = abs (values[i] - font2->numeric[xlfd_idx]);
-      
-	  if (delta1 > delta2)
-	    return 0;
-	  else if (delta1 < delta2)
-	    return 1;
-	  else
-	    {
-	      /* The difference may be equal because, e.g., the face
-		 specifies `italic' but we have only `regular' and
-		 `oblique'.  Prefer `oblique' in this case.  */
-	      if ((xlfd_idx == XLFD_WEIGHT || xlfd_idx == XLFD_SLANT)
-		  && font1->numeric[xlfd_idx] > values[i]
-		  && font2->numeric[xlfd_idx] < values[i])
-		return 1;
-	    }
-	}
-    }
-  
-  return 0;
-}
-
-
-#if SCALABLE_FONTS
-
-/* Value is non-zero if FONT is an exact match for face attributes in
-   SPECIFIED.  SPECIFIED is an array of face attribute values in font
-   sort order.  */
-
-static int
-exact_face_match_p (specified, font)
-     int *specified;
-     struct font_name *font;
-{
-  int i;
-  
-  for (i = 0; i < 4; ++i)
-    if (specified[i] != font->numeric[font_sort_order[i]])
-      break;
-
-  return i == 4;
-}
-
-
-/* Value is the name of a scaled font, generated from scalable font
-   FONT on frame F.  SPECIFIED_PT is the point-size to scale FONT to.
-   Value is allocated from heap.  */
-
-static char *
-build_scalable_font_name (f, font, specified_pt)
-     struct frame *f;
-     struct font_name *font;
-     int specified_pt;
-{
-  char point_size[20], pixel_size[20];
-  int pixel_value;
-  double resy = FRAME_W32_DISPLAY_INFO (f)->resy;
-  double pt;
-
-  /* If scalable font is for a specific resolution, compute
-     the point size we must specify from the resolution of
-     the display and the specified resolution of the font.  */
-  if (font->numeric[XLFD_RESY] != 0)
-    {
-      pt = resy / font->numeric[XLFD_RESY] * specified_pt + 0.5;
-      pixel_value = font->numeric[XLFD_RESY] / 720.0 * pt;
-    }
-  else
-    {
-      pt = specified_pt;
-      pixel_value = resy / 720.0 * pt;
-    }
-  
-  /* Set point size of the font.  */
-  sprintf (point_size, "%d", (int) pt);
-  font->fields[XLFD_POINT_SIZE] = point_size;
-  font->numeric[XLFD_POINT_SIZE] = pt;
-  
-  /* Set pixel size.  */
-  sprintf (pixel_size, "%d", pixel_value);
-  font->fields[XLFD_PIXEL_SIZE] = pixel_size;
-  font->numeric[XLFD_PIXEL_SIZE] = pixel_value;
-  
-  /* If font doesn't specify its resolution, use the
-     resolution of the display.  */
-  if (font->numeric[XLFD_RESY] == 0)
-    {
-      char buffer[20];
-      sprintf (buffer, "%d", (int) resy);
-      font->fields[XLFD_RESY] = buffer;
-      font->numeric[XLFD_RESY] = resy;
-    }
-  
-  if (strcmp (font->fields[XLFD_RESX], "0") == 0)
-    {
-      char buffer[20];
-      int resx = FRAME_W32_DISPLAY_INFO (f)->resx;
-      sprintf (buffer, "%d", resx);
-      font->fields[XLFD_RESX] = buffer;
-      font->numeric[XLFD_RESX] = resx;
-    }
-
-  return build_font_name (font);
-}
-
-
-/* Value is non-zero if we are allowed to use scalable font FONT.  We
-   can't run a Lisp function here since this function may be called
-   with input blocked.  */
-
-static int
-may_use_scalable_font_p (font, name)
-     struct font_name *font;
-     char *name;
-{
-  if (EQ (Vscalable_fonts_allowed, Qt))
-    return 1;
-  else if (CONSP (Vscalable_fonts_allowed))
-    {
-      Lisp_Object tail, regexp;
-      
-      for (tail = Vscalable_fonts_allowed; CONSP (tail); tail = XCDR (tail))
-	{
-	  regexp = XCAR (tail);
-	  if (STRINGP (regexp)
-	      && fast_c_string_match_ignore_case (regexp, name) >= 0)
-	    return 1;
-	}
-    }
-  
-  return 0;
-}
-
-#endif /* SCALABLE_FONTS != 0 */
-
-
-/* Return the name of the best matching font for face attributes
-   ATTRS in the array of font_name structures FONTS which contains
-   NFONTS elements.  Value is a font name which is allocated from
-   the heap.  FONTS is freed by this function.  */
-
-static char *
-best_matching_font (f, attrs, fonts, nfonts)
-     struct frame *f;
-     Lisp_Object *attrs;
-     struct font_name *fonts;
-     int nfonts;
-{
-  char *font_name;
-  struct font_name *best;
-  int i, pt;
-  int specified[4];
-  int exact_p;
-
-  if (nfonts == 0)
-    return NULL;
-
-  /* Make specified font attributes available in `specified',
-     indexed by sort order.  */
-  for (i = 0; i < DIM (font_sort_order); ++i)
-    {
-      int xlfd_idx = font_sort_order[i];
-  
-      if (xlfd_idx == XLFD_SWIDTH)
-	specified[i] = face_numeric_swidth (attrs[LFACE_SWIDTH_INDEX]);
-      else if (xlfd_idx == XLFD_POINT_SIZE)
-	specified[i] = pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]);
-      else if (xlfd_idx == XLFD_WEIGHT)
-	specified[i] = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
-      else if (xlfd_idx == XLFD_SLANT)
-	specified[i] = face_numeric_slant (attrs[LFACE_SLANT_INDEX]);
-      else
-	abort ();
-    }
-
-#if SCALABLE_FONTS
-
-  /* Set to 1 */
-  exact_p = 0;
-  
-  /* Start with the first non-scalable font in the list.  */
-  for (i = 0; i < nfonts; ++i)
-    if (!font_scalable_p (fonts + i))
-      break;
-
-  /* Find the best match among the non-scalable fonts.  */
-  if (i < nfonts)
-    {
-      best = fonts + i;
-      
-      for (i = 1; i < nfonts; ++i)
-	if (!font_scalable_p (fonts + i)
-	    && better_font_p (specified, fonts + i, best, 1))
-	  {
-	    best = fonts + i;
-
-	    exact_p = exact_face_match_p (specified, best);
-	    if (exact_p)
-	      break;
-	  }
-      
-    }
-  else
-    best = NULL;
-
-  /* Unless we found an exact match among non-scalable fonts, see if
-     we can find a better match among scalable fonts.  */
-  if (!exact_p)
-    {
-      /* A scalable font is better if
-
-	 1. its weight, slant, swidth attributes are better, or.
-	 
-	 2. the best non-scalable font doesn't have the required
-	 point size, and the scalable fonts weight, slant, swidth
-	 isn't worse.  */
-
-      int non_scalable_has_exact_height_p;
-
-      if (best && best->numeric[XLFD_POINT_SIZE] == pt)
-	non_scalable_has_exact_height_p = 1;
-      else
-	non_scalable_has_exact_height_p = 0;
-      
-      for (i = 0; i < nfonts; ++i)
-	if (font_scalable_p (fonts + i))
-	  {
-	    if (best == NULL
-		|| better_font_p (specified, fonts + i, best, 0)
-		|| (!non_scalable_has_exact_height_p
-		    && !better_font_p (specified, best, fonts + i, 0)))
-	      best = fonts + i;
-	  }
-    }
-
-  if (font_scalable_p (best))
-    font_name = build_scalable_font_name (f, best, pt);
-  else
-    font_name = build_font_name (best);
-  
-#else /* !SCALABLE_FONTS */
-  
-  /* Find the best non-scalable font.  */
-  best = fonts;
-  
-  for (i = 1; i < nfonts; ++i)
-    {
-      xassert (!font_scalable_p (fonts + i));
-      if (better_font_p (specified, fonts + i, best, 1))
-	best = fonts + i;
-    }
-  
-  font_name = build_font_name (best);
-
-#endif /* !SCALABLE_FONTS */
-
-  /* Free font_name structures.  */
-  free_font_names (fonts, nfonts);
-  
-  return font_name;
-}
-
-
-/* Try to get a list of fonts on frame F with font family FAMILY and
-   registry/encoding REGISTRY.  Return in *FONTS a pointer to a vector
-   of font_name structures for the fonts matched.  Value is the number
-   of fonts found.  */
-
-static int
-try_font_list (f, attrs, pattern, family, registry, fonts)
-     struct frame *f;
-     Lisp_Object *attrs;
-     char *pattern, *family, *registry;
-     struct font_name **fonts;
-{
-  int nfonts;
-
-  if (family == NULL)
-    family = LSTRDUPA (attrs[LFACE_FAMILY_INDEX]);
-  
-  nfonts = font_list (f, pattern, family, registry, fonts);
-  
-  if (nfonts == 0)
-    {
-      Lisp_Object alter;
-	  
-      /* Try alternative font families from
-	 Vface_alternative_font_family_alist.  */
-      alter = Fassoc (build_string (family),
-		      Vface_alternative_font_family_alist);
-      if (CONSP (alter))
-	for (alter = XCDR (alter);
-	     CONSP (alter) && nfonts == 0;
-	     alter = XCDR (alter))
-	  {
-	    if (STRINGP (XCAR (alter)))
-	      {
-		family = LSTRDUPA (XCAR (alter));
-		nfonts = font_list (f, NULL, family, registry, fonts);
-	      }
-	  }
-	  
-      /* Try font family of the default face or "fixed".  */
-      if (nfonts == 0)
-	{
-	  struct face *dflt = FACE_FROM_ID (f, DEFAULT_FACE_ID);
-	  if (dflt)
-	    family = LSTRDUPA (dflt->lface[LFACE_FAMILY_INDEX]);
-	  else
-	    family = "fixed";
-	  nfonts = font_list (f, NULL, family, registry, fonts);
-	}
-	  
-      /* Try any family with the given registry.  */
-      if (nfonts == 0)
-	nfonts = font_list (f, NULL, "*", registry, fonts);
-    }
-
-  return nfonts;
-}
-
-  
-/* Return the registry and encoding pattern that fonts for CHARSET
-   should match.  Value is allocated from the heap.  */
-
-char *
-x_charset_registry (charset)
-     int charset;
-{
-  Lisp_Object prop, charset_plist;
-  char *registry;
-
-  /* Get registry and encoding from the charset's plist.  */
-  charset_plist = CHARSET_TABLE_INFO (charset, CHARSET_PLIST_IDX);
-  prop = Fplist_get (charset_plist, Qx_charset_registry);
-  
-  if (STRINGP (prop))
-    {
-      if (index (XSTRING (prop)->data, '-'))
-	registry = xstrdup (XSTRING (prop)->data);
-      else
-	{
-	  /* If registry doesn't contain a `-', make it a pattern.  */
-	  registry = (char *) xmalloc (STRING_BYTES (XSTRING (prop)) + 5);
-	  strcpy (registry, XSTRING (prop)->data);
-	  strcat (registry, "*-*");
-	}
-    }
-  else if (STRINGP (Vface_default_registry))
-    registry = xstrdup (XSTRING (Vface_default_registry)->data);
-  else
-    registry = xstrdup ("iso8859-1");
-
-  return registry;
-}
-
-
-/* Return the fontset id of the fontset name or alias name given by
-   the family attribute of ATTRS on frame F.  Value is -1 if the
-   family attribute of ATTRS doesn't name a fontset.  */
-
-static int
-face_fontset (f, attrs)
-     struct frame *f;
-     Lisp_Object *attrs;
-{
-  Lisp_Object name = attrs[LFACE_FAMILY_INDEX];
-  int fontset;
-  
-  name = Fquery_fontset (name, Qnil);
-  if (NILP (name))
-    fontset = -1;
-  else
-    fontset = fs_query_fontset (f, XSTRING (name)->data);
-
-  return fontset;
-}
-
-
-/* Get the font to use for the face realizing the fully-specified Lisp
-   face ATTRS for charset CHARSET on frame F.  CHARSET < 0 means
-   unibyte text; UNIBYTE_REGISTRY is the registry and encoding to use
-   in this case.  Value is the font name which is allocated from the
-   heap (which means that it must be freed eventually).  */
-
-static char *
-choose_face_font (f, attrs, charset, unibyte_registry)
-     struct frame *f;
-     Lisp_Object *attrs;
-     int charset;
-     Lisp_Object unibyte_registry;
-{
-  struct font_name *fonts;
-  int nfonts;
-  char *registry;
-
-  /* ATTRS must be fully-specified.  */
-  xassert (lface_fully_specified_p (attrs));
-
-  if (STRINGP (unibyte_registry))
-    registry = xstrdup (XSTRING (unibyte_registry)->data);
-  else
-    registry = x_charset_registry (charset);
-
-  nfonts = try_font_list (f, attrs, NULL, NULL, registry, &fonts);
-  xfree (registry);
-  return best_matching_font (f, attrs, fonts, nfonts);
-}
-
-
-/* Choose a font to use on frame F to display CHARSET using FONTSET
-   with Lisp face attributes specified by ATTRS. CHARSET may be any
-   valid charset. CHARSET < 0 means unibyte text. If the fontset
-   doesn't contain a font pattern for charset, use the pattern for
-   CHARSET_ASCII. Value is the font name which is allocated from the
-   heap and must be freed by the caller. */
-
-static char *
-choose_face_fontset_font (f, attrs, fontset, charset)
-     struct frame *f;
-     Lisp_Object *attrs;
-     int fontset, charset;
-{
-  char *pattern;
-  char *font_name = NULL;
-  struct fontset_info *fontset_info;
-  struct font_name *fonts;
-  int nfonts;
-  
-  xassert (fontset >= 0 && fontset < FRAME_FONTSET_DATA (f)->n_fontsets);
-
-  /* For unibyte text, use the ASCII font of the fontset.  Using the
-     ASCII font seems to be the most reasonable thing we can do in
-     this case.  */
-  if (charset < 0)
-    charset = CHARSET_ASCII;
-
-  /* Get the font name pattern to use for CHARSET from the fontset.  */
-  fontset_info = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
-  pattern = fontset_info->fontname[charset];
-  if (!pattern)
-    pattern = fontset_info->fontname[CHARSET_ASCII];
-  xassert (pattern);
-
-  /* Get a list of fonts matching that pattern and choose the 
-     best match for the specified face attributes from it.  */
-  nfonts = try_font_list (f, attrs, pattern, NULL, NULL, &fonts);
-  font_name = best_matching_font (f, attrs, fonts, nfonts);
-  return font_name;
-}
-
-#endif /* HAVE_WINDOW_SYSTEM */
-
-
-
-/***********************************************************************
-			   Face Realization
- ***********************************************************************/
-
-/* Realize basic faces on frame F.  Value is zero if frame parameters
-   of F don't contain enough information needed to realize the default
-   face.  */
-
-static int
-realize_basic_faces (f)
-     struct frame *f;
-{
-  int success_p = 0;
-  
-  if (realize_default_face (f))
-    {
-      realize_named_face (f, Qmode_line, MODE_LINE_FACE_ID);
-      realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID);
-      realize_named_face (f, Qfringe, BITMAP_AREA_FACE_ID);
-      realize_named_face (f, Qheader_line, HEADER_LINE_FACE_ID);
-      realize_named_face (f, Qscroll_bar, SCROLL_BAR_FACE_ID);
-      realize_named_face (f, Qborder, BORDER_FACE_ID);
-      realize_named_face (f, Qcursor, CURSOR_FACE_ID);
-      realize_named_face (f, Qmouse, MOUSE_FACE_ID);
-      realize_named_face (f, Qmenu, MENU_FACE_ID);
-      success_p = 1;
-    }
-
-  return success_p;
-}
-
-
-/* Realize the default face on frame F.  If the face is not fully
-   specified, make it fully-specified.  Attributes of the default face
-   that are not explicitly specified are taken from frame parameters.  */
-
-static int
-realize_default_face (f)
-     struct frame *f;
-{
-  struct face_cache *c = FRAME_FACE_CACHE (f);
-  Lisp_Object lface;
-  Lisp_Object attrs[LFACE_VECTOR_SIZE];
-  Lisp_Object unibyte_registry;
-  Lisp_Object frame_font;
-  struct face *face;
-  int fontset;
-
-  /* If the `default' face is not yet known, create it.  */
-  lface = lface_from_face_name (f, Qdefault, 0);
-  if (NILP (lface))
-    {
-      Lisp_Object frame;
-      XSETFRAME (frame, f);
-      lface = Finternal_make_lisp_face (Qdefault, frame);
-    }
-
-#ifdef HAVE_WINDOW_SYSTEM
-  if (FRAME_WINDOW_P (f))
-    {
-      /* Set frame_font to the value of the `font' frame parameter.  */
-      frame_font = Fassq (Qfont, f->param_alist);
-      xassert (CONSP (frame_font) && STRINGP (XCDR (frame_font)));
-      frame_font = XCDR (frame_font);
-  
-      fontset = fs_query_fontset (f, XSTRING (frame_font)->data);
-      if (fontset >= 0)
-	{
-	  /* If frame_font is a fontset name, don't use that for
-	     determining font-related attributes of the default face
-	     because it is just an artificial name.  Use the ASCII font of
-	     the fontset, instead.  */
-	  struct font_info *font_info;
-	  struct font_name font;
-
-	  BLOCK_INPUT;
-	  font_info = FS_LOAD_FONT (f, FRAME_W32_FONT_TABLE (f), CHARSET_ASCII,
-				    NULL, fontset);
-	  UNBLOCK_INPUT;
-	  
-	  /* Set weight etc. from the ASCII font.  */
-	  if (!set_lface_from_font_name (f, lface, font_info->full_name, 0, 0))
-	    return 0;
-	  
-	  /* Remember registry and encoding of the frame font.  */
-	  unibyte_registry = deduce_unibyte_registry (f, font_info->full_name);
-	  if (STRINGP (unibyte_registry))
-	    Vface_default_registry = unibyte_registry;
-	  else
-	    Vface_default_registry = build_string ("iso8859-1");
-	  
-	  /* But set the family to the fontset alias name.  Implementation
-	     note: When a font is passed to Emacs via `-fn FONT', a
-	     fontset is created in `x-win.el' whose name ends in
-	     `fontset-startup'.  This fontset has an alias name that is
-	     equal to frame_font.  */
-	  xassert (STRINGP (frame_font));
-	  font.name = LSTRDUPA (frame_font);
-	  
-	  if (!split_font_name (f, &font, 1)
-	      || xstricmp (font.fields[XLFD_REGISTRY], "fontset") != 0
-	      || xstricmp (font.fields[XLFD_ENCODING], "startup") != 0)
-	    LFACE_FAMILY (lface) = frame_font;
-	}
-      else
-	{
-	  /* Frame parameters contain a real font.  Fill default face
-	     attributes from that font.  */
-	  if (!set_lface_from_font_name (f, lface,
-					 XSTRING (frame_font)->data, 0, 0))
-	    return 0;
-	  
-	  /* Remember registry and encoding of the frame font.  */
-	  unibyte_registry
-	    = deduce_unibyte_registry (f, XSTRING (frame_font)->data);
-	  if (STRINGP (unibyte_registry))
-	    Vface_default_registry = unibyte_registry;
-	  else
-	    Vface_default_registry = build_string ("iso8859-1");
-	}
-    }
-#endif /* HAVE_WINDOW_SYSTEM */
-
-  if (!FRAME_WINDOW_P (f))
-    {
-      LFACE_FAMILY (lface) = build_string ("default");
-      LFACE_SWIDTH (lface) = Qnormal;
-      LFACE_HEIGHT (lface) = make_number (1);
-      LFACE_WEIGHT (lface) = Qnormal;
-      LFACE_SLANT (lface) = Qnormal;
-    }
-      
-  if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
-    LFACE_UNDERLINE (lface) = Qnil;
-      
-  if (UNSPECIFIEDP (LFACE_OVERLINE (lface)))
-    LFACE_OVERLINE (lface) = Qnil;
-      
-  if (UNSPECIFIEDP (LFACE_STRIKE_THROUGH (lface)))
-    LFACE_STRIKE_THROUGH (lface) = Qnil;
-      
-  if (UNSPECIFIEDP (LFACE_BOX (lface)))
-    LFACE_BOX (lface) = Qnil;
-      
-  if (UNSPECIFIEDP (LFACE_INVERSE (lface)))
-    LFACE_INVERSE (lface) = Qnil;
-      
-  if (UNSPECIFIEDP (LFACE_FOREGROUND (lface)))
-    {
-      /* This function is called so early that colors are not yet
-	 set in the frame parameter list.  */
-      Lisp_Object color = Fassq (Qforeground_color, f->param_alist);
-      
-      if (CONSP (color) && STRINGP (XCDR (color)))
-	LFACE_FOREGROUND (lface) = XCDR (color);
-      else if (FRAME_WINDOW_P (f))
-	return 0;
-      else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
-	LFACE_FOREGROUND (lface) = build_string (unspecified_fg);
-      else
-	abort ();
-    }
-  
-  if (UNSPECIFIEDP (LFACE_BACKGROUND (lface)))
-    {
-      /* This function is called so early that colors are not yet
-	 set in the frame parameter list.  */
-      Lisp_Object color = Fassq (Qbackground_color, f->param_alist);
-      if (CONSP (color) && STRINGP (XCDR (color)))
-	LFACE_BACKGROUND (lface) = XCDR (color);
-      else if (FRAME_WINDOW_P (f))
-	return 0;
-      else if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
-	LFACE_BACKGROUND (lface) = build_string (unspecified_bg);
-      else
-	abort ();
-    }
-  
-  if (UNSPECIFIEDP (LFACE_STIPPLE (lface)))
-    LFACE_STIPPLE (lface) = Qnil;
-
-  /* Realize the face; it must be fully-specified now.  */
-  xassert (lface_fully_specified_p (XVECTOR (lface)->contents));
-  check_lface (lface);
-  bcopy (XVECTOR (lface)->contents, attrs, sizeof attrs);
-  face = realize_face (c, attrs, CHARSET_ASCII);
-
-  /* Remove the former default face.  */
-  if (c->used > DEFAULT_FACE_ID)
-    {
-      struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
-      uncache_face (c, default_face);
-      free_realized_face (f, default_face);
-    }
-
-  /* Insert the new default face.  */
-  cache_face (c, face, lface_hash (attrs));
-  xassert (face->id == DEFAULT_FACE_ID);
-  return 1;
-}
-
-
-/* Realize basic faces other than the default face in face cache C.
-   SYMBOL is the face name, ID is the face id the realized face must
-   have.  The default face must have been realized already.  */
-
-static void
-realize_named_face (f, symbol, id)
-     struct frame *f;
-     Lisp_Object symbol;
-     int id;
-{
-  struct face_cache *c = FRAME_FACE_CACHE (f);
-  Lisp_Object lface = lface_from_face_name (f, symbol, 0);
-  Lisp_Object attrs[LFACE_VECTOR_SIZE];
-  Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE];
-  struct face *new_face;
-
-  /* The default face must exist and be fully specified.  */
-  get_lface_attributes (f, Qdefault, attrs, 1);
-  check_lface_attrs (attrs);
-  xassert (lface_fully_specified_p (attrs));
-
-  /* If SYMBOL isn't know as a face, create it.  */
-  if (NILP (lface))
-    {
-      Lisp_Object frame;
-      XSETFRAME (frame, f);
-      lface = Finternal_make_lisp_face (symbol, frame);
-    }
-
-  /* Merge SYMBOL's face with the default face.  */
-  get_lface_attributes (f, symbol, symbol_attrs, 1);
-  merge_face_vectors (symbol_attrs, attrs);
-
-  /* Realize the face.  */
-  new_face = realize_face (c, attrs, CHARSET_ASCII);
-
-  /* Remove the former face.  */
-  if (c->used > id)
-    {
-      struct face *old_face = c->faces_by_id[id];
-      uncache_face (c, old_face);
-      free_realized_face (f, old_face);
-    }
-
-  /* Insert the new face.  */
-  cache_face (c, new_face, lface_hash (attrs));
-  xassert (new_face->id == id);
-}
-
-
-/* Realize the fully-specified face with attributes ATTRS in face
-   cache C for character set CHARSET or for unibyte text if CHARSET <
-   0.  Value is a pointer to the newly created realized face.  */
-
-static struct face *
-realize_face (c, attrs, charset)
-     struct face_cache *c;
-     Lisp_Object *attrs;
-     int charset;
-{
-  struct face *face;
-  
-  /* LFACE must be fully specified.  */
-  xassert (c != NULL);
-  check_lface_attrs (attrs);
-
-  if (FRAME_WINDOW_P (c->f))
-    face = realize_x_face (c, attrs, charset);
-  else if (FRAME_TERMCAP_P (c->f) || FRAME_MSDOS_P (c->f))
-    face = realize_tty_face (c, attrs, charset);
-  else
-    abort ();
-
-  return face;
-}
-
-
-/* Realize the fully-specified face with attributes ATTRS in face
-   cache C for character set CHARSET or for unibyte text if CHARSET <
-   0.  Do it for X frame C->f.  Value is a pointer to the newly
-   created realized face.  */
-
-static struct face *
-realize_x_face (c, attrs, charset)
-     struct face_cache *c;
-     Lisp_Object *attrs;
-     int charset;
-{
-#ifdef HAVE_WINDOW_SYSTEM
-  struct face *face, *default_face;
-  struct frame *f;
-  Lisp_Object stipple, overline, strike_through, box;
-  Lisp_Object unibyte_registry;
-  struct gcpro gcpro1;
-
-  xassert (FRAME_WINDOW_P (c->f));
-
-  /* If realizing a face for use in unibyte text, get the X registry
-     and encoding to use from Vface_default_registry.  */
-  if (charset < 0)
-    unibyte_registry = (STRINGP (Vface_default_registry)
-			? Vface_default_registry
-			: build_string ("iso8859-1"));
-  else
-    unibyte_registry = Qnil;
-  GCPRO1 (unibyte_registry);
-
-  /* Allocate a new realized face.  */
-  face = make_realized_face (attrs, charset, unibyte_registry);
-
-  f = c->f;
-  /* Determine the font to use.  Most of the time, the font will be
-     the same as the font of the default face, so try that first.  */
-  default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
-  if (default_face
-      && FACE_SUITABLE_FOR_CHARSET_P (default_face, charset)
-      && lface_same_font_attributes_p (default_face->lface, attrs))
-    {
-      face->font = default_face->font;
-      face->fontset = default_face->fontset;
-      face->font_info_id = default_face->font_info_id;
-      face->font_name = default_face->font_name;
-      face->registry = default_face->registry;
-    }
-  else if (charset >= 0)
-    {
-      /* For all charsets, we use our own font selection functions to
-	 choose a best matching font for the specified face
-	 attributes. If the face specifies a fontset alias name, the
-	 fontset determines the font name pattern, otherwise we
-	 construct a font pattern from face attributes and charset.  */
-      
-      char *font_name = NULL;
-      int fontset = face_fontset (f, attrs);
-
-      if (fontset < 0)
-	font_name = choose_face_font (f, attrs, charset, Qnil);
-      else
-	{
-	  font_name = choose_face_fontset_font (f, attrs, fontset, charset);
-	  fontset = -1;
-	}
-      
-      load_face_font_or_fontset (f, face, font_name, fontset);
-      xfree (font_name);
-    }
-  else
-    {
-      /* Unibyte case, and font is not equal to that of the default
-	 face.  UNIBYTE_REGISTRY is the X registry and encoding the
-	 font should have.  What is a reasonable thing to do if the
-	 user specified a fontset alias name for the face in this
-	 case?  We choose a font by taking the ASCII font of the
-	 fontset, but using UNIBYTE_REGISTRY for its registry and
-	 encoding.  */
-      
-      char *font_name = NULL;
-      int fontset = face_fontset (f, attrs);
-      
-      if (fontset < 0)
-	font_name = choose_face_font (f, attrs, charset, unibyte_registry);
-      else
-	font_name = choose_face_fontset_font (f, attrs, fontset, charset);
-      
-      load_face_font_or_fontset (f, face, font_name, -1);
-      xfree (font_name);
-    }
-
-  /* Load colors, and set remaining attributes.  */
-  
-  load_face_colors (f, face, attrs);
-
-  /* Set up box.  */
-  box = attrs[LFACE_BOX_INDEX];
-  if (STRINGP (box))
-    {
-      /* A simple box of line width 1 drawn in color given by
-	 the string.  */
-      face->box_color = load_color (f, face, attrs[LFACE_BOX_INDEX],
-				    LFACE_BOX_INDEX);
-      face->box = FACE_SIMPLE_BOX;
-      face->box_line_width = 1;
-    }
-  else if (INTEGERP (box))
-    {
-      /* Simple box of specified line width in foreground color of the
-         face.  */
-      xassert (XINT (box) > 0);
-      face->box = FACE_SIMPLE_BOX;
-      face->box_line_width = XFASTINT (box);
-      face->box_color = face->foreground;
-      face->box_color_defaulted_p = 1;
-    }
-  else if (CONSP (box))
-    {
-      /* `(:width WIDTH :color COLOR :shadow SHADOW)'.  SHADOW
-	 being one of `raised' or `sunken'.  */
-      face->box = FACE_SIMPLE_BOX;
-      face->box_color = face->foreground;
-      face->box_color_defaulted_p = 1;
-      face->box_line_width = 1;
-
-      while (CONSP (box))
-	{
-	  Lisp_Object keyword, value;
-
-	  keyword = XCAR (box);
-	  box = XCDR (box);
-
-	  if (!CONSP (box))
-	    break;
-	  value = XCAR (box);
-	  box = XCDR (box);
-
-	  if (EQ (keyword, QCline_width))
-	    {
-	      if (INTEGERP (value) && XINT (value) > 0)
-		face->box_line_width = XFASTINT (value);
-	    }
-	  else if (EQ (keyword, QCcolor))
-	    {
-	      if (STRINGP (value))
-		{
-		  face->box_color = load_color (f, face, value,
-						LFACE_BOX_INDEX);
-		  face->use_box_color_for_shadows_p = 1;
-		}
-	    }
-	  else if (EQ (keyword, QCstyle))
-	    {
-	      if (EQ (value, Qreleased_button))
-		face->box = FACE_RAISED_BOX;
-	      else if (EQ (value, Qpressed_button))
-		face->box = FACE_SUNKEN_BOX;
-	    }
-	}
-    }
-
-  /* Text underline, overline, strike-through.  */
-  
-  if (EQ (attrs[LFACE_UNDERLINE_INDEX], Qt))
-    { 
-      /* Use default color (same as foreground color).  */
-      face->underline_p = 1;
-      face->underline_defaulted_p = 1;
-      face->underline_color = 0;
-    }
-  else if (STRINGP (attrs[LFACE_UNDERLINE_INDEX]))
-    {
-      /* Use specified color.  */
-      face->underline_p = 1;
-      face->underline_defaulted_p = 0;
-      face->underline_color
-	= load_color (f, face, attrs[LFACE_UNDERLINE_INDEX],
-		      LFACE_UNDERLINE_INDEX);
-    }
-  else if (NILP (attrs[LFACE_UNDERLINE_INDEX]))
-    {
-      face->underline_p = 0;
-      face->underline_defaulted_p = 0;
-      face->underline_color = 0;
-    }
-
-  overline = attrs[LFACE_OVERLINE_INDEX];
-  if (STRINGP (overline))
-    {
-      face->overline_color
-	= load_color (f, face, attrs[LFACE_OVERLINE_INDEX],
-		      LFACE_OVERLINE_INDEX);
-      face->overline_p = 1;
-    }
-  else if (EQ (overline, Qt))
-    {
-      face->overline_color = face->foreground;
-      face->overline_color_defaulted_p = 1;
-      face->overline_p = 1;
-    }
-
-  strike_through = attrs[LFACE_STRIKE_THROUGH_INDEX];
-  if (STRINGP (strike_through))
-    {
-      face->strike_through_color
-	= load_color (f, face, attrs[LFACE_STRIKE_THROUGH_INDEX],
-		      LFACE_STRIKE_THROUGH_INDEX);
-      face->strike_through_p = 1;
-    }
-  else if (EQ (strike_through, Qt))
-    {
-      face->strike_through_color = face->foreground;
-      face->strike_through_color_defaulted_p = 1;
-      face->strike_through_p = 1;
-    }
-
-  stipple = attrs[LFACE_STIPPLE_INDEX];
-  if (!NILP (stipple))
-    face->stipple = load_pixmap (f, stipple, &face->pixmap_w, &face->pixmap_h);
-
-  UNGCPRO;
-  xassert (face->fontset < 0);
-  xassert (FACE_SUITABLE_FOR_CHARSET_P (face, charset));
-  return face;
-#endif /* HAVE_WINDOW_SYSTEM */
-}
-
-
-/* Realize the fully-specified face with attributes ATTRS in face
-   cache C for character set CHARSET or for unibyte text if CHARSET <
-   0.  Do it for TTY frame C->f.  Value is a pointer to the newly
-   created realized face.  */
-
-static struct face *
-realize_tty_face (c, attrs, charset)
-     struct face_cache *c;
-     Lisp_Object *attrs;
-     int charset;
-{
-  struct face *face;
-  int weight, slant;
-  Lisp_Object color;
-  Lisp_Object tty_defined_color_alist =
-    Fsymbol_value (intern ("tty-defined-color-alist"));
-  Lisp_Object tty_color_alist = intern ("tty-color-alist");
-  Lisp_Object frame;
-  int face_colors_defaulted = 0;
-
-  /* Frame must be a termcap frame.  */
-  xassert (FRAME_TERMCAP_P (c->f) || FRAME_MSDOS_P (c->f));
-  
-  /* Allocate a new realized face.  */
-  face = make_realized_face (attrs, charset, Qnil);
-  face->font_name = FRAME_MSDOS_P (c->f) ? "ms-dos" : "tty";
-
-  /* Map face attributes to TTY appearances.  We map slant to 
-     dimmed text because we want italic text to appear differently
-     and because dimmed text is probably used infrequently.  */
-  weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
-  slant = face_numeric_slant (attrs[LFACE_SLANT_INDEX]);
-
-  if (weight > XLFD_WEIGHT_MEDIUM)
-    face->tty_bold_p = 1;
-  if (weight < XLFD_WEIGHT_MEDIUM || slant != XLFD_SLANT_ROMAN)
-    face->tty_dim_p = 1;
-  if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
-    face->tty_underline_p = 1;
-  if (!NILP (attrs[LFACE_INVERSE_INDEX]))
-    face->tty_reverse_p = 1;
-
-  /* Map color names to color indices.  */
-  face->foreground = FACE_TTY_DEFAULT_FG_COLOR;
-  face->background = FACE_TTY_DEFAULT_BG_COLOR;
-
-  XSETFRAME (frame, c->f);
-  color = attrs[LFACE_FOREGROUND_INDEX];
-  if (STRINGP (color)
-      && XSTRING (color)->size
-      && !NILP (tty_defined_color_alist)
-      && (color = Fassoc (color, call1 (tty_color_alist, frame)),
-	  CONSP (color)))
-    /* Associations in tty-defined-color-alist are of the form
-       (NAME INDEX R G B).  We need the INDEX part.  */
-    face->foreground = XINT (XCAR (XCDR (color)));
-
-  if (face->foreground == FACE_TTY_DEFAULT_FG_COLOR
-      && STRINGP (attrs[LFACE_FOREGROUND_INDEX]))
-    {
-      face->foreground = load_color (c->f, face,
-				     attrs[LFACE_FOREGROUND_INDEX],
-				     LFACE_FOREGROUND_INDEX);
-
-#if defined (MSDOS) || defined (WINDOWSNT)
-      /* If the foreground of the default face is the default color,
-	 use the foreground color defined by the frame.  */
-#ifdef MSDOS
-      if (FRAME_MSDOS_P (c->f))
-        {
-#endif /* MSDOS */
-
-      if (face->foreground == FACE_TTY_DEFAULT_FG_COLOR
-          || face->foreground == FACE_TTY_DEFAULT_COLOR)
-        {
-          face->foreground = FRAME_FOREGROUND_PIXEL (c->f);
-          attrs[LFACE_FOREGROUND_INDEX] =
-            tty_color_name (c->f, face->foreground);
-          face_colors_defaulted = 1;
-        }
-      else if (face->foreground == FACE_TTY_DEFAULT_BG_COLOR)
-        {
-          face->foreground = FRAME_BACKGROUND_PIXEL (c->f);
-          attrs[LFACE_FOREGROUND_INDEX] =
-            tty_color_name (c->f, face->foreground);
-          face_colors_defaulted = 1;
-        }
-#ifdef MSDOS
-    }
-#endif /* MSDOS */
-#endif /* MSDOS or WINDOWSNT */
-    }
-
-  color = attrs[LFACE_BACKGROUND_INDEX];
-  if (STRINGP (color)
-      && XSTRING (color)->size
-      && !NILP (tty_defined_color_alist)
-      && (color = Fassoc (color, call1 (tty_color_alist, frame)),
-	  CONSP (color)))
-    /* Associations in tty-defined-color-alist are of the form
-       (NAME INDEX R G B).  We need the INDEX part.  */
-    face->background = XINT (XCAR (XCDR (color)));
-
-  if (face->background == FACE_TTY_DEFAULT_BG_COLOR
-      && STRINGP (attrs[LFACE_BACKGROUND_INDEX]))
-    {
-      face->background = load_color (c->f, face,
-				     attrs[LFACE_BACKGROUND_INDEX],
-				     LFACE_BACKGROUND_INDEX);
-#if defined (MSDOS) || defined (WINDOWSNT)
-      /* If the background of the default face is the default color,
-	 use the background color defined by the frame.  */
-#ifdef MSDOS
-      if (FRAME_MSDOS_P (c->f))
-	{
-#endif /* MSDOS */
-
-      if (face->background == FACE_TTY_DEFAULT_BG_COLOR
-          || face->background == FACE_TTY_DEFAULT_COLOR)
-        {
-          face->background = FRAME_BACKGROUND_PIXEL (c->f);
-          attrs[LFACE_BACKGROUND_INDEX] =
-            tty_color_name (c->f, face->background);
-          face_colors_defaulted = 1;
-        }
-      else if (face->background == FACE_TTY_DEFAULT_FG_COLOR)
-        {
-          face->background = FRAME_FOREGROUND_PIXEL (c->f);
-          attrs[LFACE_BACKGROUND_INDEX] =
-            tty_color_name (c->f, face->background);
-          face_colors_defaulted = 1;
-        }
-#ifdef MSDOS
-    }
-#endif /* MSDOS */
-#endif /* MSDOS or WINDOWSNT */
-    }
-
-  /* Swap colors if face is inverse-video.  If the colors are taken
-     from the frame colors, they are already inverted, since the
-     frame-creation function calls x-handle-reverse-video.  */
-  if (face->tty_reverse_p && !face_colors_defaulted)
-    {
-      unsigned long tem = face->foreground;
-
-      face->foreground = face->background;
-      face->background = tem;
-    }
-
-  return face;
-}
-
-
-
-/***********************************************************************
-			   Computing Faces
- ***********************************************************************/
-
-/* Return the ID of the face to use to display character CH with face
-   property PROP on frame F in current_buffer.  */
-
-int
-compute_char_face (f, ch, prop)
-     struct frame *f;
-     int ch;
-     Lisp_Object prop;
-{
-  int face_id;
-  int charset = (NILP (current_buffer->enable_multibyte_characters)
-		 ? -1
-		 : CHAR_CHARSET (ch));
-  
-  if (NILP (prop))
-    face_id = FACE_FOR_CHARSET (f, DEFAULT_FACE_ID, charset);
-  else
-    {
-      Lisp_Object attrs[LFACE_VECTOR_SIZE];
-      struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
-      bcopy (default_face->lface, attrs, sizeof attrs);
-      merge_face_vector_with_property (f, attrs, prop);
-      face_id = lookup_face (f, attrs, charset);
-    }
-
-  return face_id;
-}
-
-
-/* Return the face ID associated with buffer position POS for
-   displaying ASCII characters.  Return in *ENDPTR the position at
-   which a different face is needed, as far as text properties and
-   overlays are concerned.  W is a window displaying current_buffer.
-
-   REGION_BEG, REGION_END delimit the region, so it can be
-   highlighted.
-
-   LIMIT is a position not to scan beyond.  That is to limit the time
-   this function can take.
-
-   If MOUSE is non-zero, use the character's mouse-face, not its face.
-
-   The face returned is suitable for displaying CHARSET_ASCII if
-   current_buffer->enable_multibyte_characters is non-nil.  Otherwise,
-   the face is suitable for displaying unibyte text.  */
-
-int
-face_at_buffer_position (w, pos, region_beg, region_end,
-			 endptr, limit, mouse)
-     struct window *w;
-     int pos;
-     int region_beg, region_end;
-     int *endptr;
-     int limit;
-     int mouse;
-{
-  struct frame *f = XFRAME (w->frame);
-  Lisp_Object attrs[LFACE_VECTOR_SIZE];
-  Lisp_Object prop, position;
-  int i, noverlays;
-  Lisp_Object *overlay_vec;
-  Lisp_Object frame;
-  int endpos;
-  Lisp_Object propname = mouse ? Qmouse_face : Qface;
-  Lisp_Object limit1, end;
-  struct face *default_face;
-  int multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
-
-  /* W must display the current buffer.  We could write this function
-     to use the frame and buffer of W, but right now it doesn't.  */
-  /* xassert (XBUFFER (w->buffer) == current_buffer); */
-
-  XSETFRAME (frame, f);
-  XSETFASTINT (position, pos);
-
-  endpos = ZV;
-  if (pos < region_beg && region_beg < endpos)
-    endpos = region_beg;
-
-  /* Get the `face' or `mouse_face' text property at POS, and
-     determine the next position at which the property changes.  */
-  prop = Fget_text_property (position, propname, w->buffer);
-  XSETFASTINT (limit1, (limit < endpos ? limit : endpos));
-  end = Fnext_single_property_change (position, propname, w->buffer, limit1);
-  if (INTEGERP (end))
-    endpos = XINT (end);
-
-  /* Look at properties from overlays.  */
-  {
-    int next_overlay;
-    int len;
-
-    /* First try with room for 40 overlays.  */
-    len = 40;
-    overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
-    noverlays = overlays_at (pos, 0, &overlay_vec, &len,
-			     &next_overlay, NULL);
-
-    /* If there are more than 40, make enough space for all, and try
-       again. */
-    if (noverlays > len)
-      {
-	len = noverlays;
-	overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
-	noverlays = overlays_at (pos, 0, &overlay_vec, &len,
-				 &next_overlay, NULL);
-      }
-
-    if (next_overlay < endpos)
-      endpos = next_overlay;
-  }
-
-  *endptr = endpos;
-
-  default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
-
-  /* Optimize common cases where we can use the default face.  */
-  if (noverlays == 0
-      && NILP (prop)
-      && !(pos >= region_beg && pos < region_end)
-      && (multibyte_p
-	  || !FRAME_WINDOW_P (f)
-	  || FACE_SUITABLE_FOR_CHARSET_P (default_face, -1)))
-    return DEFAULT_FACE_ID;
-
-  /* Begin with attributes from the default face.  */
-  bcopy (default_face->lface, attrs, sizeof attrs);
-
-  /* Merge in attributes specified via text properties.  */
-  if (!NILP (prop))
-    merge_face_vector_with_property (f, attrs, prop);
-
-  /* Now merge the overlay data.  */
-  noverlays = sort_overlays (overlay_vec, noverlays, w);
-  for (i = 0; i < noverlays; i++)
-    {
-      Lisp_Object oend;
-      int oendpos;
-
-      prop = Foverlay_get (overlay_vec[i], propname);
-      if (!NILP (prop))
-	merge_face_vector_with_property (f, attrs, prop);
-
-      oend = OVERLAY_END (overlay_vec[i]);
-      oendpos = OVERLAY_POSITION (oend);
-      if (oendpos < endpos)
-	endpos = oendpos;
-    }
-
-  /* If in the region, merge in the region face.  */
-  if (pos >= region_beg && pos < region_end)
-    {
-      Lisp_Object region_face = lface_from_face_name (f, Qregion, 0);
-      merge_face_vectors (XVECTOR (region_face)->contents, attrs);
- 
-      if (region_end < endpos)
-	endpos = region_end;
-     }
-
-  *endptr = endpos;
-
-  /* Look up a realized face with the given face attributes,
-     or realize a new one.  Charset is ignored for tty frames.  */
-  return lookup_face (f, attrs, multibyte_p ? CHARSET_ASCII : -1);
-}
-
-
-/* Compute the face at character position POS in Lisp string STRING on
-   window W, for charset CHARSET_ASCII.
-
-   If STRING is an overlay string, it comes from position BUFPOS in
-   current_buffer, otherwise BUFPOS is zero to indicate that STRING is
-   not an overlay string.  W must display the current buffer.
-   REGION_BEG and REGION_END give the start and end positions of the
-   region; both are -1 if no region is visible.  BASE_FACE_ID is the
-   id of the basic face to merge with.  It is usually equal to
-   DEFAULT_FACE_ID but can be MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID
-   for strings displayed in the mode or top line.
-   
-   Set *ENDPTR to the next position where to check for faces in
-   STRING; -1 if the face is constant from POS to the end of the
-   string.
-
-   Value is the id of the face to use.  The face returned is suitable
-   for displaying CHARSET_ASCII if STRING is multibyte.  Otherwise,
-   the face is suitable for displaying unibyte text.  */
-
-int
-face_at_string_position (w, string, pos, bufpos, region_beg,
-			 region_end, endptr, base_face_id)
-     struct window *w;
-     Lisp_Object string;
-     int pos, bufpos;
-     int region_beg, region_end;
-     int *endptr;
-     enum face_id base_face_id;
-{
-  Lisp_Object prop, position, end, limit;
-  struct frame *f = XFRAME (WINDOW_FRAME (w));
-  Lisp_Object attrs[LFACE_VECTOR_SIZE];
-  struct face *base_face;
-  int multibyte_p = STRING_MULTIBYTE (string);
-
-  /* Get the value of the face property at the current position within
-     STRING.  Value is nil if there is no face property.  */
-  XSETFASTINT (position, pos);
-  prop = Fget_text_property (position, Qface, string);
-
-  /* Get the next position at which to check for faces.  Value of end
-     is nil if face is constant all the way to the end of the string.
-     Otherwise it is a string position where to check faces next.
-     Limit is the maximum position up to which to check for property
-     changes in Fnext_single_property_change.  Strings are usually
-     short, so set the limit to the end of the string.  */
-  XSETFASTINT (limit, XSTRING (string)->size);
-  end = Fnext_single_property_change (position, Qface, string, limit);
-  if (INTEGERP (end))
-    *endptr = XFASTINT (end);
-  else
-    *endptr = -1;
-
-  base_face = FACE_FROM_ID (f, base_face_id);
-  xassert (base_face);
-
-  /* Optimize the default case that there is no face property and we
-     are not in the region.  */
-  if (NILP (prop)
-      && (base_face_id != DEFAULT_FACE_ID
-	  /* BUFPOS <= 0 means STRING is not an overlay string, so
-	     that the region doesn't have to be taken into account.  */
-	  || bufpos <= 0
-	  || bufpos < region_beg
-	  || bufpos >= region_end)
-      && (multibyte_p
-	  /* We can't realize faces for different charsets differently
-	     if we don't have fonts, so we can stop here if not working
-	     on a window-system frame.  */
-	  || !FRAME_WINDOW_P (f)
-	  || FACE_SUITABLE_FOR_CHARSET_P (base_face, -1)))
-    return base_face->id;
-
-  /* Begin with attributes from the base face.  */
-  bcopy (base_face->lface, attrs, sizeof attrs);
-
-  /* Merge in attributes specified via text properties.  */
-  if (!NILP (prop))
-    merge_face_vector_with_property (f, attrs, prop);
-
-  /* If in the region, merge in the region face.  */
-  if (bufpos
-      && bufpos >= region_beg
-      && bufpos < region_end)
-    {
-      Lisp_Object region_face = lface_from_face_name (f, Qregion, 0);
-      merge_face_vectors (XVECTOR (region_face)->contents, attrs);
-    }
-
-  /* Look up a realized face with the given face attributes,
-     or realize a new one.  */
-  return lookup_face (f, attrs, multibyte_p ? CHARSET_ASCII : -1);
-}
-
-
-
-/***********************************************************************
-				Tests
- ***********************************************************************/
-
-#if GLYPH_DEBUG
-
-/* Print the contents of the realized face FACE to stderr.  */
-
-static void
-dump_realized_face (face)
-     struct face *face;
-{
-  fprintf (stderr, "ID: %d\n", face->id);
-#ifdef HAVE_WINDOW_SYSTEM
-  fprintf (stderr, "gc: %d\n", (int) face->gc);
-#endif
-  fprintf (stderr, "foreground: 0x%lx (%s)\n",
-	   face->foreground,
-	   XSTRING (face->lface[LFACE_FOREGROUND_INDEX])->data);
-  fprintf (stderr, "background: 0x%lx (%s)\n",
-	   face->background,
-	   XSTRING (face->lface[LFACE_BACKGROUND_INDEX])->data);
-  fprintf (stderr, "font_name: %s (%s)\n",
-	   face->font_name,
-	   XSTRING (face->lface[LFACE_FAMILY_INDEX])->data);
-#ifdef HAVE_WINDOW_SYSTEM
-  fprintf (stderr, "font = %p\n", face->font);
-#endif
-  fprintf (stderr, "font_info_id = %d\n", face->font_info_id);
-  fprintf (stderr, "fontset: %d\n", face->fontset);
-  fprintf (stderr, "underline: %d (%s)\n",
-	   face->underline_p,
-	   XSTRING (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))->data);
-  fprintf (stderr, "hash: %d\n", face->hash);
-  fprintf (stderr, "charset: %d\n", face->charset);
-}
-
-
-DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, "")
-   (n)
-     Lisp_Object n;
-{
-  if (NILP (n))
-    {
-      int i;
-      
-      fprintf (stderr, "font selection order: ");
-      for (i = 0; i < DIM (font_sort_order); ++i)
-	fprintf (stderr, "%d ", font_sort_order[i]);
-      fprintf (stderr, "\n");
-
-      fprintf (stderr, "alternative fonts: ");
-      debug_print (Vface_alternative_font_family_alist);
-      fprintf (stderr, "\n");
-	
-      for (i = 0; i < FRAME_FACE_CACHE (SELECTED_FRAME ())->used; ++i)
-	Fdump_face (make_number (i));
-    }
-  else
-    {
-      struct face *face;
-      CHECK_NUMBER (n, 0);
-      face = FACE_FROM_ID (SELECTED_FRAME (), XINT (n));
-      if (face == NULL)
-	error ("Not a valid face");
-      dump_realized_face (face);
-    }
-  
-  return Qnil;
-}
-
-
-DEFUN ("show-face-resources", Fshow_face_resources, Sshow_face_resources,
-       0, 0, 0, "")
-  ()
-{
-  fprintf (stderr, "number of colors = %d\n", ncolors_allocated);
-  fprintf (stderr, "number of pixmaps = %d\n", npixmaps_allocated);
-  fprintf (stderr, "number of GCs = %d\n", ngcs);
-  return Qnil;
-}
-
-#endif /* GLYPH_DEBUG != 0 */
-
-
-
-/***********************************************************************
-			    Initialization
-***********************************************************************/
-
-void
-syms_of_w32faces ()
-{
-  Qface = intern ("face");
-  staticpro (&Qface);
-  Qbitmap_spec_p = intern ("bitmap-spec-p");
-  staticpro (&Qbitmap_spec_p);
-  Qframe_update_face_colors = intern ("frame-update-face-colors");
-  staticpro (&Qframe_update_face_colors);
-
-  /* Lisp face attribute keywords.  */
-  QCfamily = intern (":family");
-  staticpro (&QCfamily);
-  QCheight = intern (":height");
-  staticpro (&QCheight);
-  QCweight = intern (":weight");
-  staticpro (&QCweight);
-  QCslant = intern (":slant");
-  staticpro (&QCslant);
-  QCunderline = intern (":underline");
-  staticpro (&QCunderline);
-  QCinverse_video = intern (":inverse-video");
-  staticpro (&QCinverse_video); 
-  QCreverse_video = intern (":reverse-video");
-  staticpro (&QCreverse_video);
-  QCforeground = intern (":foreground");
-  staticpro (&QCforeground);
-  QCbackground = intern (":background");
-  staticpro (&QCbackground);
-  QCstipple = intern (":stipple");;
-  staticpro (&QCstipple);
-  QCwidth = intern (":width");
-  staticpro (&QCwidth);
-  QCfont = intern (":font");
-  staticpro (&QCfont);
-  QCbold = intern (":bold");
-  staticpro (&QCbold);
-  QCitalic = intern (":italic");
-  staticpro (&QCitalic);
-  QCoverline = intern (":overline");
-  staticpro (&QCoverline);
-  QCstrike_through = intern (":strike-through");
-  staticpro (&QCstrike_through);
-  QCbox = intern (":box");
-  staticpro (&QCbox);
-
-  /* Symbols used for Lisp face attribute values.  */
-  QCcolor = intern (":color");
-  staticpro (&QCcolor);
-  QCline_width = intern (":line-width");
-  staticpro (&QCline_width);
-  QCstyle = intern (":style");
-  staticpro (&QCstyle);
-  Qreleased_button = intern ("released-button");
-  staticpro (&Qreleased_button);
-  Qpressed_button = intern ("pressed-button");
-  staticpro (&Qpressed_button);
-  Qnormal = intern ("normal");
-  staticpro (&Qnormal);
-  Qultra_light = intern ("ultra-light");
-  staticpro (&Qultra_light);
-  Qextra_light = intern ("extra-light");
-  staticpro (&Qextra_light);
-  Qlight = intern ("light");
-  staticpro (&Qlight);
-  Qsemi_light = intern ("semi-light");
-  staticpro (&Qsemi_light);
-  Qsemi_bold = intern ("semi-bold");
-  staticpro (&Qsemi_bold);
-  Qbold = intern ("bold");
-  staticpro (&Qbold);
-  Qextra_bold = intern ("extra-bold");
-  staticpro (&Qextra_bold);
-  Qultra_bold = intern ("ultra-bold");
-  staticpro (&Qultra_bold);
-  Qoblique = intern ("oblique");
-  staticpro (&Qoblique);
-  Qitalic = intern ("italic");
-  staticpro (&Qitalic);
-  Qreverse_oblique = intern ("reverse-oblique");
-  staticpro (&Qreverse_oblique);
-  Qreverse_italic = intern ("reverse-italic");
-  staticpro (&Qreverse_italic);
-  Qultra_condensed = intern ("ultra-condensed");
-  staticpro (&Qultra_condensed);
-  Qextra_condensed = intern ("extra-condensed");
-  staticpro (&Qextra_condensed);
-  Qcondensed = intern ("condensed");
-  staticpro (&Qcondensed);
-  Qsemi_condensed = intern ("semi-condensed");
-  staticpro (&Qsemi_condensed);
-  Qsemi_expanded = intern ("semi-expanded");
-  staticpro (&Qsemi_expanded);
-  Qexpanded = intern ("expanded");
-  staticpro (&Qexpanded);
-  Qextra_expanded = intern ("extra-expanded");
-  staticpro (&Qextra_expanded);
-  Qultra_expanded = intern ("ultra-expanded");
-  staticpro (&Qultra_expanded);
-  Qbackground_color = intern ("background-color");
-  staticpro (&Qbackground_color);
-  Qforeground_color = intern ("foreground-color");
-  staticpro (&Qforeground_color);
-  Qunspecified = intern ("unspecified");
-  staticpro (&Qunspecified);
-
-  Qx_charset_registry = intern ("x-charset-registry");
-  staticpro (&Qx_charset_registry);
-  Qface_alias = intern ("face-alias");
-  staticpro (&Qface_alias);
-  Qdefault = intern ("default");
-  staticpro (&Qdefault);
-  Qtool_bar = intern ("tool-bar");
-  staticpro (&Qtool_bar);
-  Qregion = intern ("region");
-  staticpro (&Qregion);
-  Qfringe = intern ("fringe");
-  staticpro (&Qfringe);
-  Qheader_line = intern ("header-line");
-  staticpro (&Qheader_line);
-  Qscroll_bar = intern ("scroll-bar");
-  staticpro (&Qscroll_bar);
-  Qmenu = intern ("menu");
-  staticpro (&Qmenu);
-  Qcursor = intern ("cursor");
-  staticpro (&Qcursor);
-  Qborder = intern ("border");
-  staticpro (&Qborder);
-  Qmouse = intern ("mouse");
-  staticpro (&Qmouse);
-  Qtty_color_desc = intern ("tty-color-desc");
-  staticpro (&Qtty_color_desc);
-  Qtty_color_by_index = intern ("tty-color-by-index");
-  staticpro (&Qtty_color_by_index);
-
-  defsubr (&Sinternal_make_lisp_face);
-  defsubr (&Sinternal_lisp_face_p);
-  defsubr (&Sinternal_set_lisp_face_attribute);
-#ifdef HAVE_WINDOW_SYSTEM
-  defsubr (&Sinternal_set_lisp_face_attribute_from_resource);
-#endif
-  defsubr (&Scolor_gray_p);
-  defsubr (&Scolor_supported_p);
-  defsubr (&Sinternal_get_lisp_face_attribute);
-  defsubr (&Sinternal_lisp_face_attribute_values);
-  defsubr (&Sinternal_lisp_face_equal_p);
-  defsubr (&Sinternal_lisp_face_empty_p);
-  defsubr (&Sinternal_copy_lisp_face);
-  defsubr (&Sinternal_merge_in_global_face);
-  defsubr (&Sface_font);
-  defsubr (&Sframe_face_alist);
-  defsubr (&Sinternal_set_font_selection_order);
-  defsubr (&Sinternal_set_alternative_font_family_alist);
-#if GLYPH_DEBUG
-  defsubr (&Sdump_face);
-  defsubr (&Sshow_face_resources);
-#endif /* GLYPH_DEBUG */
-  defsubr (&Sclear_face_cache);
-
-  DEFVAR_LISP ("font-list-limit", &Vfont_list_limit,
-    "*Limit for font matching.\n\
-If an integer > 0, font matching functions won't load more than\n\
-that number of fonts when searching for a matching font.");
-  Vfont_list_limit = make_number (DEFAULT_FONT_LIST_LIMIT);
-
-  DEFVAR_LISP ("face-new-frame-defaults", &Vface_new_frame_defaults,
-    "List of global face definitions (for internal use only.)");
-  Vface_new_frame_defaults = Qnil;
-  
-  DEFVAR_LISP ("face-default-stipple", &Vface_default_stipple,
-    "*Default stipple pattern used on monochrome displays.\n\
-This stipple pattern is used on monochrome displays\n\
-instead of shades of gray for a face background color.\n\
-See `set-face-stipple' for possible values for this variable.");
-  Vface_default_stipple = build_string ("gray3");
-
-  DEFVAR_LISP ("face-default-registry", &Vface_default_registry,
-    "Default registry and encoding to use.\n\
-This registry and encoding is used for unibyte text.  It is set up\n\
-from the specified frame font when Emacs starts. (For internal use only.)");
-  Vface_default_registry = Qnil;
-
-  DEFVAR_LISP ("face-alternative-font-family-alist",
-	       &Vface_alternative_font_family_alist, "");
-  Vface_alternative_font_family_alist = Qnil;
-
-#if SCALABLE_FONTS
-  
-  DEFVAR_LISP ("scalable-fonts-allowed", &Vscalable_fonts_allowed,
-    "Allowed scalable fonts.\n\
-A value of nil means don't allow any scalable fonts.\n\
-A value of t means allow any scalable font.\n\
-Otherwise, value must be a list of regular expressions.  A font may be\n\
-scaled if its name matches a regular expression in the list.");
-  Vscalable_fonts_allowed = Qt;
-  
-#endif /* SCALABLE_FONTS */
-
-#ifdef HAVE_WINDOW_SYSTEM
-  defsubr (&Sbitmap_spec_p);
-  defsubr (&Sx_list_fonts);
-  defsubr (&Sinternal_face_x_get_resource);
-  defsubr (&Sx_family_fonts);
-  defsubr (&Sx_font_family_list);
-#endif /* HAVE_WINDOW_SYSTEM */
-}