(Fnew_fontset): Call font_unparse_xlfd with 256-byte
[bpt/emacs.git] / src / fontset.c
index 82d1445..82e5b4e 100644 (file)
@@ -1,8 +1,8 @@
 /* Fontset handler.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
      Free Software Foundation, Inc.
    Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-     2005, 2006, 2007
+     2005, 2006, 2007, 2008
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H14PRO021
    Copyright (C) 2003, 2006
  
 This file is part of GNU Emacs.
 
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,9 +22,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* #define FONTSET_DEBUG */
 
@@ -94,36 +92,16 @@ EXFUN (Fclear_face_cache, 1);
    An element of a base fontset is a vector of FONT-DEFs which itself
    is a vector [ FONT-SPEC ENCODING REPERTORY ].
 
-   FONT-SPEC is a font-spec created by `font-spec' or
-       ( FAMILY . REGISTRY )
-   or
-       FONT-NAME
-   where FAMILY, REGISTRY, and FONT-NAME are strings.
+   An element of a realized fontset is nil, t, or a vector of this form:
 
-   ENCODING is a charset ID that can convert characters to glyph codes
-   of the corresponding font.
-
-   REPERTORY is a charset ID, a char-table, or nil.  If REPERTORY is a
-   charset ID, the repertory of the charset exactly matches with that
-   of the font.  If REPERTORY is a char-table, all characters who have
-   a non-nil value in the table are supported.  If REPERTORY is nil,
-   we consult with the font itself to get the repertory.
-
-   ENCODING and REPERTORY are extracted from the variable
-   Vfont_encoding_alist by using a font name generated from FONT-SPEC
-   (if it is a vector) or FONT-NAME as a matching target.
-
-
-   An element of a realized fontset is nil or t, or has this form:
-
-       [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID
-        PREFERRED-RFONT-DEF RFONT-DEF0 RFONT-DEF1 ...].
+       [ CHARSET-ORDERED-LIST-TICK PREFERRED-RFONT-DEF
+         RFONT-DEF0 RFONT-DEF1 ... ]
 
    RFONT-DEFn (i.e. Realized FONT-DEF) has this form:
 
-       [ FACE-ID FONT-INDEX FONT-DEF OPENED-FONT-NAME ]
+       [ FACE-ID FONT-DEF FONT-OBJECT SORTING-SCORE ]
 
-   RFONT-DEFn is automatically reordered by the current charset
+   RFONT-DEFn are automatically reordered by the current charset
    priority list.
 
    The value nil means that we have not yet generated the above vector
@@ -214,6 +192,7 @@ static int next_fontset_id;
 static Lisp_Object Vdefault_fontset;
 
 Lisp_Object Vfont_encoding_alist;
+Lisp_Object Vfont_encoding_charset_alist;
 Lisp_Object Vuse_default_ascent;
 Lisp_Object Vignore_relative_composition;
 Lisp_Object Valternate_fontname_alist;
@@ -221,40 +200,6 @@ Lisp_Object Vfontset_alias_alist;
 Lisp_Object Vvertical_centering_font_regexp;
 Lisp_Object Votf_script_alist;
 
-/* The following six are declarations of callback functions depending
-   on window system.  See the comments in src/fontset.h for more
-   detail.  */
-
-/* Return a pointer to struct font_info of font FONT_IDX of frame F.  */
-struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
-
-/* Return a list of font names which matches PATTERN.  See the documentation
-   of `x-list-fonts' for more details.  */
-Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
-                                   Lisp_Object pattern,
-                                   int size,
-                                   int maxnames));
-
-/* Load a font named NAME for frame F and return a pointer to the
-   information of the loaded font.  If loading is failed, return 0.  */
-struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
-
-/* Return a pointer to struct font_info of a font named NAME for frame F.  */
-struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
-
-/* Additional function for setting fontset or changing fontset
-   contents of frame F.  */
-void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
-                                   Lisp_Object oldval));
-
-/* To find a CCL program, fs_load_font calls this function.
-   The argument is a pointer to the struct font_info.
-   This function set the member `encoder' of the structure.  */
-void (*find_ccl_program_func) P_ ((struct font_info *));
-
-Lisp_Object (*get_font_repertory_func) P_ ((struct frame *,
-                                           struct font_info *));
-
 /* Check if any window system is used now.  */
 void (*check_window_system_func) P_ ((void));
 
@@ -262,6 +207,9 @@ void (*check_window_system_func) P_ ((void));
 /* Prototype declarations for static functions.  */
 static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
                                    Lisp_Object));
+static Lisp_Object fontset_find_font P_ ((Lisp_Object, int, struct face *,
+                                         int, int));
+static void reorder_font_vector P_ ((Lisp_Object, Lisp_Object));
 static Lisp_Object fontset_font P_ ((Lisp_Object, int, struct face *, int));
 static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
 static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
@@ -297,10 +245,12 @@ fontset_id_valid_p (id)
 /* Macros to access special values of (base) FONTSET.  */
 #define FONTSET_NAME(fontset)          XCHAR_TABLE (fontset)->extras[1]
 #define FONTSET_ASCII(fontset)         XCHAR_TABLE (fontset)->extras[4]
+#define FONTSET_SPEC(fontset)          XCHAR_TABLE (fontset)->extras[5]
 
 /* Macros to access special values of (realized) FONTSET.  */
 #define FONTSET_BASE(fontset)          XCHAR_TABLE (fontset)->extras[2]
 #define FONTSET_FRAME(fontset)         XCHAR_TABLE (fontset)->extras[3]
+#define FONTSET_OBJLIST(fontset)       XCHAR_TABLE (fontset)->extras[4]
 #define FONTSET_NOFONT_FACE(fontset)   XCHAR_TABLE (fontset)->extras[5]
 #define FONTSET_REPERTORY(fontset)     XCHAR_TABLE (fontset)->extras[6]
 #define FONTSET_DEFAULT(fontset)       XCHAR_TABLE (fontset)->extras[7]
@@ -311,6 +261,38 @@ fontset_id_valid_p (id)
 #define BASE_FONTSET_P(fontset)                (NILP (FONTSET_BASE (fontset)))
 
 
+/* Macros for FONT-DEF and RFONT-DEF of fontset.  */
+#define FONT_DEF_NEW(font_def, font_spec, encoding, repertory) \
+  do {                                                         \
+    (font_def) = Fmake_vector (make_number (3), (font_spec));  \
+    ASET ((font_def), 1, encoding);                            \
+    ASET ((font_def), 2, repertory);                           \
+  } while (0)
+
+#define FONT_DEF_SPEC(font_def) AREF (font_def, 0)
+#define FONT_DEF_ENCODING(font_def) AREF (font_def, 1)
+#define FONT_DEF_REPERTORY(font_def) AREF (font_def, 2)
+
+#define RFONT_DEF_FACE(rfont_def) AREF (rfont_def, 0)
+#define RFONT_DEF_SET_FACE(rfont_def, face_id) \
+  ASET ((rfont_def), 0, make_number (face_id))
+#define RFONT_DEF_FONT_DEF(rfont_def) AREF (rfont_def, 1)
+#define RFONT_DEF_SPEC(rfont_def) FONT_DEF_SPEC (AREF (rfont_def, 1))
+#define RFONT_DEF_REPERTORY(rfont_def) FONT_DEF_REPERTORY (AREF (rfont_def, 1))
+#define RFONT_DEF_OBJECT(rfont_def) AREF (rfont_def, 2)
+#define RFONT_DEF_SET_OBJECT(rfont_def, object)        \
+  ASET ((rfont_def), 2, (object))
+#define RFONT_DEF_SCORE(rfont_def) XINT (AREF (rfont_def, 3))
+#define RFONT_DEF_SET_SCORE(rfont_def, score) \
+  ASET ((rfont_def), 3, make_number (score))
+#define RFONT_DEF_NEW(rfont_def, font_def)             \
+  do {                                                 \
+    (rfont_def) = Fmake_vector (make_number (4), Qnil);        \
+    ASET ((rfont_def), 1, (font_def));         \
+    RFONT_DEF_SET_SCORE ((rfont_def), 0);              \
+  } while (0)
+
+
 /* Return the element of FONTSET for the character C.  If FONTSET is a
    base fontset other then the default fontset and FONTSET doesn't
    contain information for C, return the information in the default
@@ -336,43 +318,6 @@ fontset_ref (fontset, c)
   return elt;
 }
 
-
-/* Return the element of FONTSET for the character C, set FROM and TO
-   to the range of characters around C that have the same value as C.
-   If FONTSET is a base fontset other then the default fontset and
-   FONTSET doesn't contain information for C, return the information
-   in the default fontset.  */
-
-#define FONTSET_REF_AND_RANGE(fontset, c, form, to)    \
-  (EQ (fontset, Vdefault_fontset)                      \
-   ? char_table_ref_and_range (fontset, c, &from, &to) \
-   : fontset_ref_and_range (fontset, c, &from, &to))
-
-static Lisp_Object
-fontset_ref_and_range (fontset, c, from, to)
-     Lisp_Object fontset;
-     int c;
-     int *from, *to;
-{
-  Lisp_Object elt;
-
-  elt = char_table_ref_and_range (fontset, c, from, to);
-  if (NILP (elt) && ! EQ (fontset, Vdefault_fontset)
-      /* Don't check Vdefault_fontset for a realized fontset.  */
-      && NILP (FONTSET_BASE (fontset)))
-    {
-      int from1, to1;
-
-      elt = char_table_ref_and_range (Vdefault_fontset, c, &from1, &to1);
-      if (*from < from1)
-       *from = from1;
-      if (*to > to1)
-       *to = to1;
-    }
-  return elt;
-}
-
-
 /* Set elements of FONTSET for characters in RANGE to the value ELT.
    RANGE is a cons (FROM . TO), where FROM and TO are character codes
    specifying a range.  */
@@ -429,113 +374,101 @@ fontset_add (fontset, range, elt, add)
   return Qnil;
 }
 
+static int
+fontset_compare_rfontdef (val1, val2)
+     const void *val1, *val2;
+{
+  return (RFONT_DEF_SCORE (*(Lisp_Object *) val2)
+         - RFONT_DEF_SCORE (*(Lisp_Object *) val1));
+}
+
+/* Update FONT-GROUP which has this form:
+       [ CHARSET-ORDERED-LIST-TICK PREFERRED-RFONT-DEF
+         RFONT-DEF0 RFONT-DEF1 ... ]
+   Reorder RFONT-DEFs according to the current langauge, and update
+   CHARSET-ORDERED-LIST-TICK.
+
+   If PREFERRED_FAMILY is not nil, that family has the higher priority
+   if the encoding charsets or languages in font-specs are the same.  */
 
-/* Update FONTSET_ELEMENT which has this form:
-       [CHARSET-ORDERED-LIST-TICK PREFERRED-CHARSET-ID PREFERRED-RFONT-DEF
-        RFONT-DEF0 RFONT-DEF1 ...].
-   Reorder RFONT-DEFs according to the current order of charset
-   (Vcharset_ordered_list), and update CHARSET-ORDERED-LIST-TICK to
-   the latest value.  */
+extern Lisp_Object Fassoc_string ();
 
 static void
-reorder_font_vector (fontset_element)
-     Lisp_Object fontset_element;
+reorder_font_vector (font_group, preferred_family)
+     Lisp_Object font_group;
+     Lisp_Object preferred_family;
 {
-  Lisp_Object list, *new_vec;
-  Lisp_Object font_def;
   int size;
-  int *charset_id_table;
-  int i, idx;
+  int i;
+  int score_changed = 0;
 
-  ASET (fontset_element, 0, make_number (charset_ordered_list_tick));
-  size = ASIZE (fontset_element) - 3;
-  if (size <= 1)
-    /* No need to reorder VEC.  */
-    return;
-  charset_id_table = (int *) alloca (sizeof (int) * size);
-  new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size);
+  size = ASIZE (font_group);
+  /* Exclude the tailing nil elements from the reordering.  */
+  while (NILP (AREF (font_group, size - 1))) size--;
+  size -= 2;
 
-  /* At first, extract ENCODING (a chaset ID) from each FONT-DEF.
-     FONT-DEF has this form:
-       [FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]] */
   for (i = 0; i < size; i++)
     {
-      font_def = AREF (fontset_element, i + 3);
-      if (VECTORP (AREF (font_def, 2))
-         && INTEGERP (AREF (AREF (font_def, 2), 1)))
-       charset_id_table[i] = XINT (AREF (AREF (font_def, 2), 1));
-      else
-       charset_id_table[i] = -1;
-    }
-
-  /* Then, store FONT-DEFs in NEW_VEC in the correct order.  */
-  for (idx = 0, list = Vcharset_ordered_list;
-       idx < size && CONSP (list); list = XCDR (list))
-    {
-      for (i = 0; i < size; i++)
-       if (charset_id_table[i] == XINT (XCAR (list)))
-         new_vec[idx++] = AREF (fontset_element, i + 3);
-    }
-  for (i = 0; i < size; i++)
-    if (charset_id_table[i] < 0)
-      new_vec[idx++] = AREF (fontset_element, i + 3);
+      Lisp_Object rfont_def = AREF (font_group, i + 2);
+      Lisp_Object font_def = RFONT_DEF_FONT_DEF (rfont_def);
+      Lisp_Object font_spec = FONT_DEF_SPEC (font_def);
+      Lisp_Object lang = Ffont_get (font_spec, QClang);
+      Lisp_Object family = AREF (font_spec, FONT_FAMILY_INDEX);
+      Lisp_Object repertory = FONT_DEF_REPERTORY (font_def);
+      int score = 0;
+
+      if (! NILP (repertory))
+       {  
+         Lisp_Object tail;
 
-  /* At last, update FONT-DEFs.  */
-  for (i = 0; i < size; i++)
-    ASET (fontset_element, i + 3, new_vec[i]);
-}
+         for (score = 0xFFFF, tail = Vcharset_ordered_list;
+              ! EQ (tail, Vcharset_non_preferred_head) && CONSP (tail);
+              score--, tail = XCDR (tail))
+           if (EQ (repertory, XCAR (tail)))
+             break;
+         if (EQ (tail, Vcharset_non_preferred_head))
+           score = 0;
+       }
+      else if (! NILP (lang))
+       {
+         if (EQ (lang, Vcurrent_iso639_language))
+           score = 0xFFFF;
+         else if (CONSP (Vcurrent_iso639_language))
+           score = ! NILP (Fmemq (lang, Vcurrent_iso639_language));
+       }
 
+      if (! NILP (preferred_family) && ! NILP (family))
+       {
+         if (fast_string_match_ignore_case (preferred_family,
+                                            SYMBOL_NAME (family)) < 0)
+           score |= 0x10000;
+       }
+      if (RFONT_DEF_SCORE (rfont_def) != score)
+       {
+         RFONT_DEF_SET_SCORE (rfont_def, score);
+         score_changed = 1;
+       }
+    }
 
-/* Load a font matching the font related attributes in FACE->lface and
-   font pattern in FONT_DEF of FONTSET, and return an index of the
-   font.  FONT_DEF has this form:
-       [ FONT-SPEC ENCODING REPERTORY ]
-   If REPERTORY is nil, generate a char-table representing the font
-   repertory by looking into the font itself.  */
+  if (score_changed)
+    qsort (XVECTOR (font_group)->contents + 2, size, sizeof (Lisp_Object),
+          fontset_compare_rfontdef);
 
-static int
-load_font_get_repertory (f, face, font_def, fontset)
-     FRAME_PTR f;
-     struct face *face;
-     Lisp_Object font_def;
-     Lisp_Object fontset;
-{
-  char *font_name;
-  struct font_info *font_info;
-  int charset;
-
-  font_name = choose_face_font (f, face->lface, AREF (font_def, 0), NULL);
-  charset = XINT (AREF (font_def, 1));
-  if (! (font_info = fs_load_font (f, font_name, charset)))
-    return -1;
-
-  if (NILP (AREF (font_def, 2))
-      && NILP (Fassq (make_number (font_info->font_idx),
-                     FONTSET_REPERTORY (fontset))))
-    {
-      /* We must look into the font to get the correct repertory as a
-        char-table.  */
-      Lisp_Object repertory;
-
-      repertory = (*get_font_repertory_func) (f, font_info);
-      FONTSET_REPERTORY (fontset)
-       = Fcons (Fcons (make_number (font_info->font_idx), repertory),
-                FONTSET_REPERTORY (fontset));
-    }
-       
-  return font_info->font_idx;
+  ASET (font_group, 0, make_number (charset_ordered_list_tick));
 }
 
-static Lisp_Object fontset_find_font P_ ((Lisp_Object, int, struct face *,
-                                         int, int));
-
 /* Return RFONT-DEF (vector) in the realized fontset FONTSET for the
-   character C.  If the corresponding font is not yet opened, open it
-   (if FACE is not NULL) or return Qnil (if FACE is NULL).
-   If no proper font is found for C, return Qnil.
+   character C.  If no font is found, return Qnil if there's a
+   possibility that the default fontset or the fallback font groups
+   have a proper font, and return Qt if not.
+
+   If a font is found but is not yet opened, open it (if FACE is not
+   NULL) or return Qnil (if FACE is NULL).
+
    ID is a charset-id that must be preferred, or -1 meaning no
    preference.
-   If FALLBACK if nonzero, search only fallback fonts.  */
+
+   If FALLBACK is nonzero, search only fallback fonts.  */
 
 static Lisp_Object
 fontset_find_font (fontset, c, face, id, fallback)
@@ -544,9 +477,8 @@ fontset_find_font (fontset, c, face, id, fallback)
      struct face *face;
      int id, fallback;
 {
-  Lisp_Object base_fontset, elt, vec, font_def;
+  Lisp_Object base_fontset, elt, vec;
   int i, from, to;
-  int font_idx;
   FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
 
   base_fontset = FONTSET_BASE (fontset);
@@ -554,110 +486,92 @@ fontset_find_font (fontset, c, face, id, fallback)
     vec = CHAR_TABLE_REF (fontset, c);
   else
     vec = FONTSET_FALLBACK (fontset);
+
   if (NILP (vec))
     {
-      /* We have not yet decided a font for C.  */
       Lisp_Object range;
 
+      /* We have not yet decided a font for C.  */
       if (! face)
        return Qnil;
       if (! fallback)
-       elt = FONTSET_REF_AND_RANGE (base_fontset, c, from, to);
+       {
+         elt = char_table_ref_and_range (base_fontset, c, &from, &to);
+         range = Fcons (make_number (from), make_number (to));
+       }
       else
-       elt = FONTSET_FALLBACK (base_fontset);
-      range = Fcons (make_number (from), make_number (to));
+       {
+         elt = FONTSET_FALLBACK (base_fontset);
+       }
       if (NILP (elt))
        {
-         /* Qt means we have no font for characters of this range.  */
+         /* This fontset doesn't specify any font for C. */
+         vec = make_number (0);
+       }
+      else if (ASIZE (elt) == 1 && NILP (AREF (elt, 0)))
+       {
+         /* Explicitly specified no font.  */
          vec = Qt;
        }
       else
        {
-         /* Build a vector [ -1 -1 nil NEW-ELT0 NEW-ELT1 NEW-ELT2 ... ],
-            where the first -1 is to force reordering of NEW-ELTn,
-            NEW-ELTn is [nil nil AREF (elt, n) nil].  */
-#ifdef USE_FONT_BACKEND
-         if (! fallback
-             && enable_font_backend
-             && EQ (base_fontset, Vdefault_fontset))
-           /* Extra one element is for an automatically added
-              font-def specifying only a script.  */
-           vec = Fmake_vector (make_number (ASIZE (elt) + 4), Qnil);
-         else
-#endif /* not USE_FONT_BACKEND */
-           vec = Fmake_vector (make_number (ASIZE (elt) + 3), Qnil);
-         ASET (vec, 0, make_number (-1));
-         ASET (vec, 1, make_number (-1));
-         for (i = 0; i < ASIZE (elt); i++)
-           {
-             Lisp_Object tmp;
-
-             tmp = Fmake_vector (make_number (5), Qnil);
-             ASET (tmp, 2, AREF (elt, i));
-             ASET (vec, 3 + i, tmp);
-           }
-#ifdef USE_FONT_BACKEND
-         if (! fallback
-             && enable_font_backend
-             && EQ (base_fontset, Vdefault_fontset))
-           {
-             Lisp_Object script, font_spec;
-
-             script = CHAR_TABLE_REF (Vchar_script_table, c);
-             if (NILP (script))
-               script = intern ("latin");
-             font_spec = Ffont_spec (0, NULL);
-             ASET (font_spec, FONT_REGISTRY_INDEX, Qiso10646_1);
-             ASET (font_spec, FONT_EXTRA_INDEX,
-                   Fcons (Fcons (QCscript, script), Qnil));
-             font_def = Fmake_vector (make_number (3), Qnil);
-             ASET (font_def, 0, font_spec);
-             elt = Fmake_vector (make_number (5), Qnil);
-             ASET (elt, 2, font_def);
-             ASET (vec, 3 + i, elt);
-           }
-#endif /* USE_FONT_BACKEND */
+         /* Build a font-group vector [ -1 nil RFONT-DEF0 RFONT-DEF1 ... ],
+            where the first -1 is to force reordering of RFONT-DEFs.  */
+         int size = ASIZE (elt);
+         int j;
 
-         /* Then store it in the fontset.  */
-         if (! fallback)
-           FONTSET_SET (fontset, range, vec);
-         else
-           FONTSET_FALLBACK (fontset) = vec;
+         vec = Fmake_vector (make_number (size + 2), Qnil);
+         ASET (vec, 0, make_number (-1));
+         for (i = j = 0; i < size; i++)
+           if (! NILP (AREF (elt, i)))
+             {
+               Lisp_Object rfont_def;
+
+               RFONT_DEF_NEW (rfont_def, AREF (elt, i));
+               ASET (vec, j + 2, rfont_def);
+               j++;
+             }
        }
-    }
-  if (EQ (vec, Qt))
-    return Qnil;
-
-  if (XINT (AREF (vec, 0)) != charset_ordered_list_tick)
-    /* The priority of charsets is changed after we selected a face
-       for C last time.  */
-    reorder_font_vector (vec);
+      /* Then store it in the fontset.  */
+      if (! fallback)
+       FONTSET_SET (fontset, range, vec);
+      else
+       FONTSET_FALLBACK (fontset) = vec;
 
-  if (id < 0)
-    i = 3;
-  else
+    }
+  if (! VECTORP (vec))
+    return (EQ (vec, Qt) ? Qt : Qnil);
+
+  if (ASIZE (vec) > 4          /* multiple RFONT-DEFs */
+      && XINT (AREF (vec, 0)) != charset_ordered_list_tick)
+    /* We have just created VEC,
+       or the charset priorities were changed.  */
+    reorder_font_vector (vec, face->lface[LFACE_FAMILY_INDEX]);
+  i = 2;
+  if (id >= 0)
     {
-      struct charset *charset = CHARSET_FROM_ID (id);
-
-      if (charset->supplementary_p)
-       i = 3;
-      else if (id == XFASTINT (AREF (vec, 1)))
-       i = 2;
+      elt = AREF (vec, 1);
+      if (! NILP (elt)
+         && EQ (make_number (id), RFONT_DEF_REPERTORY (elt)))
+       i = 1;
       else
        {
-         ASET (vec, 1, make_number (id));
-         for (i = 3; i < ASIZE (vec); i++)
-           if (id == XFASTINT (AREF (AREF (AREF (vec, i), 2), 1)))
-             break;
+         for (; i < ASIZE (vec); i++)
+           {
+             elt = AREF (vec, i);
+             if (! NILP (elt)
+                 && EQ (make_number (id), RFONT_DEF_REPERTORY (elt)))
+               break;
+           }
          if (i < ASIZE (vec))
            {
-             ASET (vec, 2, AREF (vec, i));
-             i = 2;
+             ASET (vec, 1, elt);
+             i = 1;
            }
          else
            {
-             ASET (vec, 2, Qnil);
-             i = 3;
+             ASET (vec, 1, Qnil);
+             i = 2;
            }
        }
     }
@@ -665,168 +579,91 @@ fontset_find_font (fontset, c, face, id, fallback)
   /* Find the first available font in the vector of RFONT-DEF.  */
   for (; i < ASIZE (vec); i++)
     {
+      Lisp_Object font_def, font_entity, font_object;
+
       elt = AREF (vec, i);
       if (NILP (elt))
+       /* This is the sign of not to try fallback fonts.  */
+       return Qt;
+      if (id >= 0 && i > 1 && EQ (AREF (vec, 1), elt))
+       /* This is already checked.  */
        continue;
-      /* ELT == [ FACE-ID FONT-INDEX FONT-DEF OPENED-FONT-NAME ] */
-      if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0)
+      if (INTEGERP (RFONT_DEF_FACE (elt))
+         && XINT (AREF (elt, 1)) < 0)
        /* We couldn't open this font last time.  */
        continue;
 
-      if (!face && NILP (AREF (elt, 1)))
-       /* We have not yet opened the font.  */
-       return Qnil;
-
-      font_def = AREF (elt, 2);
-      /* FONT_DEF == [ FONT-SPEC ENCODING REPERTORY ] */
-
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend)
+      font_object = RFONT_DEF_OBJECT (elt);
+      if (NILP (font_object))
        {
-         /* ELT == [ FACE-ID FONT-INDEX FONT-DEF FONT-LIST ]
-            where FONT-LIST is a list of font-entity or font-object.  */
-         Lisp_Object font_list = AREF (elt, 3), prev = Qnil;
-         Lisp_Object font_object;
-         int has_char;
-
-         for (; CONSP (font_list);
-              prev = font_list, font_list = XCDR (font_list))
+         Lisp_Object font_def = RFONT_DEF_FONT_DEF (elt);
+
+         if (! face)
+           /* We have not yet opened the font.  */
+           return Qnil;
+         font_entity = font_find_for_lface (f, face->lface,
+                                            FONT_DEF_SPEC (font_def), -1);
+         if (NILP (font_entity))
            {
-             font_object = XCAR (font_list);
-             if (! (FONT_ENTITY_P (font_object)
-                    && FONT_ENTITY_NOT_LOADABLE (font_object))
-                 && (has_char = font_has_char (f, font_object, c)) != 0)
-               {
-                 if (has_char < 0)
-                   {
-                     Lisp_Object obj = font_open_for_lface (f, font_object,
-                                                            face->lface, Qnil);
-                     if (NILP (obj))
-                       {
-                         FONT_ENTITY_SET_NOT_LOADABLE (font_object);
-                         continue;
-                       }
-                     font_object = obj;
-                     XSETCAR (font_list, font_object);
-                     if (! font_has_char (f, font_object, c))
-                       continue;
-                   }
-                 if (! NILP (prev))
-                   {
-                     /* Move this element to the head.  */
-                     XSETCDR (prev, XCDR (font_list));
-                     ASET (elt, 3, Fcons (XCAR (font_list), AREF (elt, 3)));
-                   }
-                 break;
-               }
+             /* Record that no font matches the spec.  */
+             RFONT_DEF_SET_FACE (elt, -1);
+             continue;
            }
-         if (NILP (font_list))
+         font_object = font_open_for_lface (f, font_entity, face->lface, Qnil);
+         if (NILP (font_object))
            {
-             Lisp_Object font_spec = AREF (font_def, 0);
-             Lisp_Object font_entity;
-
-             if (! FONT_SPEC_P (font_spec))
-               {
-                 /* FONT_SPEC is FONT-NAME or (FAMILY . REGISTRY).  */
-                 font_spec = Ffont_spec (0, NULL);
-                 if (STRINGP (AREF (font_def, 0)))
-                   font_merge_old_spec (AREF (font_def, 0), Qnil, Qnil,
-                                        font_spec);
-                 else
-                   {
-                     Lisp_Object family = AREF (AREF (font_def, 0), 0);
-                     Lisp_Object registry = AREF (AREF (font_def, 0), 5);;
-
-                     font_merge_old_spec (Qnil, family, registry, font_spec);
-                   }
-                 ASET (font_def, 0, font_spec);
-               }
-             font_entity = font_find_for_lface (f, face->lface, font_spec, c);
-             if (NILP (font_entity))
-               continue;
-             font_list = Fcons (font_entity, AREF (elt, 3));
-             ASET (elt, 3, font_list);
+             /* Record that the font is unsable.  */
+             RFONT_DEF_SET_FACE (elt, -1);
+             continue;
            }
-         font_object = XCAR (font_list);
-         if (FONT_ENTITY_P (font_object))
-           {
-             font_object = font_open_for_lface (f, font_object,
-                                                face->lface, Qnil);
-             if (NILP (font_object))
-               {
-                 FONT_ENTITY_SET_NOT_LOADABLE (XCAR (font_list));
-                 continue;
-               }
-             XSETCAR (font_list, font_object);
-           }
-         ASET (elt, 1, make_number (0));
+         RFONT_DEF_SET_OBJECT (elt, font_object);
        }
-      else
-#endif /* USE_FONT_BACKEND */
-
-      if (INTEGERP (AREF (font_def, 2)))
-       {
-         /* The repertory is specified by charset ID.  */
-         struct charset *charset
-           = CHARSET_FROM_ID (XINT (AREF (font_def, 2)));
+      
+      if (font_has_char (f, font_object, c))
+       return elt;
 
-         if (! CHAR_CHARSET_P (c, charset))
-           /* This font can't display C.  */
-           continue;
-       }
-      else if (CHAR_TABLE_P (AREF (font_def, 2)))
+#if 0
+      /* The following code makes Emacs to find a font for C by fairly
+        exhausitive search.  But, that takes long time especially for
+        X font backend.  */
+
+      /* Try to find the different font maching with the current spec
+        and support C. */
+      font_def = RFONT_DEF_FONT_DEF (elt);
+      for (i++; i < ASIZE (vec); i++)
        {
-         /* The repertory is specified by a char table.  */
-         if (NILP (CHAR_TABLE_REF (AREF (font_def, 2), c)))
-           /* This font can't display C.  */
-           continue;
+         if (! EQ (RFONT_DEF_FONT_DEF (AREF (vec, i)), font_def))
+           break;
+         if (font_has_char (f, RFONT_DEF_OBJECT (AREF (vec, i)), c))
+           return AREF (vec, i);
        }
-      else
+      /* Find an font-entity that support C.  */
+      font_entity = font_find_for_lface (f, face->lface,
+                                        FONT_DEF_SPEC (font_def), c);
+      if (! NILP (font_entity))
        {
-         Lisp_Object slot;
-
-         if (! INTEGERP (AREF (elt, 1)))
-           {
-             /* We have not yet opened a font matching this spec.
-                Open the best matching font now and register the
-                repertory.  */
-             struct font_info *font_info;
-
-             font_idx = load_font_get_repertory (f, face, font_def, fontset);
-             ASET (elt, 1, make_number (font_idx));
-             if (font_idx < 0)
-               /* This means that we couldn't find a font matching
-                  FONT_DEF.  */
-               continue;
-             font_info = (*get_font_info_func) (f, font_idx);
-             ASET (elt, 3, build_string (font_info->full_name));
-           }
-
-         slot = Fassq (AREF (elt, 1), FONTSET_REPERTORY (fontset));
-         xassert (CONSP (slot));
-         if (NILP (CHAR_TABLE_REF (XCDR (slot), c)))
-           /* This font can't display C.  */
-           continue;
+         Lisp_Object rfont_def, new_vec;
+         int j;
+
+         font_object = font_open_for_lface (f, font_entity, face->lface,
+                                            Qnil);
+         RFONT_DEF_NEW (rfont_def, font_def);
+         RFONT_DEF_SET_OBJECT (rfont_def, font_object);
+         RFONT_DEF_SET_SCORE (rfont_def, RFONT_DEF_SCORE (elt));
+         new_vec = Fmake_vector (make_number (ASIZE (vec) + 1), Qnil);
+         for (j = 0; j < i; j++)
+           ASET (new_vec, j, AREF (vec, j));
+         ASET (new_vec, j, rfont_def);
+         for (j++; j < ASIZE (new_vec); j++)
+           ASET (new_vec, j, AREF (vec, j - 1));
+         vec = new_vec;
+         return rfont_def;
        }
-
-      /* Now we have decided to use this font spec to display C.  */
-      if (! INTEGERP (AREF (elt, 1)))
-       {
-         /* But not yet opened the best matching font.  */
-         struct font_info *font_info;
-
-         font_idx = load_font_get_repertory (f, face, font_def, fontset);
-         ASET (elt, 1, make_number (font_idx));
-         if (font_idx < 0)
-           /* Can't open it.  Try the other one.  */
-           continue;
-         font_info = (*get_font_info_func) (f, font_idx);
-         ASET (elt, 3, build_string (font_info->full_name));
-       }
-
-      /* Now we have the opened font.  */
-      return elt;
+      i--;
+#endif /* 0 */
     }
+
+  FONTSET_SET (fontset, make_number (c), make_number (0));
   return Qnil;
 }
 
@@ -843,8 +680,10 @@ fontset_font (fontset, c, face, id)
 
   /* Try a font-group for C. */
   rfont_def = fontset_find_font (fontset, c, face, id, 0);
-  if (! NILP (rfont_def))
+  if (VECTORP (rfont_def))
     return rfont_def;
+  if (EQ (rfont_def, Qt))
+    return Qnil;
   base_fontset = FONTSET_BASE (fontset);
   /* Try a font-group for C of the default fontset. */
   if (! EQ (base_fontset, Vdefault_fontset))
@@ -853,16 +692,21 @@ fontset_font (fontset, c, face, id)
        FONTSET_DEFAULT (fontset)
          = make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
       rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 0);
+      if (VECTORP (rfont_def))
+       return (rfont_def);
     }
-  if (! NILP (rfont_def))
-    return rfont_def;
+
   /* Try a fallback font-group. */
   rfont_def = fontset_find_font (fontset, c, face, id, 1);
-  if (! NILP (rfont_def))
-    return rfont_def;
-  /* Try a fallback font-group of the default fontset . */
-  if (! EQ (base_fontset, Vdefault_fontset))
+  if (! VECTORP (rfont_def)
+      && ! EQ (base_fontset, Vdefault_fontset))
+    /* Try a fallback font-group of the default fontset . */
     rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 1);
+
+  if (! VECTORP (rfont_def))
+    /* Remeber that we have no font for C.  */
+    FONTSET_SET (fontset, make_number (c), Qt);
+
   return rfont_def;
 }
 
@@ -950,15 +794,25 @@ fontset_ascii (id)
 
   fontset= FONTSET_FROM_ID (id);
   elt = FONTSET_ASCII (fontset);
-#ifdef USE_FONT_BACKEND
   if (CONSP (elt))
     elt = XCAR (elt);
-#endif  /* USE_FONT_BACKEND */
-  /* It is assured that ELT is always a string (i.e. fontname
-     pattern).  */
   return elt;
 }
 
+void
+free_realized_fontset (f, fontset)
+     FRAME_PTR f;
+     Lisp_Object fontset;
+{
+  Lisp_Object tail;
+
+  return;
+  for (tail = FONTSET_OBJLIST (fontset); CONSP (tail); tail = XCDR (tail))
+    {
+      xassert (FONT_OBJECT_P (XCAR (tail)));
+      font_close_object (f, XCAR (tail));
+    }
+}
 
 /* Free fontset of FACE defined on frame F.  Called from
    free_realized_face.  */
@@ -970,9 +824,12 @@ free_face_fontset (f, face)
 {
   Lisp_Object fontset;
 
-  fontset = AREF (Vfontset_table, face->fontset);
-  xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
+  fontset = FONTSET_FROM_ID (face->fontset);
+  if (NILP (fontset))
+    return;
+  xassert (! BASE_FONTSET_P (fontset));
   xassert (f == XFRAME (FONTSET_FRAME (fontset)));
+  free_realized_fontset (f, fontset);
   ASET (Vfontset_table, face->fontset, Qnil);
   if (face->fontset < next_fontset_id)
     next_fontset_id = face->fontset;
@@ -983,10 +840,12 @@ free_face_fontset (f, face)
       fontset = AREF (Vfontset_table, id);
       xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
       xassert (f == XFRAME (FONTSET_FRAME (fontset)));
+      free_realized_fontset (f, fontset);
       ASET (Vfontset_table, id, Qnil);
       if (id < next_fontset_id)
        next_fontset_id = face->fontset;
     }
+  face->fontset = -1;
 }
 
 
@@ -1004,8 +863,8 @@ face_suitable_for_char_p (face, c)
   fontset = FONTSET_FROM_ID (face->fontset);
   rfont_def = fontset_font (fontset, c, NULL, -1);
   return (VECTORP (rfont_def)
-         && INTEGERP (AREF (rfont_def, 0))
-         && face->id == XINT (AREF (rfont_def, 0)));
+         && INTEGERP (RFONT_DEF_FACE (rfont_def))
+         && face->id == XINT (RFONT_DEF_FACE (rfont_def)));
 }
 
 
@@ -1020,7 +879,7 @@ face_for_char (f, face, c, pos, object)
      int c, pos;
      Lisp_Object object;
 {
-  Lisp_Object fontset, charset, rfont_def;
+  Lisp_Object fontset, rfont_def;
   int face_id;
   int id;
 
@@ -1034,43 +893,47 @@ face_for_char (f, face, c, pos, object)
     id = -1;
   else
     {
+      Lisp_Object charset;
+
       charset = Fget_char_property (make_number (pos), Qcharset, object);
       if (NILP (charset))
        id = -1;
       else if (CHARSETP (charset))
-       id = XINT (CHARSET_SYMBOL_ID (charset));
+       {
+         Lisp_Object val;
+
+         val = assoc_no_quit (charset, Vfont_encoding_charset_alist);
+         if (CONSP (val) && CHARSETP (XCDR (val)))
+           charset = XCDR (val);
+         id = XINT (CHARSET_SYMBOL_ID (charset));
+       }
     }
   rfont_def = fontset_font (fontset, c, face, id);
   if (VECTORP (rfont_def))
     {
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend
-         && NILP (AREF (rfont_def, 0)))
-       {
-         struct font *font = XSAVE_VALUE (XCAR (AREF (rfont_def, 3)))->pointer;
-
-         face_id = face_for_font (f, font, face);
-         ASET (rfont_def, 0, make_number (face_id));
-       }
+      if (INTEGERP (RFONT_DEF_FACE (rfont_def)))
+       face_id = XINT (RFONT_DEF_FACE (rfont_def));
       else
-#endif /* USE_FONT_BACKEND */
-      if (NILP (AREF (rfont_def, 0)))
        {
-         /* We have not yet made a realized face that uses this font.  */
-         int font_idx = XINT (AREF (rfont_def, 1));
+         Lisp_Object font_object;
 
-         face_id = lookup_non_ascii_face (f, font_idx, face);
-         ASET (rfont_def, 0, make_number (face_id));
+         font_object = RFONT_DEF_OBJECT (rfont_def);
+         face_id = face_for_font (f, font_object, face);
+         RFONT_DEF_SET_FACE (rfont_def, face_id);
        }
-      return XINT (AREF (rfont_def, 0));
     }
-
-  if (NILP (FONTSET_NOFONT_FACE (fontset)))
+  else
     {
-      face_id = lookup_non_ascii_face (f, -1, face);
-      FONTSET_NOFONT_FACE (fontset) = make_number (face_id);
+      if (INTEGERP (FONTSET_NOFONT_FACE (fontset)))
+       face_id = XINT (FONTSET_NOFONT_FACE (fontset));
+      else
+       {
+         face_id = face_for_font (f, Qnil, face);
+         FONTSET_NOFONT_FACE (fontset) = make_number (face_id);
+       }
     }
-  return XINT (FONTSET_NOFONT_FACE (fontset));
+  xassert (face_id >= 0);
+  return face_id;
 }
 
 
@@ -1093,7 +956,6 @@ make_fontset_for_ascii_face (f, base_fontset_id, face)
       base_fontset = FONTSET_FROM_ID (base_fontset_id);
       if (!BASE_FONTSET_P (base_fontset))
        base_fontset = FONTSET_BASE (base_fontset);
-      xassert (BASE_FONTSET_P (base_fontset));
       if (! BASE_FONTSET_P (base_fontset))
        abort ();
     }
@@ -1101,111 +963,14 @@ make_fontset_for_ascii_face (f, base_fontset_id, face)
     base_fontset = Vdefault_fontset;
 
   fontset = make_fontset (frame, Qnil, base_fontset);
-  {
-    Lisp_Object elt, rfont_def, val;
-
-    elt = FONTSET_REF (base_fontset, 0);
-    xassert (VECTORP (elt) && ASIZE (elt) > 0);
-    rfont_def = Fmake_vector (make_number (4), Qnil);
-#ifdef USE_FONT_BACKEND
-    if (enable_font_backend && face->font_info)
-      {
-       struct font *font = (struct font *) face->font_info;
-
-       ASET (rfont_def, 3, Fcons (font->entity, Qnil));
-      }
-    else
-#endif  /* USE_FONT_BACKEND */
-    {
-      ASET (rfont_def, 3, build_string (face->font_name));
-    }
-    ASET (rfont_def, 1, make_number (face->font_info_id));
-    ASET (rfont_def, 2, AREF (elt, 0));
-    elt = Fmake_vector (make_number (4), Qnil);
-    ASET (elt, 0, make_number (charset_ordered_list_tick));
-    ASET (elt, 1, make_number (charset_ascii));
-    ASET (elt, 2, rfont_def);
-    ASET (elt, 3, rfont_def);
-
-    val = Fcons (Qlatin, Qnil);
-    map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table, val);
-    for (val = XCDR (val); CONSP (val); val = XCDR (val))
-      char_table_set_range (fontset, XINT (XCAR (XCAR (val))),
-                           XINT (XCDR (XCAR (val))), elt);
-    FONTSET_FALLBACK (fontset) = elt;
-  }
   return XINT (FONTSET_ID (fontset));
 }
 
-
-#if defined(WINDOWSNT) && defined (_MSC_VER)
-#pragma optimize("", off)
-#endif
-
-/* Load a font named FONTNAME on frame F.  Return a pointer to the
-   struct font_info of the loaded font.  If loading fails, return
-   NULL.  CHARSET is an ID of charset to encode characters for this
-   font.  If it is -1, find one from Vfont_encoding_alist.  */
-
-struct font_info *
-fs_load_font (f, fontname, charset)
-     FRAME_PTR f;
-     char *fontname;
-     int charset;
-{
-  struct font_info *fontp;
-  Lisp_Object fullname;
-
-  if (!fontname)
-    /* No way to get fontname.  */
-    return NULL;
-
-  fontp = (*load_font_func) (f, fontname, 0);
-  if (! fontp || fontp->charset >= 0)
-    return fontp;
-
-  fontname = fontp->full_name;
-  fullname = build_string (fontp->full_name);
-
-  if (charset < 0)
-    {
-      Lisp_Object charset_symbol;
-
-      charset_symbol = find_font_encoding (fullname);
-      if (CONSP (charset_symbol))
-       charset_symbol = XCAR (charset_symbol);
-      if (NILP (charset_symbol))
-       charset_symbol = Qascii;
-      charset = XINT (CHARSET_SYMBOL_ID (charset_symbol));
-    }
-  fontp->charset = charset;
-  fontp->vertical_centering = 0;
-  fontp->font_encoder = NULL;
-
-  if (charset != charset_ascii)
-    {
-      fontp->vertical_centering
-       = (STRINGP (Vvertical_centering_font_regexp)
-          && (fast_string_match_ignore_case
-              (Vvertical_centering_font_regexp, fullname) >= 0));
-
-      if (find_ccl_program_func)
-       (*find_ccl_program_func) (fontp);
-    }
-
-  return fontp;
-}
-
-#if defined(WINDOWSNT) && defined (_MSC_VER)
-#pragma optimize("", on)
-#endif
-
 \f
 /* Return ENCODING or a cons of ENCODING and REPERTORY of the font
    FONTNAME.  ENCODING is a charset symbol that specifies the encoding
    of the font.  REPERTORY is a charset symbol or nil.  */
 
-
 Lisp_Object
 find_font_encoding (fontname)
      Lisp_Object fontname;
@@ -1342,8 +1107,8 @@ fs_query_fontset (name, name_pattern)
 
       this_name = FONTSET_NAME (fontset);
       if (name_pattern == 1
-         ? fast_string_match (name, this_name) >= 0
-         : !strcmp (SDATA (name), SDATA (this_name)))
+         ? fast_string_match_ignore_case (name, this_name) >= 0
+         : !strcasecmp (SDATA (name), SDATA (this_name)))
        return i;
     }
   return -1;
@@ -1520,7 +1285,7 @@ generate_ascii_font_name (name, ascii_spec)
 
   if (font_parse_xlfd (SDATA (name), font_spec) < 0)
     error ("Not an XLFD font name: %s", SDATA (name));
-  for (i = FONT_FOUNDRY_INDEX; i <= FONT_WIDTH_INDEX; i++)
+  for (i = FONT_FOUNDRY_INDEX; i < FONT_EXTRA_INDEX; i++)
     if (! NILP (AREF (ascii_spec, i)))
       ASET (font_spec, i, AREF (ascii_spec, i));
   i = font_unparse_xlfd (font_spec, 0, xlfd, 256);
@@ -1591,10 +1356,12 @@ TARGET may be nil.  In that case, use FONT-SPEC for any characters for
 that no FONT-SPEC is specified.
 
 FONT-SPEC may one of these:
+ * A font-spec object made by the function `font-spec' (which see).
  * A cons (FAMILY . REGISTRY), where FAMILY is a font family name and
-   REGISTRY is a font registry name.  FAMILY may contains foundry
-   name, and REGISTRY may contains encoding name.
+   REGISTRY is a font registry name.  FAMILY may contain foundry
+   name, and REGISTRY may contain encoding name.
  * A font name string.
+ * nil, which explicitly specifies that there's no font for TARGET.
 
 Optional 4th argument FRAME, if non-nil, is a frame.  This argument is
 kept for backward compatibility and has no meaning.
@@ -1608,7 +1375,6 @@ appended.  By default, FONT-SPEC overrides the previous settings.  */)
 {
   Lisp_Object fontset;
   Lisp_Object font_def, registry, family;
-  Lisp_Object encoding, repertory;
   Lisp_Object range_list;
   struct charset *charset = NULL;
 
@@ -1619,69 +1385,61 @@ appended.  By default, FONT-SPEC overrides the previous settings.  */)
   if (!NILP (frame))
     CHECK_LIVE_FRAME (frame);
 
-  if (VECTORP (font_spec))
+  if (CONSP (font_spec))
     {
-      if (! FONT_SPEC_P (font_spec))
-       Fsignal (Qfont, list2 (build_string ("invalid font-spec"), font_spec));
-      family = Ffont_get (font_spec, QCfamily);
-      if (! NILP (family) && SYMBOLP (family))
-       family = SYMBOL_NAME (family);
-      registry = Ffont_get (font_spec, QCregistry);
-      if (! NILP (registry) && SYMBOLP (registry))
-       registry = SYMBOL_NAME (registry);
-    }
-  else if (CONSP (font_spec))
-    {
-      Lisp_Object args[4];
-      int i= 0;
-
-      family = XCAR (font_spec);
-      registry = XCDR (font_spec);
+      Lisp_Object spec = Ffont_spec (0, NULL);
 
-      if (! NILP (family))
-       {
-         CHECK_STRING (family);
-         args[i++] = QCfamily;
-         args[i++] = family;
-       }
-      CHECK_STRING (registry);
-      args[i++] = QCregistry;
-      args[i++] = registry;
-      font_spec = Ffont_spec (i, args);
+      font_parse_family_registry (XCAR (font_spec), XCDR (font_spec), spec);
+      font_spec = spec;
     }
-  else
+  else if (STRINGP (font_spec))
     {
-      CHECK_STRING (font_spec);
-      font_spec = Fdowncase (font_spec);
-    }
+      Lisp_Object args[2];
+      extern Lisp_Object QCname;
 
-  if (STRINGP (font_spec))
-    encoding = find_font_encoding (font_spec);
-  else
-    encoding = find_font_encoding (concat2 (family, registry));
-  if (NILP (encoding))
-    encoding = Qascii;
-
-  if (SYMBOLP (encoding))
-    {
-      CHECK_CHARSET (encoding);
-      encoding = repertory = CHARSET_SYMBOL_ID (encoding);
+      args[0] = QCname;
+      args[1] = font_spec;
+      font_spec = Ffont_spec (2, args);
     }
-  else
+  else if (! NILP (font_spec) && ! FONT_SPEC_P (font_spec))
+    Fsignal (Qfont, list2 (build_string ("Invalid font-spec"), font_spec));
+
+  if (! NILP (font_spec))
     {
-      repertory = XCDR (encoding);
-      encoding = XCAR (encoding);
-      CHECK_CHARSET (encoding);
-      encoding = CHARSET_SYMBOL_ID (encoding);
-      if (! NILP (repertory) && SYMBOLP (repertory))
+      Lisp_Object encoding, repertory;
+
+      family = AREF (font_spec, FONT_FAMILY_INDEX);
+      if (! NILP (family) )
+       family = SYMBOL_NAME (family);
+      registry = AREF (font_spec, FONT_REGISTRY_INDEX);
+      if (! NILP (registry))
+       registry = Fdowncase (SYMBOL_NAME (registry));
+      encoding = find_font_encoding (concat3 (family, build_string ("-"),
+                                             registry));
+      if (NILP (encoding))
+       encoding = Qascii;
+
+      if (SYMBOLP (encoding))
        {
-         CHECK_CHARSET (repertory);
-         repertory = CHARSET_SYMBOL_ID (repertory);
+         CHECK_CHARSET (encoding);
+         encoding = repertory = CHARSET_SYMBOL_ID (encoding);
        }
+      else
+       {
+         repertory = XCDR (encoding);
+         encoding = XCAR (encoding);
+         CHECK_CHARSET (encoding);
+         encoding = CHARSET_SYMBOL_ID (encoding);
+         if (! NILP (repertory) && SYMBOLP (repertory))
+           {
+             CHECK_CHARSET (repertory);
+             repertory = CHARSET_SYMBOL_ID (repertory);
+           }
+       }
+      FONT_DEF_NEW (font_def, font_spec, encoding, repertory);
     }
-  font_def = Fmake_vector (make_number (3), font_spec);
-  ASET (font_def, 1, encoding);
-  ASET (font_def, 2, repertory);
+  else
+    font_def = Qnil;
 
   if (CHARACTERP (target))
     range_list = Fcons (Fcons (target, target), Qnil);
@@ -1708,7 +1466,7 @@ appended.  By default, FONT-SPEC overrides the previous settings.  */)
          map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table,
                          val);
          range_list = XCDR (val);
-         if (EQ (target, Qlatin))
+         if (EQ (target, Qlatin) && NILP (FONTSET_ASCII (fontset)))
            {
              if (VECTORP (font_spec))
                val = generate_ascii_font_name (FONTSET_NAME (fontset),
@@ -1720,7 +1478,7 @@ appended.  By default, FONT-SPEC overrides the previous settings.  */)
        }
       if (CHARSETP (target))
        {
-         if (EQ (target, Qascii))
+         if (EQ (target, Qascii) && NILP (FONTSET_ASCII (fontset)))
            {
              if (VECTORP (font_spec))
                font_spec = generate_ascii_font_name (FONTSET_NAME (fontset),
@@ -1793,23 +1551,29 @@ FONT-SPEC is a vector, a cons, or a string.  See the documentation of
   CHECK_STRING (name);
   CHECK_LIST (fontlist);
 
+  name = Fdowncase (name);
   id = fs_query_fontset (name, 0);
   if (id < 0)
     {
-      name = Fdowncase (name);
-      val = split_font_name_into_vector (name);
-      if (NILP (val) || NILP (AREF (val, 12)) || NILP (AREF (val, 13)))
+      Lisp_Object font_spec = Ffont_spec (0, NULL);
+      Lisp_Object short_name;
+      char xlfd[256];
+      int len;
+
+      if (font_parse_xlfd (SDATA (name), font_spec) < 0)
        error ("Fontset name must be in XLFD format");
-      if (strcmp (SDATA (AREF (val, 12)), "fontset"))
-       error ("Registry field of fontset name must be \"fontset\"");
-      Vfontset_alias_alist
-       = Fcons (Fcons (name,
-                       concat2 (concat2 (AREF (val, 12), build_string ("-")),
-                                AREF (val, 13))),
-                Vfontset_alias_alist);
-      ASET (val, 12, build_string ("iso8859-1"));
+      short_name = AREF (font_spec, FONT_REGISTRY_INDEX);
+      if (strncmp (SDATA (SYMBOL_NAME (short_name)), "fontset-", 8)
+         || SBYTES (SYMBOL_NAME (short_name)) < 9)
+       error ("Registry field of fontset name must be \"fontset-*\"");
+      Vfontset_alias_alist = Fcons (Fcons (name, SYMBOL_NAME (short_name)),
+                                   Vfontset_alias_alist);
+      ASET (font_spec, FONT_REGISTRY_INDEX, Qiso8859_1);
       fontset = make_fontset (Qnil, name, Qnil);
-      FONTSET_ASCII (fontset) = build_font_name_from_vector (val);
+      len = font_unparse_xlfd (font_spec, 0, xlfd, 256);
+      if (len < 0)
+       error ("Invalid fontset name (perhaps too long): %s", SDATA (name));
+      FONTSET_ASCII (fontset) = make_unibyte_string (xlfd, len);
     }
   else
     {
@@ -1836,139 +1600,55 @@ FONT-SPEC is a vector, a cons, or a string.  See the documentation of
 
 
 /* Alist of automatically created fontsets.  Each element is a cons
-   (FONTNAME . FONTSET-ID).  */
+   (FONT-SPEC . FONTSET-ID).  */
 static Lisp_Object auto_fontset_alist;
 
 int
-new_fontset_from_font_name (Lisp_Object fontname)
-{
-  Lisp_Object val;
-  Lisp_Object name;
-  Lisp_Object vec;
-  int id;
-
-  fontname = Fdowncase (fontname);
-  val = Fassoc (fontname, auto_fontset_alist);
-  if (CONSP (val))
-    return XINT (XCDR (val));
-
-  vec = split_font_name_into_vector (fontname);
-  if ( NILP (vec))
-    vec = Fmake_vector (make_number (14), build_string (""));
-  ASET (vec, 12, build_string ("fontset"));
-  if (NILP (auto_fontset_alist))
-    {
-      ASET (vec, 13, build_string ("startup"));
-      name = build_font_name_from_vector (vec);
-    }
-  else
-    {
-      char temp[20];
-      int len = XINT (Flength (auto_fontset_alist));
-
-      sprintf (temp, "auto%d", len);
-      ASET (vec, 13, build_string (temp));
-      name = build_font_name_from_vector (vec);
-    }
-  name = Fnew_fontset (name, list2 (list2 (Qascii, fontname),
-                                   list2 (Fcons (make_number (0),
-                                                 make_number (MAX_CHAR)),
-                                          fontname)));
-  id = fs_query_fontset (name, 0);
-  auto_fontset_alist
-    = Fcons (Fcons (fontname, make_number (id)), auto_fontset_alist);
-  return id;
-}
-
-#ifdef USE_FONT_BACKEND
-int
-new_fontset_from_font (font_object)
+fontset_from_font (font_object)
      Lisp_Object font_object;
 {
   Lisp_Object font_name = font_get_name (font_object);
-  Lisp_Object font_spec = font_get_spec (font_object);
-  Lisp_Object fontset_spec, short_name, name, fontset;
+  Lisp_Object font_spec = Fcopy_font_spec (font_object);
+  Lisp_Object fontset_spec, alias, name, fontset;
+  Lisp_Object val;
+  int i;
 
+  val = assoc_no_quit (font_spec, auto_fontset_alist);
+  if (CONSP (val))
+    return XINT (FONTSET_ID (XCDR (val)));
   if (NILP (auto_fontset_alist))
-    short_name = build_string ("fontset-startup");
+    alias = intern ("fontset-startup");
   else
     {
       char temp[32];
       int len = XINT (Flength (auto_fontset_alist));
 
       sprintf (temp, "fontset-auto%d", len);
-      short_name = build_string (temp);
+      alias = intern (temp);
     }
-  fontset_spec = Fcopy_sequence (font_spec);
-  ASET (fontset_spec, FONT_REGISTRY_INDEX, short_name);
+  fontset_spec = Fcopy_font_spec (font_spec);
+  ASET (fontset_spec, FONT_REGISTRY_INDEX, alias);
   name = Ffont_xlfd_name (fontset_spec);
   if (NILP (name))
-    {
-      int i;
-
-      for (i = 0; i < FONT_SIZE_INDEX; i++)
-       if ((i != FONT_FAMILY_INDEX) && (i != FONT_REGISTRY_INDEX))
-         ASET (fontset_spec, i, Qnil);
-      name = Ffont_xlfd_name (fontset_spec);
-      if (NILP (name))
-       abort ();
-    }
+    abort ();
   fontset = make_fontset (Qnil, name, Qnil);
+  Vfontset_alias_alist = Fcons (Fcons (name, SYMBOL_NAME (alias)),
+                               Vfontset_alias_alist);
+  alias = Fdowncase (AREF (font_object, FONT_NAME_INDEX));
+  Vfontset_alias_alist = Fcons (Fcons (name, alias), Vfontset_alias_alist);
+  auto_fontset_alist = Fcons (Fcons (font_spec, fontset), auto_fontset_alist);
   FONTSET_ASCII (fontset) = font_name;
-  font_spec = Fcons (SYMBOL_NAME (AREF (font_spec, FONT_FAMILY_INDEX)),
-                    SYMBOL_NAME (AREF (font_spec, FONT_REGISTRY_INDEX)));
+  ASET (font_spec, FONT_FOUNDRY_INDEX, Qnil);
+  ASET (font_spec, FONT_ADSTYLE_INDEX, Qnil);
+  for (i = FONT_WEIGHT_INDEX; i < FONT_EXTRA_INDEX; i++)
+    ASET (font_spec, i, Qnil);
   Fset_fontset_font (name, Qlatin, font_spec, Qnil, Qnil);
+  font_spec = Fcopy_font_spec (font_spec);
+  ASET (font_spec, FONT_REGISTRY_INDEX, Qiso10646_1);
   Fset_fontset_font (name, Qnil, font_spec, Qnil, Qnil);
   return XINT (FONTSET_ID (fontset));
 }
 
-struct font *
-fontset_ascii_font (f, id)
-     FRAME_PTR f;
-     int id;
-{
-  Lisp_Object fontset = FONTSET_FROM_ID (id);
-  Lisp_Object ascii_slot = FONTSET_ASCII (fontset);
-  Lisp_Object val, font_object;
-
-  if (CONSP (ascii_slot))
-    {
-      Lisp_Object ascii_font_name = XCAR (ascii_slot);
-
-      font_object = Qnil;
-      for (val = XCDR (ascii_slot); ! NILP (val); val = XCDR (val))
-       {
-         Lisp_Object frame = font_get_frame (XCAR (val));
-
-         if (NILP (frame) || XFRAME (frame) == f)
-           {
-             font_object = XCAR (val);
-             if (XSAVE_VALUE (font_object)->integer == 0)
-               {
-                 font_object = font_open_by_name (f, SDATA (ascii_font_name));
-                 XSETCAR (val, font_object);
-               }
-             break;
-           }
-       }
-      if (NILP (font_object))
-       {
-         font_object = font_open_by_name (f, SDATA (ascii_font_name));
-         XSETCDR (ascii_slot, Fcons (font_object, XCDR (ascii_slot)));
-       }
-    }
-  else
-    {
-      font_object = font_open_by_name (f, SDATA (ascii_slot));
-      FONTSET_ASCII (fontset) = Fcons (ascii_slot, Fcons (font_object, Qnil));
-    }
-  if (NILP (font_object))
-    return NULL;
-  return XSAVE_VALUE (font_object)->pointer;
-}
-
-#endif /* USE_FONT_BACKEND */
-
 DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
        doc: /* Return information about a font named NAME on frame FRAME.
 If FRAME is omitted or nil, use the selected frame.
@@ -1987,7 +1667,7 @@ If the named font is not yet loaded, return nil.  */)
      Lisp_Object name, frame;
 {
   FRAME_PTR f;
-  struct font_info *fontp;
+  struct font *font;
   Lisp_Object info;
   Lisp_Object font_object;
 
@@ -2000,38 +1680,21 @@ If the named font is not yet loaded, return nil.  */)
   CHECK_LIVE_FRAME (frame);
   f = XFRAME (frame);
 
-  if (!query_font_func)
-    error ("Font query function is not supported");
-
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      font_object = font_open_by_name (f, SDATA (name));
-      if (NILP (font_object))
-       fontp = NULL;
-      else
-       fontp = (struct font_info *) XSAVE_VALUE (font_object)->pointer;
-    }
-  else
-#endif /* USE_FONT_BACKEND */
-  fontp = (*query_font_func) (f, SDATA (name));
-  if (!fontp)
+  font_object = font_open_by_name (f, SDATA (name));
+  if (NILP (font_object))
     return Qnil;
+  font = XFONT_OBJECT (font_object);
 
   info = Fmake_vector (make_number (7), Qnil);
-
-  XVECTOR (info)->contents[0] = build_string (fontp->name);
-  XVECTOR (info)->contents[1] = build_string (fontp->full_name);
-  XVECTOR (info)->contents[2] = make_number (fontp->size);
-  XVECTOR (info)->contents[3] = make_number (fontp->height);
-  XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
-  XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
-  XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
-
-#ifdef USE_FONT_BACKEND
-  if (! NILP (font_object))
-    font_close_object (f, font_object);
-#endif /* USE_FONT_BACKEND */
+  XVECTOR (info)->contents[0] = AREF (font_object, FONT_NAME_INDEX);
+  XVECTOR (info)->contents[1] = AREF (font_object, FONT_NAME_INDEX);
+  XVECTOR (info)->contents[2] = make_number (font->pixel_size);
+  XVECTOR (info)->contents[3] = make_number (font->height);
+  XVECTOR (info)->contents[4] = make_number (font->baseline_offset);
+  XVECTOR (info)->contents[5] = make_number (font->relative_compose);
+  XVECTOR (info)->contents[6] = make_number (font->default_ascent);
+
+  font_close_object (f, font_object);
   return info;
 }
 
@@ -2068,12 +1731,12 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
      (position, ch)
      Lisp_Object position, ch;
 {
-  int pos, pos_byte, dummy;
+  EMACS_INT pos, pos_byte, dummy;
   int face_id;
   int c;
   struct frame *f;
   struct face *face;
-  Lisp_Object charset, rfont_def;
+  Lisp_Object rfont_def;
   int cs_id;
 
   if (NILP (position))
@@ -2118,45 +1781,21 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
     return Qnil;
   face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c, pos, Qnil);
   face = FACE_FROM_ID (f, face_id);
-  rfont_def = fontset_font (FONTSET_FROM_ID (face->fontset), c, face, cs_id);
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      if (VECTORP (rfont_def) && ! NILP (AREF (rfont_def, 3)))
-       {
-         Lisp_Object font_object = XCAR (AREF (rfont_def, 3));
-         struct font *font = XSAVE_VALUE (font_object)->pointer;
-         unsigned code = font->driver->encode_char (font, c);
-         Lisp_Object fontname = font_get_name (font_object);
-
-         if (code == FONT_INVALID_CODE)
-           return Fcons (fontname, Qnil);
-         if (code <= MOST_POSITIVE_FIXNUM)
-           return Fcons (fontname, make_number (code));
-         return Fcons (fontname, Fcons (make_number (code >> 16),
-                                        make_number (code & 0xFFFF)));
-       }
-      return Qnil;
-    }
-#endif /* USE_FONT_BACKEND */
-  if (VECTORP (rfont_def) && STRINGP (AREF (rfont_def, 3)))
+  if (face->font)
     {
-      Lisp_Object font_def;
-      struct font_info *fontp;
-      struct charset *charset;
-      XChar2b char2b;
-      int code;
-
-      font_def = AREF (rfont_def, 2);
-      charset = CHARSET_FROM_ID (XINT (AREF (font_def, 1)));
-      code = ENCODE_CHAR (charset, c);
-      if (code == CHARSET_INVALID_CODE (charset))
-       return (Fcons (AREF (rfont_def, 3), Qnil));
-      STORE_XCHAR2B (&char2b, ((code >> 8) & 0xFF), (code & 0xFF));
-      fontp = (*get_font_info_func) (f, XINT (AREF (rfont_def, 1)));
-      FRAME_RIF (f)->encode_char (c, &char2b, fontp, charset, NULL);
-      code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
-      return (Fcons (AREF (rfont_def, 3), make_number (code)));
+      struct font *font = face->font;
+      unsigned code = font->driver->encode_char (font, c);
+      Lisp_Object fontname = font->props[FONT_NAME_INDEX];
+      /* Assignment to EMACS_INT stops GCC whining about limited range
+        of data type.  */
+      EMACS_INT cod = code;
+
+      if (code == FONT_INVALID_CODE)
+       return Qnil;
+      if (cod <= MOST_POSITIVE_FIXNUM)
+       return Fcons (fontname, make_number (code));
+      return Fcons (fontname, Fcons (make_number (code >> 16),
+                                    make_number (code & 0xFFFF)));
     }
   return Qnil;
 }
@@ -2251,7 +1890,9 @@ fontset.  The format is the same as abobe.  */)
 
              /* At first, set ALIST to ((FONT-SPEC) ...).  */
              for (alist = Qnil, i = 0; i < ASIZE (val); i++)
-               alist = Fcons (Fcons (AREF (AREF (val, i), 0), Qnil), alist);
+               if (! NILP (AREF (val, i)))
+                 alist = Fcons (Fcons (FONT_DEF_SPEC (AREF (val, i)), Qnil),
+                                alist);
              alist = Fnreverse (alist);
 
              /* Then store opend font names to cdr of each elements.  */
@@ -2263,35 +1904,35 @@ fontset.  The format is the same as abobe.  */)
                    val = FONTSET_FALLBACK (realized[k][i]);
                  if (! VECTORP (val))
                    continue;
-                 /* VAL is [int int ?
-                            [FACE-ID FONT-INDEX FONT-DEF FONT-NAME] ...].
-                    If a font of an element is already opened,
-                    FONT-NAME is the name of a opened font.  */
-                 for (j = 3; j < ASIZE (val); j++)
-                   if (STRINGP (AREF (AREF (val, j), 3)))
-                     {
-                       Lisp_Object font_idx;
-
-                       font_idx = AREF (AREF (val, j), 1);
-                       elt = Fassq (AREF (AREF (AREF (val, j), 2), 0), alist);
-                       if (CONSP (elt)
-                           && NILP (Fmemq (font_idx, XCDR(elt))))
-                         nconc2 (elt, Fcons (font_idx, Qnil));
-                     }
+                 /* VAL: [int ? [FACE-ID FONT-DEF FONT-OBJECT int] ... ]  */
+                 for (j = 2; j < ASIZE (val); j++)
+                   {
+                     elt = AREF (val, j);
+                     if (FONT_OBJECT_P (RFONT_DEF_OBJECT (elt)))
+                       {
+                         Lisp_Object font_object = RFONT_DEF_OBJECT (elt);
+                         Lisp_Object slot, name;
+
+                         slot = Fassq (RFONT_DEF_SPEC (elt), alist);
+                         name = AREF (font_object, FONT_NAME_INDEX);
+                         if (NILP (Fmember (name, XCDR (slot))))
+                           nconc2 (slot, Fcons (name, Qnil));
+                       }
+                   }
                }
-             for (val = alist; CONSP (val); val = XCDR (val))
-               for (elt = XCDR (XCAR (val)); CONSP (elt); elt = XCDR (elt))
-                 {
-                   struct font_info *font_info
-                     = (*get_font_info_func) (f, XINT (XCAR (elt)));
-                   XSETCAR (elt, build_string (font_info->full_name));
-                 }
 
              /* Store ALIST in TBL for characters C..TO.  */
              if (c <= MAX_5_BYTE_CHAR)
                char_table_set_range (tables[k], c, to, alist);
              else
                XCHAR_TABLE (tables[k])->defalt = alist;
+
+             /* At last, change each elements to font names.  */
+             for (; CONSP (alist); alist = XCDR (alist))
+               {
+                 elt = XCAR (alist);
+                 XSETCAR (elt, Ffont_xlfd_name (XCAR (elt)));
+               }
            }
          c = to + 1;
        }
@@ -2432,10 +2073,6 @@ DEFUN ("fontset-list-all", Ffontset_list_all, Sfontset_list_all, 0, 0, 0,
 void
 syms_of_fontset ()
 {
-  if (!load_font_func)
-    /* Window system initializer should have set proper functions.  */
-    abort ();
-
   DEFSYM (Qfontset, "fontset");
   Fput (Qfontset, Qchar_table_extra_slots, make_number (9));
   DEFSYM (Qfontset_info, "fontset-info");
@@ -2456,7 +2093,7 @@ syms_of_fontset ()
   FONTSET_ID (Vdefault_fontset) = make_number (0);
   FONTSET_NAME (Vdefault_fontset)
     = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
-  AREF (Vfontset_table, 0) = Vdefault_fontset;
+  ASET (Vfontset_table, 0, Vdefault_fontset);
   next_fontset_id = 1;
 
   auto_fontset_alist = Qnil;
@@ -2469,6 +2106,9 @@ Each element looks like (REGEXP . (ENCODING . REPERTORY)),
 where ENCODING is a charset or a char-table,
 and REPERTORY is a charset, a char-table, or nil.
 
+If ENCDING and REPERTORY are the same, the element can have the form
+\(REGEXP . ENCODING).
+
 ENCODING is for converting a character to a glyph code of the font.
 If ENCODING is a charset, encoding a character by the charset gives
 the corresponding glyph code.  If ENCODING is a char-table, looking up
@@ -2481,6 +2121,17 @@ non-nil value in the table are supported.  It REPERTORY is nil, Emacs
 gets the repertory information by an opened font and ENCODING.  */);
   Vfont_encoding_alist = Qnil;
 
+  DEFVAR_LISP ("font-encoding-charset-alist", &Vfont_encoding_charset_alist,
+              doc: /*
+Alist of charsets vs the charsets to determine the preferred font encoding.
+Each element looks like (CHARSET . ENCDOING-CHARSET),
+where ENCODING-CHARSET is a charset registered in the variable
+`font-encoding-alist' as ENCODING.
+
+When a text has a property `charset' and the value is CHARSET, a font
+whose encoding corresponds to ENCODING-CHARSET is preferred.  */);
+  Vfont_encoding_charset_alist = Qnil;
+
   DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
               doc: /*
 Char table of characters whose ascent values should be ignored.