changeset 94938:5752d7154afc

Throughout the file, delete all USE_FONT_BACKEND conditionals. Don't check enable_font_backend. Delete all codes used only when USE_FONT_BACKEND is not defined. Use FONT_XXX_NAME_NUMERIC instead of face_numeric_xxx. (QCfoundry, QCadstyle, QCregistry, QCspacing, QCsize, QCavgwidth) (Qp): Extern them. (clear_font_table, load_face_font, xlfd_lookup_field_contents): Deleted. (struct font_name): Deleted. (xlfd_numeric_value, xlfd_symbolic_value): Deleted. (compare_fonts_by_sort_order): New function. (xlfd_numeric_slant, xlfd_symbolic_slant, xlfd_numeric_weight) (xlfd_symbolic_weight, xlfd_numeric_swidth, xlfd_symbolic_swidth): Deleted. (Fx_family_fonts): Use font_list_entities, and sort fonts by compare_fonts_by_sort_order. (Fx_font_family_list): Call Ffont_family_list. (face_numeric_value, face_numeric_weight, face_numeric_slant) (face_numeric_swidth, face_symbolic_value, face_symbolic_weight) (face_symbolic_slant, face_symbolic_swidth) (split_font_name_into_vector, build_font_name_from_vector) (xlfd_fixed_p, xlfd_point_size, pixel_point_size) (font_rescale_ratio, split_font_name, build_font_name) (free_font_names, sort_fonts, x_face_list_fonts) (face_font_available_p, sorted_font_list, cmp_font_names) (font_list_1, concat_font_list, font_list, remove_duplicates): Deleted. (Fx_list_fonts): Use Ffont_list. (LFACE_AVGWIDTH): Deleted. (check_lface_attrs): Don't check LFACE_AVGWIDTH. Check LFACE_FONT by FONTP. (lface_fully_specified_p): Don't check LFACE_AVGWIDTH. (set_lface_from_font_name): Delete it. (set_lface_from_font): Renamed from set_lface_from_font_and_fontset. Caller changed. Don't set LFACE_AVGWIDTH. Use FONT_XXX_FOR_FACE to get a symbol suitable for face. (merge_face_vectors): Copy font-spec if necessary. Clear properties of the font-spec if necessary. (merge_face_ref): Clear properties of the font-spec if necessary. (Finternal_set_lisp_face_attribute): Likewise. (set_font_frame_param): Use font_load_for_lface to load a font-object, and call Fmodify_frame_parameters with it. (x_update_menu_appearance): Don't check LFACE_AVGWIDTH. Get XLFD font name by Ffont_xlfd_name. (Finternal_lisp_face_attribute_values): Don't check QCweight, QCslant, and QCwidth. (Fface_font): Get a font name from font->props[FONT_NAME_INDEX]. (lface_same_font_attributes_p): Don't check LFACE_AVGWIDTH. Compare fonts by EQ. (lookup_non_ascii_face): Deleted. (face_for_font): The 2nd argument changed. (x_supports_face_attributes_p): Don't check LFACE_AVGWIDTH. Check atomic font properties by case insensitive. (realize_non_ascii_face): Set face->overstrike correctly. (realize_x_face): Likewise. Check if LFACE_FONT is a font_object. (dump_realized_face): Get font name from font->props[FONT_NAME_INDEX]. Don't print font_info_id.
author Kenichi Handa <handa@m17n.org>
date Wed, 14 May 2008 01:41:52 +0000
parents 18a1217b0d5e
children da7871784939
files src/xfaces.c
diffstat 1 files changed, 388 insertions(+), 2369 deletions(-) [+]
line wrap: on
line diff
--- a/src/xfaces.c	Wed May 14 01:40:23 2008 +0000
+++ b/src/xfaces.c	Wed May 14 01:41:52 2008 +0000
@@ -56,15 +56,17 @@
    13. Whether or not a box should be drawn around characters, the box
    type, and, for simple boxes, in what color.
 
-   14. Font pattern, or nil.  This is a special attribute.
-   When this attribute is specified, the face uses a font opened by
-   that pattern as is.  In addition, all the other font-related
-   attributes (1st thru 5th) are generated from the opened font name.
+   14. Font-spec, or nil.  This is a special attribute.
+
+   A font-spec is a collection of font attributes (specs).
+
+   When this attribute is specified, the face uses a font matching
+   with the specs as is except for what overwritten by the specs in
+   the fontset (see below).  In addition, the other font-related
+   attributes (1st thru 5th) are updated from the spec.
+
    On the other hand, if one of the other font-related attributes are
-   specified, this attribute is set to nil.  In that case, the face
-   doesn't inherit this attribute from the `default' face, and uses a
-   font determined by the other attributes (those may be inherited
-   from the `default' face).
+   specified, the correspoinding specs in this attribute is set to nil.
 
    15. A face name or list of face names from which to inherit attributes.
 
@@ -72,7 +74,11 @@
    and is used to ensure that a font specified on the command line,
    for example, can be matched exactly.
 
-   17. A fontset name.
+   17. A fontset name.  This is another special attribute.
+
+   A fontset is a mappings from characters to font-specs, and the
+   specs overwrite the font-spec in the 14th attribute.
+
 
    Faces are frame-local by nature because Emacs allows to define the
    same named face (face names are symbols) differently for different
@@ -206,10 +212,6 @@
 #include "frame.h"
 #include "termhooks.h"
 
-#ifdef HAVE_WINDOW_SYSTEM
-#include "fontset.h"
-#endif /* HAVE_WINDOW_SYSTEM */
-
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
 #ifdef USE_MOTIF
@@ -251,7 +253,8 @@
 
 #ifdef HAVE_WINDOW_SYSTEM
 #include "font.h"
-#endif	/* HAVE_WINDOW_SYSTEM */
+#include "fontset.h"
+#endif /* HAVE_WINDOW_SYSTEM */
 
 #ifdef HAVE_X_WINDOWS
 
@@ -314,6 +317,11 @@
 Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
 Lisp_Object QCfontset;
 
+/* Keywords symbols used for font properties.  */
+extern Lisp_Object QCfoundry, QCadstyle, QCregistry;
+extern Lisp_Object QCspacing, QCsize, QCavgwidth;
+extern Lisp_Object Qp;
+
 /* Symbols used for attribute values.  */
 
 Lisp_Object Qnormal, Qbold, Qultra_light, Qextra_light, Qlight;
@@ -491,7 +499,6 @@
 			      int, int));
 static int x_face_list_fonts P_ ((struct frame *, char *,
 				  struct font_name **, int, int));
-static int font_scalable_p P_ ((struct font_name *));
 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 unsigned char *xstrlwr P_ ((unsigned char *));
@@ -516,7 +523,7 @@
 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_non_ascii_face P_ ((struct frame *, int,
+static struct face *realize_non_ascii_face P_ ((struct frame *, Lisp_Object,
 						struct face *));
 static struct face *realize_x_face P_ ((struct face_cache *, Lisp_Object *));
 static struct face *realize_tty_face P_ ((struct face_cache *, Lisp_Object *));
@@ -531,48 +538,24 @@
 static struct face_cache *make_face_cache P_ ((struct frame *));
 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_ ((Lisp_Object *));
 static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*,
 				    struct named_merge_point *));
 static int merge_face_ref P_ ((struct frame *, Lisp_Object, Lisp_Object *,
 			       int, struct named_merge_point *));
-static int set_lface_from_font_name P_ ((struct frame *, Lisp_Object,
-					 Lisp_Object, int, int));
-static void set_lface_from_font_and_fontset P_ ((struct frame *, Lisp_Object,
-						 Lisp_Object, int, int));
+static int set_lface_from_font P_ ((struct frame *, Lisp_Object, Lisp_Object,
+				    int));
 static Lisp_Object lface_from_face_name P_ ((struct frame *, Lisp_Object, int));
 static struct face *make_realized_face P_ ((Lisp_Object *));
 static char *best_matching_font P_ ((struct frame *, Lisp_Object *,
 				     struct font_name *, int, int, 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,
-					    Lisp_Object));
-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 x_display_info *));
 
 #ifdef WINDOWSNT
 extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
@@ -980,14 +963,11 @@
     {
       struct x_display_info *dpyinfo;
 
-#ifdef USE_FONT_BACKEND
-      if (! enable_font_backend)
-#endif	/* USE_FONT_BACKEND */
-      /* Fonts are common for frames on one display, i.e. on
-	 one X screen.  */
-      for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
-	if (dpyinfo->n_fonts > CLEAR_FONT_TABLE_NFONTS)
-	  clear_font_table (dpyinfo);
+#if 0
+      /* Not yet implemented.  */
+      clear_font_cache (frame);
+#endif
+
 
       /* From time to time see if we can unload some fonts.  This also
 	 frees all realized faces on all frames.  Fonts needed by
@@ -1029,70 +1009,6 @@
   return Qnil;
 }
 
-
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-
-/* Remove fonts from the font table of DPYINFO except for the default
-   ASCII fonts of frames on that display.  Called from clear_face_cache
-   from time to time.  */
-
-static void
-clear_font_table (dpyinfo)
-     struct x_display_info *dpyinfo;
-{
-  int i;
-
-  /* Free those fonts that are not used by frames on DPYINFO.  */
-  for (i = 0; i < dpyinfo->n_fonts; ++i)
-    {
-      struct font_info *font_info = dpyinfo->font_table + i;
-      Lisp_Object tail, frame;
-
-      /* Check if slot is already free.  */
-      if (font_info->name == NULL)
-	continue;
-
-      /* Don't free a default font of some frame.  */
-      FOR_EACH_FRAME (tail, frame)
-	{
-	  struct frame *f = XFRAME (frame);
-	  if (FRAME_WINDOW_P (f)
-	      && font_info->font == FRAME_FONT (f))
-	    break;
-	}
-
-      if (!NILP (tail))
-	continue;
-
-      /* Free names.  */
-      if (font_info->full_name != font_info->name)
-	xfree (font_info->full_name);
-      xfree (font_info->name);
-
-      /* Free the font.  */
-      BLOCK_INPUT;
-#ifdef HAVE_X_WINDOWS
-      XFreeFont (dpyinfo->display, font_info->font);
-#endif
-#ifdef WINDOWSNT
-      w32_unload_font (dpyinfo, font_info->font);
-#endif
-#ifdef MAC_OS
-      mac_unload_font (dpyinfo, font_info->font);
-#endif
-      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
@@ -1222,64 +1138,6 @@
 
 
 /***********************************************************************
-				Fonts
- ***********************************************************************/
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-/* Load font of face FACE which is used on frame F to display ASCII
-   characters.  The name of the font to load is determined by lface.  */
-
-static void
-load_face_font (f, face)
-     struct frame *f;
-     struct face *face;
-{
-  struct font_info *font_info = NULL;
-  char *font_name;
-  int needs_overstrike;
-
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    abort ();
-#endif	/* USE_FONT_BACKEND */
-  face->font_info_id = -1;
-  face->font = NULL;
-  face->font_name = NULL;
-
-  font_name = choose_face_font (f, face->lface, Qnil, &needs_overstrike);
-  if (!font_name)
-    return;
-
-  BLOCK_INPUT;
-  font_info = FS_LOAD_FONT (f, font_name);
-  UNBLOCK_INPUT;
-
-  if (font_info)
-    {
-      face->font_info_id = font_info->font_idx;
-      face->font = font_info->font;
-      face->font_name = font_info->full_name;
-      face->overstrike = needs_overstrike;
-      if (face->gc)
-	{
-	  BLOCK_INPUT;
-	  x_free_gc (f, face->gc);
-	  face->gc = 0;
-	  UNBLOCK_INPUT;
-	}
-    }
-  else
-    add_to_log ("Unable to load font %s",
-		build_string (font_name), Qnil);
-  xfree (font_name);
-}
-
-#endif /* HAVE_WINDOW_SYSTEM */
-
-
-
-/***********************************************************************
 				X Colors
  ***********************************************************************/
 
@@ -1920,33 +1778,6 @@
   {"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];
-
-  /* If the original name matches one of Vface_font_rescale_alist,
-     the value is the corresponding rescale ratio.  Otherwise, the
-     value is 1.0.  */
-  double rescale_ratio;
-
-  /* Lower value mean higher priority.  */
-  int registry_priority;
-};
-
 /* The frame in effect when sorting font names.  Set temporarily in
    sort_fonts so that it is available in font comparison functions.  */
 
@@ -1965,425 +1796,9 @@
 static int font_sort_order[4];
 #endif
 
-/* 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;
-     Lisp_Object 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;
-     size_t 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
 
-#ifdef USE_FONT_BACKEND
-static INLINE Lisp_Object
-face_symbolic_value (table, dim, font_prop)
-     struct table_entry *table;
-     int dim;
-     Lisp_Object font_prop;
-{
-  struct table_entry *p;
-  char *s = SDATA (SYMBOL_NAME (font_prop));
-  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].symbol;
-    }
-
-  return Qnil;
-}
-
-static INLINE Lisp_Object
-face_symbolic_weight (weight)
-     Lisp_Object weight;
-{
-  return face_symbolic_value (weight_table, DIM (weight_table), weight);
-}
-
-static INLINE Lisp_Object
-face_symbolic_slant (slant)
-     Lisp_Object slant;
-{
-  return face_symbolic_value (slant_table, DIM (slant_table), slant);
-}
-
-static INLINE Lisp_Object
-face_symbolic_swidth (width)
-     Lisp_Object width;
-{
-  return face_symbolic_value (swidth_table, DIM (swidth_table), width);
-}
-#endif	/* USE_FONT_BACKEND */
-
-Lisp_Object
-split_font_name_into_vector (fontname)
-     Lisp_Object fontname;
-{
-  struct font_name font;
-  Lisp_Object vec;
-  int i;
-
-  font.name = LSTRDUPA (fontname);
-  if (! split_font_name (NULL, &font, 0))
-    return Qnil;
-  vec = Fmake_vector (make_number (XLFD_LAST), Qnil);
-  for (i = 0; i < XLFD_LAST; i++)
-    if (font.fields[i][0] != '*')
-      ASET (vec, i, build_string (font.fields[i]));
-  return vec;
-}
-
-Lisp_Object
-build_font_name_from_vector (vec)
-     Lisp_Object vec;
-{
-  struct font_name font;
-  Lisp_Object fontname;
-  char *p;
-  int i;
-
-  for (i = 0; i < XLFD_LAST; i++)
-    {
-      font.fields[i] = (NILP (AREF (vec, i))
-			? "*" : (char *) SDATA (AREF (vec, i)));
-      if ((i == XLFD_FAMILY || i == XLFD_REGISTRY)
-	  && (p = strchr (font.fields[i], '-')))
-	{
-	  char *p1 = STRDUPA (font.fields[i]);
-
-	  p1[p - font.fields[i]] = '\0';
-	  if (i == XLFD_FAMILY)
-	    {
-	      font.fields[XLFD_FOUNDRY] = p1;
-	      font.fields[XLFD_FAMILY] = p + 1;
-	    }
-	  else
-	    {
-	      font.fields[XLFD_REGISTRY] = p1;
-	      font.fields[XLFD_ENCODING] = p + 1;
-	      break;
-	    }
-	}
-    }
-
-  p = build_font_name (&font);
-  fontname = build_string (p);
-  xfree (p);
-  return fontname;
-}
-
-/* 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.
-
-   By side effect, set FONT->numeric[XLFD_PIXEL_SIZE].  */
-
-static INLINE int
-xlfd_point_size (f, font)
-     struct frame *f;
-     struct font_name *font;
-{
-  double resy = FRAME_X_DISPLAY_INFO (f)->resy;
-  char *pixel_field = font->fields[XLFD_PIXEL_SIZE];
-  double pixel;
-  int real_pt;
-
-  if (*pixel_field == '[')
-    {
-      /* The pixel size field is `[A B C D]' which specifies
-	 a transformation matrix.
-
-	 A  B  0
-	 C  D  0
-	 0  0  1
-
-	 by which all glyphs of the font are transformed.  The spec
-	 says that s scalar value N for the pixel size is equivalent
-	 to A = N * resx/resy, B = C = 0, D = N.  */
-      char *start = pixel_field + 1, *end;
-      double matrix[4];
-      int i;
-
-      for (i = 0; i < 4; ++i)
-	{
-	  matrix[i] = strtod (start, &end);
-	  start = end;
-	}
-
-      pixel = matrix[3];
-    }
-  else
-    pixel = atoi (pixel_field);
-
-  font->numeric[XLFD_PIXEL_SIZE] = pixel;
-  if (pixel == 0)
-    real_pt = 0;
-  else
-    real_pt = PT_PER_INCH * 10.0 * pixel / resy + 0.5;
-
-  return real_pt;
-}
-
-
-/* Return point size of PIXEL dots while considering Y-resultion (DPI)
-   of frame F.  This function is used to guess a point size of font
-   when only the pixel height of the font is available.  */
-
-static INLINE int
-pixel_point_size (f, pixel)
-     struct frame *f;
-     int pixel;
-{
-  double resy = FRAME_X_DISPLAY_INFO (f)->resy;
-  double real_pt;
-  int int_pt;
-
-  /* As one inch is PT_PER_INCH points, PT_PER_INCH/RESY gives the
-     point size of one dot.  */
-  real_pt = pixel * PT_PER_INCH / resy;
-  int_pt = real_pt + 0.5;
-
-  return int_pt;
-}
-
-
 /* Return a rescaling ratio of a font of NAME.  */
 
 static double
@@ -2402,586 +1817,42 @@
   return 1.0;
 }
 
-
-/* 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 `-'.  */
+static enum font_property_index font_props_for_sorting[FONT_SIZE_INDEX];
 
 static int
-split_font_name (f, font, numeric_p)
-     struct frame *f;
-     struct font_name *font;
-     int numeric_p;
+compare_fonts_by_sort_order (v1, v2)
+     const void *v1, *v2;
 {
-  int i = 0;
-  int success_p;
-  double rescale_ratio;
-
-  if (numeric_p)
-    /* This must be done before splitting the font name.  */
-    rescale_ratio = font_rescale_ratio (font->name);
-
-  if (*font->name == '-')
-    {
-      char *p = xstrlwr (font->name) + 1;
-
-      while (i < XLFD_LAST)
-	{
-	  font->fields[i] = p;
-	  ++i;
-
-	  /* Pixel and point size may be of the form `[....]'.  For
-	     BNF, see XLFD spec, chapter 4.  Negative values are
-	     indicated by tilde characters which we replace with
-	     `-' characters, here.  */
-	  if (*p == '['
-	      && (i - 1 == XLFD_PIXEL_SIZE
-		  || i - 1 == XLFD_POINT_SIZE))
-	    {
-	      char *start, *end;
-	      int j;
-
-	      for (++p; *p && *p != ']'; ++p)
-		if (*p == '~')
-		  *p = '-';
-
-	      /* Check that the matrix contains 4 floating point
-		 numbers.  */
-	      for (j = 0, start = font->fields[i - 1] + 1;
-		   j < 4;
-		   ++j, start = end)
-		if (strtod (start, &end) == 0 && start == end)
-		  break;
-
-	      if (j < 4)
-		break;
-	    }
-
-	  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);
-      font->numeric[XLFD_AVGWIDTH] = atoi (font->fields[XLFD_AVGWIDTH]);
-      font->rescale_ratio = rescale_ratio;
-    }
-
-  /* Initialize it to zero.  It will be overridden by font_list while
-     trying alternate registries.  */
-  font->registry_priority = 0;
-
-  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;
-{
+  Lisp_Object font1 = *(Lisp_Object *) v1;
+  Lisp_Object font2 = *(Lisp_Object *) v2;
   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)
+  
+  for (i = 0; i < FONT_SIZE_INDEX; i++)
+    {
+      enum font_property_index idx = font_props_for_sorting[i];
+      Lisp_Object val1 = AREF (font1, idx), val2 = AREF (font2, idx);
+      int result;
+
+      if (idx <= FONT_REGISTRY_INDEX)
 	{
-	  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.
-
-   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.  */
-
-static int
-x_face_list_fonts (f, pattern, pfonts, nfonts, try_alternatives_p)
-     struct frame *f;
-     char *pattern;
-     struct font_name **pfonts;
-     int nfonts, try_alternatives_p;
-{
-  int n, nignored;
-
-  /* NTEMACS_TODO : currently this uses w32_list_fonts, but it may be
-     better to do it the other way around. */
-  Lisp_Object lfonts;
-  Lisp_Object lpattern, tem;
-  struct font_name *fonts = 0;
-  int num_fonts = nfonts;
-
-  *pfonts = 0;
-  lpattern = build_string (pattern);
-
-  /* Get the list of fonts matching PATTERN.  */
-#ifdef WINDOWSNT
-  BLOCK_INPUT;
-  lfonts = w32_list_fonts (f, lpattern, 0, nfonts);
-  UNBLOCK_INPUT;
-#else
-  lfonts = x_list_fonts (f, lpattern, -1, nfonts);
-#endif
-
-  if (nfonts < 0 && CONSP (lfonts))
-    num_fonts = XFASTINT (Flength (lfonts));
-
-  /* Make a copy of the font names we got from X, and
-     split them into fields.  */
-  n = nignored = 0;
-  for (tem = lfonts; CONSP (tem) && n < num_fonts; tem = XCDR (tem))
-    {
-      Lisp_Object elt, tail;
-      const char *name = SDATA (XCAR (tem));
-
-      /* Ignore fonts matching a pattern from face-ignored-fonts.  */
-      for (tail = Vface_ignored_fonts; CONSP (tail); tail = XCDR (tail))
-	{
-	  elt = XCAR (tail);
-	  if (STRINGP (elt)
-	      && fast_c_string_match_ignore_case (elt, name) >= 0)
-	    break;
-	}
-      if (!NILP (tail))
-	{
-	  ++nignored;
-	  continue;
-	}
-
-      if (! fonts)
-        {
-          *pfonts = (struct font_name *) xmalloc (num_fonts * sizeof **pfonts);
-          fonts = *pfonts;
-        }
-
-      /* Make a copy of the font name.  */
-      fonts[n].name = xstrdup (name);
-
-      if (split_font_name (f, fonts + n, 1))
-	{
-	  if (font_scalable_p (fonts + n)
-	      && !may_use_scalable_font_p (name))
-	    {
-	      ++nignored;
-	      xfree (fonts[n].name);
-	    }
+	  if (STRINGP (val1))
+	    result = STRINGP (val2) ? strcmp (SDATA (val1), SDATA (val2)) : -1;
 	  else
-	    ++n;
+	    result = STRINGP (val2) ? 1 : 0;
 	}
       else
-	xfree (fonts[n].name);
-    }
-
-  /* If no fonts found, try patterns from Valternate_fontname_alist.  */
-  if (n == 0 && try_alternatives_p)
-    {
-      Lisp_Object list = Valternate_fontname_alist;
-
-      if (*pfonts)
-        {
-          xfree (*pfonts);
-          *pfonts = 0;
-        }
-
-      while (CONSP (list))
 	{
-	  Lisp_Object entry = XCAR (list);
-	  if (CONSP (entry)
-	      && STRINGP (XCAR (entry))
-	      && strcmp (SDATA (XCAR (entry)), 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 (SDATA (name), pattern) == 0
-		     || (n = x_face_list_fonts (f, SDATA (name),
-						pfonts, nfonts, 0),
-			 n == 0)))
-	    patterns = XCDR (patterns);
-	}
-    }
-
-  return n;
-}
-
-
-/* Check if a font matching pattern_offset_t on frame F is available
-   or not.  PATTERN may be a cons (FAMILY . REGISTRY), in which case,
-   a font name pattern is generated from FAMILY and REGISTRY.  */
-
-int
-face_font_available_p (f, pattern)
-     struct frame *f;
-     Lisp_Object pattern;
-{
-  Lisp_Object fonts;
-
-  if (! STRINGP (pattern))
-    {
-      Lisp_Object family, registry;
-      char *family_str, *registry_str, *pattern_str;
-
-      CHECK_CONS (pattern);
-      family = XCAR (pattern);
-      if (NILP (family))
-	family_str = "*";
-      else
-	{
-	  CHECK_STRING (family);
-	  family_str = (char *) SDATA (family);
+	  if (INTEGERP (val1))
+	    result = INTEGERP (val2) ? XINT (val1) - XINT (val2) : -1;
+	  else
+	    result = INTEGERP (val2) ? 1 : 0;
 	}
-      registry = XCDR (pattern);
-      if (NILP (registry))
-	registry_str = "*";
-      else
-	{
-	  CHECK_STRING (registry);
-	  registry_str = (char *) SDATA (registry);
-	}
-
-      pattern_str = (char *) alloca (strlen (family_str)
-				     + strlen (registry_str)
-				     + 10);
-      strcpy (pattern_str, index (family_str, '-') ? "-" : "-*-");
-      strcat (pattern_str, family_str);
-      strcat (pattern_str, "-*-");
-      strcat (pattern_str, registry_str);
-      if (!index (registry_str, '-'))
-	{
-	  if (registry_str[strlen (registry_str) - 1] == '*')
-	    strcat (pattern_str, "-*");
-	  else
-	    strcat (pattern_str, "*-*");
-	}
-      pattern = build_string (pattern_str);
-    }
-
-  /* Get the list of fonts matching PATTERN.  */
-#ifdef WINDOWSNT
-  BLOCK_INPUT;
-  fonts = w32_list_fonts (f, pattern, 0, 1);
-  UNBLOCK_INPUT;
-#else
-  fonts = x_list_fonts (f, pattern, -1, 1);
-#endif
-  return XINT (Flength (fonts));
-}
-
-
-/* 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))
-    nfonts = XINT (Vfont_list_limit);
-
-  *fonts = NULL;
-  nfonts = x_face_list_fonts (f, pattern, fonts, nfonts, 1);
-
-  /* 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 if (*fonts)
-    {
-      xfree (*fonts);
-      *fonts = NULL;
-    }
-
-  return nfonts;
+      if (result)
+	return result;
+    }
+  return 0;
 }
 
-
-/* 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_X_DISPLAY_INFO (font_frame)->resy;
-	  int x_resy = x->numeric[XLFD_RESY];
-	  int y_resy = y->numeric[XLFD_RESY];
-	  cmp = eabs (resy - x_resy) - eabs (resy - y_resy);
-	}
-    }
-
-  return cmp;
-}
-
-
-/* Get a sorted list of fonts matching PATTERN on frame F.  If PATTERN
-   is nil, list fonts matching FAMILY and REGISTRY.  FAMILY is a
-   family name string or nil.  REGISTRY is a registry name string.
-   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_1 (f, pattern, family, registry, fonts)
-     struct frame *f;
-     Lisp_Object pattern, family, registry;
-     struct font_name **fonts;
-{
-  char *pattern_str, *family_str, *registry_str;
-
-  if (NILP (pattern))
-    {
-      family_str = (NILP (family) ? "*" : (char *) SDATA (family));
-      registry_str = (NILP (registry) ? "*" : (char *) SDATA (registry));
-
-      pattern_str = (char *) alloca (strlen (family_str)
-				     + strlen (registry_str)
-				     + 10);
-      strcpy (pattern_str, index (family_str, '-') ? "-" : "-*-");
-      strcat (pattern_str, family_str);
-      strcat (pattern_str, "-*-");
-      strcat (pattern_str, registry_str);
-      if (!index (registry_str, '-'))
-	{
-	  if (registry_str[strlen (registry_str) - 1] == '*')
-	    strcat (pattern_str, "-*");
-	  else
-	    strcat (pattern_str, "*-*");
-	}
-    }
-  else
-    pattern_str = (char *) SDATA (pattern);
-
-  return sorted_font_list (f, pattern_str, cmp_font_names, fonts);
-}
-
-
-/* Concatenate font list FONTS1 and FONTS2.  FONTS1 and FONTS2
-   contains NFONTS1 fonts and NFONTS2 fonts respectively.  Return a
-   pointer to a newly allocated font list.  FONTS1 and FONTS2 are
-   freed.  */
-
-static struct font_name *
-concat_font_list (fonts1, nfonts1, fonts2, nfonts2)
-     struct font_name *fonts1, *fonts2;
-     int nfonts1, nfonts2;
-{
-  int new_nfonts = nfonts1 + nfonts2;
-  struct font_name *new_fonts;
-
-  new_fonts = (struct font_name *) xmalloc (sizeof *new_fonts * new_nfonts);
-  bcopy (fonts1, new_fonts, sizeof *new_fonts * nfonts1);
-  bcopy (fonts2, new_fonts + nfonts1, sizeof *new_fonts * nfonts2);
-  xfree (fonts1);
-  xfree (fonts2);
-  return new_fonts;
-}
-
-
-/* Get a sorted list of fonts of family FAMILY on frame F.
-
-   If PATTERN is non-nil, list fonts matching that pattern.
-
-   If REGISTRY is non-nil, it is a list of registry (and encoding)
-   names.  Return fonts with those registries and the alternative
-   registries from Vface_alternative_font_registry_alist.
-
-   If REGISTRY is nil return fonts of any registry.
-
-   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, fonts)
-     struct frame *f;
-     Lisp_Object pattern, family, registry;
-     struct font_name **fonts;
-{
-  int nfonts;
-  int reg_prio;
-  int i;
-
-  if (NILP (registry))
-    return font_list_1 (f, pattern, family, registry, fonts);
-
-  for (reg_prio = 0, nfonts = 0; CONSP (registry); registry = XCDR (registry))
-    {
-      Lisp_Object elt, alter;
-      int nfonts2;
-      struct font_name *fonts2;
-
-      elt = XCAR (registry);
-      alter = Fassoc (elt, Vface_alternative_font_registry_alist);
-      if (NILP (alter))
-	alter = Fcons (elt, Qnil);
-      for (; CONSP (alter); alter = XCDR (alter), reg_prio++)
-	{
-	  nfonts2 = font_list_1 (f, pattern, family, XCAR (alter), &fonts2);
-	  if (nfonts2 > 0)
-	    {
-	      if (reg_prio > 0)
-		for (i = 0; i < nfonts2; i++)
-		  fonts2[i].registry_priority = reg_prio;
-	      if (nfonts > 0)
-		*fonts = concat_font_list (*fonts, nfonts, fonts2, nfonts2);
-	      else
-		*fonts = fonts2;
-	      nfonts += nfonts2;
-	    }
-	}
-    }
-
-  return nfonts;
-}
-
-
-/* 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))))
-	XSETCDR (tail, XCDR (next));
-      else
-	tail = XCDR (tail);
-    }
-}
-
-
 DEFUN ("x-family-fonts", Fx_family_fonts, Sx_family_fonts, 0, 2, 0,
        doc: /* Return a list of available fonts of family FAMILY on FRAME.
 If FAMILY is omitted or nil, list all families.
@@ -3002,41 +1873,66 @@
      Lisp_Object family, frame;
 {
   struct frame *f = check_x_frame (frame);
-  struct font_name *fonts;
+  Lisp_Object font_spec = Qnil, vec;
   int i, nfonts;
   Lisp_Object result;
-  struct gcpro gcpro1;
 
   if (!NILP (family))
-    CHECK_STRING (family);
+    {
+      CHECK_STRING (family);
+      font_spec = Ffont_spec (0, NULL);
+      Ffont_put (font_spec, QCfamily, family);
+    }
+  vec = font_list_entities (frame, font_spec);
+  nfonts = ASIZE (vec);
+  if (nfonts == 0)
+    return Qnil;
+  if (nfonts > 1)
+    {
+      for (i = 0; i < 4; i++)
+	switch (font_sort_order[i])
+	  {
+	  case XLFD_SWIDTH:
+	    font_props_for_sorting[i] = FONT_WIDTH_INDEX; break;
+	  case XLFD_POINT_SIZE:
+	    font_props_for_sorting[i] = FONT_SIZE_INDEX; break;
+	  case XLFD_WEIGHT:
+	    font_props_for_sorting[i] = FONT_WEIGHT_INDEX; break;
+	  default:
+	    font_props_for_sorting[i] = FONT_SLANT_INDEX; break;
+	  }
+      font_props_for_sorting[i++] = FONT_FAMILY_INDEX;
+      font_props_for_sorting[i++] = FONT_FOUNDRY_INDEX;
+      font_props_for_sorting[i++] = FONT_ADSTYLE_INDEX;
+      font_props_for_sorting[i++] = FONT_REGISTRY_INDEX;
+
+      qsort (XVECTOR (vec)->contents, nfonts, sizeof (Lisp_Object),
+	     compare_fonts_by_sort_order);
+    }
 
   result = Qnil;
-  GCPRO1 (result);
-  nfonts = font_list (f, Qnil, family, Qnil, &fonts);
   for (i = nfonts - 1; i >= 0; --i)
     {
+      Lisp_Object font = AREF (vec, i);
       Lisp_Object v = Fmake_vector (make_number (8), Qnil);
-      char *tem;
-
-      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);
+      int point;
+      Lisp_Object spacing;
+
+      ASET (v, 0, AREF (font, FONT_FAMILY_INDEX));
+      ASET (v, 1, FONT_WIDTH_SYMBOLIC (font));
+      point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10,
+			      f->resy);
+      ASET (v, 2, make_number (point));
+      ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font));
+      ASET (v, 4, FONT_SLANT_SYMBOLIC (font));
+      spacing = Ffont_get (font, QCspacing);
+      ASET (v, 5, (NILP (spacing) || EQ (spacing, Qp)) ? Qnil : Qt);
+      ASET (v, 6, AREF (font, FONT_NAME_INDEX));
+      ASET (v, 7, AREF (font, FONT_REGISTRY_INDEX));
 
       result = Fcons (v, result);
     }
 
-  remove_duplicates (result);
-  free_font_names (fonts, nfonts);
-  UNGCPRO;
   return result;
 }
 
@@ -3051,28 +1947,7 @@
      (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_INDEX ();
-
-  /* Let's consider all fonts.  */
-  specbind (intern ("font-list-limit"), make_number (-1));
-  nfonts = font_list (f, Qnil, Qnil, Qnil, &fonts);
-
-  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);
+  return Ffont_family_list (frame);
 }
 
 
@@ -3100,30 +1975,27 @@
     Lisp_Object pattern, face, frame, maximum, width;
 {
   struct frame *f;
-  int size;
-  int maxnames;
+  int size, avgwidth;
 
   check_x ();
   CHECK_STRING (pattern);
 
-  if (NILP (maximum))
-    maxnames = -1;
-  else
-    {
-      CHECK_NATNUM (maximum);
-      maxnames = XINT (maximum);
-    }
+  if (! NILP (maximum))
+    CHECK_NATNUM (maximum);
 
   if (!NILP (width))
     CHECK_NUMBER (width);
 
   /* We can't simply call check_x_frame because this function may be
      called before any frame is created.  */
+  if (NILP (frame))
+    frame = selected_frame;
   f = frame_or_selected_frame (frame, 2);
-  if (!FRAME_WINDOW_P (f))
+  if (! FRAME_WINDOW_P (f))
     {
       /* Perhaps we have not yet created any frame.  */
       f = NULL;
+      frame = Qnil;
       face = Qnil;
     }
 
@@ -3141,19 +2013,31 @@
 			   : FACE_FROM_ID (f, face_id));
 
       if (face && face->font)
-	size = FONT_WIDTH (face->font);
+	{
+	  size = face->font->pixel_size;
+	  avgwidth = face->font->average_width;
+	}
       else
-	size = FONT_WIDTH (FRAME_FONT (f));  /* FRAME_COLUMN_WIDTH (f) */
-
+	{
+	  size = FRAME_FONT (f)->pixel_size;
+	  avgwidth = FRAME_FONT (f)->average_width;
+	}
       if (!NILP (width))
-	size *= XINT (width);
+	avgwidth *= XINT (width);
     }
 
   {
+    Lisp_Object font_spec;
     Lisp_Object args[2];
 
-    args[0] = x_list_fonts (f, pattern, size, maxnames);
-    if (f == NULL)
+    font_spec = font_spec_from_name (pattern);
+    if (size)
+      {
+	Ffont_put (font_spec, QCsize, make_number (size));
+	Ffont_put (font_spec, QCavgwidth, make_number (avgwidth));
+      }
+    args[0] = Flist_fonts (font_spec, frame, maximum, Qnil);
+    if (NILP (frame))
       /* We don't have to check fontsets.  */
       return args[0];
     args[1] = list_fontsets (f, pattern, size);
@@ -3186,7 +2070,6 @@
 #define LFACE_BOX(LFACE)	    AREF ((LFACE), LFACE_BOX_INDEX)
 #define LFACE_FONT(LFACE)	    AREF ((LFACE), LFACE_FONT_INDEX)
 #define LFACE_INHERIT(LFACE)	    AREF ((LFACE), LFACE_INHERIT_INDEX)
-#define LFACE_AVGWIDTH(LFACE)	    AREF ((LFACE), LFACE_AVGWIDTH_INDEX)
 #define LFACE_FONTSET(LFACE)	    AREF ((LFACE), LFACE_FONTSET_INDEX)
 
 /* Non-zero if LFACE is a Lisp face.  A Lisp face is a vector of size
@@ -3212,9 +2095,6 @@
   xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
 	   || IGNORE_DEFFACE_P (attrs[LFACE_SWIDTH_INDEX])
 	   || SYMBOLP (attrs[LFACE_SWIDTH_INDEX]));
-  xassert (UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX])
-	   || IGNORE_DEFFACE_P (attrs[LFACE_AVGWIDTH_INDEX])
-	   || INTEGERP (attrs[LFACE_AVGWIDTH_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
 	   || IGNORE_DEFFACE_P (attrs[LFACE_HEIGHT_INDEX])
 	   || INTEGERP (attrs[LFACE_HEIGHT_INDEX])
@@ -3265,11 +2145,7 @@
 	   || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX])));
   xassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX])
 	   || IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX])
-	   || NILP (attrs[LFACE_FONT_INDEX])
-#ifdef USE_FONT_BACKEND
-	   || FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])
-#endif	/* USE_FONT_BACKEND */
-	   || STRINGP (attrs[LFACE_FONT_INDEX]));
+	   || FONTP (attrs[LFACE_FONT_INDEX]));
   xassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX])
 	   || STRINGP (attrs[LFACE_FONTSET_INDEX]));
 #endif
@@ -3478,8 +2354,7 @@
   int i;
 
   for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
-    if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX
-	&& i != LFACE_AVGWIDTH_INDEX && i != LFACE_FONTSET_INDEX)
+    if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX)
       if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i]))
 #ifdef MAC_OS
         /* MAC_TODO: No stipple support on Mac OS yet, this index is
@@ -3494,144 +2369,19 @@
 
 #ifdef HAVE_WINDOW_SYSTEM
 
-/* Set font-related attributes of Lisp face LFACE from the fullname of
-   the font opened by FONTNAME.  If FORCE_P is zero, set only
-   unspecified attributes of LFACE.  The exception is `font'
-   attribute.  It is set to FONTNAME as is regardless of FORCE_P.
-
-   If FONTNAME is not available on frame F,
-	return 0 if MAY_FAIL_P is non-zero, otherwise abort.
-   If the fullname is not in a valid XLFD format,
-   	return 0 if MAY_FAIL_P is non-zero, otherwise set normal values
-	in LFACE and return 1.
-   Otherwise, return 1.  */
+/* Set font-related attributes of Lisp face LFACE from FONT-OBJECT.
+   If FORCE_P is zero, set only unspecified attributes of LFACE.  The
+   exception is `font' attribute.  It is set to FONT_OBJECT regardless
+   of FORCE_P.  */
 
 static int
-set_lface_from_font_name (f, lface, fontname, force_p, may_fail_p)
-     struct frame *f;
-     Lisp_Object lface;
-     Lisp_Object fontname;
-     int force_p, may_fail_p;
-{
-  struct font_name font;
-  char *buffer;
-  int pt;
-  int have_xlfd_p;
-  int fontset;
-  char *font_name = SDATA (fontname);
-  struct font_info *font_info;
-
-  /* If FONTNAME is actually a fontset name, get ASCII font name of it.  */
-  fontset = fs_query_fontset (fontname, 0);
-
-  if (fontset > 0)
-    font_name = SDATA (fontset_ascii (fontset));
-  else if (fontset == 0)
-    {
-      if (may_fail_p)
-	return 0;
-      abort ();
-    }
-
-  /* Check if FONT_NAME is surely available on the system.  Usually
-     FONT_NAME is already cached for the frame F and FS_LOAD_FONT
-     returns quickly.  But, even if FONT_NAME is not yet cached,
-     caching it now is not futail because we anyway load the font
-     later.  */
-  BLOCK_INPUT;
-  font_info = FS_LOAD_FONT (f, font_name);
-  UNBLOCK_INPUT;
-
-  if (!font_info)
-    {
-      if (may_fail_p)
-	return 0;
-      abort ();
-    }
-
-  font.name = STRDUPA (font_info->full_name);
-  have_xlfd_p = split_font_name (f, &font, 1);
-
-  /* Set attributes only if unspecified, otherwise face defaults for
-     new frames would never take effect.  If we couldn't get a font
-     name conforming to XLFD, set normal values.  */
-
-  if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
-    {
-      Lisp_Object val;
-      if (have_xlfd_p)
-	{
-	  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]);
-	  val = build_string (buffer);
-	}
-      else
-	val = build_string ("*");
-      LFACE_FAMILY (lface) = val;
-    }
-
-  if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
-    {
-      if (have_xlfd_p)
-	pt = xlfd_point_size (f, &font);
-      else
-	pt = pixel_point_size (f, font_info->height * 10);
-      xassert (pt > 0);
-      LFACE_HEIGHT (lface) = make_number (pt);
-    }
-
-  if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
-    LFACE_SWIDTH (lface)
-      = have_xlfd_p ? xlfd_symbolic_swidth (&font) : Qnormal;
-
-  if (force_p || UNSPECIFIEDP (LFACE_AVGWIDTH (lface)))
-    LFACE_AVGWIDTH (lface)
-      = (have_xlfd_p
-	 ? make_number (font.numeric[XLFD_AVGWIDTH])
-	 : Qunspecified);
-
-  if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
-    LFACE_WEIGHT (lface)
-      = have_xlfd_p ? xlfd_symbolic_weight (&font) : Qnormal;
-
-  if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
-    LFACE_SLANT (lface)
-      = have_xlfd_p ? xlfd_symbolic_slant (&font) : Qnormal;
-
-  if (fontset > 0)
-    {
-      LFACE_FONT (lface) = build_string (font_info->full_name);
-      LFACE_FONTSET (lface) = fontset_name (fontset);
-    }
-  else
-    {
-      LFACE_FONT (lface) = fontname;
-      fontset
-	= new_fontset_from_font_name (build_string (font_info->full_name));
-      LFACE_FONTSET (lface) = fontset_name (fontset);
-    }
-  return 1;
-}
-
-#ifdef USE_FONT_BACKEND
-/* Set font-related attributes of Lisp face LFACE from FONT-OBJECT and
-   FONTSET.  If FORCE_P is zero, set only unspecified attributes of
-   LFACE.  The exceptions are `font' and `fontset' attributes.  They
-   are set regardless of FORCE_P.  */
-
-static void
-set_lface_from_font_and_fontset (f, lface, font_object, fontset, force_p)
+set_lface_from_font (f, lface, font_object, force_p)
      struct frame *f;
      Lisp_Object lface, font_object;
-     int fontset;
      int force_p;
 {
-  struct font *font = XSAVE_VALUE (font_object)->pointer;
-  Lisp_Object entity = font->entity;
   Lisp_Object val;
+  struct font *font = XFONT_OBJECT (font_object);
 
   /* Set attributes only if unspecified, otherwise face defaults for
      new frames would never take effect.  If the font doesn't have a
@@ -3639,8 +2389,8 @@
 
   if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface)))
     {
-      Lisp_Object foundry = AREF (entity, FONT_FOUNDRY_INDEX);
-      Lisp_Object family = AREF (entity, FONT_FAMILY_INDEX);
+      Lisp_Object foundry = AREF (font_object, FONT_FOUNDRY_INDEX);
+      Lisp_Object family = AREF (font_object, FONT_FAMILY_INDEX);
 
       if (! NILP (foundry))
 	{
@@ -3662,42 +2412,31 @@
 
   if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface)))
     {
-      int pt = pixel_point_size (f, font->pixel_size * 10);
+      int pt = PIXEL_TO_POINT (font->pixel_size * 10, f->resy);
 
       xassert (pt > 0);
       LFACE_HEIGHT (lface) = make_number (pt);
     }
 
-  if (force_p || UNSPECIFIEDP (LFACE_AVGWIDTH (lface)))
-    LFACE_AVGWIDTH (lface) = make_number (font->font.average_width);
-
   if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface)))
     {
-      Lisp_Object weight = font_symbolic_weight (entity);
-
-      val = NILP (weight) ? Qnormal : face_symbolic_weight (weight);
-      LFACE_WEIGHT (lface) = ! NILP (val) ? val : weight;
+      val = FONT_WEIGHT_FOR_FACE (font_object);
+      LFACE_WEIGHT (lface) = ! NILP (val) ? val :Qnormal;
     }
   if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface)))
     {
-      Lisp_Object slant = font_symbolic_slant (entity);
-
-      val = NILP (slant) ? Qnormal : face_symbolic_slant (slant);
-      LFACE_SLANT (lface) = ! NILP (val) ? val : slant;
+      val = FONT_SLANT_FOR_FACE (font_object);
+      LFACE_SLANT (lface) = ! NILP (val) ? val : Qnormal;
     }
   if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface)))
     {
-      Lisp_Object width = font_symbolic_width (entity);
-
-      val = NILP (width) ? Qnormal : face_symbolic_swidth (width);
-      LFACE_SWIDTH (lface) = ! NILP (val) ? val : width;
-    }
-
-  LFACE_FONT (lface) = make_unibyte_string (font->font.full_name,
-					    strlen (font->font.full_name));
-  LFACE_FONTSET (lface) = fontset_name (fontset);
+      val = FONT_WIDTH_FOR_FACE (font_object);
+      LFACE_SWIDTH (lface) = ! NILP (val) ? val : Qnormal;
+    }
+
+  LFACE_FONT (lface) = font_object;
+  return 1;
 }
-#endif	/* USE_FONT_BACKEND */
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
@@ -3777,28 +2516,42 @@
       && !NILP (from[LFACE_INHERIT_INDEX]))
     merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, 0, named_merge_points);
 
-  /* If TO specifies a :font attribute, and FROM specifies some
-     font-related attribute, we need to clear TO's :font attribute
-     (because it will be inconsistent with whatever FROM specifies, and
-     FROM takes precedence).  */
-  if (!NILP (to[LFACE_FONT_INDEX])
-      && (!UNSPECIFIEDP (from[LFACE_FAMILY_INDEX])
-	  || !UNSPECIFIEDP (from[LFACE_HEIGHT_INDEX])
-	  || !UNSPECIFIEDP (from[LFACE_WEIGHT_INDEX])
-	  || !UNSPECIFIEDP (from[LFACE_SLANT_INDEX])
-	  || !UNSPECIFIEDP (from[LFACE_SWIDTH_INDEX])
-	  || !UNSPECIFIEDP (from[LFACE_AVGWIDTH_INDEX])))
-    to[LFACE_FONT_INDEX] = Qnil;
+  i = LFACE_FONT_INDEX;
+  if (!UNSPECIFIEDP (from[i]))
+    {
+      if (!UNSPECIFIEDP (to[i]))
+	to[i] = Fmerge_font_spec (from[i], to[i]);
+      else
+	to[i] = Fcopy_font_spec (from[i]);
+      ASET (to[i], FONT_SIZE_INDEX, Qnil);
+    }
 
   for (i = 1; i < LFACE_VECTOR_SIZE; ++i)
     if (!UNSPECIFIEDP (from[i]))
       {
 	if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i]))
-	  to[i] = merge_face_heights (from[i], to[i], to[i]);
-	else
-	  to[i] = from[i];
+	  {
+	    to[i] = merge_face_heights (from[i], to[i], to[i]);
+	    font_clear_prop (to, FONT_SIZE_INDEX);
+	  }
+	else if (i != LFACE_FONT_INDEX)
+	  {
+	    to[i] = from[i];
+	    if (i >= LFACE_FAMILY_INDEX && i <=LFACE_SLANT_INDEX)
+	      font_clear_prop (to,
+			       (i == LFACE_FAMILY_INDEX ? FONT_FAMILY_INDEX
+				: i == LFACE_SWIDTH_INDEX ? FONT_WIDTH_INDEX
+				: i == LFACE_HEIGHT_INDEX ? FONT_SIZE_INDEX
+				: i == LFACE_WEIGHT_INDEX ? FONT_WEIGHT_INDEX
+				: FONT_SLANT_INDEX));
+	  }
       }
 
+  /* If `font' attribute is specified, reflect the font properties in
+     it to the other attributes.  */
+  if (0 && !UNSPECIFIEDP (to[LFACE_FONT_INDEX]))
+    font_update_lface (f, to);
+
   /* TO is always an absolute face, which should inherit from nothing.
      We blindly copy the :inherit attribute above and fix it up here.  */
   to[LFACE_INHERIT_INDEX] = Qnil;
@@ -3914,7 +2667,10 @@
 	      else if (EQ (keyword, QCfamily))
 		{
 		  if (STRINGP (value))
-		    to[LFACE_FAMILY_INDEX] = value;
+		    {
+		      to[LFACE_FAMILY_INDEX] = value;
+		      font_clear_prop (to, FONT_FAMILY_INDEX);
+		    }
 		  else
 		    err = 1;
 		}
@@ -3924,23 +2680,30 @@
 		    merge_face_heights (value, to[LFACE_HEIGHT_INDEX], Qnil);
 
 		  if (! NILP (new_height))
-		    to[LFACE_HEIGHT_INDEX] = new_height;
+		    {
+		      to[LFACE_HEIGHT_INDEX] = new_height;
+		      font_clear_prop (to, FONT_SIZE_INDEX);
+		    }
 		  else
 		    err = 1;
 		}
 	      else if (EQ (keyword, QCweight))
 		{
-		  if (SYMBOLP (value)
-		      && face_numeric_weight (value) >= 0)
-		    to[LFACE_WEIGHT_INDEX] = value;
+		  if (SYMBOLP (value) && FONT_WEIGHT_NAME_NUMERIC (value) >= 0)
+		    {
+		      to[LFACE_WEIGHT_INDEX] = value;
+		      font_clear_prop (to, FONT_WEIGHT_INDEX);
+		    }
 		  else
 		    err = 1;
 		}
 	      else if (EQ (keyword, QCslant))
 		{
-		  if (SYMBOLP (value)
-		      && face_numeric_slant (value) >= 0)
-		    to[LFACE_SLANT_INDEX] = value;
+		  if (SYMBOLP (value) && FONT_SLANT_NAME_NUMERIC (value) >= 0)
+		    {
+		      to[LFACE_SLANT_INDEX] = value;
+		      font_clear_prop (to, FONT_SLANT_INDEX);
+		    }
 		  else
 		    err = 1;
 		}
@@ -4017,9 +2780,11 @@
 		}
 	      else if (EQ (keyword, QCwidth))
 		{
-		  if (SYMBOLP (value)
-		      && face_numeric_swidth (value) >= 0)
-		    to[LFACE_SWIDTH_INDEX] = value;
+		  if (SYMBOLP (value) && FONT_WIDTH_NAME_NUMERIC (value) >= 0)
+		    {
+		      to[LFACE_SWIDTH_INDEX] = value;
+		      font_clear_prop (to, FONT_WIDTH_INDEX);
+		    }
 		  else
 		    err = 1;
 		}
@@ -4250,10 +3015,9 @@
 {
   Lisp_Object lface;
   Lisp_Object old_value = Qnil;
-  /* Set 1 if ATTR is QCfont.  */
-  int font_attr_p = 0;
-  /* Set 1 if ATTR is one of font-related attributes other than QCfont.  */
-  int font_related_attr_p = 0;
+  /* Set one of enum font_property_index (> 0) if ATTR is one of
+     font-related attributes other than QCfont and QCfontset.  */
+  enum font_property_index prop_index = 0;
 
   CHECK_SYMBOL (face);
   CHECK_SYMBOL (attr);
@@ -4308,7 +3072,7 @@
 	}
       old_value = LFACE_FAMILY (lface);
       LFACE_FAMILY (lface) = value;
-      font_related_attr_p = 1;
+      prop_index = FONT_FAMILY_INDEX;
     }
   else if (EQ (attr, QCheight))
     {
@@ -4329,31 +3093,31 @@
 
       old_value = LFACE_HEIGHT (lface);
       LFACE_HEIGHT (lface) = value;
-      font_related_attr_p = 1;
+      prop_index = FONT_SIZE_INDEX;
     }
   else if (EQ (attr, QCweight))
     {
       if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
 	{
 	  CHECK_SYMBOL (value);
-	  if (face_numeric_weight (value) < 0)
+	  if (FONT_WEIGHT_NAME_NUMERIC (value) < 0)
 	    signal_error ("Invalid face weight", value);
 	}
       old_value = LFACE_WEIGHT (lface);
       LFACE_WEIGHT (lface) = value;
-      font_related_attr_p = 1;
+      prop_index = FONT_WEIGHT_INDEX;
     }
   else if (EQ (attr, QCslant))
     {
       if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
 	{
 	  CHECK_SYMBOL (value);
-	  if (face_numeric_slant (value) < 0)
+	  if (FONT_SLANT_NAME_NUMERIC (value) < 0)
 	    signal_error ("Invalid face slant", value);
 	}
       old_value = LFACE_SLANT (lface);
       LFACE_SLANT (lface) = value;
-      font_related_attr_p = 1;
+      prop_index = FONT_SLANT_INDEX;
     }
   else if (EQ (attr, QCunderline))
     {
@@ -4516,84 +3280,70 @@
       if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
 	{
 	  CHECK_SYMBOL (value);
-	  if (face_numeric_swidth (value) < 0)
+	  if (FONT_WIDTH_NAME_NUMERIC (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) || EQ (attr, QCfontset))
+      prop_index = FONT_WIDTH_INDEX;
+    }
+  else if (EQ (attr, QCfont))
     {
 #ifdef HAVE_WINDOW_SYSTEM
       if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
 	{
-	  /* Set font-related attributes of the Lisp face from an XLFD
-	     font name.  */
-	  struct frame *f;
-	  Lisp_Object tmp;
-
-	  if (EQ (frame, Qt))
-	    f = SELECTED_FRAME ();
-	  else
-	    f = check_x_frame (frame);
-
-#ifdef USE_FONT_BACKEND
-	  if (enable_font_backend
-	      && !UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
+	  if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
 	    {
-	      tmp = Fquery_fontset (value, Qnil);
-	      if (EQ (attr, QCfontset))
+	      FRAME_PTR f;
+
+	      old_value = LFACE_FONT (lface);
+	      if (! FONTP (value))
 		{
-		  if (NILP (tmp))
-		    signal_error ("Invalid fontset name", value);
-		  LFACE_FONTSET (lface) = tmp;
-		}
-	      else
-		{
-		  int fontset;
-		  Lisp_Object font_object;
-
-		  if (! NILP (tmp))
+		  if (STRINGP (value))
 		    {
-		      fontset = fs_query_fontset (tmp, 0);
-		      value = fontset_ascii (fontset);
+		      int fontset = fs_query_fontset (value, 0);
+
+		      if (fontset >= 0)
+			value = fontset_ascii (fontset);
+		      else
+			value = font_spec_from_name (value);
 		    }
 		  else
-		    {
-		      fontset = FRAME_FONTSET (f);
-		    }
-		  font_object = font_open_by_name (f, SDATA (value));
+		    signal_error ("Invalid font or font-spec", value);
+		}
+	      if (EQ (frame, Qt))
+		f = XFRAME (selected_frame);
+	      else
+		f = XFRAME (frame);
+	      if (! FONT_OBJECT_P (value))
+		{
+		  Lisp_Object *attrs = XVECTOR (lface)->contents;
+		  Lisp_Object font_object;
+
+		  font_object = font_load_for_lface (f, attrs, value);
 		  if (NILP (font_object))
-		    signal_error ("Invalid font", value);
-		  set_lface_from_font_and_fontset (f, lface, font_object,
-						   fontset, 1);
+		    signal_error ("Font not available", value);
+		  value = font_object;
 		}
+	      set_lface_from_font (f, lface, value, 1);
 	    }
 	  else
-#endif	/* USE_FONT_BACKEND */
-	  if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
-	    {
-	      CHECK_STRING (value);
-
-	      /* VALUE may be a fontset name or an alias of fontset.  In
-		 such a case, use the base fontset name.  */
-	      tmp = Fquery_fontset (value, Qnil);
-	      if (!NILP (tmp))
-		value = tmp;
-	      else if (EQ (attr, QCfontset))
-		signal_error ("Invalid fontset name", value);
-
-	      if (EQ (attr, QCfont))
-		{
-		  if (!set_lface_from_font_name (f, lface, value, 1, 1))
-		    signal_error ("Invalid font or fontset name", value);
-		}
-	      else
-		LFACE_FONTSET (lface) = value;
-	    }
-
-	  font_attr_p = 1;
+	    LFACE_FONT (lface) = value;
+	}
+#endif /* HAVE_WINDOW_SYSTEM */
+    }
+  else if (EQ (attr, QCfontset))
+    {
+#ifdef HAVE_WINDOW_SYSTEM
+      if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
+	{
+	  Lisp_Object tmp;
+
+	  old_value = LFACE_FONTSET (lface);
+	  tmp = Fquery_fontset (value, Qnil);
+	  if (NILP (tmp))
+	    signal_error ("Invalid fontset name", value);
+	  LFACE_FONTSET (lface) = value = tmp;
 	}
 #endif /* HAVE_WINDOW_SYSTEM */
     }
@@ -4615,24 +3365,25 @@
     {
       old_value = LFACE_WEIGHT (lface);
       LFACE_WEIGHT (lface) = NILP (value) ? Qnormal : Qbold;
-      font_related_attr_p = 1;
+      prop_index = FONT_WEIGHT_INDEX;
     }
   else if (EQ (attr, QCitalic))
     {
+      attr = QCslant;
       old_value = LFACE_SLANT (lface);
       LFACE_SLANT (lface) = NILP (value) ? Qnormal : Qitalic;
-      font_related_attr_p = 1;
+      prop_index = FONT_SLANT_INDEX;
     }
   else
     signal_error ("Invalid face attribute name", attr);
 
-  if (font_related_attr_p
-      && !UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
-    /* If a font-related attribute other than QCfont is specified, the
-       original `font' attribute nor that of default face is useless
-       to determine a new font.  Thus, we set it to nil so that font
-       selection mechanism doesn't use it.  */
-    LFACE_FONT (lface) = Qnil;
+  if (prop_index)
+    /* If a font-related attribute other than QCfont and QCfontset is
+       specified, and if the original QCfont attribute has a font
+       (font-spec or font-object), set the corresponding property in
+       the font to nil so that the font selector doesn't think that
+       the attribute is mandatory.  */
+    font_clear_prop (XVECTOR (lface)->contents, prop_index);
 
   /* Changing a named face means that all realized faces depending on
      that face are invalid.  Since we cannot tell which realized faces
@@ -4641,9 +3392,7 @@
      init_iterator will then free realized faces.  */
   if (!EQ (frame, Qt)
       && NILP (Fget (face, Qface_no_inherit))
-      && (EQ (attr, QCfont)
-	  || EQ (attr, QCfontset)
-	  || NILP (Fequal (old_value, value))))
+      && NILP (Fequal (old_value, value)))
     {
       ++face_change_count;
       ++windows_or_buffers_changed;
@@ -4662,7 +3411,7 @@
 	  /* Changed font-related attributes of the `default' face are
 	     reflected in changed `font' frame parameters. */
 	  if (FRAMEP (frame)
-	      && (font_related_attr_p || font_attr_p)
+	      && (prop_index || EQ (attr, QCfont))
 	      && lface_fully_specified_p (XVECTOR (lface)->contents))
 	    set_font_frame_param (frame, lface);
 	  else
@@ -4749,11 +3498,8 @@
 
 #ifdef HAVE_WINDOW_SYSTEM
 
-/* Set the `font' frame parameter of FRAME determined from `default'
-   face attributes LFACE.  If a font name is explicitely
-   specfied in LFACE, use it as is.  Otherwise, determine a font name
-   from the other font-related atrributes of LFACE.  In that case, if
-   there's no matching font, signals an error.  */
+/* Set the `font' frame parameter of FRAME determined from the
+   font-object set in `default' face attributes LFACE.  */
 
 static void
 set_font_frame_param (frame, lface)
@@ -4763,43 +3509,17 @@
 
   if (FRAME_WINDOW_P (f))
     {
-      Lisp_Object font_name;
-      char *font;
-
-      if (STRINGP (LFACE_FONT (lface)))
-	font_name = LFACE_FONT (lface);
-#ifdef USE_FONT_BACKEND
-      else if (enable_font_backend)
+      Lisp_Object font = LFACE_FONT (lface);
+
+      if (FONT_SPEC_P (font))
 	{
-	  /* We set FONT_NAME to a font-object.  */
-	  if (FONT_OBJECT_P (LFACE_FONT (lface)))
-	    font_name = LFACE_FONT (lface);
-	  else
-	    {
-	      font_name = font_find_for_lface (f, &AREF (lface, 0), Qnil, -1);
-	      if (NILP (font_name))
-		error ("No font matches the specified attribute");
-	      font_name = font_open_for_lface (f, font_name, &AREF (lface, 0),
-					       Qnil);
-	      if (NILP (font_name))
-		error ("No font matches the specified attribute");
-	    }
+	  font = font_load_for_lface (f, XVECTOR (lface)->contents, font);
+	  if (NILP (font))
+	    return;
+	  LFACE_FONT (lface) = font;
 	}
-#endif
-      else
-	{
-	  /* Choose a font name that reflects LFACE's attributes and has
-	     the registry and encoding pattern specified in the default
-	     fontset (3rd arg: -1) for ASCII characters (4th arg: 0).  */
-	  font = choose_face_font (f, XVECTOR (lface)->contents, Qnil, NULL);
-	  if (!font)
-	    error ("No font matches the specified attribute");
-	  font_name = build_string (font);
-	  xfree (font);
-	}
-
       f->default_face_done_p = 0;
-      Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font_name), Qnil));
+      Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font), Qnil));
     }
 }
 
@@ -5031,14 +3751,14 @@
 	  changed_p = 1;
 	}
 
-      if (face->font_name
+      if (face->font
 	  && (!UNSPECIFIEDP (LFACE_FAMILY (lface))
 	      || !UNSPECIFIEDP (LFACE_SWIDTH (lface))
-	      || !UNSPECIFIEDP (LFACE_AVGWIDTH (lface))
 	      || !UNSPECIFIEDP (LFACE_WEIGHT (lface))
 	      || !UNSPECIFIEDP (LFACE_SLANT (lface))
 	      || !UNSPECIFIEDP (LFACE_HEIGHT (lface))))
 	{
+	  Lisp_Object xlfd = Ffont_xlfd_name (LFACE_FONT (lface));
 #ifdef USE_MOTIF
 	  const char *suffix = "List";
 	  Bool motif = True;
@@ -5051,22 +3771,26 @@
 #endif
 	  Bool motif = False;
 #endif
+
+	  if (! NILP (xlfd))
+	    {
 #if defined HAVE_X_I18N
-	  extern char *xic_create_fontsetname
-	    P_ ((char *base_fontname, Bool motif));
-	  char *fontsetname = xic_create_fontsetname (face->font_name, motif);
+	      extern char *xic_create_fontsetname
+		P_ ((char *base_fontname, Bool motif));
+	      char *fontsetname = xic_create_fontsetname (SDATA (xlfd), motif);
 #else
-	  char *fontsetname = face->font_name;
+	      char *fontsetname = (char *) SDATA (xlfd);
 #endif
-	  sprintf (line, "%s.pane.menubar*font%s: %s",
-		   myname, suffix, fontsetname);
-	  XrmPutLineResource (&rdb, line);
-	  sprintf (line, "%s.%s*font%s: %s",
-		   myname, popup_path, suffix, fontsetname);
-	  XrmPutLineResource (&rdb, line);
-	  changed_p = 1;
-	  if (fontsetname != face->font_name)
-	    xfree (fontsetname);
+	      sprintf (line, "%s.pane.menubar*font%s: %s",
+		       myname, suffix, fontsetname);
+	      XrmPutLineResource (&rdb, line);
+	      sprintf (line, "%s.%s*font%s: %s",
+		       myname, popup_path, suffix, fontsetname);
+	      XrmPutLineResource (&rdb, line);
+	      changed_p = 1;
+	      if (fontsetname != (char *) SDATA (xlfd))
+		xfree (fontsetname);
+	    }
 	}
 
       if (changed_p && f->output_data.x->menubar_widget)
@@ -5198,35 +3922,7 @@
 
   CHECK_SYMBOL (attr);
 
-  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))
+  if (EQ (attr, QCunderline))
     result = Fcons (Qt, Fcons (Qnil, Qnil));
   else if (EQ (attr, QCoverline))
     result = Fcons (Qt, Fcons (Qnil, Qnil));
@@ -5322,12 +4018,11 @@
 	  CHECK_CHARACTER (character);
 	  face_id = FACE_FOR_CHAR (f, face, XINT (character), -1, Qnil);
 	  face = FACE_FROM_ID (f, face_id);
-	  return (face->font && face->font_name
-		  ? build_string (face->font_name)
-		  : Qnil);
 	}
 #endif
-      return build_string (face->font_name);
+      return (face->font
+	      ? face->font->props[FONT_NAME_INDEX]
+	      : Qnil);
     }
 }
 
@@ -5490,7 +4185,7 @@
 
 /* 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, slant, font, and fontset.  Both
+   family, point size, weight, width, slant, and font.  Both
    LFACE1 and LFACE2 must be fully-specified.  */
 
 static INLINE int
@@ -5503,14 +4198,9 @@
 		    SDATA (lface2[LFACE_FAMILY_INDEX])) == 0
 	  && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX])
 	  && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX])
-	  && EQ (lface1[LFACE_AVGWIDTH_INDEX], lface2[LFACE_AVGWIDTH_INDEX])
 	  && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX])
 	  && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX])
-	  && (EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX])
-	      || (STRINGP (lface1[LFACE_FONT_INDEX])
-		  && STRINGP (lface2[LFACE_FONT_INDEX])
-		  && ! xstricmp (SDATA (lface1[LFACE_FONT_INDEX]),
-				 SDATA (lface2[LFACE_FONT_INDEX]))))
+	  && EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX])
 	  && (EQ (lface1[LFACE_FONTSET_INDEX], lface2[LFACE_FONTSET_INDEX])
 	      || (STRINGP (lface1[LFACE_FONTSET_INDEX])
 		  && STRINGP (lface2[LFACE_FONTSET_INDEX])
@@ -5559,10 +4249,8 @@
 	  if (face->gc)
 	    {
 	      BLOCK_INPUT;
-#ifdef USE_FONT_BACKEND
-	      if (enable_font_backend && face->font_info)
+	      if (face->font)
 		font_done_for_face (f, face);
-#endif	/* USE_FONT_BACKEND */
 	      x_free_gc (f, face->gc);
 	      face->gc = 0;
 	      UNBLOCK_INPUT;
@@ -5600,25 +4288,6 @@
 #ifdef HAVE_X_WINDOWS
       xgcv.graphics_exposures = False;
 #endif
-      /* The font of FACE may be null if we couldn't load it.  */
-      if (face->font)
-	{
-#ifdef HAVE_X_WINDOWS
-#ifdef USE_FONT_BACKEND
-	  if (enable_font_backend)
-	    xgcv.font = FRAME_X_DISPLAY_INFO (f)->font->fid;
-	  else
-#endif
-	  xgcv.font = face->font->fid;
-#endif
-#ifdef WINDOWSNT
-	  xgcv.font = face->font;
-#endif
-#ifdef MAC_OS
-	  xgcv.font = face->font;
-#endif
-	  mask |= GCFont;
-	}
 
       BLOCK_INPUT;
 #ifdef HAVE_X_WINDOWS
@@ -5630,10 +4299,8 @@
 	}
 #endif
       face->gc = x_create_gc (f, mask, &xgcv);
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend && face->font)
+      if (face->font)
 	font_prepare_for_face (f, face);
-#endif	/* USE_FONT_BACKEND */
       UNBLOCK_INPUT;
     }
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -5739,10 +4406,8 @@
 	  if (face && face->gc)
 	    {
 	      BLOCK_INPUT;
-#ifdef USE_FONT_BACKEND
-	      if (enable_font_backend && face->font_info)
+	      if (face->font)
 		font_done_for_face (c->f, face);
-#endif	/* USE_FONT_BACKEND */
 	      x_free_gc (c->f, face->gc);
 	      face->gc = 0;
 	      UNBLOCK_INPUT;
@@ -6029,16 +4694,15 @@
 
 #ifdef HAVE_WINDOW_SYSTEM
 /* Look up a realized face that has the same attributes as BASE_FACE
-   except for the font in the face cache of frame F.  If FONT_ID is
-   not negative, it is an ID number of an already opened font that is
-   used by the face.  If FONT_ID is negative, the face has no font.
-   Value is the ID of the face found.  If no suitable face is found,
-   realize a new one.  */
+   except for the font in the face cache of frame F.  If FONT-OBJECT
+   is not nil, it is an already opened font.  If FONT-OBJECT is nil,
+   the face has no font.  Value is the ID of the face found.  If no
+   suitable face is found, realize a new one.  */
 
 int
-lookup_non_ascii_face (f, font_id, base_face)
+face_for_font (f, font_object, base_face)
      struct frame *f;
-     int font_id;
+     Lisp_Object font_object;
      struct face *base_face;
 {
   struct face_cache *cache = FRAME_FACE_CACHE (f);
@@ -6056,58 +4720,16 @@
       if (face->ascii_face == face)
 	continue;
       if (face->ascii_face == base_face
-	  && face->font_info_id == font_id)
-	break;
-    }
-
-  /* If not found, realize a new face.  */
-  if (face == NULL)
-    face = realize_non_ascii_face (f, font_id, base_face);
-
-#if GLYPH_DEBUG
-  xassert (face == FACE_FROM_ID (f, face->id));
-#endif /* GLYPH_DEBUG */
-
-  return face->id;
-}
-
-#ifdef USE_FONT_BACKEND
-int
-face_for_font (f, font, base_face)
-     struct frame *f;
-     struct font *font;
-     struct face *base_face;
-{
-  struct face_cache *cache = FRAME_FACE_CACHE (f);
-  unsigned hash;
-  int i;
-  struct face *face;
-
-  xassert (cache != NULL);
-  base_face = base_face->ascii_face;
-  hash = lface_hash (base_face->lface);
-  i = hash % FACE_CACHE_BUCKETS_SIZE;
-
-  for (face = cache->buckets[i]; face; face = face->next)
-    {
-      if (face->ascii_face == face)
-	continue;
-      if (face->ascii_face == base_face
-	  && face->font == font->font.font
-	  && face->font_info == (struct font_info *) font)
+	  && face->font == (NILP (font_object) ? NULL
+			    : XFONT_OBJECT (font_object))
+	  && lface_equal_p (face->lface, base_face->lface))
 	return face->id;
     }
 
   /* If not found, realize a new face.  */
-  face = realize_non_ascii_face (f, -1, base_face);
-  face->font = font->font.font;
-  face->font_info = (struct font_info *) font;
-  face->font_info_id = 0;
-  face->font_name = font->font.full_name;
+  face = realize_non_ascii_face (f, font_object, base_face);
   return face->id;
 }
-#endif	/* USE_FONT_BACKEND */
-
 #endif	/* HAVE_WINDOW_SYSTEM */
 
 /* Return the face id of the realized face for named face SYMBOL on
@@ -6363,12 +4985,12 @@
       || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX])
       || !UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX])
       || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX])
-      || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])
-      || !UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX]))
+      || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]))
     {
       int face_id;
       struct face *face;
       Lisp_Object merged_attrs[LFACE_VECTOR_SIZE];
+      int i;
 
       bcopy (def_attrs, merged_attrs, sizeof merged_attrs);
 
@@ -6383,6 +5005,21 @@
       /* If the font is the same, then not supported.  */
       if (face->font == def_face->font)
 	return 0;
+      for (i = FONT_TYPE_INDEX; i <= FONT_SIZE_INDEX; i++)
+	if (! EQ (face->font->props[i], def_face->font->props[i]))
+	  {
+	    Lisp_Object s1, s2;
+
+	    if (i < FONT_FOUNDRY_INDEX || i > FONT_REGISTRY_INDEX
+		|| face->font->driver->case_sensitive)
+	      return 1;
+	    s1 = SYMBOL_NAME (face->font->props[i]);
+	    s2 = SYMBOL_NAME (def_face->font->props[i]);
+	    if (! EQ (Fcompare_strings (s1, make_number (0), Qnil,
+					s2, make_number (0), Qnil, Qt), Qt))
+	      return 1;
+	  }
+      return 0;
     }
 
   /* Everything checks out, this face is supported.  */
@@ -6443,24 +5080,24 @@
   /* Test for terminal `capabilities' (non-color character attributes).  */
 
   /* font weight (bold/dim) */
-  weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]);
+  weight = FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]);
   if (weight >= 0)
     {
-      int def_weight = face_numeric_weight (def_attrs[LFACE_WEIGHT_INDEX]);
-
-      if (weight > XLFD_WEIGHT_MEDIUM)
+      int def_weight = FONT_WEIGHT_NAME_NUMERIC (def_attrs[LFACE_WEIGHT_INDEX]);
+
+      if (weight > 100)
 	{
-	  if (def_weight > XLFD_WEIGHT_MEDIUM)
+	  if (def_weight > 100)
 	    return 0;		/* same as default */
 	  test_caps = TTY_CAP_BOLD;
 	}
-      else if (weight < XLFD_WEIGHT_MEDIUM)
+      else if (weight < 100)
 	{
-	  if (def_weight < XLFD_WEIGHT_MEDIUM)
+	  if (def_weight < 100)
 	    return 0;		/* same as default */
 	  test_caps = TTY_CAP_DIM;
 	}
-      else if (def_weight == XLFD_WEIGHT_MEDIUM)
+      else if (def_weight == 100)
 	return 0;		/* same as default */
     }
 
@@ -6713,10 +5350,7 @@
       free_all_realized_faces (Qnil);
     }
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    font_update_sort_order (font_sort_order);
-#endif	/* USE_FONT_BACKEND */
+  font_update_sort_order (font_sort_order);
 
   return Qnil;
 }
@@ -6758,494 +5392,10 @@
 
 #ifdef HAVE_WINDOW_SYSTEM
 
-/* 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.  */
-
-static int
-font_scalable_p (font)
-     struct font_name *font;
-{
-  char *s = font->fields[XLFD_AVGWIDTH];
-  return (*s == '0' && *(s + 1) == '\0')
-#ifdef WINDOWSNT
-  /* Windows implementation of XLFD is slightly broken for backward
-     compatibility with previous broken versions, so test for
-     wildcards as well as 0. */
-  || *s == '*'
-#endif
-    ;
-}
-
-
 /* Ignore the difference of font point size less than this value.  */
 
 #define FONT_POINT_SIZE_QUANTUM 5
 
-/* 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.  AVGWIDTH, if not zero, is a specified font average width
-   to compare with.  */
-
-static int
-better_font_p (values, font1, font2, compare_pt_p, avgwidth)
-     int *values;
-     struct font_name *font1, *font2;
-     int compare_pt_p, avgwidth;
-{
-  int i;
-
-  /* Any font is better than no font.  */
-  if (! font1)
-    return 0;
-  if (! font2)
-    return 1;
-
-  for (i = 0; i < DIM (font_sort_order); ++i)
-    {
-      int xlfd_idx = font_sort_order[i];
-
-      if (compare_pt_p || xlfd_idx != XLFD_POINT_SIZE)
-	{
-	  int delta1, delta2;
-
-	  if (xlfd_idx == XLFD_POINT_SIZE)
-	    {
-	      delta1 = eabs (values[i] - (font1->numeric[xlfd_idx]
-					 / font1->rescale_ratio));
-	      delta2 = eabs (values[i] - (font2->numeric[xlfd_idx]
-					 / font2->rescale_ratio));
-	      if (eabs (delta1 - delta2) < FONT_POINT_SIZE_QUANTUM)
-		continue;
-	    }
-	  else
-	    {
-	      delta1 = eabs (values[i] - font1->numeric[xlfd_idx]);
-	      delta2 = eabs (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;
-	    }
-	}
-    }
-
-  if (avgwidth)
-    {
-      int delta1 = eabs (avgwidth - font1->numeric[XLFD_AVGWIDTH]);
-      int delta2 = eabs (avgwidth - font2->numeric[XLFD_AVGWIDTH]);
-      if (delta1 > delta2)
-	return 0;
-      else if (delta1 < delta2)
-	return 1;
-    }
-
-  if (! compare_pt_p)
-    {
-      /* We prefer a real scalable font; i.e. not what autoscaled.  */
-      int auto_scaled_1 = (font1->numeric[XLFD_POINT_SIZE] == 0
-			   && font1->numeric[XLFD_RESY] > 0);
-      int auto_scaled_2 = (font2->numeric[XLFD_POINT_SIZE] == 0
-			   && font2->numeric[XLFD_RESY] > 0);
-
-      if (auto_scaled_1 != auto_scaled_2)
-	return auto_scaled_2;
-    }
-
-  return font1->registry_priority < font2->registry_priority;
-}
-
-
-/* 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.  AVGWIDTH, if non-zero, is an average width to compare
-   with.  */
-
-static int
-exact_face_match_p (specified, font, avgwidth)
-     int *specified;
-     struct font_name *font;
-     int avgwidth;
-{
-  int i;
-
-  for (i = 0; i < DIM (font_sort_order); ++i)
-    if (specified[i] != font->numeric[font_sort_order[i]])
-      break;
-
-  return (i == DIM (font_sort_order)
-	  && (avgwidth <= 0
-	      || avgwidth == font->numeric[XLFD_AVGWIDTH]));
-}
-
-
-/* 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 pixel_size[20];
-  int pixel_value;
-  double resy = FRAME_X_DISPLAY_INFO (f)->resy;
-  double pt;
-
-  if (font->numeric[XLFD_PIXEL_SIZE] != 0
-      || font->numeric[XLFD_POINT_SIZE] != 0)
-    /* This is a scalable font but is requested for a specific size.
-       We should not change that size.  */
-    return build_font_name (font);
-
-  /* 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] / (PT_PER_INCH * 10.0) * pt + 0.5;
-    }
-  else
-    {
-      pt = specified_pt;
-      pixel_value = resy / (PT_PER_INCH * 10.0) * pt + 0.5;
-    }
-  /* We may need a font of the different size.  */
-  pixel_value *= font->rescale_ratio;
-
-  /* We should keep POINT_SIZE 0.  Otherwise, X server can't open a
-     font of the specified PIXEL_SIZE.  */
-#if 0
-  { /* Set point size of the font.  */
-    char point_size[20];
-    sprintf (point_size, "%d", (int) pt);
-    font->fields[XLFD_POINT_SIZE] = point_size;
-    font->numeric[XLFD_POINT_SIZE] = pt;
-  }
-#endif
-
-  /* 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_X_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)
-     const char *font;
-{
-  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, font) >= 0)
-	    return 1;
-	}
-    }
-
-  return 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.  WIDTH_RATIO is a factor with which to multiply average
-   widths if ATTRS specifies such a width.
-
-   Value is a font name which is allocated from the heap.  FONTS is
-   freed by this function.
-
-   If NEEDS_OVERSTRIKE is non-zero, a boolean is returned in it to
-   indicate whether the resulting font should be drawn using overstrike
-   to simulate bold-face.  */
-
-static char *
-best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike)
-     struct frame *f;
-     Lisp_Object *attrs;
-     struct font_name *fonts;
-     int nfonts;
-     int width_ratio;
-     int *needs_overstrike;
-{
-  char *font_name;
-  struct font_name *best;
-  int i, pt = 0;
-  int specified[5];
-  int exact_p, avgwidth;
-
-  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 ();
-    }
-
-  avgwidth = (UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX])
-	      ? 0
-	      : XFASTINT (attrs[LFACE_AVGWIDTH_INDEX]) * width_ratio);
-
-  exact_p = 0;
-
-  if (needs_overstrike)
-    *needs_overstrike = 0;
-
-  best = NULL;
-
-  /* Find the best match among the non-scalable fonts.  */
-  for (i = 0; i < nfonts; ++i)
-    if (!font_scalable_p (fonts + i)
-	&& better_font_p (specified, fonts + i, best, 1, avgwidth))
-      {
-	best = fonts + i;
-
-	exact_p = exact_face_match_p (specified, best, avgwidth);
-	if (exact_p)
-	  break;
-      }
-
-  /* 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 (better_font_p (specified, fonts + i, best, 0, 0)
-		|| (!non_scalable_has_exact_height_p
-		    && !better_font_p (specified, best, fonts + i, 0, 0)))
-	      {
-		non_scalable_has_exact_height_p = 1;
-		best = fonts + i;
-	      }
-	  }
-    }
-
-  /* We should have found SOME font.  */
-  if (best == NULL)
-    abort ();
-
-  if (! exact_p && needs_overstrike)
-    {
-      enum xlfd_weight want_weight = specified[XLFD_WEIGHT];
-      enum xlfd_weight got_weight = best->numeric[XLFD_WEIGHT];
-
-      if (want_weight > XLFD_WEIGHT_MEDIUM && want_weight > got_weight)
-	{
-	  /* We want a bold font, but didn't get one; try to use
-	     overstriking instead to simulate bold-face.  However,
-	     don't overstrike an already-bold font unless the
-	     desired weight grossly exceeds the available weight.  */
-	  if (got_weight > XLFD_WEIGHT_MEDIUM)
-	    *needs_overstrike = (want_weight - got_weight) > 2;
-	  else
-	    *needs_overstrike = 1;
-	}
-    }
-
-  if (font_scalable_p (best))
-    font_name = build_scalable_font_name (f, best, pt);
-  else
-    font_name = build_font_name (best);
-
-  /* Free font_name structures.  */
-  free_font_names (fonts, nfonts);
-
-  return font_name;
-}
-
-
-/* Get a list of matching fonts on frame F, considering FAMILY
-   and alternative font families from Vface_alternative_font_registry_alist.
-
-   FAMILY is the font family whose alternatives are considered.
-
-   REGISTRY, if a string, specifies a font registry and encoding to
-   match.  A value of nil means include fonts of any registry and
-   encoding.
-
-   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_alternative_families (f, family, registry, fonts)
-     struct frame *f;
-     Lisp_Object family, registry;
-     struct font_name **fonts;
-{
-  Lisp_Object alter;
-  int nfonts = 0;
-
-  nfonts = font_list (f, Qnil, family, registry, fonts);
-  if (nfonts == 0)
-    {
-      /* Try alternative font families.  */
-      alter = Fassoc (family, Vface_alternative_font_family_alist);
-      if (CONSP (alter))
-	{
-	  for (alter = XCDR (alter);
-	       CONSP (alter) && nfonts == 0;
-	       alter = XCDR (alter))
-	    {
-	      if (STRINGP (XCAR (alter)))
-		nfonts = font_list (f, Qnil, XCAR (alter), registry, fonts);
-	    }
-	}
-
-      /* Try all scalable fonts before giving up.  */
-      if (nfonts == 0 && ! EQ (Vscalable_fonts_allowed, Qt))
-	{
-	  int count = SPECPDL_INDEX ();
-	  specbind (Qscalable_fonts_allowed, Qt);
-	  nfonts = try_alternative_families (f, family, registry, fonts);
-	  unbind_to (count, Qnil);
-	}
-    }
-  return nfonts;
-}
-
-
-/* Get a list of matching fonts on frame F.
-
-   PATTERN, if a string, specifies a font name pattern to match while
-   ignoring FAMILY and REGISTRY.
-
-   FAMILY, if a list, specifies a list of font families to try.
-
-   REGISTRY, if a list, specifies a list of font registries and
-   encodinging to try.
-
-   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, pattern, family, registry, fonts)
-     struct frame *f;
-     Lisp_Object pattern, family, registry;
-     struct font_name **fonts;
-{
-  int nfonts = 0;
-
-  if (STRINGP (pattern))
-    {
-      nfonts = font_list (f, pattern, Qnil, Qnil, fonts);
-      if (nfonts == 0 && ! EQ (Vscalable_fonts_allowed, Qt))
-	{
-	  int count = SPECPDL_INDEX ();
-	  specbind (Qscalable_fonts_allowed, Qt);
-	  nfonts = font_list (f, pattern, Qnil, Qnil, fonts);
-	  unbind_to (count, Qnil);
-	}
-    }
-  else
-    {
-      Lisp_Object tail;
-
-      if (NILP (family))
-	nfonts = font_list (f, Qnil, Qnil, registry, fonts);
-      else
-	for (tail = family; ! nfonts && CONSP (tail); tail = XCDR (tail))
-	  nfonts = try_alternative_families (f, XCAR (tail), registry, fonts);
-
-      /* Try font family of the default face or "fixed".  */
-      if (nfonts == 0 && !NILP (family))
-	{
-	  struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID);
-	  if (default_face)
-	    family = default_face->lface[LFACE_FAMILY_INDEX];
-	  else
-	    family = build_string ("fixed");
-	  nfonts = try_alternative_families (f, family, registry, fonts);
-	}
-
-      /* Try any family with the given registry.  */
-      if (nfonts == 0 && !NILP (family))
-	nfonts = try_alternative_families (f, Qnil, registry, fonts);
-    }
-
-  return nfonts;
-}
-
-
 /* Return the fontset id of the base fontset name or alias name given
    by the fontset attribute of ATTRS.  Value is -1 if the fontset
    attribute of ATTRS doesn't name a fontset.  */
@@ -7262,107 +5412,6 @@
   return fs_query_fontset (name, 0);
 }
 
-
-/* Choose a name of font to use on frame F to display characters with
-   Lisp face attributes specified by ATTRS.  The font name is
-   determined by the font-related attributes in ATTRS and FONT-SPEC
-   (if specified).
-
-   When we are choosing a font for ASCII characters, FONT-SPEC is
-   always nil.  Otherwise FONT-SPEC is an object created by
-   `font-spec' or a string specifying a font name pattern.
-
-   If NEEDS_OVERSTRIKE is not NULL, a boolean is returned in it to
-   indicate whether the resulting font should be drawn using
-   overstrike to simulate bold-face.
-
-   Value is the font name which is allocated from the heap and must be
-   freed by the caller.  */
-
-char *
-choose_face_font (f, attrs, font_spec, needs_overstrike)
-     struct frame *f;
-     Lisp_Object *attrs;
-     Lisp_Object font_spec;
-     int *needs_overstrike;
-{
-  Lisp_Object pattern, family, adstyle, registry;
-  char *font_name = NULL;
-  struct font_name *fonts;
-  int nfonts;
-
-  if (needs_overstrike)
-    *needs_overstrike = 0;
-
-  /* If we are choosing an ASCII font and a font name is explicitly
-     specified in ATTRS, return it.  */
-  if (NILP (font_spec) && STRINGP (attrs[LFACE_FONT_INDEX]))
-    return xstrdup (SDATA (attrs[LFACE_FONT_INDEX]));
-
-  if (NILP (attrs[LFACE_FAMILY_INDEX]))
-    family = Qnil;
-  else
-    family = Fcons (attrs[LFACE_FAMILY_INDEX], Qnil);
-
-  /* Decide FAMILY, ADSTYLE, and REGISTRY from FONT_SPEC.  But,
-     ADSTYLE is not used in the font selector for the moment.  */
-  if (VECTORP (font_spec))
-    {
-      pattern = Qnil;
-      if (! NILP (AREF (font_spec, FONT_FAMILY_INDEX)))
-	family = Fcons (SYMBOL_NAME (AREF (font_spec, FONT_FAMILY_INDEX)),
-			family);
-      adstyle = AREF (font_spec, FONT_ADSTYLE_INDEX);
-      registry = Fcons (SYMBOL_NAME (AREF (font_spec, FONT_REGISTRY_INDEX)),
-			Qnil);
-    }
-  else if (STRINGP (font_spec))
-    {
-      pattern = font_spec;
-      family = Qnil;
-      adstyle = Qnil;
-      registry = Qnil;
-    }
-  else
-    {
-      /* We are choosing an ASCII font.  By default, use the registry
-	 name "iso8859-1".  But, if the registry name of the ASCII
-	 font specified in the fontset of ATTRS is not "iso8859-1"
-	 (e.g "iso10646-1"), use also that name with higher
-	 priority.  */
-      int fontset = face_fontset (attrs);
-      Lisp_Object ascii;
-      int len;
-      struct font_name font;
-
-      pattern = Qnil;
-      adstyle = Qnil;
-      registry = Fcons (build_string ("iso8859-1"), Qnil);
-
-      ascii = fontset_ascii (fontset);
-      len = SBYTES (ascii);
-      if (len < 9
-	  || strcmp (SDATA (ascii) + len - 9, "iso8859-1"))
-	{
-	  font.name = LSTRDUPA (ascii);
-	  /* Check if the name is in XLFD.  */
-	  if (split_font_name (f, &font, 0))
-	    {
-	      font.fields[XLFD_ENCODING][-1] = '-';
-	      registry = Fcons (build_string (font.fields[XLFD_REGISTRY]),
-				registry);
-	    }
-	}
-    }
-
-  /* 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, pattern, family, registry, &fonts);
-  font_name = best_matching_font (f, attrs, fonts, nfonts, NILP (font_spec),
-				  needs_overstrike);
-  return font_name;
-}
-
 #endif /* HAVE_WINDOW_SYSTEM */
 
 
@@ -7431,7 +5480,6 @@
   struct face_cache *c = FRAME_FACE_CACHE (f);
   Lisp_Object lface;
   Lisp_Object attrs[LFACE_VECTOR_SIZE];
-  Lisp_Object frame_font;
   struct face *face;
 
   /* If the `default' face is not yet known, create it.  */
@@ -7443,31 +5491,14 @@
        lface = Finternal_make_lisp_face (Qdefault, frame);
   }
 
-
 #ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f))
     {
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend)
-	{
-	  frame_font = font_find_object (FRAME_FONT_OBJECT (f));
-	  xassert (FONT_OBJECT_P (frame_font));
-	  set_lface_from_font_and_fontset (f, lface, frame_font,
-					   FRAME_FONTSET (f),
-					   f->default_face_done_p);
-	}
-      else
-	{
-#endif	/* USE_FONT_BACKEND */
-      /* 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);
-      set_lface_from_font_name (f, lface, frame_font,
-                                f->default_face_done_p, 1);
-#ifdef USE_FONT_BACKEND
-	}
-#endif	/* USE_FONT_BACKEND */
+      Lisp_Object font_object;
+
+      XSETFONT (font_object, FRAME_FONT (f));
+      set_lface_from_font (f, lface, font_object, f->default_face_done_p);
+      LFACE_FONTSET (lface) = fontset_name (FRAME_FONTSET (f));
       f->default_face_done_p = 1;
     }
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -7481,7 +5512,6 @@
 	LFACE_WEIGHT (lface) = Qnormal;
       if (UNSPECIFIEDP (LFACE_SLANT (lface)))
 	LFACE_SLANT (lface) = Qnormal;
-      LFACE_AVGWIDTH (lface) = Qunspecified;
     }
 
   if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
@@ -7552,7 +5582,7 @@
  	 acceptable as a font for the default face (perhaps because
  	 auto-scaled fonts are rejected), so we must adjust the frame
  	 font.  */
-      x_set_font (f, build_string (face->font_name), Qnil);
+      x_set_font (f, LFACE_FONT (lface), Qnil);
     }
 #endif	/* HAVE_X_WINDOWS */
 #endif	/* HAVE_WINDOW_SYSTEM */
@@ -7642,45 +5672,32 @@
 
 
 #ifdef HAVE_WINDOW_SYSTEM
-/* Realize the fully-specified face that has the same attributes as
-   BASE_FACE except for the font on frame F.  If FONT_ID is not
-   negative, it is an ID number of an already opened font that should
-   be used by the face.  If FONT_ID is negative, the face has no font,
-   i.e., characters are displayed by empty boxes.  */
+/* Realize the fully-specified face that uses FONT-OBJECT and has the
+   same attributes as BASE_FACE except for the font on frame F.
+   FONT-OBJECT may be nil, in which case, realized a face of
+   no-font.  */
 
 static struct face *
-realize_non_ascii_face (f, font_id, base_face)
+realize_non_ascii_face (f, font_object, base_face)
      struct frame *f;
-     int font_id;
+     Lisp_Object font_object;
      struct face *base_face;
 {
   struct face_cache *cache = FRAME_FACE_CACHE (f);
   struct face *face;
-  struct font_info *font_info;
 
   face = (struct face *) xmalloc (sizeof *face);
   *face = *base_face;
   face->gc = 0;
-#ifdef USE_FONT_BACKEND
   face->extra = NULL;
-#endif	/* USE_FONT_BACKEND */
+  face->overstrike
+    = (! NILP (font_object)
+       && FONT_WEIGHT_NAME_NUMERIC (face->lface[LFACE_WEIGHT_INDEX]) > 100
+       && FONT_WEIGHT_NUMERIC (font_object) <= 100);
 
   /* Don't try to free the colors copied bitwise from BASE_FACE.  */
   face->colors_copied_bitwise_p = 1;
-
-  face->font_info_id = font_id;
-  if (font_id >= 0)
-    {
-      font_info = FONT_INFO_FROM_ID (f, font_id);
-      face->font = font_info->font;
-      face->font_name = font_info->full_name;
-    }
-  else
-    {
-      face->font = NULL;
-      face->font_name = NULL;
-    }
-
+  face->font = NILP (font_object) ? NULL : XFONT_OBJECT (font_object);
   face->gc = 0;
 
   cache_face (cache, face, face->hash);
@@ -7723,14 +5740,7 @@
       && lface_same_font_attributes_p (default_face->lface, attrs))
     {
       face->font = default_face->font;
-      face->font_info_id = default_face->font_info_id;
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend)
-	face->font_info = default_face->font_info;
-#endif	/* USE_FONT_BACKEND */
-      face->font_name = default_face->font_name;
-      face->fontset
-	= make_fontset_for_ascii_face (f, default_face->fontset, face);
+      face->fontset = make_fontset_for_ascii_face (f, -1, face);
     }
   else
     {
@@ -7750,17 +5760,25 @@
 	fontset = default_face->fontset;
       if (fontset == -1)
 	abort ();
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend)
-	font_load_for_face (f, face);
+      if (! FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]))
+	attrs[LFACE_FONT_INDEX]
+	  = font_load_for_lface (f, attrs, attrs[LFACE_FONT_INDEX]);
+      if (FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]))
+	{
+	  face->font = XFONT_OBJECT (attrs[LFACE_FONT_INDEX]);
+	  face->fontset = make_fontset_for_ascii_face (f, fontset, face);
+	}
       else
-#endif	/* USE_FONT_BACKEND */
-	load_face_font (f, face);
-      if (face->font)
-	face->fontset = make_fontset_for_ascii_face (f, fontset, face);
-      else
-	face->fontset = -1;
-    }
+	{
+	  face->font = NULL;
+	  face->fontset = -1;
+	}
+    }
+
+  if (face->font
+      && FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]) > 100
+      && FONT_WEIGHT_NUMERIC (attrs[LFACE_FONT_INDEX]) <= 100)
+    face->overstrike = 1;
 
   /* Load colors, and set remaining attributes.  */
 
@@ -7997,17 +6015,18 @@
 
   /* Allocate a new realized face.  */
   face = make_realized_face (attrs);
+#if 0
   face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty";
+#endif
 
   /* 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)
+  weight = FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]);
+  slant = FONT_SLANT_NAME_NUMERIC (attrs[LFACE_SLANT_INDEX]);
+  if (weight > 100)
     face->tty_bold_p = 1;
-  if (weight < XLFD_WEIGHT_MEDIUM || slant != XLFD_SLANT_ROMAN)
+  if (weight < 100 || slant != 100)
     face->tty_dim_p = 1;
   if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
     face->tty_underline_p = 1;
@@ -8466,13 +6485,13 @@
   fprintf (stderr, "background: 0x%lx (%s)\n",
 	   face->background,
 	   SDATA (face->lface[LFACE_BACKGROUND_INDEX]));
-  fprintf (stderr, "font_name: %s (%s)\n",
-	   face->font_name,
-	   SDATA (face->lface[LFACE_FAMILY_INDEX]));
+  if (face->font)
+    fprintf (stderr, "font_name: %s (%s)\n",
+	     SDATA (face->font->props[FONT_NAME_INDEX]),
+	     SDATA (face->lface[LFACE_FAMILY_INDEX]));
 #ifdef HAVE_X_WINDOWS
   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,