]> git.eshelyaron.com Git - emacs.git/commitdiff
*** empty log message ***
authorKenichi Handa <handa@m17n.org>
Wed, 30 Apr 2008 01:45:11 +0000 (01:45 +0000)
committerKenichi Handa <handa@m17n.org>
Wed, 30 Apr 2008 01:45:11 +0000 (01:45 +0000)
47 files changed:
configure
configure.in
lisp/composite.el
lisp/cus-face.el
lisp/faces.el
lisp/international/fontset.el
lisp/international/mule-cmds.el
lisp/language/chinese.el
lisp/language/japanese.el
lisp/language/korean.el
src/ChangeLog.fb [new file with mode: 0644]
src/Makefile.in
src/charset.c
src/charset.h
src/coding.c
src/composite.c
src/dispextern.h
src/dispnew.c
src/emacs.c
src/fns.c
src/font.c
src/font.h
src/fontset.c
src/fontset.h
src/frame.c
src/frame.h
src/ftfont.c
src/ftxfont.c
src/image.c
src/lisp.h
src/makefile.w32-in
src/print.c
src/puresize.h
src/w32fns.c
src/w32font.c
src/w32font.h
src/w32gui.h
src/w32term.c
src/w32term.h
src/w32uniscribe.c
src/xdisp.c
src/xfaces.c
src/xfns.c
src/xfont.c
src/xftfont.c
src/xterm.c
src/xterm.h

index 192c51b9c23d40c5faf504b3fe02c18dd6dca7f7..1d39e679fb41309e2948677bde2ec033d7d5377c 100755 (executable)
--- a/configure
+++ b/configure
@@ -1332,7 +1332,6 @@ Optional Features:
   --enable-carbon-app[=DIR]
                           specify install directory for Emacs.app on Mac OS X
                           [DIR=/Application]
-  --disable-font-backend  don't compile font-backend support
   --enable-asserts        compile code with asserts enabled
   --enable-maintainer-mode
                           enable make rules and dependencies not useful (and
@@ -2144,15 +2143,6 @@ if test "${enable_carbon_app+set}" = set; then
 fi
 
 
-## Enabled by default.
-# Check whether --enable-font-backend was given.
-if test "${enable_font_backend+set}" = set; then
-  enableval=$enable_font_backend; USE_FONT_BACKEND=$enableval
-else
-  USE_FONT_BACKEND=yes
-fi
-
-
 # Check whether --enable-asserts was given.
 if test "${enable_asserts+set}" = set; then
   enableval=$enable_asserts; USE_XASSERTS=$enableval
@@ -2861,7 +2851,7 @@ case "${machine}" in
 esac
 
 case "${opsys}" in
-     bsd386 | bsdos2-1 |  bsdos2 | bsdos3 | bsdos4 | bsd4-1 | bsd4-2 | bsd4-3 | usg5-0 | usg5-2-2 | usg5-2 | usg5-3 | ultrix4-3 | 386bsd | hpux | hpux8 | hpux9 | hpux9shr | hpux10 | hpux10-20 | aix3-1 | aix3-2-5 | aix3-2 | aix4-1 | nextstep | ux4800 | uxpds | uxpv )
+     bsd386 | bsdos2-1 |  bsdos2 | bsdos3 | bsdos4 | bsd4-1 | bsd4-2 | bsd4-3 | usg5-0 | usg5-2-2 | usg5-2 | usg5-3 | ultrix4-3 | 386bsd | hpux | hpux8 | hpux9 | hpux9shr | hpux10 | aix3-1 | aix3-2-5 | aix3-2 | aix4-1 | nextstep | ux4800 | uxpds | uxpv )
          echo "The system that you are configuring on: ${canonical} is considered to be obsolete"
          echo "and it is planned to be desupported in the next version of Emacs"
          echo "Please email emacs-devel@gnu.org as soon as possible if this system is still in use."
@@ -12633,23 +12623,13 @@ _ACEOF
 fi
 
 ### Start of font-backend section.
-if test "${HAVE_X11}" != "yes"; then
-  USE_FONT_BACKEND=no
-fi
 
-if test "${USE_FONT_BACKEND}" = "yes"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define USE_FONT_BACKEND 1
-_ACEOF
-
-
-  ## Use -lXft if available, unless `--with-freetype=no' nor `--with-xft=no'.
-  HAVE_XFT=maybe
-  if test "x${with_freetype}" = "xno"; then
-    with_xft="no";
-  fi
-  if test "x${with_xft}" != "xno"; then
+## Use -lXft if available, unless `--with-freetype=no' nor `--with-xft=no'.
+HAVE_XFT=maybe
+if test "x${with_freetype}" = "xno"; then
+  with_xft="no";
+fi
+if test "x${with_xft}" != "xno"; then
 
 
   succeeded=no
@@ -12745,14 +12725,14 @@ echo "${ECHO_T}no" >&6; }
      HAVE_XFT=no
   fi
 
-    if test "$HAVE_XFT" != no; then
-      OLD_CPPFLAGS="$CPPFLAGS"
-      OLD_CFLAGS="$CFLAGS"
-      OLD_LIBS="$LIBS"
-      CPPFLAGS="$CPPFLAGS $XFT_CFLAGS"
-      CFLAGS="$CFLAGS $XFT_CFLAGS"
-      LIBS="$XFT_LIBS $LIBS"
-      if test "${ac_cv_header_X11_Xft_Xft_h+set}" = set; then
+  if test "$HAVE_XFT" != no; then
+    OLD_CPPFLAGS="$CPPFLAGS"
+    OLD_CFLAGS="$CFLAGS"
+    OLD_LIBS="$LIBS"
+    CPPFLAGS="$CPPFLAGS $XFT_CFLAGS"
+    CFLAGS="$CFLAGS $XFT_CFLAGS"
+    LIBS="$XFT_LIBS $LIBS"
+    if test "${ac_cv_header_X11_Xft_Xft_h+set}" = set; then
   { echo "$as_me:$LINENO: checking for X11/Xft/Xft.h" >&5
 echo $ECHO_N "checking for X11/Xft/Xft.h... $ECHO_C" >&6; }
 if test "${ac_cv_header_X11_Xft_Xft_h+set}" = set; then
 
 
 
-      if test "${HAVE_XFT}" = "yes"; then
+    if test "${HAVE_XFT}" = "yes"; then
 
 cat >>confdefs.h <<\_ACEOF
 #define HAVE_XFT 1
 _ACEOF
 
 
-        C_SWITCH_X_SITE="$C_SWITCH_X_SITE $XFT_CFLAGS"
-      else
-        CPPFLAGS="$OLD_CPPFLAGS"
-        CFLAGS="$OLD_CFLAGS"
-        LIBS="$OLD_LIBS"
-      fi                        # "${HAVE_XFT}" = "yes"
-    fi                          # "$HAVE_XFT" != no
-  fi                            # "x${with_xft}" != "xno"
-
-    if test "$HAVE_XFT" != "yes"; then
-     HAVE_XFT=no
-  fi
+      C_SWITCH_X_SITE="$C_SWITCH_X_SITE $XFT_CFLAGS"
+    else
+      CPPFLAGS="$OLD_CPPFLAGS"
+      CFLAGS="$OLD_CFLAGS"
+      LIBS="$OLD_LIBS"
+    fi                        # "${HAVE_XFT}" = "yes"
+  fi                          # "$HAVE_XFT" != no
+fi                            # "x${with_xft}" != "xno"
 
+if test "$HAVE_XFT" != "yes"; then
+   HAVE_XFT=no
+fi
 
-  HAVE_FREETYPE=no
-  ### Use -lfreetype if available, unless `--with-freetype=no'.
-  if test "${HAVE_XFT}" = "yes"; then
-            HAVE_FREETYPE=yes
-  elif test "x${with_freetype}" != "xno"; then
+
+HAVE_FREETYPE=no
+### Use -lfreetype if available, unless `--with-freetype=no'.
+if test "${HAVE_XFT}" = "yes"; then
+      HAVE_FREETYPE=yes
+elif test "x${with_freetype}" != "xno"; then
 
 
   succeeded=no
@@ -13068,7 +13048,7 @@ echo "${ECHO_T}no" >&6; }
      HAVE_FREETYPE=no
   fi
 
-    if test "${HAVE_FREETYPE}" = "yes"; then
+  if test "${HAVE_FREETYPE}" = "yes"; then
 
   succeeded=no
 
@@ -13163,20 +13143,20 @@ echo "${ECHO_T}no" >&6; }
      HAVE_FC=no
   fi
 
-      if test "${HAVE_FC}" = "no"; then
-                HAVE_FREETYPE=no
-      fi
+    if test "${HAVE_FC}" = "no"; then
+            HAVE_FREETYPE=no
     fi
   fi
+fi
 
-  HAVE_LIBOTF=no
-  if test "${HAVE_FREETYPE}" = "yes"; then
+HAVE_LIBOTF=no
+if test "${HAVE_FREETYPE}" = "yes"; then
 
 cat >>confdefs.h <<\_ACEOF
 #define HAVE_FREETYPE 1
 _ACEOF
 
-    if test "${with_libotf}" != "no"; then
+  if test "${with_libotf}" != "no"; then
 
   succeeded=no
 
@@ -13271,18 +13251,18 @@ echo "${ECHO_T}no" >&6; }
      HAVE_LIBOTF=no
   fi
 
-      if test "$HAVE_LIBOTF" = "yes"; then
+    if test "$HAVE_LIBOTF" = "yes"; then
 
 cat >>confdefs.h <<\_ACEOF
 #define HAVE_LIBOTF 1
 _ACEOF
 
-      fi
     fi
   fi
+fi
 
-  HAVE_M17N_FLT=no
-  if test "${with_m17n_flt}" != "no"; then
+HAVE_M17N_FLT=no
+if test "${with_m17n_flt}" != "no"; then
 
   succeeded=no
 
@@ -13377,14 +13357,14 @@ echo "${ECHO_T}no" >&6; }
      HAVE_M17N_FLT=no
   fi
 
-    if test "$HAVE_M17N_FLT" = "yes"; then
+  if test "$HAVE_M17N_FLT" = "yes"; then
 
 cat >>confdefs.h <<\_ACEOF
 #define HAVE_M17N_FLT 1
 _ACEOF
 
-    fi
   fi
+fi
 
 
 
@@ -13395,7 +13375,6 @@ _ACEOF
 
 
 
-fi                              # "${USE_FONT_BACKEND}" = "yes"
 ### End of font-backend section.
 
 ### Use -lXpm if available, unless `--with-xpm=no'.
@@ -16734,6 +16713,7 @@ cat >>conftest.$ac_ext <<_ACEOF
 # endif
 #endif
 
+#include <limits.h>
 #include <stdlib.h>
 
 #ifdef HAVE_UNISTD_H
@@ -16882,12 +16862,15 @@ main ()
      isn't worth using anyway.  */
   alarm (60);
 
-  for (time_t_max = 1; 0 < time_t_max; time_t_max *= 2)
-    continue;
-  time_t_max--;
-  if ((time_t) -1 < 0)
-    for (time_t_min = -1; (time_t) (time_t_min * 2) < 0; time_t_min *= 2)
-      continue;
+  for (;;)
+    {
+      t = (time_t_max << 1) + 1;
+      if (t <= time_t_max)
+       break;
+      time_t_max = t;
+    }
+  time_t_min = - ((time_t) ~ (time_t) 0 == (time_t) -1) - time_t_max;
+
   delta = time_t_max / 997; /* a suitable prime number */
   for (i = 0; i < N_STRINGS; i++)
     {
@@ -16902,10 +16885,12 @@ main ()
             && mktime_test ((time_t) (60 * 60 * 24))))
        return 1;
 
-      for (j = 1; 0 < j; j *= 2)
+      for (j = 1; ; j <<= 1)
        if (! bigtime_test (j))
          return 1;
-      if (! bigtime_test (j - 1))
+       else if (INT_MAX / 2 < j)
+         break;
+      if (! bigtime_test (INT_MAX))
        return 1;
     }
   return ! (irix_6_4_bug () && spring_forward_gap () && year_2050_test ());
@@ -18814,11 +18799,13 @@ _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <stdio.h>
+#include <sys/types.h> /* for off_t */
+     #include <stdio.h>
 int
 main ()
 {
-return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
+int (*fp) (FILE *, off_t, int) = fseeko;
+     return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
   ;
   return 0;
 }
@@ -18858,11 +18845,13 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #define _LARGEFILE_SOURCE 1
-#include <stdio.h>
+#include <sys/types.h> /* for off_t */
+     #include <stdio.h>
 int
 main ()
 {
-return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
+int (*fp) (FILE *, off_t, int) = fseeko;
+     return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
   ;
   return 0;
 }
@@ -24141,7 +24130,6 @@ echo "  Does Emacs use -lpng?                                   ${HAVE_PNG}"
 echo "  Does Emacs use -lrsvg-2?                                ${HAVE_RSVG}"
 echo "  Does Emacs use -lgpm?                                   ${HAVE_GPM}"
 echo "  Does Emacs use -ldbus?                                  ${HAVE_DBUS}"
-echo "  Does Emacs use a font backend?                          ${USE_FONT_BACKEND}"
 
 if test "${USE_FONT_BACKEND}" = "yes"; then
   echo "  Does Emacs use -lfreetype?                              ${HAVE_FREETYPE}"
index 4740fb9b5da11df6fc0730086a363e49913f51a6..448e6d2d91e4e3fe2d28dc12cffc916a5aa14e18 100644 (file)
@@ -172,12 +172,6 @@ AC_ARG_ENABLE(carbon-app,
                 [DIR=/Application]])],
 [ carbon_appdir_x=${enableval}])
 
-## Enabled by default.
-AC_ARG_ENABLE(font-backend,
-[AS_HELP_STRING([--disable-font-backend],[don't compile font-backend support])],
-      USE_FONT_BACKEND=$enableval,
-      USE_FONT_BACKEND=yes)
-
 AC_ARG_ENABLE(asserts,
 [AS_HELP_STRING([--enable-asserts], [compile code with asserts enabled])],
       USE_XASSERTS=$enableval,
@@ -1954,100 +1948,93 @@ either XPointer or XPointer*.])dnl
 fi
 
 ### Start of font-backend section.
-if test "${HAVE_X11}" != "yes"; then
-  USE_FONT_BACKEND=no
+
+## Use -lXft if available, unless `--with-freetype=no' nor `--with-xft=no'.
+HAVE_XFT=maybe
+if test "x${with_freetype}" = "xno"; then
+  with_xft="no";
+fi
+if test "x${with_xft}" != "xno"; then
+
+  PKG_CHECK_MODULES(XFT, xft >= 0.13.0, , HAVE_XFT=no)
+  if test "$HAVE_XFT" != no; then
+    OLD_CPPFLAGS="$CPPFLAGS"
+    OLD_CFLAGS="$CFLAGS"
+    OLD_LIBS="$LIBS"
+    CPPFLAGS="$CPPFLAGS $XFT_CFLAGS"
+    CFLAGS="$CFLAGS $XFT_CFLAGS"
+    LIBS="$XFT_LIBS $LIBS"
+    AC_CHECK_HEADER(X11/Xft/Xft.h,
+      AC_CHECK_LIB(Xft, XftFontOpen, HAVE_XFT=yes, , $XFT_LIBS))
+
+    if test "${HAVE_XFT}" = "yes"; then
+      AC_DEFINE(HAVE_XFT, 1, [Define to 1 if you have the Xft library.])
+       AC_SUBST(XFT_LIBS)
+      C_SWITCH_X_SITE="$C_SWITCH_X_SITE $XFT_CFLAGS"
+    else
+      CPPFLAGS="$OLD_CPPFLAGS"
+      CFLAGS="$OLD_CFLAGS"
+      LIBS="$OLD_LIBS"
+    fi                        # "${HAVE_XFT}" = "yes"
+  fi                          # "$HAVE_XFT" != no
+fi                            # "x${with_xft}" != "xno"
+
+dnl For the "Does Emacs use" message at the end.
+if test "$HAVE_XFT" != "yes"; then
+   HAVE_XFT=no
 fi
 
-if test "${USE_FONT_BACKEND}" = "yes"; then
-  AC_DEFINE(USE_FONT_BACKEND, 1, [Define to 1 if we should use font-backend.])
 
-  ## Use -lXft if available, unless `--with-freetype=no' nor `--with-xft=no'.
-  HAVE_XFT=maybe
-  if test "x${with_freetype}" = "xno"; then
-    with_xft="no";
-  fi
-  if test "x${with_xft}" != "xno"; then
+HAVE_FREETYPE=no
+### Use -lfreetype if available, unless `--with-freetype=no'.
+if test "${HAVE_XFT}" = "yes"; then
+  dnl As we use Xft, we anyway use freetype.
+  dnl In this case, there's no need of additional CFLAGS and LIBS.
+  HAVE_FREETYPE=yes
+elif test "x${with_freetype}" != "xno"; then
 
-    PKG_CHECK_MODULES(XFT, xft >= 0.13.0, , HAVE_XFT=no)
-    if test "$HAVE_XFT" != no; then
-      OLD_CPPFLAGS="$CPPFLAGS"
-      OLD_CFLAGS="$CFLAGS"
-      OLD_LIBS="$LIBS"
-      CPPFLAGS="$CPPFLAGS $XFT_CFLAGS"
-      CFLAGS="$CFLAGS $XFT_CFLAGS"
-      LIBS="$XFT_LIBS $LIBS"
-      AC_CHECK_HEADER(X11/Xft/Xft.h,
-        AC_CHECK_LIB(Xft, XftFontOpen, HAVE_XFT=yes, , $XFT_LIBS))
-
-      if test "${HAVE_XFT}" = "yes"; then
-        AC_DEFINE(HAVE_XFT, 1, [Define to 1 if you have the Xft library.])
-       AC_SUBST(XFT_LIBS)
-        C_SWITCH_X_SITE="$C_SWITCH_X_SITE $XFT_CFLAGS"
-      else
-        CPPFLAGS="$OLD_CPPFLAGS"
-        CFLAGS="$OLD_CFLAGS"
-        LIBS="$OLD_LIBS"
-      fi                        # "${HAVE_XFT}" = "yes"
-    fi                          # "$HAVE_XFT" != no
-  fi                            # "x${with_xft}" != "xno"
-
-  dnl For the "Does Emacs use" message at the end.
-  if test "$HAVE_XFT" != "yes"; then
-     HAVE_XFT=no
-  fi
-  
-  
-  HAVE_FREETYPE=no
-  ### Use -lfreetype if available, unless `--with-freetype=no'.
-  if test "${HAVE_XFT}" = "yes"; then
-    dnl As we use Xft, we anyway use freetype.
-    dnl In this case, there's no need of additional CFLAGS and LIBS.
-    HAVE_FREETYPE=yes
-  elif test "x${with_freetype}" != "xno"; then
-  
-    PKG_CHECK_MODULES(FREETYPE, freetype2, HAVE_FREETYPE=yes, HAVE_FREETYPE=no)
-    if test "${HAVE_FREETYPE}" = "yes"; then
-      PKG_CHECK_MODULES(FONTCONFIG, fontconfig, HAVE_FC=yes, HAVE_FC=no)
-      if test "${HAVE_FC}" = "no"; then
-        dnl Without fontconfig, we can't use freetype at the moment.
-        HAVE_FREETYPE=no
-      fi
+  PKG_CHECK_MODULES(FREETYPE, freetype2, HAVE_FREETYPE=yes, HAVE_FREETYPE=no)
+  if test "${HAVE_FREETYPE}" = "yes"; then
+    PKG_CHECK_MODULES(FONTCONFIG, fontconfig, HAVE_FC=yes, HAVE_FC=no)
+    if test "${HAVE_FC}" = "no"; then
+      dnl Without fontconfig, we can't use freetype at the moment.
+      HAVE_FREETYPE=no
     fi
   fi
-  
-  HAVE_LIBOTF=no
-  if test "${HAVE_FREETYPE}" = "yes"; then
-    AC_DEFINE(HAVE_FREETYPE, 1,
-              [Define to 1 if using the freetype and fontconfig libraries.])
-    if test "${with_libotf}" != "no"; then
-      PKG_CHECK_MODULES(LIBOTF, libotf, HAVE_LIBOTF=yes, 
-                        HAVE_LIBOTF=no)
-      if test "$HAVE_LIBOTF" = "yes"; then
-        AC_DEFINE(HAVE_LIBOTF, 1, [Define to 1 if using libotf.])
-      fi
+fi
+
+HAVE_LIBOTF=no
+if test "${HAVE_FREETYPE}" = "yes"; then
+  AC_DEFINE(HAVE_FREETYPE, 1,
+            [Define to 1 if using the freetype and fontconfig libraries.])
+  if test "${with_libotf}" != "no"; then
+    PKG_CHECK_MODULES(LIBOTF, libotf, HAVE_LIBOTF=yes, 
+                      HAVE_LIBOTF=no)
+    if test "$HAVE_LIBOTF" = "yes"; then
+      AC_DEFINE(HAVE_LIBOTF, 1, [Define to 1 if using libotf.])
     fi
+  fi
 dnl FIXME should there be an error if HAVE_FREETYPE != yes?
 dnl Does the new font backend require it, or can it work without it?
+fi
+
+HAVE_M17N_FLT=no
+if test "${with_m17n_flt}" != "no"; then
+  PKG_CHECK_MODULES(M17N_FLT, m17n-flt, HAVE_M17N_FLT=yes, HAVE_M17N_FLT=no)
+  if test "$HAVE_M17N_FLT" = "yes"; then
+    AC_DEFINE(HAVE_M17N_FLT, 1, [Define to 1 if using libm17n-flt.])
   fi
-  
-  HAVE_M17N_FLT=no
-  if test "${with_m17n_flt}" != "no"; then
-    PKG_CHECK_MODULES(M17N_FLT, m17n-flt, HAVE_M17N_FLT=yes, HAVE_M17N_FLT=no)
-    if test "$HAVE_M17N_FLT" = "yes"; then
-      AC_DEFINE(HAVE_M17N_FLT, 1, [Define to 1 if using libm17n-flt.])
-    fi
-  fi
-  
-  AC_SUBST(FREETYPE_CFLAGS)
-  AC_SUBST(FREETYPE_LIBS)
-  AC_SUBST(FONTCONFIG_CFLAGS)
-  AC_SUBST(FONTCONFIG_LIBS)
-  AC_SUBST(LIBOTF_CFLAGS)
-  AC_SUBST(LIBOTF_LIBS)
-  AC_SUBST(M17N_FLT_CFLAGS)
-  AC_SUBST(M17N_FLT_LIBS)
-  
-fi                              # "${USE_FONT_BACKEND}" = "yes"
+fi
+
+AC_SUBST(FREETYPE_CFLAGS)
+AC_SUBST(FREETYPE_LIBS)
+AC_SUBST(FONTCONFIG_CFLAGS)
+AC_SUBST(FONTCONFIG_LIBS)
+AC_SUBST(LIBOTF_CFLAGS)
+AC_SUBST(LIBOTF_LIBS)
+AC_SUBST(M17N_FLT_CFLAGS)
+AC_SUBST(M17N_FLT_LIBS)
+
 ### End of font-backend section.
 
 ### Use -lXpm if available, unless `--with-xpm=no'.
@@ -2996,7 +2983,6 @@ echo "  Does Emacs use -lpng?                                   ${HAVE_PNG}"
 echo "  Does Emacs use -lrsvg-2?                                ${HAVE_RSVG}"
 echo "  Does Emacs use -lgpm?                                   ${HAVE_GPM}"
 echo "  Does Emacs use -ldbus?                                  ${HAVE_DBUS}"
-echo "  Does Emacs use a font backend?                          ${USE_FONT_BACKEND}"
 
 if test "${USE_FONT_BACKEND}" = "yes"; then
   echo "  Does Emacs use -lfreetype?                              ${HAVE_FREETYPE}"
index 3028b0e8c6b62fca93cdbcbba981b9d0a7b71234..e3ac7a98d5ff4c4d7894c127e030be561cde125c 100644 (file)
@@ -343,7 +343,7 @@ This function is the default value of `compose-chars-after-function'."
        pattern func result)
     (or limit
        (setq limit (if (stringp object) (length object) (point-max))))
-    (when tail
+    (when (and font-obj tail)
       (save-match-data
        (save-excursion
          (while tail
@@ -497,9 +497,8 @@ This function is the default value of `auto-composition-function' (which see)."
                  (let* ((ch (aref string from))
                         (elt (aref table ch))
                         font-obj newpos)
-                   (when elt
-                     (if window
-                         (setq font-obj (font-at from window string)))
+                   (when (and elt
+                              (setq font-obj (font-at from window string)))
                      (if (functionp elt)
                          (setq newpos (funcall elt from to font-obj string))
                        (while (and elt
@@ -519,9 +518,8 @@ This function is the default value of `auto-composition-function' (which see)."
                  (let* ((ch (char-after from))
                         (elt (aref table ch))
                         func pattern font-obj newpos)
-                   (when elt
-                     (if window
-                         (setq font-obj (font-at from window)))
+                   (when (and elt
+                              (setq font-obj (font-at from window)))
                      (if (functionp elt)
                          (setq newpos (funcall elt from to font-obj nil))
                        (goto-char from)
@@ -661,7 +659,7 @@ With arg, enable it iff arg is positive."
                (font-obj (and (display-multi-font-p)
                               (font-at (point) (selected-window))))
                (pos (point)))
-           (if (functionp func)
+           (if (and (functionp func) font-obj)
                (goto-char (funcall func (point) to font-obj nil)))
            (if (<= (point) pos)
                (forward-char 1)))))
index 61a06dd2ee5847499ec5e8393792c0175c43dcdc..c5665990732cb52a8d1d03fb5d7debf760bffc43 100644 (file)
@@ -86,7 +86,6 @@
             (const :tag "ultracondensed" ultra-condensed)
             (const :tag "ultraexpanded" ultra-expanded)
             (const :tag "wide" extra-expanded)))
-
     (:height
      (choice :tag "Height"
             :help-echo "Face's font height."
             (const :tag "semibold" semi-bold)
             (const :tag "semilight" semi-light)
             (const :tag "ultralight" ultra-light)
-            (const :tag "ultrabold" ultra-bold)))
+            (const :tag "ultrabold" ultra-bold)
+            (const :tag "thin" thin)))
 
     (:slant
      (choice :tag "Slant"
index f30fc752fba117b9aaccf0940e1e1cac154d0313..556497a6a12800fce50337b0bf9a18409eafd802 100644 (file)
@@ -103,76 +103,41 @@ REGISTRY, ALTERNATIVE1, ALTERNATIVE2, and etc."
           (internal-set-alternative-font-registry-alist value)))
 
 
-(defcustom font-weight-table
-  (if (eq system-type 'windows-nt)
-      '((thin . 100)
-        (ultralight . 199) (ultra-light . 200) (extra-light . 201)
-        (light . 300)
-        (semilight . 330) (semi-light . 331)
-        (book . 350)
-        (normal . 400) (regular . 401)
-        (medium . 500)
-        (semibold . 599) (semi-bold . 600) (demibold . 601) (demi . 602)
-        (bold . 700)
-        (extrabold . 799) (extra-bold . 800)
-        (ultrabold . 801) (ultra-bold . 802)
-        (black . 900) (heavy . 901))
-    '((thin . 0)
-      (ultralight . 39) (ultra-light . 40) (extra-light . 41)
-      (light . 50)
-      (semilight . 65) (semi-light . 66)
-      (book . 75)
-      (medium . 99) (regular . 100) (normal . 101)
-      (semibold . 179) (semi-bold . 180) (demibold . 181) (demi . 182)
-      (bold . 200)
-      (extrabold . 204) (extra-bold . 205)
-      (ultrabold . 206) (ultra-bold . 207)
-      (black . 210) (heavy . 211)))
-  "*Alist of font weight symbols vs the corresponding numeric values."
-  :tag "Font weight table"
-  :version "23.1"
-  :group 'font-selection
-  :type '(repeat (cons symbol integer))
-  :set #'(lambda (symbol value)
-          (set-default symbol value)
-          (if (fboundp 'internal-set-font-style-table)
-              (internal-set-font-style-table :weight value))))
-
-(defcustom font-slant-table
-  '((ro . 0)
-    (ri . 10)
-    (r . 98) (roman . 99) (normal . 100)
-    (i . 199) (italic . 200) (ot . 201)
-    (o . 210) (oblique . 211))
-  "*Alist of font slant symbols vs the corresponding numeric values."
-  :tag "Font slant table"
-  :version "23.1"
-  :group 'font-selection
-  :type '(repeat (cons symbol integer))
-  :set #'(lambda (symbol value)
-          (set-default symbol value)
-          (if (fboundp 'internal-set-font-style-table)
-              (internal-set-font-style-table :slant value))))
-
-(defcustom font-swidth-table
-  '((ultracondensed . 50) (ultra-condensed . 51)
-    (extracondensed . 63) (extra-condensed . 64)
-    (narrow . 74) (compressed . 75) (condensed . 76)
-    (semi-condensed . 87) (semicondensed . 88)
-    (medium . 99) (normal . 100) (regular . 101)
-    (semiexpanded . 112) (semi-expanded . 113) (demiexpanded . 114)
-    (expanded . 125)
-    (extraexpanded . 150) (extra-expanded . 151)
-    (ultraexpanded . 199) (ultra-expanded . 200) (wide . 201))
-  "*Alist of font swidth symbols vs the corresponding numeric values."
-  :tag "Font swidth table"
-  :version "23.1"
-  :group 'font-selection
-  :type '(repeat (cons symbol integer))
-  :set #'(lambda (symbol value)
-          (set-default symbol value)
-          (if (fboundp 'internal-set-font-style-table)
-              (internal-set-font-style-table :width value))))
+(defconst font-weight-table
+  '((thin 0)
+    (ultra-light 20 ultralight)
+    (extra-light 40 extralight)
+    (light 50)
+    (semi-light 75 semilight demilight book)
+    (normal 100 medium regular)
+    (semi-bold 180 semibold demibold demi)
+    (bold 200)
+    (extra-bold 205 extrabold)
+    (ultra-bold 210 ultrabold black))
+  "Alist of font weight symbols vs the corresponding numeric values.")
+
+(defconst font-slant-table
+  '((reverse-oblique 0 ro)
+    (reverse-italic 10 ri)
+    (normal 100 r)
+    (italic 200 i ot)
+    (oblique 210 o))
+  "Alist of font slant symbols vs the corresponding numeric values.")
+
+(defconst font-width-table
+  '((ultra-condensed 50 ultracondensed)
+    (extra-condensed 63 extracondensed)
+    (condensed 75 compressed narrow)
+    (semi-condensed 87 semicondensed semicondensed)
+    (normal 100 medium regular)
+    (semi-expanded 113 semiexpanded demiexpanded)
+    (expanded 125)
+    (extra-expanded 150 extraexpanded)
+    (ultra-expanded 200 ultraexpanded wide))
+  "Alist of font width symbols vs the corresponding numeric values.")
+
+(internal-set-font-style-table
+ font-weight-table font-slant-table font-width-table)
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Creation, copying.
@@ -1016,12 +981,21 @@ an integer value."
            (:family
             (if (window-system frame)
                 (mapcar #'(lambda (x) (cons (car x) (car x)))
-                        (x-font-family-list))
+                        (font-family-list))
              ;; Only one font on TTYs.
              (list (cons "default" "default"))))
-           ((:width :weight :slant :inverse-video)
-            (mapcar #'(lambda (x) (cons (symbol-name x) x))
-                    (internal-lisp-face-attribute-values attribute)))
+          (:width
+           (mapcar #'(lambda (x) (cons (symbol-name (car x)) (car x)))
+                   font-width-table))
+           (:weight
+           (mapcar #'(lambda (x) (cons (symbol-name (car x)) (car x)))
+                   font-weight-table))
+          (:slant
+           (mapcar #'(lambda (x) (cons (symbol-name (car x)) (car x)))
+                   font-slant-table))
+          (:inverse-video
+           (mapcar #'(lambda (x) (cons (symbol-name x) x))
+                   (internal-lisp-face-attribute-values attribute)))
            ((:underline :overline :strike-through :box)
             (if (window-system frame)
                 (nconc (mapcar #'(lambda (x) (cons (symbol-name x) x))
index 0a885513edfe64d1ebc83f062b27188bed294cf8..d5a5073e4392a8e0f50108872f234ab064fefaa1 100644 (file)
 
      (yi ,(font-spec :registry "iso10646-1" :script 'yi))
 
-     (kana ,(font-spec :registry "iso10646-1" :script 'kana)
-          (nil . "JISX0208*")
+     (kana (nil . "JISX0208*")
           (nil . "GB2312.1980-0")
           (nil . "KSC5601.1987*")
           (nil . "JISX0201*")
           (nil . "JISX0213.2000-1")
-          (nil . "JISX0213.2004-1"))
+          (nil . "JISX0213.2004-1")
+          ,(font-spec :registry "iso10646-1" :script 'kana))
 
      (bopomofo ,(font-spec :registry "iso10646-1" :script 'bopomofo)
               (nil . "sisheng_cwnn-0"))
 
-     (han ,(font-spec :registry "iso10646-1" :language 'ja)
-         ,(font-spec :registry "iso10646-1" :language 'zh)
-         (nil . "GB2312.1980-0")
+     (han (nil . "GB2312.1980-0")
          (nil . "JISX0208*")
          (nil . "JISX0212*")
          (nil . "big5*")
          (nil . "gb18030")
          (nil . "JISX0213.2000-1")
          (nil . "JISX0213.2000-2")
-         (nil . "JISX0213.2004-1"))
+         (nil . "JISX0213.2004-1")
+         ,(font-spec :registry "iso10646-1" :lang 'ja)
+         ,(font-spec :registry "iso10646-1" :lang 'zh))
 
-     (cjk-misc ,(font-spec :registry "iso10646-1" :language 'ja)
-              ,(font-spec :registry "iso10646-1" :language 'zh)
-              (nil . "GB2312.1980-0")
+     (cjk-misc (nil . "GB2312.1980-0")
               (nil . "JISX0208*")
               (nil . "JISX0212*")
               (nil . "big5*")
               (nil . "gbk-0")
               (nil . "gb18030")
               (nil . "JISX0213.2000-1")
-              (nil . "JISX0213.2000-2"))
+              (nil . "JISX0213.2000-2")
+              ,(font-spec :registry "iso10646-1" :language 'ja)
+              ,(font-spec :registry "iso10646-1" :language 'zh))
 
-     (hangul ,(font-spec :registry "iso10646-1" :language 'ko)
-            (nil . "KSC5601.1987-0"))
+     (hangul (nil . "KSC5601.1987-0")
+            ,(font-spec :registry "iso10646-1" :language 'ko))
 
      (braille ,(font-spec :registry "iso10646-1" :script 'braille))
 
@@ -745,6 +745,7 @@ Done when `mouse-set-font' is called."
   (let (l)
     (dolist (fontset (fontset-list))
       (or (string-match "fontset-default$" fontset)
+         (string-match "fontset-auto[0-9]+$" fontset)
          (push (list (fontset-plain-name fontset) fontset) l)))
     (cons "Fontset"
          (sort l #'(lambda (x y) (string< (car x) (car y)))))))
index a04ffe18772e323926ea86358fdbaf15764dbe85..67f77c3c9d034225a9fb1d3286b65891853a5fc7 100644 (file)
@@ -1845,6 +1845,9 @@ specifies the character set for the major languages of Western Europe."
     (if (functionp func)
        (funcall func)))
 
+  (setq current-iso639-language
+       (get-language-info language-name 'iso639-language))
+
   (run-hooks 'set-language-environment-hook)
   (force-mode-line-update t))
 
index fd39368687665aecea3f7b434f160bc3e785d3e8..815cf7aa0e037f95bf0ff444fb18db0373782aeb 100644 (file)
 
 (set-language-info-alist
  "Chinese-GB" '((charset chinese-gb2312 chinese-sisheng)
+               (iso639-language . zh)
                (coding-system chinese-iso-8bit iso-2022-cn chinese-hz)
                (coding-priority chinese-iso-8bit chinese-big5 iso-2022-cn)
                (input-method . "chinese-py-punct")
 
 (set-language-info-alist
  "Chinese-BIG5" '((charset chinese-big5-1 chinese-big5-2)
+                 (iso639-language . zh)
                  (coding-system chinese-big5 chinese-iso-7bit)
                  (coding-priority chinese-big5 iso-2022-cn chinese-iso-8bit)
                  (input-method . "chinese-py-punct-b5")
                          chinese-cns11643-3 chinese-cns11643-4
                          chinese-cns11643-5 chinese-cns11643-6
                          chinese-cns11643-7)
+                (iso639-language . zh)
                 (coding-system iso-2022-cn euc-tw)
                 (coding-priority iso-2022-cn euc-tw chinese-big5
                                  chinese-iso-8bit)
@@ -201,6 +204,7 @@ accepts Big5 for input also (which is then converted to CNS)."))
                             chinese-cns11643-3 chinese-cns11643-4
                             chinese-cns11643-5 chinese-cns11643-6
                             chinese-cns11643-7 chinese-big5-1 chinese-big5-2)
+                   (iso639-language . zh)
                    (coding-system euc-tw iso-2022-cn)
                    (coding-priority euc-tw chinese-big5 iso-2022-cn
                                     chinese-iso-8bit)
@@ -227,6 +231,7 @@ converted to CNS)."))
 
 (set-language-info-alist
  "Chinese-GBK" '((charset chinese-gbk)
+                (iso639-language . zh)
                 (coding-system chinese-gbk)
                 (coding-priority gbk iso-2022-cn chinese-big5
                                  chinese-iso-8bit) ; fixme?
@@ -253,6 +258,7 @@ converted to CNS)."))
 
 (set-language-info-alist
  "Chinese-GB18030" '((charset gb18030)
+                    (iso639-language . zh)
                     (coding-system chinese-gb18030)
                     (coding-priority gb18030 gbk iso-2022-cn chinese-big5
                                      chinese-iso-8bit) ; fixme?
index 2d7a3e41bcc4117f6d718835c45754f8b0138d0a..be68d89757f652be4dec62e35a0a0ebb9193a02e 100644 (file)
@@ -197,6 +197,7 @@ eucJP-ms is defined in <http://www.opengroup.or.jp/jvc/cde/appendix.html>."
 (set-language-info-alist
  "Japanese" '((setup-function . setup-japanese-environment-internal)
              (exit-function . use-default-char-width-table)
+             (iso639-language . ja)
              (tutorial . "TUTORIAL.ja")
              (charset japanese-jisx0208
                       japanese-jisx0212 latin-jisx0201 katakana-jisx0201
index 725bf23c19e00944a825d88e5d7dd1905e1262b4..bca437d92b1f2c1dae78a28d531852292ba1afe7 100644 (file)
@@ -63,6 +63,7 @@
 (set-language-info-alist
  "Korean" '((setup-function . setup-korean-environment-internal)
            (exit-function . exit-korean-environment)
+           (iso639-language . ko)
            (tutorial . "TUTORIAL.ko")
            (charset korean-ksc5601)
            (coding-system iso-2022-kr korean-iso-8bit)
diff --git a/src/ChangeLog.fb b/src/ChangeLog.fb
new file mode 100644 (file)
index 0000000..dee6b9e
--- /dev/null
@@ -0,0 +1,103 @@
+2008-04-30  Kenichi Handa  <handa@m17n.org>
+
+       * font.c: Include <strings.h>.
+       (enable_font_backend): Delete it.
+       (Qfont_spec, Qfont_entity, Qfont_object): New variables.
+       (CHECK_VALIDATE_FONT_SPEC): Delete it.
+       (PT_PER_INCH, POINT_TO_PIXEL, PIXEL_TO_POINT): Moved to font.h.
+       (null_string): Delete it.
+       (null_vector): Make it static.
+       (font_family_alist): Delete it.
+       (Qnormal): Extern it.
+       (QCextra, QClanguage): Delete it.
+       (QClang, QCavgwidth, QCfont_entity, QCfc_unknown_spec): New
+       variables.
+       (font_make_spec, font_make_entity, font_make_object)
+       (font_intern_prop): Renamed from intern_downcase.  Don't downcase
+       the string.  Callers changed.
+       (font_pixel_size): Adjusted for the format change of font-related
+       objects.
+       (prop_name_to_numeric, prop_numeric_to_name): Delete them.
+       (font_style_to_value, font_style_symbolic): New function.
+       (build_font_family_alist): Delete it.
+       (font_registry_charsets): Use Fassoc_string instead of
+       assq_no_quit.
+       (font_prop_validate_symbol): Don't return null_string.
+       (font_prop_validate_style): Adjusted for the change of
+       style-related values in a font vector.
+       (font_property_table): Delete entries for QClangauge and
+       QCantialias, add entries for QCavgwidth.
+       (get_font_prop_index): Delete the 2nd argument FROM.
+       (font_prop_validate): Arguments changed.
+       (font_put_extra): Adjusted for the change of font-related objects.
+       (font_expand_wildcards, font_parse_xlfd, font_unparse_xlfd)
+       (font_parse_fcname, font_unparse_fcname)
+       (font_prepare_composition): Likewise.
+       (font_parse_family_registry): Renamed from font_merge_old_spec.
+       (otf_open): Delete the 1st arg entity.
+       (font_otf_capability): Adjusted for the above change.
+       (font_score): New arg alternate_families.  Adjusted for the change
+       of font-related objects.
+       (font_sort_entites): New arg best_only.
+       (font_symbolic_weight, font_symbolic_slant, font_symbolic_width):
+       Delete them.
+       (font_match_p): Check alternate families.
+       (font_find_object): Delete it.
+       (font_check_object): New function.
+       (font_clear_cache): Adjusted for the change of font-related
+       objects.
+       (font_delete_unmatched): New arg.
+       (font_list_entities): Call font_driver->list with a spec that
+       doesn't specify style-related properties.
+       (font_matching_entity): Arguments changed.  Caller changed.
+       (font_open_entity): Adjusted for the change of font-related
+       objects.
+       (font_close_object, font_has_char, font_encode_char)
+       (font_get_name, font_get_spec): Likewise.
+       (font_spec_from_name, font_clear_prop, font_update_lface): New
+       functions.
+       (font_find_for_lface, font_open_for_lface, font_load_for_lface):
+       (font_prepare_for_face, font_done_for_face, font_open_by_name)
+       (font_at): Adjusted for the change of font-related objects.
+       (font_range): New function.
+       (Ffontp, Ffont_spec, Ffont_get, Ffont_put, Flist_fonts)
+       (Ffont_xlfd_name): Adjusted for the change of font-related
+       objects.
+       (Fcopy_font_spec, Fmerge_font_spec): New function.
+       (Ffont_family_list): Renamed from list-families.
+       (Finternal_set_font_style_table): Arguments changed.
+       (Ffont_fill_gstring, Ffont_shape_text, Fopen_font)
+       (Ffont_drive_otf, Fquery_font, Ffont_match_p): Adjusted for the
+       change of font-related objects.
+       (syms_of_font): Delete "ifdef USE_FONT_BACKEND".  DEFSYM new
+       symboles.
+
+2008-04-28  Kenichi Handa  <handa@m17n.org>
+
+       * font.h (Qfont_spec, Qfont_entity, Qfont_object): Extern them.
+       (enum font_property_index): New members FONT_DPI_INDEX,
+       FONT_SPACING_INDEX, FONT_AVGWIDTH_INDEX, FONT_NAME_INDEX,
+       FONT_FULLNAME_INDEX, FONT_FILE_INDEX, FONT_FORMAT_INDEX,
+       FONT_OBJECT_MAX.  Delete FONT_FRAME_INDEX.
+       (FONT_WEIGHT_NUMERIC, FONT_SLANT_NUMERIC, FONT_WIDTH_NUMERIC)
+       (FONT_WEIGHT_SYMBOLIC, FONT_SLANT_SYMBOLIC, FONT_WIDTH_SYMBOLIC)
+       (FONT_WEIGHT_FOR_FACE, FONT_SLANT_FOR_FACE, FONT_WIDTH_FOR_FACE)
+       (FONT_WEIGHT_NAME_NUMERIC, FONT_SLANT_NAME_NUMERIC)
+       (FONT_WIDTH_NAME_NUMERIC, FONT_SET_STYLE): New macros.
+       (struct font_spec, struct font_entity): New structs.
+       (FONT_ENCODING_NOT_DECIDED): Moved from fontset.h.
+       (struct font): Many members from old "struct font_info" moved to
+       here.  Members font and entity deleted.
+       (FONT_SPEC_P, FONT_ENTITY_P, FONT_OBJECT_P, FONTP): Modified for
+       the new font-related objects.
+       (CHECK_FONT_SPEC, CHECK_FONT_ENTITY, CHECK_FONT_OBJECT)
+       (CHECK_FONT_GET_OBJECT): Likewise.
+       (XFONT_SPEC, XFONT_ENTITY, XFONT_OBJECT, XSETFONT): New macros.
+       (PT_PER_INCH, POINT_TO_PIXEL, PIXEL_TO_POINT): Moved from font.h.
+       (struct font_driver): New members case_sensitive anc check.  Type
+       of the member open changed.
+       (enable_font_backend, font_symbolic_weight, font_symbolic_slant)
+       (font_symbolic_width, font_find_object, font_get_spec)
+       (font_set_lface_from_name): Delete extern.
+       (Fcopy_font_spec, Fmerge_font_spec, Ffont_family_list): New
+       EXFUNs.
index 77e082d5f1f4f4c957c0d91dd732512976619dce..b048ef18284a6ce1d580efdcadba5a546802f51d 100644 (file)
@@ -541,7 +541,6 @@ emacsappsrc = ${srcdir}/../mac/Emacs.app/
 
 #ifdef HAVE_WINDOW_SYSTEM
 FONTSRC = font.h
-#ifdef USE_FONT_BACKEND
 #ifdef HAVE_X_WINDOWS
 #if defined (HAVE_XFT)
 FONTOBJ = font.o xfont.o ftfont.o xftfont.o ftxfont.o
@@ -553,9 +552,6 @@ FONTOBJ = font.o xfont.o
 #else /* ! HAVE_X_WINDOWS */
 FONTOBJ = font.o
 #endif /* ! HAVE_X_WINDOWS */
-#else  /* ! USE_FONT_BACKEND */
-FONTOBJ = font.o
-#endif /* ! USE_FONT_BACKEND */
 #endif /* HAVE_WINDOW_SYSTEM */
 
 /* lastfile must follow all files
@@ -1084,7 +1080,7 @@ filelock.o: filelock.c buffer.h character.h charset.h coding.h systime.h \
    epaths.h $(config_h)
 filemode.o: filemode.c  $(config_h)
 frame.o: frame.c xterm.h window.h frame.h termhooks.h commands.h keyboard.h \
-   blockinput.h atimer.h systime.h buffer.h character.h fontset.h \
+   blockinput.h atimer.h systime.h buffer.h character.h fontset.h font.h \
    msdos.h dosfns.h dispextern.h w32term.h macterm.h termchar.h $(config_h)
 fringe.o: fringe.c dispextern.h frame.h window.h buffer.h termhooks.h $(config_h)
 font.o: font.c dispextern.h frame.h window.h ccl.h character.h charset.h \
@@ -1094,7 +1090,8 @@ fontset.o: dispextern.h fontset.h fontset.c ccl.h buffer.h character.h \
    charset.h frame.h keyboard.h termhooks.h $(FONTSRC) $(config_h)
 getloadavg.o: getloadavg.c $(config_h)
 image.o: image.c frame.h window.h dispextern.h blockinput.h atimer.h \
-   systime.h xterm.h w32term.h w32gui.h macterm.h macgui.h $(config_h)
+   systime.h xterm.h w32term.h w32gui.h macterm.h macgui.h $(FONTSRC) \
+   $(config_h)
 indent.o: indent.c frame.h window.h indent.h buffer.h $(config_h) termchar.h \
    termopts.h disptab.h region-cache.h character.h category.h composite.h \
    dispextern.h keyboard.h
@@ -1220,7 +1217,7 @@ fns.o: fns.c commands.h $(config_h) frame.h buffer.h character.h keyboard.h \
  blockinput.h atimer.h systime.h xterm.h termhooks.h
 print.o: print.c process.h frame.h window.h buffer.h keyboard.h character.h \
    $(config_h) dispextern.h termchar.h $(INTERVAL_SRC) msdos.h composite.h \
-   blockinput.h atimer.h systime.h
+   blockinput.h atimer.h systime.h $(FONTSRC)
 lread.o: lread.c commands.h keyboard.h buffer.h epaths.h character.h \
  charset.h $(config_h) $(INTERVAL_SRC) termhooks.h coding.h msdos.h
 
index 5fe7e43a7a8f1325451e6555aa7e239b3772b0da..121cea7521d33b2bdde63d3004c978c9a9bc6b5e 100644 (file)
@@ -97,6 +97,10 @@ int charset_unibyte;
 /* List of charsets ordered by the priority.  */
 Lisp_Object Vcharset_ordered_list;
 
+/* Sub-list of Vcharset_ordered_list that contains all non-preferred
+   charsets.  */
+Lisp_Object Vcharset_non_preferred_head;
+
 /* Incremented everytime we change Vcharset_ordered_list.  This is
    unsigned short so that it fits in Lisp_Int and never matches
    -1.  */
@@ -118,6 +122,8 @@ Lisp_Object Vcharset_map_path;
 
 Lisp_Object Vchar_unified_charset_table;
 
+Lisp_Object Vcurrent_iso639_language;
+
 /* Defined in chartab.c */
 extern void
 map_char_table_for_charset P_ ((void (*c_function) (Lisp_Object, Lisp_Object),
@@ -1810,7 +1816,8 @@ char_charset (c, charset_list, code_return)
   if (NILP (charset_list))
     charset_list = Vcharset_ordered_list;
 
-  while (CONSP (charset_list))
+  while (CONSP (charset_list)
+        && ! EQ (charset_list, Vcharset_non_preferred_head))
     {
       struct charset *charset = CHARSET_FROM_ID (XINT (XCAR (charset_list)));
       unsigned code = ENCODE_CHAR (charset, c);
@@ -1823,7 +1830,8 @@ char_charset (c, charset_list, code_return)
        }
       charset_list = XCDR (charset_list);
     }
-  return NULL;
+  return (c <= MAX_UNICODE_CHAR ? CHARSET_FROM_ID (charset_unicode)
+         : CHARSET_FROM_ID (charset_eight_bit));
 }
 
 
@@ -1994,7 +2002,7 @@ usage: (set-charset-priority &rest charsets)  */)
        }
     }
   arglist[0] = Fnreverse (new_head);
-  arglist[1] = old_list;
+  arglist[1] = Vcharset_non_preferred_head = old_list;
   Vcharset_ordered_list = Fnconc (2, arglist);
   charset_ordered_list_tick++;
 
@@ -2133,6 +2141,12 @@ syms_of_charset ()
               doc: /* List of all charsets ever defined.  */);
   Vcharset_list = Qnil;
 
+  DEFVAR_LISP ("current-iso639-language", &Vcurrent_iso639_language,
+              doc: /* ISO639 language mnemonic symbol for the current language environment.
+If the current language environment is for multiple languages (e.g. "Latin-1"),
+the value may be a list of mnemonics.  */);
+  Vcurrent_iso639_language = Qnil;
+
   charset_ascii
     = define_charset_internal (Qascii, 1, "\x00\x7F\x00\x00\x00\x00",
                               0, 127, 'B', -1, 0, 1, 0, 0);
index 4b8bee4520d93f5cbef59c93d0225e69b0961c16..e037dbfe54b2cc0852dae4b175c9d57fe7283936 100644 (file)
@@ -253,6 +253,7 @@ extern struct charset *charset_table;
 #define CHARSET_FROM_ID(id) (charset_table + (id))
 
 extern Lisp_Object Vcharset_ordered_list;
+extern Lisp_Object Vcharset_non_preferred_head;
 
 /* Incremented everytime we change the priority of charsets.  */
 extern unsigned short charset_ordered_list_tick;
@@ -263,6 +264,7 @@ extern Lisp_Object Vemacs_mule_charset_list;
 
 extern struct charset *emacs_mule_charset[256];
 
+extern Lisp_Object Vcurrent_iso639_language;
 
 /* Macros to access information about charset.  */
 
index 81e8e4e10bc9e99efe2bceab2aedd1b9f81c8579..4e8063543fe73de6934a6c2f96617b09a250b1d4 100644 (file)
@@ -2695,6 +2695,8 @@ detect_coding_iso_2022 (coding, detect_info)
       struct coding_system *this = &(coding_categories[i]);
       Lisp_Object attrs, val;
 
+      if (this->id < 0)
+       continue;
       attrs = CODING_ID_ATTRS (this->id);
       if (CODING_ISO_FLAGS (this) & CODING_ISO_FLAG_FULL_SUPPORT
          && ! EQ (CODING_ATTR_SAFE_CHARSETS (attrs), Viso_2022_charset_list))
index 52fae5532818fafc03b6fd68e90e603938d5aeaa..b2344734c050dc67dfd49ec556bac14eaee6d0c9 100644 (file)
@@ -159,7 +159,6 @@ EXFUN (Fremove_list_of_text_properties, 4);
 /* Temporary variable used in macros COMPOSITION_XXX.  */
 Lisp_Object composition_temp;
 
-extern int enable_font_backend;
 \f
 /* Return COMPOSITION-ID of a composition at buffer position
    CHARPOS/BYTEPOS and length NCHARS.  The `composition' property of
@@ -276,9 +275,7 @@ get_composition_id (charpos, bytepos, nchars, prop, string)
      vector or a list.  It should be a sequence of:
        char1 rule1 char2 rule2 char3 ...    ruleN charN+1  */
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend
-      && VECTORP (components)
+  if (VECTORP (components)
       && ASIZE (components) >= 2
       && VECTORP (AREF (components, 0)))
     {
@@ -289,9 +286,7 @@ get_composition_id (charpos, bytepos, nchars, prop, string)
        if (! VECTORP (AREF (key, i)))
          goto invalid_composition;
     }
-  else
-#endif  /* USE_FONT_BACKEND */
-  if (VECTORP (components) || CONSP (components))
+  else if (VECTORP (components) || CONSP (components))
     {
       int len = XVECTOR (key)->size;
 
@@ -324,12 +319,10 @@ get_composition_id (charpos, bytepos, nchars, prop, string)
                 : ((INTEGERP (components) || STRINGP (components))
                    ? COMPOSITION_WITH_ALTCHARS
                    : COMPOSITION_WITH_RULE_ALTCHARS));
-#ifdef USE_FONT_BACKEND
   if (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS
       && VECTORP (components)
       && ! INTEGERP (AREF (components, 0)))
     cmp->method = COMPOSITION_WITH_GLYPH_STRING;
-#endif  /* USE_FONT_BACKEND */
   cmp->hash_index = hash_index;
   glyph_len = (cmp->method == COMPOSITION_WITH_RULE_ALTCHARS
               ? (XVECTOR (key)->size + 1) / 2
@@ -338,16 +331,13 @@ get_composition_id (charpos, bytepos, nchars, prop, string)
   cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2);
   cmp->font = NULL;
 
-#ifdef USE_FONT_BACKEND
+  /* Calculate the width of overall glyphs of the composition.  */
   if (cmp->method == COMPOSITION_WITH_GLYPH_STRING)
     {
       cmp->width = 1;          /* Should be fixed later.  */
       cmp->glyph_len--;
     }
-  else
-#endif /* USE_FONT_BACKEND */
-  /* Calculate the width of overall glyphs of the composition.  */
-  if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
+  else if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
     {
       /* Relative composition.  */
       cmp->width = 0;
@@ -652,12 +642,6 @@ compose_text (start, end, components, modification_func, string)
 {
   Lisp_Object prop;
 
-#if 0
-  if (VECTORP (components) && ASIZE (components) > 1
-      && VECTORP (AREF (components, 0)))
-    prop = components;
-  else
-#endif /* USE_FONT_BACKEND */
   prop = Fcons (Fcons (make_number (end - start), components),
                modification_func);
   Fput_text_property  (make_number (start), make_number (end),
index 88373c7dddcde52bcbd94d20580e0f7b9bf9ac53..602a3834b550b108844ee5854c6f8173c3e91dc6 100644 (file)
@@ -1161,10 +1161,7 @@ struct glyph_string
   struct face *face;
 
   /* Font in which this string is to be drawn.  */
-  XFontStruct *font;
-
-  /* Font info for this string.  */
-  struct font_info *font_info;
+  struct font *font;
 
   /* Non-null means this string describes (part of) a composition.
      All characters from char2b are drawn composed.  */
@@ -1243,6 +1240,10 @@ struct glyph_string
   /* Number of clipping areas. */
   int num_clips;
 
+  int underline_position;
+
+  int underline_thickness;
+
   struct glyph_string *next, *prev;
 };
 
@@ -1413,7 +1414,6 @@ enum lface_attribute_index
   LFACE_BOX_INDEX,
   LFACE_FONT_INDEX,
   LFACE_INHERIT_INDEX,
-  LFACE_AVGWIDTH_INDEX,
   LFACE_FONTSET_INDEX,
   LFACE_VECTOR_SIZE
 };
@@ -1456,12 +1456,6 @@ struct face
      drawing the characters in this face.  */
   GC gc;
 
-  /* Font used for this face, or null if the font could not be loaded
-     for some reason.  This points to a `font' slot of a struct
-     font_info, and we should not call XFreeFont on it because the
-     font may still be used somewhere else.  */
-  XFontStruct *font;
-
   /* Background stipple or bitmap used for this face.  This is
      an id as returned from load_pixmap.  */
   int stipple;
@@ -1489,17 +1483,7 @@ struct face
   unsigned long strike_through_color;
   unsigned long box_color;
 
-  /* The font's name.  This points to a `name' of a font_info, and it
-     must not be freed.  */
-  char *font_name;
-
-  /* Font info ID for this face's font.  An ID is stored here because
-     pointers to font_info structures may change.  The reason is that
-     they are pointers into a font table vector that is itself
-     reallocated.  */
-  int font_info_id;
-
-  struct font_info *font_info;
+  struct font *font;
 
   /* Fontset ID if for this face's fontset.  Non-ASCII faces derived
      from the same ASCII face have the same fontset.  */
@@ -2351,19 +2335,6 @@ struct redisplay_interface
                                    int h, int wd));
   void (*destroy_fringe_bitmap) P_ ((int which));
 
-/* Get metrics of character CHAR2B in FONT of type FONT_TYPE.
-   Value is null if CHAR2B is not contained in the font.  */
-  XCharStruct * (*per_char_metric) P_ ((XFontStruct *font, XChar2b *char2b,
-                                       int font_type));
-
-/* Encode CHAR2B using encoding information from FONT_INFO.  CHAR2B is
-   the two-byte form of C.  Encoding is returned in *CHAR2B.  If
-   TWO_BYTE_P is non-null, return non-zero there if font is two-byte.  */
-  int (*encode_char) P_ ((int c, XChar2b *char2b,
-                         struct font_info *font_into,
-                         struct charset *charset,
-                         int *two_byte_p));
-
 /* Compute left and right overhang of glyph string S.
    A NULL pointer if platform does not support this. */
   void (*compute_glyph_string_overhangs) P_ ((struct glyph_string *s));
@@ -2737,7 +2708,7 @@ extern int unibyte_display_via_language_environment;
 extern void reseat_at_previous_visible_line_start P_ ((struct it *));
 
 extern int calc_pixel_width_or_height P_ ((double *, struct it *, Lisp_Object,
-                                          /* XFontStruct */ void *, int, int *));
+                                          struct font *, int, int *));
 
 #ifdef HAVE_WINDOW_SYSTEM
 
index 4f6e6374da3fc2c48c5e95e4bb0dce3ca7b42447..2b3605a161991b55668a04b59e2cedcb5d557f39 100644 (file)
@@ -324,7 +324,9 @@ static struct frame *frame_matrix_frame;
    matrix adjustments.  Redisplay must stop, and glyph matrices must
    be adjusted when this flag becomes non-zero during display.  The
    reason fonts can be loaded so late is that fonts of fontsets are
-   loaded on demand.  */
+   loaded on demand.  Another reason is that a line contains many
+   characters displayed by zero width or very narrow glyphs of
+   variable-width fonts.  */
 
 int fonts_changed_p;
 
index cafc64601d139f4c2b0d054208c5427caa89b665..e24a0fe2553aedb361c8fc32c48529c6e5e214fb 100644 (file)
@@ -787,9 +787,6 @@ bug_reporting_address ()
   return count >= 3 ? REPORT_EMACS_BUG_PRETEST_ADDRESS : REPORT_EMACS_BUG_ADDRESS;
 }
 
-#ifdef USE_FONT_BACKEND
-extern int enable_font_backend;
-#endif /* USE_FONT_BACKEND */
 
 /* ARGSUSED */
 int
@@ -1426,12 +1423,9 @@ main (argc, argv
   no_loadup
     = argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args);
 
-#ifdef USE_FONT_BACKEND
-  enable_font_backend = 1;
   if (argmatch (argv, argc, "-disable-font-backend", "--disable-font-backend",
                 4, NULL, &skip_args))
-    enable_font_backend = 0;
-#endif /* USE_FONT_BACKEND */
+    ;
 
 #ifdef HAVE_X_WINDOWS
   /* Stupid kludge to catch command-line display spec.  We can't
index e89fbbc2801966dab34bff93d4ea8f791e6c5e75..1f6208dc5485f3c0f1b9d8081c2b23073e1228f6 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -2207,12 +2207,13 @@ internal_equal (o1, o2, depth, props)
        if (WINDOW_CONFIGURATIONP (o1))
          return compare_window_configurations (o1, o2, 0);
 
-       /* Aside from them, only true vectors, char-tables, and compiled
-          functions are sensible to compare, so eliminate the others now.  */
+       /* Aside from them, only true vectors, char-tables, compiled
+          functions, and fonts (font-spec, font-entity, font-ojbect)
+          are sensible to compare, so eliminate the others now.  */
        if (size & PSEUDOVECTOR_FLAG)
          {
            if (!(size & (PVEC_COMPILED
-                         | PVEC_CHAR_TABLE | PVEC_SUB_CHAR_TABLE)))
+                         | PVEC_CHAR_TABLE | PVEC_SUB_CHAR_TABLE | PVEC_FONT)))
              return 0;
            size &= PSEUDOVECTOR_SIZE_MASK;
          }
index 9856c935ef6e0ee0aa765d43ae00fb3e7a019dc3..ba48c276b78a5fbf8ae193fb4e795886b4a2d695 100644 (file)
@@ -24,6 +24,7 @@ Boston, MA 02110-1301, USA.  */
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <strings.h>
 #include <ctype.h>
 #ifdef HAVE_M17N_FLT
 #include <m17n-flt.h>
@@ -63,64 +64,34 @@ Boston, MA 02110-1301, USA.  */
 #define xassert(X)     (void) 0
 #endif
 
-int enable_font_backend;
+Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
 
 Lisp_Object Qopentype;
 
-/* Important character set symbols.  */
+/* Important character set strings.  */
 Lisp_Object Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip;
 
-/* Like CHECK_FONT_SPEC but also validate properties of the font-spec,
-   and set X to the validated result.  */
-
-#define CHECK_VALIDATE_FONT_SPEC(x)                            \
-  do {                                                         \
-    if (! FONT_SPEC_P (x)) wrong_type_argument (Qfont, x);     \
-    x = font_prop_validate (x);                                        \
-  } while (0)
-
-/* Number of pt per inch (from the TeXbook).  */
-#define PT_PER_INCH 72.27
-
-/* Return a pixel size (integer) corresponding to POINT size (double)
-   on resolution DPI.  */
-#define POINT_TO_PIXEL(POINT, DPI) ((POINT) * (DPI) / PT_PER_INCH + 0.5)
-
-/* Return a point size (double) corresponding to POINT size (integer)
-   on resolution DPI.  */
-#define PIXEL_TO_POINT(PIXEL, DPI) ((PIXEL) * PT_PER_INCH * 10 / (DPI) + 0.5)
-
-/* Special string of zero length.  It is used to specify a NULL name
-   in a font properties (e.g. adstyle).  We don't use the symbol of
-   NULL name because it's confusing (Lisp printer prints nothing for
-   it). */
-Lisp_Object null_string;
-
 /* Special vector of zero length.  This is repeatedly used by (struct
    font_driver *)->list when a specified font is not found. */
-Lisp_Object null_vector;
+static Lisp_Object null_vector;
 
-/* Vector of 3 elements.  Each element is an alist for one of font
-   style properties (weight, slant, width).  Each alist contains a
+/* Vector of 3 elements.  Each element is a vector for one of font
+   style properties (weight, slant, width).  The vector contains a
    mapping between symbolic property values (e.g. `medium' for weight)
    and numeric property values (e.g. 100).  So, it looks like this:
-       [((thin . 0) ... (heavy . 210))
-        ((ro . 0) ... (ot . 210))
-        ((ultracondensed . 50) ... (wide . 200))]  */
+       [[(ultra-light . 20) ... (black . 210)]
+        [(reverse-oblique . 0) ... (oblique . 210)]
+        [(ultra-contains . 50) ... (wide . 200)]]  */
 static Lisp_Object font_style_table;
 
-/* Alist of font family vs the corresponding aliases.
-   Each element has this form:
-       (FAMILY ALIAS1 ALIAS2 ...)   */
-
-static Lisp_Object font_family_alist;
+extern Lisp_Object Qnormal;
 
 /* Symbols representing keys of normal font properties.  */
 extern Lisp_Object QCtype, QCfamily, QCweight, QCslant, QCwidth, QCsize, QCname;
-Lisp_Object QCfoundry, QCadstyle, QCregistry, QCextra;
+Lisp_Object QCfoundry, QCadstyle, QCregistry;
 /* Symbols representing keys of font extra info.  */
-Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClanguage, QCscript;
-Lisp_Object QCantialias;
+Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript, QCavgwidth;
+Lisp_Object QCantialias, QCfont_entity, QCfc_unknown_spec;
 /* Symbols representing values of font spacing property.  */
 Lisp_Object Qc, Qm, Qp, Qd;
 
@@ -147,16 +118,92 @@ static Lisp_Object font_charset_alist;
    here.  */
 static struct font_driver_list *font_driver_list;
 
+\f
+
+/* Creaters of font-related Lisp object.  */
+
+Lisp_Object
+font_make_spec ()
+{
+  Lisp_Object font_spec;
+  struct font_spec *spec
+    = ((struct font_spec *)
+       allocate_pseudovector (VECSIZE (struct font_spec),
+                             FONT_SPEC_MAX, PVEC_FONT));
+  XSETFONT (font_spec, spec);
+  return font_spec;
+}
+
+Lisp_Object
+font_make_entity ()
+{
+  Lisp_Object font_entity;
+  struct font_entity *entity
+    = ((struct font_entity *)
+       allocate_pseudovector (VECSIZE (struct font_entity),
+                             FONT_ENTITY_MAX, PVEC_FONT));
+  XSETFONT (font_entity, entity);
+  return font_entity;
+}
+
+Lisp_Object
+font_make_object (size)
+     int size;
+{
+  Lisp_Object font_object;
+  struct font *font
+    = (struct font *) allocate_pseudovector (size, FONT_OBJECT_MAX, PVEC_FONT);
+  XSETFONT (font_object, font);
+
+  return font_object;
+}
+
+\f
+
 static int font_pixel_size P_ ((FRAME_PTR f, Lisp_Object));
-static Lisp_Object prop_name_to_numeric P_ ((enum font_property_index,
-                                            Lisp_Object));
-static Lisp_Object prop_numeric_to_name P_ ((enum font_property_index, int));
 static Lisp_Object font_open_entity P_ ((FRAME_PTR, Lisp_Object, int));
-static void build_font_family_alist P_ ((void));
+static Lisp_Object font_matching_entity P_ ((FRAME_PTR, Lisp_Object *,
+                                            Lisp_Object));
 
 /* Number of registered font drivers.  */
 static int num_font_drivers;
 
+
+/* Return a Lispy value of a font property value at STR and LEN bytes.
+   If STR is "*", it returns nil.
+   If all characters in STR are digits, it returns an integer.
+   Otherwise, it returns a symbol interned from STR.  */
+
+Lisp_Object
+font_intern_prop (str, len)
+     char *str;
+     int len;
+{
+  int i;
+  Lisp_Object tem, string;
+  Lisp_Object obarray;
+
+  if (len == 1 && *str == '*')
+    return Qnil;
+  if (len >=1 && isdigit (*str))
+    {
+      for (i = 1; i < len; i++)
+       if (! isdigit (str[i]))
+         break;
+      if (i == len)
+       return make_number (atoi (str));
+    }
+
+  /* The following code is copied from the function intern (in lread.c).  */
+  obarray = Vobarray;
+  if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
+    obarray = check_obarray (obarray);
+  tem = oblookup (obarray, str, len, len);
+  if (SYMBOLP (tem))
+    return tem;
+  return Fintern (make_unibyte_string (str, len), obarray);
+}
+
 /* Return a pixel size of font-spec SPEC on frame F.  */
 
 static int
@@ -173,119 +220,118 @@ font_pixel_size (f, spec)
     return XINT (size);
   if (NILP (size))
     return 0;
+  xassert (FLOATP (size));
   point_size = XFLOAT_DATA (size);
-  extra = AREF (spec, FONT_EXTRA_INDEX);
-  val = assq_no_quit (QCdpi, extra);
-  if (CONSP (val))
-    {
-      if (INTEGERP (XCDR (val)))
-       dpi = XINT (XCDR (val));
-      else
-       dpi = XFLOAT_DATA (XCDR (val)) + 0.5;
-    }
+  dpi = AREF (spec, FONT_DPI_INDEX);
+  if (INTEGERP (dpi))
+    dpi = XINT (XCDR (val));
   else
     dpi = f->resy;
   pixel_size = POINT_TO_PIXEL (point_size, dpi);
   return pixel_size;
 }
 
-/* Return a numeric value corresponding to PROP's NAME (symbol).  If
-   NAME is not registered in font_style_table, return Qnil.  PROP must
-   be one of FONT_{WEIGHT|SLANT|SWIDTH}_INDEX.  */
-
-static Lisp_Object
-prop_name_to_numeric (prop, name)
-     enum font_property_index prop;
-     Lisp_Object name;
-{
-  int table_index = prop - FONT_WEIGHT_INDEX;
-  Lisp_Object val;
-
-  val = assq_no_quit (name, AREF (font_style_table, table_index));
-  return (NILP (val) ? Qnil : XCDR (val));
-}
-
 
-/* Return a name (symbol) corresponding to PROP's NUMERIC value.  If
-   no name is registered for NUMERIC in font_style_table, return a
-   symbol of integer name (e.g. `123').  PROP must be one of
-   FONT_{WEIGHT|SLANT|SWIDTH}_INDEX.  */
+/* Return a value of PROP's VAL (symbol or integer) to be stored in a
+   font vector.  If VAL is not valid (i.e. not registered in
+   font_style_table), return -1 if NOERROR is zero, and return a
+   proper index if NOERROR is nonzero.  In that case, register VAL in
+   font_style_table if VAL is a symbol, and return a closest index if
+   VAL is an integer.  */
 
-static Lisp_Object
-prop_numeric_to_name (prop, numeric)
+int
+font_style_to_value (prop, val, noerror)
      enum font_property_index prop;
-     int numeric;
+     Lisp_Object val;
+     int noerror;
 {
-  int table_index = prop - FONT_WEIGHT_INDEX;
-  Lisp_Object table = AREF (font_style_table, table_index);
-  char buf[10];
+  Lisp_Object table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX);
+  int len = ASIZE (table);
+  int i;
 
-  while (! NILP (table))
+  if (SYMBOLP (val))
     {
-      if (XINT (XCDR (XCAR (table))) >= numeric)
+      char *s;
+      Lisp_Object args[2], elt;
+
+      /* At first try exact match.  */
+      for (i = 0; i < len; i++)
+       if (EQ (val, XCAR (AREF (table, i))))
+         return (XINT (XCDR (AREF (table, i))) << 8) | i;
+      /* Try also with case-folding match.  */
+      s = SDATA (SYMBOL_NAME (val));
+      for (i = 0; i < len; i++)
        {
-         if (XINT (XCDR (XCAR (table))) == numeric)
-           return XCAR (XCAR (table));
-         else
-           break;
+         elt = XCAR (AREF (table, i));
+         if (strcasecmp (s, (char *) SDATA (SYMBOL_NAME (elt))) == 0)
+           return i;
        }
-      table = XCDR (table);
+      if (! noerror)
+       return -1;
+      if (len == 255)
+       abort ();
+      args[0] = table;
+      args[1] = Fmake_vector (make_number (1), Fcons (val, make_number (255)));
+      ASET (font_style_table, prop - FONT_WEIGHT_INDEX, Fvconcat (2, args));
+      return (255 << 8) | i;
     }
-  sprintf (buf, "%d", numeric);
-  return intern (buf);
-}
+  else
+    {
+      int last_i, i, last_n;
+      int numeric = XINT (val);
 
+      for (i = 1, last_i = last_n = -1; i < len;)
+       {
+         int n = XINT (XCDR (AREF (table, i)));
 
-/* Return a symbol whose name is STR (length LEN).  If STR contains
-   uppercase letters, downcase them in advance.  */
+         if (numeric == n)
+           return (n << 8) | i;
+         if (numeric < n)
+           {
+             if (! noerror)
+               return -1;
+             return ((last_i < 0 || n - numeric < numeric - last_n)
+                     ? (n << 8) | i : (last_n << 8 | last_i));
+           }
+         last_i = i;
+         last_n = n;
+         for (i++; i < len && n == XINT (XCDR (AREF (table, i + 1))); i++);
+       }
+      if (! noerror)
+       return -1;
+      return (last_n << 8) | last_i;
+    }
+}
 
 Lisp_Object
-intern_downcase (str, len)
-     char *str;
-     int len;
+font_style_symbolic (font, prop, for_face)
+     Lisp_Object font;
+     enum font_property_index prop;
+     int for_face;
 {
-  char *buf;
-  int i;
+  Lisp_Object val = AREF (font, prop);
+  Lisp_Object table;
+  int i, numeric;
 
-  for (i = 0; i < len; i++)
-    if (isupper (str[i]))
-      break;
-  if (i == len)
-    return Fintern (make_unibyte_string (str, len), Qnil);
-  buf = alloca (len);
-  if (! buf)
-    return Fintern (null_string, Qnil);
-  bcopy (str, buf, len);
-  for (; i < len; i++)
-    if (isascii (buf[i]))
-      buf[i] = tolower (buf[i]);
-  return Fintern (make_unibyte_string (buf, len), Qnil);
+  if (NILP (val))
+    return Qnil;
+  table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX);
+  if (! for_face)
+    return XCAR (AREF (table, XINT (val) & 0xFF));
+  numeric = XINT (val) >> 8;
+  for (i = 0; i < ASIZE (table); i++)
+    if (XINT (XCDR (AREF (table, i))) == numeric)
+      return XCAR (AREF (table, i));
+  abort ();
+  return Qnil;
 }
 
 extern Lisp_Object Vface_alternative_font_family_alist;
 
-/* Setup font_family_alist of the form:
-       ((FAMILY-SYMBOL ALIAS-SYMBOL ...) ...)
-   from Vface_alternative_font_family_alist of the form:
-       ((FAMILY-STRING ALIAS-STRING ...) ...)  */
-
-static void
-build_font_family_alist ()
-{
-  Lisp_Object alist = Vface_alternative_font_family_alist;
-
-  for (; CONSP (alist); alist = XCDR (alist))
-    {
-      Lisp_Object tail, elt;
-
-      for (tail = XCAR (alist), elt = Qnil ; CONSP (tail); tail = XCDR (tail))
-       elt = nconc2 (elt, Fcons (Fintern (XCAR (tail), Qnil), Qnil));
-      font_family_alist = Fcons (elt, font_family_alist);
-    }
-}
-
 extern Lisp_Object find_font_encoding P_ ((Lisp_Object));
 
+EXFUN (Fassoc_string, 3);
+
 /* Return encoding charset and repertory charset for REGISTRY in
    ENCODING and REPERTORY correspondingly.  If correct information for
    REGISTRY is available, return 0.  Otherwise return -1.  */
@@ -298,7 +344,7 @@ font_registry_charsets (registry, encoding, repertory)
   Lisp_Object val;
   int encoding_id, repertory_id;
 
-  val = assq_no_quit (registry, font_charset_alist);
+  val = Fassoc_string (registry, font_charset_alist, Qt);
   if (! NILP (val))
     {
       val = XCDR (val);
@@ -351,54 +397,56 @@ font_registry_charsets (registry, encoding, repertory)
 /* Font property value validaters.  See the comment of
    font_property_table for the meaning of the arguments.  */
 
+static Lisp_Object font_prop_validate P_ ((int, Lisp_Object, Lisp_Object));
 static Lisp_Object font_prop_validate_symbol P_ ((Lisp_Object, Lisp_Object));
 static Lisp_Object font_prop_validate_style P_ ((Lisp_Object, Lisp_Object));
 static Lisp_Object font_prop_validate_non_neg P_ ((Lisp_Object, Lisp_Object));
 static Lisp_Object font_prop_validate_spacing P_ ((Lisp_Object, Lisp_Object));
-static int get_font_prop_index P_ ((Lisp_Object, int));
-static Lisp_Object font_prop_validate P_ ((Lisp_Object));
+static int get_font_prop_index P_ ((Lisp_Object));
 
 static Lisp_Object
 font_prop_validate_symbol (prop, val)
      Lisp_Object prop, val;
 {
-  if (EQ (prop, QCotf))
-    return (SYMBOLP (val) ? val : Qerror);
   if (STRINGP (val))
-    val = (SCHARS (val) == 0 ? null_string
-          : intern_downcase ((char *) SDATA (val), SBYTES (val)));
-  else if (SYMBOLP (val))
-    {
-      if (SCHARS (SYMBOL_NAME (val)) == 0)
-       val = null_string;
-    }
-  else
+    val = Fintern (val, Qnil);
+  if (! SYMBOLP (val))
     val = Qerror;
+  else if (EQ (prop, QCregistry))
+    val = Fintern (Fdowncase (SYMBOL_NAME (val)), Qnil);
   return val;
 }
 
+
 static Lisp_Object
-font_prop_validate_style (prop, val)
-     Lisp_Object prop, val;
+font_prop_validate_style (style, val)
+     Lisp_Object style, val;
 {
-  if (! INTEGERP (val))
+  enum font_property_index prop = (EQ (style, QCweight) ? FONT_WEIGHT_INDEX
+                                  : EQ (style, QCslant) ? FONT_SLANT_INDEX
+                                  : FONT_WIDTH_INDEX);
+  int n;
+  if (INTEGERP (val))
     {
-      if (STRINGP (val))
-       val = intern_downcase ((char *) SDATA (val), SBYTES (val));
-      if (! SYMBOLP (val))
+      n = XINT (val);
+      if ((n & 0xFF)
+         >= ASIZE (AREF (font_style_table, prop - FONT_WEIGHT_INDEX)))
        val = Qerror;
       else
        {
-         enum font_property_index prop_index
-           = (EQ (prop, QCweight) ? FONT_WEIGHT_INDEX
-              : EQ (prop, QCslant) ? FONT_SLANT_INDEX
-              : FONT_WIDTH_INDEX);
-
-         val = prop_name_to_numeric (prop_index, val);
-         if (NILP (val))
+         Lisp_Object elt = AREF (AREF (font_style_table, prop - FONT_WEIGHT_INDEX), n & 0xFF);
+         if (XINT (XCDR (elt)) != (n >> 8))
            val = Qerror;
        }
     }
+  else if (SYMBOLP (val))
+    {
+      int n = font_style_to_value (prop, val, 0);
+
+      val = n >= 0 ? make_number (val) : Qerror;
+    }
+  else
+    val = Qerror;
   return val;
 }
 
@@ -422,6 +470,8 @@ font_prop_validate_spacing (prop, val)
     return make_number (FONT_SPACING_MONO);
   if (EQ (val, Qp))
     return make_number (FONT_SPACING_PROPORTIONAL);
+  if (EQ (val, Qd))
+    return make_number (FONT_SPACING_DUAL);
   return Qerror;
 }
 
@@ -480,13 +530,14 @@ struct
     { &QCslant, font_prop_validate_style },
     { &QCwidth, font_prop_validate_style },
     { &QCsize, font_prop_validate_non_neg },
-    { &QClanguage, font_prop_validate_symbol },
-    { &QCscript, font_prop_validate_symbol },
     { &QCdpi, font_prop_validate_non_neg },
     { &QCspacing, font_prop_validate_spacing },
-    { &QCscalable, NULL },
-    { &QCotf, font_prop_validate_otf },
-    { &QCantialias, font_prop_validate_symbol }
+    { &QCavgwidth, font_prop_validate_non_neg },
+    /* The order of the above entries must match with enum
+       font_property_index.  */
+    { &QClang, font_prop_validate_symbol },
+    { &QCscript, font_prop_validate_symbol },
+    { &QCotf, font_prop_validate_otf }
   };
 
 /* Size (number of elements) of the above table.  */
@@ -494,64 +545,48 @@ struct
   ((sizeof font_property_table) / (sizeof *font_property_table))
 
 /* Return an index number of font property KEY or -1 if KEY is not an
-   already known property.  Start searching font_property_table from
-   index FROM (which is 0 or FONT_EXTRA_INDEX).  */
+   already known property.  */
 
 static int
-get_font_prop_index (key, from)
+get_font_prop_index (key)
      Lisp_Object key;
-     int from;
 {
-  for (; from < FONT_PROPERTY_TABLE_SIZE; from++)
-    if (EQ (key, *font_property_table[from].key))
-      return from;
+  int i;
+
+  for (i = 0; i < FONT_PROPERTY_TABLE_SIZE; i++)
+    if (EQ (key, *font_property_table[i].key))
+      return i;
   return -1;
 }
 
-/* Validate font properties in SPEC (vector) while updating elements
-   to regularized values.  Signal an error if an invalid property is
-   found. */
+/* Validate the font property.  The property key is specified by the
+   symbol PROP, or the index IDX (if PROP is nil).  If VAL is invalid,
+   signal an error.  The value is VAL or the regularized one.  */
 
-static Lisp_Object
-font_prop_validate (spec)
-     Lisp_Object spec;
+Lisp_Object
+font_prop_validate (idx, prop, val)
+     int idx;
+     Lisp_Object prop, val;
 {
-  int i;
-  Lisp_Object prop, val, extra;
+  Lisp_Object validated;
 
-  for (i = FONT_TYPE_INDEX; i < FONT_EXTRA_INDEX; i++)
-    {
-      if (! NILP (AREF (spec, i)))
-       {
-         prop = *font_property_table[i].key;
-         val = (font_property_table[i].validater) (prop, AREF (spec, i));
-         if (EQ (val, Qerror))
-           Fsignal (Qfont, list2 (build_string ("invalid font property"),
-                                  Fcons (prop, AREF (spec, i))));
-         ASET (spec, i, val);
-       }
-    }
-  for (extra = AREF (spec, FONT_EXTRA_INDEX);
-       CONSP (extra); extra = XCDR (extra))
+  if (NILP (prop))
+    prop = *font_property_table[idx].key;
+  else
     {
-      Lisp_Object elt = XCAR (extra);
-
-      prop = XCAR (elt);
-      i = get_font_prop_index (prop, FONT_EXTRA_INDEX);
-      if (i >= 0
-         && font_property_table[i].validater)
-       {
-         val = (font_property_table[i].validater) (prop, XCDR (elt));
-         if (EQ (val, Qerror))
-           Fsignal (Qfont, list2 (build_string ("invalid font property"),
-                                  elt));
-         XSETCDR (elt, val);
-       }
+      idx = get_font_prop_index (prop);
+      if (idx < 0)
+       return val;
     }
-  return spec;
+  validated = (font_property_table[idx].validater) (prop, val);
+  if (EQ (validated, Qerror))
+    signal_error ("invalid font property", Fcons (prop, val));
+  return validated;
 }
 
-/* Store VAL as a value of extra font property PROP in FONT.  */
+
+/* Store VAL as a value of extra font property PROP in FONT while
+   keeping the sorting order.  Don't check the validity of VAL.  */
 
 Lisp_Object
 font_put_extra (font, prop, val)
@@ -562,8 +597,15 @@ font_put_extra (font, prop, val)
 
   if (NILP (slot))
     {
-      extra = Fcons (Fcons (prop, val), extra);
-      ASET (font, FONT_EXTRA_INDEX, extra);
+      Lisp_Object prev = Qnil;
+
+      while (CONSP (extra)
+            && NILP (Fstring_lessp (prop, XCAR (XCAR (extra)))))
+       prev = extra, extra = XCDR (extra);
+      if (NILP (prev))
+       ASET (font, FONT_EXTRA_INDEX, Fcons (Fcons (prop, val), extra));
+      else
+       XSETCDR (prev, Fcons (Fcons (prop, val), extra));
       return val;
     }
   XSETCDR (slot, val);
@@ -573,7 +615,6 @@ font_put_extra (font, prop, val)
 \f
 /* Font name parser and unparser */
 
-static Lisp_Object intern_font_field P_ ((char *, int));
 static int parse_matrix P_ ((char *));
 static int font_expand_wildcards P_ ((Lisp_Object *, int));
 static int font_parse_name P_ ((char *, Lisp_Object));
@@ -618,34 +659,6 @@ enum xlfd_field_mask
 };
 
 
-/* Return a Lispy value of a XLFD font field at STR and LEN bytes.
-   If LEN is zero, it returns `null_string'.
-   If STR is "*", it returns nil.
-   If all characters in STR are digits, it returns an integer.
-   Otherwise, it returns a symbol interned from downcased STR.  */
-
-static Lisp_Object
-intern_font_field (str, len)
-     char *str;
-     int len;
-{
-  int i;
-
-  if (len == 0)
-    return null_string;
-  if (*str == '*' && len == 1)
-    return Qnil;
-  if (isdigit (*str))
-    {
-      for (i = 1; i < len; i++)
-       if (! isdigit (str[i]))
-         break;
-      if (i == len)
-       return make_number (atoi (str));
-    }
-  return intern_downcase (str, len);
-}
-
 /* Parse P pointing the pixel/point size field of the form
    `[A B C D]' which specifies a transformation matrix:
 
@@ -756,7 +769,7 @@ font_expand_wildcards (field, n)
                from = XLFD_POINT_INDEX, to = XLFD_AVGWIDTH_INDEX,
                  mask = XLFD_LARGENUM_MASK;
            }
-         else if (EQ (val, null_string))
+         else if (SBYTES (SYMBOL_NAME (val)) == 0)
            from = XLFD_FOUNDRY_INDEX, to = XLFD_ADSTYLE_INDEX,
              mask = XLFD_NULL_MASK;
          else if (i == 0)
@@ -774,15 +787,15 @@ font_expand_wildcards (field, n)
            }
          else if (range_from <= XLFD_WEIGHT_INDEX
                   && range_to >= XLFD_WEIGHT_INDEX
-                  && !NILP (prop_name_to_numeric (FONT_WEIGHT_INDEX, val)))
+                  && FONT_WEIGHT_NAME_NUMERIC (val) >= 0)
            from = to = XLFD_WEIGHT_INDEX, mask = XLFD_WEIGHT_MASK;
          else if (range_from <= XLFD_SLANT_INDEX
                   && range_to >= XLFD_SLANT_INDEX
-                  && !NILP (prop_name_to_numeric (FONT_SLANT_INDEX, val)))
+                  && FONT_SLANT_NAME_NUMERIC (val) >= 0)
            from = to = XLFD_SLANT_INDEX, mask = XLFD_SLANT_MASK;
          else if (range_from <= XLFD_SWIDTH_INDEX
                   && range_to >= XLFD_SWIDTH_INDEX
-                  && !NILP (prop_name_to_numeric (FONT_WIDTH_INDEX, val)))
+                  && FONT_WIDTH_NAME_NUMERIC (val) >= 0)
            from = to = XLFD_SWIDTH_INDEX, mask = XLFD_SWIDTH_MASK;
          else
            {
@@ -903,6 +916,7 @@ font_check_xlfd_parse (Lisp_Object font, char *name)
 
 #endif
 
+
 /* Parse NAME (null terminated) as XLFD and store information in FONT
    (font-spec or font-entity).  Size property of FONT is set as
    follows:
@@ -916,9 +930,7 @@ font_check_xlfd_parse (Lisp_Object font, char *name)
 
    FONT is usually a font-spec, but when this function is called from
    X font backend driver, it is a font-entity.  In that case, NAME is
-   a fully specified XLFD, and we set FONT_EXTRA_INDEX of FONT to a
-   symbol RESX-RESY-SPACING-AVGWIDTH.
-*/
+   a fully specified XLFD.  */
 
 int
 font_parse_xlfd (name, font)
@@ -926,9 +938,7 @@ font_parse_xlfd (name, font)
      Lisp_Object font;
 {
   int len = strlen (name);
-  int i, j;
-  Lisp_Object dpi, spacing;
-  int avgwidth;
+  int i, j, n;
   char *f[XLFD_LAST_INDEX + 1];
   Lisp_Object val;
   char *p;
@@ -942,52 +952,49 @@ font_parse_xlfd (name, font)
   else
     i = 0;
   for (p = name + i; *p; p++)
-    if (*p == '-' && i < XLFD_LAST_INDEX)
-      f[i++] = p + 1;
-  f[i] = p;
+    if (*p == '-')
+      {
+       f[i++] = p + 1;
+       if (i == XLFD_LAST_INDEX)
+         break;
+      }
+  f[i] = name + len;
 
-  dpi = spacing = Qnil;
-  avgwidth = -1;
+#define INTERN_FIELD(N) font_intern_prop (f[N], f[(N) + 1] - 1 - f[N])
 
   if (i == XLFD_LAST_INDEX)
     {
+      /* Fully specified XLFD.  */
       int pixel_size;
+      int spacing_char;
 
-      /* Fully specified XLFD.  */
-      for (i = 0, j = FONT_FOUNDRY_INDEX; i < XLFD_WEIGHT_INDEX; i++, j++)
-       {
-         val = intern_font_field (f[i], f[i + 1] - 1 - f[i]);
-         if (! NILP (val))
-           ASET (font, j, val);
-       }
-      for (j = FONT_WEIGHT_INDEX; i < XLFD_ADSTYLE_INDEX; i++, j++)
+      ASET (font, FONT_FOUNDRY_INDEX, INTERN_FIELD (XLFD_FOUNDRY_INDEX));
+      ASET (font, FONT_FAMILY_INDEX, INTERN_FIELD (XLFD_FAMILY_INDEX));
+      for (i = XLFD_WEIGHT_INDEX, j = FONT_WEIGHT_INDEX;
+          i <= XLFD_SWIDTH_INDEX; i++, j++)
        {
-         val = intern_font_field (f[i], f[i + 1] - 1 - f[i]);
+         val = INTERN_FIELD (i);
          if (! NILP (val))
            {
-             Lisp_Object numeric = prop_name_to_numeric (j, val);
-
-             if (INTEGERP (numeric))
-               val = numeric;
-             ASET (font, j, val);
+             if ((n = font_style_to_value (j, INTERN_FIELD (i), 0)) < 0)
+               return -1;
+             ASET (font, j, make_number (n));
            }
        }
-      val = intern_font_field (f[i], f[i + 1] - 1 - f[i]);
-      if (! NILP (val))
-       ASET (font, FONT_ADSTYLE_INDEX, val);
-      i = XLFD_REGISTRY_INDEX;
-      val = intern_font_field (f[i], f[i + 2] - f[i]);
-      if (! NILP (val))
-       ASET (font, FONT_REGISTRY_INDEX, val);
-
+      ASET (font, FONT_ADSTYLE_INDEX, INTERN_FIELD (XLFD_ADSTYLE_INDEX));
+      if (strcmp (f[XLFD_REGISTRY_INDEX], "*-*") == 0)
+       ASET (font, FONT_REGISTRY_INDEX, Qnil);
+      else
+       ASET (font, FONT_REGISTRY_INDEX,
+             font_intern_prop (f[XLFD_REGISTRY_INDEX],
+                               f[XLFD_LAST_INDEX] - f[XLFD_REGISTRY_INDEX]));
       p = f[XLFD_PIXEL_INDEX];
       if (*p == '[' && (pixel_size = parse_matrix (p)) >= 0)
        ASET (font, FONT_SIZE_INDEX, make_number (pixel_size));
       else
        {
-         i = XLFD_PIXEL_INDEX;
-         val = intern_font_field (f[i], f[i + 1] - 1 - f[i]);
-         if (! NILP (val))
+         val = INTERN_FIELD (XLFD_PIXEL_INDEX);
+         if (INTEGERP (val))
            ASET (font, FONT_SIZE_INDEX, val);
          else
            {
@@ -1001,43 +1008,31 @@ font_parse_xlfd (name, font)
                point_size = atoi (p), point_size /= 10;
              if (point_size >= 0)
                ASET (font, FONT_SIZE_INDEX, make_float (point_size));
-             else
-               {
-                 i = XLFD_PIXEL_INDEX;
-                 val = intern_font_field (f[i], f[i + 1] - 1 - f[i]);
-                 if (! NILP (val))
-                   ASET (font, FONT_SIZE_INDEX, val);
-               }
            }
        }
 
-      /* Parse RESX, RESY, SPACING, and AVGWIDTH.  */
-      if (FONT_ENTITY_P (font))
+      ASET (font, FONT_DPI_INDEX, INTERN_FIELD (XLFD_RESY_INDEX));
+      val = INTERN_FIELD (XLFD_SPACING_INDEX);
+      if (! NILP (val))
        {
-         i = XLFD_RESX_INDEX;
-         ASET (font, FONT_EXTRA_INDEX,
-               intern_font_field (f[i], f[XLFD_REGISTRY_INDEX] - 1 - f[i]));
-         eassert (font_check_xlfd_parse (font, name));
-         return 0;
+         val = font_prop_validate_spacing (FONT_SPACING_INDEX, val);
+         if (! INTEGERP (val))
+           return -1;
+         ASET (font, FONT_SPACING_INDEX, val);
        }
-
-      /* Here we just setup DPI, SPACING, and AVGWIDTH.  They are set
-        in FONT_EXTRA_INDEX later.  */
-      i = XLFD_RESX_INDEX;
-      dpi = intern_font_field (f[i], f[i + 1] - 1 - f[i]);
-      i = XLFD_SPACING_INDEX;
-      spacing = intern_font_field (f[i], f[i + 1] - 1 - f[i]);
       p = f[XLFD_AVGWIDTH_INDEX];
       if (*p == '~')
        p++;
-      if (isdigit (*p))
-       avgwidth = atoi (p);
+      ASET (font, FONT_AVGWIDTH_INDEX,
+           font_intern_prop (p, f[XLFD_REGISTRY_INDEX] - 1 - p));
     }
   else
     {
       int wild_card_found = 0;
       Lisp_Object prop[XLFD_LAST_INDEX];
 
+      if (FONT_ENTITY_P (font))
+       return -1;
       for (j = 0; j < i; j++)
        {
          if (*f[j] == '*')
@@ -1047,49 +1042,41 @@ font_parse_xlfd (name, font)
              prop[j] = Qnil;
              wild_card_found = 1;
            }
-         else if (isdigit (*f[j]))
-           {
-             for (p = f[j] + 1; isdigit (*p); p++);
-             if (*p && *p != '-')
-               prop[j] = intern_downcase (f[j], p - f[j]);
-             else
-               prop[j] = make_number (atoi (f[j]));
-           }
          else if (j + 1 < i)
-           prop[j] = intern_font_field (f[j], f[j + 1] - 1 - f[j]);
+           prop[j] = INTERN_FIELD (j);
          else
-           prop[j] = intern_font_field (f[j], f[i] - f[j]);
+           prop[j] = font_intern_prop (f[j], f[i] - f[j]);
        }
       if (! wild_card_found)
        return -1;
       if (font_expand_wildcards (prop, i) < 0)
        return -1;
 
-      for (i = 0, j = FONT_FOUNDRY_INDEX; i < XLFD_WEIGHT_INDEX; i++, j++)
-       if (! NILP (prop[i]))
-         ASET (font, j, prop[i]);
-      for (j = FONT_WEIGHT_INDEX; i < XLFD_ADSTYLE_INDEX; i++, j++)
+      ASET (font, FONT_FOUNDRY_INDEX, prop[XLFD_FOUNDRY_INDEX]);
+      ASET (font, FONT_FAMILY_INDEX, prop[XLFD_FAMILY_INDEX]);
+      for (i = XLFD_WEIGHT_INDEX, j = FONT_WEIGHT_INDEX;
+          i <= XLFD_SWIDTH_INDEX; i++, j++)
        if (! NILP (prop[i]))
-         ASET (font, j, prop[i]);
-      if (! NILP (prop[XLFD_ADSTYLE_INDEX]))
-       ASET (font, FONT_ADSTYLE_INDEX, prop[XLFD_ADSTYLE_INDEX]);
+         {
+           if ((n = font_style_to_value (j, prop[i], 1)) < 0)
+             return -1;
+           ASET (font, j, make_number (n));
+         }
+      ASET (font, FONT_ADSTYLE_INDEX, prop[XLFD_ADSTYLE_INDEX]);
       val = prop[XLFD_REGISTRY_INDEX];
       if (NILP (val))
        {
          val = prop[XLFD_ENCODING_INDEX];
          if (! NILP (val))
-           val = Fintern (concat2 (build_string ("*-"), SYMBOL_NAME (val)),
-                          Qnil);
+           val = concat2 (build_string ("*-"), SYMBOL_NAME (val));
        }
       else if (NILP (prop[XLFD_ENCODING_INDEX]))
-       val = Fintern (concat2 (SYMBOL_NAME (val), build_string ("-*")),
-                      Qnil);
+       val = concat2 (SYMBOL_NAME (val), build_string ("-*"));
       else
-       val = Fintern (concat3 (SYMBOL_NAME (val), build_string ("-"),
-                               SYMBOL_NAME (prop[XLFD_ENCODING_INDEX])),
-                      Qnil);
+       val = concat3 (SYMBOL_NAME (val), build_string ("-"),
+                      SYMBOL_NAME (prop[XLFD_ENCODING_INDEX]));
       if (! NILP (val))
-       ASET (font, FONT_REGISTRY_INDEX, val);
+       ASET (font, FONT_REGISTRY_INDEX, Fintern (val, Qnil));
 
       if (INTEGERP (prop[XLFD_PIXEL_INDEX]))
        ASET (font, FONT_SIZE_INDEX, prop[XLFD_PIXEL_INDEX]);
@@ -1100,19 +1087,20 @@ font_parse_xlfd (name, font)
          ASET (font, FONT_SIZE_INDEX, make_float (point_size / 10));
        }
 
-      dpi = prop[XLFD_RESX_INDEX];
-      spacing = prop[XLFD_SPACING_INDEX];
+      if (INTEGERP (prop[XLFD_RESX_INDEX]))
+       ASET (font, FONT_DPI_INDEX, prop[XLFD_RESY_INDEX]);
+      if (! NILP (prop[XLFD_SPACING_INDEX]))
+       {
+         val = font_prop_validate_spacing (FONT_SPACING_INDEX,
+                                           prop[XLFD_SPACING_INDEX]);
+         if (! INTEGERP (val))
+           return -1;
+         ASET (font, FONT_SPACING_INDEX, val);
+       }
       if (INTEGERP (prop[XLFD_AVGWIDTH_INDEX]))
-       avgwidth = XINT (prop[XLFD_AVGWIDTH_INDEX]);
+       ASET (font, FONT_AVGWIDTH_INDEX, prop[XLFD_AVGWIDTH_INDEX]);
     }
 
-  if (! NILP (dpi))
-    font_put_extra (font, QCdpi, dpi);
-  if (! NILP (spacing))
-    font_put_extra (font, QCspacing, spacing);
-  if (avgwidth >= 0)
-    font_put_extra (font, QCscalable, avgwidth == 0 ? Qt : Qnil);
-
   return 0;
 }
 
@@ -1177,16 +1165,12 @@ font_unparse_xlfd (font, pixel_size, name, nbytes)
   for (i = FONT_WEIGHT_INDEX, j = XLFD_WEIGHT_INDEX; i <= FONT_WIDTH_INDEX;
        i++, j++)
     {
-      val = AREF (font, i);
+      val = font_style_symbolic (font, i, 0);
       if (NILP (val))
        f[j] = "*", len += 2;
       else
        {
-         if (INTEGERP (val))
-           val = prop_numeric_to_name (i, XINT (val));
-         if (SYMBOLP (val))
-           val = SYMBOL_NAME (val);
-         xassert (STRINGP (val));
+         val = SYMBOL_NAME (val);
          f[j] = (char *) SDATA (val), len += SBYTES (val) + 1;
        }
     }
@@ -1195,7 +1179,7 @@ font_unparse_xlfd (font, pixel_size, name, nbytes)
   xassert (NUMBERP (val) || NILP (val));
   if (INTEGERP (val))
     {
-      int i = XINT (val);
+      i = XINT (val);
       if (i <= 0)
        i = pixel_size;
       if (i > 0)
@@ -1208,81 +1192,52 @@ font_unparse_xlfd (font, pixel_size, name, nbytes)
     }
   else if (FLOATP (val))
     {
-      int i = XFLOAT_DATA (val) * 10;
+      i = XFLOAT_DATA (val) * 10;
       f[XLFD_PIXEL_INDEX] = alloca (12);
       len += sprintf (f[XLFD_PIXEL_INDEX], "*-%d", i) + 1;
     }
   else
     f[XLFD_PIXEL_INDEX] = "*-*", len += 4;
 
-  val = AREF (font, FONT_EXTRA_INDEX);
-
-  if (FONT_ENTITY_P (font)
-      && EQ (AREF (font, FONT_TYPE_INDEX), Qx))
+  if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
     {
-      /* Setup names for RESX-RESY-SPACING-AVWIDTH.  */
-      if (SYMBOLP (val) && ! NILP (val))
-       {
-         val = SYMBOL_NAME (val);
-         f[XLFD_RESX_INDEX] = (char *) SDATA (val), len += SBYTES (val) + 1;
-       }
-      else
-       f[XLFD_RESX_INDEX] = "*-*-*-*", len += 6;
+      i = XINT (AREF (font, FONT_DPI_INDEX));
+      f[XLFD_RESX_INDEX] = alloca (22);
+      len += sprintf (f[XLFD_RESX_INDEX],
+                     "%d-%d", i, i) + 1;
     }
   else
+    f[XLFD_RESX_INDEX] = "*-*", len += 4;
+  if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
     {
-      Lisp_Object dpi = assq_no_quit (QCdpi, val);
-      Lisp_Object spacing = assq_no_quit (QCspacing, val);
-      Lisp_Object scalable = assq_no_quit (QCscalable, val);
+      int spacing = XINT (AREF (font, FONT_SPACING_INDEX));
 
-      if (CONSP (dpi) || CONSP (spacing) || CONSP (scalable))
-       {
-         char *str = alloca (24);
-         int this_len;
-
-         if (CONSP (dpi) && INTEGERP (XCDR (dpi)))
-           this_len = sprintf (str, "%d-%d",
-                               XINT (XCDR (dpi)), XINT (XCDR (dpi)));
-         else
-           this_len = sprintf (str, "*-*");
-         if (CONSP (spacing) && ! NILP (XCDR (spacing)))
-           {
-             val = XCDR (spacing);
-             if (INTEGERP (val))
-               {
-                 if (XINT (val) < FONT_SPACING_MONO)
-                   val = Qp;
-                 else if (XINT (val) < FONT_SPACING_CHARCELL)
-                   val = Qm;
-                 else
-                   val = Qc;
-               }
-             xassert (SYMBOLP (val));
-             this_len += sprintf (str + this_len, "-%c",
-                                  SDATA (SYMBOL_NAME (val))[0]);
-           }
-         else
-           this_len += sprintf (str + this_len, "-*");
-         if (CONSP (scalable) && ! NILP (XCDR (spacing)))
-           this_len += sprintf (str + this_len, "-0");
-         else
-           this_len += sprintf (str + this_len, "-*");
-         f[XLFD_RESX_INDEX] = str;
-         len += this_len;
-       }
-      else
-       f[XLFD_RESX_INDEX] = "*-*-*-*", len += 8;
+      f[XLFD_SPACING_INDEX] = (spacing <= FONT_SPACING_PROPORTIONAL ? "p"
+                              : spacing <= FONT_SPACING_DUAL ? "d"
+                              : spacing <= FONT_SPACING_MONO ? "m"
+                              : "c");
+      len += 2;
     }
-
+  else
+    f[XLFD_SPACING_INDEX] = "*", len += 2;
+  if (INTEGERP (AREF (font,  FONT_AVGWIDTH_INDEX)))
+    {
+      f[XLFD_AVGWIDTH_INDEX] = alloca (11);
+      len += sprintf (f[XLFD_AVGWIDTH_INDEX],
+                     "%d", XINT (AREF (font, FONT_AVGWIDTH_INDEX))) + 1;
+    }
+  else
+    f[XLFD_AVGWIDTH_INDEX] = "*", len += 2;
   len++;       /* for terminating '\0'.  */
   if (len >= nbytes)
     return -1;
-  return sprintf (name, "-%s-%s-%s-%s-%s-%s-%s-%s-%s",
+  return sprintf (name, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
                  f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX],
                  f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX],
-                 f[XLFD_SWIDTH_INDEX],
-                 f[XLFD_ADSTYLE_INDEX], f[XLFD_PIXEL_INDEX],
-                 f[XLFD_RESX_INDEX], f[XLFD_REGISTRY_INDEX]);
+                 f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX],
+                 f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX],
+                 f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX],
+                 f[XLFD_REGISTRY_INDEX]);
 }
 
 /* Parse NAME (null terminated) as Fonconfig's name format and store
@@ -1297,8 +1252,6 @@ font_parse_fcname (name, font)
   char *p0, *p1;
   int len = strlen (name);
   char *copy;
-  int weight_set = 0;
-  int slant_set = 0;
 
   if (len == 0)
     return -1;
@@ -1313,7 +1266,7 @@ font_parse_fcname (name, font)
       for (p0 = name + 1; *p0 && (*p0 != '-' && *p0 != ':'); p0++)
        if (*p0 == '\\' && p0[1])
          p0++;
-      family = intern_font_field (name, p0 - name);
+      family = font_intern_prop (name, p0 - name);
       if (*p0 == '-')
        {
          if (! isdigit (p0[1]))
@@ -1334,7 +1287,8 @@ font_parse_fcname (name, font)
   name = copy;
 
   /* Now parse ":KEY=VAL" patterns.  Store known keys and values in
-     extra, copy unknown ones to COPY.  */
+     extra, copy unknown ones to COPY.  It is stored in extra slot by
+     the key QCfc_unknown_spec.  */
   while (*p0)
     {
       Lisp_Object key, val;
@@ -1344,30 +1298,26 @@ font_parse_fcname (name, font)
       if (*p1 != '=')
        {
          /* Must be an enumerated value.  */
-         val = intern_font_field (p0 + 1, p1 - p0 - 1);
+         val = font_intern_prop (p0 + 1, p1 - p0 - 1);
          if (memcmp (p0 + 1, "light", 5) == 0
              || memcmp (p0 + 1, "medium", 6) == 0
              || memcmp (p0 + 1, "demibold", 8) == 0
              || memcmp (p0 + 1, "bold", 4) == 0
              || memcmp (p0 + 1, "black", 5) == 0)
-           {
-             ASET (font, FONT_WEIGHT_INDEX, val);
-              weight_set = 1;
-           }
+           FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, val);
          else if (memcmp (p0 + 1, "roman", 5) == 0
                   || memcmp (p0 + 1, "italic", 6) == 0
                   || memcmp (p0 + 1, "oblique", 7) == 0)
-           {
-             ASET (font, FONT_SLANT_INDEX, val);
-              slant_set = 1;
-           }
+           FONT_SET_STYLE (font, FONT_SLANT_INDEX, val);
          else if (memcmp (p0 + 1, "charcell", 8) == 0
                   || memcmp (p0 + 1, "mono", 4) == 0
                   || memcmp (p0 + 1, "proportional", 12) == 0)
            {
-             font_put_extra (font, QCspacing,
-                             (p0[1] == 'c' ? Qc : p0[1] == 'm' ? Qm : Qp));
-           }
+             int spacing = (p0[1] == 'c' ? FONT_SPACING_CHARCELL
+                            : p0[1] == 'm' ? FONT_SPACING_MONO
+                            : FONT_SPACING_PROPORTIONAL);
+             ASET (font, FONT_SPACING_INDEX, make_number (spacing));
+           }             
          else
            {
              /* unknown key */
@@ -1381,34 +1331,28 @@ font_parse_fcname (name, font)
            prop = FONT_SIZE_INDEX;
          else
            {
-             key = intern_font_field (p0, p1 - p0);
-             prop = get_font_prop_index (key, 0);
+             key = font_intern_prop (p0, p1 - p0);
+             prop = get_font_prop_index (key);
            }
          p0 = p1 + 1;
          for (p1 = p0; *p1 && *p1 != ':'; p1++);
-         val = intern_font_field (p0, p1 - p0);
+         val = font_intern_prop (p0, p1 - p0);
          if (! NILP (val))
            {
-             if (prop >= 0 && prop < FONT_EXTRA_INDEX)
-               {
-                  if (prop == FONT_WEIGHT_INDEX)
-                    weight_set = 1;
-                  else if (prop == FONT_SLANT_INDEX)
-                    slant_set = 1;
-
-                 ASET (font, prop, val);
-               }
+             if (prop >= FONT_FOUNDRY_INDEX && prop < FONT_EXTRA_INDEX)
+               ASET (font, prop, font_prop_validate (prop, Qnil, val));
+             else if (prop >= 0)
+               Ffont_put (font, key, val);
              else
-               font_put_extra (font, key, val);
+               bcopy (p0 - 1, copy, p1 - p0 + 1);
+             copy += p1 - p0 + 1;
            }
        }
       p0 = p1;
     }
-
-  if (!weight_set)
-    ASET (font, FONT_WEIGHT_INDEX, build_string ("normal"));
-  if (!slant_set)
-    ASET (font, FONT_SLANT_INDEX, build_string ("normal"));
+  if (name != copy)
+    font_put_extra (font, QCfc_unknown_spec,
+                   make_unibyte_string (name, copy - name));
 
   return 0;
 }
@@ -1424,17 +1368,18 @@ font_unparse_fcname (font, pixel_size, name, nbytes)
      char *name;
      int nbytes;
 {
-  Lisp_Object val;
+  Lisp_Object tail, val;
   int point_size;
-  int dpi, spacing, scalable;
+  int dpi, spacing, avgwidth;
   int i, len = 1;
   char *p;
   Lisp_Object styles[3];
   char *style_names[3] = { "weight", "slant", "width" };
+  char work[256];
 
   val = AREF (font, FONT_FAMILY_INDEX);
-  if (SYMBOLP (val) && ! NILP (val))
-    len += SBYTES (SYMBOL_NAME (val));
+  if (STRINGP (val))
+    len += SBYTES (val);
 
   val = AREF (font, FONT_SIZE_INDEX);
   if (INTEGERP (val))
@@ -1452,64 +1397,44 @@ font_unparse_fcname (font, pixel_size, name, nbytes)
     }
 
   val = AREF (font, FONT_FOUNDRY_INDEX);
-  if (SYMBOLP (val) && ! NILP (val))
+  if (STRINGP (val))
     /* ":foundry=NAME" */
-    len += 9 + SBYTES (SYMBOL_NAME (val));
+    len += 9 + SBYTES (val);
 
-  for (i = FONT_WEIGHT_INDEX; i <= FONT_WIDTH_INDEX; i++)
+  for (i = 0; i < 3; i++)
     {
-      val = AREF (font, i);
-      if (INTEGERP (val))
-       {
-         val = prop_numeric_to_name (i, XINT (val));
-       }
-      if (SYMBOLP (val) && ! NILP (val))
-        len += (strlen (style_names[i - FONT_WEIGHT_INDEX])
-                + 2 + SBYTES (SYMBOL_NAME (val))); /* :xxx=NAME */
-      styles[i - FONT_WEIGHT_INDEX] = val;
-    }
+      int this_len;
 
-  val = AREF (font, FONT_EXTRA_INDEX);
-  if (FONT_ENTITY_P (font)
-      && EQ (AREF (font, FONT_TYPE_INDEX), Qx))
-    {
-      char *p;
-
-      /* VAL is a symbol of name `RESX-RESY-SPACING-AVWIDTH'.  */
-      p = (char *) SDATA (SYMBOL_NAME (val));
-      dpi = atoi (p);
-      for (p++; *p != '-'; p++);       /* skip RESX */
-      for (p++; *p != '-'; p++);       /* skip RESY */
-      spacing = (*p == 'c' ? FONT_SPACING_CHARCELL
-                : *p == 'm' ? FONT_SPACING_MONO
-                : FONT_SPACING_PROPORTIONAL);
-      for (p++; *p != '-'; p++);       /* skip SPACING */
-      scalable = (atoi (p) == 0);
-      /* The longest pattern is ":dpi=NUM:scalable=False:spacing=100" */
-      len += 42;
+      styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
+      if (! NILP (styles[i]))
+       len += sprintf (work, ":%s=%s", style_names[i],
+                       SDATA (SYMBOL_NAME (styles[i])));
     }
-  else
+
+  if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
+    len += sprintf (work, ":dpi=%d", dpi);
+  if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
+    len += strlen (":spacing=100");
+  if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
+    len += strlen (":scalable=false"); /* or ":scalable=true" */
+  for (tail = AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
     {
-      Lisp_Object elt;
-
-      dpi = spacing = scalable = -1;
-      elt = assq_no_quit (QCdpi, val);
-      if (CONSP (elt))
-       dpi = XINT (XCDR (elt)), len += 15; /* for ":dpi=NUM" */
-      elt = assq_no_quit (QCspacing, val);
-      if (CONSP (elt))
-       spacing = XINT (XCDR (elt)), len += 12; /* for ":spacing=100" */
-      elt = assq_no_quit (QCscalable, val);
-      if (CONSP (elt))
-       scalable = ! NILP (XCDR (elt)), len += 15; /* for ":scalable=False" */
+      Lisp_Object key = XCAR (XCAR (tail)), val = XCDR (XCAR (tail));
+
+      len += SBYTES (SYMBOL_NAME (key)) + 1; /* for :KEY= */
+      if (STRINGP (val))
+       len += SBYTES (val);
+      else if (INTEGERP (val))
+       len += sprintf (work, "%d", XINT (val));
+      else if (SYMBOLP (val))
+       len += (NILP (val) ? 5 : 4); /* for "false" or "true" */
     }
 
   if (len > nbytes)
     return -1;
   p = name;
   if (! NILP (AREF (font, FONT_FAMILY_INDEX)))
-    p += sprintf(p, "%s",
-                SDATA (SYMBOL_NAME (AREF (font, FONT_FAMILY_INDEX))));
+    p += sprintf(p, "%s", SDATA (SYMBOL_NAME (AREF (font, FONT_FAMILY_INDEX))));
   if (point_size > 0)
     {
       if (p == name)
@@ -1519,32 +1444,30 @@ font_unparse_fcname (font, pixel_size, name, nbytes)
     }
   else if (pixel_size > 0)
     p += sprintf (p, ":pixelsize=%d", pixel_size);
-  if (SYMBOLP (AREF (font, FONT_FOUNDRY_INDEX))
-      && ! NILP (AREF (font, FONT_FOUNDRY_INDEX)))
+  if (! NILP (AREF (font, FONT_FOUNDRY_INDEX)))
     p += sprintf (p, ":foundry=%s",
                  SDATA (SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX))));
   for (i = 0; i < 3; i++)
-    if (SYMBOLP (styles[i]) && ! NILP (styles [i]))
+    if (! NILP (styles[i]))
       p += sprintf (p, ":%s=%s", style_names[i],
-                   SDATA (SYMBOL_NAME (styles [i])));
-  if (dpi >= 0)
-    p += sprintf (p, ":dpi=%d", dpi);
-  if (spacing >= 0)
-    p += sprintf (p, ":spacing=%d", spacing);
-  if (scalable > 0)
-    p += sprintf (p, ":scalable=True");
-  else if (scalable == 0)
-    p += sprintf (p, ":scalable=False");
+                   SDATA (SYMBOL_NAME (styles[i])));
+  if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
+    p += sprintf (p, ":dpi=%d", XINT (AREF (font, FONT_DPI_INDEX)));
+  if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
+    p += sprintf (p, ":spacing=%d", XINT (AREF (font, FONT_SPACING_INDEX)));
+  if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
+    {
+      if (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0)
+       p += sprintf (p, ":scalable=true");
+      else
+       p += sprintf (p, ":scalable=false");
+    }
   return (p - name);
 }
 
 /* Parse NAME (null terminated) and store information in FONT
    (font-spec or font-entity).  If NAME is successfully parsed, return
-   0.  Otherwise return -1.
-
-   If NAME is XLFD and FONT is a font-entity, store
-   RESX-RESY-SPACING-AVWIDTH information as a symbol in
-   FONT_EXTRA_INDEX.  */
+   0.  Otherwise return -1.  */
 
 static int
 font_parse_name (name, font)
@@ -1556,57 +1479,58 @@ font_parse_name (name, font)
   return font_parse_fcname (name, font);
 }
 
-/* Merge old style font specification (either a font name NAME or a
-   combination of a family name FAMILY and a registry name REGISTRY
-   into the font specification SPEC.  */
+
+/* Merge FAMILY and REGISTRY into FONT_SPEC.  FAMILY may have the form
+   "FAMILY-FOUNDRY".  REGISTRY may not contain charset-encoding
+   part.  */
 
 void
-font_merge_old_spec (name, family, registry, spec)
-     Lisp_Object name, family, registry, spec;
+font_parse_family_registry (family, registry, font_spec)
+     Lisp_Object family, registry;
 {
-  if (STRINGP (name))
+  int len;
+  char *p0, *p1;
+
+  if (! NILP (family))
     {
-      if (font_parse_xlfd ((char *) SDATA (name), spec) < 0)
+      CHECK_STRING (family);
+      len = SBYTES (family);
+      p0 = (char *) SDATA (family);
+      p1 = index (p0, '-');
+      if (p1)
        {
-         Lisp_Object extra = Fcons (Fcons (QCname, name), Qnil);
-
-         ASET (spec, FONT_EXTRA_INDEX, extra);
+         if (*p0 != '*' || p1 - p0 > 1)
+           ASET (font_spec, FONT_FOUNDRY_INDEX,
+                 font_intern_prop (p0, p1 - p0));
+         p1++;
+         len -= p1 - p0;
+         ASET (font_spec, FONT_FAMILY_INDEX, font_intern_prop (p1, len));
        }
+      else
+       ASET (font_spec, FONT_FAMILY_INDEX, Fintern (family, Qnil));
     }
-  else
+  if (! NILP (registry))
     {
-      if (! NILP (family))
+      /* Convert "XXX" and "XXX*" to "XXX*-*".  */
+      CHECK_STRING (registry);
+      len = SBYTES (registry);
+      p0 = (char *) SDATA (registry);
+      p1 = index (p0, '-');
+      if (! p1)
        {
-         int len;
-         char *p0, *p1;
-
-         xassert (STRINGP (family));
-         len = SBYTES (family);
-         p0 = (char *) SDATA (family);
-         p1 = index (p0, '-');
-         if (p1)
-           {
-             if ((*p0 != '*' || p1 - p0 > 1)
-                 && NILP (AREF (spec, FONT_FOUNDRY_INDEX)))
-               ASET (spec, FONT_FOUNDRY_INDEX,
-                     intern_downcase (p0, p1 - p0));
-             if (NILP (AREF (spec, FONT_FAMILY_INDEX)))
-               ASET (spec, FONT_FAMILY_INDEX,
-                     intern_downcase (p1 + 1, len - (p1 + 1 - p0)));
-           }
-         else if (NILP (AREF (spec, FONT_FAMILY_INDEX)))
-           ASET (spec, FONT_FAMILY_INDEX, intern_downcase (p0, len));
+         if (SDATA (registry)[len - 1] == '*')
+           registry = concat2 (registry, build_string ("-*"));
+         else
+           registry = concat2 (registry, build_string ("*-*"));
        }
-      if (! NILP (registry)
-         && NILP (AREF (spec, FONT_REGISTRY_INDEX)))
-       ASET (spec, FONT_REGISTRY_INDEX,
-             intern_downcase ((char *) SDATA (registry), SBYTES (registry)));
+      registry = Fdowncase (registry);
+      ASET (font_spec, FONT_REGISTRY_INDEX, Fintern (registry, Qnil));
     }
 }
 
 \f
-/* This part (through the next ^L) is still experimental and never
-   tested.  We may drastically change codes.  */
+/* This part (through the next ^L) is still experimental and not
+   tested much.  We may drastically change codes.  */
 
 /* OTF handler */
 
@@ -1672,7 +1596,7 @@ static void
 check_otf_features (otf_features)
      Lisp_Object otf_features;
 {
-  Lisp_Object val, elt;
+  Lisp_Object val;
 
   CHECK_CONS (otf_features);
   CHECK_SYMBOL (XCAR (otf_features));
@@ -1711,20 +1635,19 @@ otf_tag_symbol (tag)
 }
 
 static OTF *
-otf_open (entity, file)
-     Lisp_Object entity;
-     char *file;
+otf_open (file)
+     Lisp_Object file;
 {
-  Lisp_Object val = Fassoc (entity, otf_list);
+  Lisp_Object val = Fassoc (file, otf_list);
   OTF *otf;
 
   if (! NILP (val))
     otf = XSAVE_VALUE (XCDR (val))->pointer;
   else
     {
-      otf = file ? OTF_open (file) : NULL;
+      otf = STRINGP (file) ? OTF_open ((char *) SDATA (file)) : NULL;
       val = make_save_value (otf, 0);
-      otf_list = Fcons (Fcons (entity, val), otf_list);
+      otf_list = Fcons (Fcons (file, val), otf_list);
     }
   return otf;
 }
@@ -1742,7 +1665,7 @@ font_otf_capability (font)
   Lisp_Object capability = Fcons (Qnil, Qnil);
   int i;
 
-  otf = otf_open (font->entity, font->file_name);
+  otf = otf_open (font->props[FONT_FILE_INDEX]);
   if (! otf)
     return Qnil;
   for (i = 0; i < 2; i++)
@@ -1815,7 +1738,7 @@ generate_otf_features (spec, features)
      char *features;
 {
   Lisp_Object val;
-  char *p, *pend;
+  char *p;
   int asterisk;
 
   p = features;
@@ -1918,7 +1841,7 @@ font_prepare_composition (cmp, f)
     = AREF (XHASH_TABLE (composition_hash_table)->key_and_value,
            cmp->hash_index * 2);
 
-  cmp->font = XSAVE_VALUE (LGSTRING_FONT (gstring))->pointer;
+  cmp->font = XFONT_OBJECT (LGSTRING_FONT (gstring));
   cmp->glyph_len = LGSTRING_LENGTH (gstring);
   cmp->pixel_width = LGSTRING_WIDTH (gstring);
   cmp->lbearing = LGSTRING_LBEARING (gstring);
@@ -1935,87 +1858,100 @@ font_prepare_composition (cmp, f)
 \f
 /* Font sorting */
 
-static unsigned font_score P_ ((Lisp_Object, Lisp_Object *));
+static unsigned font_score P_ ((Lisp_Object, Lisp_Object *, Lisp_Object));
 static int font_compare P_ ((const void *, const void *));
 static Lisp_Object font_sort_entites P_ ((Lisp_Object, Lisp_Object,
-                                         Lisp_Object, Lisp_Object));
+                                         Lisp_Object, Lisp_Object,
+                                         int));
 
 /* We sort fonts by scoring each of them against a specified
    font-spec.  The score value is 32 bit (`unsigned'), and the smaller
    the value is, the closer the font is to the font-spec.
 
-   Each 1-bit of the highest 4 bits of the score is used for atomic
-   properties FOUNDRY, FAMILY, ADSTYLE, and REGISTRY.
+   The highest 2 bits of the score is used for FAMILY.  The exact
+   match is 0, match with one of face-font-family-alternatives is
+   nonzero.
+
+   The next 2 bits of the score is used for the atomic properties
+   FOUNDRY and ADSTYLE respectively.
 
-   Each 7-bit in the lowest 28 bits are used for numeric properties
+   Each 7-bit in the lower 28 bits are used for numeric properties
    WEIGHT, SLANT, WIDTH, and SIZE.  */
 
 /* How many bits to shift to store the difference value of each font
-   property in a score.  */
+   property in a score.  Note that flots for FONT_TYPE_INDEX and
+   FONT_REGISTRY_INDEX are not used.  */
 static int sort_shift_bits[FONT_SIZE_INDEX + 1];
 
 /* Score font-entity ENTITY against properties of font-spec SPEC_PROP.
    The return value indicates how different ENTITY is compared with
-   SPEC_PROP.  */
+   SPEC_PROP.
+
+   ALTERNATE_FAMILIES, if non-nil, is a pre-calculated list of
+   alternate family names for AREF (SPEC_PROP, FONT_FAMILY_INDEX).  */
 
 static unsigned
-font_score (entity, spec_prop)
+font_score (entity, spec_prop, alternate_families)
      Lisp_Object entity, *spec_prop;
+     Lisp_Object alternate_families;
 {
   unsigned score = 0;
   int i;
-  /* Score four atomic fields.  Maximum difference is 1. */
-  for (i = FONT_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX; i++)
-    if (! NILP (spec_prop[i])
-       && ! EQ (spec_prop[i], AREF (entity, i)))
-      score |= 1 << sort_shift_bits[i];
-
-  /* Score four numeric fields.  Maximum difference is 127. */
-  for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++)
-    {
-      Lisp_Object entity_val = AREF (entity, i);
-      Lisp_Object spec_val = spec_prop[i];
 
-      /* If weight and slant are unspecified, score normal lower (low wins). */
-      if (NILP (spec_val))
-        {
-          if (i == FONT_WEIGHT_INDEX || i == FONT_SLANT_INDEX)
-            spec_val = prop_name_to_numeric (i, build_string ("normal"));
-        }
+  /* Score three atomic fields.  Maximum difference is 1 (family is 3). */
+  for (i = FONT_FOUNDRY_INDEX; i <= FONT_ADSTYLE_INDEX; i++)
+    if (i != FONT_REGISTRY_INDEX
+       && ! NILP (spec_prop[i]) && ! EQ (AREF (entity, i), spec_prop[i]))
+      {
+       Lisp_Object entity_str = SYMBOL_NAME (AREF (entity, i));
+       Lisp_Object spec_str = SYMBOL_NAME (spec_prop[i]);
 
-      if (! NILP (spec_val) && ! EQ (spec_val, entity_val))
-       {
-         if (! INTEGERP (entity_val))
-           score |= 127 << sort_shift_bits[i];
-         else
-           {
-             int diff = XINT (entity_val) - XINT (spec_val);
+       if (strcasecmp (SDATA (spec_str), SDATA (entity_str)))
+         {
+           if (i == FONT_FAMILY_INDEX && CONSP (alternate_families))
+             {
+               int j;
+
+               for (j = 1; CONSP (alternate_families);
+                    j++, alternate_families = XCDR (alternate_families)) 
+                 {
+                   spec_str = XCAR (alternate_families);
+                   if (strcasecmp (SDATA (spec_str), SDATA (entity_str)) == 0)
+                     break;
+                   
+                 }
+               if (j > 3)
+                 j = 3;
+               score |= j << sort_shift_bits[i];
+             }
+           else
+             score |= 1 << sort_shift_bits[i];
+         }
+      }
 
-             if (diff < 0)
-               diff = - diff;
-             if (i == FONT_SIZE_INDEX)
-               {
-                 if (XINT (entity_val) > 0
-                     && diff > FONT_PIXEL_SIZE_QUANTUM)
-                   score |= min (diff, 127) << sort_shift_bits[i];
-               }
-#ifdef WINDOWSNT
-              else if (i == FONT_WEIGHT_INDEX)
-                {
-                  /* Windows uses a much wider range for weight (100-900)
-                     compared with freetype (0-210), so scale down the
-                     difference.  A more general way of doing this
-                     would be to look up the values of regular and bold
-                     and/or light and calculate the scale factor from them,
-                     but the lookup would be expensive, and if only Windows
-                     needs it, not worth the effort.  */
-                  score |= min (diff / 4, 127) << sort_shift_bits[i];
-                }
-#endif
-             else
-               score |= min (diff, 127) << sort_shift_bits[i];
-           }
-       }
+  /* Score three style numeric fields.  Maximum difference is 127. */
+  for (i = FONT_WEIGHT_INDEX; i <= FONT_WIDTH_INDEX; i++)
+    if (! NILP (spec_prop[i]) && ! EQ (AREF (entity, i), spec_prop[i]))
+      {
+       int diff = (XINT (AREF (entity, i)) >> 8) - (XINT (spec_prop[i]) >> 8);
+
+       if (diff < 0)
+         diff = - diff;
+       score |= min (diff, 127) << sort_shift_bits[i];
+      }
+
+  /* Score the size.  Maximum difference is 127.  */
+  i = FONT_SIZE_INDEX;
+  if (! NILP (spec_prop[i]) && ! EQ (AREF (entity, i), spec_prop[i])
+      && XINT (AREF (entity, i)) > 0)
+    {
+      int diff = XINT (spec_prop[i]) - XINT (AREF (entity, i));
+
+      if (diff < 0)
+       diff = - diff;
+      if (diff <= FONT_PIXEL_SIZE_QUANTUM)
+       diff = 1;
+      score |= min (diff, 127) << sort_shift_bits[FONT_SIZE_INDEX];
     }
 
   return score;
@@ -2028,8 +1964,7 @@ static int
 font_compare (d1, d2)
      const void *d1, *d2;
 {
-  return (*(unsigned *) d1 < *(unsigned *) d2
-         ? -1 : *(unsigned *) d1 > *(unsigned *) d2);
+  return (*(unsigned *) d1 - *(unsigned *) d2);
 }
 
 
@@ -2045,48 +1980,81 @@ struct font_sort_data
    If PREFER specifies a point-size, calculate the corresponding
    pixel-size from QCdpi property of PREFER or from the Y-resolution
    of FRAME before sorting.  If SPEC is not nil, it is a font-spec to
-   get the font-entities in VEC.  */
+   get the font-entities in VEC.
+
+   If BEST-ONLY is nonzero, return the best matching entity.  Otherwise,
+   return the sorted VEC.  */
 
 static Lisp_Object
-font_sort_entites (vec, prefer, frame, spec)
+font_sort_entites (vec, prefer, frame, spec, best_only)
      Lisp_Object vec, prefer, frame, spec;
+     int best_only;
 {
   Lisp_Object prefer_prop[FONT_SPEC_MAX];
   int len, i;
   struct font_sort_data *data;
+  Lisp_Object alternate_families = Qnil;
+  unsigned best_score;
+  Lisp_Object best_entity;
   USE_SAFE_ALLOCA;
 
   len = ASIZE (vec);
   if (len <= 1)
-    return vec;
+    return best_only ? AREF (vec, 0) : vec;
 
   for (i = FONT_FOUNDRY_INDEX; i <= FONT_SIZE_INDEX; i++)
     prefer_prop[i] = AREF (prefer, i);
 
   if (! NILP (spec))
     {
-      /* As it is assured that all fonts in VEC match with SPEC, we
-        should ignore properties specified in SPEC.  So, set the
-        corresponding properties in PREFER_PROP to nil. */
-      for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++)
+      /* A font driver may return a font that has a property value
+        different from the value specified in SPEC if the driver
+        thinks they are the same.  That happens, for instance, such a
+        generic family name as "serif" is specified.  So, to ignore
+        such a difference, for all properties specified in SPEC, set
+        the corresponding properties in PREFER_PROP to nil.  */
+      for (i = FONT_FOUNDRY_INDEX; i <= FONT_SIZE_INDEX; i++)
        if (! NILP (AREF (spec, i)))
-         prefer_prop[i++] = Qnil;
+         prefer_prop[i] = Qnil;
     }
 
   if (FLOATP (prefer_prop[FONT_SIZE_INDEX]))
     prefer_prop[FONT_SIZE_INDEX]
       = make_number (font_pixel_size (XFRAME (frame), prefer));
+  if (! NILP (prefer_prop[FONT_FAMILY_INDEX]))
+    {
+      alternate_families
+       = Fassoc_string (prefer_prop[FONT_FAMILY_INDEX],
+                        Vface_alternative_font_family_alist, Qt);
+      if (CONSP (alternate_families))
+       alternate_families = XCDR (alternate_families);
+    }
 
   /* Scoring and sorting.  */
   SAFE_ALLOCA (data, struct font_sort_data *, (sizeof *data) * len);
+  best_score = 0xFFFFFFFF;
+  best_entity = Qnil;
   for (i = 0; i < len; i++)
     {
       data[i].entity = AREF (vec, i);
-      data[i].score = font_score (data[i].entity, prefer_prop);
+      data[i].score = font_score (data[i].entity, prefer_prop,
+                                 alternate_families);
+      if (best_only && best_score > data[i].score)
+       {
+         best_score = data[i].score;
+         best_entity = data[i].entity;
+         if (best_score == 0)
+           break;
+       }
     }
-  qsort (data, len, sizeof *data, font_compare);
-  for (i = 0; i < len; i++)
-    ASET (vec, i, data[i].entity);
+  if (NILP (best_entity))
+    {
+      qsort (data, len, sizeof *data, font_compare);
+      for (i = 0; i < len; i++)
+       ASET (vec, i, data[i].entity);
+    }
+  else
+    vec = best_entity;
   SAFE_FREE ();
 
   return vec;
@@ -2103,9 +2071,9 @@ void
 font_update_sort_order (order)
      int *order;
 {
-  int i, shift_bits = 21;
+  int i, shift_bits;
 
-  for (i = 0; i < 4; i++, shift_bits -= 7)
+  for (i = 0, shift_bits = 21; i < 4; i++, shift_bits -= 7)
     {
       int xlfd_idx = order[i];
 
@@ -2121,87 +2089,51 @@ font_update_sort_order (order)
 }
 
 
-/* Return weight property of FONT as symbol.  */
-
-Lisp_Object
-font_symbolic_weight (font)
-     Lisp_Object font;
-{
-  Lisp_Object weight = AREF (font, FONT_WEIGHT_INDEX);
-
-  if (INTEGERP (weight))
-    weight = prop_numeric_to_name (FONT_WEIGHT_INDEX, XINT (weight));
-  return weight;
-}
-
-
-/* Return slant property of FONT as symbol.  */
-
-Lisp_Object
-font_symbolic_slant (font)
-     Lisp_Object font;
-{
-  Lisp_Object slant = AREF (font, FONT_SLANT_INDEX);
-
-  if (INTEGERP (slant))
-    slant = prop_numeric_to_name (FONT_SLANT_INDEX, XINT (slant));
-  return slant;
-}
-
-
-/* Return width property of FONT as symbol.  */
-
-Lisp_Object
-font_symbolic_width (font)
-     Lisp_Object font;
-{
-  Lisp_Object width = AREF (font, FONT_WIDTH_INDEX);
-
-  if (INTEGERP (width))
-    width = prop_numeric_to_name (FONT_WIDTH_INDEX, XINT (width));
-  return width;
-}
-
-
 /* Check if ENTITY matches with the font specification SPEC.  */
 
 int
 font_match_p (spec, entity)
      Lisp_Object spec, entity;
 {
+  Lisp_Object prefer_prop[FONT_SPEC_MAX];
+  Lisp_Object alternate_families = Qnil;
+  int prefer_style[3];
   int i;
 
-  for (i = FONT_FOUNDRY_INDEX; i < FONT_SIZE_INDEX; i++)
-    if (! NILP (AREF (spec, i))
-       && ! EQ (AREF (spec, i), AREF (entity, i)))
-      return 0;
-  if (INTEGERP (AREF (spec, FONT_SIZE_INDEX))
-      && XINT (AREF (entity, FONT_SIZE_INDEX)) > 0
-      && (XINT (AREF (spec, FONT_SIZE_INDEX))
-         != XINT (AREF (entity, FONT_SIZE_INDEX))))
-    return 0;
-  return 1;
+  for (i = FONT_FOUNDRY_INDEX; i <= FONT_SIZE_INDEX; i++)
+    prefer_prop[i] = AREF (spec, i);
+  if (FLOATP (prefer_prop[FONT_SIZE_INDEX]))
+    prefer_prop[FONT_SIZE_INDEX]
+      = make_number (font_pixel_size (XFRAME (selected_frame), spec));
+  if (! NILP (prefer_prop[FONT_FAMILY_INDEX]))
+    {
+      alternate_families
+       = Fassoc_string (prefer_prop[FONT_FAMILY_INDEX],
+                        Vface_alternative_font_family_alist, Qt);
+      if (CONSP (alternate_families))
+       alternate_families = XCDR (alternate_families);
+    }
+
+  return (font_score (entity, prefer_prop, alternate_families) == 0);
 }
 
 
-/* Return a lispy font object corresponding to FONT.  */
+/* CHeck a lispy font object corresponding to FONT.  */
 
-Lisp_Object
-font_find_object (font)
+int
+font_check_object (font)
      struct font *font;
 {
   Lisp_Object tail, elt;
 
-  for (tail = AREF (font->entity, FONT_OBJLIST_INDEX); CONSP (tail);
+  for (tail = font->props[FONT_OBJLIST_INDEX]; CONSP (tail);
        tail = XCDR (tail))
     {
       elt = XCAR (tail);
-      if (font == XSAVE_VALUE (elt)->pointer
-         && XSAVE_VALUE (elt)->integer > 0)
-       return elt;
+      if (font == XFONT_OBJECT (elt))
+       return 1;
     }
-  abort ();
-  return Qnil;
+  return 0;
 }
 
 \f
@@ -2317,13 +2249,10 @@ font_clear_cache (f, cache, driver)
                  for (; CONSP (objlist); objlist = XCDR (objlist))
                    {
                      Lisp_Object val = XCAR (objlist);
-                     struct Lisp_Save_Value *p = XSAVE_VALUE (val);
-                     struct font *font = p->pointer;
+                     struct font *font = XFONT_OBJECT (val);
 
                      xassert (font && driver == font->driver);
                      driver->close (f, font);
-                     p->pointer = NULL;
-                     p->integer = 0;
                      num_fonts--;
                    }
                  if (driver->free_entity)
@@ -2338,40 +2267,99 @@ font_clear_cache (f, cache, driver)
 
 static Lisp_Object scratch_font_spec, scratch_font_prefer;
 
+Lisp_Object
+font_delete_unmatched (list, spec, size)
+     Lisp_Object list, spec;
+     int size;
+{
+  Lisp_Object entity, prev, tail;
+  enum font_property_index prop;
 
-/* Return a vector of font-entities matching with SPEC on frame F.  */
+  for (tail = list, prev = Qnil; CONSP (tail); )
+    {
+      entity = XCAR (tail);
+      for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++)
+       if (INTEGERP (AREF (spec, prop))
+           && ((XINT (AREF (spec, prop)) >> 8)
+               != (XINT (AREF (entity, prop)) >> 8)))
+         prop = FONT_SPEC_MAX;
+      if (prop++ <= FONT_SIZE_INDEX
+         && size
+         && XINT (AREF (entity, FONT_SIZE_INDEX)) > 0)
+       {
+         int diff = XINT (AREF (entity, FONT_SIZE_INDEX)) - size;
 
-static Lisp_Object
+         if (diff != 0
+             && (diff < 0 ? -diff > FONT_PIXEL_SIZE_QUANTUM
+                 : diff > FONT_PIXEL_SIZE_QUANTUM))
+           prop = FONT_SPEC_MAX;
+       }
+      for (; prop < FONT_EXTRA_INDEX; prop++)
+       if (! NILP (AREF (spec, prop))
+           && ! EQ (AREF (spec, prop), AREF (entity, prop)))
+         prop = FONT_SPEC_MAX;
+      if (prop < FONT_SPEC_MAX)
+       prev = tail, tail = XCDR (tail);
+      else if (NILP (prev))
+       list = tail = XCDR (tail);
+      else
+       tail = XCDR (tail), XSETCDR (prev, tail);
+    }
+  return list;
+}
+
+
+/* Return a vector of font-entities matching with SPEC on FRAME.  */
+
+Lisp_Object
 font_list_entities (frame, spec)
      Lisp_Object frame, spec;
 {
   FRAME_PTR f = XFRAME (frame);
   struct font_driver_list *driver_list = f->font_driver_list;
-  Lisp_Object ftype, family, size, alternate_familes;
-  Lisp_Object *vec = alloca (sizeof (Lisp_Object) * num_font_drivers);
+  Lisp_Object ftype, family, alternate_familes;
+  Lisp_Object *vec;
+  int size;
+  int need_filtering = 0;
+  int n_family = 1;
   int i;
 
-  if (! vec)
-    return null_vector;
+  xassert (FONT_SPEC_P (spec));
 
   family = AREF (spec, FONT_FAMILY_INDEX);
   if (NILP (family))
     alternate_familes = Qnil;
   else
     {
-      if (NILP (font_family_alist)
-         && !NILP (Vface_alternative_font_family_alist))
-       build_font_family_alist ();
-      alternate_familes = assq_no_quit (family, font_family_alist);
+      alternate_familes = Fassoc_string (family, 
+                                        Vface_alternative_font_family_alist,
+                                        Qt);
       if (! NILP (alternate_familes))
        alternate_familes = XCDR (alternate_familes);
+      n_family += XINT (Flength (alternate_familes));
     }
-  size = AREF (spec, FONT_SIZE_INDEX);
-  if (FLOATP (size))
-    ASET (spec, FONT_SIZE_INDEX, make_number (font_pixel_size (f, spec)));
 
-  xassert (ASIZE (spec) == FONT_SPEC_MAX);
+  if (INTEGERP (AREF (spec, FONT_SIZE_INDEX)))
+    size = XINT (AREF (spec, FONT_SIZE_INDEX));
+  else if (FLOATP (AREF (spec, FONT_SIZE_INDEX)))
+    size = font_pixel_size (f, spec);
+  else
+    size = 0;
+
   ftype = AREF (spec, FONT_TYPE_INDEX);
+  for (i = 0; i <= FONT_REGISTRY_INDEX; i++)
+    ASET (scratch_font_spec, i, AREF (spec, i));
+  for (; i < FONT_EXTRA_INDEX; i++)
+    {
+      ASET (scratch_font_spec, i, Qnil);
+      if (! NILP (AREF (spec, i)))
+       need_filtering = 1;
+    }
+  ASET (scratch_font_spec, FONT_EXTRA_INDEX, AREF (spec, FONT_EXTRA_INDEX));
+
+  vec = alloca (sizeof (Lisp_Object) * num_font_drivers * n_family);
+  if (! vec)
+    return null_vector;
 
   for (i = 0; driver_list; driver_list = driver_list->next)
     if (driver_list->on
@@ -2380,50 +2368,53 @@ font_list_entities (frame, spec)
        Lisp_Object cache = font_get_cache (f, driver_list->driver);
        Lisp_Object tail = alternate_familes;
 
-       ASET (spec, FONT_TYPE_INDEX, driver_list->driver->type);
-       ASET (spec, FONT_FAMILY_INDEX, family);
-
        while (1)
          {
-           Lisp_Object val = assoc_no_quit (spec, XCDR (cache));
+           Lisp_Object val = assoc_no_quit (scratch_font_spec, XCDR (cache));
 
-           if (CONSP (val))
+           if (CONSP (val) && VECTORP (XCDR (val)))
              val = XCDR (val);
            else
              {
-               val = driver_list->driver->list (frame, spec);
-               if (VECTORP (val))
-                 XSETCDR (cache, Fcons (Fcons (Fcopy_sequence (spec), val),
-                                        XCDR (cache)));
+               Lisp_Object copy;
+
+               val = driver_list->driver->list (frame, scratch_font_spec);
+               if (! NILP (val) && need_filtering)
+                 val = font_delete_unmatched (val, spec, size);
+               copy = Fcopy_font_spec (scratch_font_spec);
+               XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache)));
              }
-           if (VECTORP (val) && ASIZE (val) > 0)
+           if (! NILP (val))
              {
                vec[i++] = val;
                break;
              }
            if (NILP (tail))
              break;
-           ASET (spec, FONT_FAMILY_INDEX, XCAR (tail));
+           ASET (scratch_font_spec, FONT_FAMILY_INDEX,
+                 Fintern (XCAR (tail), Qnil));
            tail = XCDR (tail);
          }
       }
-  ASET (spec, FONT_TYPE_INDEX, ftype);
-  ASET (spec, FONT_FAMILY_INDEX, family);
-  ASET (spec, FONT_SIZE_INDEX, size);
+
   return (i > 0 ? Fvconcat (i, vec) : null_vector);
 }
 
 
-/* Return a font entity matching with SPEC on FRAME.  */
+/* Return a font entity matching with SPEC on FRAME.  ATTRS, if non
+   nil, is an array of face's attributes, which specifies preferred
+   font-related attributes.  */
 
 static Lisp_Object
-font_matching_entity (frame, spec)
-     Lisp_Object frame, spec;
+font_matching_entity (f, attrs, spec)
+     FRAME_PTR f;
+     Lisp_Object *attrs, spec;
 {
-  FRAME_PTR f = XFRAME (frame);
   struct font_driver_list *driver_list = f->font_driver_list;
   Lisp_Object ftype, size, entity;
+  Lisp_Object frame;
 
+  XSETFRAME (frame, f);
   ftype = AREF (spec, FONT_TYPE_INDEX);
   size = AREF (spec, FONT_SIZE_INDEX);
   if (FLOATP (size))
@@ -2434,21 +2425,16 @@ font_matching_entity (frame, spec)
        && (NILP (ftype) || EQ (driver_list->driver->type, ftype)))
       {
        Lisp_Object cache = font_get_cache (f, driver_list->driver);
-       Lisp_Object key;
 
        ASET (spec, FONT_TYPE_INDEX, driver_list->driver->type);
-       key = Fcons (spec, Qnil);
-       entity = assoc_no_quit (key, XCDR (cache));
-       if (CONSP (entity))
+       entity = assoc_no_quit (spec, XCDR (cache));
+       if (CONSP (entity) && ! VECTORP (XCDR (entity)))
          entity = XCDR (entity);
        else
          {
            entity = driver_list->driver->match (frame, spec);
-           if (! NILP (entity))
-             {
-               XSETCAR (key, Fcopy_sequence (spec));
-               XSETCDR (cache, Fcons (Fcons (key, entity), XCDR (cache)));
-             }
+           XSETCDR (cache, Fcons (Fcons (Fcopy_font_spec (spec), entity),
+                                  XCDR (cache)));
          }
        if (! NILP (entity))
          break;
@@ -2471,53 +2457,52 @@ font_open_entity (f, entity, pixel_size)
   struct font_driver_list *driver_list;
   Lisp_Object objlist, size, val, font_object;
   struct font *font;
+  int min_width;
 
+  xassert (FONT_ENTITY_P (entity));
   size = AREF (entity, FONT_SIZE_INDEX);
-  xassert (NATNUMP (size));
   if (XINT (size) != 0)
     pixel_size = XINT (size);
 
-  font_object = Qnil;
   for (objlist = AREF (entity, FONT_OBJLIST_INDEX); CONSP (objlist);
        objlist = XCDR (objlist))
-    {
-      font = XSAVE_VALUE (XCAR (objlist))->pointer;
-      if (font->pixel_size == pixel_size)
-       {
-         font_object = XCAR (objlist);
-         XSAVE_VALUE (font_object)->integer++;
-         break;
-       }
-    }
+    if (XFONT_OBJECT (XCAR (objlist))->pixel_size == pixel_size)
+      return  XCAR (objlist);
+
+  val = AREF (entity, FONT_TYPE_INDEX);
+  for (driver_list = f->font_driver_list;
+       driver_list && ! EQ (driver_list->driver->type, val);
+       driver_list = driver_list->next);
+  if (! driver_list)
+    return Qnil;
 
+  font_object = driver_list->driver->open (f, entity, pixel_size);
   if (NILP (font_object))
+    return Qnil;
+  ASET (entity, FONT_OBJLIST_INDEX,
+       Fcons (font_object, AREF (entity, FONT_OBJLIST_INDEX)));
+  ASET (font_object, FONT_OBJLIST_INDEX, AREF (entity, FONT_OBJLIST_INDEX));
+  num_fonts++;
+
+  font = XFONT_OBJECT (font_object);
+  min_width = (font->min_width ? font->min_width
+              : font->average_width ? font->average_width
+              : font->space_width ? font->space_width
+              : 1);
+  FRAME_X_DISPLAY_INFO (f)->n_fonts++;
+  if (FRAME_X_DISPLAY_INFO (f)->n_fonts == 1)
     {
-      val = AREF (entity, FONT_TYPE_INDEX);
-      for (driver_list = f->font_driver_list;
-          driver_list && ! EQ (driver_list->driver->type, val);
-          driver_list = driver_list->next);
-      if (! driver_list)
-       return Qnil;
-
-      font = driver_list->driver->open (f, entity, pixel_size);
-      if (! font)
-       return Qnil;
-      font->scalable = XINT (size) == 0;
-
-      font_object = make_save_value (font, 1);
-      ASET (entity, FONT_OBJLIST_INDEX,
-           Fcons (font_object, AREF (entity, FONT_OBJLIST_INDEX)));
-      num_fonts++;
+      FRAME_SMALLEST_CHAR_WIDTH (f) = min_width;
+      FRAME_SMALLEST_FONT_HEIGHT (f) = font->height;
+      fonts_changed_p = 1;
+    }
+  else
+    {
+      if (FRAME_SMALLEST_CHAR_WIDTH (f) > min_width)
+       FRAME_SMALLEST_CHAR_WIDTH (f) = min_width, fonts_changed_p = 1;
+      if (FRAME_SMALLEST_FONT_HEIGHT (f) > font->height)
+       FRAME_SMALLEST_FONT_HEIGHT (f) = font->height, fonts_changed_p = 1;
     }
-
-  if (FRAME_SMALLEST_CHAR_WIDTH (f) > font->min_width)
-    FRAME_SMALLEST_CHAR_WIDTH (f) = font->min_width;
-  if (FRAME_SMALLEST_CHAR_WIDTH (f) <= 0)
-    FRAME_SMALLEST_CHAR_WIDTH (f) = 1;
-  if (FRAME_SMALLEST_FONT_HEIGHT (f) > font->font.height)
-    FRAME_SMALLEST_FONT_HEIGHT (f) = font->font.height;
-  if (FRAME_SMALLEST_FONT_HEIGHT (f) <= 0)
-    FRAME_SMALLEST_FONT_HEIGHT (f) = 1;
 
   return font_object;
 }
@@ -2530,25 +2515,20 @@ font_close_object (f, font_object)
      FRAME_PTR f;
      Lisp_Object font_object;
 {
-  struct font *font = XSAVE_VALUE (font_object)->pointer;
+  struct font *font = XFONT_OBJECT (font_object);
   Lisp_Object objlist;
   Lisp_Object tail, prev = Qnil;
 
-  xassert (XSAVE_VALUE (font_object)->integer > 0);
-  XSAVE_VALUE (font_object)->integer--;
-  if (XSAVE_VALUE (font_object)->integer > 0)
-    return;
-
-  objlist = AREF (font->entity, FONT_OBJLIST_INDEX);
+  objlist = AREF (font_object, FONT_OBJLIST_INDEX);
   for (prev = Qnil, tail = objlist; CONSP (tail);
        prev = tail, tail = XCDR (tail))
     if (EQ (font_object, XCAR (tail)))
       {
-       if (font->driver->close)
-         font->driver->close (f, font);
-       XSAVE_VALUE (font_object)->pointer = NULL;
+       xassert (FRAME_X_DISPLAY_INFO (f)->n_fonts);
+       font->driver->close (f, font);
+       FRAME_X_DISPLAY_INFO (f)->n_fonts--;
        if (NILP (prev))
-         ASET (font->entity, FONT_OBJLIST_INDEX, XCDR (objlist));
+         ASET (font_object, FONT_OBJLIST_INDEX, XCDR (objlist));
        else
          XSETCDR (prev, XCDR (objlist));
        num_fonts--;
@@ -2585,11 +2565,10 @@ font_has_char (f, font, c)
     }
 
   xassert (FONT_OBJECT_P (font));
-  fontp = XSAVE_VALUE (font)->pointer;
-
+  fontp = XFONT_OBJECT (font);
   if (fontp->driver->has_char)
     {
-      int result = fontp->driver->has_char (fontp->entity, c);
+      int result = fontp->driver->has_char (font, c);
 
       if (result >= 0)
        return result;
@@ -2605,8 +2584,10 @@ font_encode_char (font_object, c)
      Lisp_Object font_object;
      int c;
 {
-  struct font *font = XSAVE_VALUE (font_object)->pointer;
+  struct font *font;
 
+  xassert (FONT_OBJECT_P (font_object));
+  font = XFONT_OBJECT (font_object);
   return font->driver->encode_char (font, c);
 }
 
@@ -2617,12 +2598,10 @@ Lisp_Object
 font_get_name (font_object)
      Lisp_Object font_object;
 {
-  struct font *font = XSAVE_VALUE (font_object)->pointer;
-  char *name = (font->font.full_name ? font->font.full_name
-               : font->font.name ? font->font.name
-               : NULL);
+  Lisp_Object name;
 
-  return (name ? make_unibyte_string (name, strlen (name)) : null_string);
+  xassert (FONT_OBJECT_P (font_object));
+  return AREF (font_object, FONT_NAME_INDEX);
 }
 
 
@@ -2632,154 +2611,227 @@ Lisp_Object
 font_get_spec (font_object)
      Lisp_Object font_object;
 {
-  struct font *font = XSAVE_VALUE (font_object)->pointer;
-  Lisp_Object spec = Ffont_spec (0, NULL);
+  Lisp_Object spec = font_make_spec ();
   int i;
 
   for (i = 0; i < FONT_SIZE_INDEX; i++)
-    ASET (spec, i, AREF (font->entity, i));
-  ASET (spec, FONT_SIZE_INDEX, make_number (font->pixel_size));
+    ASET (spec, i, AREF (font_object, i));
+  ASET (spec, FONT_SIZE_INDEX,
+       make_number (XFONT_OBJECT (font_object)->pixel_size));
   return spec;
 }
 
+Lisp_Object
+font_spec_from_name (font_name)
+     Lisp_Object font_name;
+{
+  Lisp_Object args[2];
+
+  args[0] = QCname;
+  args[1] = font_name;
+  return Ffont_spec (2, args);
+}
+
 
-/* Return the frame on which FONT exists.  FONT is a font object or a
-   font entity.  */
+void
+font_clear_prop (attrs, prop)
+     Lisp_Object *attrs;
+     enum font_property_index prop;
+{
+  Lisp_Object font = attrs[LFACE_FONT_INDEX];
+  Lisp_Object extra, prev;
 
-Lisp_Object
-font_get_frame (font)
-     Lisp_Object font;
+  if (! FONTP (font))
+    return;
+  if (NILP (AREF (font, prop))
+      && prop != FONT_FAMILY_INDEX && prop != FONT_FAMILY_INDEX)
+    return;
+  font = Fcopy_font_spec (font);
+  ASET (font, prop, Qnil);
+  if (prop == FONT_FAMILY_INDEX)
+    {
+      ASET (font, FONT_FOUNDRY_INDEX, Qnil);
+      ASET (font, FONT_ADSTYLE_INDEX, Qnil);
+      ASET (font, FONT_SIZE_INDEX, Qnil);
+      ASET (font, FONT_DPI_INDEX, Qnil);
+      ASET (font, FONT_SPACING_INDEX, Qnil);
+      ASET (font, FONT_AVGWIDTH_INDEX, Qnil);
+    }
+  else if (prop == FONT_SIZE_INDEX)
+    {
+      ASET (font, FONT_DPI_INDEX, Qnil);
+      ASET (font, FONT_SPACING_INDEX, Qnil);
+      ASET (font, FONT_AVGWIDTH_INDEX, Qnil);
+    }
+  attrs[LFACE_FONT_INDEX] = font;
+}
+
+void
+font_update_lface (f, attrs)
+     FRAME_PTR f;
+     Lisp_Object *attrs;
 {
-  if (FONT_OBJECT_P (font))
-    font = ((struct font *) XSAVE_VALUE (font)->pointer)->entity;
-  xassert (FONT_ENTITY_P (font));
-  return AREF (font, FONT_FRAME_INDEX);
+  Lisp_Object spec, val;
+  int n;
+
+  spec = attrs[LFACE_FONT_INDEX];
+  if (! FONT_SPEC_P (spec))
+    return;
+
+  if (! NILP (AREF (spec, FONT_FOUNDRY_INDEX))
+      || ! NILP (AREF (spec, FONT_FAMILY_INDEX)))
+    {
+      Lisp_Object family;
+
+      if (NILP (AREF (spec, FONT_FOUNDRY_INDEX)))
+       family = AREF (spec, FONT_FAMILY_INDEX);
+      else if (NILP (AREF (spec, FONT_FAMILY_INDEX)))
+       family = concat2 (SYMBOL_NAME (AREF (spec, FONT_FOUNDRY_INDEX)),
+                         build_string ("-*"));
+      else
+       family = concat3 (SYMBOL_NAME (AREF (spec, FONT_FOUNDRY_INDEX)),
+                         build_string ("-"),
+                         SYMBOL_NAME (AREF (spec, FONT_FAMILY_INDEX)));
+      attrs[LFACE_FAMILY_INDEX] = family;
+    }
+  if (! NILP (AREF (spec, FONT_WEIGHT_INDEX)))
+    attrs[LFACE_WEIGHT_INDEX] = FONT_WEIGHT_FOR_FACE (spec);
+  if (! NILP (AREF (spec, FONT_SLANT_INDEX)))
+    attrs[LFACE_SLANT_INDEX] = FONT_SLANT_FOR_FACE (spec);;
+  if (! NILP (AREF (spec, FONT_WIDTH_INDEX)))
+    attrs[LFACE_SWIDTH_INDEX] = FONT_WIDTH_FOR_FACE (spec);
+  if (! NILP (AREF (spec, FONT_SIZE_INDEX)))
+    {
+      int point;
+
+      if (INTEGERP (AREF (spec, FONT_SIZE_INDEX)))
+       {
+         Lisp_Object val;
+         int dpi = f->resy;
+
+         val = Ffont_get (spec, QCdpi);
+         if (! NILP (val))
+           dpi = XINT (val);
+         point = PIXEL_TO_POINT (XINT (AREF (spec, FONT_SIZE_INDEX)) * 10,
+                                 dpi);
+       }
+      else if (FLOATP (AREF (spec, FONT_SIZE_INDEX)))
+       point = XFLOAT_DATA (AREF (spec, FONT_SIZE_INDEX)) * 10;
+      attrs[LFACE_HEIGHT_INDEX] = make_number (point);
+    }
 }
 
 
-/* Find a font entity best matching with LFACE.  If SPEC is non-nil,
-   the font must exactly match with it.  C, if not negative, is a
+/* Return a font-entity satisfying SPEC and best matching with face's
+   font related attributes in ATTRS.  C, if not negative, is a
    character that the entity must support.  */
 
 Lisp_Object
-font_find_for_lface (f, lface, spec, c)
+font_find_for_lface (f, attrs, spec, c)
      FRAME_PTR f;
-     Lisp_Object *lface;
+     Lisp_Object *attrs;
      Lisp_Object spec;
      int c;
 {
-  Lisp_Object frame, entities, val;
+  Lisp_Object frame, entities, val, props[FONT_REGISTRY_INDEX + 1] ;
+  Lisp_Object size;
   int i, result;
 
-  XSETFRAME (frame, f);
-
-  if (NILP (spec))
-    {
-      if (c >= 0x100)
-       return Qnil;
-      for (i = 0; i < FONT_SPEC_MAX; i++)
-       ASET (scratch_font_spec, i, Qnil);
-      ASET (scratch_font_spec, FONT_REGISTRY_INDEX, Qiso8859_1);
-
-      if (! NILP (lface[LFACE_FAMILY_INDEX]))
-       font_merge_old_spec (Qnil, lface[LFACE_FAMILY_INDEX], Qnil,
-                            scratch_font_spec);
-      entities = font_list_entities (frame, scratch_font_spec);
-      while (ASIZE (entities) == 0)
-       {
-         /* Try without FOUNDRY or FAMILY.  */
-         if (! NILP (AREF (scratch_font_spec, FONT_FOUNDRY_INDEX)))
-           {
-             ASET (scratch_font_spec, FONT_FOUNDRY_INDEX, Qnil);
-             entities = font_list_entities (frame, scratch_font_spec);
-           }
-         else if (! NILP (AREF (scratch_font_spec, FONT_FAMILY_INDEX)))
-           {
-             ASET (scratch_font_spec, FONT_FAMILY_INDEX, Qnil);
-             entities = font_list_entities (frame, scratch_font_spec);
-           }
-         else
-           break;
-       }
-    }
-  else
+  if (c >= 0)
     {
       Lisp_Object registry = AREF (spec, FONT_REGISTRY_INDEX);
+      struct charset *encoding, *repertory;
 
-      if (NILP (registry))
-       registry = Qiso8859_1;
-
-      if (c >= 0)
+      if (font_registry_charsets (registry, &encoding, &repertory) < 0)
+       return Qnil;
+      if (repertory)
        {
-         struct charset *encoding, *repertory;
-
-         if (font_registry_charsets (registry, &encoding, &repertory) < 0)
-           return Qnil;
-         if (repertory)
-           {
-             if (ENCODE_CHAR (repertory, c)
-                 == CHARSET_INVALID_CODE (repertory))
-               return Qnil;
-             /* Any font of this registry support C.  So, let's
-                suppress the further checking.  */
-             c = -1;
-           }
-         else if (c > encoding->max_char)
+         if (ENCODE_CHAR (repertory, c) == CHARSET_INVALID_CODE (repertory))
            return Qnil;
+         /* Any font of this registry support C.  So, let's
+            suppress the further checking.  */
+         c = -1;
        }
-      for (i = 0; i < FONT_SPEC_MAX; i++)
-       ASET (scratch_font_spec, i, AREF (spec, i));
-      ASET (scratch_font_spec, FONT_REGISTRY_INDEX, registry);
-      entities = font_list_entities (frame, scratch_font_spec);
+      else if (c > encoding->max_char)
+       return Qnil;
     }
 
+  XSETFRAME (frame, f);
+  size = AREF (spec, FONT_SIZE_INDEX);
+  ASET (spec, FONT_SIZE_INDEX, Qnil);
+  entities = font_list_entities (frame, spec);
+  ASET (spec, FONT_SIZE_INDEX, size);
   if (ASIZE (entities) == 0)
     return Qnil;
-  if (ASIZE (entities) > 1)
+  if (ASIZE (entities) == 1)
+    {
+      if (c < 0)
+       return AREF (entities, 0);
+    }
+  else
     {
       /* Sort fonts by properties specified in LFACE.  */
       Lisp_Object prefer = scratch_font_prefer;
       double pt;
 
-      if (! NILP (lface[LFACE_FAMILY_INDEX]))
-       font_merge_old_spec (Qnil, lface[LFACE_FAMILY_INDEX], Qnil, prefer);
-      ASET (prefer, FONT_WEIGHT_INDEX,
-           font_prop_validate_style (QCweight, lface[LFACE_WEIGHT_INDEX]));
-      ASET (prefer, FONT_SLANT_INDEX,
-           font_prop_validate_style (QCslant, lface[LFACE_SLANT_INDEX]));
-      ASET (prefer, FONT_WIDTH_INDEX,
-           font_prop_validate_style (QCwidth, lface[LFACE_SWIDTH_INDEX]));
-      pt = XINT (lface[LFACE_HEIGHT_INDEX]);
-      ASET (prefer, FONT_SIZE_INDEX, make_float (pt / 10));
-
-      font_sort_entites (entities, prefer, frame, spec);
+      font_parse_family_registry (attrs[LFACE_FAMILY_INDEX], Qnil, prefer);
+      FONT_SET_STYLE (prefer, FONT_WEIGHT_INDEX, attrs[LFACE_WEIGHT_INDEX]);
+      FONT_SET_STYLE (prefer, FONT_SLANT_INDEX, attrs[LFACE_SLANT_INDEX]);
+      FONT_SET_STYLE (prefer, FONT_WIDTH_INDEX, attrs[LFACE_SWIDTH_INDEX]);
+      if (INTEGERP (size))
+       ASET (prefer, FONT_SIZE_INDEX, size);
+      else if (FLOATP (size))
+       ASET (prefer, FONT_SIZE_INDEX, font_pixel_size (f, spec));
+      else
+       {
+         double pt = XINT (attrs[LFACE_HEIGHT_INDEX]);
+         int pixel_size = POINT_TO_PIXEL (pt / 10, f->resy);
+         ASET (prefer, FONT_SIZE_INDEX, make_number (pixel_size));
+       }
+      ASET (spec, FONT_SIZE_INDEX, Qnil);
+      entities = font_sort_entites (entities, prefer, frame, spec, c < 0);
+      ASET (spec, FONT_SIZE_INDEX, size);
     }
-
   if (c < 0)
-    return AREF (entities, 0);
+    return entities;
 
-  val = AREF (entities, 0);
-  result = font_has_char (f, val, c);
-  if (result > 0)
-    return val;
-  if (result == 0)
-    return Qnil;
-  val = font_open_for_lface (f, val, lface, spec);
-  if (NILP (val))
-    return Qnil;
-  result = font_has_char (f, val, c);
-  font_close_object (f, val);
-  if (result > 0)
-    return val;
+  for (i = 0; i < ASIZE (entities); i++)
+    {
+      int j;
+
+      val = AREF (entities, i);
+      if (i > 0)
+       {
+         for (j = FONT_FOUNDRY_INDEX; j <= FONT_REGISTRY_INDEX; j++)
+           if (! EQ (AREF (val, j), props[j]))
+             break;
+         if (j > FONT_REGISTRY_INDEX)
+           continue;
+       }
+      for (j = FONT_FOUNDRY_INDEX; j <= FONT_REGISTRY_INDEX; j++)
+       props[j] = AREF (val, j);
+      result = font_has_char (f, val, c);
+      if (result > 0)
+       return val;
+      if (result == 0)
+       return Qnil;
+      val = font_open_for_lface (f, val, attrs, spec);
+      if (NILP (val))
+       continue;
+      result = font_has_char (f, val, c);
+      font_close_object (f, val);
+      if (result > 0)
+       return AREF (entities, i);
+    }
   return Qnil;
 }
 
 
 Lisp_Object
-font_open_for_lface (f, entity, lface, spec)
+font_open_for_lface (f, entity, attrs, spec)
      FRAME_PTR f;
      Lisp_Object entity;
-     Lisp_Object *lface;
+     Lisp_Object *attrs;
      Lisp_Object spec;
 {
   int size;
@@ -2788,7 +2840,7 @@ font_open_for_lface (f, entity, lface, spec)
     size = XINT (AREF (spec, FONT_SIZE_INDEX));
   else
     {
-      double pt = XINT (lface[LFACE_HEIGHT_INDEX]);
+      double pt = XINT (attrs[LFACE_HEIGHT_INDEX]);
 
       pt /= 10;
       size = POINT_TO_PIXEL (pt, f->resy);
@@ -2797,46 +2849,28 @@ font_open_for_lface (f, entity, lface, spec)
 }
 
 
-/* Load a font best matching with FACE's font-related properties into
-   FACE on frame F.  If no proper font is found, record that FACE has
-   no font.  */
+/* Find a font satisfying SPEC and best matching with face's
+   attributes in ATTRS on FRAME, and return the opened
+   font-object.  */
 
-void
-font_load_for_face (f, face)
+Lisp_Object
+font_load_for_lface (f, attrs, spec)
      FRAME_PTR f;
-     struct face *face;
+     Lisp_Object *attrs, spec;
 {
-  Lisp_Object font_object = face->lface[LFACE_FONT_INDEX];
-
-  if (NILP (font_object))
-    {
-      Lisp_Object entity = font_find_for_lface (f, face->lface, Qnil, -1);
-
-      if (! NILP (entity))
-       font_object = font_open_for_lface (f, entity, face->lface, Qnil);
-    }
-  else if (STRINGP (font_object))
-    {
-      font_object = font_open_by_name (f, SDATA (font_object));
-    }
-
-  if (! NILP (font_object))
-    {
-      struct font *font = XSAVE_VALUE (font_object)->pointer;
+  Lisp_Object entity;
 
-      face->font = font->font.font;
-      face->font_info = (struct font_info *) font;
-      face->font_info_id = 0;
-      face->font_name = font->font.full_name;
-    }
-  else
+  entity = font_find_for_lface (f, attrs, spec, -1);
+  if (NILP (entity))
     {
-      face->font = NULL;
-      face->font_info = NULL;
-      face->font_info_id = -1;
-      face->font_name = NULL;
-      add_to_log ("Unable to load font for a face%s", null_string, Qnil);
+      /* No font is listed for SPEC, but each font-backend may have
+        the different criteria about "font matching".  So, try
+        it.  */
+      entity = font_matching_entity (f, attrs, spec);
+      if (NILP (entity))
+       return Qnil;
     }
+  return font_open_for_lface (f, entity, attrs, spec);
 }
 
 
@@ -2847,10 +2881,8 @@ font_prepare_for_face (f, face)
      FRAME_PTR f;
      struct face *face;
 {
-  struct font *font = (struct font *) face->font_info;
-
-  if (font->driver->prepare_face)
-    font->driver->prepare_face (f, face);
+  if (face->font->driver->prepare_face)
+    face->font->driver->prepare_face (f, face);
 }
 
 
@@ -2861,10 +2893,8 @@ font_done_for_face (f, face)
      FRAME_PTR f;
      struct face *face;
 {
-  struct font *font = (struct font *) face->font_info;
-
-  if (font->driver->done_face)
-    font->driver->done_face (f, face);
+  if (face->font->driver->done_face)
+    face->font->driver->done_face (f, face);
   face->extra = NULL;
 }
 
@@ -2889,34 +2919,41 @@ font_open_by_name (f, name)
   args[1] = make_unibyte_string (name, strlen (name));
   spec = Ffont_spec (2, args);
   prefer = scratch_font_prefer;
-  for (i = FONT_WEIGHT_INDEX; i < FONT_SIZE_INDEX; i++)
-    if (NILP (AREF (spec, i)))
-      ASET (prefer, i, make_number (100));
+  for (i = 0; i < FONT_SPEC_MAX; i++)
+    {
+      if (i >= FONT_WEIGHT_INDEX && i <= FONT_WIDTH_INDEX)
+       FONT_SET_STYLE (prefer, i, make_number (100));
+      else
+       ASET (prefer, i, Qnil);
+    }
   size = AREF (spec, FONT_SIZE_INDEX);
   if (NILP (size))
     pixel_size = 0;
-  else if (INTEGERP (size))
-    pixel_size = XINT (size);
-  else                         /* FLOATP (size) */
+  else
     {
-      double pt = XFLOAT_DATA (size);
+      if (INTEGERP (size))
+       pixel_size = XINT (size);
+      else                             /* FLOATP (size) */
+       {
+         double pt = XFLOAT_DATA (size);
 
-      pixel_size = POINT_TO_PIXEL (pt, f->resy);
-      size = make_number (pixel_size);
-      ASET (spec, FONT_SIZE_INDEX, size);
+         pixel_size = POINT_TO_PIXEL (pt, f->resy);
+       }
+      if (pixel_size == 0)
+       ASET (spec, FONT_SIZE_INDEX, Qnil);
     }
   if (pixel_size == 0)
     {
       pixel_size = POINT_TO_PIXEL (12.0, f->resy);
       size = make_number (pixel_size);
+      ASET (prefer, FONT_SIZE_INDEX, size);
     }
-  ASET (prefer, FONT_SIZE_INDEX, size);
   if (NILP (AREF (spec, FONT_REGISTRY_INDEX)))
     ASET (spec, FONT_REGISTRY_INDEX, Qiso8859_1);
 
   entity_list = Flist_fonts (spec, frame, make_number (1), prefer);
   if (NILP (entity_list))
-    entity = font_matching_entity (frame, spec);
+    entity = font_matching_entity (f, NULL, spec);
   else
     entity = XCAR (entity_list);
   return (NILP (entity)
@@ -3101,6 +3138,7 @@ font_at (c, pos, face, w, string)
 {
   FRAME_PTR f;
   int multibyte;
+  Lisp_Object font_object;
 
   if (c < 0)
     {
@@ -3154,21 +3192,97 @@ font_at (c, pos, face, w, string)
       int face_id = FACE_FOR_CHAR (f, face, c, pos, string);
       face = FACE_FROM_ID (f, face_id);
     }
-  if (! face->font_info)
+  if (! face->font)
     return Qnil;
-  return font_find_object ((struct font *) face->font_info);
+
+  xassert (font_check_object ((struct font *) face->font));
+  XSETFONT (font_object, face->font);
+  return font_object;
+}
+
+
+/* Check how many characters after POS (at most to LIMIT) can be
+   displayed by the same font.  FACE is the face selected for the
+   character as POS on frame F.  STRING, if not nil, is the string to
+   check instead of the current buffer.
+   
+   The return value is the position of the character that is displayed
+   by the differnt font than that of the character as POS.  */
+
+EMACS_INT
+font_range (pos, limit, face, f, string)
+     EMACS_INT pos, limit;
+     struct face *face;
+     FRAME_PTR f;
+     Lisp_Object string;
+{
+  int multibyte;
+  EMACS_INT pos_byte;
+  int c;
+  struct font *font;
+  int first = 1;
+
+  if (NILP (string))
+    {
+      multibyte = ! NILP (current_buffer->enable_multibyte_characters);
+      pos_byte = CHAR_TO_BYTE (pos);
+    }
+  else
+    {
+      multibyte = STRING_MULTIBYTE (string);
+      pos_byte = string_char_to_byte (string, pos);
+    }
+
+  if (! multibyte)
+    /* All unibyte character are displayed by the same font.  */
+    return limit;
+
+  while (pos < limit)
+    {
+      int face_id;
+
+      if (NILP (string))
+       FETCH_CHAR_ADVANCE_NO_CHECK (c, pos, pos_byte);
+      else
+       FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, pos, pos_byte);
+      face_id = FACE_FOR_CHAR (f, face, c, pos, string);
+      face = FACE_FROM_ID (f, face_id);
+      if (first)
+       {
+         font = face->font;
+         first = 0;
+         continue;
+       }
+      else if (font != face->font)
+       {
+         pos--;
+         break;
+       }
+    }
+  return pos;
 }
 
 \f
 /* Lisp API */
 
-DEFUN ("fontp", Ffontp, Sfontp, 1, 1, 0,
+DEFUN ("fontp", Ffontp, Sfontp, 1, 2, 0,
        doc: /* Return t if OBJECT is a font-spec, font-entity, or font-object.
-Return nil otherwise.  */)
-     (object)
+Return nil otherwise.
+Optional 2nd argument EXTRA-TYPE, if non-nil, specifies to check
+which kind of font it is.  It must be one of `font-spec', `font-entity'
+`font-object'.  */)
+     (object, extra_type)
      Lisp_Object object;
 {
-  return (FONTP (object) ? Qt : Qnil);
+  if (NILP (extra_type))
+    return (FONTP (object) ? Qt : Qnil);
+  if (EQ (extra_type, Qfont_spec))
+    return (FONT_SPEC_P (object) ? Qt : Qnil);
+  if (EQ (extra_type, Qfont_entity))
+    return (FONT_ENTITY_P (object) ? Qt : Qnil);
+  if (EQ (extra_type, Qfont_object))
+    return (FONT_OBJECT_P (object) ? Qt : Qnil);
+  wrong_type_argument (intern ("font-extra-type"), extra_type);
 }
 
 DEFUN ("font-spec", Ffont_spec, Sfont_spec, 0, MANY, 0,
@@ -3189,7 +3303,7 @@ VALUE must be a string or a symbol specifying the font foundry, e.g. ``misc''.
 `:adstyle'
 
 VALUE must be a string or a symbol specifying the additional
-typographic style information of a font, e.g. ``sans''.  Usually null.
+typographic style information of a font, e.g. ``sans''.
 
 `:registry'
 
@@ -3199,38 +3313,101 @@ encoding of a font, e.g. ``iso8859-1''.
 `:size'
 
 VALUE must be a non-negative integer or a floating point number
-specifying the font size.  It specifies the font size in 1/10 pixels
+specifying the font size.  It specifies the font size in pixels
 (if VALUE is an integer), or in points (if VALUE is a float).
 usage: (font-spec ARGS ...)  */)
      (nargs, args)
      int nargs;
      Lisp_Object *args;
 {
-  Lisp_Object spec = Fmake_vector (make_number (FONT_SPEC_MAX), Qnil);
+  Lisp_Object spec = font_make_spec ();
   int i;
 
   for (i = 0; i < nargs; i += 2)
     {
-      enum font_property_index prop;
       Lisp_Object key = args[i], val = args[i + 1];
 
-      prop = get_font_prop_index (key, 0);
-      if (prop < FONT_EXTRA_INDEX)
-       ASET (spec, prop, val);
+      if (EQ (key, QCname))
+       {
+         CHECK_STRING (val);
+         font_parse_name ((char *) SDATA (val), spec);
+         font_put_extra (spec, key, val);
+       }
+      else if (EQ (key, QCfamily))
+       {
+         CHECK_STRING (val);
+         font_parse_family_registry (val, Qnil, spec);
+       }
       else
        {
-         if (EQ (key, QCname))
+         int idx = get_font_prop_index (key);
+
+         if (idx >= 0)
            {
-             CHECK_STRING (val);
-             font_parse_name ((char *) SDATA (val), spec);
+             val = font_prop_validate (idx, Qnil, val);
+             if (idx < FONT_EXTRA_INDEX)
+               ASET (spec, idx, val);
+             else
+               font_put_extra (spec, key, val);
            }
-         font_put_extra (spec, key, val);
+         else
+           font_put_extra (spec, key, font_prop_validate (0, key, val));
        }
     }
-  CHECK_VALIDATE_FONT_SPEC (spec);
   return spec;
 }
 
+DEFUN ("copy-font-spec", Fcopy_font_spec, Scopy_font_spec, 1, 1, 0,
+       doc: /* Return a copy of FONT as a font-spec.  */)
+     (font)
+     Lisp_Object font;
+{
+  Lisp_Object new_spec, tail, extra;
+  int i;
+
+  CHECK_FONT (font);
+  new_spec = font_make_spec ();
+  for (i = 1; i < FONT_EXTRA_INDEX; i++)
+    ASET (new_spec, i, AREF (font, i));
+  extra = Qnil;
+  for (tail = AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
+    {
+      if (! EQ (XCAR (XCAR (tail)), QCfont_entity))
+       extra = Fcons (Fcons (XCAR (XCAR (tail)), XCDR (XCAR (tail))), extra);
+    }
+  ASET (new_spec, FONT_EXTRA_INDEX, extra);
+  return new_spec;
+}
+
+DEFUN ("merge-font-spec", Fmerge_font_spec, Smerge_font_spec, 2, 2, 0,
+       doc: /* Merge font-specs FROM and TO, and return a new font-spec.
+Every specified properties in FROM override the corresponding
+properties in TO.  */)
+     (from, to)
+     Lisp_Object from, to;
+{
+  Lisp_Object extra, tail;
+  int i;
+
+  CHECK_FONT (from);
+  CHECK_FONT (to);
+  to = Fcopy_font_spec (to);
+  for (i = 0; i < FONT_EXTRA_INDEX; i++)
+    ASET (to, i, AREF (from, i));
+  extra = AREF (to, FONT_EXTRA_INDEX);
+  for (tail = AREF (from, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
+    if (! EQ (XCAR (XCAR (tail)), Qfont_entity))
+      {
+       Lisp_Object slot = assq_no_quit (XCAR (XCAR (tail)), extra);
+
+       if (! NILP (slot))
+         XSETCDR (slot, XCDR (XCAR (tail)));
+       else
+         extra = Fcons (Fcons (XCAR (XCAR (tail)), XCDR (XCAR (tail))), extra);
+      }
+  ASET (to, FONT_EXTRA_INDEX, extra);
+  return to;
+}
 
 DEFUN ("font-get", Ffont_get, Sfont_get, 2, 2, 0,
        doc: /* Return the value of FONT's property KEY.
@@ -3238,29 +3415,15 @@ FONT is a font-spec, a font-entity, or a font-object.  */)
      (font, key)
      Lisp_Object font, key;
 {
-  enum font_property_index idx;
+  int idx;
 
-  if (FONT_OBJECT_P (font))
-    {
-      struct font *fontp = XSAVE_VALUE (font)->pointer;
+  CHECK_FONT (font);
+  CHECK_SYMBOL (key);
 
-      if (EQ (key, QCotf))
-       {
-          if (fontp->driver->otf_capability)
-            return fontp->driver->otf_capability (fontp);
-          else
-            return Qnil;
-       }
-      font = fontp->entity;
-    }
-  else
-    CHECK_FONT (font);
-  idx = get_font_prop_index (key, 0);
-  if (idx < FONT_EXTRA_INDEX)
+  idx = get_font_prop_index (key);
+  if (idx >= 0 && idx < FONT_EXTRA_INDEX)
     return AREF (font, idx);
-  if (FONT_ENTITY_P (font))
-    return Qnil;
-  return Fcdr (Fassoc (key, AREF (font, FONT_EXTRA_INDEX)));
+  return Fcdr (Fassq (key, AREF (font, FONT_EXTRA_INDEX)));
 }
 
 
@@ -3269,19 +3432,21 @@ DEFUN ("font-put", Ffont_put, Sfont_put, 3, 3, 0,
      (font_spec, prop, val)
      Lisp_Object font_spec, prop, val;
 {
-  enum font_property_index idx;
+  int idx;
   Lisp_Object extra, slot;
 
   CHECK_FONT_SPEC (font_spec);
-  idx = get_font_prop_index (prop, 0);
-  if (idx < FONT_EXTRA_INDEX)
-    return ASET (font_spec, idx, val);
-  extra = AREF (font_spec, FONT_EXTRA_INDEX);
-  slot = Fassoc (extra, prop);
-  if (NILP (slot))
-    extra = Fcons (Fcons (prop, val), extra);
+  idx = get_font_prop_index (prop);
+  if (idx >= 0 && idx < FONT_EXTRA_INDEX)
+    {
+      if (idx == FONT_FAMILY_INDEX
+         && STRINGP (val))
+       font_parse_family_registry (val, Qnil, font_spec);
+      else
+       ASET (font_spec, idx, font_prop_validate (idx, Qnil, val));
+    }
   else
-    Fsetcdr (slot, val);
+    font_put_extra (font_spec, prop, font_prop_validate (0, prop, val));
   return val;
 }
 
@@ -3301,7 +3466,7 @@ how they are close to PREFER.  */)
   if (NILP (frame))
     frame = selected_frame;
   CHECK_LIVE_FRAME (frame);
-  CHECK_VALIDATE_FONT_SPEC (font_spec);
+  CHECK_FONT_SPEC (font_spec);
   if (! NILP (num))
     {
       CHECK_NUMBER (num);
@@ -3310,7 +3475,7 @@ how they are close to PREFER.  */)
        return Qnil;
     }
   if (! NILP (prefer))
-    CHECK_FONT (prefer);
+    CHECK_FONT_SPEC (prefer);
 
   vec = font_list_entities (frame, font_spec);
   len = ASIZE (vec);
@@ -3320,7 +3485,7 @@ how they are close to PREFER.  */)
     return Fcons (AREF (vec, 0), Qnil);
 
   if (! NILP (prefer))
-    vec = font_sort_entites (vec, prefer, frame, font_spec);
+    vec = font_sort_entites (vec, prefer, frame, font_spec, 0);
 
   list = tail = Fcons (AREF (vec, 0), Qnil);
   if (n == 0 || n > len)
@@ -3335,7 +3500,7 @@ how they are close to PREFER.  */)
   return list;
 }
 
-DEFUN ("list-families", Flist_families, Slist_families, 0, 1, 0,
+DEFUN ("font-family-list", Ffont_family_list, Sfont_family_list, 0, 1, 0,
        doc: /* List available font families on the current frame.
 Optional argument FRAME specifies the target frame.  */)
      (frame)
@@ -3393,19 +3558,17 @@ If the name is too long for XLFD (maximum 255 chars), return nil.  */)
   char name[256];
   int pixel_size = 0;
 
-  if (FONT_SPEC_P (font))
-    CHECK_VALIDATE_FONT_SPEC (font);
-  else if (FONT_ENTITY_P (font))
-    CHECK_FONT (font);
-  else
+  CHECK_FONT (font);
+
+  if (FONT_OBJECT_P (font))
     {
-      struct font *fontp;
+      Lisp_Object font_name = AREF (font, FONT_NAME_INDEX);
 
-      CHECK_FONT_GET_OBJECT (font, fontp);
-      font = fontp->entity;
-      pixel_size = fontp->pixel_size;
+      if (STRINGP (font_name)
+         && SDATA (font_name)[0] == '-')
+       return font_name;
+      pixel_size = XFONT_OBJECT (font)->pixel_size;
     }
-
   if (font_unparse_xlfd (font, pixel_size, name, 256) < 0)
     return Qnil;
   return build_string (name);
@@ -3446,41 +3609,55 @@ DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0,
 }
 
 DEFUN ("internal-set-font-style-table", Finternal_set_font_style_table,
-       Sinternal_set_font_style_table, 2, 2, 0,
-       doc: /* Set font style table for PROP to TABLE.
-PROP must be `:weight', `:slant', or `:width'.
-TABLE must be an alist of symbols vs the corresponding numeric values
-sorted by numeric values.  */)
-     (prop, table)
-     Lisp_Object prop, table;
+       Sinternal_set_font_style_table, 3, 3, 0,
+       doc: /* Setup font style table from WEIGHT, SLANT, and WIDTH tables.
+WEIGHT, SLANT, WIDTH must be `font-weight-table', `font-slant-table',
+`font-width-table' respectivly.
+This function is called after those tables are initialized. */)
+     (weight, slant, width)
+     Lisp_Object weight, slant, width;
 {
-  int table_index;
-  int numeric;
-  Lisp_Object tail, val;
+  Lisp_Object tables[3];
+  int i;
 
-  CHECK_SYMBOL (prop);
-  table_index = (EQ (prop, QCweight) ? 0
-                : EQ (prop, QCslant) ? 1
-                : EQ (prop, QCwidth) ? 2
-                : 3);
-  if (table_index >= ASIZE (font_style_table))
-    error ("Invalid font style property: %s", SDATA (SYMBOL_NAME (prop)));
-  table = Fcopy_sequence (table);
-  numeric = -1;
-  for (tail = table; CONSP (tail); tail = XCDR (tail))
+  tables[0] = weight, tables[1] = slant, tables[2] = width;
+
+  font_style_table = Fmake_vector (make_number (3), Qnil);
+  /* In the following loop, we don't use XCAR and XCDR until assuring
+     the argument is a cons cell so that the error in the tables can
+     be detected.  */
+  for (i = 0; i < 3; i++)
     {
-      prop = Fcar (XCAR (tail));
-      val = Fcdr (XCAR (tail));
-      CHECK_SYMBOL (prop);
-      CHECK_NATNUM (val);
-      if (numeric > XINT (val))
-       error ("Numeric values not sorted for %s", SDATA (SYMBOL_NAME (prop)));
-      else if (numeric == XINT (val))
-       error ("Duplicate numeric values for %s", SDATA (SYMBOL_NAME (prop)));
-      numeric = XINT (val);
-      XSETCAR (tail, Fcons (prop, val));
+      Lisp_Object tail, elt, list, val;
+
+      for (tail = tables[i], list = Qnil; CONSP (tail); tail = XCDR (tail))
+       {
+         int numeric = -1;
+
+         elt = Fcar (tail);
+         CHECK_SYMBOL (Fcar (elt));
+         val = Fcons (XCAR (elt), Qnil);
+         elt = XCDR (elt);
+         CHECK_NATNUM (Fcar (elt));
+         if (numeric >= XINT (XCAR (elt)))
+           error ("Numeric values not unique nor sorted in %s",
+                  (i == 0 ? "font-weight-table"
+                   : i == 1 ? "font-slant-table"
+                   : "font-width-table"));
+         numeric = XINT (XCAR (elt));
+         XSETCDR (val, XCAR (elt));
+         list = Fcons (val, list);
+         for (elt = XCDR (elt); CONSP (elt); elt = XCDR (elt))
+           {
+             val = XCAR (elt);
+             CHECK_SYMBOL (val);
+             list = Fcons (Fcons (XCAR (elt), make_number (numeric)), list);
+           }
+       }
+      list = Fnreverse (list);
+      ASET (font_style_table, i, Fvconcat (1, &list));
     }
-  ASET (font_style_table, table_index, table);
+
   return Qnil;
 }
 
@@ -3545,7 +3722,7 @@ FONT-OBJECT may be nil if GSTRING already already contains one.  */)
   CHECK_VECTOR (gstring);
   if (NILP (font_object))
     font_object = LGSTRING_FONT (gstring);
-  CHECK_FONT_GET_OBJECT (font_object, font);
+  font = XFONT_OBJECT (font_object);
 
   if (STRINGP (object))
     {
@@ -3624,11 +3801,11 @@ FONT-OBJECT.  */)
   struct font_metrics metrics;
   EMACS_INT start, end;
   Lisp_Object gstring, n;
-  int len, i, j;
+  int len, i;
 
   if (! FONT_OBJECT_P (font_object))
     return Qnil;
-  CHECK_FONT_GET_OBJECT (font_object, font);
+  font = XFONT_OBJECT (font_object);
   if (! font->driver->shape)
     return Qnil;
 
@@ -3793,7 +3970,8 @@ glyph-string.  */)
   int len, num;
 
   check_otf_features (otf_features);
-  CHECK_FONT_GET_OBJECT (font_object, font);
+  CHECK_FONT_OBJECT (font_object);
+  font = XFONT_OBJECT (font_object);
   if (! font->driver->otf_drive)
     error ("Font backend %s can't drive OpenType GSUB table",
           SDATA (SYMBOL_NAME (font->driver->type)));
@@ -3884,19 +4062,22 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
   int isize;
 
   CHECK_FONT_ENTITY (font_entity);
-  if (NILP (size))
-    size = AREF (font_entity, FONT_SIZE_INDEX);
-  CHECK_NUMBER (size);
   if (NILP (frame))
     frame = selected_frame;
   CHECK_LIVE_FRAME (frame);
 
-  isize = XINT (size);
-  if (isize == 0)
-    isize = 120;
-  if (isize < 0)
-    isize = POINT_TO_PIXEL (- isize, XFRAME (frame)->resy);
-
+  if (NILP (size))
+    isize = XINT (AREF (font_entity, FONT_SIZE_INDEX));
+  else
+    {
+      CHECK_NUMBER_OR_FLOAT (size);
+      if (FLOATP (size))
+       isize = POINT_TO_PIXEL (- isize, XFRAME (frame)->resy);
+      else
+       isize = XINT (size);
+      if (isize == 0)
+       isize = 120;
+    }
   return font_open_entity (XFRAME (frame), font_entity, isize);
 }
 
@@ -3963,22 +4144,16 @@ If the font is not OpenType font, CAPABILITY is nil.  */)
   CHECK_FONT_GET_OBJECT (font_object, font);
 
   val = Fmake_vector (make_number (9), Qnil);
-  if (font->font.full_name)
-    ASET (val, 0, make_unibyte_string (font->font.full_name,
-                                      strlen (font->font.full_name)));
-  if (font->file_name)
-    ASET (val, 1, make_unibyte_string (font->file_name,
-                                      strlen (font->file_name)));
+  ASET (val, 0, AREF (font_object, FONT_NAME_INDEX));
+  ASET (val, 1, AREF (font_object, FONT_FILE_INDEX));
   ASET (val, 2, make_number (font->pixel_size));
-  ASET (val, 3, make_number (font->font.size));
+  ASET (val, 3, make_number (font->max_width));
   ASET (val, 4, make_number (font->ascent));
   ASET (val, 5, make_number (font->descent));
-  ASET (val, 6, make_number (font->font.space_width));
-  ASET (val, 7, make_number (font->font.average_width));
+  ASET (val, 6, make_number (font->space_width));
+  ASET (val, 7, make_number (font->average_width));
   if (font->driver->otf_capability)
     ASET (val, 8, Fcons (Qopentype, font->driver->otf_capability (font)));
-  else
-    ASET (val, 8, Fcons (font->format, Qnil));
   return val;
 }
 
@@ -4032,10 +4207,7 @@ FONT is a font-spec, font-entity, or font-object. */)
      Lisp_Object spec, font;
 {
   CHECK_FONT_SPEC (spec);
-  if (FONT_OBJECT_P (font))
-    font = ((struct font *) XSAVE_VALUE (font)->pointer)->entity;
-  else if (! FONT_ENTITY_P (font))
-    CHECK_FONT_SPEC (font);
+  CHECK_FONT (font);
 
   return (font_match_p (spec, font) ? Qt : Qnil);
 }
@@ -4059,9 +4231,6 @@ the current buffer.  It defaults to the currently selected window.  */)
     }
   else
     {
-      EMACS_INT len;
-      unsigned char *str;
-
       CHECK_NUMBER (position);
       CHECK_STRING (string);
       pos = XINT (position);
@@ -4139,18 +4308,19 @@ syms_of_font ()
   sort_shift_bits[FONT_ADSTYLE_INDEX] = 28;
   sort_shift_bits[FONT_FOUNDRY_INDEX] = 29;
   sort_shift_bits[FONT_FAMILY_INDEX] = 30;
-  sort_shift_bits[FONT_REGISTRY_INDEX] = 31;
-  /* Note that sort_shift_bits[FONT_TYPE_INDEX] is never used.  */
+  /* Note that sort_shift_bits[FONT_SORT_TYPE] and
+     sort_shift_bits[FONT_SORT_REGISTRY] are never used.  */
 
   staticpro (&font_style_table);
   font_style_table = Fmake_vector (make_number (3), Qnil);
 
-  staticpro (&font_family_alist);
-  font_family_alist = Qnil;
-
   staticpro (&font_charset_alist);
   font_charset_alist = Qnil;
 
+  DEFSYM (Qfont_spec, "font-spec");
+  DEFSYM (Qfont_entity, "font-entity");
+  DEFSYM (Qfont_object, "font-object");
+
   DEFSYM (Qopentype, "opentype");
 
   DEFSYM (Qiso8859_1, "iso8859-1");
@@ -4159,7 +4329,7 @@ syms_of_font ()
   DEFSYM (Qunicode_sip, "unicode-sip");
 
   DEFSYM (QCotf, ":otf");
-  DEFSYM (QClanguage, ":language");
+  DEFSYM (QClang, ":lang");
   DEFSYM (QCscript, ":script");
   DEFSYM (QCantialias, ":antialias");
 
@@ -4169,15 +4339,15 @@ syms_of_font ()
   DEFSYM (QCspacing, ":spacing");
   DEFSYM (QCdpi, ":dpi");
   DEFSYM (QCscalable, ":scalable");
-  DEFSYM (QCextra, ":extra");
+  DEFSYM (QCavgwidth, ":avgwidth");
+  DEFSYM (QCfont_entity, ":font-entity");
+  DEFSYM (QCfc_unknown_spec, ":fc-unknown-spec");
 
   DEFSYM (Qc, "c");
   DEFSYM (Qm, "m");
   DEFSYM (Qp, "p");
   DEFSYM (Qd, "d");
 
-  staticpro (&null_string);
-  null_string = build_string ("");
   staticpro (&null_vector);
   null_vector = Fmake_vector (make_number (0), Qnil);
 
@@ -4196,7 +4366,7 @@ syms_of_font ()
   defsubr (&Sfont_get);
   defsubr (&Sfont_put);
   defsubr (&Slist_fonts);
-  defsubr (&Slist_families);
+  defsubr (&Sfont_family_list);
   defsubr (&Sfind_font);
   defsubr (&Sfont_xlfd_name);
   defsubr (&Sclear_font_cache);
@@ -4219,34 +4389,29 @@ syms_of_font ()
 #endif
 #endif /* FONT_DEBUG */
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
 #ifdef HAVE_FREETYPE
-      syms_of_ftfont ();
+  syms_of_ftfont ();
 #ifdef HAVE_X_WINDOWS
-      syms_of_xfont ();
-      syms_of_ftxfont ();
+  syms_of_xfont ();
+  syms_of_ftxfont ();
 #ifdef HAVE_XFT
-      syms_of_xftfont ();
+  syms_of_xftfont ();
 #endif  /* HAVE_XFT */
 #endif /* HAVE_X_WINDOWS */
 #else  /* not HAVE_FREETYPE */
 #ifdef HAVE_X_WINDOWS
-      syms_of_xfont ();
+  syms_of_xfont ();
 #endif /* HAVE_X_WINDOWS */
 #endif /* not HAVE_FREETYPE */
 #ifdef HAVE_BDFFONT
-      syms_of_bdffont ();
+  syms_of_bdffont ();
 #endif /* HAVE_BDFFONT */
 #ifdef WINDOWSNT
-      syms_of_w32font ();
+  syms_of_w32font ();
 #endif /* WINDOWSNT */
 #ifdef MAC_OS
-      syms_of_atmfont ();
+  syms_of_atmfont ();
 #endif /* MAC_OS */
-    }
-#endif /* USE_FONT_BACKEND */
 }
 
 /* arch-tag: 74c9475d-5976-4c93-a327-942ae3072846
index d93caef3deee093a8329291aaaa3d80476f2a116..ed688525d4c24d6d39ee97796171a6eac480d78d 100644 (file)
@@ -30,31 +30,32 @@ Boston, MA 02110-1301, USA.  */
 
    FONT-SPEC
 
-       Vector (length FONT_SPEC_MAX) of font properties.  Some
+       Pseudo vector (length FONT_SPEC_MAX) of font properties.  Some
        properties can be left unspecified (i.e. nil).  Emacs asks
        font-drivers to find a font by FONT-SPEC.  A fontset entry
        specifies requisite properties whereas a face specifies just
-       preferable properties.  This object is fully modifiable by
-       Lisp.
+       preferable properties.
 
    FONT-ENTITY
 
-       Vector (length FONT_ENTITY_MAX) of fully specified font
-       properties that a font-driver returns upon a request of
+       Pseudo vector (length FONT_ENTITY_MAX) of fully instanciated
+       font properties that a font-driver returns upon a request of
        FONT-SPEC.
 
-       Note: Only the method `list' of a font-driver can create this
-       object, and should never be modified by Lisp.  In that sense,
-       it may be cleaner to implement it as a Lisp object of a new
-       type (e.g. struct Lisp_Font).
+       Note: Only the method `list' and `match' of a font-driver can
+       create this object, and should never be modified by Lisp.
 
    FONT-OBJECT
 
-       Lisp object of type Lisp_Misc_Save_Value encapsulating a
-       pointer to "struct font".  This corresponds to an opened font.
+       Pseudo vector (length FONT_OBJECT_MAX) of a opend font.
 
-       Note: The note for FONT-ENTITY also applies to this.
-*/
+       Lisp object encapsulating "struct font".  This corresponds to
+       an opened font.
+
+       Note: Only the method `open' of a font-driver can create this
+       object, and should never be modified by Lisp.  */
+
+extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
 
 
 struct font_driver;
@@ -68,8 +69,8 @@ struct font;
 enum font_property_index
   {
     /* FONT-TYPE is a symbol indicating a font backend; currently `x',
-       `xft', `ftx', `freetype' are available on X and gdi on Windows.
-       For Windows, we `bdf' and `uniscribe' backends are in progress.
+       `xft', `ftx' are available on X and gdi on Windows.
+       For Windows, `bdf' and `uniscribe' backends are in progress.
        For Mac OS X, we need `atm'.  */
     FONT_TYPE_INDEX,
 
@@ -83,34 +84,78 @@ enum font_property_index
     FONT_ADSTYLE_INDEX,
 
     /* FONT-REGISTRY is a combination of a charset-registry and
-       charset0encoding name (symbol).  */
+       charset-encoding name (symbol).  */
     FONT_REGISTRY_INDEX,
 
     /* FONT-WEIGHT is a numeric value of weight (e.g. medium, bold) of
-       the font.  The value is what defined by FC_WEIGHT_* in
-       fontconfig. */
+       the font.  The lowest 8-bit is an index determining the
+       symbolic name, and the higher bits is the actual numeric value
+       defined in `font-weight-table'. */
     FONT_WEIGHT_INDEX,
 
     /* FONT-SLANT is a numeric value of slant (e.g. r, i, o) of the
-       font.  The value is what defined by FC_SLANT_* in
-       fontconfig plus 100. */
+       font.  The lowest 8-bit is an index determining the symbolic
+       name, and the higher bits is the actual numeric value defined
+       in `font-slant-table'.  */
     FONT_SLANT_INDEX,
 
-    /* FONT-WIDTH is a numeric value of setwidth (e.g. normal,
-       condensed) of the font.  The value is what defined by
-       FC_WIDTH_* in fontconfig. */
+    /* FONT-WIDTH is a numeric value of setwidth (e.g. normal) of the
+       font.  The lowest 8-bit is an index determining the symbolic
+       name, and the higher bits is the actual numeric value defined
+       `font-width-table'.  */
     FONT_WIDTH_INDEX,
 
     /* FONT-SIZE is a size of the font.  If integer, it is a pixel
        size.  For a font-spec, the value can be float specifying a
-       point size.  For a font-entity, the value can be zero meaning
-       that the font is scalable.  */
+       point size.  The value zero means that the font is
+       scalable.  */
     FONT_SIZE_INDEX,
 
+    /* FONT-DPI is a resolution (dot per inch) for which the font is
+       designed. */
+    FONT_DPI_INDEX,
+
+    /* FONT-SPACING is a spacing (mono, proportional, charcell) of the
+       font (integer; one of enum font_spacing).  */
+    FONT_SPACING_INDEX,
+
+    /* FONT-AVGWIDTH is an average width (1/10 pixel unit) of the
+       font.  */
+    FONT_AVGWIDTH_INDEX,
+
+#if 0
+    /* The following two members are to substitute for the above 6
+       members (FONT_WEIGHT_INDEX to FONT_AVGWIDTH_INDEX excluding
+       FONT_SIZE_INDEX) if it is found that font-entities consumes too
+       much memory.  */
+
+    /* FONT-STYLE is a 24-bit integer containing indices for
+       style-related properties WEIGHT, SLANT, and WIDTH.  The lowest
+       8-bit is an indice to the weight table AREF (font_style_table,
+       0), the next 8-bit is an indice to the slant table AREF
+       (font_style_table, 1), the highest 8-bit is an indice to the
+       slant table AREF (font_style_table, 2).  The indice 0 indicates
+       that the corresponding style is not specified.  This way, we
+       can represent at most 255 different names for each style, which
+       is surely sufficient.  */
+    FONT_STYLE_INDEX,
+
+    /* FONT-METRICS is a 27-bit integer containing metrics-related
+       properties DPI, AVGWIDTH, SPACING.  The lowest 12-bit is for
+       DPI, the next 12-bit is for AVGWIDTH, the highest 3-bit is for
+       SPACING.  In each bit field, the highest bit indicates that the
+       corresponding value is set or not.  This way, we can represent
+       DPI by 11-bit (0 to 2047), AVGWIDTH by 11-bit (0 to 2047),
+       SPACING by 3-bit (0 for proportional, 1 for dual, 2 for mono, 3
+       for charcell), which is surely sufficient.  */
+    FONT_METRICS_INDEX,
+#endif
+
     /* In a font-spec, the value is an alist of extra information of a
        font such as name, OpenType features, and language coverage.
-       In a font-entity, the value is an extra infomation for
-       identifying a font (font-driver dependent).  */
+       In addition, in a font-entity, the value may contain a pair
+       (font-entity . INFO) where INFO is an extra infomation to
+       identify a font (font-driver dependent).  */
     FONT_EXTRA_INDEX,          /* alist                alist */
 
     /* This value is the length of font-spec vector.  */
@@ -118,48 +163,229 @@ enum font_property_index
 
     /* The followings are used only for a font-entity.  */
 
-    /* Frame on which the font is found.  The value is nil if the font
-       can be opend on any frame.  */
-    FONT_FRAME_INDEX = FONT_SPEC_MAX,
-
-    /* List of font-objects opened from the font-entity.  The value is
-       nil if no font can be opened for this font-entity.  */
-    FONT_OBJLIST_INDEX,
+    /* List of font-objects opened from the font-entity.  */
+    FONT_OBJLIST_INDEX = FONT_SPEC_MAX,
 
     /* This value is the length of font-entity vector.  */
-    FONT_ENTITY_MAX
+    FONT_ENTITY_MAX,
+
+    /* XLFD name of the font (string). */
+    FONT_NAME_INDEX = FONT_ENTITY_MAX,
+    
+    /* Full name of the font (string).  It is the name extracted from
+       the opend font, and may be different from the above.  It may be
+       nil if the opened font doesn't give a name.  */
+    FONT_FULLNAME_INDEX,
+
+    /* File name of the font or nil if a file associated with the font
+       is not available.  */
+    FONT_FILE_INDEX,
+
+    /* Format of the font (symbol).  */
+    FONT_FORMAT_INDEX,
+
+    /* This value is the length of font-object vector.  */
+    FONT_OBJECT_MAX
   };
 
-extern Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClanguage, QCscript;
+/* Return the numeric weight value of FONT.  */
+#define FONT_WEIGHT_NUMERIC(font)              \
+  (INTEGERP (AREF ((font), FONT_WEIGHT_INDEX)) \
+   ? (XINT (AREF ((font), FONT_WEIGHT_INDEX)) >> 8) : -1)
+/* Return the numeric slant value of FONT.  */
+#define FONT_SLANT_NUMERIC(font)               \
+  (INTEGERP (AREF ((font), FONT_SLANT_INDEX))  \
+   ? (XINT (AREF ((font), FONT_SLANT_INDEX)) >> 8) : -1)
+/* Return the numeric width value of FONT.  */
+#define FONT_WIDTH_NUMERIC(font)               \
+  (INTEGERP (AREF ((font), FONT_WIDTH_INDEX))  \
+   ? (XINT (AREF ((font), FONT_WIDTH_INDEX)) >> 8) : -1)
+/* Return the symbolic weight value of FONT.  */
+#define FONT_WEIGHT_SYMBOLIC(font)     \
+  font_style_symbolic (font, FONT_WEIGHT_INDEX, 0)
+/* Return the symbolic slant value of FONT.  */
+#define FONT_SLANT_SYMBOLIC(font)      \
+  font_style_symbolic (font, FONT_SLANT_INDEX, 0)
+/* Return the symbolic width value of FONT.  */
+#define FONT_WIDTH_SYMBOLIC(font)      \
+  font_style_symbolic (font, FONT_WIDTH_INDEX, 0)
+/* Return the face-weight corresponding to the weight of FONT.  */
+#define FONT_WEIGHT_FOR_FACE(font)     \
+  font_style_symbolic (font, FONT_WEIGHT_INDEX, 1)
+/* Return the face-slant corresponding to the slant of FONT.  */
+#define FONT_SLANT_FOR_FACE(font)      \
+  font_style_symbolic (font, FONT_SLANT_INDEX, 1)
+/* Return the face-swidth corresponding to the slant of FONT.  */
+#define FONT_WIDTH_FOR_FACE(font)      \
+  font_style_symbolic (font, FONT_WIDTH_INDEX, 1)
+
+/* Return the numeric weight value corresponding ot the symbol NAME.  */
+#define FONT_WEIGHT_NAME_NUMERIC(name) \
+  (font_style_to_value (FONT_WEIGHT_INDEX, (name), 0) >> 8)
+/* Return the numeric slant value corresponding ot the symbol NAME.  */
+#define FONT_SLANT_NAME_NUMERIC(name)  \
+  (font_style_to_value (FONT_SLANT_INDEX, (name), 0) >> 8)
+/* Return the numeric width value corresponding ot the symbol NAME.  */
+#define FONT_WIDTH_NAME_NUMERIC(name)  \
+  (font_style_to_value (FONT_WIDTH_INDEX, (name), 0) >> 8)
+
+/* Set the font property PROP of FONT to VAL.  PROP is one of
+   style-related font property index (FONT_WEIGHT/SLANT/WIDTH_INDEX).
+   VAL (integer or symbol) is the numeric or symbolic style value.  */
+#define FONT_SET_STYLE(font, prop, val)        \
+  ASET ((font), prop, make_number (font_style_to_value (prop, val, 1)))
+
+extern Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript;
+extern Lisp_Object QCavgwidth, QCfont_entity, QCfc_unknown_spec;
 
 /* Important character set symbols.  */
 extern Lisp_Object Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip;
 
-extern Lisp_Object null_string;
-extern Lisp_Object null_vector;
+/* Structure for a font-spec.  */
+
+struct font_spec
+{
+  EMACS_UINT size;
+  struct Lisp_Vector *next;
+  Lisp_Object props[FONT_SPEC_MAX];
+};
 
-/* Structure for an opened font.  We can safely cast this structure to
-   "struct font_info".  */
+/* Structure for a font-entity.  */
+
+struct font_entity
+{
+  EMACS_UINT size;
+  struct Lisp_Vector *next;
+  Lisp_Object props[FONT_ENTITY_MAX];
+};
+
+/* A value which may appear in the member `encoding' of struct font
+   indicating that a font itself doesn't tell which encoding to be
+   used.  */
+#define FONT_ENCODING_NOT_DECIDED 255
+
+/* Structure for a font-object.  */
 
 struct font
 {
-  struct font_info font;
+  EMACS_UINT size;
+  struct Lisp_Vector *next;
+
+  /* All Lisp_Object components must come first.
+     That ensures they are all aligned normally.  */
+
+  Lisp_Object props[FONT_OBJECT_MAX];
+
+  /* Beyond here, there should be no more Lisp_Object components.  */
+
+#ifdef WINDOWSNT
+  /* Codepage of characters that will be displayed by the font.  */
+  int codepage;
+#endif
 
-  /* From which font-entity the font is opened.  */
-  Lisp_Object entity;
+  /* Maximum bound width over all existing characters of the font.  On
+     X window, this is same as (font->max_bounds.width).  */
+  int max_width;
 
   /* By which pixel size the font is opened.  */
   int pixel_size;
 
-  /* Font-driver for the font.  */
-  struct font_driver *driver;
+  /* Height of the font.  On X window, this is the same as
+     (font->ascent + font->descent).  */
+  int height;
+
+  /* Width of the space glyph of the font.  If the font doesn't have a
+     SPACE glyph, the value is 0.  */
+  int space_width;
+
+  /* Average width of glyphs in the font.  If the font itself doesn't
+     have that information but has glyphs of ASCII character, the
+     value is the average with of those glyphs.  Otherwise, the value
+     is 0.  */
+  int average_width;
+
+  /* Minimum glyph width (in pixels).  */
+  int min_width;
 
-  /* Symbol of font font; x, ttf, pcf, etc,   */
-  Lisp_Object format;
+  /* Ascent and descent of the font (in pixels).  */
+  int ascent, descent;
 
-  /* File name of the font, or NULL if the font is not associated with
-     a file.  */
-  char *file_name;
+  /* Vertical pixel width of the underline.  If is zero if that
+     information is not in the font.  */
+  int underline_thickness;
+
+  /* Vertical pixel position (relative to the baseline) of the
+     underline.  If it is positive, it is below the baseline.  It is
+     negative if that information is not in the font.  */
+  int underline_position;
+
+  /* 1 if `vertical-centering-font-regexp' matches this font name.
+     In this case, we render characters at vartical center positions
+     of lines.  */
+  int vertical_centering;
+
+  /* Encoding type of the font.  The value is one of
+     0, 1, 2, or 3:
+       0: code points 0x20..0x7F or 0x2020..0x7F7F are used
+       1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used
+       2: code points 0x20A0..0x7FFF are used
+       3: code points 0xA020..0xFF7F are used
+     If the member `font_encoder' is not NULL, this member is ignored.  */
+  unsigned char encoding_type;
+
+  /* The baseline position of a font is normally `ascent' value of the
+     font.  However, there exists many fonts which don't set `ascent'
+     an appropriate value to be used as baseline position.  This is
+     typical in such ASCII fonts which are designed to be used with
+     Chinese, Japanese, Korean characters.  When we use mixture of
+     such fonts and normal fonts (having correct `ascent' value), a
+     display line gets very ugly.  Since we have no way to fix it
+     automatically, it is users responsibility to supply well designed
+     fonts or correct `ascent' value of fonts.  But, the latter
+     requires heavy work (modifying all bitmap data in BDF files).
+     So, Emacs accepts a private font property
+     `_MULE_BASELINE_OFFSET'.  If a font has this property, we
+     calculate the baseline position by subtracting the value from
+     `ascent'.  In other words, the value indicates how many bits
+     higher we should draw a character of the font than normal ASCII
+     text for a better looking.
+
+     We also have to consider the fact that the concept of `baseline'
+     differs among scripts to which each character belongs.  For
+     instance, baseline should be at the bottom most position of all
+     glyphs for Chinese, Japanese, and Korean.  But, many of existing
+     fonts for those characters doesn't have correct `ascent' values
+     because they are designed to be used with ASCII fonts.  To
+     display characters of different language on the same line, the
+     best way will be to arrange them in the middle of the line.  So,
+     in such a case, again, we utilize the font property
+     `_MULE_BASELINE_OFFSET'.  If the value is larger than `ascent' we
+     calculate baseline so that a character is arranged in the middle
+     of a line.  */
+  int baseline_offset;
+
+  /* Non zero means a character should be composed at a position
+     relative to the height (or depth) of previous glyphs in the
+     following cases:
+       (1) The bottom of the character is higher than this value.  In
+       this case, the character is drawn above the previous glyphs.
+       (2) The top of the character is lower than 0 (i.e. baseline
+       height).  In this case, the character is drawn beneath the
+       previous glyphs.
+
+     This value is taken from a private font property
+     `_MULE_RELATIVE_COMPOSE' which is introduced by Emacs.  */
+  int relative_compose;
+
+  /* Non zero means an ascent value to be used for a character
+     registered in char-table `use-default-ascent'.  */
+  int default_ascent;
+
+  /* CCL program to calculate code points of the font.  */
+  struct ccl_program *font_encoder;
+
+  /* Font-driver for the font.  */
+  struct font_driver *driver;
 
   /* Charset to encode a character code into a glyph code of the font.
      -1 means that the font doesn't require this information to encode
@@ -171,15 +397,6 @@ struct font
      determine it.  */
   int repertory_charset;
 
-  /* Minimum glyph width (in pixels).  */
-  int min_width;
-
-  /* Ascent and descent of the font (in pixels).  */
-  int ascent, descent;
-
-  /* 1 iff the font is scalable.  */
-  int scalable;
-
   /* There will be more to this structure, but they are private to a
      font-driver.  */
 };
@@ -212,20 +429,23 @@ struct font_bitmap
 
 /* Predicates to check various font-related objects.  */
 
+/* 1 iff X is one of font-spec, font-entity, and font-object.  */
+#define FONTP(x) PSEUDOVECTORP (x, PVEC_FONT)
+/* 1 iff X is font-spec.  */
 #define FONT_SPEC_P(x) \
-  (VECTORP (x) && ASIZE (x) == FONT_SPEC_MAX)
+  (FONTP (x) && (ASIZE (x) & PSEUDOVECTOR_SIZE_MASK) == FONT_SPEC_MAX)
+/* 1 iff X is font-entity.  */
 #define FONT_ENTITY_P(x)       \
-  (VECTORP (x) && ASIZE (x) == FONT_ENTITY_MAX)
+  (FONTP (x) && (ASIZE (x) & PSEUDOVECTOR_SIZE_MASK) == FONT_ENTITY_MAX)
+/* 1 iff X is font-object.  */
 #define FONT_OBJECT_P(x)       \
-  (XTYPE (x) == Lisp_Misc && XMISCTYPE (x) == Lisp_Misc_Save_Value)
-#define FONTP(x)                                       \
-  ((VECTORP (x) && (ASIZE (x) == FONT_SPEC_MAX         \
-                   || ASIZE (x) == FONT_ENTITY_MAX))   \
-   || FONT_OBJECT_P (x))
+  (FONTP (x) && (ASIZE (x) & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX)
 
+/* 1 iff ENTITY can't be loaded.  */
 #define FONT_ENTITY_NOT_LOADABLE(entity)       \
   EQ (AREF (entity, FONT_OBJLIST_INDEX), Qt)
 
+/* Flag ENTITY not loadable.  */
 #define FONT_ENTITY_SET_NOT_LOADABLE(entity)   \
   ASET (entity, FONT_OBJLIST_INDEX, Qt)
 
@@ -235,19 +455,37 @@ struct font_bitmap
 #define CHECK_FONT(x)  \
   do { if (! FONTP (x)) wrong_type_argument (Qfont, x); } while (0)
 #define CHECK_FONT_SPEC(x)     \
-  do { if (! FONT_SPEC_P (x)) wrong_type_argument (Qfont, x); } while (0)
+  do { if (! FONT_SPEC_P (x)) wrong_type_argument (Qfont_spec, x); } while (0)
 #define CHECK_FONT_ENTITY(x)   \
-  do { if (! FONT_ENTITY_P (x)) wrong_type_argument (Qfont, x); } while (0)
+  do { if (! FONT_ENTITY_P (x)) wrong_type_argument (Qfont_entity, x); } while (0)
 #define CHECK_FONT_OBJECT(x)   \
-  do { if (! FONT_OBJECT_P (x)) wrong_type_argument (Qfont, x); } while (0)
+  do { if (! FONT_OBJECT_P (x)) wrong_type_argument (Qfont_object, x); } while (0)
 
-#define CHECK_FONT_GET_OBJECT(x, font)                                 \
-  do {                                                                 \
-    if (! FONT_OBJECT_P (x)) wrong_type_argument (Qfont, x);   \
-    if (! XSAVE_VALUE (x)->pointer) error ("Font already closed");     \
-    font = XSAVE_VALUE (x)->pointer;                                   \
+#define CHECK_FONT_GET_OBJECT(x, font) \
+  do {                                 \
+    CHECK_FONT_OBJECT (x);             \
+    font = XFONT_OBJECT (x);           \
   } while (0)
 
+#define XFONT_SPEC(p)  \
+  (eassert (FONT_SPEC_P(p)), (struct font_spec *) XPNTR (p))
+#define XFONT_ENTITY(p)        \
+  (eassert (FONT_ENTITY_P(p)), (struct font_entity *) XPNTR (p))
+#define XFONT_OBJECT(p)        \
+  (eassert (FONT_OBJECT_P(p)), (struct font *) XPNTR (p))
+#define XSETFONT(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_FONT))
+
+/* Number of pt per inch (from the TeXbook).  */
+#define PT_PER_INCH 72.27
+
+/* Return a pixel size (integer) corresponding to POINT size (double)
+   on resolution DPI.  */
+#define POINT_TO_PIXEL(POINT, DPI) ((POINT) * (DPI) / PT_PER_INCH + 0.5)
+
+/* Return a point size (double) corresponding to POINT size (integer)
+   on resolution DPI.  */
+#define PIXEL_TO_POINT(PIXEL, DPI) ((PIXEL) * PT_PER_INCH / (DPI) + 0.5)
+
 /* Ignore the difference of font pixel sizes less than or equal to
    this value.  */
 #define FONT_PIXEL_SIZE_QUANTUM 1
@@ -334,13 +572,19 @@ struct font_driver
   /* Symbol indicating the type of the font-driver.  */
   Lisp_Object type;
 
+  /* 1 iff the font's foundary, family, and adstyle names are case
+     sensitve.  */
+  int case_sensitive;
+
   /* Return a cache of font-entities on frame F.  The cache must be a
      cons whose cdr part is the actual cache area.  */
   Lisp_Object (*get_cache) P_ ((FRAME_PTR F));
 
   /* List fonts exactly matching with FONT_SPEC on FRAME.  The value
-     is a vector of font-entities.  This is the sole API that
-     allocates font-entities.  */
+     is a list of font-entities.  It is assured that the properties
+     WEIGHT to AVGWIDTH are all nil (i.e. not specified) in FONT_SPEC.
+     This and the following `match' are the only APIs that allocate
+     font-entities.  */
   Lisp_Object (*list) P_ ((Lisp_Object frame, Lisp_Object font_spec));
 
   /* Return a font entity most closely maching with FONT_SPEC on
@@ -359,8 +603,8 @@ struct font_driver
 
   /* Open a font specified by FONT_ENTITY on frame F.  If the font is
      scalable, open it with PIXEL_SIZE.  */
-  struct font *(*open) P_ ((FRAME_PTR f, Lisp_Object font_entity,
-                           int pixel_size));
+  Lisp_Object (*open) P_ ((FRAME_PTR f, Lisp_Object font_entity,
+                          int pixel_size));
 
   /* Close FONT on frame F.  */
   void (*close) P_ ((FRAME_PTR f, struct font *font));
@@ -477,6 +721,12 @@ struct font_driver
      than the length of LGSTRING, nil should be return.  In that case,
      this function is called again with the larger LGSTRING.  */
   Lisp_Object (*shape) P_ ((Lisp_Object lgstring));
+
+  /* Optional.
+
+     If FONT is usable on frame F, return 0.  Otherwise return -1.
+   */
+  int (*check) P_ ((FRAME_PTR F, struct font *font));
 };
 
 
@@ -509,49 +759,61 @@ struct font_data_list
   struct font_data_list *next;
 };
 
-extern int enable_font_backend;
-
 EXFUN (Ffont_spec, MANY);
+EXFUN (Fcopy_font_spec, 1);
+EXFUN (Fmerge_font_spec, 2);
 EXFUN (Ffont_get, 2);
 EXFUN (Flist_fonts, 4);
+EXFUN (Ffont_family_list, 1);
 EXFUN (Fclear_font_cache, 0);
 EXFUN (Ffont_xlfd_name, 1);
 
+extern Lisp_Object font_make_spec P_ ((void));
+extern Lisp_Object font_make_entity P_ ((void));
+extern Lisp_Object font_make_object P_ ((int));
+
 extern int font_registry_charsets P_ ((Lisp_Object, struct charset **,
                                       struct charset **));
-extern Lisp_Object font_symbolic_weight P_ ((Lisp_Object font));
-extern Lisp_Object font_symbolic_slant P_ ((Lisp_Object font));
-extern Lisp_Object font_symbolic_width P_ ((Lisp_Object font));
+extern int font_style_to_value P_ ((enum font_property_index prop,
+                                   Lisp_Object name, int noerror));
+extern Lisp_Object font_style_symbolic P_ ((Lisp_Object font,
+                                           enum font_property_index prop,
+                                           int for_face));
 
 extern int font_match_p P_ ((Lisp_Object spec, Lisp_Object entity));
+extern Lisp_Object font_list_entities P_ ((Lisp_Object frame,
+                                          Lisp_Object spec));
 
-extern Lisp_Object font_find_object P_ ((struct font *font));
 extern Lisp_Object font_get_name P_ ((Lisp_Object font_object));
-extern Lisp_Object font_get_spec P_ ((Lisp_Object font_object));
+extern Lisp_Object font_spec_from_name P_ ((Lisp_Object font_name));
 extern Lisp_Object font_get_frame P_ ((Lisp_Object font_object));
 extern int font_has_char P_ ((FRAME_PTR, Lisp_Object, int));
 extern unsigned font_encode_char P_ ((Lisp_Object, int));
 
-extern int font_set_lface_from_name P_ ((FRAME_PTR f,
-                                        Lisp_Object lface,
-                                        Lisp_Object fontname,
-                                        int force_p, int may_fail_p));
+extern void font_clear_prop P_ ((Lisp_Object *attrs,
+                                enum font_property_index prop));
+extern void font_update_lface P_ ((FRAME_PTR f, Lisp_Object *attrs));
 extern Lisp_Object font_find_for_lface P_ ((FRAME_PTR f, Lisp_Object *lface,
                                            Lisp_Object spec, int c));
 extern Lisp_Object font_open_for_lface P_ ((FRAME_PTR f, Lisp_Object entity,
                                            Lisp_Object *lface,
                                            Lisp_Object spec));
-extern void font_load_for_face P_ ((FRAME_PTR f, struct face *face));
+extern Lisp_Object font_load_for_lface P_ ((FRAME_PTR f, Lisp_Object *lface,
+                                           Lisp_Object spec));
 extern void font_prepare_for_face P_ ((FRAME_PTR f, struct face *face));
+extern void font_done_for_face P_ ((FRAME_PTR f, struct face *face));
+
 extern Lisp_Object font_open_by_name P_ ((FRAME_PTR f, char *name));
 extern void font_close_object (FRAME_PTR f, Lisp_Object font_object);
 
-extern Lisp_Object intern_downcase P_ ((char *str, int len));
+extern Lisp_Object font_intern_prop P_ ((char *str, int len));
 extern void font_update_sort_order P_ ((int *order));
 
-extern void font_merge_old_spec P_ ((Lisp_Object name, Lisp_Object family,
-                                    Lisp_Object registry, Lisp_Object spec));
-
+extern void font_parse_family_registry P_ ((Lisp_Object family,
+                                           Lisp_Object registry,
+                                           Lisp_Object spec));
+extern Lisp_Object font_spec_from_family_registry P_ ((Lisp_Object family,
+                                                      Lisp_Object registry));
 
 extern int font_parse_xlfd P_ ((char *name, Lisp_Object font));
 extern int font_unparse_xlfd P_ ((Lisp_Object font, int pixel_size,
@@ -564,6 +826,9 @@ extern void free_font_driver_list P_ ((FRAME_PTR f));
 extern Lisp_Object font_update_drivers P_ ((FRAME_PTR f, Lisp_Object list));
 extern Lisp_Object font_at P_ ((int c, EMACS_INT pos, struct face *face,
                                struct window *w, Lisp_Object object));
+extern EMACS_INT font_range P_ ((EMACS_INT pos, EMACS_INT limit,
+                                struct face *face, FRAME_PTR f,
+                                Lisp_Object object));
 
 extern struct font *font_prepare_composition P_ ((struct composition *cmp,
                                                  FRAME_PTR f));
index 48a32ea2dd5f296562a42f2e47dd8026182ef489..3625028a7da1a5cbb7d3a5e42df23a0dbff2e2dd 100644 (file)
@@ -26,7 +26,7 @@ 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.  */
 
-/* #define FONTSET_DEBUG */
+#define FONTSET_DEBUG
 
 #include <config.h>
 
@@ -94,36 +94,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-FAMILY
-        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
@@ -222,40 +202,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));
 
@@ -263,7 +209,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 void reorder_font_vector P_ ((Lisp_Object, int, 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));
@@ -299,6 +247,7 @@ 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]
@@ -314,6 +263,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
@@ -395,152 +376,89 @@ 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-CHARSET-ID PREFERRED-FAMILY
-        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.  */
+       [ 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.  */
+
+extern Lisp_Object Fassoc_string ();
 
 static void
-reorder_font_vector (font_group, charset_id, family)
+reorder_font_vector (font_group, preferred_family)
      Lisp_Object font_group;
-     int charset_id;
-     Lisp_Object family;
+     Lisp_Object preferred_family;
 {
-  Lisp_Object list, *new_vec;
   int size;
-  int *charset_id_table;
-  int i, idx;
-  Lisp_Object preferred_by_charset, preferred_by_family;
+  int i;
+  int score_changed = 0;
 
-  size = ASIZE (font_group) - 3;
+  size = ASIZE (font_group);
   /* Exclude the tailing nil elements from the reordering.  */
   while (NILP (AREF (font_group, size - 1))) size--;
-  charset_id_table = (int *) alloca (sizeof (int) * size);
-  new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size);
-
-  /* At first, extract ENCODING (a chaset ID) from RFONT_DEF which
-     has this form:
-       [FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]]
-     In addtion, if RFONT_DEF is preferred by family or charset, store
-     it from the start of new_vec.  */
-  for (i = 0, idx = 0; i < size; i++)
+  size -= 2;
+
+  for (i = 0; i < size; i++)
     {
-      Lisp_Object rfont_def = AREF (font_group, i + 3);
-      Lisp_Object font_spec = AREF (AREF (rfont_def, 2), 0);
-      Lisp_Object this_family = AREF (font_spec, FONT_FAMILY_INDEX);
-      int id = XINT (AREF (AREF (rfont_def, 2), 1));
-      struct charset *charset = CHARSET_FROM_ID (id);
-
-      charset_id_table[i] = -1;
-      if (! NILP (this_family)
-         && (fast_string_match_ignore_case (family, SYMBOL_NAME (this_family))
-             >= 0))
+      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;
+
+         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 (idx > 0)
-           memmove (new_vec + 1, new_vec, sizeof (Lisp_Object) * idx);
-         new_vec[0] = rfont_def;
-         idx++;
-         ASET (font_group, i + 3, Qnil);
+         if (fast_string_match_ignore_case (preferred_family,
+                                            SYMBOL_NAME (family)) < 0)
+           score |= 0x10000;
        }
-      else if (id == charset_id)
+      if (RFONT_DEF_SCORE (rfont_def) != score)
        {
-         new_vec[idx++] = rfont_def;
-         ASET (font_group, i + 3, Qnil);
+         RFONT_DEF_SET_SCORE (rfont_def, score);
+         score_changed = 1;
        }
-      else if (! charset->supplementary_p)
-       charset_id_table[i] = id;
     }
 
-  if (idx == 0
-      && (XINT (AREF (font_group, 0)) == charset_ordered_list_tick))
-    /* No need of reordering.  */
-    return;
+  if (score_changed)
+    qsort (XVECTOR (font_group)->contents + 2, size, sizeof (Lisp_Object),
+          fontset_compare_rfontdef);
 
   ASET (font_group, 0, make_number (charset_ordered_list_tick));
-  ASET (font_group, 1, make_number (charset_id));
-  ASET (font_group, 2, family);
-
-  /* Then, store the remaining RFONT-DEFs in NEW_VEC in the correct
-     order.  */
-  for (list = Vcharset_ordered_list; idx < size; list = XCDR (list))
-    {
-      int id = XINT (XCAR (list));
-      struct charset *charset = CHARSET_FROM_ID (id);
-
-      if (charset->supplementary_p)
-       break;
-      for (i = 0; i < size; i++)
-       if (charset_id_table[i] == XINT (XCAR (list))
-           && ! NILP (AREF (font_group, i + 3)))
-         {
-           new_vec[idx++] = AREF (font_group, i + 3);
-           ASET (font_group, i + 3, Qnil);
-         }
-    }
-  for (i = 0; i < size; i++)
-    if (! NILP (AREF (font_group, i + 3)))
-      new_vec[idx++] = AREF (font_group, i + 3);
-
-  /* At last, update elements of FONT-GROUP.  */
-  for (i = 0; i < size; i++)
-    ASET (font_group, i + 3, new_vec[i]);
-}
-
-
-/* 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.  */
-
-extern Lisp_Object QCname;
-
-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;
-  Lisp_Object font_spec, name;
-
-  font_spec = AREF (font_def, 0);
-  name = Ffont_get (font_spec, QCname);
-  if (! NILP (name))
-    font_name = choose_face_font (f, face->lface, name, NULL);
-  else
-    font_name = choose_face_font (f, face->lface, font_spec, 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;
 }
 
-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 no font is found, return Qnil if there's a
    possibility that the default fontset or the fallback font groups
@@ -561,9 +479,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);
@@ -600,22 +517,20 @@ fontset_find_font (fontset, c, face, id, fallback)
        }
       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].  */
+         /* 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;
 
-         vec = Fmake_vector (make_number (size + 3), Qnil);
+         vec = Fmake_vector (make_number (size + 2), Qnil);
          ASET (vec, 0, make_number (-1));
-         ASET (vec, 1, make_number (-1));
          for (i = j = 0; i < size; i++)
            if (! NILP (AREF (elt, i)))
              {
-               Lisp_Object tmp;
-               tmp = Fmake_vector (make_number (5), Qnil);
-               ASET (tmp, 2, AREF (elt, i));
-               ASET (vec, j + 3, tmp);
+               Lisp_Object rfont_def;
+
+               RFONT_DEF_NEW (rfont_def, AREF (elt, i));
+               ASET (vec, j + 2, rfont_def);
                j++;
              }
        }
@@ -629,150 +544,128 @@ fontset_find_font (fontset, c, face, id, fallback)
   if (! VECTORP (vec))
     return (EQ (vec, Qt) ? Qt : Qnil);
 
-  if (ASIZE (vec) > 4
-      && (XINT (AREF (vec, 0)) != charset_ordered_list_tick
-         || (id >= 0 && XINT (AREF (vec, 1)) != id)
-         || NILP (Fequal (AREF (vec, 2), face->lface[LFACE_FAMILY_INDEX]))))
+  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,
-       or the preferred charset was changed,
-       or the preferred family was changed.  */
-    reorder_font_vector (vec, id, face->lface[LFACE_FAMILY_INDEX]);
+       or the charset priorities were changed.  */
+    reorder_font_vector (vec, face->lface[LFACE_FAMILY_INDEX]);
+  i = 2;
+  if (id >= 0)
+    {
+      elt = AREF (vec, 1);
+      if (! NILP (elt)
+         && EQ (make_number (id), RFONT_DEF_REPERTORY (elt)))
+       i = 1;
+      else
+       {
+         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, 1, elt);
+             i = 1;
+           }
+         else
+           {
+             ASET (vec, 1, Qnil);
+             i = 2;
+           }
+       }
+    }
 
   /* Find the first available font in the vector of RFONT-DEF.  */
-  for (i = 3; i < ASIZE (vec); i++)
+  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;
-      /* ELT == [ FACE-ID FONT-INDEX FONT-DEF ... ] */
-      if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0)
+      if (id >= 0 && i > 1 && EQ (AREF (vec, 1), elt))
+       /* This is already checked.  */
+       continue;
+      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-ENTITY ]
-            where FONT-ENTITY turns to a font-object once opened.  */
-         Lisp_Object font_entity = AREF (elt, 3);
-         int has_char = 0;
+         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_entity = font_find_for_lface (f, face->lface,
-                                                AREF (font_def, 0), -1);
-             if (NILP (font_entity))
-               {
-                 ASET (elt, 1, make_number (-1));
-                 continue;
-               }
-             ASET (elt, 3, font_entity);
+             /* Record that no font matches the spec.  */
+             RFONT_DEF_SET_FACE (elt, -1);
+             continue;
            }
-         else if (FONT_ENTITY_P (font_entity))
+         font_object = font_open_for_lface (f, font_entity, face->lface, Qnil);
+         if (NILP (font_object))
            {
-             if (FONT_ENTITY_NOT_LOADABLE (font_entity))
-               continue;
+             /* Record that the font is unsable.  */
+             RFONT_DEF_SET_FACE (elt, -1);
+             continue;
            }
-         has_char = font_has_char (f, font_entity, c);
-         if (! has_char)
-           continue;
-         if (! FONT_OBJECT_P (font_entity))
-           {
-             Lisp_Object font_object
-               = font_open_for_lface (f, font_entity, face->lface, Qnil);
-
-             if (NILP (font_object))
-               {
-                 FONT_ENTITY_SET_NOT_LOADABLE (font_entity);
-                 continue;
-               }
-             FONTSET_OBJLIST (fontset)
-               = Fcons (font_object, FONTSET_OBJLIST (fontset));
-             ASET (elt, 3, font_object);
-             if (has_char < 0)
-               {
-                 has_char = font_has_char (f, font_object, c);
-                 if (! has_char)
-                   continue;
-               }
-           }
-         /* Decide to use this font.  */
-         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 expecially 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;
 
-      /* 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));
+         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;
        }
-      return elt;
+      i--;
+#endif /* 0 */
     }
 
+  FONTSET_SET (fontset, make_number (c), make_number (0));
   return Qnil;
 }
 
@@ -803,9 +696,6 @@ fontset_font (fontset, c, face, id)
       rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 0);
       if (VECTORP (rfont_def))
        return (rfont_def);
-      if (! NILP (rfont_def))
-       /* Remeber that we have no font for C.  */
-       FONTSET_SET (fontset, make_number (c), Qt);
     }
 
   /* Try a fallback font-group. */
@@ -906,12 +796,8 @@ 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;
 }
 
@@ -920,7 +806,6 @@ free_realized_fontset (f, fontset)
      FRAME_PTR f;
      Lisp_Object fontset;
 {
-  int i;
   Lisp_Object tail;
 
   return;
@@ -942,7 +827,9 @@ free_face_fontset (f, face)
   Lisp_Object fontset;
 
   fontset = FONTSET_FROM_ID (face->fontset);
-  xassert (!NILP (fontset) && ! BASE_FONTSET_P (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);
@@ -960,6 +847,7 @@ free_face_fontset (f, face)
       if (id < next_fontset_id)
        next_fontset_id = face->fontset;
     }
+  face->fontset = -1;
 }
 
 
@@ -977,8 +865,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)));
 }
 
 
@@ -993,7 +881,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;
 
@@ -1007,6 +895,8 @@ 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;
@@ -1023,34 +913,29 @@ face_for_char (f, face, c, pos, object)
   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 (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;
 }
 
 
@@ -1083,75 +968,11 @@ make_fontset_for_ascii_face (f, base_fontset_id, face)
   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;
@@ -1288,8 +1109,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;
@@ -1466,7 +1287,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);
@@ -1537,9 +1358,10 @@ 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.
 
@@ -1555,7 +1377,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;
 
@@ -1566,51 +1387,37 @@ 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));
-    }
-  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 if (STRINGP (font_spec))
     {
       Lisp_Object args[2];
+      extern Lisp_Object QCname;
 
       args[0] = QCname;
       args[1] = font_spec;
       font_spec = Ffont_spec (2, args);
     }
-  else if (! NILP (font_spec))
-    wrong_type_argument (intern ("font-spec"), font_spec);
+  else if (! NILP (font_spec) && ! FONT_SPEC_P (font_spec))
+    Fsignal (Qfont, list2 (build_string ("Invalid font-spec"), font_spec));
 
   if (! NILP (font_spec))
     {
+      Lisp_Object encoding, repertory;
+
       family = AREF (font_spec, FONT_FAMILY_INDEX);
-      if (! NILP (family) && SYMBOLP (family))
+      if (! NILP (family) )
        family = SYMBOL_NAME (family);
       registry = AREF (font_spec, FONT_REGISTRY_INDEX);
-      if (! NILP (registry) && SYMBOLP (registry))
-       registry = SYMBOL_NAME (registry);
-
-      encoding = find_font_encoding (concat2 (family, registry));
+      if (! NILP (registry))
+       registry = Fdowncase (SYMBOL_NAME (registry));
+      encoding = find_font_encoding (concat3 (family, build_string ("-"),
+                                             registry));
       if (NILP (encoding))
        encoding = Qascii;
 
@@ -1631,9 +1438,7 @@ appended.  By default, FONT-SPEC overrides the previous settings.  */)
              repertory = CHARSET_SYMBOL_ID (repertory);
            }
        }
-      font_def = Fmake_vector (make_number (3), font_spec);
-      ASET (font_def, 1, encoding);
-      ASET (font_def, 2, repertory);
+      FONT_DEF_NEW (font_def, font_spec, encoding, repertory);
     }
   else
     font_def = Qnil;
@@ -1748,23 +1553,28 @@ 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;
+      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);
+      xlfd = alloca (SBYTES (name) + 1);
+      len = font_unparse_xlfd (font_spec, 0, xlfd, SBYTES (name) + 1);
+      FONTSET_ASCII (fontset) = make_unibyte_string (xlfd, len);
     }
   else
     {
@@ -1791,141 +1601,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);
-  XSETCDR (font_spec, build_string ("iso10646-1"));
-  Fset_fontset_font (name, Qlatin, font_spec, Qnil, Qappend);
+  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.
@@ -1944,7 +1668,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;
 
@@ -1957,38 +1681,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 (enable_font_backend && ! 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;
 }
 
@@ -2030,7 +1737,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
   int c;
   struct frame *f;
   struct face *face;
-  Lisp_Object charset, rfont_def;
+  Lisp_Object rfont_def;
   int cs_id;
 
   if (NILP (position))
@@ -2075,48 +1782,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 (face->font)
     {
-      if (VECTORP (rfont_def) && ! NILP (AREF (rfont_def, 3)))
-       {
-         Lisp_Object font_object = 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);
-         /* 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;
-    }
-#endif /* USE_FONT_BACKEND */
-  if (VECTORP (rfont_def) && STRINGP (AREF (rfont_def, 3)))
-    {
-      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;
 }
@@ -2211,12 +1891,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++)
-               {
-                 if (NILP (AREF (val, i)))
-                   alist = Fcons (Qnil, alist);
-                 else
-                   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.  */
@@ -2228,61 +1905,20 @@ fontset.  The format is the same as abobe.  */)
                    val = FONTSET_FALLBACK (realized[k][i]);
                  if (! VECTORP (val))
                    continue;
-#ifdef USE_FONT_BACKEND
-                 /* VAL: [int int ?
-                          [FACE-ID FONT-INDEX FONT-DEF FONT-ENTITY/OBJECT]
-                          ...]  */
-                 if (enable_font_backend)
-                   for (j = 3; j < ASIZE (val); j++)
-                     {
-                       elt = AREF (val, j);
-                       if (INTEGERP (AREF (elt, 1))
-                           && XINT (AREF (elt, 1)) >= 0)
-                         {
-                           Lisp_Object font_object = AREF (elt, 3);
-
-                           if (FONT_OBJECT_P (font_object))
-                             {
-                               struct font *font
-                                 = XSAVE_VALUE (font_object)->pointer;
-                               char *name = font->font.full_name;
-                               int len = strlen (name);
-                               Lisp_Object slot;
-
-                               slot = Fassq (AREF (AREF (elt, 2), 0), alist);
-                               nconc2 (slot,
-                                       Fcons (make_unibyte_string (name, len),
-                                              Qnil));
-                             }
-                         }
-                     }
-                 else
-#endif  /* not USE_FONT_BACKEND */
+                 /* VAL: [int ? [FACE-ID FONT-DEF FONT-OBJECT int] ... ]  */
+                 for (j = 2; j < ASIZE (val); j++)
                    {
-                     /* 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));
-                         }
-                     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));
-                         }
+                     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));
+                       }
                    }
                }
 
@@ -2291,6 +1927,13 @@ fontset.  The format is the same as abobe.  */)
                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;
        }
@@ -2431,10 +2074,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");
index c850ca3c9d8c8a979475984085ec33f1539726bd..8d84a7828d24956b1e494e6d8d6aab668f1efd2d 100644 (file)
@@ -29,173 +29,6 @@ Boston, MA 02110-1301, USA.  */
 #ifndef EMACS_FONTSET_H
 #define EMACS_FONTSET_H
 
-/* This data type is used for the font_table field of window system
-   depending data area (e.g. struct x_display_info on X window).  */
-
-struct font_info
-{
-  /* Pointer to window system dependent font structure.  On X window,
-     this value should be coerced to (XFontStruct *).  */
-  void *font;
-
-  /* Index number of the font.  */
-  int font_idx;
-
-  /* Name to be used to find the font.  */
-  char *name;
-
-  /* Full name of the font given by a window system.  */
-  char *full_name;
-
-  /* Charset to encode a character code into a glyph code of the
-     font.  */
-  int charset;
-
-#ifdef WINDOWSNT
-  /* Codepage of characters that will be displayed by the font.  */
-  int codepage;
-#endif
-
-  /* Maximum bound width over all existing characters of the font.  On
-     X window, this is same as (font->max_bounds.width) */
-  int size;
-
-  /* Height of the font.  On X window, this is the same as
-     (font->ascent + font->descent).  */
-  int height;
-
-  /* Width of the space glyph of the font.  */
-  int space_width;
-
-  /* Average width of glyphs in the font.  */
-  int average_width;
-
-  /* 1 if `vertical-centering-font-regexp' matches this font name.
-     In this case, we render characters at vartical center positions
-     of lines.  */
-  int vertical_centering;
-
-  /* Encoding type of the font.  The value is one of
-     0, 1, 2, or 3:
-       0: code points 0x20..0x7F or 0x2020..0x7F7F are used
-       1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used
-       2: code points 0x20A0..0x7FFF are used
-       3: code points 0xA020..0xFF7F are used
-     If the member `font_encoder' is not NULL, this member is ignored.
-  */
-  unsigned char encoding_type;
-
-  /* The baseline position of a font is normally `ascent' value of the
-     font.  However, there exists many fonts which don't set `ascent'
-     an appropriate value to be used as baseline position.  This is
-     typical in such ASCII fonts which are designed to be used with
-     Chinese, Japanese, Korean characters.  When we use mixture of
-     such fonts and normal fonts (having correct `ascent' value), a
-     display line gets very ugly.  Since we have no way to fix it
-     automatically, it is users responsibility to supply well designed
-     fonts or correct `ascent' value of fonts.  But, the latter
-     requires heavy work (modifying all bitmap data in BDF files).
-     So, Emacs accepts a private font property
-     `_MULE_BASELINE_OFFSET'.  If a font has this property, we
-     calculate the baseline position by subtracting the value from
-     `ascent'.  In other words, the value indicates how many bits
-     higher we should draw a character of the font than normal ASCII
-     text for a better looking.
-
-     We also have to consider the fact that the concept of `baseline'
-     differs among languages to which each character belongs.  For
-     instance, baseline should be at the bottom most position of all
-     glyphs for Chinese, Japanese, and Korean.  But, many of existing
-     fonts for those characters doesn't have correct `ascent' values
-     because they are designed to be used with ASCII fonts.  To
-     display characters of different language on the same line, the
-     best way will be to arrange them in the middle of the line.  So,
-     in such a case, again, we utilize the font property
-     `_MULE_BASELINE_OFFSET'.  If the value is larger than `ascent' we
-     calculate baseline so that a character is arranged in the middle
-     of a line.  */
-
-  int baseline_offset;
-
-  /* Non zero means a character should be composed at a position
-     relative to the height (or depth) of previous glyphs in the
-     following cases:
-       (1) The bottom of the character is higher than this value.  In
-       this case, the character is drawn above the previous glyphs.
-       (2) The top of the character is lower than 0 (i.e. baseline
-       height).  In this case, the character is drawn beneath the
-       previous glyphs.
-
-     This value is taken from a private font property
-     `_MULE_RELATIVE_COMPOSE' which is introduced by Emacs.  */
-  int relative_compose;
-
-  /* Non zero means an ascent value to be used for a character
-     registered in char-table `use-default-ascent'.  */
-  int default_ascent;
-
-  /* CCL program to calculate code points of the font.  */
-  struct ccl_program *font_encoder;
-};
-
-/* A value which may appear in the member `encoding' of struch
-   font_info indicating that a font itself doesn't tell which encoding
-   to be used.  */
-#define FONT_ENCODING_NOT_DECIDED 255
-
-enum FONT_SPEC_INDEX
-  {
-    FONT_SPEC_FAMILY_INDEX,
-    FONT_SPEC_WEIGHT_INDEX,
-    FONT_SPEC_SLANT_INDEX,
-    FONT_SPEC_SWIDTH_INDEX,
-    FONT_SPEC_ADSTYLE_INDEX,
-    FONT_SPEC_REGISTRY_INDEX,
-    FONT_SPEC_MAX_INDEX
-  };
-
-/* Forward declaration for prototypes.  */
-struct frame;
-
-/* The following six are window system dependent functions.
-   Initialization routine of each window system should set appropriate
-   functions to these variables.  For instance, in case of X window,
-   x_term_init does this.  */
-
-/* Return a pointer to struct font_info of font FONT_IDX of frame F.  */
-extern struct font_info *(*get_font_info_func) P_ ((struct frame *f,
-                                                   int font_idx));
-
-/* Return a list of font names which matches PATTERN.  See the document of
-   `x-list-fonts' for more detail.  */
-extern 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 -1.  */
-extern struct font_info *(*load_font_func) P_ ((struct frame *f,
-                                               char *name, int));
-
-/* Return a pointer to struct font_info of a font named NAME for frame F.
-   If no such font is loaded, return NULL.  */
-extern struct font_info *(*query_font_func) P_ ((struct frame *f, char *name));
-
-/* Additional function for setting fontset or changing fontset
-   contents of frame F.  This function may change the coordinate of
-   the frame.  */
-extern void (*set_frame_fontset_func) P_ ((struct frame *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 memer `encoder' of the structure.  */
-extern void (*find_ccl_program_func) P_ ((struct font_info *));
-
-extern Lisp_Object (*get_font_repertory_func) P_ ((struct frame *,
-                                                  struct font_info *));
-
 /* Check if any window system is used now.  */
 extern void (*check_window_system_func) P_ ((void));
 
@@ -207,9 +40,8 @@ extern int face_suitable_for_char_p P_ ((struct face *, int));
 extern int face_for_char P_ ((FRAME_PTR, struct face *, int,
                              int, Lisp_Object));
 extern int make_fontset_for_ascii_face P_ ((FRAME_PTR, int, struct face *));
-extern int new_fontset_from_font_name P_ ((Lisp_Object));
+extern int fontset_from_font_name P_ ((Lisp_Object));
 extern void set_default_ascii_font P_ ((Lisp_Object));
-extern struct font_info *fs_load_font P_ ((struct frame *, char *, int));
 extern int fs_query_fontset P_ ((Lisp_Object, int));
 EXFUN (Fquery_fontset, 2);
 extern Lisp_Object list_fontsets P_ ((struct frame *, Lisp_Object, int));
@@ -221,49 +53,13 @@ extern Lisp_Object Vfontset_alias_alist;
 extern Lisp_Object Vvertical_centering_font_regexp;
 extern Lisp_Object Votf_script_alist;
 
-/* Load a font named FONTNAME on frame F.  All fonts for frame F is
-   stored in a table pointed by FONT_TABLE.  Return a pointer to the
-   struct font_info of the loaded font.  If loading fails, return
-   NULL.  */
-
-#define FS_LOAD_FONT(f, fontname) fs_load_font (f, fontname, -1)
-
-
-/* Return an immutable id for font_info FONT_INFO on frame F.  The
-   reason for this macro is hat one cannot hold pointers to font_info
-   structures in other data structures, because the table is
-   reallocated in x_list_fonts.  */
-
-#define FONT_INFO_ID(F, FONT_INFO) \
-     (FONT_INFO) - (FRAME_X_DISPLAY_INFO ((F))->font_table)
-
-/* Given a font_info id ID, return a pointer to the font_info
-   structure on frame F.  If ID is invalid, return null.  */
-
-#define FONT_INFO_FROM_ID(F, ID)                                       \
-     (((ID) >= 0 && (ID) < FRAME_X_DISPLAY_INFO ((F))->font_table_size)        \
-      ? (FRAME_X_DISPLAY_INFO ((F))->font_table + (ID))                        \
-      : 0)
-
-#ifdef USE_FONT_BACKEND
-#define FONT_INFO_FROM_FACE(F, FACE)           \
-  (enable_font_backend ? (FACE)->font_info     \
-   : FONT_INFO_FROM_ID ((F), (FACE)->font_info_id))
-#else  /* not USE_FONT_BACKEND */
-#define FONT_INFO_FROM_FACE(F, FACE)   \
-  FONT_INFO_FROM_ID ((F), (FACE)->font_info_id)
-#endif /* not USE_FONT_BACKEND */
-
 extern Lisp_Object fontset_name P_ ((int));
 extern Lisp_Object fontset_ascii P_ ((int));
 extern int fontset_height P_ ((int));
 
-#ifdef USE_FONT_BACKEND
 struct font;
-extern int face_for_font P_ ((struct frame *, struct font *, struct face *));
+extern int face_for_font P_ ((struct frame *, Lisp_Object, struct face *));
 extern int new_fontset_from_font P_ ((Lisp_Object));
-extern struct font *fontset_ascii_font P_ ((FRAME_PTR, int));
-#endif /* USE_FONT_BACKEND */
 
 #endif /* EMACS_FONTSET_H */
 
index 188e1d18717f58d64d525f5cc552d7fb03ea5e13..1309ad59a32a98653bbdb5c54fc09dc9249c9bbb 100644 (file)
@@ -38,14 +38,15 @@ Boston, MA 02110-1301, USA.  */
 #include "commands.h"
 #include "keyboard.h"
 #include "frame.h"
-#ifdef HAVE_WINDOW_SYSTEM
-#include "fontset.h"
-#endif
 #include "blockinput.h"
 #include "termchar.h"
 #include "termhooks.h"
 #include "dispextern.h"
 #include "window.h"
+#ifdef HAVE_WINDOW_SYSTEM
+#include "font.h"
+#include "fontset.h"
+#endif
 #ifdef MSDOS
 #include "msdos.h"
 #include "dosfns.h"
@@ -54,10 +55,6 @@ Boston, MA 02110-1301, USA.  */
 
 #ifdef HAVE_WINDOW_SYSTEM
 
-#ifdef USE_FONT_BACKEND
-#include "font.h"
-#endif /* USE_FONT_BACKEND */
-
 /* The name we're using in resource queries.  Most often "emacs".  */
 
 Lisp_Object Vx_resource_name;
@@ -117,9 +114,7 @@ Lisp_Object Qtty_color_mode;
 Lisp_Object Qtty, Qtty_type;
 
 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
-#ifdef USE_FONT_BACKEND
 Lisp_Object Qfont_backend;
-#endif /* USE_FONT_BACKEND */
 
 Lisp_Object Qinhibit_face_set_after_frame_default;
 Lisp_Object Qface_set_after_frame_default;
@@ -334,10 +329,8 @@ make_frame (mini_p)
 #endif
   f->size_hint_flags = 0;
   f->win_gravity = 0;
-#ifdef USE_FONT_BACKEND
   f->font_driver_list = NULL;
   f->font_data_list = NULL;
-#endif /* USE_FONT_BACKEND */
 
   root_window = make_window ();
   if (mini_p)
@@ -1468,10 +1461,8 @@ But FORCE inhibits this too.  */)
      memory. */
   free_glyphs (f);
 
-#ifdef USE_FONT_BACKEND
   /* Give chance to each font driver to free a frame specific data.  */
   font_update_drivers (f, Qnil);
-#endif /* USE_FONT_BACKEND */
 
   /* Mark all the windows that used to be on FRAME as deleted, and then
      remove the reference to them.  */
@@ -2835,9 +2826,7 @@ static struct frame_parm_table frame_parms[] =
   {"right-fringe",             &Qright_fringe},
   {"wait-for-wm",              &Qwait_for_wm},
   {"fullscreen",                &Qfullscreen},
-#ifdef USE_FONT_BACKEND
   {"font-backend",             &Qfont_backend}
-#endif /* USE_FONT_BACKEND */
 };
 
 #ifdef HAVE_WINDOW_SYSTEM
@@ -3347,89 +3336,56 @@ x_set_font (f, arg, oldval)
      struct frame *f;
      Lisp_Object arg, oldval;
 {
-  Lisp_Object result;
-  Lisp_Object fontset_name;
   Lisp_Object frame;
-  int old_fontset = FRAME_FONTSET(f);
+  int fontset = -1;
+  Lisp_Object font_object;
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      int fontset = -1;
-      Lisp_Object font_object;
+  /* Set the frame parameter back to the old value because we mail
+     fail to use ARG as the new parameter value.  */
+  store_frame_param (f, Qfont, oldval);
 
-      /* ARG is a fontset name, a font name, or a font object.
-        In the last case, this function never fail.  */
-      if (STRINGP (arg))
+  /* ARG is a fontset name, a font name, or a font object.
+     In the last case, this function never fail.  */
+  if (STRINGP (arg))
+    {
+      fontset = fs_query_fontset (arg, 0);
+      if (fontset < 0)
        {
-         fontset = fs_query_fontset (arg, 0);
-         if (fontset < 0)
-           font_object = font_open_by_name (f, SDATA (arg));
-         else if (fontset > 0)
-           {
-             Lisp_Object ascii_font = fontset_ascii (fontset);
-
-             font_object = font_open_by_name (f, SDATA (ascii_font));
-           }
+         font_object = font_open_by_name (f, SDATA (arg));
+         if (NILP (font_object))
+           error ("Font `%s' is not defined", SDATA (arg));
+         arg = AREF (font_object, FONT_NAME_INDEX);
        }
-      else
-       font_object = arg;
-
-      if (fontset < 0 && ! NILP (font_object))
-       fontset = new_fontset_from_font (font_object);
+      else if (fontset > 0)
+       {
+         Lisp_Object ascii_font = fontset_ascii (fontset);
 
-      if (fontset == 0)
-       /* Refuse the default fontset.  */
-       result = Qt;
-      else if (NILP (font_object))
-       result = Qnil;
+         font_object = font_open_by_name (f, SDATA (ascii_font));
+         if (NILP (font_object))
+           error ("Font `%s' is not defined", SDATA (arg));
+         arg = fontset_name (fontset);
+       }
       else
-       result = x_new_fontset2 (f, fontset, font_object);
+       error ("The default fontset can't be used for a frame font");
     }
-  else
+  else if (FONT_OBJECT_P (arg))
     {
-#endif /* USE_FONT_BACKEND */
-  CHECK_STRING (arg);
-
-  fontset_name = Fquery_fontset (arg, Qnil);
-
-  BLOCK_INPUT;
-  result = (STRINGP (fontset_name)
-            ? x_new_fontset (f, fontset_name)
-            : x_new_fontset (f, arg));
-  UNBLOCK_INPUT;
-#ifdef USE_FONT_BACKEND
+      font_object = arg;
+      arg = AREF (font_object, FONT_NAME_INDEX);
     }
-#endif
-
-  if (EQ (result, Qnil))
-    error ("Font `%s' is not defined", SDATA (arg));
-  else if (EQ (result, Qt))
-    error ("The default fontset can't be used for a frame font");
-  else if (STRINGP (result))
-    {
-      set_default_ascii_font (result);
-      if (STRINGP (fontset_name))
-       {
-         /* Fontset names are built from ASCII font names, so the
-            names may be equal despite there was a change.  */
-         if (old_fontset == FRAME_FONTSET (f))
-           return;
-       }
-      store_frame_param (f, Qfont, result);
-
-      if (!NILP (Fequal (result, oldval)))
-        return;
+  else
+    signal_error ("Invalid font", arg);
 
-      /* Recalculate toolbar height.  */
-      f->n_tool_bar_rows = 0;
-      /* Ensure we redraw it.  */
-      clear_current_matrices (f);
+  if (! NILP (Fequal (font_object, oldval)))
+    return;
+  x_new_font (f, font_object, fontset);
+  store_frame_param (f, Qfont, arg);
+  /* Recalculate toolbar height.  */
+  f->n_tool_bar_rows = 0;
+  /* Ensure we redraw it.  */
+  clear_current_matrices (f);
 
-      recompute_basic_faces (f);
-    }
-  else
-    abort ();
+  recompute_basic_faces (f);
 
   do_pending_window_change (0);
 
@@ -3446,7 +3402,6 @@ x_set_font (f, arg, oldval)
 }
 
 
-#ifdef USE_FONT_BACKEND
 void
 x_set_font_backend (f, new_value, old_value)
      struct frame *f;
@@ -3476,7 +3431,7 @@ x_set_font_backend (f, new_value, old_value)
   if (! NILP (old_value) && ! NILP (Fequal (old_value, new_value)))
     return;
 
-  if (FRAME_FONT_OBJECT (f))
+  if (FRAME_FONT (f))
     free_all_realized_faces (Qnil);
 
   new_value = font_update_drivers (f, NILP (new_value) ? Qt : new_value);
@@ -3489,7 +3444,7 @@ x_set_font_backend (f, new_value, old_value)
     }
   store_frame_param (f, Qfont_backend, new_value);
 
-  if (FRAME_FONT_OBJECT (f))
+  if (FRAME_FONT (f))
     {
       Lisp_Object frame;
 
@@ -3499,7 +3454,6 @@ x_set_font_backend (f, new_value, old_value)
       ++windows_or_buffers_changed;
     }
 }
-#endif /* USE_FONT_BACKEND */
 
 
 void
index d18f5aedcbaefd468e8f3794f989564d7dbf10af..fd94f3c2d018c3134c49db9161b39c5cecb67f18 100644 (file)
@@ -1061,11 +1061,7 @@ extern void x_set_scroll_bar_default_width P_ ((struct frame *));
 extern void x_set_offset P_ ((struct frame *, int, int, int));
 extern void x_wm_set_icon_position P_ ((struct frame *, int, int));
 
-extern Lisp_Object x_new_font P_ ((struct frame *, char *));
-extern Lisp_Object x_new_fontset P_ ((struct frame *, Lisp_Object));
-#ifdef USE_FONT_BACKEND
-extern Lisp_Object x_new_fontset2 P_ ((struct frame *, int, Lisp_Object));
-#endif /* USE_FONT_BACKEND */
+extern Lisp_Object x_new_font P_ ((struct frame *, Lisp_Object, int));
 
 /* These are in frame.c  */
 
index a3ce243f369b2b04452a8341458ae2ad662b23d7..84a15e80b5b91b47794fa753a7a020621ef3cca4 100644 (file)
@@ -71,10 +71,8 @@ struct ftfont_info
 };
 
 static int ftfont_build_basic_charsets P_ ((void));
-static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *,
-                                             Lisp_Object, Lisp_Object));
-static Lisp_Object ftfont_list_generic_family P_ ((Lisp_Object, Lisp_Object,
-                                                  Lisp_Object));
+static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *, Lisp_Object));
+static Lisp_Object ftfont_list_generic_family P_ ((Lisp_Object));
 Lisp_Object ftfont_font_format P_ ((FcPattern *));
 
 #define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM))
@@ -99,10 +97,12 @@ ftfont_build_basic_charsets ()
   return 0;
 }
 
+extern Lisp_Object Qc, Qm, Qp, Qd;
+
 static Lisp_Object
-ftfont_pattern_entity (p, frame, registry)
+ftfont_pattern_entity (p, registry)
      FcPattern *p;
-     Lisp_Object frame, registry;
+     Lisp_Object registry;
 {
   Lisp_Object entity;
   FcChar8 *file, *fontformat;
@@ -110,6 +110,7 @@ ftfont_pattern_entity (p, frame, registry)
   FcChar8 *str;
   int numeric;
   double dbl;
+  FcBool b;
 
   if (FcPatternGetString (p, FC_FILE, 0, &file) != FcResultMatch)
     return Qnil;
@@ -120,38 +121,48 @@ ftfont_pattern_entity (p, frame, registry)
 #endif /* FC_FONTFORMAT */
     fontformat = NULL;
 
-  entity = Fmake_vector (make_number (FONT_ENTITY_MAX), null_string);
+  entity = font_make_entity ();
 
   ASET (entity, FONT_TYPE_INDEX, Qfreetype);
   ASET (entity, FONT_REGISTRY_INDEX, registry);
-  ASET (entity, FONT_FRAME_INDEX, frame);
-  ASET (entity, FONT_OBJLIST_INDEX, Qnil);
 
   if (FcPatternGetString (p, FC_FOUNDRY, 0, &str) == FcResultMatch)
-    ASET (entity, FONT_FOUNDRY_INDEX, intern_downcase (str, strlen (str)));
+    ASET (entity, FONT_FOUNDRY_INDEX, font_intern_prop (str, strlen (str)));
   if (FcPatternGetString (p, FC_FAMILY, 0, &str) == FcResultMatch)
-    ASET (entity, FONT_FAMILY_INDEX, intern_downcase (str, strlen (str)));
+    ASET (entity, FONT_FAMILY_INDEX, font_intern_prop (str, strlen (str)));
   if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch)
     {
-      if (numeric == FC_WEIGHT_REGULAR)
-       numeric = 100;
-      ASET (entity, FONT_WEIGHT_INDEX, make_number (numeric));
+      if (numeric >= FC_WEIGHT_REGULAR && numeric < FC_WEIGHT_MEDIUM)
+       numeric = FC_WEIGHT_MEDIUM;
+      FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, make_number (numeric));
     }
   if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch)
-    ASET (entity, FONT_SLANT_INDEX, make_number (numeric + 100));
+    {
+      numeric += 100;
+      FONT_SET_STYLE (entity, FONT_SLANT_INDEX, make_number (numeric));
+    }
   if (FcPatternGetInteger (p, FC_WIDTH, 0, &numeric) == FcResultMatch)
-    ASET (entity, FONT_WIDTH_INDEX, make_number (numeric));
+    {
+      FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, make_number (numeric));
+    }
   if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch)
     ASET (entity, FONT_SIZE_INDEX, make_number (dbl));
   else
     ASET (entity, FONT_SIZE_INDEX, make_number (0));
+  if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) == FcResultMatch)
+    ASET (entity, FONT_SPACING_INDEX, make_number (numeric));
+  if (FcPatternGetDouble (p, FC_DPI, 0, &dbl) == FcResultMatch)
+    {
+      int dpi = dbl;
+      ASET (entity, FONT_DPI_INDEX, make_number (dpi));
+    }
+  if (FcPatternGetBool (p, FC_SCALABLE, 0, &b) == FcResultMatch
+      && b == FcTrue)
+    ASET (entity, FONT_AVGWIDTH_INDEX, make_number (0));
 
-  if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) != FcResultMatch)
-    numeric = -1;
   file = FcStrCopy (file);
   if (! file)
     return Qnil;
-
   p = FcPatternCreate ();
   if (! p)
     return Qnil;
@@ -163,24 +174,28 @@ ftfont_pattern_entity (p, frame, registry)
       || (fontformat
          && FcPatternAddString (p, FC_FONTFORMAT, fontformat) == FcFalse)
 #endif /* FC_FONTFORMAT */
-      || (numeric >= 0
-         && FcPatternAddInteger (p, FC_SPACING, numeric) == FcFalse))
+      )
     {
       FcPatternDestroy (p);
       return Qnil;
     }
-  ASET (entity, FONT_EXTRA_INDEX, make_save_value (p, 0));
+  font_put_extra (entity, QCfont_entity, make_save_value (p, 0));
   return entity;
 }
 
+
 static Lisp_Object ftfont_generic_family_list;
 
 static Lisp_Object
-ftfont_list_generic_family (spec, frame, registry)
-     Lisp_Object spec, frame, registry;
+ftfont_list_generic_family (family)
+     Lisp_Object family;
 {
-  Lisp_Object family = AREF (spec, FONT_FAMILY_INDEX);
   Lisp_Object slot, list, val;
+  FcObjectSet *objset = NULL;
+  FcPattern *pattern = NULL, *pat = NULL;
+  FcFontSet *fontset = NULL;
+  FcChar8 *fam;
+  int i, j;
 
   if (EQ (family, Qmono))
     family = Qmonospace;
@@ -188,86 +203,53 @@ ftfont_list_generic_family (spec, frame, registry)
     family = Qsans_serif;
   slot = assq_no_quit (family, ftfont_generic_family_list);
   if (! CONSP (slot))
-    return null_vector;
+    return Qnil;
   list = XCDR (slot);
-  if (EQ (list, Qt))
+  if (! EQ (list, Qt))
+    return list;
+
+  objset = FcObjectSetBuild (FC_FAMILY, NULL);
+  if (! objset)
+    goto err;
+  pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString,
+                           SYMBOL_FcChar8 (family), (char *) 0);
+  if (! pattern)
+    goto err;
+  pat = FcPatternCreate ();
+  if (! pat)
+    goto err;
+  FcConfigSubstitute (NULL, pattern, FcMatchPattern);
+  for (i = 0, list = Qnil;
+       FcPatternGetString (pattern, FC_FAMILY, i, &fam) == FcResultMatch;
+       i++)
     {
-      /* Not yet listed.  */
-      FcObjectSet *objset = NULL;
-      FcPattern *pattern = NULL, *pat = NULL;
-      FcFontSet *fontset = NULL;
-      FcChar8 *fam;
-      int i, j;
-
-      objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT,
-                                FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING,
-                                FC_CHARSET, FC_FILE,
-#ifdef FC_FONTFORMAT
-                                FC_FONTFORMAT,
-#endif /* FC_FONTFORMAT */
-                                NULL);
-      if (! objset)
-       goto err;
-      pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString,
-                               SYMBOL_FcChar8 (family), (char *) 0);
-      if (! pattern)
+      if (strcmp ((char *) fam, (char *) SYMBOL_FcChar8 (family)) == 0)
+       continue;
+      if (! FcPatternAddString (pat, FC_FAMILY, fam))
        goto err;
-      pat = FcPatternCreate ();
-      if (! pat)
+      fontset = FcFontList (NULL, pat, objset);
+      if (! fontset)
        goto err;
-      FcConfigSubstitute (NULL, pattern, FcMatchPattern);
-      for (i = 0, val = Qnil;
-          FcPatternGetString (pattern, FC_FAMILY, i, &fam) == FcResultMatch;
-          i++)
-       {
-         if (strcmp ((char *) fam, (char *) SYMBOL_FcChar8 (family)) == 0)
-           continue;
-         if (! FcPatternAddString (pat, FC_FAMILY, fam))
-           goto err;
-         fontset = FcFontList (NULL, pat, objset);
-         if (! fontset)
-           goto err;
-         /* Here we build the list in reverse order so that the last
-            loop in this function build a list in the correct
-            order.  */
-         for (j = 0; j < fontset->nfont; j++)
-           {
-             Lisp_Object entity;
-
-             entity = ftfont_pattern_entity (fontset->fonts[j],
-                                             frame, registry);
-             if (! NILP (entity))
-               val = Fcons (entity, val);
-           }
-         FcFontSetDestroy (fontset);
-         fontset = NULL;
-         FcPatternDel (pat, FC_FAMILY);
-       }
-      list = val;
-      XSETCDR (slot, list);
-    err:
-      if (pat) FcPatternDestroy (pat);
-      if (pattern) FcPatternDestroy (pattern);
-      if (fontset) FcFontSetDestroy (fontset);
-      if (objset) FcObjectSetDestroy (objset);
-      if (EQ (list, Qt))
-       return Qnil;
+      if (fontset->nfont > 0)
+       list = Fcons (intern ((char *) fam), list);
+      FcFontSetDestroy (fontset);
+      fontset = NULL;
+      FcPatternDel (pat, FC_FAMILY);
     }
-  ASET (spec, FONT_FAMILY_INDEX, Qnil);
-  for (val = Qnil; CONSP (list); list = XCDR (list))
-    if (font_match_p (spec, XCAR (list)))
-      val = Fcons (XCAR (list), val);
-  ASET (spec, FONT_FAMILY_INDEX, family);
-  return Fvconcat (1, &val);
+  XSETCDR (slot, list);
+ err:
+  if (pat) FcPatternDestroy (pat);
+  if (pattern) FcPatternDestroy (pattern);
+  if (fontset) FcFontSetDestroy (fontset);
+  if (objset) FcObjectSetDestroy (objset);
+  return list;
 }
 
-
 static Lisp_Object ftfont_get_cache P_ ((FRAME_PTR));
 static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object));
 static Lisp_Object ftfont_match P_ ((Lisp_Object, Lisp_Object));
 static Lisp_Object ftfont_list_family P_ ((Lisp_Object));
-static void ftfont_free_entity P_ ((Lisp_Object));
-static struct font *ftfont_open P_ ((FRAME_PTR, Lisp_Object, int));
+static Lisp_Object ftfont_open P_ ((FRAME_PTR, Lisp_Object, int));
 static void ftfont_close P_ ((FRAME_PTR, struct font *));
 static int ftfont_has_char P_ ((Lisp_Object, int));
 static unsigned ftfont_encode_char P_ ((struct font *, int));
@@ -282,11 +264,12 @@ static Lisp_Object ftfont_shape P_ ((Lisp_Object));
 struct font_driver ftfont_driver =
   {
     0,                         /* Qfreetype */
+    0,                         /* case insensitive */
     ftfont_get_cache,
     ftfont_list,
     ftfont_match,
     ftfont_list_family,
-    ftfont_free_entity,
+    NULL,
     ftfont_open,
     ftfont_close,
     /* We can't draw a text without device dependent functions.  */
@@ -409,41 +392,41 @@ ftfont_get_open_type_spec (Lisp_Object otf_spec)
   return spec;
 }
 
-static Lisp_Object
-ftfont_list (frame, spec)
-     Lisp_Object frame, spec;
+static FcPattern *
+ftfont_spec_pattern (spec, otlayout, otspec)
+     Lisp_Object spec;
+     char *otlayout;
+     struct OpenTypeSpec **otspec;
 {
   Lisp_Object val, tmp, extra;
   int i;
   FcPattern *pattern = NULL;
   FcCharSet *charset = NULL;
   FcLangSet *langset = NULL;
-  FcFontSet *fontset = NULL;
-  FcObjectSet *objset = NULL;
-  Lisp_Object script;
-  Lisp_Object registry = Qunicode_bmp;
-  struct OpenTypeSpec *otspec= NULL;
-  int weight = 0;
-  double dpi = -1;
+  int n;
+  int dpi = -1;
   int spacing = -1;
   int scalable = -1;
-  char otlayout[15];           /* For "otlayout:XXXX" */
-  
-  val = null_vector;
-
-  if (! fc_initialized)
-    {
-      FcInit ();
-      fc_initialized = 1;
-    }
+  Lisp_Object name = Qnil;
+  Lisp_Object script = Qnil;
+  Lisp_Object registry = Qunicode_bmp;
 
   if (! NILP (AREF (spec, FONT_ADSTYLE_INDEX))
-      && ! EQ (AREF (spec, FONT_ADSTYLE_INDEX), null_string))
-    return val;
-  if (! NILP (AREF (spec, FONT_SLANT_INDEX))
-      && XINT (AREF (spec, FONT_SLANT_INDEX)) < 100)
+      && SBYTES (SYMBOL_NAME (AREF (spec, FONT_ADSTYLE_INDEX))) > 0)
+    /* Fontconfig doesn't support adstyle property.  */
+    return NULL;
+  if ((n = FONT_SLANT_NUMERIC (spec)) >= 0
+      && n < 100)
     /* Fontconfig doesn't support reverse-italic/obligue.  */
-    return val;
+    return NULL;
+
+  if (INTEGERP (AREF (spec, FONT_DPI_INDEX)))
+    dpi = XINT (dpi);
+  if (INTEGERP (AREF (spec, FONT_SPACING_INDEX)))
+    spacing = XINT (val);
+  if (INTEGERP (AREF (spec, FONT_AVGWIDTH_INDEX))
+      && XINT (AREF (spec, FONT_AVGWIDTH_INDEX)) == 0)
+    scalable = 1;
 
   if (! NILP (AREF (spec, FONT_REGISTRY_INDEX)))
     {
@@ -452,34 +435,27 @@ ftfont_list (frame, spec)
        {
          if (! cs_iso8859_1
              && ftfont_build_basic_charsets () < 0)
-           return Qnil;
+           return NULL;
          charset = cs_iso8859_1;
        }
       else if (! EQ (registry, Qiso10646_1)
               && ! EQ (registry, Qunicode_bmp)
               && ! EQ (registry, Qunicode_sip))
-       return val;
+       return NULL;
     }
 
   otlayout[0] = '\0';
-  script = Qnil;
   for (extra = AREF (spec, FONT_EXTRA_INDEX);
        CONSP (extra); extra = XCDR (extra))
     {
       Lisp_Object key, val;
 
-      tmp = XCAR (extra);
-      key = XCAR (tmp), val = XCDR (tmp);
-      if (EQ (key, QCotf))
-       {
-         otspec = ftfont_get_open_type_spec (val);
-         if (! otspec)
-           return null_vector;
-         strcat (otlayout, "otlayout:");
-         OTF_TAG_STR (otspec->script_tag, otlayout + 9);
-         script = otspec->script;
-       }
-      else if (EQ (key, QClanguage))
+      key = XCAR (XCAR (extra)), val = XCDR (XCAR (extra));
+      if (EQ (key, QCdpi))
+       dpi = XINT (val);
+      else if (EQ (key, QCfc_unknown_spec))
+       name = val;
+      else if (EQ (key, QClang))
        {
          langset = FcLangSetCreate ();
          if (! langset)
@@ -495,12 +471,19 @@ ftfont_list (frame, spec)
                  && ! FcLangSetAdd (langset, SYMBOL_FcChar8 (XCAR (val))))
                goto err;
        }
+      else if (EQ (key, QCname))
+       name = val;
+      else if (EQ (key, QCotf))
+       {
+         *otspec = ftfont_get_open_type_spec (val);
+         if (! *otspec)
+           return NULL;
+         strcat (otlayout, "otlayout:");
+         OTF_TAG_STR ((*otspec)->script_tag, otlayout + 9);
+         script = (*otspec)->script;
+       }
       else if (EQ (key, QCscript))
        script = val;
-      else if (EQ (key, QCdpi))
-       dpi = XINT (val);
-      else if (EQ (key, QCspacing))
-       spacing = XINT (val);
       else if (EQ (key, QCscalable))
        scalable = ! NILP (val);
     }
@@ -521,32 +504,15 @@ ftfont_list (frame, spec)
        }
     }
 
-  pattern = FcPatternCreate ();
+  pattern = NILP (name) ? FcPatternCreate () : FcNameParse (SDATA (name));
   if (! pattern)
     goto err;
+  FcPatternDel (pattern, FC_SIZE);
+  FcPatternDel (pattern, FC_PIXEL_SIZE);
   tmp = AREF (spec, FONT_FOUNDRY_INDEX);
-  if (SYMBOLP (tmp) && ! NILP (tmp)
+  if (! NILP (tmp)
       && ! FcPatternAddString (pattern, FC_FOUNDRY, SYMBOL_FcChar8 (tmp)))
     goto err;
-  tmp = AREF (spec, FONT_FAMILY_INDEX);
-  if (SYMBOLP (tmp) && ! NILP (tmp)
-      && ! FcPatternAddString (pattern, FC_FAMILY, SYMBOL_FcChar8 (tmp)))
-    goto err;
-  /* Emacs conventionally doesn't distinguish normal, regular, and
-     medium weight, but fontconfig does.  So, we can't restrict font
-     listing by weight.  We check it after getting a list.  */
-  tmp = AREF (spec, FONT_WEIGHT_INDEX);
-  if (INTEGERP (tmp))
-    weight = XINT (tmp);
-  tmp = AREF (spec, FONT_SLANT_INDEX);
-  if (INTEGERP (tmp)
-      && ! FcPatternAddInteger (pattern, FC_SLANT, XINT (tmp) - 100))
-    goto err;
-  tmp = AREF (spec, FONT_WIDTH_INDEX);
-  if (INTEGERP (tmp)
-      && ! FcPatternAddInteger (pattern, FC_WIDTH, XINT (tmp)))
-    goto err;
-
   if (charset
       && ! FcPatternAddCharSet (pattern, FC_CHARSET, charset))
     goto err;
@@ -562,65 +528,100 @@ ftfont_list (frame, spec)
   if (scalable >= 0
       && ! FcPatternAddBool (pattern, FC_SCALABLE, scalable ? FcTrue : FcFalse))
     goto err;
+  goto finish;
+
+ err:
+  /* We come here because of unexpected error in fontconfig API call
+     (usually insufficient memory).  */
+  if (pattern)
+    {
+      FcPatternDestroy (pattern);
+      pattern = NULL;
+    }
+  if (*otspec)
+    {
+      if ((*otspec)->nfeatures[0] > 0)
+       free ((*otspec)->features[0]);
+      if ((*otspec)->nfeatures[1] > 0)
+       free ((*otspec)->features[1]);
+      free (*otspec);
+      *otspec = NULL;
+    }
 
+ finish:
+  if (charset && charset != cs_iso8859_1) FcCharSetDestroy (charset);
+  if (langset) FcLangSetDestroy (langset);
+  return pattern;
+}
+
+static Lisp_Object
+ftfont_list (frame, spec)
+     Lisp_Object frame, spec;
+{
+  Lisp_Object val, tmp, registry, family, family_list;
+  int i;
+  FcPattern *pattern;
+  FcFontSet *fontset = NULL;
+  FcObjectSet *objset = NULL;
+  double pixel_size = 0;
+  int weight = -1, slant = -1, width = -1;
+  double dpi = -1;
+  int spacing = -1;
+  int scalable = -1;
+  char otlayout[15];           /* For "otlayout:XXXX" */
+  struct OpenTypeSpec *otspec = NULL;
+  
+  if (! fc_initialized)
+    {
+      FcInit ();
+      fc_initialized = 1;
+    }
+
+  pattern = ftfont_spec_pattern (spec, otlayout, &otspec);
+  if (! pattern)
+    return Qnil;
   objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT,
-                            FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING,
+                            FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, FC_SCALABLE,
                             FC_CHARSET, FC_FILE,
+#ifdef FC_CAPABILITY
+                            FC_CAPABILITY,
+#endif /* FC_CAPABILITY */
 #ifdef FC_FONTFORMAT
                             FC_FONTFORMAT,
 #endif /* FC_FONTFORMAT */
                             NULL);
   if (! objset)
     goto err;
-  if (otlayout[0])
+
+  registry = AREF (spec, FONT_REGISTRY_INDEX);
+  family = AREF (spec, FONT_FAMILY_INDEX);
+  if (NILP (family))
+    family_list = Fcons (Qnil, Qnil);
+  else
     {
-#ifdef FC_CAPABILITY
-      if (! FcObjectSetAdd (objset, FC_CAPABILITY))
-       goto err;
-#else  /* not FC_CAPABILITY */
-      goto finish;
-#endif /* not FC_CAPABILITY */
+      family_list = ftfont_list_generic_family (family);
+      if (NILP (family_list))
+       family_list = Fcons (family, Qnil);
     }
 
-  fontset = FcFontList (NULL, pattern, objset);
-  if (! fontset)
-    goto err;
-
-  if (fontset->nfont > 0)
+  for (val = Qnil; CONSP (family_list); family_list = XCDR (family_list))
     {
-      double pixel_size;
-
-      if (NILP (AREF (spec, FONT_SIZE_INDEX)))
-       pixel_size = 0;
-      else
-       pixel_size = XINT (AREF (spec, FONT_SIZE_INDEX));
-
-      for (i = 0, val = Qnil; i < fontset->nfont; i++)
+      family = XCAR (family_list);
+      if (! NILP (family))
+       {
+         FcPatternDel (pattern, FC_FAMILY);
+         if (! FcPatternAddString (pattern, FC_FAMILY, SYMBOL_FcChar8 (family)))
+           goto err;
+       }
+      fontset = FcFontList (NULL, pattern, objset);
+      if (! fontset)
+       goto err;
+      for (i = 0; i < fontset->nfont; i++)
        {
          Lisp_Object entity;
+         int n;
+         double dbl;
 
-         if (pixel_size > 0)
-           {
-             double this;
-
-             if (FcPatternGetDouble (fontset->fonts[i], FC_PIXEL_SIZE, 0,
-                                     &this) == FcResultMatch
-                 && ((this < pixel_size - FONT_PIXEL_SIZE_QUANTUM)
-                     || (this > pixel_size + FONT_PIXEL_SIZE_QUANTUM)))
-               continue;
-           }
-         if (weight > 0)
-           {
-             int this;
-
-             if (FcPatternGetInteger (fontset->fonts[i], FC_WEIGHT, 0,
-                                      &this) != FcResultMatch
-                 || (this != weight
-                     && (weight != 100
-                         || this < FC_WEIGHT_REGULAR
-                         || this > FC_WEIGHT_MEDIUM)))
-               continue;
-           }
 #ifdef FC_CAPABILITY
          if (otlayout[0])
            {
@@ -655,14 +656,13 @@ ftfont_list (frame, spec)
                continue;
            }
 #endif /* HAVE_LIBOTF */
-         entity = ftfont_pattern_entity (fontset->fonts[i], frame, registry);
+         entity = ftfont_pattern_entity (fontset->fonts[i], registry);
          if (! NILP (entity))
            val = Fcons (entity, val);
        }
-      val = Fvconcat (1, &val);
+      FcFontSetDestroy (fontset);
+      fontset = NULL;
     }
-  else if (! NILP (AREF (spec, FONT_FAMILY_INDEX)))
-    val = ftfont_list_generic_family (spec, frame, registry);
   goto finish;
 
  err:
@@ -671,19 +671,9 @@ ftfont_list (frame, spec)
   val = Qnil;
 
  finish:
-  if (charset && charset != cs_iso8859_1) FcCharSetDestroy (charset);
   if (objset) FcObjectSetDestroy (objset);
   if (fontset) FcFontSetDestroy (fontset);
-  if (langset) FcLangSetDestroy (langset);
   if (pattern) FcPatternDestroy (pattern);
-  if (otspec)
-    {
-      if (otspec->nfeatures[0] > 0)
-       free (otspec->features[0]);
-      if (otspec->nfeatures[1] > 0)
-       free (otspec->features[1]);
-      free (otspec);
-    }
   return val;
 }
 
@@ -692,8 +682,10 @@ ftfont_match (frame, spec)
      Lisp_Object frame, spec;
 {
   Lisp_Object extra, val, entity;
-  FcPattern *pattern = NULL, *match = NULL;
+  FcPattern *pattern, *match = NULL;
   FcResult result;
+  char otlayout[15];           /* For "otlayout:XXXX" */
+  struct OpenTypeSpec *otspec = NULL;
 
   if (! fc_initialized)
     {
@@ -701,35 +693,35 @@ ftfont_match (frame, spec)
       fc_initialized = 1;
     }
 
-  extra = AREF (spec, FONT_EXTRA_INDEX);
-  val = assq_no_quit (QCname, extra);
-  if (! CONSP (val) || ! STRINGP (XCDR (val)))
+  pattern = ftfont_spec_pattern (spec, otlayout, &otspec);
+  if (! pattern)
     return Qnil;
 
-  entity = Qnil;
-  pattern = FcNameParse (SDATA (XCDR (val)));
-  if (pattern)
+  if (INTEGERP (AREF (spec, FONT_SIZE_INDEX)))
     {
-      if (INTEGERP (AREF (spec, FONT_SIZE_INDEX)))
-       {
-         FcValue value;
+      FcValue value;
 
-         value.type = FcTypeDouble;
-         value.u.d = XINT (AREF (spec, FONT_SIZE_INDEX));
-         FcPatternAdd (pattern, FC_PIXEL_SIZE, value, FcFalse);
-       }
-      if (FcConfigSubstitute (NULL, pattern, FcMatchPattern) == FcTrue)
+      value.type = FcTypeDouble;
+      value.u.d = XINT (AREF (spec, FONT_SIZE_INDEX));
+      FcPatternAdd (pattern, FC_PIXEL_SIZE, value, FcFalse);
+    }
+  if (FcConfigSubstitute (NULL, pattern, FcMatchPattern) == FcTrue)
+    {
+      FcDefaultSubstitute (pattern);
+      match = FcFontMatch (NULL, pattern, &result);
+      if (match)
        {
-         FcDefaultSubstitute (pattern);
-         match = FcFontMatch (NULL, pattern, &result);
-         if (match)
-           {
-             entity = ftfont_pattern_entity (match, frame, Qunicode_bmp);
-             FcPatternDestroy (match);
-           }
+         entity = ftfont_pattern_entity (match, Qunicode_bmp);
+         FcPatternDestroy (match);
+         if (! NILP (AREF (spec, FONT_FAMILY_INDEX))
+             && NILP (assq_no_quit (AREF (spec, FONT_FAMILY_INDEX),
+                                    ftfont_generic_family_list))
+             && NILP (Fstring_equal (AREF (spec, FONT_FAMILY_INDEX),
+                                     AREF (entity, FONT_FAMILY_INDEX))))
+           entity = Qnil;
        }
-      FcPatternDestroy (pattern);
     }
+  FcPatternDestroy (pattern);
 
   return entity;
 }
@@ -767,8 +759,7 @@ ftfont_list_family (frame)
       FcChar8 *str;
 
       if (FcPatternGetString (pat, FC_FAMILY, 0, &str) == FcResultMatch)
-       list = Fcons (intern_downcase ((char *) str, strlen ((char *) str)),
-                     list);
+       list = Fcons (intern ((char *) str), list);
     }
 
  finish:
@@ -780,17 +771,7 @@ ftfont_list_family (frame)
 }
 
 
-static void 
-ftfont_free_entity (entity)
-     Lisp_Object entity;
-{
-  Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX);
-  FcPattern *pattern = XSAVE_VALUE (val)->pointer;
-
-  FcPatternDestroy (pattern);
-}
-
-static struct font *
+static Lisp_Object
 ftfont_open (f, entity, pixel_size)
      FRAME_PTR f;
      Lisp_Object entity;
@@ -801,42 +782,45 @@ ftfont_open (f, entity, pixel_size)
   FT_Face ft_face;
   FT_Size ft_size;
   FT_UInt size;
-  Lisp_Object val;
+  Lisp_Object val, font_object;
   FcPattern *pattern;
-  FcChar8 *file;
+  FcChar8 *file = NULL, *fmt = NULL;
+  FcBool scalable;
   int spacing;
-  char *name;
-  int len;
+  char name[256];
+  int i, len;
+  int upEM;
 
-  val = AREF (entity, FONT_EXTRA_INDEX);
-  if (XTYPE (val) != Lisp_Misc
-      || XMISCTYPE (val) != Lisp_Misc_Save_Value)
-    return NULL;
+  val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
+  if (! CONSP (val))
+    return Qnil;
+  val = XCDR (val);
   pattern = XSAVE_VALUE (val)->pointer;
   if (XSAVE_VALUE (val)->integer == 0)
     {
       /* We have not yet created FT_Face for this font.  */
       if (! ft_library
          && FT_Init_FreeType (&ft_library) != 0)
-       return NULL;
+       return Qnil;
       if (FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch)
-       return NULL;
+       return Qnil;
       if (FT_New_Face (ft_library, (char *) file, 0, &ft_face) != 0)
-       return NULL;
+       return Qnil;
       FcPatternAddFTFace (pattern, FC_FT_FACE, ft_face);
       ft_size = ft_face->size;
+      XSAVE_VALUE (val)->integer++;
     }
   else
     {
       if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &ft_face)
          != FcResultMatch)
-       return NULL;
+       return Qnil;
       if (FT_New_Size (ft_face, &ft_size) != 0)
-       return NULL;
+       return Qnil;
       if (FT_Activate_Size (ft_size) != 0)
        {
          FT_Done_Size (ft_size);
-         return NULL;
+         return Qnil;
        }
     } 
 
@@ -847,84 +831,99 @@ ftfont_open (f, entity, pixel_size)
     {
       if (XSAVE_VALUE (val)->integer == 0)
        FT_Done_Face (ft_face);
-      return NULL;
+      return Qnil;
     }
 
-  ftfont_info = malloc (sizeof (struct ftfont_info));
-  if (! ftfont_info)
-    return NULL;
+  font_object = font_make_object (VECSIZE (struct ftfont_info));
+  ASET (font_object, FONT_TYPE_INDEX, Qfreetype);
+  for (i = 1;i < FONT_ENTITY_MAX; i++)
+    ASET (font_object, i, AREF (entity, i));
+  ASET (font_object, FONT_SIZE_INDEX, make_number (size));
+  len = font_unparse_xlfd (entity, size, name, 256);
+  if (len > 0)
+    ASET (font_object, FONT_NAME_INDEX, make_unibyte_string (name, len));
+  len = font_unparse_fcname (entity, size, name, 256);
+  if (len > 0)
+    ASET (font_object, FONT_FULLNAME_INDEX, make_unibyte_string (name, len));
+  else
+    ASET (font_object, FONT_FULLNAME_INDEX,
+         AREF (font_object, FONT_NAME_INDEX));
+  if (! file
+      && ! FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch)
+    return Qnil;
+  ASET (font_object, FONT_FILE_INDEX,
+       make_unibyte_string ((char *) file, strlen ((char *) file)));
+  ASET (font_object, FONT_FORMAT_INDEX, ftfont_font_format (pattern));
+  font = XFONT_OBJECT (font_object);
+  ftfont_info = (struct ftfont_info *) font;
   ftfont_info->ft_size = ft_size;
 #ifdef HAVE_LIBOTF
   ftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT;
   ftfont_info->otf = NULL;
 #endif /* HAVE_LIBOTF */
-
-  font = (struct font *) ftfont_info;
-  font->format = ftfont_font_format (pattern);
-  font->entity = entity;
   font->pixel_size = size;
   font->driver = &ftfont_driver;
-  len = 96;
-  name = malloc (len);
-  while (name && font_unparse_fcname (entity, pixel_size, name, len) < 0)
-    {
-      char *new = realloc (name, len += 32);
+  font->encoding_charset = font->repertory_charset = -1;
 
-      if (! new)
-       free (name);
-      name = new;
+  upEM = ft_face->units_per_EM;
+  if (! FcPatternGetBool (pattern, FC_SCALABLE, 0, &scalable) == FcResultMatch)
+    scalable = FcFalse;
+  if (scalable)
+    {
+      font->ascent = ft_face->ascender * size / upEM;
+      font->descent = - ft_face->descender * size / upEM;
+      font->height = ft_face->height * size / upEM;
+    }
+  else
+    {
+      font->ascent = ft_face->size->metrics.ascender >> 6;
+      font->descent = - ft_face->size->metrics.descender >> 6;
+      font->height = ft_face->size->metrics.height >> 6;
     }
-  font->font.full_name = font->font.name = name;
-  font->file_name = (char *) file;
-  font->font.size = ft_face->size->metrics.max_advance >> 6;
-  if (font->font.size <= 0)
-    font->font.size = size;
-  font->font.charset = font->encoding_charset = font->repertory_charset = -1;
-  font->ascent = ft_face->size->metrics.ascender >> 6;
-  font->descent = - ft_face->size->metrics.descender >> 6;
-  font->font.height = font->ascent + font->descent;
   if (FcPatternGetInteger (pattern, FC_SPACING, 0, &spacing) != FcResultMatch)
     spacing = FC_PROPORTIONAL;
   if (spacing != FC_PROPORTIONAL)
-    font->font.average_width = font->font.space_width = font->font.size;
+    font->min_width = font->average_width = font->space_width
+      = (scalable ? ft_face->max_advance_width * size / upEM
+        : ft_face->size->metrics.max_advance >> 6);
   else
     {
-      int i;
+      int n;
 
-      font->font.average_width = font->font.space_width = 0;
-      for (i = 32; i < 127; i++)
-       {
-         if (FT_Load_Char (ft_face, i, FT_LOAD_DEFAULT) != 0)
-           break;
-         if (i == 32)
-           font->font.space_width = ft_face->glyph->metrics.horiAdvance >> 6;
-         font->font.average_width += ft_face->glyph->metrics.horiAdvance >> 6;
-       }
-      if (i == 127)
-       {
-         /* The font contains all ASCII printable characters.  */
-         font->font.average_width /= 95;
-       }
-      else
-       {
-         if (i == 32)
-           font->font.space_width = font->font.size;
-         font->font.average_width = font->font.size;
-       }
+      font->min_width = font->average_width = font->space_width = 0;
+      for (i = 32, n = 0; i < 127; i++)
+       if (FT_Load_Char (ft_face, i, FT_LOAD_DEFAULT) != 0)
+         {
+           int this_width = ft_face->glyph->metrics.horiAdvance >> 6;
+
+           if (this_width > 0
+               && (! font->min_width || font->min_width > this_width))
+             font->min_width = this_width;
+           if (i == 32)
+             font->space_width = this_width;
+           font->average_width += this_width;
+           n++;
+         }
+      if (n > 0)
+       font->average_width /= n;
     }
 
-  /* Unfortunately FreeType doesn't provide a way to get minimum char
-     width.  So, we use space_width instead.  */
-  font->min_width = font->font.space_width;
-
-  font->font.baseline_offset = 0;
-  font->font.relative_compose = 0;
-  font->font.default_ascent = 0;
-  font->font.vertical_centering = 0;
-
-  (XSAVE_VALUE (val)->integer)++;
+  font->baseline_offset = 0;
+  font->relative_compose = 0;
+  font->default_ascent = 0;
+  font->vertical_centering = 0;
+  if (scalable)
+    {
+      font->underline_position = -ft_face->underline_position * size / upEM;
+      font->underline_thickness = -ft_face->underline_thickness * size / upEM;
+    }
+  else
+    {
+      font->underline_position = -1;
+      font->underline_thickness = 0;
+    }
 
-  return font;
+  return font_object;
 }
 
 static void
@@ -933,9 +932,10 @@ ftfont_close (f, font)
      struct font *font;
 {
   struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
-  Lisp_Object entity = font->entity;
-  Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX);
+  Lisp_Object val;
 
+  val = assq_no_quit (QCfont_entity, font->props[FONT_EXTRA_INDEX]);
+  val = XCDR (val);
   (XSAVE_VALUE (val)->integer)--;
   if (XSAVE_VALUE (val)->integer == 0)
     {
@@ -947,8 +947,6 @@ ftfont_close (f, font)
     }
   else
     FT_Done_Size (ftfont_info->ft_size);
-
-  free (font);
 }
 
 static int 
@@ -960,7 +958,8 @@ ftfont_has_char (entity, c)
   FcPattern *pattern;
   FcCharSet *charset;
 
-  val = AREF (entity, FONT_EXTRA_INDEX);
+  val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
+  val = XCDR (val);
   pattern = XSAVE_VALUE (val)->pointer;
   if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch)
     return -1;
@@ -1019,7 +1018,7 @@ ftfont_text_extents (font, code, nglyphs, metrics)
        }
       else
        {
-         width += font->font.space_width;
+         width += font->space_width;
        }
     }
   if (metrics)
@@ -1161,7 +1160,7 @@ ftfont_get_metrics (font, gstring, from, to)
        else
          {
            g->lbearing = 0;
-           g->rbearing = g->xadv = flt_font_ft->font->font.space_width << 6;
+           g->rbearing = g->xadv = flt_font_ft->font->space_width << 6;
            g->ascent = flt_font_ft->font->ascent << 6;
            g->descent = flt_font_ft->font->descent << 6;
          }
index d575182ef85df88b06cf43143040ce687d3dc7ea..4254b11b35ec96b9899aaf15ef4afe7b1e09c3f9 100644 (file)
@@ -244,7 +244,7 @@ ftxfont_draw_backgrond (f, font, gc, x, y, width)
 /* Prototypes for font-driver methods.  */
 static Lisp_Object ftxfont_list P_ ((Lisp_Object, Lisp_Object));
 static Lisp_Object ftxfont_match P_ ((Lisp_Object, Lisp_Object));
-static struct font *ftxfont_open P_ ((FRAME_PTR, Lisp_Object, int));
+static Lisp_Object ftxfont_open P_ ((FRAME_PTR, Lisp_Object, int));
 static void ftxfont_close P_ ((FRAME_PTR, struct font *));
 static int ftxfont_draw P_ ((struct glyph_string *, int, int, int, int, int));
 
@@ -255,16 +255,11 @@ ftxfont_list (frame, spec)
      Lisp_Object frame;
      Lisp_Object spec;
 {
-  Lisp_Object val = ftfont_driver.list (frame, spec);
+  Lisp_Object list = ftfont_driver.list (frame, spec), tail;
   
-  if (! NILP (val))
-    {
-      int i;
-
-      for (i = 0; i < ASIZE (val); i++)
-       ASET (AREF (val, i), FONT_TYPE_INDEX, Qftx);
-    }
-  return val;
+  for (tail = list; CONSP (tail); tail = XCDR (tail))
+    ASET (XCAR (tail), FONT_TYPE_INDEX, Qftx);
+  return list;
 }
 
 static Lisp_Object
@@ -279,62 +274,22 @@ ftxfont_match (frame, spec)
   return entity;
 }
 
-static struct font *
+static Lisp_Object
 ftxfont_open (f, entity, pixel_size)
      FRAME_PTR f;
      Lisp_Object entity;
      int pixel_size;
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Lisp_Object font_object;
   struct font *font;
-  XFontStruct *xfont = malloc (sizeof (XFontStruct));
-  
-  if (! xfont)
-    return NULL;
-  font = ftfont_driver.open (f, entity, pixel_size);
-  if (! font)
-    {
-      free (xfont);
-      return NULL;
-    }
-  xfont->fid = (Font) 0;
-  xfont->ascent = font->ascent;
-  xfont->descent = font->descent;
-  xfont->max_bounds.width = font->font.size;
-  xfont->min_bounds.width = font->min_width;
-  font->font.font = xfont;
-  font->driver = &ftxfont_driver;
 
-  dpyinfo->n_fonts++;
-
-  /* Set global flag fonts_changed_p to non-zero if the font loaded
-     has a character with a smaller width than any other character
-     before, or if the font loaded has a smaller height than any other
-     font loaded before.  If this happens, it will make a glyph matrix
-     reallocation necessary.  */
-  if (dpyinfo->n_fonts == 1)
-    {
-      dpyinfo->smallest_font_height = font->font.height;
-      dpyinfo->smallest_char_width = font->min_width;
-      fonts_changed_p = 1;
-    }
-  else
-    {
-      if (dpyinfo->smallest_font_height > font->font.height)
-       dpyinfo->smallest_font_height = font->font.height, fonts_changed_p |= 1;
-      if (dpyinfo->smallest_char_width > font->min_width)
-       dpyinfo->smallest_char_width = font->min_width, fonts_changed_p |= 1;
-    }
-
-  if (fonts_changed_p)
-    {
-      if (dpyinfo->smallest_font_height == 0)
-       dpyinfo->smallest_font_height = 1;
-      if (dpyinfo->smallest_char_width == 0)
-       dpyinfo->smallest_char_width = 1;
-    }
-
-  return font;
+  font_object = ftfont_driver.open (f, entity, pixel_size);
+  if (NILP (font_object))
+    return Qnil;
+  font = XFONT_OBJECT (font_object);
+  font->driver = &ftxfont_driver;
+  return font_object;
 }
 
 static void
@@ -343,7 +298,6 @@ ftxfont_close (f, font)
      struct font *font;
 {
   ftfont_driver.close (f, font);
-  FRAME_X_DISPLAY_INFO (f)->n_fonts--;
 }
 
 static int
@@ -353,7 +307,7 @@ ftxfont_draw (s, from, to, x, y, with_background)
 {
   FRAME_PTR f = s->f;
   struct face *face = s->face;
-  struct font *font = (struct font *) s->font_info;
+  struct font *font = s->font;
   XPoint p[0x700];
   int n[7];
   unsigned *code;
index fbf6a15cef6281e84e16c040ce47c7b9f7e56aca..abf5f63cbfeeb2de84d5fe167221ac51c6c83d2d 100644 (file)
@@ -40,9 +40,10 @@ Boston, MA 02110-1301, USA.  */
 #include "blockinput.h"
 #include "systime.h"
 #include <epaths.h>
-#include "charset.h"
+#include "character.h"
 #include "coding.h"
 #include "termhooks.h"
+#include "font.h"
 
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
index ab07ea750f4378f95d1a4673f917cba93fc0b45d..2b08ec89b8ac9aebc4121787baa71ef9c2ffbb53 100644 (file)
@@ -350,8 +350,9 @@ enum pvec_type
   PVEC_HASH_TABLE = 0x40000,
   PVEC_TERMINAL = 0x80000,
   PVEC_SUB_CHAR_TABLE = 0x100000,
-  PVEC_OTHER = 0x200000,
-  PVEC_TYPE_MASK = 0x2ffe00
+  PVEC_FONT = 0x200000,
+  PVEC_OTHER = 0x400000,
+  PVEC_TYPE_MASK = 0x7ffe00
 
 #if 0 /* This is used to make the value of PSEUDOVECTOR_FLAG available to
         GDB.  It doesn't work on OS Alpha.  Moved to a variable in
index 28fddaaeb5d8b6ad5a011354a207f753c15f4acb..9593155763ba5f73ba7afac36bf5296096b5954a 100644 (file)
@@ -135,8 +135,8 @@ WIN32OBJ = $(BLD)/w32term.$(O)              \
           $(BLD)/xfaces.$(O)           \
           $(BLD)/w32select.$(O)                \
           $(BLD)/w32menu.$(O)          \
-          $(BLD)/w32reg.$(O)           \
-          $(BLD)/w32bdf.$(O)
+          $(BLD)/w32reg.$(O)
+#         $(BLD)/w32bdf.$(O)
 
 FONTOBJ = $(BLD)/w32font.$(O) $(BLD)/w32uniscribe.$(O)
 
index 5a1d57998e62dc51d18b262e77f98934cd9018c8..f4ad53826d98569249a38baba1e410e35481edd4 100644 (file)
@@ -36,6 +36,7 @@ Boston, MA 02110-1301, USA.  */
 #include "intervals.h"
 #include "blockinput.h"
 #include "termhooks.h"         /* For struct terminal.  */
+#include "font.h"
 
 Lisp_Object Vstandard_output, Qstandard_output;
 
@@ -2129,6 +2130,34 @@ print_object (obj, printcharfun, escapeflag)
          strout (buf, -1, -1, printcharfun, 0);
          PRINTCHAR ('>');
        }
+      else if (FONTP (obj))
+       {
+         EMACS_INT i;
+
+         if (! FONT_OBJECT_P (obj))
+           {
+             if (FONT_SPEC_P (obj))
+               strout ("#<font-spec", -1, -1, printcharfun, 0);
+             else
+               strout ("#<font-entity", -1, -1, printcharfun, 0);
+             for (i = 0; i < FONT_SPEC_MAX; i++)
+               {
+                 PRINTCHAR (' ');
+                 if (i < FONT_WEIGHT_INDEX || i > FONT_WIDTH_INDEX)
+                   print_object (AREF (obj, i), printcharfun, escapeflag);
+                 else
+                   print_object (font_style_symbolic (obj, i, 0),
+                                 printcharfun, escapeflag);
+               }
+           }
+         else
+           {
+             strout ("#<font-object ", -1, -1, printcharfun, 0);
+             print_object (AREF (obj, FONT_NAME_INDEX), printcharfun,
+                           escapeflag);
+           }
+         PRINTCHAR ('>');
+       }
       else
        {
          EMACS_INT size = XVECTOR (obj)->size;
index 26435f39a778c3ac324024ed3aa02478f90acf63..984b6cf2b5735bd4962a27970bf587d1cf6a04c1 100644 (file)
@@ -43,7 +43,7 @@ Boston, MA 02110-1301, USA.  */
 #endif
 
 #ifndef BASE_PURESIZE
-#define BASE_PURESIZE (1190000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
+#define BASE_PURESIZE (1330000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
 #endif
 
 /* Increase BASE_PURESIZE by a ratio depending on the machine's word size.  */
index a927310fffe6817ad59364577c865405f07ff1a3..0e54fbbc45943925df6f539ca4059996da2ed5a3 100644 (file)
@@ -62,9 +62,8 @@ Boston, MA 02110-1301, USA.  */
 #include <imm.h>
 #define FILE_NAME_TEXT_FIELD edt1
 
-#ifdef USE_FONT_BACKEND
 #include "font.h"
-#endif
+#include "w32font.h"
 
 void syms_of_w32fns ();
 void globals_of_w32fns ();
@@ -74,7 +73,9 @@ extern double atof ();
 extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object));
 extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT));
 extern void w32_free_menu_strings P_ ((HWND));
+#if OLD_FONT
 extern XCharStruct *w32_per_char_metric P_ ((XFontStruct *, wchar_t *, int));
+#endif
 
 extern int quit_char;
 
@@ -342,10 +343,8 @@ extern HMENU current_popup_menu;
 static int menubar_in_use = 0;
 
 /* From w32uniscribe.c  */
-#ifdef USE_FONT_BACKEND
 extern void syms_of_w32uniscribe ();
 extern int uniscribe_available;
-#endif
 
 /* Function prototypes for hourglass support.  */
 static void show_hourglass P_ ((struct frame *));
@@ -4270,7 +4269,6 @@ unwind_create_frame (frame)
   return Qnil;
 }
 
-#ifdef USE_FONT_BACKEND
 static void
 x_default_font_parameter (f, parms)
      struct frame *f;
@@ -4301,7 +4299,6 @@ x_default_font_parameter (f, parms)
     }
   x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
 }
-#endif
 
 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
        1, 1, 0,
@@ -4444,57 +4441,16 @@ This function is an internal primitive--use `make-frame' instead.  */)
   f->resx = dpyinfo->resx;
   f->resy = dpyinfo->resy;
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      /* Perhaps, we must allow frame parameter, say `font-backend',
-        to specify which font backends to use.  */
-      if (uniscribe_available)
-       register_font_driver (&uniscribe_font_driver, f);
-      register_font_driver (&w32font_driver, f);
-
-      x_default_parameter (f, parameters, Qfont_backend, Qnil,
-                          "fontBackend", "FontBackend", RES_TYPE_STRING);
-    }
-#endif /* USE_FONT_BACKEND */
+  if (uniscribe_available)
+    register_font_driver (&uniscribe_font_driver, f);
+  register_font_driver (&w32font_driver, f);
+
+  x_default_parameter (f, parameters, Qfont_backend, Qnil,
+                      "fontBackend", "FontBackend", RES_TYPE_STRING);
 
   /* Extract the window parameters from the supplied values
      that are needed to determine window geometry.  */
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    x_default_font_parameter (f, parameters);
-  else
-#endif 
-  {
-    Lisp_Object font;
-
-    font = w32_get_arg (parameters, Qfont, "font", "Font", RES_TYPE_STRING);
-
-    BLOCK_INPUT;
-    /* First, try whatever font the caller has specified.  */
-    if (STRINGP (font))
-      {
-        tem = Fquery_fontset (font, Qnil);
-        if (STRINGP (tem))
-          font = x_new_fontset (f, tem);
-        else
-          font = x_new_font (f, SDATA (font));
-      }
-    /* Try out a font which we hope has bold and italic variations.  */
-    if (!STRINGP (font))
-      font = x_new_font (f, "-*-Courier New-normal-r-*-*-*-100-*-*-c-*-iso8859-1");
-    if (! STRINGP (font))
-      font = x_new_font (f, "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1");
-    /* If those didn't work, look for something which will at least work.  */
-    if (! STRINGP (font))
-      font = x_new_font (f, "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1");
-    UNBLOCK_INPUT;
-    if (! STRINGP (font))
-      font = build_string ("Fixedsys");
-
-    x_default_parameter (f, parameters, Qfont, font,
-                        "font", "Font", RES_TYPE_STRING);
-  }
+  x_default_font_parameter (f, parameters);
 
   x_default_parameter (f, parameters, Qborder_width, make_number (2),
                       "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
@@ -4683,6 +4639,8 @@ DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
 }
 
 \f
+#if OLD_FONT
+
 /* Return the charset portion of a font name.  */
 char *
 xlfd_charset_of_font (char * fontname)
@@ -5008,6 +4966,7 @@ w32_unload_font (dpyinfo, font)
       xfree (font);
     }
 }
+#endif /* OLD_FONT */
 
 /* The font conversion stuff between x and w32 */
 
@@ -5506,6 +5465,8 @@ w32_to_all_x_charsets (fncharset)
   }
 }
 
+#if OLD_FONT
+
 /* Get the Windows codepage corresponding to the specified font.  The
    charset info in the font name is used to look up
    w32-charset-to-codepage-alist.  */
@@ -5561,7 +5522,7 @@ w32_codepage_for_font (char *fontname)
   else
     return CP_UNKNOWN;
 }
-
+#endif /* OLD_FONT */
 
 static BOOL
 w32_to_x_font (lplogfont, lpxstr, len, specific_charset)
@@ -5847,6 +5808,8 @@ x_to_w32_font (lpxstr, lplogfont)
   return (TRUE);
 }
 
+#if OLD_FONT
+
 /* Strip the pixel height and point height from the given xlfd, and
    return the pixel height. If no pixel height is specified, calculate
    one from the point height, or if that isn't defined either, return
@@ -6560,10 +6523,14 @@ w32_find_ccl_program (fontp)
     }
 }
 
+#endif /* OLD_FONT */
+
 /* directory-files from dired.c.  */
 Lisp_Object Fdirectory_files P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
 
 \f
+#if OLD_FONT
+
 /* Find BDF files in a specified directory.  (use GCPRO when calling,
    as this calls lisp to get a directory listing).  */
 static Lisp_Object
@@ -6614,6 +6581,7 @@ in the list.  DIRECTORY may be a list of directories.  */)
     }
   return list;
 }
+#endif /* OLD_FONT */
 
 \f
 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
@@ -7084,6 +7052,7 @@ If DISPLAY is nil, that stands for the selected frame's display.  */)
     error ("Display still has frames on it");
 
   BLOCK_INPUT;
+#if OLD_FONT
   /* Free the fonts in the font table.  */
   for (i = 0; i < dpyinfo->n_fonts; i++)
     if (dpyinfo->font_table[i].name)
@@ -7093,6 +7062,7 @@ If DISPLAY is nil, that stands for the selected frame's display.  */)
         xfree (dpyinfo->font_table[i].name);
         w32_unload_font (dpyinfo, dpyinfo->font_table[i].font);
       }
+#endif
   x_destroy_all_bitmaps (dpyinfo);
 
   x_delete_display (dpyinfo);
@@ -7523,56 +7493,16 @@ x_create_tip_frame (dpyinfo, parms, text)
   f->resx = dpyinfo->resx;
   f->resy = dpyinfo->resy;
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      /* Perhaps, we must allow frame parameter, say `font-backend',
-        to specify which font backends to use.  */
-      register_font_driver (&w32font_driver, f);
+  /* Perhaps, we must allow frame parameter, say `font-backend',
+     to specify which font backends to use.  */
+  register_font_driver (&w32font_driver, f);
 
-      x_default_parameter (f, parms, Qfont_backend, Qnil,
-                          "fontBackend", "FontBackend", RES_TYPE_STRING);
-    }
-#endif /* USE_FONT_BACKEND */
+  x_default_parameter (f, parms, Qfont_backend, Qnil,
+                      "fontBackend", "FontBackend", RES_TYPE_STRING);
 
   /* Extract the window parameters from the supplied values
      that are needed to determine window geometry.  */
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    x_default_font_parameter (f, parms);
-  else
-#endif /* USE_FONT_BACKEND */
-  {
-    Lisp_Object font;
-
-    font = w32_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
-
-    BLOCK_INPUT;
-    /* First, try whatever font the caller has specified.  */
-    if (STRINGP (font))
-      {
-       tem = Fquery_fontset (font, Qnil);
-       if (STRINGP (tem))
-         font = x_new_fontset (f, tem);
-       else
-         font = x_new_font (f, SDATA (font));
-      }
-
-    /* Try out a font which we hope has bold and italic variations.  */
-    if (!STRINGP (font))
-      font = x_new_font (f, "-*-Courier New-normal-r-*-*-*-100-*-*-c-*-iso8859-1");
-    if (! STRINGP (font))
-      font = x_new_font (f, "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1");
-    /* If those didn't work, look for something which will at least work.  */
-    if (! STRINGP (font))
-      font = x_new_font (f, "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1");
-    UNBLOCK_INPUT;
-    if (! STRINGP (font))
-      font = build_string ("Fixedsys");
-
-    x_default_parameter (f, parms, Qfont, font,
-                        "font", "Font", RES_TYPE_STRING);
-  }
+  x_default_font_parameter (f, parms);
 
   x_default_parameter (f, parms, Qborder_width, make_number (2),
                       "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
@@ -8304,7 +8234,7 @@ in the font selection dialog. */)
   /* Initialize as much of the font details as we can from the current
      default font.  */
   hdc = GetDC (FRAME_W32_WINDOW (f));
-  oldobj = SelectObject (hdc, FRAME_FONT (f)->hfont);
+  oldobj = SelectObject (hdc, FONT_COMPAT (FRAME_FONT (f))->hfont);
   GetTextFace (hdc, LF_FACESIZE, lf.lfFaceName);
   if (GetTextMetrics (hdc, &tm))
     {
@@ -8887,9 +8817,7 @@ frame_parm_handler w32_frame_parm_handlers[] =
   x_set_fringe_width,
   0, /* x_set_wait_for_wm, */
   x_set_fullscreen,
-#ifdef USE_FONT_BACKEND
   x_set_font_backend
-#endif
 };
 
 void
@@ -9286,11 +9214,14 @@ versions of Windows) characters.  */);
   defsubr (&Sw32_reconstruct_hot_key);
   defsubr (&Sw32_toggle_lock_key);
   defsubr (&Sw32_window_exists_p);
+#if OLD_FONT
   defsubr (&Sw32_find_bdf_fonts);
+#endif
 
   defsubr (&Sfile_system_info);
   defsubr (&Sdefault_printer_name);
 
+#if OLD_FONT
   /* Setting callback functions for fontset handler.  */
   get_font_info_func = w32_get_font_info;
 
@@ -9304,6 +9235,7 @@ versions of Windows) characters.  */);
   query_font_func = w32_query_font;
   set_frame_fontset_func = x_set_font;
   get_font_repertory_func = x_get_font_repertory;
+#endif
   check_window_system_func = check_w32;
 
 
@@ -9366,9 +9298,7 @@ globals_of_w32fns ()
   /* MessageBox does not work without this when linked to comctl32.dll 6.0.  */
   InitCommonControls ();
 
-#ifdef USE_FONT_BACKEND
   syms_of_w32uniscribe ();
-#endif
 }
 
 #undef abort
index ed53ff9c4b1993ccd774e5376a769ae5aa3a4a68..3c6d2c4bfad16a726d432aefa7cc8706fc51ec92 100644 (file)
@@ -18,8 +18,6 @@ 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.  */
 
-#ifdef USE_FONT_BACKEND
-
 #include <config.h>
 #include <windows.h>
 #include <math.h>
@@ -55,7 +53,7 @@ static Lisp_Object Qserif, Qscript, Qdecorative;
 static Lisp_Object Qraster, Qoutline, Qunknown;
 
 /* antialiasing  */
-extern Lisp_Object QCantialias, QCotf, QClanguage; /* defined in font.c  */
+extern Lisp_Object QCantialias, QCotf, QClang; /* defined in font.c  */
 extern Lisp_Object Qnone; /* reuse from w32fns.c  */
 static Lisp_Object Qstandard, Qsubpixel, Qnatural;
 
@@ -206,24 +204,24 @@ w32font_list_family (frame)
 /* w32 implementation of open for font backend.
    Open a font specified by FONT_ENTITY on frame F.
    If the font is scalable, open it with PIXEL_SIZE.  */
-static struct font *
+static Lisp_Object
 w32font_open (f, font_entity, pixel_size)
      FRAME_PTR f;
      Lisp_Object font_entity;
      int pixel_size;
 {
-  struct w32font_info *w32_font = xmalloc (sizeof (struct w32font_info));
+  Lisp_Object font_object;
+  struct w32font_info *w32_font;
 
-  if (w32_font == NULL)
-    return NULL;
+  font_object = font_make_object (VECSIZE (struct w32font_info));
+  w32_font = (struct w32font_info *) XFONT_OBJECT (font_object);
 
   if (!w32font_open_internal (f, font_entity, pixel_size, w32_font))
     {
-      xfree (w32_font);
-      return NULL;
+      return Qnil;
     }
 
-  return (struct font *) w32_font;
+  return font_object;
 }
 
 /* w32 implementation of close for font_backend.
@@ -233,21 +231,15 @@ w32font_close (f, font)
      FRAME_PTR f;
      struct font *font;
 {
-  if (font->font.font)
+  struct w32font_info *w32_font = (struct w32font_info *) font;
+
+  if (w32_font->compat_w32_font)
     {
-      W32FontStruct *old_w32_font = (W32FontStruct *)font->font.font;
+      W32FontStruct *old_w32_font = w32_font->compat_w32_font;
       DeleteObject (old_w32_font->hfont);
       xfree (old_w32_font);
-      font->font.font = 0;
+      w32_font->compat_w32_font = 0;
     }
-
-  if (font->font.full_name && font->font.full_name != font->font.name)
-    xfree (font->font.full_name);
-
-  if (font->font.name)
-    xfree (font->font.name);
-
-  xfree (font);
 }
 
 /* w32 implementation of has_char for font backend.
@@ -320,7 +312,7 @@ w32font_encode_char (font, c)
   f = XFRAME (selected_frame);
 
   dc = get_frame_dc (f);
-  old_font = SelectObject (dc, ((W32FontStruct *) (font->font.font))->hfont);
+  old_font = SelectObject (dc, w32_font->compat_w32_font->hfont);
 
   retval = GetCharacterPlacementW (dc, in, len, 0, &result, 0);
 
@@ -419,8 +411,7 @@ w32font_text_extents (font, code, nglyphs, metrics)
                  f = XFRAME (selected_frame);
   
                   dc = get_frame_dc (f);
-                  old_font = SelectObject (dc, ((W32FontStruct *)
-                                                (font->font.font))->hfont);
+                  old_font = SelectObject (dc, FONT_COMPAT (font)->hfont);
                }
              compute_metrics (dc, w32_font, *(code + i), char_metric);
            }
@@ -477,8 +468,7 @@ w32font_text_extents (font, code, nglyphs, metrics)
       f = XFRAME (selected_frame);
 
       dc = get_frame_dc (f);
-      old_font = SelectObject (dc, ((W32FontStruct *)
-                                    (font->font.font))->hfont);
+      old_font = SelectObject (dc, FONT_COMPAT (font)->hfont);
     }
 
   if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size))
@@ -491,7 +481,7 @@ w32font_text_extents (font, code, nglyphs, metrics)
   if (!total_width)
     {
       RECT rect;
-      rect.top = 0; rect.bottom = font->font.height; rect.left = 0; rect.right = 1;
+      rect.top = 0; rect.bottom = font->height; rect.left = 0; rect.right = 1;
       DrawTextW (dc, wcode, nglyphs, &rect,
                  DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
       total_width = rect.right;
@@ -533,7 +523,7 @@ w32font_draw (s, from, to, x, y, with_background)
 {
   UINT options;
   HRGN orig_clip;
-  struct w32font_info *w32font = (struct w32font_info *) s->face->font_info;
+  struct w32font_info *w32font = (struct w32font_info *) s->face->font;
 
   options = w32font->glyph_idx;
 
@@ -563,7 +553,7 @@ w32font_draw (s, from, to, x, y, with_background)
     {
       HBRUSH brush;
       RECT rect;
-      struct font *font = (struct font *) s->face->font_info;
+      struct font *font = s->face->font;
 
       brush = CreateSolidBrush (s->gc->background);
       rect.left = x;
@@ -719,7 +709,7 @@ w32font_list_internal (frame, font_spec, opentype_only)
       release_frame_dc (f, dc);
     }
 
-  return NILP (match_data.list) ? null_vector : Fvconcat (1, &match_data.list);
+  return NILP (match_data.list) ? Qnil : match_data.list;
 }
 
 /* Internal implementation of w32font_match.
@@ -803,8 +793,8 @@ w32font_open_internal (f, font_entity, pixel_size, w32_font)
 
   /* W32FontStruct - we should get rid of this, and use the w32font_info
      struct for any W32 specific fields. font->font.font can then be hfont.  */
-  font->font.font = xmalloc (sizeof (W32FontStruct));
-  compat_w32_font = (W32FontStruct *) font->font.font;
+  w32_font->compat_w32_font = xmalloc (sizeof (W32FontStruct));
+  compat_w32_font = w32_font->compat_w32_font;
   bzero (compat_w32_font, sizeof (W32FontStruct));
   compat_w32_font->font_type = UNICODE_FONT;
   /* Duplicate the text metrics.  */
@@ -812,9 +802,7 @@ w32font_open_internal (f, font_entity, pixel_size, w32_font)
   compat_w32_font->hfont = hfont;
 
   len = strlen (logfont.lfFaceName);
-  font->font.name = (char *) xmalloc (len + 1);
-  bcopy (logfont.lfFaceName, font->font.name, len);
-  font->font.name[len] = '\0';
+  font->props[FONT_NAME_INDEX] = make_unibyte_string (logfont.lfFaceName, len);
 
   {
     char *name;
@@ -833,25 +821,23 @@ w32font_open_internal (f, font_entity, pixel_size, w32_font)
         name = new;
       }
     if (name)
-      font->font.full_name = name;
+      font->props[FONT_FULLNAME_INDEX]
+       = make_unibyte_string (name, strlen (name));
     else
-      font->font.full_name = font->font.name;
+      font->props[FONT_FULLNAME_INDEX] = font->props[FONT_NAME_INDEX];
   }
-  font->font.charset = 0;
-  font->font.codepage = 0;
-  font->font.size = w32_font->metrics.tmMaxCharWidth;
-  font->font.height = w32_font->metrics.tmHeight
+  font->codepage = 0;
+  font->max_width = w32_font->metrics.tmMaxCharWidth;
+  font->height = w32_font->metrics.tmHeight
     + w32_font->metrics.tmExternalLeading;
-  font->font.space_width = font->font.average_width
-    = w32_font->metrics.tmAveCharWidth;
-
-  font->font.vertical_centering = 0;
-  font->font.encoding_type = 0;
-  font->font.baseline_offset = 0;
-  font->font.relative_compose = 0;
-  font->font.default_ascent = w32_font->metrics.tmAscent;
-  font->font.font_encoder = NULL;
-  font->entity = font_entity;
+  font->space_width = font->average_width = w32_font->metrics.tmAveCharWidth;
+
+  font->vertical_centering = 0;
+  font->encoding_type = 0;
+  font->baseline_offset = 0;
+  font->relative_compose = 0;
+  font->default_ascent = w32_font->metrics.tmAscent;
+  font->font_encoder = NULL;
   font->pixel_size = size;
   font->driver = &w32font_driver;
   /* Use format cached during list, as the information we have access to
@@ -861,56 +847,26 @@ w32font_open_internal (f, font_entity, pixel_size, w32_font)
     {
       val = assq_no_quit (QCformat, extra);
       if (CONSP (val))
-        font->format = XCDR (val);
+        font->props[FONT_FORMAT_INDEX] = XCDR (val);
       else
-        font->format = Qunknown;
+        font->props[FONT_FORMAT_INDEX] = Qunknown;
     }
   else
-    font->format = Qunknown;
+    font->props[FONT_FORMAT_INDEX] = Qunknown;
 
-  font->file_name = NULL;
+  font->props[FONT_FILE_INDEX] = Qnil;
   font->encoding_charset = -1;
   font->repertory_charset = -1;
   /* TODO: do we really want the minimum width here, which could be negative? */
-  font->min_width = font->font.space_width;
+  font->min_width = font->space_width;
   font->ascent = w32_font->metrics.tmAscent;
   font->descent = w32_font->metrics.tmDescent;
-  font->scalable = w32_font->metrics.tmPitchAndFamily & TMPF_VECTOR;
 
   /* max_descent is used for underlining in w32term.c.  Hopefully this
      is temporary, as we'll want to get rid of the old compatibility
      stuff later.  */
   compat_w32_font->max_bounds.descent = font->descent;
 
-  /* Set global flag fonts_changed_p to non-zero if the font loaded
-     has a character with a smaller width than any other character
-     before, or if the font loaded has a smaller height than any other
-     font loaded before.  If this happens, it will make a glyph matrix
-     reallocation necessary.  */
-  {
-    struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
-    dpyinfo->n_fonts++;
-
-    if (dpyinfo->n_fonts == 1)
-      {
-        dpyinfo->smallest_font_height = font->font.height;
-        dpyinfo->smallest_char_width = font->min_width;
-      }
-    else
-      {
-        if (dpyinfo->smallest_font_height > font->font.height)
-          {
-            dpyinfo->smallest_font_height = font->font.height;
-            fonts_changed_p |= 1;
-          }
-        if (dpyinfo->smallest_char_width > font->min_width)
-          {
-            dpyinfo->smallest_char_width = font->min_width;
-            fonts_changed_p |= 1;
-          }
-      }
-  }
-
   return 1;
 }
 
@@ -930,14 +886,17 @@ add_font_name_to_list (logical_font, physical_font, font_type, list_object)
   if (logical_font->elfLogFont.lfFaceName[0] == '@')
     return 1;
 
-  family = intern_downcase (logical_font->elfLogFont.lfFaceName,
-                            strlen (logical_font->elfLogFont.lfFaceName));
+  family = font_intern_prop (logical_font->elfLogFont.lfFaceName,
+                            strlen (logical_font->elfLogFont.lfFaceName));
   if (! memq_no_quit (family, *list))
     *list = Fcons (family, *list);
 
   return 1;
 }
 
+static int w32_decode_weight P_ ((int));
+static int w32_encode_weight P_ ((int));
+
 /* Convert an enumerated Windows font to an Emacs font entity.  */
 static Lisp_Object
 w32_enumfont_pattern_entity (frame, logical_font, physical_font,
@@ -954,16 +913,15 @@ w32_enumfont_pattern_entity (frame, logical_font, physical_font,
   BYTE generic_type;
   DWORD full_type = physical_font->ntmTm.ntmFlags;
 
-  entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil);
+  entity = font_make_entity ();
 
   ASET (entity, FONT_TYPE_INDEX, backend);
-  ASET (entity, FONT_FRAME_INDEX, frame);
   ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet, font_type));
   ASET (entity, FONT_OBJLIST_INDEX, Qnil);
 
   /* Foundry is difficult to get in readable form on Windows.
      But Emacs crashes if it is not set, so set it to something more
-     generic.  Thes values make xflds compatible with Emacs 22. */
+     generic.  These values make xflds compatible with Emacs 22. */
   if (lf->lfOutPrecision == OUT_STRING_PRECIS)
     tem = Qraster;
   else if (lf->lfOutPrecision == OUT_STROKE_PRECIS)
@@ -987,14 +945,14 @@ w32_enumfont_pattern_entity (frame, logical_font, physical_font,
   else if (generic_type == FF_SWISS)
     tem = Qsans;
   else
-    tem = null_string;
+    tem = Qnil;
 
   ASET (entity, FONT_ADSTYLE_INDEX, tem);
 
   if (physical_font->ntmTm.tmPitchAndFamily & 0x01)
-    font_put_extra (entity, QCspacing, make_number (FONT_SPACING_PROPORTIONAL));
+    ASET (entity, FONT_SPACING_INDEX, make_number (FONT_SPACING_PROPORTIONAL));
   else
-    font_put_extra (entity, QCspacing, make_number (FONT_SPACING_MONO));
+    ASET (entity, FONT_SPACING_INDEX, make_number (FONT_SPACING_MONO));
 
   if (requested_font->lfQuality != DEFAULT_QUALITY)
     {
@@ -1002,13 +960,15 @@ w32_enumfont_pattern_entity (frame, logical_font, physical_font,
                       lispy_antialias_type (requested_font->lfQuality));
     }
   ASET (entity, FONT_FAMILY_INDEX,
-        intern_downcase (lf->lfFaceName, strlen (lf->lfFaceName)));
+        font_intern_prop (lf->lfFaceName, strlen (lf->lfFaceName)));
 
-  ASET (entity, FONT_WEIGHT_INDEX, make_number (lf->lfWeight));
-  ASET (entity, FONT_SLANT_INDEX, make_number (lf->lfItalic ? 200 : 100));
+  FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
+                 make_number (w32_decode_weight (lf->lfWeight)));
+  FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
+                 make_number (lf->lfItalic ? 200 : 100));
   /* TODO: PANOSE struct has this info, but need to call GetOutlineTextMetrics
      to get it.  */
-  ASET (entity, FONT_WIDTH_INDEX, make_number (100));
+  FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, make_number (100));
 
   if (font_type & RASTER_FONTTYPE)
     ASET (entity, FONT_SIZE_INDEX, make_number (physical_font->ntmTm.tmHeight));
@@ -1098,14 +1058,14 @@ font_matches_spec (type, font, spec, backend, logfont)
 
   /* Check italic. Can't check logfonts, since it is a boolean field,
      so there is no difference between "non-italic" and "don't care".  */
-  val = AREF (spec, FONT_SLANT_INDEX);
-  if (INTEGERP (val))
-    {
-      int slant = XINT (val);
-      if ((slant > 150 && !font->ntmTm.tmItalic)
-          || (slant <= 150 && font->ntmTm.tmItalic))
-        return 0;
-    }
+  {
+    int slant = FONT_SLANT_NUMERIC (spec);
+
+    if (slant >= 0
+       && ((slant > 150 && !font->ntmTm.tmItalic)
+           || (slant <= 150 && font->ntmTm.tmItalic)))
+         return 0;
+  }
 
   /* Check adstyle against generic family.  */
   val = AREF (spec, FONT_ADSTYLE_INDEX);
@@ -1117,6 +1077,18 @@ font_matches_spec (type, font, spec, backend, logfont)
         return 0;
     }
 
+  /* Check spacing */
+  val = AREF (spec, FONT_SPACING_INDEX);
+  if (INTEGERP (val))
+    {
+      int spacing = XINT (val);
+      int proportional = (spacing < FONT_SPACING_MONO);
+
+      if ((proportional && !(font->ntmTm.tmPitchAndFamily & 0x01))
+         || (!proportional && (font->ntmTm.tmPitchAndFamily & 0x01)))
+       return 0;
+    }
+
   /* Check extra parameters.  */
   for (extra = AREF (spec, FONT_EXTRA_INDEX);
        CONSP (extra); extra = XCDR (extra))
@@ -1126,27 +1098,9 @@ font_matches_spec (type, font, spec, backend, logfont)
       if (CONSP (extra_entry))
         {
           Lisp_Object key = XCAR (extra_entry);
-          val = XCDR (extra_entry);
-          if (EQ (key, QCspacing))
-            {
-              int proportional;
-              if (INTEGERP (val))
-                {
-                  int spacing = XINT (val);
-                  proportional = (spacing < FONT_SPACING_MONO);
-                }
-              else if (EQ (val, Qp))
-                proportional = 1;
-              else if (EQ (val, Qc) || EQ (val, Qm))
-                proportional = 0;
-              else
-                return 0; /* Bad font spec.  */
 
-              if ((proportional && !(font->ntmTm.tmPitchAndFamily & 0x01))
-                  || (!proportional && (font->ntmTm.tmPitchAndFamily & 0x01)))
-                return 0;
-            }
-          else if (EQ (key, QCscript) && SYMBOLP (val))
+          val = XCDR (extra_entry);
+          if (EQ (key, QCscript) && SYMBOLP (val))
             {
               /* Only truetype fonts will have information about what
                  scripts they support.  This probably means the user
@@ -1234,7 +1188,7 @@ font_matches_spec (type, font, spec, backend, logfont)
                     return 0;
                 }
             }
-         else if (EQ (key, QClanguage) && SYMBOLP (val))
+         else if (EQ (key, QClang) && SYMBOLP (val))
            {
              /* Just handle the CJK languages here, as the language
                 parameter is used to select a font with appropriate
@@ -1401,10 +1355,55 @@ w32_registry (w32_charset, font_type)
   else
     {
       char * charset = w32_to_x_charset (w32_charset, NULL);
-      return intern_downcase (charset, strlen(charset));
+      return font_intern_prop (charset, strlen(charset));
     }
 }
 
+static struct
+{
+  unsigned w32_numeric;
+  unsigned numeric;
+} w32_weight_table[] =
+  { { FW_THIN, 0 },
+    { FW_EXTRALIGHT, 40 },
+    { FW_LIGHT, 50},
+    { FW_NORMAL, 100},
+    { FW_MEDIUM, 100},
+    { FW_SEMIBOLD, 180},
+    { FW_BOLD, 200},
+    { FW_EXTRABOLD, 205},
+    { FW_HEAVY, 210} };
+
+static int
+w32_decode_weight (fnweight)
+     int fnweight;
+{
+  if (fnweight >= FW_HEAVY)      return 210;
+  if (fnweight >= FW_EXTRABOLD)  return 205;
+  if (fnweight >= FW_BOLD)       return 200;
+  if (fnweight >= FW_SEMIBOLD)   return 180;
+  if (fnweight >= FW_NORMAL)     return 100;
+  if (fnweight >= FW_LIGHT)      return 50;
+  if (fnweight >= FW_EXTRALIGHT) return 40;
+  if (fnweight > FW_THIN)        return 20;
+  return 0;
+}
+
+static int
+w32_encode_weight (n)
+     int n;
+{
+  if (n >= 210) return FW_HEAVY;
+  if (n >= 205) return FW_EXTRABOLD;
+  if (n >= 200) return FW_BOLD;
+  if (n >= 180) return FW_SEMIBOLD;
+  if (n >= 100) return FW_NORMAL;
+  if (n >= 50)  return FW_LIGHT;
+  if (n >= 40)  return FW_EXTRALIGHT;
+  if (n >= 20)  return  FW_THIN;
+  return 0;
+}
+
 /* Fill in all the available details of LOGFONT from FONT_SPEC.  */
 static void
 fill_in_logfont (f, logfont, font_spec)
@@ -1415,19 +1414,14 @@ fill_in_logfont (f, logfont, font_spec)
   Lisp_Object tmp, extra;
   int dpi = FRAME_W32_DISPLAY_INFO (f)->resy;
 
-  extra = AREF (font_spec, FONT_EXTRA_INDEX);
-  /* Allow user to override dpi settings.  */
-  if (CONSP (extra))
+  tmp = AREF (font_spec, FONT_DPI_INDEX);
+  if (INTEGERP (tmp))
     {
-      tmp = assq_no_quit (QCdpi, extra);
-      if (CONSP (tmp) && INTEGERP (XCDR (tmp)))
-        {
-          dpi = XINT (XCDR (tmp));
-        }
-      else if (CONSP (tmp) && FLOATP (XCDR (tmp)))
-        {
-          dpi = (int) (XFLOAT_DATA (XCDR (tmp)) + 0.5);
-        }
+      dpi = XINT (tmp);
+    }
+  else if (FLOATP (tmp))
+    {
+      dpi = (int) (XFLOAT_DATA (tmp) + 0.5);
     }
 
   /* Height  */
@@ -1444,13 +1438,13 @@ fill_in_logfont (f, logfont, font_spec)
   /* Weight  */
   tmp = AREF (font_spec, FONT_WEIGHT_INDEX);
   if (INTEGERP (tmp))
-    logfont->lfWeight = XINT (tmp);
+    logfont->lfWeight = w32_encode_weight (FONT_WEIGHT_NUMERIC (font_spec));
 
   /* Italic  */
   tmp = AREF (font_spec, FONT_SLANT_INDEX);
   if (INTEGERP (tmp))
     {
-      int slant = XINT (tmp);
+      int slant = FONT_SLANT_NUMERIC (font_spec);
       logfont->lfItalic = slant > 150 ? 1 : 0;
     }
 
@@ -1496,41 +1490,36 @@ fill_in_logfont (f, logfont, font_spec)
         logfont->lfPitchAndFamily = family | DEFAULT_PITCH;
     }
 
+                                          
+  /* Set pitch based on the spacing property.  */
+  tmp = AREF (font_spec, FONT_SPACING_INDEX);
+  if (INTEGERP (tmp))
+    {
+      int spacing = XINT (tmp);
+      if (spacing < FONT_SPACING_MONO)
+       logfont->lfPitchAndFamily
+         = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
+      else
+       logfont->lfPitchAndFamily
+         = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
+    }
+
   /* Process EXTRA info.  */
-  for ( ; CONSP (extra); extra = XCDR (extra))
+  for (extra = AREF (font_spec, FONT_EXTRA_INDEX);
+       CONSP (extra); extra = XCDR (extra))
     {
       tmp = XCAR (extra);
       if (CONSP (tmp))
         {
           Lisp_Object key, val;
           key = XCAR (tmp), val = XCDR (tmp);
-          if (EQ (key, QCspacing))
-            {
-              /* Set pitch based on the spacing property.  */
-              if (INTEGERP (val))
-                {
-                  int spacing = XINT (val);
-                  if (spacing < FONT_SPACING_MONO)
-                    logfont->lfPitchAndFamily
-                      = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
-                  else
-                    logfont->lfPitchAndFamily
-                      = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
-                }
-              else if (EQ (val, Qp))
-                logfont->lfPitchAndFamily
-                  = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
-              else if (EQ (val, Qc) || EQ (val, Qm))
-                logfont->lfPitchAndFamily
-                  = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
-            }
           /* Only use QCscript if charset is not provided, or is unicode
              and a single script is specified.  This is rather crude,
              and is only used to narrow down the fonts returned where
              there is a definite match.  Some scripts, such as latin, han,
              cjk-misc match multiple lfCharSet values, so we can't pre-filter
              them.  */
-          else if (EQ (key, QCscript)
+         if (EQ (key, QCscript)
                    && logfont->lfCharSet == DEFAULT_CHARSET
                    && SYMBOLP (val))
             {
@@ -1797,7 +1786,7 @@ w32font_full_name (font, font_obj, pixel_size, name, nbytes)
 
   if (font->lfWeight && font->lfWeight != FW_NORMAL)
     {
-      weight = font_symbolic_weight (font_obj);
+      weight = FONT_WEIGHT_SYMBOLIC (font_obj);
       len += 8 + SBYTES (SYMBOL_NAME (weight)); /* :weight=NAME */
     }
 
@@ -1893,6 +1882,7 @@ clear_cached_metrics (w32_font)
 struct font_driver w32font_driver =
   {
     0, /* Qgdi */
+    0, /* case insensitive */
     w32font_get_cache,
     w32font_list,
     w32font_match,
@@ -2029,7 +2019,6 @@ syms_of_w32font ()
   w32font_driver.type = Qgdi;
   register_font_driver (&w32font_driver, NULL);
 }
-#endif /* USE_FONT_BACKEND  */
 
 /* arch-tag: 65b8a3cd-46aa-4c0d-a1f3-99e75b9c07ee
    (do not change this comment) */
index 6345d59c71fffc4ec08019165b9686d16e1e0a81..10edec4845ad9f87b21b25a2753d1fe66dbe1896 100644 (file)
@@ -55,8 +55,11 @@ struct w32font_info
   unsigned int glyph_idx;
   struct w32_metric_cache **cached_metrics;
   int n_cache_blocks;
+  W32FontStruct *compat_w32_font;
 };
 
+#define FONT_COMPAT(f) (((struct w32font_info *) (f))->compat_w32_font)
+
 #define CACHE_BLOCKSIZE 128
 
 Lisp_Object w32font_get_cache P_ ((FRAME_PTR fe));
index b0faa3e597d6017ad7e1365573986ca570007caa..f0e07680475bbbdb8316a37648a28ecdb6d46966 100644 (file)
@@ -63,7 +63,10 @@ typedef struct _XGCValues
 {
   COLORREF foreground;
   COLORREF background;
+#if OLD_FONT
   XFontStruct * font;
+#endif
+  struct font *font;
 } XGCValues;
 
 #define GCForeground 0x01
index a40fe2edc4878904aefd63a38f7a5acc3e774a44..5e416c12f1624571ec542ccbe25b351195308543 100644 (file)
@@ -59,10 +59,8 @@ Boston, MA 02110-1301, USA.  */
 #include "w32bdf.h"
 #include <shellapi.h>
 
-#ifdef USE_FONT_BACKEND
 #include "font.h"
-#endif /* USE_FONT_BACKEND */
-
+#include "w32font.h"
 \f
 /* Fringe bitmaps.  */
 
@@ -896,6 +894,8 @@ w32_reset_terminal_modes (struct terminal *term)
 
 /* Function prototypes of this page.  */
 
+#if OLD_FONT
+
 XCharStruct *w32_per_char_metric P_ ((XFontStruct *, wchar_t *, int));
 static int w32_encode_char P_ ((int, wchar_t *, struct font_info *,
                                struct charset *, int *));
@@ -1140,7 +1140,6 @@ w32_cache_char_metrics (font)
     }
 }
 
-
 /* Determine if a font is double byte. */
 static int
 w32_font_is_double_byte (XFontStruct *font)
@@ -1483,6 +1482,7 @@ w32_text_out (s, x, y,chars,nchars)
                 nchars * charset_dim, NULL);
 }
 
+#endif /* OLD_FONT */
 
 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
@@ -1594,11 +1594,6 @@ x_set_mouse_face_gc (s)
   /* If font in this face is same as S->font, use it.  */
   if (s->font == s->face->font)
     s->gc = s->face->gc;
-#ifdef USE_FONT_BACKEND
-  else if (enable_font_backend)
-    /* No need of setting a font for s->gc.  */
-    s->gc = s->face->gc;
-#endif /* USE_FONT_BACKEND */
   else
     {
       /* Otherwise construct scratch_cursor_gc with values from FACE
@@ -1692,11 +1687,7 @@ static INLINE void
 x_set_glyph_string_clipping (s)
      struct glyph_string *s;
 {
-#ifdef USE_FONT_BACKEND
   RECT *r = s->clip;
-#else
-  RECT r[2];
-#endif
   int n = get_glyph_string_clip_rects (s, r, 2);
 
   if (n == 1)
@@ -1714,9 +1705,7 @@ x_set_glyph_string_clipping (s)
       DeleteObject (clip2);
       DeleteObject (full_clip);
     }
-#ifdef USE_FONT_BACKEND
     s->num_clips = n;
-#endif /* USE_FONT_BACKEND */
 }
 
 /* Set SRC's clipping for output of glyph string DST.  This is called
@@ -1729,19 +1718,14 @@ x_set_glyph_string_clipping_exactly (src, dst)
 {
   RECT r;
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      r.left = src->x;
-      r.right = r.left + src->width;
-      r.top = src->y;
-      r.bottom = r.top + src->height;
-      dst->clip[0] = r;
-      dst->num_clips = 1;
-    }
-  else
+  r.left = src->x;
+  r.right = r.left + src->width;
+  r.top = src->y;
+  r.bottom = r.top + src->height;
+  dst->clip[0] = r;
+  dst->num_clips = 1;
+#if OLD_FONT
     {
-#endif /* USE_FONT_BACKEND */
   struct glyph_string *clip_head = src->clip_head;
   struct glyph_string *clip_tail = src->clip_tail;
 
@@ -1749,9 +1733,8 @@ x_set_glyph_string_clipping_exactly (src, dst)
   src->clip_head = src->clip_tail = src;
   get_glyph_string_clip_rect (src, &r);
   src->clip_head = clip_head, src->clip_tail = clip_tail;
-#ifdef USE_FONT_BACKEND
     }
-#endif /* USE_FONT_BACKEND */
+#endif /* OLD_FONT */
   w32_set_clip_rectangle (dst->hdc, &r);
 }
 
@@ -1766,26 +1749,17 @@ w32_compute_glyph_string_overhangs (s)
   if (s->cmp == NULL
       && s->first_glyph->type == CHAR_GLYPH)
     {
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend)
-       {
-         unsigned *code = alloca (sizeof (unsigned) * s->nchars);
-         struct font *font = (struct font *) s->font_info;
-         struct font_metrics metrics;
-         int i;
+      unsigned *code = alloca (sizeof (unsigned) * s->nchars);
+      struct font *font = s->font;
+      struct font_metrics metrics;
+      int i;
 
-         for (i = 0; i < s->nchars; i++)
-           code[i] = s->char2b[i];
-         font->driver->text_extents (font, code, s->nchars, &metrics);
-         s->right_overhang = (metrics.rbearing > metrics.width
-                              ? metrics.rbearing - metrics.width : 0);
-         s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
-       }
-#else
-  /* TODO: Windows does not appear to have a method for
-     getting this info without getting the ABC widths for each
-     individual character and working it out manually. */
-#endif
+      for (i = 0; i < s->nchars; i++)
+       code[i] = s->char2b[i];
+      font->driver->text_extents (font, code, s->nchars, &metrics);
+      s->right_overhang = (metrics.rbearing > metrics.width
+                          ? metrics.rbearing - metrics.width : 0);
+      s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
     }
   else if (s->cmp)
     {
@@ -1870,7 +1844,7 @@ x_draw_glyph_string_background (s, force_p)
         if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
               || s->font_not_found_p
               || s->extends_to_end_of_line_p
-               || s->font->bdf
+              || FONT_COMPAT (s->font)->bdf
               || cleartype_active
               || force_p)
        {
@@ -1910,8 +1884,8 @@ x_draw_glyph_string_foreground (s)
   SetBkColor (s->hdc, s->gc->background);
   SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
 
-  if (s->font && s->font->hfont)
-    old_font = SelectObject (s->hdc, s->font->hfont);
+  if (s->font && FONT_COMPAT (s->font)->hfont)
+    old_font = SelectObject (s->hdc, FONT_COMPAT (s->font)->hfont);
 
   /* Draw characters of S as rectangles if S's font could not be
      loaded. */
@@ -1926,14 +1900,13 @@ x_draw_glyph_string_foreground (s)
           x += g->pixel_width;
         }
     }
-#ifdef USE_FONT_BACKEND
-  else if (enable_font_backend)
+
     {
-      int boff = s->font_info->baseline_offset;
-      struct font *font = (struct font *) s->font_info;
+      int boff = s->font->baseline_offset;
+      struct font *font = s->font;
       int y;
 
-      if (s->font_info->vertical_centering)
+      if (s->font->vertical_centering)
        boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
 
       y = s->ybase - boff;
@@ -1945,34 +1918,8 @@ x_draw_glyph_string_foreground (s)
       if (s->face->overstrike)
        font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
     }
-#endif /* USE_FONT_BACKEND */
-  else
-    {
-      char *char1b = (char *) s->char2b;
-      int boff = s->font_info->baseline_offset;
-
-      if (s->font_info->vertical_centering)
-       boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
-
-      /* If we can use 8-bit functions, condense S->char2b.  */
-      if (!s->two_byte_p)
-        for (i = 0; i < s->nchars; ++i)
-          char1b[i] = XCHAR2B_BYTE2 (&s->char2b[i]);
 
-      /* Draw text with TextOut and friends. */
-      w32_text_out (s, x, s->ybase - boff, s->char2b, s->nchars);
-
-      if (s->face->overstrike)
-       {
-         /* For overstriking (to simulate bold-face), draw the
-            characters again shifted to the right by one pixel.  */
-         int old_BkMode = SetBkMode (s->hdc, TRANSPARENT);
-         w32_text_out (s, x + 1, s->ybase - boff, s->char2b, s->nchars);
-         if (old_BkMode && old_BkMode != TRANSPARENT)
-           SetBkMode (s->hdc, old_BkMode);
-       }
-    }
-  if (s->font && s->font->hfont)
+  if (s->font && FONT_COMPAT (s->font)->hfont)
     SelectObject (s->hdc, old_font);
 }
 
@@ -2003,8 +1950,8 @@ x_draw_composite_glyph_string_foreground (s)
   SetBkMode (s->hdc, TRANSPARENT);
   SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
 
-  if (s->font && s->font->hfont)
-    old_font = SelectObject (s->hdc, s->font->hfont);
+  if (s->font && FONT_COMPAT (s->font)->hfont)
+    old_font = SelectObject (s->hdc, FONT_COMPAT (s->font)->hfont);
 
   /* Draw a rectangle for the composition if the font for the very
      first character of the composition could not be loaded.  */
@@ -2014,10 +1961,9 @@ x_draw_composite_glyph_string_foreground (s)
         w32_draw_rectangle (s->hdc, s->gc, x, s->y, s->width - 1,
                             s->height - 1);
     }
-#ifdef USE_FONT_BACKEND
-  else if (enable_font_backend)
+
     {
-      struct font *font = (struct font *) s->font_info;
+      struct font *font = s->font;
       int y = s->ybase;
       int width = 0;
 
@@ -2070,23 +2016,8 @@ x_draw_composite_glyph_string_foreground (s)
              }
        }
     }
-#endif /* USE_FONT_BACKEND */
-  else
-    {
-      for (i = 0, j = s->gidx; i < s->nchars; i++, j++)
-       if (s->face)
-          {
-            w32_text_out (s, x + s->cmp->offsets[j * 2],
-                          s->ybase - s->cmp->offsets[j * 2 + 1],
-                          s->char2b + j, 1);
-            if (s->face->overstrike)
-           w32_text_out (s, x + s->cmp->offsets[j * 2] + 1,
-                         s->ybase - s->cmp->offsets[j + 1],
-                         s->char2b + j, 1);
-          }
-    }
 
-  if (s->font && s->font->hfont)
+  if (s->font && FONT_COMPAT (s->font)->hfont)
     SelectObject (s->hdc, old_font);
 }
 
@@ -2894,9 +2825,7 @@ x_draw_glyph_string (s)
             x_set_glyph_string_gc (next);
             x_set_glyph_string_clipping (next);
             x_draw_glyph_string_background (next, 1);
-#ifdef USE_FONT_BACKEND
             next->num_clips = 0;
-#endif /* USE_FONT_BACKEND */
           }
     }
 
@@ -2960,30 +2889,21 @@ x_draw_glyph_string (s)
     {
       /* Draw underline.  */
       if (s->face->underline_p
-          && (s->font->bdf || !s->font->tm.tmUnderlined))
+          && (FONT_COMPAT (s->font)->bdf
+             || !FONT_COMPAT (s->font)->tm.tmUnderlined))
         {
           unsigned long h;
           int y;
          /* Get the underline thickness.  Default is 1 pixel.  */
-#ifdef USE_FONT_BACKEND
-         if (enable_font_backend)
-           /* In the future, we must use information of font.  */
-           h = 1;
-         else
-#endif /* USE_FONT_BACKEND */
-            h = 1;
+         /* In the future, we must use information of font.  */
+         h = 1;
 
-#ifdef USE_FONT_BACKEND
-         if (enable_font_backend)
-           {
-             if (s->face->font)
-               /* In the future, we must use information of font.  */
-               y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
-             else
-               y = s->y + s->height - h;
-           }
+         if (s->face->font)
+           /* In the future, we must use information of font.  */
+           y = s->ybase + (s->face->font->descent + 1) / 2;
          else
-#endif
+           y = s->y + s->height - h;
+#if OLD_FONT
             {
                 y = s->y + s->height - h;
                 /* TODO: Use font information for positioning and
@@ -2999,6 +2919,7 @@ x_draw_glyph_string (s)
                 }
 #endif
             }
+#endif /* OLD_FONT */
           if (s->face->underline_defaulted_p)
             {
               w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
@@ -3029,7 +2950,8 @@ x_draw_glyph_string (s)
 
       /* Draw strike-through.  */
       if (s->face->strike_through_p
-          && (s->font->bdf || !s->font->tm.tmStruckOut))
+          && (FONT_COMPAT (s->font)->bdf
+             || !FONT_COMPAT (s->font)->tm.tmStruckOut))
         {
           unsigned long h = 1;
           unsigned long dy = (s->height - h) / 2;
@@ -3071,9 +2993,7 @@ x_draw_glyph_string (s)
                  x_draw_composite_glyph_string_foreground (prev);
                 w32_set_clip_rectangle (prev->hdc, NULL);
                prev->hl = save;
-#ifdef USE_FONT_BACKEND
                prev->num_clips = 0;
-#endif /* USE_FONT_BACKEND */
              }
        }
 
@@ -3098,18 +3018,14 @@ x_draw_glyph_string (s)
                  x_draw_composite_glyph_string_foreground (next);
                 w32_set_clip_rectangle (next->hdc, NULL);
                next->hl = save;
-#ifdef USE_FONT_BACKEND
                next->num_clips = 0;
-#endif /* USE_FONT_BACKEND */
              }
        }
     }
 
   /* Reset clipping.  */
   w32_set_clip_rectangle (s->hdc, NULL);
-#ifdef USE_FONT_BACKEND
   s->num_clips = 0;
-#endif /* USE_FONT_BACKEND */
 }
 
 
@@ -5853,6 +5769,8 @@ x_io_error_quitter (display)
 \f
 /* Changing the font of the frame.  */
 
+#if OLD_FONT
+
 /* Give frame F the font named FONTNAME as its default font, and
    return the full name of that font.  FONTNAME may be a wildcard
    pattern; in that case, we choose some font that fits the pattern.
@@ -5951,31 +5869,32 @@ x_new_fontset (f, fontsetname)
 
   return fontset_name (fontset);
 }
+#endif /* OLD_FONT */
+
 
-#ifdef USE_FONT_BACKEND
 Lisp_Object
-x_new_fontset2 (f, fontset, font_object)
+x_new_font (f, font_object, fontset)
      struct frame *f;
-     int fontset;
      Lisp_Object font_object;
+     int fontset;
 {
-  struct font *font = XSAVE_VALUE (font_object)->pointer;
+  struct font *font = XFONT_OBJECT (font_object);
 
-  if (FRAME_FONT_OBJECT (f) == font)
+  if (fontset < 0)
+    fontset = fontset_from_font (font_object);
+  FRAME_FONTSET (f) = fontset;
+  if (FRAME_FONT (f) == font)
     /* This font is already set in frame F.  There's nothing more to
        do.  */
     return fontset_name (fontset);
 
   BLOCK_INPUT;
 
-  FRAME_FONT_OBJECT (f) = font;
-  FRAME_FONT (f) = font->font.font;
-  FRAME_BASELINE_OFFSET (f) = font->font.baseline_offset;
-  FRAME_FONTSET (f) = fontset;
-
-  FRAME_COLUMN_WIDTH (f) = font->font.average_width;
-  FRAME_SPACE_WIDTH (f) = font->font.space_width;
-  FRAME_LINE_HEIGHT (f) = font->font.height;
+  FRAME_FONT (f) = font;
+  FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
+  FRAME_COLUMN_WIDTH (f) = font->average_width;
+  FRAME_SPACE_WIDTH (f) = font->space_width;
+  FRAME_LINE_HEIGHT (f) = font->height;
 
   compute_fringe_widths (f, 1);
 
@@ -6012,7 +5931,6 @@ x_new_fontset2 (f, fontset, font_object)
 
   return fontset_name (fontset);
 }
-#endif /* USE_FONT_BACKEND */
 
 \f
 /***********************************************************************
@@ -6569,14 +6487,11 @@ x_free_frame_resources (f)
 
   BLOCK_INPUT;
 
-#ifdef USE_FONT_BACKEND
-      /* We must free faces before destroying windows because some
-        font-driver (e.g. xft) access a window while finishing a
-        face.  */
-      if (enable_font_backend
-         && FRAME_FACE_CACHE (f))
-       free_frame_faces (f);
-#endif /* USE_FONT_BACKEND */
+  /* We must free faces before destroying windows because some
+     font-driver (e.g. xft) access a window while finishing a
+     face.  */
+  if (FRAME_FACE_CACHE (f))
+    free_frame_faces (f);
 
   if (FRAME_W32_WINDOW (f))
     my_destroy_window (f, FRAME_W32_WINDOW (f));
@@ -6681,6 +6596,8 @@ x_wm_set_icon_position (f, icon_x, icon_y)
                                Fonts
  ***********************************************************************/
 
+#if OLD_FONT
+
 /* The following functions are listed here to help diff stay in step
    with xterm.c.  See w32fns.c for definitions.
 
@@ -6783,6 +6700,9 @@ x_query_font (f, fontname)
 x_find_ccl_program (fontp)
 
 */
+
+#endif /* OLD_FONT */
+
 \f
 /***********************************************************************
                            Initialization
@@ -6916,8 +6836,10 @@ static struct redisplay_interface w32_redisplay_interface =
   w32_draw_fringe_bitmap,
   w32_define_fringe_bitmap,
   w32_destroy_fringe_bitmap,
+#if OLD_FONT
   w32_per_char_metric,
   w32_encode_char,
+#endif
   w32_compute_glyph_string_overhangs,
   x_draw_glyph_string,
   w32_define_frame_cursor,
@@ -7005,12 +6927,14 @@ x_delete_terminal (struct terminal *terminal)
     return;
 
   BLOCK_INPUT;
+#if OLD_FONT
   /* Free the fonts in the font table.  */
   for (i = 0; i < dpyinfo->n_fonts; i++)
     if (dpyinfo->font_table[i].name)
       {
         DeleteObject (((XFontStruct*)(dpyinfo->font_table[i].font))->hfont);
       }
+#endif
 
   x_delete_display (dpyinfo);
   UNBLOCK_INPUT;
@@ -7139,7 +7063,9 @@ x_delete_display (dpyinfo)
     if (dpyinfo->palette)
       DeleteObject(dpyinfo->palette);
   }
+#if OLD_FONT
   xfree (dpyinfo->font_table);
+#endif
   xfree (dpyinfo->w32_id_name);
 
   w32_reset_fringes ();
index 5af3eac8ade000001303ade8cb113f9ecd7fe572..87cf42b088a68ccc5887d735b0d4dbb01e251d90 100644 (file)
@@ -27,16 +27,11 @@ Boston, MA 02110-1301, USA.  */
 #define BLACK_PIX_DEFAULT(f) PALETTERGB(0,0,0)
 #define WHITE_PIX_DEFAULT(f) PALETTERGB(255,255,255)
 
-#define FONT_WIDTH(f)       \
-  ((f)->bdf ? (f)->bdf->width : (f)->tm.tmMaxCharWidth)
-#define FONT_HEIGHT(f)      \
-   ((f)->bdf ? (f)->bdf->height : (f)->tm.tmHeight)
-#define FONT_BASE(f)        \
-  ((f)->bdf ? (f)->bdf->ury : (f)->tm.tmAscent)
-#define FONT_DESCENT(f)     \
-  ((f)->bdf ? -((f)->bdf->lly) : (f)->tm.tmDescent)
-#define FONT_AVG_WIDTH(f)   \
-  ((f)->bdf ? (f)->bdf->width : (f)->tm.tmAveCharWidth)
+#define FONT_WIDTH(f)     ((f)->max_width)
+#define FONT_HEIGHT(f)    ((f)->height)
+#define FONT_BASE(f)      ((f)->ascent)
+#define FONT_DESCENT(f)   ((f)->descent)
+#define FONT_AVG_WIDTH(f) ((f)->average_width)
 
 #define CP_DEFAULT 1004
 /* Special pseudo-codepages. */
@@ -152,11 +147,13 @@ struct w32_display_info
      received; value is reset after key is received.  */
   int faked_key;
 
+#if OLD_FONT
   /* A table of all the fonts we have already loaded.  */
   struct font_info *font_table;
 
   /* The current capacity of font_table.  */
   int font_table_size;
+#endif
 
   /* Minimum width over all characters in all fonts in font_table.  */
   int smallest_char_width;
@@ -256,12 +253,14 @@ Lisp_Object display_x_get_resource P_ ((struct w32_display_info *,
 
 extern struct w32_display_info *w32_term_init ();
 \f
+#if OLD_FONT
 extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
 extern struct font_info *w32_get_font_info (), *w32_query_font ();
 extern void w32_cache_char_metrics (XFontStruct *font);
 extern void w32_find_ccl_program();
 extern Lisp_Object x_get_font_repertory P_ ((struct frame *,
                                             struct font_info *));
+#endif
 \f
 #define PIX_TYPE COLORREF
 
@@ -324,11 +323,10 @@ struct w32_output
   Window parent_desc;
 
   /* Default ASCII font of this frame. */
+#if OLD_FONT
   XFontStruct *font;
-
-#ifdef USE_FONT_BACKEND
-  struct font *fontp;
-#endif /* USE_FONT_BACKEND */
+#endif
+  struct font *font;
 
   /* The baseline offset of the default ASCII font.  */
   int baseline_offset;
@@ -416,10 +414,6 @@ extern struct w32_output w32term_display;
 #define FRAME_FONTSET(f) ((f)->output_data.w32->fontset)
 #define FRAME_BASELINE_OFFSET(f) ((f)->output_data.w32->baseline_offset)
 
-#ifdef USE_FONT_BACKEND
-#define FRAME_FONT_OBJECT(f) ((f)->output_data.w32->fontp)
-#endif /* USE_FONT_BACKEND */
-
 /* This gives the w32_display_info structure for the display F is on.  */
 #define FRAME_W32_DISPLAY_INFO(f) (&one_w32_display_info)
 #define FRAME_X_DISPLAY_INFO(f) (&one_w32_display_info)
@@ -427,8 +421,10 @@ extern struct w32_output w32term_display;
 /* This is the `Display *' which frame F is on.  */
 #define FRAME_X_DISPLAY(f) (0)
 
+#if OLD_FONT
 /* This is the 'font_info *' which frame F has.  */
 #define FRAME_W32_FONT_TABLE(f) (FRAME_W32_DISPLAY_INFO (f)->font_table)
+#endif
 
 /* Value is the smallest width of any character in any font on frame F.  */
 
@@ -599,8 +595,10 @@ do { \
 #define w32_clear_area(f,hdc,px,py,nx,ny) \
   w32_fill_area (f, hdc, FRAME_BACKGROUND_PIXEL (f), px, py, nx, ny)
 
+#if OLD_FONT
 extern struct font_info *w32_load_font ();
 extern void w32_unload_font ();
+#endif
 
 /* Define for earlier versions of Visual C */
 #ifndef WM_MOUSEWHEEL
index 6682def4f1a47a547be88bb492a5396feca29e27..4b32b02f02d95c3ceab9b5bd7b19855b8548ec5e 100644 (file)
@@ -18,7 +18,6 @@ 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.  */
 
-#ifdef USE_FONT_BACKEND
 
 #include <config.h>
 /* Override API version - Uniscribe is only available as standard since
@@ -112,32 +111,30 @@ uniscribe_list_family (frame)
   return list;
 }
 
-static struct font *
+static Lisp_Object
 uniscribe_open (f, font_entity, pixel_size)
      FRAME_PTR f;
      Lisp_Object font_entity;
      int pixel_size;
 {
+  Lisp_Object font_object
+    = font_make_object (VECSIZE (struct uniscribe_font_info));
   struct uniscribe_font_info *uniscribe_font
-    = xmalloc (sizeof (struct uniscribe_font_info));
-
-  if (uniscribe_font == NULL)
-    return NULL;
+    = (struct uniscribe_font_info *) XFONT_OBJECT (font_object);
 
   if (!w32font_open_internal (f, font_entity, pixel_size,
                               (struct w32font_info *) uniscribe_font))
     {
-      xfree (uniscribe_font);
-      return NULL;
+      return Qnil;
     }
 
   /* Initialize the cache for this font.  */
   uniscribe_font->cache = NULL;
   /* Mark the format as opentype  */
-  uniscribe_font->w32_font.font.format = Qopentype;
+  uniscribe_font->w32_font.font.props[FONT_FORMAT_INDEX] = Qopentype;
   uniscribe_font->w32_font.font.driver = &uniscribe_font_driver;
 
-  return (struct font *) uniscribe_font;
+  return font_object;
 }
 
 static void
@@ -168,8 +165,7 @@ uniscribe_otf_capability (font)
 
   f = XFRAME (selected_frame);
   context = get_frame_dc (f);
-  old_font = SelectObject (context,
-                          ((W32FontStruct *) (font->font.font))->hfont);
+  old_font = SelectObject (context, FONT_COMPAT (font)->hfont);
 
   features = otf_features (context, "GSUB");
   XSETCAR (capability, features);
@@ -262,8 +258,7 @@ uniscribe_shape (lgstring)
 
   f = XFRAME (selected_frame);
   context = get_frame_dc (f);
-  old_font = SelectObject (context,
-                          ((W32FontStruct *) (font->font.font))->hfont);
+  old_font = SelectObject (context, FONT_COMPAT (font)->hfont);
 
   glyphs = alloca (max_glyphs * sizeof (WORD));
   clusters = alloca (nchars * sizeof (WORD));
@@ -428,8 +423,7 @@ uniscribe_encode_char (font, c)
   /* Use selected frame until API is updated to pass the frame.  */
   f = XFRAME (selected_frame);
   context = get_frame_dc (f);
-  old_font = SelectObject (context,
-                           ((W32FontStruct *)(font->font.font))->hfont);
+  old_font = SelectObject (context, FONT_COMPAT (font)->hfont);
 
   retval = GetGlyphIndicesW (context, chars, 1, indices,
                             GGI_MARK_NONEXISTING_GLYPHS);
@@ -494,8 +488,8 @@ add_opentype_font_name_to_list (logical_font, physical_font, font_type,
       && font_type != TRUETYPE_FONTTYPE)
     return 1;
 
-  family = intern_downcase (logical_font->elfLogFont.lfFaceName,
-                            strlen (logical_font->elfLogFont.lfFaceName));
+  family = font_intern_prop (logical_font->elfLogFont.lfFaceName,
+                            strlen (logical_font->elfLogFont.lfFaceName));
   if (! memq_no_quit (family, *list))
     *list = Fcons (family, *list);
 
@@ -819,6 +813,7 @@ font_table_error:
 struct font_driver uniscribe_font_driver =
   {
     0, /* Quniscribe */
+    0, /* case insensitive */
     w32font_get_cache,
     uniscribe_list,
     uniscribe_match,
@@ -866,7 +861,5 @@ syms_of_w32uniscribe ()
   register_font_driver (&uniscribe_font_driver, NULL);
 }
 
-#endif /* USE_FONT_BACKEND  */
-
 /* arch-tag: 9530f0e1-7471-47dd-a780-94330af87ea0
    (do not change this comment) */
index bb9ec58792cab0404b1a118eaffa41edfc86b8e0..e3ecc6236bc096b1ea89ae18301ee78c3650d3c8 100644 (file)
@@ -203,9 +203,7 @@ Boston, MA 02110-1301, USA.  */
 #endif
 
 #ifdef HAVE_WINDOW_SYSTEM
-#ifdef USE_FONT_BACKEND
 #include "font.h"
-#endif /* USE_FONT_BACKEND */
 #endif /* HAVE_WINDOW_SYSTEM */
 
 #ifndef FRAME_X_OUTPUT
@@ -4589,10 +4587,8 @@ handle_auto_composed_prop (it)
          Lisp_Object cmp_prop;
          EMACS_INT cmp_start, cmp_end;
 
-#ifdef USE_FONT_BACKEND
-         if (enable_font_backend
-             && get_property_and_range (pos, Qcomposition, &cmp_prop,
-                                        &cmp_start, &cmp_end, it->string)
+         if (get_property_and_range (pos, Qcomposition, &cmp_prop,
+                                     &cmp_start, &cmp_end, it->string)
              && cmp_start == pos
              && COMPOSITION_METHOD (cmp_prop) == COMPOSITION_WITH_GLYPH_STRING)
            {
@@ -4606,7 +4602,7 @@ handle_auto_composed_prop (it)
                   different font.  */
                val = Qnil;
            }
-#endif
+
          if (! NILP (val))
            {
              Lisp_Object end;
@@ -4641,16 +4637,13 @@ handle_auto_composed_prop (it)
              int count = SPECPDL_INDEX ();
              Lisp_Object args[5];
 
+             limit = font_range (pos, limit, FACE_FROM_ID (it->f, it->face_id),
+                                 it->f, it->string);
              args[0] = Vauto_composition_function;
              specbind (Qauto_composition_function, Qnil);
              args[1] = make_number (pos);
              args[2] = make_number (limit);
-#ifdef USE_FONT_BACKEND
-             if (enable_font_backend)
-               args[3] = it->window;
-             else
-#endif /* USE_FONT_BACKEND */
-               args[3] = Qnil;
+             args[3] = it->window;
              args[4] = it->string;
              safe_call (5, args);
              unbind_to (count, Qnil);
@@ -4737,7 +4730,6 @@ handle_composition_prop (it)
          it->cmp_len = COMPOSITION_LENGTH (prop);
          /* For a terminal, draw only the first (non-TAB) character
             of the components.  */
-#ifdef USE_FONT_BACKEND
          if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
            {
              /* FIXME: This doesn't do anything!?! */
@@ -4746,7 +4738,6 @@ handle_composition_prop (it)
                                           cmp->hash_index * 2);
            }
          else
-#endif /* USE_FONT_BACKEND */
            {
              int i;
 
@@ -18816,7 +18807,7 @@ calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
      double *res;
      struct it *it;
      Lisp_Object prop;
-     void *font;
+     struct font *font;
      int width_p, *align_to;
 {
   double pixels;
@@ -18869,9 +18860,9 @@ calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
 
 #ifdef HAVE_WINDOW_SYSTEM
       if (EQ (prop, Qheight))
-       return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
+       return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
       if (EQ (prop, Qwidth))
-       return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
+       return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
 #else
       if (EQ (prop, Qheight) || EQ (prop, Qwidth))
        return OK_PIXELS (1);
@@ -19154,49 +19145,14 @@ get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
 {
   struct face *face = FACE_FROM_ID (f, face_id);
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
+  if (face->font)
     {
-      struct font *font = (struct font *) face->font_info;
+      unsigned code = face->font->driver->encode_char (face->font, c);
 
-      if (font)
-       {
-         unsigned code = font->driver->encode_char (font, c);
-
-         if (code != FONT_INVALID_CODE)
-           STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
-         else
-           STORE_XCHAR2B (char2b, 0, 0);
-       }
-    }
-  else
-#endif /* USE_FONT_BACKEND */
-  if (!multibyte_p)
-    {
-      /* Unibyte case.  We don't have to encode, but we have to make
-        sure to use a face suitable for unibyte.  */
-      STORE_XCHAR2B (char2b, 0, c);
-      face_id = FACE_FOR_CHAR (f, face, c, -1, Qnil);
-      face = FACE_FROM_ID (f, face_id);
-    }
-  else if (c < 128)
-    {
-      /* Case of ASCII in a face known to fit ASCII.  */
-      STORE_XCHAR2B (char2b, 0, c);
-    }
-  else if (face->font != NULL)
-    {
-      struct font_info *font_info
-       = FONT_INFO_FROM_ID (f, face->font_info_id);
-      struct charset *charset = CHARSET_FROM_ID (font_info->charset);
-      unsigned code = ENCODE_CHAR (charset, c);
-
-      if (CHARSET_DIMENSION (charset) == 1)
-       STORE_XCHAR2B (char2b, 0, code);
-      else
+      if (code != FONT_INVALID_CODE)
        STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
-       /* Maybe encode the character in *CHAR2B.  */
-      FRAME_RIF (f)->encode_char (c, char2b, font_info, charset, NULL);
+      else
+       STORE_XCHAR2B (char2b, 0, 0);
     }
 
   /* Make sure X resources of the face are allocated.  */
@@ -19231,56 +19187,14 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
   if (two_byte_p)
     *two_byte_p = 0;
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      struct font *font = (struct font *) face->font_info;
-
-      if (font)
-       {
-         unsigned code = font->driver->encode_char (font, glyph->u.ch);
-
-         if (code != FONT_INVALID_CODE)
-           STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
-         else
-           STORE_XCHAR2B (char2b, 0, code);
-       }
-    }
-  else
-#endif /* USE_FONT_BACKEND */
-  if (!glyph->multibyte_p)
-    {
-      /* Unibyte case.  We don't have to encode, but we have to make
-        sure to use a face suitable for unibyte.  */
-      STORE_XCHAR2B (char2b, 0, glyph->u.ch);
-    }
-  else if (glyph->u.ch < 128)
-    {
-      /* Case of ASCII in a face known to fit ASCII.  */
-      STORE_XCHAR2B (char2b, 0, glyph->u.ch);
-    }
-  else
+  if (face->font)
     {
-      struct font_info *font_info
-       = FONT_INFO_FROM_ID (f, face->font_info_id);
-      if (font_info)
-       {
-         struct charset *charset = CHARSET_FROM_ID (font_info->charset);
-         unsigned code = ENCODE_CHAR (charset, glyph->u.ch);
+      unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
 
-         if (CHARSET_DIMENSION (charset) == 1)
-           STORE_XCHAR2B (char2b, 0, code);
-         else
-           STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
-
-         /* Maybe encode the character in *CHAR2B.  */
-         if (CHARSET_ID (charset) != charset_ascii)
-           {
-             glyph->font_type
-               = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info,
-                                             charset, two_byte_p);
-           }
-       }
+      if (code != FONT_INVALID_CODE)
+       STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+      else
+       STORE_XCHAR2B (char2b, 0, code);
     }
 
   /* Make sure X resources of the face are allocated.  */
@@ -19312,16 +19226,14 @@ fill_composite_glyph_string (s, base_face, overlaps)
 
   s->for_overlaps = overlaps;
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend && s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
+  if (s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
     {
       Lisp_Object gstring
        = AREF (XHASH_TABLE (composition_hash_table)->key_and_value,
                s->cmp->hash_index * 2);
 
       s->face = base_face;
-      s->font_info = base_face->font_info;
-      s->font = s->font_info->font;
+      s->font = base_face->font;
       for (i = 0, s->nchars = 0; i < s->cmp->glyph_len; i++, s->nchars++)
        {
          Lisp_Object g = LGSTRING_GLYPH (gstring, i);
@@ -19336,7 +19248,6 @@ fill_composite_glyph_string (s, base_face, overlaps)
       s->width = s->cmp->pixel_width;
     }
   else
-#endif /* USE_FONT_BACKEND */
     {
       /* For all glyphs of this composition, starting at the offset
         S->gidx, until we reach the end of the definition or encounter a
@@ -19345,7 +19256,6 @@ fill_composite_glyph_string (s, base_face, overlaps)
 
       s->face = NULL;
       s->font = NULL;
-      s->font_info = NULL;
       for (i = s->gidx; i < s->cmp->glyph_len; i++)
        {
          int c = COMPOSITION_GLYPH (s->cmp, i);
@@ -19363,7 +19273,6 @@ fill_composite_glyph_string (s, base_face, overlaps)
                    {
                      s->face = face;
                      s->font = s->face->font;
-                     s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
                    }
                  else if (s->face != face)
                    break;
@@ -19448,7 +19357,6 @@ fill_glyph_string (s, face_id, start, end, overlaps)
     }
 
   s->font = s->face->font;
-  s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
 
   /* If the specified font could not be loaded, use the frame's font,
      but record the fact that we couldn't load it in
@@ -19512,7 +19420,6 @@ fill_stretch_glyph_string (s, row, area, start, end)
   face_id = glyph->face_id;
   s->face = FACE_FROM_ID (s->f, face_id);
   s->font = s->face->font;
-  s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
   s->width = glyph->pixel_width;
   s->nchars = 1;
   voffset = glyph->voffset;
@@ -19534,35 +19441,20 @@ fill_stretch_glyph_string (s, row, area, start, end)
   return glyph - s->row->glyphs[s->area];
 }
 
-static XCharStruct *
-get_per_char_metric (f, font, font_info, char2b, font_type)
+static struct font_metrics *
+get_per_char_metric (f, font, char2b)
      struct frame *f;
-     XFontStruct *font;
-     struct font_info *font_info;
+     struct font *font;
      XChar2b *char2b;
-     int font_type;
 {
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      static XCharStruct pcm_value;
-      unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
-      struct font *fontp;
-      struct font_metrics metrics;
+  static struct font_metrics metrics;
+  unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
+  struct font *fontp;
 
-      if (! font_info || code == FONT_INVALID_CODE)
-       return NULL;
-      fontp = (struct font *) font_info;
-      fontp->driver->text_extents (fontp, &code, 1, &metrics);
-      pcm_value.lbearing = metrics.lbearing;
-      pcm_value.rbearing = metrics.rbearing;
-      pcm_value.ascent = metrics.ascent;
-      pcm_value.descent = metrics.descent;
-      pcm_value.width = metrics.width;
-      return &pcm_value;
-    }
-#endif /* USE_FONT_BACKEND */
-  return FRAME_RIF (f)->per_char_metric (font, char2b, font_type);
+  if (! font || code == FONT_INVALID_CODE)
+    return NULL;
+  font->driver->text_extents (font, &code, 1, &metrics);
+  return &metrics;
 }
 
 /* EXPORT for RIF:
@@ -19580,17 +19472,12 @@ x_get_glyph_overhangs (glyph, f, left, right)
 
   if (glyph->type == CHAR_GLYPH)
     {
-      XFontStruct *font;
       struct face *face;
-      struct font_info *font_info;
       XChar2b char2b;
-      XCharStruct *pcm;
+      struct font_metrics *pcm;
 
       face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
-      font = face->font;
-      font_info = FONT_INFO_FROM_FACE (f, face);
-      if (font  /* ++KFS: Should this be font_info ?  */
-         && (pcm = get_per_char_metric (f, font, font_info, &char2b, glyph->font_type)))
+      if (face->font && (pcm = get_per_char_metric (f, face->font, &char2b)))
        {
          if (pcm->rbearing > pcm->width)
            *right = pcm->rbearing - pcm->width;
@@ -20536,7 +20423,7 @@ produce_stretch_glyph (it)
   int ascent = 0;
   double tem;
   struct face *face = FACE_FROM_ID (it->f, it->face_id);
-  XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
+  struct font *font = face->font ? face->font : FRAME_FONT (it->f);
 
   PREPARE_FACE_FOR_DISPLAY (it->f, face);
 
@@ -20677,7 +20564,7 @@ static Lisp_Object
 calc_line_height_property (it, val, font, boff, override)
      struct it *it;
      Lisp_Object val;
-     XFontStruct *font;
+     struct font *font;
      int boff, override;
 {
   Lisp_Object face_name = Qnil;
@@ -20712,7 +20599,6 @@ calc_line_height_property (it, val, font, boff, override)
     {
       int face_id;
       struct face *face;
-      struct font_info *font_info;
 
       face_id = lookup_named_face (it->f, face_name, 0);
       if (face_id < 0)
@@ -20722,10 +20608,8 @@ calc_line_height_property (it, val, font, boff, override)
       font = face->font;
       if (font == NULL)
        return make_number (-1);
-
-      font_info = FONT_INFO_FROM_FACE (it->f, face);
-      boff = font_info->baseline_offset;
-      if (font_info->vertical_centering)
+      boff = font->baseline_offset;
+      if (font->vertical_centering)
        boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
     }
 
@@ -20767,11 +20651,10 @@ x_produce_glyphs (it)
   if (it->what == IT_CHARACTER)
     {
       XChar2b char2b;
-      XFontStruct *font;
+      struct font *font;
       struct face *face = FACE_FROM_ID (it->f, it->face_id);
-      XCharStruct *pcm;
+      struct font_metrics *pcm;
       int font_not_found_p;
-      struct font_info *font_info;
       int boff;                        /* baseline offset */
       /* We may change it->multibyte_p upon unibyte<->multibyte
         conversion.  So, save the current value now and restore it
@@ -20813,13 +20696,11 @@ x_produce_glyphs (it)
        {
          font = FRAME_FONT (it->f);
          boff = FRAME_BASELINE_OFFSET (it->f);
-         font_info = NULL;
        }
       else
        {
-         font_info = FONT_INFO_FROM_FACE (it->f, face);
-         boff = font_info->baseline_offset;
-         if (font_info->vertical_centering)
+         boff = font->baseline_offset;
+         if (font->vertical_centering)
            boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
        }
 
@@ -20831,8 +20712,7 @@ x_produce_glyphs (it)
 
          it->nglyphs = 1;
 
-         pcm = get_per_char_metric (it->f, font, font_info, &char2b,
-                                    FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
+         pcm = get_per_char_metric (it->f, font, &char2b);
 
          if (it->override_ascent >= 0)
            {
@@ -21066,8 +20946,7 @@ x_produce_glyphs (it)
             multiplying the width of font by the width of the
             character.  */
 
-           pcm = get_per_char_metric (it->f, font, font_info, &char2b,
-                                      FONT_TYPE_FOR_MULTIBYTE (font, it->c));
+         pcm = get_per_char_metric (it->f, font, &char2b);
 
          if (font_not_found_p || !pcm)
            {
@@ -21147,18 +21026,16 @@ x_produce_glyphs (it)
       int boff;                        /* baseline offset */
       struct composition *cmp = composition_table[it->cmp_id];
       int glyph_len = cmp->glyph_len;
-      XFontStruct *font = face->font;
+      struct font *font = face->font;
 
       it->nglyphs = 1;
 
-#ifdef USE_FONT_BACKEND
       if (cmp->method == COMPOSITION_WITH_GLYPH_STRING)
        {
          PREPARE_FACE_FOR_DISPLAY (it->f, face);
          font_prepare_composition (cmp, it->f);
        }
       else
-#endif /* USE_FONT_BACKEND */
       /* If we have not yet calculated pixel size data of glyphs of
         the composition for the current face font, calculate them
         now.  Theoretically, we have to check all fonts for the
@@ -21181,9 +21058,8 @@ x_produce_glyphs (it)
          int face_id;
          int c;
          XChar2b char2b;
-         XCharStruct *pcm;
+         struct font_metrics *pcm;
          int font_not_found_p;
-         struct font_info *font_info;
          int pos;
 
          for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
@@ -21209,9 +21085,8 @@ x_produce_glyphs (it)
              face = face->ascii_face;
              font = face->font;
            }
-         font_info = FONT_INFO_FROM_FACE (it->f, face);
-         boff = font_info->baseline_offset;
-         if (font_info->vertical_centering)
+         boff = font->baseline_offset;
+         if (font->vertical_centering)
            boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
          font_ascent = FONT_BASE (font) + boff;
          font_descent = FONT_DESCENT (font) - boff;
@@ -21224,8 +21099,7 @@ x_produce_glyphs (it)
            {
              get_char_face_and_encoding (it->f, c, it->face_id,
                                          &char2b, it->multibyte_p, 0);
-             pcm = get_per_char_metric (it->f, font, font_info, &char2b,
-                                        FONT_TYPE_FOR_MULTIBYTE (font, c));
+             pcm = get_per_char_metric (it->f, font, &char2b);
            }
 
          /* Initialize the bounding box.  */
@@ -21252,11 +21126,11 @@ x_produce_glyphs (it)
          highest = ascent + boff;
 
          if (! font_not_found_p
-             && font_info->default_ascent
+             && font->default_ascent
              && CHAR_TABLE_P (Vuse_default_ascent)
              && !NILP (Faref (Vuse_default_ascent,
                               make_number (it->char_to_display))))
-           highest = font_info->default_ascent + boff;
+           highest = font->default_ascent + boff;
 
          /* Draw the first glyph at the normal position.  It may be
             shifted to right later if some other glyphs are drawn
@@ -21285,15 +21159,12 @@ x_produce_glyphs (it)
                pcm = NULL;
              else
                {
-                 font_info = FONT_INFO_FROM_FACE (it->f, this_face);
-                 this_boff = font_info->baseline_offset;
-                 if (font_info->vertical_centering)
+                 this_boff = font->baseline_offset;
+                 if (font->vertical_centering)
                    this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
                  get_char_face_and_encoding (it->f, ch, face_id,
                                              &char2b, it->multibyte_p, 0);
-                 pcm = get_per_char_metric (it->f, font, font_info, &char2b,
-                                            FONT_TYPE_FOR_MULTIBYTE (font,
-                                                                     ch));
+                 pcm = get_per_char_metric (it->f, font, &char2b);
                }
              if (! pcm)
                cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
@@ -21310,13 +21181,13 @@ x_produce_glyphs (it)
                         alternate chars.  */
                      left = (leftmost + rightmost - width) / 2;
                      btm = - descent + boff;
-                     if (font_info->relative_compose
+                     if (font->relative_compose
                          && (! CHAR_TABLE_P (Vignore_relative_composition)
                              || NILP (Faref (Vignore_relative_composition,
                                              make_number (ch)))))
                        {
 
-                         if (- descent >= font_info->relative_compose)
+                         if (- descent >= font->relative_compose)
                            /* One extra pixel between two glyphs.  */
                            btm = highest + 1;
                          else if (ascent <= 0)
index 087dc86297a33c1a3bf2dd42db79f23a6aadd46f..8575e171c1bef26ac3279a90adfb3ec6d5994da8 100644 (file)
@@ -56,15 +56,17 @@ Boston, MA 02110-1301, USA.  */
    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 @@ Boston, MA 02110-1301, USA.  */
    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 @@ Boston, MA 02110-1301, USA.  */
 #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 @@ Boston, MA 02110-1301, USA.  */
 
 #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 QCreverse_video;
 Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit;
 Lisp_Object QCfontset;
 
+/* Keywords symbols used for font properties.  */
+extern Lisp_Object QCfoundry, QCadstyle, QCregistry;
+extern 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 @@ static int better_font_p P_ ((int *, struct font_name *, struct font_name *,
                              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 try_alternative_families P_ ((struct frame *f, Lisp_Object,
 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 int lface_same_font_attributes_p P_ ((Lisp_Object *, Lisp_Object *));
 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 @@ clear_face_cache (clear_fonts_p)
     {
       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 @@ Optional THOROUGHLY non-nil means try to free unused fonts, too.  */)
   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 */
-
-
 \f
 /***********************************************************************
                              X Pixmaps
@@ -1220,64 +1136,6 @@ load_pixmap (f, name, w_ptr, h_ptr)
 #endif /* HAVE_WINDOW_SYSTEM */
 
 
-\f
-/***********************************************************************
-                               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 */
-
-
 \f
 /***********************************************************************
                                X Colors
@@ -1920,33 +1778,6 @@ static struct table_entry swidth_table[] =
   {"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,1203 +1796,251 @@ static int font_sort_order[4] = {
 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;
+#ifdef HAVE_WINDOW_SYSTEM
+
+/* Return a rescaling ratio of a font of NAME.  */
 
-  low = 0;
-  high = dim - 1;
+static double
+font_rescale_ratio (name)
+     char *name;
+{
+  Lisp_Object tail, elt;
 
-  while (low <= high)
+  for (tail = Vface_font_rescale_alist; CONSP (tail); tail = XCDR (tail))
     {
-      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;
+      elt = XCAR (tail);
+      if (STRINGP (XCAR (elt)) && FLOATP (XCDR (elt))
+         && fast_c_string_match_ignore_case (XCAR (elt), name) >= 0)
+       return XFLOAT_DATA (XCDR (elt));
     }
-
-  return NULL;
+  return 1.0;
 }
 
+static enum font_property_index font_props_for_sorting[FONT_SIZE_INDEX];
 
-/* 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 int
+compare_fonts_by_sort_order (v1, v2)
+     const void *v1, *v2;
+{
+  Lisp_Object font1 = *(Lisp_Object *) v1;
+  Lisp_Object font2 = *(Lisp_Object *) v2;
+  int i;
+  
+  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;
 
-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;
+      if (idx <= FONT_REGISTRY_INDEX)
+       {
+         if (STRINGP (val1))
+           result = STRINGP (val2) ? strcmp (SDATA (val1), SDATA (val2)) : -1;
+         else
+           result = STRINGP (val2) ? 1 : 0;
+       }
+      else
+       {
+         if (INTEGERP (val1))
+           result = INTEGERP (val2) ? XINT (val1) - XINT (val2) : -1;
+         else
+           result = INTEGERP (val2) ? 1 : 0;
+       }
+      if (result)
+       return result;
+    }
+  return 0;
 }
 
+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.
+Otherwise, FAMILY must be a string, possibly containing wildcards
+`?' and `*'.
+If FRAME is omitted or nil, use the selected frame.
+Each element of the result is a vector [FAMILY WIDTH POINT-SIZE WEIGHT
+SLANT FIXED-P FULL REGISTRY-AND-ENCODING].
+FAMILY is the font family name.  POINT-SIZE is the size of the
+font in 1/10 pt.  WIDTH, WEIGHT, and SLANT are symbols describing the
+width, weight and slant of the font.  These symbols are the same as for
+face attributes.  FIXED-P is non-nil if the font is fixed-pitch.
+FULL is the full name of the font, and REGISTRY-AND-ENCODING is a string
+giving the registry and encoding of the font.
+The result list is sorted according to the current setting of
+the face font sort order.  */)
+     (family, frame)
+     Lisp_Object family, frame;
+{
+  struct frame *f = check_x_frame (frame);
+  Lisp_Object font_spec = Qnil, vec;
+  int i, nfonts;
+  Lisp_Object result;
 
-/* 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.  */
+  if (!NILP (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] = QCwidth; break;
+         case XLFD_POINT_SIZE: font_props_for_sorting[i] = QCsize; break;
+         case XLFD_WEIGHT: font_props_for_sorting[i] = QCweight; break;
+         default: font_props_for_sorting[i] = QCslant; break;
+         }
+      font_sort_order[i++] = QCfamily;
+      font_sort_order[i++] = QCfoundry;
+      font_sort_order[i++] = QCadstyle;
+      font_sort_order[i++] = QCregistry;
 
-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;
-}
+      qsort (XVECTOR (vec)->contents, nfonts, sizeof (Lisp_Object),
+            compare_fonts_by_sort_order);
+    }
 
+  result = Qnil;
+  for (i = nfonts - 1; i >= 0; --i)
+    {
+      Lisp_Object font = AREF (vec, i);
+      Lisp_Object v = Fmake_vector (make_number (8), Qnil);
+      int point;
+      Lisp_Object spacing;
+
+      ASET (v, 0, AREF (font, FONT_FAMILY_INDEX));
+      ASET (v, 1, FONT_WIDTH_SYMBOLIC (font));
+      point = PIXEL_TO_POINT (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));
 
-/* Return a numeric value for the slant of the font given by FONT.  */
+      result = Fcons (v, result);
+    }
 
-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 result;
 }
 
 
-/* Return a symbol representing the weight of the font given by FONT.  */
-
-static INLINE Lisp_Object
-xlfd_symbolic_slant (font)
-     struct font_name *font;
+DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list,
+       0, 1, 0,
+       doc: /* Return a list of available font families on FRAME.
+If FRAME is omitted or nil, use the selected frame.
+Value is a list of conses (FAMILY . FIXED-P) where FAMILY
+is a font family, and FIXED-P is non-nil if fonts of that family
+are fixed-pitch.  */)
+     (frame)
+     Lisp_Object frame;
 {
-  return xlfd_symbolic_value (slant_table, DIM (slant_table),
-                             font, XLFD_SLANT, Qnormal);
+  return Ffont_family_list (frame);
 }
 
 
-/* Return a numeric value for the weight of the font given by FONT.  */
+DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0,
+       doc: /* Return a list of the names of available fonts matching PATTERN.
+If optional arguments FACE and FRAME are specified, return only fonts
+the same size as FACE on FRAME.
+PATTERN is a string, perhaps with wildcard characters;
+  the * character matches any substring, and
+  the ? character matches any single character.
+  PATTERN is case-insensitive.
+FACE is a face name--a symbol.
+
+The return value is a list of strings, suitable as arguments to
+set-face-font.
 
-static INLINE int
-xlfd_numeric_weight (font)
-     struct font_name *font;
+Fonts Emacs can't use may or may not be excluded
+even if they match PATTERN and FACE.
+The optional fourth argument MAXIMUM sets a limit on how many
+fonts to match.  The first MAXIMUM fonts are reported.
+The optional fifth argument WIDTH, if specified, is a number of columns
+occupied by a character of a font.  In that case, return only fonts
+the WIDTH times as wide as FACE on FRAME.  */)
+     (pattern, face, frame, maximum, width)
+    Lisp_Object pattern, face, frame, maximum, width;
 {
-  return xlfd_numeric_value (weight_table, DIM (weight_table),
-                            font, XLFD_WEIGHT, XLFD_WEIGHT_MEDIUM);
-}
+  struct frame *f;
+  int size, avgwidth;
 
+  check_x ();
+  CHECK_STRING (pattern);
 
-/* Return a symbol representing the slant of the font given by FONT.  */
+  if (! NILP (maximum))
+    CHECK_NATNUM (maximum);
 
-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);
-}
+  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))
+    {
+      /* Perhaps we have not yet created any frame.  */
+      f = NULL;
+      frame = Qnil;
+      face = Qnil;
+    }
 
-/* Return a numeric value for the swidth of the font whose XLFD font
-   name fields are found in FONT.  */
+  /* Determine the width standard for comparison with the fonts we find.  */
 
-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);
-}
+  if (NILP (face))
+    size = 0;
+  else
+    {
+      /* This is of limited utility since it works with character
+        widths.  Keep it for compatibility.  --gerd.  */
+      int face_id = lookup_named_face (f, face, 0);
+      struct face *face = (face_id < 0
+                          ? NULL
+                          : FACE_FROM_ID (f, face_id));
 
+      if (face && face->font)
+       {
+         size = face->font->pixel_size;
+         avgwidth = face->font->average_width;
+       }
+      else
+       {
+         size = FRAME_FONT (f)->pixel_size;
+         avgwidth = FRAME_FONT (f)->average_width;
+       }
+      if (!NILP (width))
+       avgwidth *= XINT (width);
+    }
 
-/* Return a symbolic value for the swidth of FONT.  */
+  {
+    Lisp_Object font_spec;
+    Lisp_Object args[2];
 
-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);
+    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);
+    return Fnconc (2, args);
+  }
 }
 
-
-/* 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
-font_rescale_ratio (name)
-     char *name;
-{
-  Lisp_Object tail, elt;
-
-  for (tail = Vface_font_rescale_alist; CONSP (tail); tail = XCDR (tail))
-    {
-      elt = XCAR (tail);
-      if (STRINGP (XCAR (elt)) && FLOATP (XCDR (elt))
-         && fast_c_string_match_ignore_case (XCAR (elt), name) >= 0)
-       return XFLOAT_DATA (XCDR (elt));
-    }
-  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 int
-split_font_name (f, font, numeric_p)
-     struct frame *f;
-     struct font_name *font;
-     int numeric_p;
-{
-  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;
-{
-  int i;
-  int size = 100;
-  char *font_name = (char *) xmalloc (size);
-  int total_length = 0;
-
-  for (i = 0; i < XLFD_LAST; ++i)
-    {
-      /* Add 1 because of the leading `-'.  */
-      int len = strlen (font->fields[i]) + 1;
-
-      /* Reallocate font_name if necessary.  Add 1 for the final
-         NUL-byte.  */
-      if (total_length + len + 1 >= size)
-       {
-         int new_size = max (2 * size, size + len + 1);
-         int sz = new_size * sizeof *font_name;
-         font_name = (char *) xrealloc (font_name, sz);
-         size = new_size;
-       }
-
-      font_name[total_length] = '-';
-      bcopy (font->fields[i], font_name + total_length + 1, len - 1);
-      total_length += len;
-    }
-
-  font_name[total_length] = 0;
-  return font_name;
-}
-
-
-/* Free an array FONTS of N font_name structures.  This frees FONTS
-   itself and all `name' fields in its elements.  */
-
-static INLINE void
-free_font_names (fonts, n)
-     struct font_name *fonts;
-     int n;
-{
-  while (n)
-    xfree (fonts[--n].name);
-  xfree (fonts);
-}
-
-
-/* Sort vector FONTS of font_name structures which contains NFONTS
-   elements using qsort and comparison function CMPFN.  F is the frame
-   on which the fonts will be used.  The global variable font_frame
-   is temporarily set to F to make it available in CMPFN.  */
-
-static INLINE void
-sort_fonts (f, fonts, nfonts, cmpfn)
-     struct frame *f;
-     struct font_name *fonts;
-     int nfonts;
-     int (*cmpfn) P_ ((const void *, const void *));
-{
-  font_frame = f;
-  qsort (fonts, nfonts, sizeof *fonts, cmpfn);
-  font_frame = NULL;
-}
-
-
-/* Get fonts matching PATTERN on frame F.  If F is null, use the first
-   display in x_display_list.  FONTS is a pointer to a vector of
-   NFONTS font_name structures.  TRY_ALTERNATIVES_P non-zero means try
-   alternative patterns from Valternate_fontname_alist if no fonts are
-   found matching PATTERN.
-
-   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);
-           }
-         else
-           ++n;
-       }
-      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);
-       }
-      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;
-}
-
-
-/* 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.
-Otherwise, FAMILY must be a string, possibly containing wildcards
-`?' and `*'.
-If FRAME is omitted or nil, use the selected frame.
-Each element of the result is a vector [FAMILY WIDTH POINT-SIZE WEIGHT
-SLANT FIXED-P FULL REGISTRY-AND-ENCODING].
-FAMILY is the font family name.  POINT-SIZE is the size of the
-font in 1/10 pt.  WIDTH, WEIGHT, and SLANT are symbols describing the
-width, weight and slant of the font.  These symbols are the same as for
-face attributes.  FIXED-P is non-nil if the font is fixed-pitch.
-FULL is the full name of the font, and REGISTRY-AND-ENCODING is a string
-giving the registry and encoding of the font.
-The result list is sorted according to the current setting of
-the face font sort order.  */)
-     (family, frame)
-     Lisp_Object family, frame;
-{
-  struct frame *f = check_x_frame (frame);
-  struct font_name *fonts;
-  int i, nfonts;
-  Lisp_Object result;
-  struct gcpro gcpro1;
-
-  if (!NILP (family))
-    CHECK_STRING (family);
-
-  result = Qnil;
-  GCPRO1 (result);
-  nfonts = font_list (f, Qnil, family, Qnil, &fonts);
-  for (i = nfonts - 1; i >= 0; --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);
-
-      result = Fcons (v, result);
-    }
-
-  remove_duplicates (result);
-  free_font_names (fonts, nfonts);
-  UNGCPRO;
-  return result;
-}
-
-
-DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list,
-       0, 1, 0,
-       doc: /* Return a list of available font families on FRAME.
-If FRAME is omitted or nil, use the selected frame.
-Value is a list of conses (FAMILY . FIXED-P) where FAMILY
-is a font family, and FIXED-P is non-nil if fonts of that family
-are fixed-pitch.  */)
-     (frame)
-     Lisp_Object frame;
-{
-  struct frame *f = check_x_frame (frame);
-  int nfonts, i;
-  struct font_name *fonts;
-  Lisp_Object result;
-  struct gcpro gcpro1;
-  int count = SPECPDL_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);
-}
-
-
-DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0,
-       doc: /* Return a list of the names of available fonts matching PATTERN.
-If optional arguments FACE and FRAME are specified, return only fonts
-the same size as FACE on FRAME.
-PATTERN is a string, perhaps with wildcard characters;
-  the * character matches any substring, and
-  the ? character matches any single character.
-  PATTERN is case-insensitive.
-FACE is a face name--a symbol.
-
-The return value is a list of strings, suitable as arguments to
-set-face-font.
-
-Fonts Emacs can't use may or may not be excluded
-even if they match PATTERN and FACE.
-The optional fourth argument MAXIMUM sets a limit on how many
-fonts to match.  The first MAXIMUM fonts are reported.
-The optional fifth argument WIDTH, if specified, is a number of columns
-occupied by a character of a font.  In that case, return only fonts
-the WIDTH times as wide as FACE on FRAME.  */)
-     (pattern, face, frame, maximum, width)
-    Lisp_Object pattern, face, frame, maximum, width;
-{
-  struct frame *f;
-  int size;
-  int maxnames;
-
-  check_x ();
-  CHECK_STRING (pattern);
-
-  if (NILP (maximum))
-    maxnames = -1;
-  else
-    {
-      CHECK_NATNUM (maximum);
-      maxnames = XINT (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.  */
-  f = frame_or_selected_frame (frame, 2);
-  if (!FRAME_WINDOW_P (f))
-    {
-      /* Perhaps we have not yet created any frame.  */
-      f = NULL;
-      face = Qnil;
-    }
-
-  /* Determine the width standard for comparison with the fonts we find.  */
-
-  if (NILP (face))
-    size = 0;
-  else
-    {
-      /* This is of limited utility since it works with character
-        widths.  Keep it for compatibility.  --gerd.  */
-      int face_id = lookup_named_face (f, face, 0);
-      struct face *face = (face_id < 0
-                          ? NULL
-                          : FACE_FROM_ID (f, face_id));
-
-      if (face && face->font)
-       size = FONT_WIDTH (face->font);
-      else
-       size = FONT_WIDTH (FRAME_FONT (f));  /* FRAME_COLUMN_WIDTH (f) */
-
-      if (!NILP (width))
-       size *= XINT (width);
-    }
-
-  {
-    Lisp_Object args[2];
-
-    args[0] = x_list_fonts (f, pattern, size, maxnames);
-    if (f == NULL)
-      /* We don't have to check fontsets.  */
-      return args[0];
-    args[1] = list_fontsets (f, pattern, size);
-    return Fnconc (2, args);
-  }
-}
-
-#endif /* HAVE_WINDOW_SYSTEM */
+#endif /* HAVE_WINDOW_SYSTEM */
 
 
 \f
@@ -3186,7 +2065,6 @@ the WIDTH times as wide as FACE on FRAME.  */)
 #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 +2090,6 @@ check_lface_attrs (attrs)
   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 +2140,7 @@ check_lface_attrs (attrs)
           || !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 +2349,7 @@ lface_fully_specified_p (attrs)
   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 +2364,19 @@ lface_fully_specified_p (attrs)
 
 #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 +2384,8 @@ set_lface_from_font_and_fontset (f, lface, font_object, fontset, force_p)
 
   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 +2407,31 @@ set_lface_from_font_and_fontset (f, lface, font_object, fontset, force_p)
 
   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;
+      val = FONT_WIDTH_FOR_FACE (font_object);
+      LFACE_SWIDTH (lface) = ! NILP (val) ? val : Qnormal;
     }
 
-  LFACE_FONT (lface) = make_unibyte_string (font->font.full_name,
-                                           strlen (font->font.full_name));
-  LFACE_FONTSET (lface) = fontset_name (fontset);
+  LFACE_FONT (lface) = font_object;
+  return 1;
 }
-#endif /* USE_FONT_BACKEND */
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
@@ -3777,28 +2511,42 @@ merge_face_vectors (f, from, to, named_merge_points)
       && !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 +2662,10 @@ merge_face_ref (f, face_ref, to, err_msgs, named_merge_points)
              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 +2675,30 @@ merge_face_ref (f, face_ref, to, err_msgs, named_merge_points)
                    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 +2775,11 @@ merge_face_ref (f, face_ref, to, err_msgs, named_merge_points)
                }
              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 +3010,9 @@ FRAME 0 means change the face on all frames, and change the default
 {
   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 +3067,7 @@ FRAME 0 means change the face on all frames, and change the default
        }
       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 +3088,31 @@ FRAME 0 means change the face on all frames, and change the default
 
       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 +3275,70 @@ FRAME 0 means change the face on all frames, and change the default
       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;
+      prop_index = FONT_WIDTH_INDEX;
     }
-  else if (EQ (attr, QCfont) || EQ (attr, QCfontset))
+  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;
+                 if (STRINGP (value))
+                   {
+                     int fontset = fs_query_fontset (value, 0);
+
+                     if (fontset >= 0)
+                       value = fontset_ascii (fontset);
+                     else
+                       value = font_spec_from_name (value);
+                   }
+                 else
+                   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))
                {
-                 int fontset;
+                 Lisp_Object *attrs = XVECTOR (lface)->contents;
                  Lisp_Object font_object;
 
-                 if (! NILP (tmp))
-                   {
-                     fontset = fs_query_fontset (tmp, 0);
-                     value = fontset_ascii (fontset);
-                   }
-                 else
-                   {
-                     fontset = FRAME_FONTSET (f);
-                   }
-                 font_object = font_open_by_name (f, SDATA (value));
+                 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;
-           }
+           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;
 
-         font_attr_p = 1;
+         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 +3360,25 @@ FRAME 0 means change the face on all frames, and change the default
     {
       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 +3387,7 @@ FRAME 0 means change the face on all frames, and change the default
      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 +3406,7 @@ FRAME 0 means change the face on all frames, and change the default
          /* 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 +3493,8 @@ FRAME 0 means change the face on all frames, and change the default
 
 #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 +3504,17 @@ set_font_frame_param (frame, lface)
 
   if (FRAME_WINDOW_P (f))
     {
-      Lisp_Object font_name;
-      char *font;
+      Lisp_Object font = LFACE_FONT (lface);
 
-      if (STRINGP (LFACE_FONT (lface)))
-       font_name = LFACE_FONT (lface);
-#ifdef USE_FONT_BACKEND
-      else if (enable_font_backend)
-       {
-         /* 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");
-           }
-       }
-#endif
-      else
+      if (FONT_SPEC_P (font))
        {
-         /* 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);
+         font = font_load_for_lface (f, XVECTOR (lface)->contents, font);
+         if (NILP (font))
+           return;
+         LFACE_FONT (lface) = 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 +3746,14 @@ x_update_menu_appearance (f)
          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 = font_xlfd_name (LFACE_FONT (lface))
 #ifdef USE_MOTIF
          const char *suffix = "List";
          Bool motif = True;
@@ -5051,22 +3766,26 @@ x_update_menu_appearance (f)
 #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 = 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 != SDATA (xlfd))
+               xfree (fontsetname);
+           }
        }
 
       if (changed_p && f->output_data.x->menubar_widget)
@@ -5198,35 +3917,7 @@ Value is nil if ATTR doesn't have a discrete set of valid values.  */)
 
   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 +4013,11 @@ return the font name used for CHARACTER.  */)
          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 +4180,7 @@ lface_hash (v)
 
 /* 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 +4193,9 @@ lface_same_font_attributes_p (lface1, lface2)
                    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 +4244,8 @@ free_realized_face (f, face)
          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 +4283,6 @@ prepare_face_for_display (f, face)
 #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 +4294,8 @@ prepare_face_for_display (f, face)
        }
 #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 +4401,8 @@ clear_face_gcs (c)
          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;
@@ -6027,55 +4687,17 @@ lookup_face (f, attr)
   return face->id;
 }
 
-#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.  */
-
-int
-lookup_non_ascii_face (f, font_id, base_face)
-     struct frame *f;
-     int font_id;
-     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_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 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-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.  */
 
-#ifdef USE_FONT_BACKEND
 int
-face_for_font (f, font, base_face)
+face_for_font (f, font_object, base_face)
      struct frame *f;
-     struct font *font;
+     Lisp_Object font_object;
      struct face *base_face;
 {
   struct face_cache *cache = FRAME_FACE_CACHE (f);
@@ -6093,21 +4715,16 @@ face_for_font (f, font, base_face)
       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 +4980,12 @@ x_supports_face_attributes_p (f, attrs, def_face)
       || !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 +5000,21 @@ x_supports_face_attributes_p (f, attrs, def_face)
       /* 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 +5075,24 @@ tty_supports_face_attributes_p (f, attrs, def_face)
   /* 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]);
+      int def_weight = FONT_WEIGHT_NAME_NUMERIC (def_attrs[LFACE_WEIGHT_INDEX]);
 
-      if (weight > XLFD_WEIGHT_MEDIUM)
+      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 +5345,7 @@ Value is ORDER.  */)
       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 +5387,10 @@ be found.  Value is ALIST.  */)
 
 #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 +5407,6 @@ face_fontset (attrs)
   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 +5475,6 @@ realize_default_face (f)
   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 +5486,14 @@ realize_default_face (f)
        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 +5507,6 @@ realize_default_face (f)
        LFACE_WEIGHT (lface) = Qnormal;
       if (UNSPECIFIEDP (LFACE_SLANT (lface)))
        LFACE_SLANT (lface) = Qnormal;
-      LFACE_AVGWIDTH (lface) = Qunspecified;
     }
 
   if (UNSPECIFIEDP (LFACE_UNDERLINE (lface)))
@@ -7552,7 +5577,7 @@ realize_default_face (f)
         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 +5667,32 @@ realize_face (cache, attrs, former_face_id)
 
 
 #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 +5735,7 @@ realize_x_face (cache, attrs)
       && 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,18 +5755,26 @@ realize_x_face (cache, attrs)
        fontset = default_face->fontset;
       if (fontset == -1)
        abort ();
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend)
-       font_load_for_face (f, face);
-      else
-#endif /* USE_FONT_BACKEND */
-       load_face_font (f, face);
-      if (face->font)
-       face->fontset = make_fontset_for_ascii_face (f, fontset, 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
-       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.  */
 
   load_face_colors (f, face, attrs);
@@ -7997,17 +6010,18 @@ realize_tty_face (cache, attrs)
 
   /* 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;
@@ -8467,12 +6481,11 @@ dump_realized_face (face)
           face->background,
           SDATA (face->lface[LFACE_BACKGROUND_INDEX]));
   fprintf (stderr, "font_name: %s (%s)\n",
-          face->font_name,
+          face->font->full_name,
           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,
index bfbc6ac02e931e4d4e6044459e0367e825f3d994..ffdf6774a9e863ca3a1a48caf497e9a3291dcf30 100644 (file)
@@ -50,10 +50,7 @@ Boston, MA 02110-1301, USA.  */
 #include "termhooks.h"
 #include "atimer.h"
 #include "termchar.h"
-
-#ifdef USE_FONT_BACKEND
 #include "font.h"
-#endif /* USE_FONT_BACKEND */
 
 #ifdef HAVE_X_WINDOWS
 
@@ -1928,8 +1925,7 @@ hack_wm_protocols (f, widget)
 
 #ifdef HAVE_X_I18N
 
-static XFontSet xic_create_xfontset P_ ((struct frame *, char *));
-static XFontSet xic_create_xfontset2 P_ ((struct frame *));
+static XFontSet xic_create_xfontset P_ ((struct frame *));
 static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *));
 
 
@@ -2105,105 +2101,11 @@ print_fontset_result (xfs, name, missing_list, missing_count)
 #endif
 
 static XFontSet
-xic_create_xfontset (f, base_fontname)
+xic_create_xfontset (f)
      struct frame *f;
-     char *base_fontname;
 {
   XFontSet xfs = NULL;
-  char **missing_list = NULL;
-  int missing_count;
-  char *def_string;
-  Lisp_Object rest, frame;
-
-  if (!base_fontname)
-    base_fontname = xic_defaut_fontset;
-
-  /* See if there is another frame already using same fontset.  */
-  FOR_EACH_FRAME (rest, frame)
-    {
-      struct frame *cf = XFRAME (frame);
-      if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
-          && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
-          && FRAME_XIC_BASE_FONTNAME (cf)
-          && !strcmp (FRAME_XIC_BASE_FONTNAME (cf), base_fontname))
-        {
-          xfs = FRAME_XIC_FONTSET (cf);
-          break;
-        }
-    }
-
-  if (!xfs)
-    {
-      char *fontsetname = xic_create_fontsetname (base_fontname, False);
-
-      /* New fontset.  */
-      xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
-                           fontsetname, &missing_list,
-                           &missing_count, &def_string);
-#ifdef DEBUG_XIC_FONTSET
-      print_fontset_result (xfs, fontsetname, missing_list, missing_count);
-#endif
-      if (missing_list)
-       XFreeStringList (missing_list);
-      if (! xfs)
-       {
-         /* FONTSETNAME contains a list of font names (specific fonts
-            first, general fonts last), but giving that to
-            XCreateFontSet at once occasionally fails (bug of X?).
-            So, we try to call XCreateFontSet for each fontname.  */
-         char *p0 = fontsetname, *p1;
-
-         while (p0)
-           {
-             p1 = strchr (p0, ',');
-             if (p1)
-               *p1 = '\0';
-             xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
-                                   p0, &missing_list,
-                                   &missing_count, &def_string);
-#ifdef DEBUG_XIC_FONTSET
-             print_fontset_result (xfs, p0, missing_list, missing_count);
-#endif
-             if (missing_list)
-               XFreeStringList (missing_list);
-             if (xfs)
-               break;
-             p0 = p1 ? p1 + 1 : NULL;
-           }
-       }
-      xfree (fontsetname);
-      if (! xfs && base_fontname != xic_defaut_fontset)
-       {
-         /* Try the default fontset name at a last resort.  */
-         fontsetname = xic_create_fontsetname (xic_defaut_fontset, False);
-         xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
-                               fontsetname, &missing_list,
-                               &missing_count, &def_string);
-#ifdef DEBUG_XIC_FONTSET
-         print_fontset_result (xfs, fontsetname, missing_list, missing_count);
-#endif
-         if (missing_list)
-           XFreeStringList (missing_list);
-         xfree (fontsetname);
-       }
-    }
-
-  if (FRAME_XIC_BASE_FONTNAME (f))
-    xfree (FRAME_XIC_BASE_FONTNAME (f));
-  FRAME_XIC_BASE_FONTNAME (f) = xstrdup (base_fontname);
-
-  /* No need to free def_string.  */
-  return xfs;
-}
-
-#ifdef USE_FONT_BACKEND
-
-static XFontSet
-xic_create_xfontset2 (f)
-     struct frame *f;
-{
-  XFontSet xfs = NULL;
-  struct font *font = FRAME_FONT_OBJECT (f);
+  struct font *font = FRAME_FONT (f);
   int pixel_size = font->pixel_size;
   Lisp_Object rest, frame;
 
@@ -2214,8 +2116,8 @@ xic_create_xfontset2 (f)
 
       if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
           && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f)
-         && FRAME_FONT_OBJECT (f)
-         && FRAME_FONT_OBJECT (f)->pixel_size == pixel_size)
+         && FRAME_FONT (f)
+         && FRAME_FONT (f)->pixel_size == pixel_size)
         {
           xfs = FRAME_XIC_FONTSET (cf);
           break;
@@ -2295,7 +2197,6 @@ xic_create_xfontset2 (f)
 
   return xfs;
 }
-#endif /* USE_FONT_BACKEND */
 
 /* Free the X fontset of frame F if it is the last frame using it.  */
 
@@ -2369,15 +2270,7 @@ create_frame_xic (f)
     return;
 
   /* Create X fontset. */
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    xfs = xic_create_xfontset2 (f);
-  else
-#endif
-  xfs = xic_create_xfontset
-    (f, (FRAME_FONTSET (f) < 0) ? NULL
-        : (char *) SDATA (fontset_ascii (FRAME_FONTSET (f))));
-
+  xfs = xic_create_xfontset (f);
   xim = FRAME_X_XIM (f);
   if (xim)
     {
@@ -2532,12 +2425,7 @@ xic_set_xfontset (f, base_fontname)
 
   xic_free_xfontset (f);
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    xfs = xic_create_xfontset2 (f);
-  else
-#endif
-  xfs = xic_create_xfontset (f, base_fontname);
+  xfs = xic_create_xfontset (f);
 
   attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
   if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
@@ -3041,20 +2929,13 @@ x_make_gc (f)
   /* Create the GCs of this frame.
      Note that many default values are used.  */
 
-  /* Normal video */
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    gc_values.font = FRAME_X_DISPLAY_INFO (f)->font->fid;
-  else
-#endif
-  gc_values.font = FRAME_FONT (f)->fid;
   gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
   gc_values.background = FRAME_BACKGROUND_PIXEL (f);
   gc_values.line_width = 0;    /* Means 1 using fast algorithm.  */
   f->output_data.x->normal_gc
     = XCreateGC (FRAME_X_DISPLAY (f),
                 FRAME_X_WINDOW (f),
-                GCLineWidth | GCFont | GCForeground | GCBackground,
+                GCLineWidth | GCForeground | GCBackground,
                 &gc_values);
 
   /* Reverse video style.  */
@@ -3063,7 +2944,7 @@ x_make_gc (f)
   f->output_data.x->reverse_gc
     = XCreateGC (FRAME_X_DISPLAY (f),
                 FRAME_X_WINDOW (f),
-                GCFont | GCForeground | GCBackground | GCLineWidth,
+                GCForeground | GCBackground | GCLineWidth,
                 &gc_values);
 
   /* Cursor has cursor-color background, background-color foreground.  */
@@ -3076,7 +2957,7 @@ x_make_gc (f)
                             cursor_bits, 16, 16);
   f->output_data.x->cursor_gc
     = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                (GCFont | GCForeground | GCBackground
+                (GCForeground | GCBackground
                  | GCFillStyle /* | GCStipple */ | GCLineWidth),
                 &gc_values);
 
@@ -3173,7 +3054,7 @@ unwind_create_frame (frame)
   return Qnil;
 }
 
-#ifdef USE_FONT_BACKEND
+
 static void
 x_default_font_parameter (f, parms)
      struct frame *f;
@@ -3210,7 +3091,7 @@ x_default_font_parameter (f, parms)
     }
   x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
 }
-#endif /* USE_FONT_BACKEND */
+
 
 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
        1, 1, 0,
@@ -3394,73 +3275,21 @@ This function is an internal primitive--use `make-frame' instead.  */)
   f->resx = dpyinfo->resx;
   f->resy = dpyinfo->resy;
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      /* Perhaps, we must allow frame parameter, say `font-backend',
-        to specify which font backends to use.  */
 #ifdef HAVE_FREETYPE
 #ifdef HAVE_XFT
-      register_font_driver (&xftfont_driver, f);
+  register_font_driver (&xftfont_driver, f);
 #else  /* not HAVE_XFT */
-      register_font_driver (&ftxfont_driver, f);
+  register_font_driver (&ftxfont_driver, f);
 #endif /* not HAVE_XFT */
 #endif /* HAVE_FREETYPE */
-      register_font_driver (&xfont_driver, f);
+  register_font_driver (&xfont_driver, f);
 
-      x_default_parameter (f, parms, Qfont_backend, Qnil,
-                          "fontBackend", "FontBackend", RES_TYPE_STRING);
-    }
-#endif /* USE_FONT_BACKEND */
+  x_default_parameter (f, parms, Qfont_backend, Qnil,
+                      "fontBackend", "FontBackend", RES_TYPE_STRING);
 
   /* Extract the window parameters from the supplied values
      that are needed to determine window geometry.  */
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    x_default_font_parameter (f, parms);
-else
-#endif /* USE_FONT_BACKEND */
-  {
-    Lisp_Object font;
-
-    font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
-
-    /* If the caller has specified no font, try out fonts which we
-       hope have bold and italic variations.  */
-    if (!STRINGP (font))
-      {
-       char *names[]
-         = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
-             "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
-             "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
-             /* This was formerly the first thing tried, but it finds
-                too many fonts and takes too long.  */
-             "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
-             /* If those didn't work, look for something which will
-                at least work.  */
-             "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
-             NULL };
-       int i;
-
-       BLOCK_INPUT;
-       for (i = 0; names[i]; i++)
-         {
-           Lisp_Object list;
-
-           list = x_list_fonts (f, build_string (names[i]), 0, 1);
-           if (CONSP (list))
-             {
-               font = XCAR (list);
-               break;
-             }
-         }
-       UNBLOCK_INPUT;
-       if (! STRINGP (font))
-         font = build_string ("fixed");
-      }
-    x_default_parameter (f, parms, Qfont, font,
-                        "font", "Font", RES_TYPE_STRING);
-  }
+  x_default_font_parameter (f, parms);
 
 #ifdef USE_LUCID
   /* Prevent lwlib/xlwmenu.c from crashing because of a bug
@@ -4987,68 +4816,21 @@ x_create_tip_frame (dpyinfo, parms, text)
   f->resx = dpyinfo->resx;
   f->resy = dpyinfo->resy;
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      /* Perhaps, we must allow frame parameter, say `font-backend',
-        to specify which font backends to use.  */
 #ifdef HAVE_FREETYPE
 #ifdef HAVE_XFT
-      register_font_driver (&xftfont_driver, f);
+  register_font_driver (&xftfont_driver, f);
 #else  /* not HAVE_XFT */
-      register_font_driver (&ftxfont_driver, f);
+  register_font_driver (&ftxfont_driver, f);
 #endif /* not HAVE_XFT */
 #endif /* HAVE_FREETYPE */
-      register_font_driver (&xfont_driver, f);
+  register_font_driver (&xfont_driver, f);
 
-      x_default_parameter (f, parms, Qfont_backend, Qnil,
-                          "fontBackend", "FontBackend", RES_TYPE_STRING);
-    }
-#endif /* USE_FONT_BACKEND */
+  x_default_parameter (f, parms, Qfont_backend, Qnil,
+                      "fontBackend", "FontBackend", RES_TYPE_STRING);
 
   /* Extract the window parameters from the supplied values that are
      needed to determine window geometry.  */
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    x_default_font_parameter (f, parms);
-else
-#endif /* USE_FONT_BACKEND */
-  {
-    Lisp_Object font;
-
-    font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
-
-    BLOCK_INPUT;
-    /* First, try whatever font the caller has specified.  */
-    if (STRINGP (font))
-      {
-       tem = Fquery_fontset (font, Qnil);
-       if (STRINGP (tem))
-         font = x_new_fontset (f, tem);
-       else
-         font = x_new_font (f, SDATA (font));
-      }
-
-    /* Try out a font which we hope has bold and italic variations.  */
-    if (!STRINGP (font))
-      font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
-    if (!STRINGP (font))
-      font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
-    if (! STRINGP (font))
-      font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
-    if (! STRINGP (font))
-      /* This was formerly the first thing tried, but it finds too many fonts
-        and takes too long.  */
-      font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
-    /* If those didn't work, look for something which will at least work.  */
-    if (! STRINGP (font))
-      font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
-    UNBLOCK_INPUT;
-    if (! STRINGP (font))
-      font = build_string ("fixed");
-
-    x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil));
-  }
+  x_default_font_parameter (f, parms);
 
   x_default_parameter (f, parms, Qborder_width, make_number (2),
                       "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
@@ -5991,9 +5773,7 @@ frame_parm_handler x_frame_parm_handlers[] =
   x_set_fringe_width,
   x_set_wait_for_wm,
   x_set_fullscreen,
-#ifdef USE_FONT_BACKEND
   x_set_font_backend
-#endif /* USE_FONT_BACKEND */
 };
 
 void
@@ -6193,18 +5973,6 @@ the tool bar buttons.  */);
   defsubr (&Sx_backspace_delete_keys_p);
 
   /* Setting callback functions for fontset handler.  */
-  get_font_info_func = x_get_font_info;
-
-#if 0 /* This function pointer doesn't seem to be used anywhere.
-        And the pointer assigned has the wrong type, anyway.  */
-  list_fonts_func = x_list_fonts;
-#endif
-
-  load_font_func = x_load_font;
-  find_ccl_program_func = x_find_ccl_program;
-  query_font_func = x_query_font;
-  set_frame_fontset_func = x_set_font;
-  get_font_repertory_func = x_get_font_repertory;
   check_window_system_func = check_x;
 
   hourglass_atimer = NULL;
index f13f3e5e36caef5627f15a65a9baa6bc0ab1c93d..8f400687a8abd0b850f5e0f68a77434a64c87ece 100644 (file)
@@ -23,6 +23,7 @@ Boston, MA 02110-1301, USA.  */
 
 #include <config.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <X11/Xlib.h>
 
 #include "lisp.h"
@@ -34,57 +35,26 @@ Boston, MA 02110-1301, USA.  */
 #include "charset.h"
 #include "fontset.h"
 #include "font.h"
+#include "ccl.h"
 
 \f
 /* X core font driver.  */
 
+struct xfont_info
+{
+  struct font font;
+  Display *display;
+  XFontStruct *xfont;
+};
+
 /* Prototypes of support functions.  */
 extern void x_clear_errors P_ ((Display *));
 
-static char *xfont_query_font P_ ((Display *, char *, Lisp_Object));
 static XCharStruct *xfont_get_pcm P_ ((XFontStruct *, XChar2b *));
+static void xfont_find_ccl_program P_ ((struct font *));
 static int xfont_registry_charsets P_ ((Lisp_Object, struct charset **,
                                        struct charset **));
 
-static char *
-xfont_query_font (display, name, spec)
-     Display *display;
-     char *name;
-     Lisp_Object spec;
-{
-  XFontStruct *font;
-
-  BLOCK_INPUT;
-  x_catch_errors (display);
-  font = XLoadQueryFont (display, name);
-  name = NULL;
-  if (x_had_errors_p (display))
-    {
-      /* This error is perhaps due to insufficient memory on X
-        server.  Let's just ignore it.  */
-      x_clear_errors (display);
-    }
-  else if (font)
-    {
-      unsigned long value;
-
-      if (XGetFontProperty (font, XA_FONT, &value))
-       {
-         char *n = (char *) XGetAtomName (display, (Atom) value);
-
-         if (font_parse_xlfd (n, spec) >= 0)
-           name = n;
-         else
-           XFree (n);
-       }
-      XFreeFont (display, font);
-    }
-  x_uncatch_errors ();
-  UNBLOCK_INPUT;
-
-  return name;
-}
-
 
 /* Get metrics of character CHAR2B in XFONT.  Value is null if CHAR2B
    is not contained in the font.  */
@@ -154,25 +124,60 @@ xfont_get_pcm (xfont, char2b)
          ? NULL : pcm);
 }
 
+/* Find a CCL program for a font specified by FONTP, and set the member
+ `encoder' of the structure.  */
+
+static void
+xfont_find_ccl_program (font)
+     struct font *font;
+{
+  Lisp_Object list, elt;
+
+  elt = Qnil;
+  for (list = Vfont_ccl_encoder_alist; CONSP (list); list = XCDR (list))
+    {
+      elt = XCAR (list);
+      if (CONSP (elt)
+         && STRINGP (XCAR (elt))
+         && ((fast_string_match_ignore_case (XCAR (elt),
+                                             font->props[FONT_NAME_INDEX])
+              >= 0)
+             || (fast_string_match_ignore_case (XCAR (elt),
+                                                font->props[FONT_FULLNAME_INDEX])
+                 >= 0)))
+       break;
+    }
+
+  if (! NILP (list))
+    {
+      struct ccl_program *ccl
+       = (struct ccl_program *) xmalloc (sizeof (struct ccl_program));
+
+      if (setup_ccl_program (ccl, XCDR (elt)) < 0)
+       xfree (ccl);
+      else
+       font->font_encoder = ccl;
+    }
+}
+
 static Lisp_Object xfont_get_cache P_ ((FRAME_PTR));
 static Lisp_Object xfont_list P_ ((Lisp_Object, Lisp_Object));
 static Lisp_Object xfont_match P_ ((Lisp_Object, Lisp_Object));
 static Lisp_Object xfont_list_family P_ ((Lisp_Object));
-static struct font *xfont_open P_ ((FRAME_PTR, Lisp_Object, int));
+static Lisp_Object xfont_open P_ ((FRAME_PTR, Lisp_Object, int));
 static void xfont_close P_ ((FRAME_PTR, struct font *));
 static int xfont_prepare_face P_ ((FRAME_PTR, struct face *));
-#if 0
-static void xfont_done_face P_ ((FRAME_PTR, struct face *));
-#endif
 static int xfont_has_char P_ ((Lisp_Object, int));
 static unsigned xfont_encode_char P_ ((struct font *, int));
 static int xfont_text_extents P_ ((struct font *, unsigned *, int,
                                   struct font_metrics *));
 static int xfont_draw P_ ((struct glyph_string *, int, int, int, int, int));
+static int xfont_check P_ ((FRAME_PTR, struct font *));
 
 struct font_driver xfont_driver =
   {
     0,                         /* Qx */
+    0,                         /* case insensitive */
     xfont_get_cache,
     xfont_list,
     xfont_match,
@@ -181,11 +186,13 @@ struct font_driver xfont_driver =
     xfont_open,
     xfont_close,
     xfont_prepare_face,
-    NULL /*xfont_done_face*/,
+    NULL,
     xfont_has_char,
     xfont_encode_char,
     xfont_text_extents,
-    xfont_draw
+    xfont_draw,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    xfont_check
   };
 
 extern Lisp_Object QCname;
@@ -201,6 +208,14 @@ xfont_get_cache (f)
 
 extern Lisp_Object Vface_alternative_font_registry_alist;
 
+static int
+compare_font_names (const void *name1, const void *name2)
+{
+  return strcasecmp (*(const char **) name1, *(const char **) name2);
+}
+
+static Lisp_Object xfont_list_pattern P_ ((Lisp_Object, Display *, char *));
+
 static Lisp_Object
 xfont_list_pattern (frame, display, pattern)
      Lisp_Object frame;
@@ -230,54 +245,55 @@ xfont_list_pattern (frame, display, pattern)
       XFreeFontNames (names);
     }
 
-  for (i = 0; i < num_fonts; i++)
+  if (num_fonts > 0)
     {
-      Lisp_Object entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil);
-      int result;
+      char **indices = alloca (sizeof (char *) * num_fonts);
 
-      ASET (entity, FONT_TYPE_INDEX, Qx);
-      ASET (entity, FONT_FRAME_INDEX, frame);
+      for (i = 0; i < num_fonts; i++)
+       indices[i] = names[i];
+      qsort (indices, num_fonts, sizeof (char *), compare_font_names);
 
-      result = font_parse_xlfd (names[i], entity);
-      if (result < 0)
+      for (i = 0; i < num_fonts; i++)
        {
-         /* This may be an alias name.  Try to get the full XLFD name
-            from XA_FONT property of the font.  */
-         XFontStruct *font = XLoadQueryFont (display, names[i]);
-         unsigned long value;
+         Lisp_Object entity;
+         int result;
 
-         if (! font)
+         if (i > 0 && strcasecmp (indices[i - 1], indices[i]) == 0)
            continue;
-         if (XGetFontProperty (font, XA_FONT, &value))
-           {
-             char *name = (char *) XGetAtomName (display, (Atom) value);
-             int len = strlen (name);
-
-             /* If DXPC (a Differential X Protocol Compressor)
-                 Ver.3.7 is running, XGetAtomName will return null
-                 string.  We must avoid such a name.  */
-             if (len > 0)
-               result = font_parse_xlfd (name, entity);
-             XFree (name);
-           }
-         XFreeFont (display, font);
-       }
 
-      if (result == 0)
-       {
-         Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX);
-         char *p = (char *) SDATA (SYMBOL_NAME (val));
+         entity = font_make_entity ();
+         ASET (entity, FONT_TYPE_INDEX, Qx);
 
-         /* P == "RESX-RESY-SPACING-AVGWIDTH.  We rejust this font if
-            it's an autoscaled one (i.e. RESX > 0 && AVGWIDTH == 0).  */
-         if (atoi (p) > 0)
+         result = font_parse_xlfd (indices[i], entity);
+         if (result < 0)
            {
-             p += SBYTES (SYMBOL_NAME (val));
-             while (p[-1] != '-') p--;
-             if (atoi (p) == 0)
+             /* This may be an alias name.  Try to get the full XLFD name
+                from XA_FONT property of the font.  */
+             XFontStruct *font = XLoadQueryFont (display, indices[i]);
+             unsigned long value;
+
+             if (! font)
                continue;
+             if (XGetFontProperty (font, XA_FONT, &value))
+               {
+                 char *name = (char *) XGetAtomName (display, (Atom) value);
+                 int len = strlen (name);
+
+                 /* If DXPC (a Differential X Protocol Compressor)
+                    Ver.3.7 is running, XGetAtomName will return null
+                    string.  We must avoid such a name.  */
+                 if (len > 0)
+                   result = font_parse_xlfd (name, entity);
+                 XFree (name);
+               }
+             XFreeFont (display, font);
            }
-         list = Fcons (entity, list);
+
+         if (result == 0
+             /* Avoid auto-scaled fonts.  */
+             && (XINT (AREF (entity, FONT_DPI_INDEX)) == 0
+                 || XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) > 0))
+           list = Fcons (entity, list);
        }
     }
 
@@ -293,63 +309,68 @@ xfont_list (frame, spec)
 {
   FRAME_PTR f = XFRAME (frame);
   Display *display = FRAME_X_DISPLAY_INFO (f)->display;
-  Lisp_Object list, val, extra, font_name;
+  Lisp_Object registry, list, val, extra, font_name;
+  Lisp_Object dpi, avgwidth;
   int len;
   char name[256];
   
   extra = AREF (spec, FONT_EXTRA_INDEX);
-  font_name = Qnil;
   if (CONSP (extra))
     {
       val = assq_no_quit (QCotf, extra);
       if (! NILP (val))
-       return null_vector;
+       return Qnil;
       val = assq_no_quit (QCscript, extra);
       if (! NILP (val))
-       return null_vector;
-      val = assq_no_quit (QClanguage, extra);
+       return Qnil;
+      val = assq_no_quit (QClang, extra);
       if (! NILP (val))
-       return null_vector;
-      val = assq_no_quit (QCname, extra);
-      if (CONSP (val))
-       font_name = XCDR (val);
+       return Qnil;
     }
 
-  if (STRINGP (font_name)
-      && ! strchr ((char *) SDATA (font_name), ':'))
-    list = xfont_list_pattern (frame, display, (char *) SDATA (font_name));
-  else if ((len = font_unparse_xlfd (spec, 0, name, 256)) < 0)
-    return null_vector;
-  else
+  registry = AREF (spec, FONT_REGISTRY_INDEX);
+  if (NILP (registry))
+    ASET (spec, FONT_REGISTRY_INDEX, Qiso8859_1);
+  len = font_unparse_xlfd (spec, 0, name, 256);
+  ASET (spec, FONT_REGISTRY_INDEX, registry);
+  if (len < 0)
+    return Qnil;
+  list = xfont_list_pattern (frame, display, name);
+  if (NILP (list) && NILP (registry))
     {
-      list = xfont_list_pattern (frame, display, name);
-      if (NILP (list))
+      /* Try iso10646-1 */
+      char *r = name + len - 9;        /* 9 == strlen (iso8859-1) */
+
+      if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */
        {
-         Lisp_Object registry = AREF (spec, FONT_REGISTRY_INDEX);
-         Lisp_Object alter;
+         strcpy (r, "iso10646-1");
+         list = xfont_list_pattern (frame, display, name);
+       }
+    }
+  if (NILP (list) && ! NILP (registry))
+    {
+      Lisp_Object alter;
 
-         if (! NILP (registry)
-             && (alter = Fassoc (SYMBOL_NAME (registry),
-                                 Vface_alternative_font_registry_alist),
-                 CONSP (alter)))
-           {
-             /* Pointer to REGISTRY-ENCODING field.  */
-             char *r = name + len - SBYTES (SYMBOL_NAME (registry));
-
-             for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter))
-               if (STRINGP (XCAR (alter))
-                   && ((r - name) + SBYTES (XCAR (alter))) < 255)
-                 {
-                   strcpy (r, (char *) SDATA (XCAR (alter)));
-                   list = xfont_list_pattern (frame, display, name);
-                   if (! NILP (list))
-                     break;
-                 }
-           }
+      if ((alter = Fassoc (SYMBOL_NAME (registry),
+                          Vface_alternative_font_registry_alist),
+          CONSP (alter)))
+       {
+         /* Pointer to REGISTRY-ENCODING field.  */
+         char *r = name + len - SBYTES (SYMBOL_NAME (registry));
+
+         for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter))
+           if (STRINGP (XCAR (alter))
+               && ((r - name) + SBYTES (XCAR (alter))) < 256)
+             {
+               strcpy (r, (char *) SDATA (XCAR (alter)));
+               list = xfont_list_pattern (frame, display, name);
+               if (! NILP (list))
+                 break;
+             }
        }
     }
 
-  return (NILP (list) ? null_vector : Fvconcat (1, &list));
+  return list;
 }
 
 static Lisp_Object
@@ -359,18 +380,23 @@ xfont_match (frame, spec)
   FRAME_PTR f = XFRAME (frame);
   Display *display = FRAME_X_DISPLAY_INFO (f)->display;
   Lisp_Object extra, val, entity;
-  char *name;
+  char buf[256], *name;
   XFontStruct *xfont;
   unsigned long value;
 
   extra = AREF (spec, FONT_EXTRA_INDEX);
   val = assq_no_quit (QCname, extra);
   if (! CONSP (val) || ! STRINGP (XCDR (val)))
-    return Qnil;
+    {
+      if (font_unparse_xlfd (spec, 0, buf, 256) < 0)
+       return Qnil;
+      name = buf;
+    }
+  else
+    name = (char *) SDATA (XCDR (val));
 
   BLOCK_INPUT;
   entity = Qnil;
-  name = (char *) SDATA (XCDR (val));
   xfont = XLoadQueryFont (display, name);
   if (xfont)
     {
@@ -386,9 +412,8 @@ xfont_match (frame, spec)
             string.  We must avoid such a name.  */
          if (len > 0)
            {
-             entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil);
+             entity = font_make_entity ();
              ASET (entity, FONT_TYPE_INDEX, Qx);
-             ASET (entity, FONT_FRAME_INDEX, frame);
              if (font_parse_xlfd (name, entity) < 0)
                entity = Qnil;
            }
@@ -453,8 +478,8 @@ xfont_list_family (frame)
        continue;
       last_len = p1 - p0;
       last_family = p0;
-      family = intern_downcase (p0, last_len);
-      if (! memq_no_quit (family, list))
+      family = make_unibyte_string (p0, last_len);
+      if (NILP (Fassoc_string (family, list, Qt)))
        list = Fcons (family, list);
     }
 
@@ -465,7 +490,9 @@ xfont_list_family (frame)
   return list;
 }
 
-static struct font *
+extern Lisp_Object QCavgwidth;
+
+static Lisp_Object
 xfont_open (f, entity, pixel_size)
      FRAME_PTR f;
      Lisp_Object entity;
@@ -478,20 +505,29 @@ xfont_open (f, entity, pixel_size)
   unsigned long value;
   Lisp_Object registry;
   struct charset *encoding, *repertory;
+  Lisp_Object font_object, fullname;
   struct font *font;
   XFontStruct *xfont;
+  int i;
 
   /* At first, check if we know how to encode characters for this
      font.  */
   registry = AREF (entity, FONT_REGISTRY_INDEX);
   if (font_registry_charsets (registry, &encoding, &repertory) < 0)
-    return NULL;
+    return Qnil;
 
   if (XINT (AREF (entity, FONT_SIZE_INDEX)) != 0)
     pixel_size = XINT (AREF (entity, FONT_SIZE_INDEX));
+  else if (pixel_size == 0)
+    {
+      if (FRAME_FONT (f))
+       pixel_size = FRAME_FONT (f)->pixel_size;
+      else
+       pixel_size = 14;
+    }
   len = font_unparse_xlfd (entity, pixel_size, name, 256);
   if (len <= 0)
-    return NULL;
+    return Qnil;
 
   BLOCK_INPUT;
   x_catch_errors (display);
@@ -503,147 +539,122 @@ xfont_open (f, entity, pixel_size)
       x_clear_errors (display);
       xfont = NULL;
     }
+  fullname = Qnil;
+  /* Try to get the full name of FONT.  */
+  if (xfont && XGetFontProperty (xfont, XA_FONT, &value))
+    {
+      char *p0, *p;
+      int dashes = 0;
+
+      p0 = p = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);;
+      /* Count the number of dashes in the "full name".
+        If it is too few, this isn't really the font's full name,
+        so don't use it.
+        In X11R4, the fonts did not come with their canonical names
+        stored in them.  */
+      while (*p)
+       {
+         if (*p == '-')
+           dashes++;
+         p++;
+       }
+
+      if (dashes >= 13)
+       fullname = Fdowncase (make_unibyte_string (p0, p - p0));
+      XFree (p0);
+    }
   x_uncatch_errors ();
   UNBLOCK_INPUT;
 
   if (! xfont)
-    return NULL;
-  font = malloc (sizeof (struct font));
-  font->format = Qx;
-  font->font.font = xfont;
-  font->entity = entity;
+    return Qnil;
+
+  font_object = font_make_object (VECSIZE (struct xfont_info));
+  ASET (font_object, FONT_TYPE_INDEX, Qx);
+  if (STRINGP (fullname))
+    font_parse_xlfd (SDATA (fullname), font_object);
+  for (i = 1; i < FONT_ENTITY_MAX; i++)
+    ASET (font_object, i, AREF (entity, i));
+  ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size));
+  if (STRINGP (fullname))
+    ASET (font_object, FONT_NAME_INDEX, fullname);
+  else
+    ASET (font_object, FONT_NAME_INDEX, make_unibyte_string (name, len));
+  ASET (font_object, FONT_FULLNAME_INDEX, fullname);
+  ASET (font_object, FONT_FILE_INDEX, Qnil);
+  ASET (font_object, FONT_FORMAT_INDEX, Qx);
+  font = XFONT_OBJECT (font_object);
+  ((struct xfont_info *) font)->xfont = xfont;
+  ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
   font->pixel_size = pixel_size;
   font->driver = &xfont_driver;
-  font->font.name = malloc (len + 1);
-  if (! font->font.name)
-    {
-      XFreeFont (display, xfont);
-      free (font);
-      return NULL;
-    }
-  bcopy (name, font->font.name, len + 1);
-  font->font.charset = encoding->id;
   font->encoding_charset = encoding->id;
   font->repertory_charset = repertory ? repertory->id : -1;
   font->ascent = xfont->ascent;
   font->descent = xfont->descent;
-
+  font->height = font->ascent + font->descent;
+  font->min_width = xfont->min_bounds.width;
   if (xfont->min_bounds.width == xfont->max_bounds.width)
     {
       /* Fixed width font.  */
-      font->font.average_width = font->font.space_width
-       = xfont->min_bounds.width;
+      font->average_width = font->space_width = xfont->min_bounds.width;
     }
   else
     {
-      XChar2b char2b;
       XCharStruct *pcm;
+      XChar2b char2b;
+      Lisp_Object val;
 
       char2b.byte1 = 0x00, char2b.byte2 = 0x20;
       pcm = xfont_get_pcm (xfont, &char2b);
       if (pcm)
-       font->font.space_width = pcm->width;
+       font->space_width = pcm->width;
       else
-       font->font.space_width = xfont->max_bounds.width;
-
-      font->font.average_width
-       = (XGetFontProperty (xfont, dpyinfo->Xatom_AVERAGE_WIDTH, &value)
-          ? (long) value / 10 : 0);
-      if (font->font.average_width < 0)
-       font->font.average_width = - font->font.average_width;
-      if (font->font.average_width == 0)
-       {
-         if (pcm)
-           {
-             int width = pcm->width;
-             for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
-               if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL)
-                 width += pcm->width;
-             font->font.average_width = width / 95;
-           }
-         else
-           font->font.average_width = xfont->max_bounds.width;
-       }
-    }
-  font->min_width = xfont->min_bounds.width;
-  if (font->min_width <= 0)
-    font->min_width = font->font.space_width;
-
-  BLOCK_INPUT;
-  /* Try to get the full name of FONT.  Put it in FULL_NAME.  */
-  if (XGetFontProperty (xfont, XA_FONT, &value))
-    {
-      char *full_name = NULL, *p0, *p;
-      int dashes = 0;
-
-      p0 = p = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);;
-      /* Count the number of dashes in the "full name".
-        If it is too few, this isn't really the font's full name,
-        so don't use it.
-        In X11R4, the fonts did not come with their canonical names
-        stored in them.  */
-      while (*p)
+       font->space_width = 0;
+
+      val = Ffont_get (font_object, QCavgwidth);
+      if (INTEGERP (val))
+       font->average_width = XINT (val);
+      if (font->average_width < 0)
+       font->average_width = - font->average_width;
+      if (font->average_width == 0
+         && encoding->ascii_compatible_p)
        {
-         if (*p == '-')
-           dashes++;
-         p++;
-       }
+         int width = font->space_width, n = pcm != NULL;
 
-      if (dashes >= 13)
-       {
-         full_name = (char *) malloc (p - p0 + 1);
-         if (full_name)
-           bcopy (p0, full_name, p - p0 + 1);
+         for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
+           if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL)
+             width += pcm->width, n++;
+         font->average_width = width / n;
        }
-      XFree (p0);
-
-      if (full_name)
-       font->font.full_name = full_name;
-      else
-       font->font.full_name = font->font.name;
     }
-  font->file_name = NULL;
 
-  font->font.size = xfont->max_bounds.width;
-  font->font.height = xfont->ascent + xfont->descent;
-  font->font.baseline_offset
+  BLOCK_INPUT;
+  font->underline_thickness
+    = (XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &value)
+       ? (long) value : 0);
+  font->underline_position
+    = (XGetFontProperty (xfont, XA_UNDERLINE_POSITION, &value)
+       ? (long) value : -1);
+  font->baseline_offset
     = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value)
        ? (long) value : 0);
-  font->font.relative_compose
+  font->relative_compose
     = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value)
        ? (long) value : 0);
-  font->font.default_ascent
+  font->default_ascent
     = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value)
        ? (long) value : 0);
-  font->font.vertical_centering
-    = (STRINGP (Vvertical_centering_font_regexp)
-       && (fast_c_string_match_ignore_case
-          (Vvertical_centering_font_regexp, font->font.full_name) >= 0));
-
   UNBLOCK_INPUT;
 
-  dpyinfo->n_fonts++;
-
-  /* Set global flag fonts_changed_p to non-zero if the font loaded
-     has a character with a smaller width than any other character
-     before, or if the font loaded has a smaller height than any other
-     font loaded before.  If this happens, it will make a glyph matrix
-     reallocation necessary.  */
-  if (dpyinfo->n_fonts == 1)
-    {
-      dpyinfo->smallest_font_height = font->font.height;
-      dpyinfo->smallest_char_width = font->min_width;
-      fonts_changed_p = 1;
-    }
-  else
-    {
-      if (dpyinfo->smallest_font_height > font->font.height)
-       dpyinfo->smallest_font_height = font->font.height, fonts_changed_p |= 1;
-      if (dpyinfo->smallest_char_width > font->min_width)
-       dpyinfo->smallest_char_width = font->min_width, fonts_changed_p |= 1;
-    }
+  if (NILP (fullname))
+    fullname = AREF (font_object, FONT_NAME_INDEX);
+  font->vertical_centering
+    = (STRINGP (Vvertical_centering_font_regexp)
+       && (fast_string_match_ignore_case
+          (Vvertical_centering_font_regexp, fullname) >= 0));
 
-  return font;
+  return font_object;
 }
 
 static void
@@ -652,14 +663,8 @@ xfont_close (f, font)
      struct font *font;
 {
   BLOCK_INPUT;
-  XFreeFont (FRAME_X_DISPLAY (f), font->font.font);
+  XFreeFont (FRAME_X_DISPLAY (f), ((struct xfont_info *) font)->xfont);
   UNBLOCK_INPUT;
-
-  if (font->font.name != font->font.full_name)
-    free (font->font.full_name);
-  free (font->font.name);
-  free (font);
-  FRAME_X_DISPLAY_INFO (f)->n_fonts--;
 }
 
 static int
@@ -668,28 +673,13 @@ xfont_prepare_face (f, face)
      struct face *face;
 {
   BLOCK_INPUT;
-  XSetFont (FRAME_X_DISPLAY (f), face->gc, face->font->fid);
+  XSetFont (FRAME_X_DISPLAY (f), face->gc,
+           ((struct xfont_info *) face->font)->xfont->fid);
   UNBLOCK_INPUT;
 
   return 0;
 }
 
-#if 0
-static void
-xfont_done_face (f, face)
-     FRAME_PTR f;
-     struct face *face;
-{
-  if (face->extra)
-    {
-      BLOCK_INPUT;
-      XFreeGC (FRAME_X_DISPLAY (f), (GC) face->extra);
-      UNBLOCK_INPUT;
-      face->extra = NULL;
-    }
-}
-#endif /* 0 */
-
 static int
 xfont_has_char (entity, c)
      Lisp_Object entity;
@@ -710,6 +700,7 @@ xfont_encode_char (font, c)
      struct font *font;
      int c;
 {
+  XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
   struct charset *charset;
   unsigned code;
   XChar2b char2b;
@@ -726,7 +717,7 @@ xfont_encode_char (font, c)
     }
   char2b.byte1 = code >> 8;
   char2b.byte2 = code & 0xFF;
-  return (xfont_get_pcm (font->font.font, &char2b) ? code : FONT_INVALID_CODE);
+  return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE);
 }
 
 static int
@@ -736,6 +727,7 @@ xfont_text_extents (font, code, nglyphs, metrics)
      int nglyphs;
      struct font_metrics *metrics;
 {
+  XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
   int width = 0;
   int i, x;
 
@@ -749,7 +741,7 @@ xfont_text_extents (font, code, nglyphs, metrics)
       if (code[i] >= 0x10000)
        continue;
       char2b.byte1 = code[i] >> 8, char2b.byte2 = code[i] & 0xFF;
-      pcm = xfont_get_pcm (font->font.font, &char2b);
+      pcm = xfont_get_pcm (xfont, &char2b);
       if (! pcm)
        continue;
       if (metrics->lbearing > width + pcm->lbearing)
@@ -772,20 +764,15 @@ xfont_draw (s, from, to, x, y, with_background)
      struct glyph_string *s;
      int from, to, x, y, with_background;
 {
-  XFontStruct *xfont = s->face->font;
+  XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont;
   int len = to - from;
   GC gc = s->gc;
   int i;
 
-  if (gc != s->face->gc)
+  if (s->gc != s->face->gc)
     {
-      XGCValues xgcv;
-      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (s->f);
-
       BLOCK_INPUT;
-      XGetGCValues (s->display, gc, GCFont, &xgcv);
-      if (xgcv.font != xfont->fid)
-       XSetFont (s->display, gc, xfont->fid);
+      XSetFont (s->display, gc, xfont->fid);
       UNBLOCK_INPUT;
     }
 
@@ -849,6 +836,16 @@ xfont_draw (s, from, to, x, y, with_background)
   return len;
 }
 
+static int
+xfont_check (f, font)
+     FRAME_PTR f;
+     struct font *font;
+{
+  struct xfont_info *xfont = (struct xfont_info *) font;
+
+  return (FRAME_X_DISPLAY (f) == xfont->display ? 0 : -1);
+}
+
 \f
 void
 syms_of_xfont ()
index 55d0b943c13af084425e9668fa7a357b7e6cc1c3..1324b4dcd5bf8b40d2a4b376349e768dff9c4a18 100644 (file)
@@ -137,7 +137,7 @@ xftfont_get_colors (f, face, gc, xftface_info, fg, bg)
 
 static Lisp_Object xftfont_list P_ ((Lisp_Object, Lisp_Object));
 static Lisp_Object xftfont_match P_ ((Lisp_Object, Lisp_Object));
-static struct font *xftfont_open P_ ((FRAME_PTR, Lisp_Object, int));
+static Lisp_Object xftfont_open P_ ((FRAME_PTR, Lisp_Object, int));
 static void xftfont_close P_ ((FRAME_PTR, struct font *));
 static int xftfont_prepare_face P_ ((FRAME_PTR, struct face *));
 static void xftfont_done_face P_ ((FRAME_PTR, struct face *));
@@ -157,13 +157,12 @@ xftfont_list (frame, spec)
      Lisp_Object frame;
      Lisp_Object spec;
 {
-  Lisp_Object val = ftfont_driver.list (frame, spec);
+  Lisp_Object list = ftfont_driver.list (frame, spec), tail;
   int i;
   
-  if (! NILP (val))
-    for (i = 0; i < ASIZE (val); i++)
-      ASET (AREF (val, i), FONT_TYPE_INDEX, Qxft);
-  return val;
+  for (tail = list; CONSP (tail); tail = XCDR (tail))
+    ASET (XCAR (tail), FONT_TYPE_INDEX, Qxft);
+  return list;
 }
 
 static Lisp_Object
@@ -173,7 +172,7 @@ xftfont_match (frame, spec)
 {
   Lisp_Object entity = ftfont_driver.match (frame, spec);
 
-  if (VECTORP (entity))
+  if (! NILP (entity))
     ASET (entity, FONT_TYPE_INDEX, Qxft);
   return entity;
 }
@@ -182,7 +181,7 @@ extern Lisp_Object ftfont_font_format P_ ((FcPattern *));
 
 static FcChar8 ascii_printable[95];
 
-static struct font *
+static Lisp_Object
 xftfont_open (f, entity, pixel_size)
      FRAME_PTR f;
      Lisp_Object entity;
@@ -190,7 +189,7 @@ xftfont_open (f, entity, pixel_size)
 {
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   Display *display = FRAME_X_DISPLAY (f);
-  Lisp_Object val;
+  Lisp_Object val, font_object;
   FcPattern *pattern, *pat = NULL;
   FcChar8 *file;
   struct xftfont_info *xftfont_info = NULL;
@@ -199,18 +198,19 @@ xftfont_open (f, entity, pixel_size)
   double size = 0;
   XftFont *xftfont = NULL;
   int spacing;
-  char *name;
-  int len;
+  char name[256];
+  int len, i;
   XGlyphInfo extents;
   FT_Face ft_face;
 
-  val = AREF (entity, FONT_EXTRA_INDEX);
-  if (XTYPE (val) != Lisp_Misc
-      || XMISCTYPE (val) != Lisp_Misc_Save_Value)
-    return NULL;
-  pattern = XSAVE_VALUE (val)->pointer;
+  val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
+  if (! CONSP (val)
+      || XTYPE (XCDR (val)) != Lisp_Misc
+      || XMISCTYPE (XCDR (val)) != Lisp_Misc_Save_Value)
+    return Qnil;
+  pattern = XSAVE_VALUE (XCDR (val))->pointer;
   if (FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch)
-    return NULL;
+    return Qnil;
 
   size = XINT (AREF (entity, FONT_SIZE_INDEX));
   if (size == 0)
@@ -228,49 +228,39 @@ xftfont_open (f, entity, pixel_size)
   BLOCK_INPUT;
   XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat);
   xftfont = XftFontOpenPattern (display, pat);
+  UNBLOCK_INPUT;
+  if (! xftfont)
+    return Qnil;
   /* We should not destroy PAT here because it is kept in XFTFONT and
      destroyed automatically when XFTFONT is closed.  */
-  if (! xftfont)
-    goto err;
-
-  xftfont_info = malloc (sizeof (struct xftfont_info));
-  if (! xftfont_info)
-    goto err;
-  xfont = malloc (sizeof (XFontStruct));
-  if (! xfont)
-    goto err;
+  font_object = font_make_object (VECSIZE (struct xftfont_info));
+  ASET (font_object, FONT_TYPE_INDEX, Qxft);
+  for (i = 1; i < FONT_ENTITY_MAX; i++)
+    ASET (font_object, i, AREF (entity, i));
+  ASET (font_object, FONT_SIZE_INDEX, make_number (size));
+  len = font_unparse_xlfd (entity, size, name, 256);
+  if (len > 0)
+    ASET (font_object, FONT_NAME_INDEX, make_unibyte_string (name, len));
+  len = font_unparse_fcname (entity, size, name, 256);
+  if (len > 0)
+    ASET (font_object, FONT_FULLNAME_INDEX, make_unibyte_string (name, len));
+  else
+    ASET (font_object, FONT_FULLNAME_INDEX,
+         AREF (font_object, FONT_NAME_INDEX));
+  ASET (font_object, FONT_FILE_INDEX,
+       make_unibyte_string ((char *) file, strlen ((char *) file)));
+  ASET (font_object, FONT_FORMAT_INDEX, ftfont_font_format (pattern));
+  font = XFONT_OBJECT (font_object);
+  font->pixel_size = pixel_size;
+  font->driver = &xftfont_driver;
+  font->encoding_charset = font->repertory_charset = -1;
+
+  xftfont_info = (struct xftfont_info *) font;
   xftfont_info->display = display;
   xftfont_info->screen = FRAME_X_SCREEN_NUMBER (f);
   xftfont_info->xftfont = xftfont;
-#ifdef HAVE_LIBOTF
-  ft_face = XftLockFace (xftfont);
-  xftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT;
-  XftUnlockFace (xftfont);
-  xftfont_info->otf = NULL;
-#endif /* HAVE_LIBOTF */
-
-  font = (struct font *) xftfont_info;
-  font->format = ftfont_font_format (xftfont->pattern);
-  font->entity = entity;
   font->pixel_size = size;
   font->driver = &xftfont_driver;
-  len = 96;
-  name = malloc (len);
-  while (name && font_unparse_fcname (entity, pixel_size, name, len) < 0)
-    {
-      char *new = realloc (name, len += 32);
-
-      if (! new)
-       free (name);
-      name = new;
-    }
-  if (! name)
-    goto err;
-  font->font.full_name = font->font.name = name;
-  font->file_name = (char *) file;
-  font->font.size = xftfont->max_advance_width;
-  font->font.charset = font->encoding_charset = font->repertory_charset = -1;
-
   if (FcPatternGetInteger (xftfont->pattern, FC_SPACING, 0, &spacing)
       != FcResultMatch)
     spacing = FC_PROPORTIONAL;
@@ -280,21 +270,22 @@ xftfont_open (f, entity, pixel_size)
       for (i = 0; i < 95; i++)
        ascii_printable[i] = ' ' + i;
     }
+  BLOCK_INPUT;
   if (spacing != FC_PROPORTIONAL)
     {
-      font->font.average_width = font->font.space_width
+      font->min_width = font->average_width = font->space_width
        = xftfont->max_advance_width;
       XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
     }
   else
     {
       XftTextExtents8 (display, xftfont, ascii_printable, 1, &extents);
-      font->font.space_width = extents.xOff;
-      if (font->font.space_width <= 0)
+      font->space_width = extents.xOff;
+      if (font->space_width <= 0)
        /* dirty workaround */
-       font->font.space_width = pixel_size;    
+       font->space_width = pixel_size; 
       XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
-      font->font.average_width = (font->font.space_width + extents.xOff) / 95;
+      font->average_width = (font->space_width + extents.xOff) / 95;
     }
   UNBLOCK_INPUT;
 
@@ -304,57 +295,37 @@ xftfont_open (f, entity, pixel_size)
   font->descent = xftfont->descent;
   if (font->descent < extents.height - extents.y)
     font->descent = extents.height - extents.y;
-  font->font.height = font->ascent + font->descent;
+  font->height = font->ascent + font->descent;
 
-  /* Unfortunately Xft doesn't provide a way to get minimum char
-     width.  So, we use space_width instead.  */
-  font->min_width = font->font.space_width;
-
-  font->font.baseline_offset = 0;
-  font->font.relative_compose = 0;
-  font->font.default_ascent = 0;
-  font->font.vertical_centering = 0;
-
-  /* Setup pseudo XFontStruct */
-  xfont->fid = 0;
-  xfont->ascent = font->ascent;
-  xfont->descent = font->descent;
-  xfont->max_bounds.descent = font->descent;
-  xfont->max_bounds.width = xftfont->max_advance_width;
-  xfont->min_bounds.width = font->font.space_width;
-  font->font.font = xfont;
-
-  dpyinfo->n_fonts++;
-
-  /* Set global flag fonts_changed_p to non-zero if the font loaded
-     has a character with a smaller width than any other character
-     before, or if the font loaded has a smaller height than any other
-     font loaded before.  If this happens, it will make a glyph matrix
-     reallocation necessary.  */
-  if (dpyinfo->n_fonts == 1)
+  ft_face = XftLockFace (xftfont);
+  if (XINT (AREF (entity, FONT_SIZE_INDEX)) == 0)
     {
-      dpyinfo->smallest_font_height = font->font.height;
-      dpyinfo->smallest_char_width = font->min_width;
-      fonts_changed_p = 1;
+      int upEM = ft_face->units_per_EM;
+
+      font->underline_position = -ft_face->underline_position * size / upEM;
+      font->underline_thickness = -ft_face->underline_thickness * size / upEM;
     }
   else
     {
-      if (dpyinfo->smallest_font_height > font->font.height)
-       dpyinfo->smallest_font_height = font->font.height,
-         fonts_changed_p |= 1;
-      if (dpyinfo->smallest_char_width > font->min_width)
-       dpyinfo->smallest_char_width = font->min_width,
-         fonts_changed_p |= 1;
+      font->underline_position = -1;
+      font->underline_thickness = 0;
     }
+#ifdef HAVE_LIBOTF
+  xftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT;
+  xftfont_info->otf = NULL;
+#endif /* HAVE_LIBOTF */
+  XftUnlockFace (xftfont);
 
-  return font;
+  /* Unfortunately Xft doesn't provide a way to get minimum char
+     width.  So, we use space_width instead.  */
+  font->min_width = font->space_width;
 
- err:
-  if (xftfont) XftFontClose (display, xftfont);
-  UNBLOCK_INPUT;
-  if (xftfont_info) free (xftfont_info);
-  if (xfont) free (xfont);
-  return NULL;
+  font->baseline_offset = 0;
+  font->relative_compose = 0;
+  font->default_ascent = 0;
+  font->vertical_centering = 0;
+
+  return font_object;
 }
 
 static void
@@ -368,11 +339,9 @@ xftfont_close (f, font)
   if (xftfont_info->otf)
     OTF_close (xftfont_info->otf);
 #endif
+  BLOCK_INPUT;
   XftFontClose (xftfont_info->display, xftfont_info->xftfont);
-  if (font->font.name)
-    free (font->font.name);
-  free (font);
-  FRAME_X_DISPLAY_INFO (f)->n_fonts--;
+  UNBLOCK_INPUT;
 }
 
 static int
@@ -394,12 +363,8 @@ xftfont_prepare_face (f, face)
   xftface_info = malloc (sizeof (struct xftface_info));
   if (! xftface_info)
     return -1;
-
-  BLOCK_INPUT;
   xftfont_get_colors (f, face, face->gc, NULL,
                      &xftface_info->xft_fg, &xftface_info->xft_bg);
-  UNBLOCK_INPUT;
-
   face->extra = xftface_info;
   return 0;
 }
@@ -491,7 +456,7 @@ xftfont_draw (s, from, to, x, y, with_background)
 {
   FRAME_PTR f = s->f;
   struct face *face = s->face;
-  struct xftfont_info *xftfont_info = (struct xftfont_info *) s->font_info;
+  struct xftfont_info *xftfont_info = (struct xftfont_info *) s->font;
   struct xftface_info *xftface_info = NULL;
   XftDraw *xft_draw = xftfont_get_xft_draw (f);
   FT_UInt *code;
@@ -500,7 +465,7 @@ xftfont_draw (s, from, to, x, y, with_background)
   int len = to - from;
   int i;
 
-  if (s->font_info == face->font_info)
+  if (s->font == face->font)
     xftface_info = (struct xftface_info *) face->extra;
   xftfont_get_colors (f, face, s->gc, xftface_info,
                      &fg, with_background ? &bg : NULL);
@@ -511,12 +476,8 @@ xftfont_draw (s, from, to, x, y, with_background)
     XftDrawSetClip (xft_draw, NULL);
 
   if (with_background)
-    {
-      struct font *font = (struct font *) face->font_info;
-
-      XftDrawRect (xft_draw, &bg,
-                  x, y - face->font->ascent, s->width, font->font.height);
-    }
+    XftDrawRect (xft_draw, &bg,
+                x, y - face->font->ascent, s->width, face->font->height);
   code = alloca (sizeof (FT_UInt) * len);
   for (i = 0; i < len; i++)
     code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
index 147e492e7d5087b3b80fa25744522f9c6924b456..7dc1c2cb4877b6efd49ba1c1c4007d6df820b2d9 100644 (file)
@@ -70,7 +70,6 @@ Boston, MA 02110-1301, USA.  */
 #include "charset.h"
 #include "character.h"
 #include "coding.h"
-#include "ccl.h"
 #include "frame.h"
 #include "dispextern.h"
 #include "fontset.h"
@@ -86,6 +85,7 @@ Boston, MA 02110-1301, USA.  */
 #include "process.h"
 #include "atimer.h"
 #include "keymap.h"
+#include "font.h"
 
 #ifdef USE_X_TOOLKIT
 #include <X11/Shell.h>
@@ -102,10 +102,6 @@ Boston, MA 02110-1301, USA.  */
 #include "gtkutil.h"
 #endif
 
-#ifdef USE_FONT_BACKEND
-#include "font.h"
-#endif /* USE_FONT_BACKEND */
-
 #ifdef USE_LUCID
 extern int xlwmenu_window_p P_ ((Widget w, Window window));
 extern void xlwmenu_redisplay P_ ((Widget));
@@ -340,8 +336,6 @@ static void x_update_window_end P_ ((struct window *, int, int));
 static int x_io_error_quitter P_ ((Display *));
 static struct terminal *x_create_terminal P_ ((struct x_display_info *));
 void x_delete_terminal P_ ((struct terminal *));
-static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
-static int x_compute_min_glyph_bounds P_ ((struct frame *));
 static void x_update_end P_ ((struct frame *));
 static void XTframe_up_to_date P_ ((struct frame *));
 static void XTset_terminal_modes P_ ((struct terminal *));
@@ -870,155 +864,6 @@ XTreset_terminal_modes (struct terminal *terminal)
 {
 }
 
-
-\f
-/***********************************************************************
-                          Display Iterator
- ***********************************************************************/
-
-/* Function prototypes of this page.  */
-
-static int x_encode_char P_ ((int, XChar2b *, struct font_info *,
-                             struct charset *, int *));
-
-
-/* Get metrics of character CHAR2B in FONT.  Value is null if CHAR2B
-   is not contained in the font.  */
-
-static XCharStruct *
-x_per_char_metric (font, char2b, font_type)
-     XFontStruct *font;
-     XChar2b *char2b;
-     int font_type;  /* unused on X */
-{
-  /* The result metric information.  */
-  XCharStruct *pcm = NULL;
-
-  xassert (font && char2b);
-
-  if (font->per_char != NULL)
-    {
-      if (font->min_byte1 == 0 && font->max_byte1 == 0)
-       {
-         /* min_char_or_byte2 specifies the linear character index
-            corresponding to the first element of the per_char array,
-            max_char_or_byte2 is the index of the last character.  A
-            character with non-zero CHAR2B->byte1 is not in the font.
-            A character with byte2 less than min_char_or_byte2 or
-            greater max_char_or_byte2 is not in the font.  */
-         if (char2b->byte1 == 0
-             && char2b->byte2 >= font->min_char_or_byte2
-             && char2b->byte2 <= font->max_char_or_byte2)
-           pcm = font->per_char + char2b->byte2 - font->min_char_or_byte2;
-       }
-      else
-       {
-         /* If either min_byte1 or max_byte1 are nonzero, both
-            min_char_or_byte2 and max_char_or_byte2 are less than
-            256, and the 2-byte character index values corresponding
-            to the per_char array element N (counting from 0) are:
-
-            byte1 = N/D + min_byte1
-            byte2 = N\D + min_char_or_byte2
-
-            where:
-
-            D = max_char_or_byte2 - min_char_or_byte2 + 1
-            / = integer division
-            \ = integer modulus  */
-         if (char2b->byte1 >= font->min_byte1
-             && char2b->byte1 <= font->max_byte1
-             && char2b->byte2 >= font->min_char_or_byte2
-             && char2b->byte2 <= font->max_char_or_byte2)
-           {
-             pcm = (font->per_char
-                    + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1)
-                       * (char2b->byte1 - font->min_byte1))
-                    + (char2b->byte2 - font->min_char_or_byte2));
-           }
-       }
-    }
-  else
-    {
-      /* If the per_char pointer is null, all glyphs between the first
-        and last character indexes inclusive have the same
-        information, as given by both min_bounds and max_bounds.  */
-      if (char2b->byte2 >= font->min_char_or_byte2
-         && char2b->byte2 <= font->max_char_or_byte2)
-       pcm = &font->max_bounds;
-    }
-
-  return ((pcm == NULL
-          || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
-         ? NULL : pcm);
-}
-
-
-/* Encode CHAR2B using encoding information from FONT_INFO.  CHAR2B is
-   the two-byte form of C.  Encoding is returned in *CHAR2B.  */
-
-static int
-x_encode_char (c, char2b, font_info, charset, two_byte_p)
-     int c;
-     XChar2b *char2b;
-     struct font_info *font_info;
-     struct charset *charset;
-     int *two_byte_p;
-{
-  XFontStruct *font = font_info->font;
-
-  /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
-     This may be either a program in a special encoder language or a
-     fixed encoding.  */
-  if (font_info->font_encoder)
-    {
-      /* It's a program.  */
-      struct ccl_program *ccl = font_info->font_encoder;
-
-      check_ccl_update (ccl);
-      if (CHARSET_DIMENSION (charset) == 1)
-       {
-         ccl->reg[0] = CHARSET_ID (charset);
-         ccl->reg[1] = char2b->byte2;
-         ccl->reg[2] = -1;
-       }
-      else
-       {
-         ccl->reg[0] = CHARSET_ID (charset);
-         ccl->reg[1] = char2b->byte1;
-         ccl->reg[2] = char2b->byte2;
-       }
-
-      ccl_driver (ccl, NULL, NULL, 0, 0, Qnil);
-
-      /* We assume that MSBs are appropriately set/reset by CCL
-        program.  */
-      if (font->max_byte1 == 0)        /* 1-byte font */
-       STORE_XCHAR2B (char2b, 0, ccl->reg[1]);
-      else
-       STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]);
-    }
-  else if (font_info->encoding_type)
-    {
-      /* Fixed encoding scheme.  See fontset.h for the meaning of the
-        encoding numbers.  */
-      unsigned char enc = font_info->encoding_type;
-
-      if ((enc == 1 || enc == 2)
-         && CHARSET_DIMENSION (charset) == 2)
-       char2b->byte1 |= 0x80;
-
-      if (enc == 1 || enc == 3)
-       char2b->byte2 |= 0x80;
-    }
-
-  if (two_byte_p)
-    *two_byte_p = ((XFontStruct *) (font_info->font))->max_byte1 > 0;
-
-  return FONT_TYPE_UNKNOWN;
-}
-
-
 \f
 /***********************************************************************
                            Glyph display
@@ -1056,7 +901,7 @@ static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
                                 int, int, int, XRectangle *));
 
 #if GLYPH_DEBUG
-static void x_check_font P_ ((struct frame *, XFontStruct *));
+static void x_check_font P_ ((struct frame *, struct font *));
 #endif
 
 
@@ -1098,14 +943,8 @@ x_set_cursor_gc (s)
        }
 
       IF_DEBUG (x_check_font (s->f, s->font));
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend)
-       xgcv.font = FRAME_X_DISPLAY_INFO (s->f)->font->fid;
-      else
-#endif
-      xgcv.font = s->font->fid;
       xgcv.graphics_exposures = False;
-      mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
+      mask = GCForeground | GCBackground | GCGraphicsExposures;
 
       if (FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc)
        XChangeGC (s->display, FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc,
@@ -1141,32 +980,19 @@ x_set_mouse_face_gc (s)
   s->face = FACE_FROM_ID (s->f, face_id);
   PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
 
-  /* If font in this face is same as S->font, use it.  */
   if (s->font == s->face->font)
     s->gc = s->face->gc;
-#ifdef USE_FONT_BACKEND
-  else if (enable_font_backend)
-    /* No need of setting a font for s->gc.  */
-    s->gc = s->face->gc;
-#endif /* USE_FONT_BACKEND */
   else
     {
       /* Otherwise construct scratch_cursor_gc with values from FACE
-        but font FONT.  */
+        except for FONT.  */
       XGCValues xgcv;
       unsigned long mask;
 
       xgcv.background = s->face->background;
       xgcv.foreground = s->face->foreground;
-      IF_DEBUG (x_check_font (s->f, s->font));
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend)
-       xgcv.font = FRAME_X_DISPLAY_INFO (s->f)->font->fid;
-      else
-#endif
-      xgcv.font = s->font->fid;
       xgcv.graphics_exposures = False;
-      mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
+      mask = GCForeground | GCBackground | GCGraphicsExposures;
 
       if (FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc)
        XChangeGC (s->display, FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc,
@@ -1176,8 +1002,8 @@ x_set_mouse_face_gc (s)
          = XCreateGC (s->display, s->window, mask, &xgcv);
 
       s->gc = FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc;
-    }
 
+    }
   xassert (s->gc != 0);
 }
 
@@ -1248,18 +1074,12 @@ static INLINE void
 x_set_glyph_string_clipping (s)
      struct glyph_string *s;
 {
-#ifdef USE_FONT_BACKEND
   XRectangle *r = s->clip;
-#else
-  XRectangle r[2];
-#endif
   int n = get_glyph_string_clip_rects (s, r, 2);
 
   if (n > 0)
     XSetClipRectangles (s->display, s->gc, 0, 0, r, n, Unsorted);
-#ifdef USE_FONT_BACKEND
   s->num_clips = n;
-#endif
 }
 
 
@@ -1273,29 +1093,12 @@ x_set_glyph_string_clipping_exactly (src, dst)
 {
   XRectangle r;
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    {
-      r.x = src->x;
-      r.width = src->width;
-      r.y = src->y;
-      r.height = src->height;
-      dst->clip[0] = r;
-      dst->num_clips = 1;
-    }
-  else
-    {
-#endif /* USE_FONT_BACKEND */
-  struct glyph_string *clip_head = src->clip_head;
-  struct glyph_string *clip_tail = src->clip_tail;
-
-  /* This foces clipping just this glyph string.  */
-  src->clip_head = src->clip_tail = src;
-  get_glyph_string_clip_rect (src, &r);
-  src->clip_head = clip_head, src->clip_tail = clip_tail;
-#ifdef USE_FONT_BACKEND
-    }
-#endif /* USE_FONT_BACKEND */
+  r.x = src->x;
+  r.width = src->width;
+  r.y = src->y;
+  r.height = src->height;
+  dst->clip[0] = r;
+  dst->num_clips = 1;
   XSetClipRectangles (dst->display, dst->gc, 0, 0, &r, 1, Unsorted);
 }
 
@@ -1310,30 +1113,17 @@ x_compute_glyph_string_overhangs (s)
   if (s->cmp == NULL
       && s->first_glyph->type == CHAR_GLYPH)
     {
-      XCharStruct cs;
-      int direction, font_ascent, font_descent;
-
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend)
-       {
-         unsigned *code = alloca (sizeof (unsigned) * s->nchars);
-         struct font *font = (struct font *) s->font_info;
-         struct font_metrics metrics;
-         int i;
+      unsigned *code = alloca (sizeof (unsigned) * s->nchars);
+      struct font *font = s->font;
+      struct font_metrics metrics;
+      int i;
 
-         for (i = 0; i < s->nchars; i++)
-           code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
-         font->driver->text_extents (font, code, s->nchars, &metrics);
-         cs.rbearing = metrics.rbearing;
-         cs.lbearing = metrics.lbearing;
-         cs.width = metrics.width;
-       }
-      else
-#endif /* USE_FONT_BACKEND */
-      XTextExtents16 (s->font, s->char2b, s->nchars, &direction,
-                     &font_ascent, &font_descent, &cs);
-      s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
-      s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
+      for (i = 0; i < s->nchars; i++)
+       code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
+      font->driver->text_extents (font, code, s->nchars, &metrics);
+      s->right_overhang = (metrics.rbearing > metrics.width
+                          ? metrics.rbearing - metrics.width : 0);
+      s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
     }
   else if (s->cmp)
     {
@@ -1429,15 +1219,14 @@ x_draw_glyph_string_foreground (s)
          x += g->pixel_width;
        }
     }
-#ifdef USE_FONT_BACKEND
-  else if (enable_font_backend)
+  else
     {
-      int boff = s->font_info->baseline_offset;
-      struct font *font = (struct font *) s->font_info;
+      struct font *font = s->font;
+      int boff = font->baseline_offset;
       int y;
 
-      if (s->font_info->vertical_centering)
-       boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
+      if (font->vertical_centering)
+       boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
 
       y = s->ybase - boff;
       if (s->for_overlaps
@@ -1448,58 +1237,6 @@ x_draw_glyph_string_foreground (s)
       if (s->face->overstrike)
        font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
     }
-#endif /* USE_FONT_BACKEND */
-  else
-    {
-      char *char1b = (char *) s->char2b;
-      int boff = s->font_info->baseline_offset;
-
-      if (s->font_info->vertical_centering)
-       boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
-
-      /* If we can use 8-bit functions, condense S->char2b.  */
-      if (!s->two_byte_p)
-       for (i = 0; i < s->nchars; ++i)
-         char1b[i] = s->char2b[i].byte2;
-
-      /* Draw text with XDrawString if background has already been
-        filled.  Otherwise, use XDrawImageString.  (Note that
-        XDrawImageString is usually faster than XDrawString.)  Always
-        use XDrawImageString when drawing the cursor so that there is
-        no chance that characters under a box cursor are invisible.  */
-      if (s->for_overlaps
-         || (s->background_filled_p && s->hl != DRAW_CURSOR))
-       {
-         /* Draw characters with 16-bit or 8-bit functions.  */
-         if (s->two_byte_p)
-           XDrawString16 (s->display, s->window, s->gc, x,
-                          s->ybase - boff, s->char2b, s->nchars);
-         else
-           XDrawString (s->display, s->window, s->gc, x,
-                        s->ybase - boff, char1b, s->nchars);
-       }
-      else
-       {
-         if (s->two_byte_p)
-           XDrawImageString16 (s->display, s->window, s->gc, x,
-                               s->ybase - boff, s->char2b, s->nchars);
-         else
-           XDrawImageString (s->display, s->window, s->gc, x,
-                             s->ybase - boff, char1b, s->nchars);
-       }
-
-      if (s->face->overstrike)
-       {
-         /* For overstriking (to simulate bold-face), draw the
-            characters again shifted to the right by one pixel.  */
-         if (s->two_byte_p)
-           XDrawString16 (s->display, s->window, s->gc, x + 1,
-                          s->ybase - boff, s->char2b, s->nchars);
-         else
-           XDrawString (s->display, s->window, s->gc, x + 1,
-                        s->ybase - boff, char1b, s->nchars);
-       }
-    }
 }
 
 /* Draw the foreground of composite glyph string S.  */
@@ -1531,10 +1268,9 @@ x_draw_composite_glyph_string_foreground (s)
        XDrawRectangle (s->display, s->window, s->gc, x, s->y,
                        s->width - 1, s->height - 1);
     }
-#ifdef USE_FONT_BACKEND
-  else if (enable_font_backend)
+  else
     {
-      struct font *font = (struct font *) s->font_info;
+      struct font *font = s->font;
       int y = s->ybase;
       int width = 0;
 
@@ -1587,23 +1323,6 @@ x_draw_composite_glyph_string_foreground (s)
              }
        }
     }
-#endif /* USE_FONT_BACKEND */
-  else
-    {
-      for (i = 0, j = s->gidx; i < s->nchars; i++, j++)
-       if (s->face)
-         {
-           XDrawString16 (s->display, s->window, s->gc,
-                          x + s->cmp->offsets[j * 2],
-                          s->ybase - s->cmp->offsets[j * 2 + 1],
-                          s->char2b + j, 1);
-           if (s->face->overstrike)
-             XDrawString16 (s->display, s->window, s->gc,
-                            x + s->cmp->offsets[j * 2] + 1,
-                            s->ybase - s->cmp->offsets[j * 2 + 1],
-                            s->char2b + j, 1);
-         }
-    }
 }
 
 
@@ -2865,9 +2584,7 @@ x_draw_glyph_string (s)
            x_set_glyph_string_gc (next);
            x_set_glyph_string_clipping (next);
            x_draw_glyph_string_background (next, 1);
-#ifdef USE_FONT_BACKEND
            next->num_clips = 0;
-#endif /* USE_FONT_BACKEND */
          }
     }
 
@@ -2932,33 +2649,25 @@ x_draw_glyph_string (s)
       /* Draw underline.  */
       if (s->face->underline_p)
        {
-         unsigned long tem, h;
+         unsigned long thickness, position;
          int y;
 
-         /* Get the underline thickness.  Default is 1 pixel.  */
-#ifdef USE_FONT_BACKEND
-         if (enable_font_backend)
-           /* In the future, we must use information of font.  */
-           h = 1;
-         else
-#endif /* USE_FONT_BACKEND */
-         if (!XGetFontProperty (s->font, XA_UNDERLINE_THICKNESS, &h))
-           h = 1;
-
-#ifdef USE_FONT_BACKEND
-         if (enable_font_backend)
+         if (s->prev && s->prev->face->underline_p)
            {
-             if (s->face->font)
-               /* In the future, we must use information of font.  */
-               y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
-             else
-               y = s->y + s->height - h;
+             /* We use the same underline style as the previous one.  */
+             thickness = s->prev->underline_thickness;
+             position = s->prev->underline_position;
            }
          else
-#endif
            {
-             y = s->y + s->height - h;
-             if (!x_underline_at_descent_line)
+             /* Get the underline thickness.  Default is 1 pixel.  */
+             if (s->font && s->font->underline_thickness > 0)
+               thickness = s->font->underline_thickness;
+             else
+               thickness = 1;
+             if (x_underline_at_descent_line)
+               position = (s->height - thickness) - s->ybase;
+             else
                {
                  /* Get the underline position.  This is the recommended
                     vertical offset in pixels from the baseline to the top of
@@ -2969,23 +2678,25 @@ x_draw_glyph_string (s)
                     ROUND(x) = floor (x + 0.5)  */
 
                  if (x_use_underline_position_properties
-                     && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem))
-                   y = s->ybase + (long) tem;
-                 else if (s->face->font)
-                   y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
+                     && s->font && s->font->underline_position >= 0)
+                   position = s->font->underline_position;
+                 else if (s->font)
+                   position = (s->font->descent + 1) / 2;
                }
+             s->underline_thickness = thickness;
+             s->underline_position = position;
            }
-
+         y = s->ybase + position;
          if (s->face->underline_defaulted_p)
            XFillRectangle (s->display, s->window, s->gc,
-                           s->x, y, s->background_width, h);
+                           s->x, y, s->background_width, thickness);
          else
            {
              XGCValues xgcv;
              XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
              XSetForeground (s->display, s->gc, s->face->underline_color);
              XFillRectangle (s->display, s->window, s->gc,
-                             s->x, y, s->background_width, h);
+                             s->x, y, s->background_width, thickness);
              XSetForeground (s->display, s->gc, xgcv.foreground);
            }
        }
@@ -3054,9 +2765,7 @@ x_draw_glyph_string (s)
                  x_draw_composite_glyph_string_foreground (prev);
                XSetClipMask (prev->display, prev->gc, None);
                prev->hl = save;
-#ifdef USE_FONT_BACKEND
                prev->num_clips = 0;
-#endif /* USE_FONT_BACKEND */
              }
        }
 
@@ -3081,18 +2790,14 @@ x_draw_glyph_string (s)
                  x_draw_composite_glyph_string_foreground (next);
                XSetClipMask (next->display, next->gc, None);
                next->hl = save;
-#ifdef USE_FONT_BACKEND
                next->num_clips = 0;
-#endif /* USE_FONT_BACKEND */
              }
        }
     }
 
   /* Reset clipping.  */
   XSetClipMask (s->display, s->gc, None);
-#ifdef USE_FONT_BACKEND
   s->num_clips = 0;
-#endif /* USE_FONT_BACKEND */
 }
 
 /* Shift display to make room for inserted glyphs.   */
@@ -8255,34 +7960,32 @@ x_io_error_quitter (display)
 \f
 /* Changing the font of the frame.  */
 
-/* Give frame F the font named FONTNAME as its default font, and
-   return the full name of that font.  FONTNAME may be a wildcard
-   pattern; in that case, we choose some font that fits the pattern.
-   The return value shows which font we chose.  */
+/* Give frame F the font FONT-OBJECT as its default font.  The return
+   value is FONT-OBJECT.  FONTSET is an ID of the fontset for the
+   frame.  If it is negative, generate a new fontset from
+   FONT-OBJECT.  */
 
 Lisp_Object
-x_new_font (f, fontname)
+x_new_font (f, font_object, fontset)
      struct frame *f;
-     register char *fontname;
+     Lisp_Object font_object;
+     int fontset;
 {
-  struct font_info *fontp
-    = FS_LOAD_FONT (f, fontname);
-
-  if (!fontp)
-    return Qnil;
+  struct font *font = XFONT_OBJECT (font_object);
 
-  if (FRAME_FONT (f) == (XFontStruct *) (fontp->font))
+  if (fontset < 0)
+    fontset = fontset_from_font (font_object);
+  FRAME_FONTSET (f) = fontset;
+  if (FRAME_FONT (f) == font)
     /* This font is already set in frame F.  There's nothing more to
        do.  */
-    return build_string (fontp->full_name);
+    return font_object;
 
-  FRAME_FONT (f) = (XFontStruct *) (fontp->font);
-  FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
-  FRAME_FONTSET (f) = -1;
-
-  FRAME_COLUMN_WIDTH (f) = fontp->average_width;
-  FRAME_SPACE_WIDTH (f) = fontp->space_width;
-  FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (FRAME_FONT (f));
+  FRAME_FONT (f) = font;
+  FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
+  FRAME_COLUMN_WIDTH (f) = font->average_width;
+  FRAME_SPACE_WIDTH (f) = font->space_width;
+  FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font);
 
   compute_fringe_widths (f, 1);
 
@@ -8299,21 +8002,8 @@ x_new_font (f, fontname)
       FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
     }
 
-  /* Now make the frame display the given font.  */
   if (FRAME_X_WINDOW (f) != 0)
     {
-      Font fid;
-
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend)
-       fid = FRAME_X_DISPLAY_INFO (f)->font->fid;
-      else
-#endif
-      fid = FRAME_FONT (f)->fid;
-      XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc, fid);
-      XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->reverse_gc, fid);
-      XSetFont (FRAME_X_DISPLAY (f), f->output_data.x->cursor_gc, fid);
-
       /* Don't change the size of a tip frame; there's no point in
         doing it because it's done in Fx_show_tip, and it leads to
         problems because the tip frame has no widget.  */
@@ -8321,121 +8011,18 @@ x_new_font (f, fontname)
        x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
     }
 
-  return build_string (fontp->full_name);
-}
-
-/* Give frame F the fontset named FONTSETNAME as its default fontset,
-   and return the full name of that fontset.  FONTSETNAME may be a
-   wildcard pattern; in that case, we choose some fontset that fits
-   the pattern.  FONTSETNAME may be a font name for ASCII characters;
-   in that case, we create a fontset from that font name.
-
-   The return value shows which fontset we chose.
-   If FONTSETNAME specifies the default fontset, return Qt.
-   If an ASCII font in the specified fontset can't be loaded, return
-   Qnil.  */
-
-Lisp_Object
-x_new_fontset (f, fontsetname)
-     struct frame *f;
-     Lisp_Object fontsetname;
-{
-  int fontset = fs_query_fontset (fontsetname, 0);
-  Lisp_Object result;
-
-  if (fontset > 0 && f->output_data.x->fontset == fontset)
-    /* This fontset is already set in frame F.  There's nothing more
-       to do.  */
-    return fontset_name (fontset);
-  else if (fontset == 0)
-    /* The default fontset can't be the default font.   */
-    return Qt;
-
-  if (fontset > 0)
-    result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
-  else
-    result = x_new_font (f, SDATA (fontsetname));
-
-  if (!STRINGP (result))
-    /* Can't load ASCII font.  */
-    return Qnil;
-
-  if (fontset < 0)
-    fontset = new_fontset_from_font_name (result);
-
-  /* Since x_new_font doesn't update any fontset information, do it now.  */
-  FRAME_FONTSET (f) = fontset;
-
 #ifdef HAVE_X_I18N
   if (FRAME_XIC (f)
       && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
-    xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
-#endif
-
-  return fontset_name (fontset);
-}
-
-#ifdef USE_FONT_BACKEND
-Lisp_Object
-x_new_fontset2 (f, fontset, font_object)
-     struct frame *f;
-     int fontset;
-     Lisp_Object font_object;
-{
-  struct font *font = XSAVE_VALUE (font_object)->pointer;
-
-  if (FRAME_FONT_OBJECT (f) == font)
-    /* This font is already set in frame F.  There's nothing more to
-       do.  */
-    return fontset_name (fontset);
-
-  BLOCK_INPUT;
-
-  FRAME_FONT_OBJECT (f) = font;
-  FRAME_FONT (f) = font->font.font;
-  FRAME_BASELINE_OFFSET (f) = font->font.baseline_offset;
-  FRAME_FONTSET (f) = fontset;
-
-  FRAME_COLUMN_WIDTH (f) = font->font.average_width;
-  FRAME_SPACE_WIDTH (f) = font->font.space_width;
-  FRAME_LINE_HEIGHT (f) = font->font.height;
-
-  compute_fringe_widths (f, 1);
-
-  /* Compute the scroll bar width in character columns.  */
-  if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
-    {
-      int wid = FRAME_COLUMN_WIDTH (f);
-      FRAME_CONFIG_SCROLL_BAR_COLS (f)
-       = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid - 1) / wid;
-    }
-  else
     {
-      int wid = FRAME_COLUMN_WIDTH (f);
-      FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
-    }
-
-  /* Now make the frame display the given font.  */
-  if (FRAME_X_WINDOW (f) != 0)
-    {
-      /* Don't change the size of a tip frame; there's no point in
-        doing it because it's done in Fx_show_tip, and it leads to
-        problems because the tip frame has no widget.  */
-      if (NILP (tip_frame) || XFRAME (tip_frame) != f)
-       x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+      BLOCK_INPUT;
+      xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
+      UNBLOCK_INPUT;
     }
-
-#ifdef HAVE_X_I18N
-  if (FRAME_XIC (f)
-      && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
-    xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
 #endif
 
-  UNBLOCK_INPUT;
-
-  return fontset_name (fontset);
+  return font_object;
 }
-#endif /* USE_FONT_BACKEND */
 
 \f
 /***********************************************************************
@@ -9768,14 +9355,11 @@ x_free_frame_resources (f)
      commands to the X server.  */
   if (dpyinfo->display)
     {
-#ifdef USE_FONT_BACKEND
       /* We must free faces before destroying windows because some
         font-driver (e.g. xft) access a window while finishing a
         face.  */
-      if (enable_font_backend
-         && FRAME_FACE_CACHE (f))
+      if (FRAME_FACE_CACHE (f))
        free_frame_faces (f);
-#endif /* USE_FONT_BACKEND */
 
       if (f->output_data.x->icon_desc)
        XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
@@ -10142,316 +9726,6 @@ x_wm_set_icon_position (f, icon_x, icon_y)
                                Fonts
  ***********************************************************************/
 
-/* Return a pointer to struct font_info of font FONT_IDX of frame F.  */
-
-struct font_info *
-x_get_font_info (f, font_idx)
-     FRAME_PTR f;
-     int font_idx;
-{
-  return (FRAME_X_FONT_TABLE (f) + font_idx);
-}
-
-
-/* Return a list of names of available fonts matching PATTERN on frame F.
-
-   If SIZE is > 0, it is the size (maximum bounds width) of fonts
-   to be listed.
-
-   SIZE < 0 means include auto scaled fonts.
-
-   Frame F null means we have not yet created any frame on X, and
-   consult the first display in x_display_list.  MAXNAMES sets a limit
-   on how many fonts to match.  */
-
-Lisp_Object
-x_list_fonts (f, pattern, size, maxnames)
-     struct frame *f;
-     Lisp_Object pattern;
-     int size;
-     int maxnames;
-{
-  Lisp_Object list = Qnil, patterns, newlist = Qnil, key = Qnil;
-  Lisp_Object tem, second_best;
-  struct x_display_info *dpyinfo
-    = f ? FRAME_X_DISPLAY_INFO (f) : x_display_list;
-  Display *dpy = dpyinfo->display;
-  int try_XLoadQueryFont = 0;
-  int allow_auto_scaled_font = 0;
-
-  if (size < 0)
-    {
-      allow_auto_scaled_font = 1;
-      size = 0;
-    }
-
-  patterns = Fassoc (pattern, Valternate_fontname_alist);
-  if (NILP (patterns))
-    patterns = Fcons (pattern, Qnil);
-
-  if (maxnames == 1 && !size)
-    /* We can return any single font matching PATTERN.  */
-    try_XLoadQueryFont = 1;
-
-  for (; CONSP (patterns); patterns = XCDR (patterns))
-    {
-      int num_fonts;
-      char **names = NULL;
-
-      pattern = XCAR (patterns);
-      /* See if we cached the result for this particular query.
-         The cache is an alist of the form:
-        ((((PATTERN . MAXNAMES) . SCALABLE) (FONTNAME . WIDTH) ...) ...)  */
-      tem = XCDR (dpyinfo->name_list_element);
-      key = Fcons (Fcons (pattern, make_number (maxnames)),
-                  allow_auto_scaled_font ? Qt : Qnil);
-      list = Fassoc (key, tem);
-      if (!NILP (list))
-       {
-         list = Fcdr_safe (list);
-         /* We have a cashed list.  Don't have to get the list again.  */
-         goto label_cached;
-       }
-
-      /* At first, put PATTERN in the cache.  */
-
-      BLOCK_INPUT;
-      x_catch_errors (dpy);
-
-      if (try_XLoadQueryFont)
-       {
-         XFontStruct *font;
-         unsigned long value;
-
-         font = XLoadQueryFont (dpy, SDATA (pattern));
-         if (x_had_errors_p (dpy))
-           {
-             /* This error is perhaps due to insufficient memory on X
-                 server.  Let's just ignore it.  */
-             font = NULL;
-             x_clear_errors (dpy);
-           }
-
-         if (font
-             && XGetFontProperty (font, XA_FONT, &value))
-           {
-             char *name = (char *) XGetAtomName (dpy, (Atom) value);
-             int len = strlen (name);
-             char *tmp;
-
-             /* If DXPC (a Differential X Protocol Compressor)
-                 Ver.3.7 is running, XGetAtomName will return null
-                 string.  We must avoid such a name.  */
-             if (len == 0)
-               try_XLoadQueryFont = 0;
-             else
-               {
-                 num_fonts = 1;
-                 names = (char **) alloca (sizeof (char *));
-                 /* Some systems only allow alloca assigned to a
-                     simple var.  */
-                 tmp = (char *) alloca (len + 1);  names[0] = tmp;
-                 bcopy (name, names[0], len + 1);
-                 XFree (name);
-               }
-           }
-         else
-           try_XLoadQueryFont = 0;
-
-         if (font)
-           XFreeFont (dpy, font);
-       }
-
-      if (!try_XLoadQueryFont)
-       {
-         /* We try at least 10 fonts because XListFonts will return
-            auto-scaled fonts at the head.  */
-          if (maxnames < 0)
-            {
-              int limit;
-
-              for (limit = 500;;)
-                {
-                  names = XListFonts (dpy, SDATA (pattern), limit, &num_fonts);
-                  if (num_fonts == limit)
-                    {
-                      BLOCK_INPUT;
-                      XFreeFontNames (names);
-                      UNBLOCK_INPUT;
-                      limit *= 2;
-                    }
-                  else
-                    break;
-                }
-            }
-          else
-            names = XListFonts (dpy, SDATA (pattern), max (maxnames, 10),
-                                &num_fonts);
-
-         if (x_had_errors_p (dpy))
-           {
-             /* This error is perhaps due to insufficient memory on X
-                 server.  Let's just ignore it.  */
-             names = NULL;
-             x_clear_errors (dpy);
-           }
-       }
-
-      x_uncatch_errors ();
-      UNBLOCK_INPUT;
-
-      if (names)
-       {
-         int i;
-
-         /* Make a list of all the fonts we got back.
-            Store that in the font cache for the display.  */
-         for (i = 0; i < num_fonts; i++)
-           {
-             int width = 0;
-             char *p = names[i];
-             int average_width = -1, resx = 0, dashes = 0;
-
-             /* Count the number of dashes in NAMES[I].  If there are
-                14 dashes, the field value following 9th dash
-                (RESOLUTION_X) is nonzero, and the field value
-                following 12th dash (AVERAGE_WIDTH) is 0, this is a
-                auto-scaled font which is usually too ugly to be used
-                for editing.  Let's ignore it.  */
-             while (*p)
-               if (*p++ == '-')
-                 {
-                   dashes++;
-                   if (dashes == 7) /* PIXEL_SIZE field */
-                     width = atoi (p);
-                   else if (dashes == 9)
-                     resx = atoi (p);
-                   else if (dashes == 12) /* AVERAGE_WIDTH field */
-                     average_width = atoi (p);
-                 }
-
-             if (allow_auto_scaled_font
-                 || dashes < 14 || average_width != 0 || resx == 0)
-               {
-                 tem = build_string (names[i]);
-                 if (NILP (Fassoc (tem, list)))
-                   {
-                     if (STRINGP (Vx_pixel_size_width_font_regexp)
-                         && ((fast_c_string_match_ignore_case
-                              (Vx_pixel_size_width_font_regexp, names[i]))
-                             >= 0))
-                       /* We can set the value of PIXEL_SIZE to the
-                         width of this font.  */
-                       list = Fcons (Fcons (tem, make_number (width)), list);
-                     else
-                       /* For the moment, width is not known.  */
-                       list = Fcons (Fcons (tem, Qnil), list);
-                   }
-               }
-           }
-
-         if (!try_XLoadQueryFont)
-           {
-             BLOCK_INPUT;
-             XFreeFontNames (names);
-             UNBLOCK_INPUT;
-           }
-       }
-
-      /* Now store the result in the cache.  */
-      XSETCDR (dpyinfo->name_list_element,
-              Fcons (Fcons (key, list), XCDR (dpyinfo->name_list_element)));
-
-    label_cached:
-      if (NILP (list)) continue; /* Try the remaining alternatives.  */
-
-      newlist = second_best = Qnil;
-      /* Make a list of the fonts that have the right width.  */
-      for (; CONSP (list); list = XCDR (list))
-       {
-         int found_size;
-
-         tem = XCAR (list);
-
-         if (!CONSP (tem) || NILP (XCAR (tem)))
-           continue;
-         if (!size)
-           {
-             newlist = Fcons (XCAR (tem), newlist);
-             continue;
-           }
-
-         if (!INTEGERP (XCDR (tem)))
-           {
-             /* Since we have not yet known the size of this font, we
-                must try slow function call XLoadQueryFont.  */
-             XFontStruct *thisinfo;
-
-             BLOCK_INPUT;
-             x_catch_errors (dpy);
-             thisinfo = XLoadQueryFont (dpy,
-                                        SDATA (XCAR (tem)));
-             if (x_had_errors_p (dpy))
-               {
-                 /* This error is perhaps due to insufficient memory on X
-                    server.  Let's just ignore it.  */
-                 thisinfo = NULL;
-                 x_clear_errors (dpy);
-               }
-             x_uncatch_errors ();
-             UNBLOCK_INPUT;
-
-             if (thisinfo)
-               {
-                 XSETCDR (tem,
-                          (thisinfo->min_bounds.width == 0
-                           ? make_number (0)
-                           : make_number (thisinfo->max_bounds.width)));
-                 BLOCK_INPUT;
-                 XFreeFont (dpy, thisinfo);
-                 UNBLOCK_INPUT;
-               }
-             else
-               /* For unknown reason, the previous call of XListFont had
-                 returned a font which can't be opened.  Record the size
-                 as 0 not to try to open it again.  */
-               XSETCDR (tem, make_number (0));
-           }
-
-         found_size = XINT (XCDR (tem));
-         if (found_size == size)
-           newlist = Fcons (XCAR (tem), newlist);
-         else if (found_size > 0)
-           {
-             if (NILP (second_best))
-               second_best = tem;
-             else if (found_size < size)
-               {
-                 if (XINT (XCDR (second_best)) > size
-                     || XINT (XCDR (second_best)) < found_size)
-                   second_best = tem;
-               }
-             else
-               {
-                 if (XINT (XCDR (second_best)) > size
-                     && XINT (XCDR (second_best)) > found_size)
-                   second_best = tem;
-               }
-           }
-       }
-      if (!NILP (newlist))
-       break;
-      else if (!NILP (second_best))
-       {
-         newlist = Fcons (XCAR (second_best), Qnil);
-         break;
-       }
-    }
-
-  return newlist;
-}
-
-
 #if GLYPH_DEBUG
 
 /* Check that FONT is valid on frame F.  It is if it can be found in F's
@@ -10460,551 +9734,17 @@ x_list_fonts (f, pattern, size, maxnames)
 static void
 x_check_font (f, font)
      struct frame *f;
-     XFontStruct *font;
+     struct font *font;
 {
-  int i;
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-
-  xassert (font != NULL);
+  Lisp_Object frame;
 
-#ifdef USE_FONT_BACKEND
-  if (enable_font_backend)
-    /* Fixme: Perhaps we should check all cached fonts.  */
-    return;
-#endif
-  for (i = 0; i < dpyinfo->n_fonts; i++)
-    if (dpyinfo->font_table[i].name
-       && font == dpyinfo->font_table[i].font)
-      break;
-
-  xassert (i < dpyinfo->n_fonts);
+  xassert (font != NULL && ! NILP (font->props[FONT_TYPE_INDEX]));
+  if (font->driver->check)
+    xassert (font->driver->check (f, font) == 0);
 }
 
 #endif /* GLYPH_DEBUG != 0 */
 
-/* Set *W to the minimum width, *H to the minimum font height of FONT.
-   Note: There are (broken) X fonts out there with invalid XFontStruct
-   min_bounds contents.  For example, handa@etl.go.jp reports that
-   "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
-   have font->min_bounds.width == 0.  */
-
-static INLINE void
-x_font_min_bounds (font, w, h)
-     XFontStruct *font;
-     int *w, *h;
-{
-  *h = FONT_HEIGHT (font);
-  *w = font->min_bounds.width;
-
-  /* Try to handle the case where FONT->min_bounds has invalid
-     contents.  Since the only font known to have invalid min_bounds
-     is fixed-width, use max_bounds if min_bounds seems to be invalid.  */
-  if (*w <= 0)
-    *w = font->max_bounds.width;
-}
-
-
-/* Compute the smallest character width and smallest font height over
-   all fonts available on frame F.  Set the members smallest_char_width
-   and smallest_font_height in F's x_display_info structure to
-   the values computed.  Value is non-zero if smallest_font_height or
-   smallest_char_width become smaller than they were before.  */
-
-static int
-x_compute_min_glyph_bounds (f)
-     struct frame *f;
-{
-  int i;
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-  XFontStruct *font;
-  int old_width = dpyinfo->smallest_char_width;
-  int old_height = dpyinfo->smallest_font_height;
-
-  dpyinfo->smallest_font_height = 100000;
-  dpyinfo->smallest_char_width = 100000;
-
-  for (i = 0; i < dpyinfo->n_fonts; ++i)
-    if (dpyinfo->font_table[i].name)
-      {
-       struct font_info *fontp = dpyinfo->font_table + i;
-       int w, h;
-
-       font = (XFontStruct *) fontp->font;
-       xassert (font != (XFontStruct *) ~0);
-       x_font_min_bounds (font, &w, &h);
-
-       dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h);
-       dpyinfo->smallest_char_width = min (dpyinfo->smallest_char_width, w);
-      }
-
-  xassert (dpyinfo->smallest_char_width > 0
-          && dpyinfo->smallest_font_height > 0);
-
-  return (dpyinfo->n_fonts == 1
-         || dpyinfo->smallest_char_width < old_width
-         || dpyinfo->smallest_font_height < old_height);
-}
-
-
-/* Load font named FONTNAME of the size SIZE for frame F, and return a
-   pointer to the structure font_info while allocating it dynamically.
-   If SIZE is 0, load any size of font.
-   If loading is failed, return NULL.  */
-
-struct font_info *
-x_load_font (f, fontname, size)
-     struct frame *f;
-     register char *fontname;
-     int size;
-{
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-  Lisp_Object font_names;
-
-  /* Get a list of all the fonts that match this name.  Once we
-     have a list of matching fonts, we compare them against the fonts
-     we already have by comparing names.  */
-  font_names = x_list_fonts (f, build_string (fontname), size, 1);
-
-  if (!NILP (font_names))
-    {
-      Lisp_Object tail;
-      int i;
-
-      for (i = 0; i < dpyinfo->n_fonts; i++)
-       for (tail = font_names; CONSP (tail); tail = XCDR (tail))
-         if (dpyinfo->font_table[i].name
-             && (!strcmp (dpyinfo->font_table[i].name,
-                          SDATA (XCAR (tail)))
-                 || !strcmp (dpyinfo->font_table[i].full_name,
-                             SDATA (XCAR (tail)))))
-           return (dpyinfo->font_table + i);
-    }
-
-  /* Load the font and add it to the table.  */
-  {
-    char *full_name;
-    XFontStruct *font;
-    struct font_info *fontp;
-    unsigned long value;
-    int i;
-
-    /* If we have found fonts by x_list_font, load one of them.  If
-       not, we still try to load a font by the name given as FONTNAME
-       because XListFonts (called in x_list_font) of some X server has
-       a bug of not finding a font even if the font surely exists and
-       is loadable by XLoadQueryFont.  */
-    if (size > 0 && !NILP (font_names))
-      fontname = (char *) SDATA (XCAR (font_names));
-
-    BLOCK_INPUT;
-    x_catch_errors (FRAME_X_DISPLAY (f));
-    font = (XFontStruct *) XLoadQueryFont (FRAME_X_DISPLAY (f), fontname);
-    if (x_had_errors_p (FRAME_X_DISPLAY (f)))
-      {
-       /* This error is perhaps due to insufficient memory on X
-          server.  Let's just ignore it.  */
-       font = NULL;
-       x_clear_errors (FRAME_X_DISPLAY (f));
-      }
-    x_uncatch_errors ();
-    UNBLOCK_INPUT;
-    if (!font)
-      return NULL;
-
-    /* Find a free slot in the font table.  */
-    for (i = 0; i < dpyinfo->n_fonts; ++i)
-      if (dpyinfo->font_table[i].name == NULL)
-       break;
-
-    /* If no free slot found, maybe enlarge the font table.  */
-    if (i == dpyinfo->n_fonts
-       && dpyinfo->n_fonts == dpyinfo->font_table_size)
-      {
-       int sz;
-       dpyinfo->font_table_size = max (16, 2 * dpyinfo->font_table_size);
-       sz = dpyinfo->font_table_size * sizeof *dpyinfo->font_table;
-       dpyinfo->font_table
-         = (struct font_info *) xrealloc (dpyinfo->font_table, sz);
-      }
-
-    fontp = dpyinfo->font_table + i;
-    if (i == dpyinfo->n_fonts)
-      ++dpyinfo->n_fonts;
-
-    /* Now fill in the slots of *FONTP.  */
-    BLOCK_INPUT;
-    bzero (fontp, sizeof (*fontp));
-    fontp->font = font;
-    fontp->font_idx = i;
-    fontp->charset = -1;       /* fs_load_font sets it.  */
-    fontp->name = (char *) xmalloc (strlen (fontname) + 1);
-    bcopy (fontname, fontp->name, strlen (fontname) + 1);
-
-    if (font->min_bounds.width == font->max_bounds.width)
-      {
-       /* Fixed width font.  */
-       fontp->average_width = fontp->space_width = font->min_bounds.width;
-      }
-    else
-      {
-       XChar2b char2b;
-       XCharStruct *pcm;
-
-       char2b.byte1 = 0x00, char2b.byte2 = 0x20;
-       pcm = x_per_char_metric (font, &char2b, 0);
-       if (pcm)
-         fontp->space_width = pcm->width;
-       else
-         fontp->space_width = FONT_WIDTH (font);
-
-       fontp->average_width
-         = (XGetFontProperty (font, dpyinfo->Xatom_AVERAGE_WIDTH, &value)
-            ? (long) value / 10 : 0);
-       if (fontp->average_width < 0)
-         fontp->average_width = - fontp->average_width;
-       if (fontp->average_width == 0)
-         {
-           if (pcm)
-             {
-               int width = pcm->width;
-               for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
-                 if ((pcm = x_per_char_metric (font, &char2b, 0)) != NULL)
-                   width += pcm->width;
-               fontp->average_width = width / 95;
-             }
-           else
-             fontp->average_width = FONT_WIDTH (font);
-         }
-      }
-
-    /* Try to get the full name of FONT.  Put it in FULL_NAME.  */
-    full_name = 0;
-    if (XGetFontProperty (font, XA_FONT, &value))
-      {
-       char *name = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);
-       char *p = name;
-       int dashes = 0;
-
-       /* Count the number of dashes in the "full name".
-          If it is too few, this isn't really the font's full name,
-          so don't use it.
-          In X11R4, the fonts did not come with their canonical names
-          stored in them.  */
-       while (*p)
-         {
-           if (*p == '-')
-             dashes++;
-           p++;
-         }
-
-       if (dashes >= 13)
-         {
-           full_name = (char *) xmalloc (p - name + 1);
-           bcopy (name, full_name, p - name + 1);
-         }
-
-       XFree (name);
-      }
-
-    if (full_name != 0)
-      fontp->full_name = full_name;
-    else
-      fontp->full_name = fontp->name;
-
-    fontp->size = font->max_bounds.width;
-    fontp->height = FONT_HEIGHT (font);
-
-    if (NILP (font_names))
-      {
-       /* We come here because of a bug of XListFonts mentioned at
-          the head of this block.  Let's store this information in
-          the cache for x_list_fonts.  */
-       Lisp_Object lispy_name = build_string (fontname);
-       Lisp_Object lispy_full_name = build_string (fontp->full_name);
-       Lisp_Object key = Fcons (Fcons (lispy_name, make_number (256)),
-                                Qnil);
-
-       XSETCDR (dpyinfo->name_list_element,
-                Fcons (Fcons (key,
-                              Fcons (Fcons (lispy_full_name,
-                                            make_number (fontp->size)),
-                                     Qnil)),
-                       XCDR (dpyinfo->name_list_element)));
-       if (full_name)
-         {
-           key = Fcons (Fcons (lispy_full_name, make_number (256)),
-                        Qnil);
-           XSETCDR (dpyinfo->name_list_element,
-                    Fcons (Fcons (key,
-                                  Fcons (Fcons (lispy_full_name,
-                                                make_number (fontp->size)),
-                                         Qnil)),
-                           XCDR (dpyinfo->name_list_element)));
-         }
-      }
-
-    /* The slot `encoding' specifies how to map a character
-       code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
-       the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
-       (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
-       2:0xA020..0xFF7F).  For the moment, we don't know which charset
-       uses this font.  So, we set information in fontp->encoding_type
-       which is never used by any charset.  If mapping can't be
-       decided, set FONT_ENCODING_NOT_DECIDED.  */
-    fontp->encoding_type
-      = (font->max_byte1 == 0
-        /* 1-byte font */
-        ? (font->min_char_or_byte2 < 0x80
-           ? (font->max_char_or_byte2 < 0x80
-              ? 0              /* 0x20..0x7F */
-              : FONT_ENCODING_NOT_DECIDED) /* 0x20..0xFF */
-           : 1)                /* 0xA0..0xFF */
-        /* 2-byte font */
-        : (font->min_byte1 < 0x80
-           ? (font->max_byte1 < 0x80
-              ? (font->min_char_or_byte2 < 0x80
-                 ? (font->max_char_or_byte2 < 0x80
-                    ? 0                /* 0x2020..0x7F7F */
-                    : FONT_ENCODING_NOT_DECIDED) /* 0x2020..0x7FFF */
-                 : 3)          /* 0x20A0..0x7FFF */
-              : FONT_ENCODING_NOT_DECIDED) /* 0x20??..0xA0?? */
-           : (font->min_char_or_byte2 < 0x80
-              ? (font->max_char_or_byte2 < 0x80
-                 ? 2           /* 0xA020..0xFF7F */
-                 : FONT_ENCODING_NOT_DECIDED) /* 0xA020..0xFFFF */
-              : 1)));          /* 0xA0A0..0xFFFF */
-
-    fontp->baseline_offset
-      = (XGetFontProperty (font, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value)
-        ? (long) value : 0);
-    fontp->relative_compose
-      = (XGetFontProperty (font, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value)
-        ? (long) value : 0);
-    fontp->default_ascent
-      = (XGetFontProperty (font, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value)
-        ? (long) value : 0);
-
-    /* Set global flag fonts_changed_p to non-zero if the font loaded
-       has a character with a smaller width than any other character
-       before, or if the font loaded has a smaller height than any
-       other font loaded before.  If this happens, it will make a
-       glyph matrix reallocation necessary.  */
-    fonts_changed_p |= x_compute_min_glyph_bounds (f);
-    UNBLOCK_INPUT;
-    return fontp;
-  }
-}
-
-
-/* Return a pointer to struct font_info of a font named FONTNAME for
-   frame F.  If no such font is loaded, return NULL.  */
-
-struct font_info *
-x_query_font (f, fontname)
-     struct frame *f;
-     register char *fontname;
-{
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
-  int i;
-
-  for (i = 0; i < dpyinfo->n_fonts; i++)
-    if (dpyinfo->font_table[i].name
-       && (!xstricmp (dpyinfo->font_table[i].name, fontname)
-           || !xstricmp (dpyinfo->font_table[i].full_name, fontname)))
-      return (dpyinfo->font_table + i);
-  return NULL;
-}
-
-
-/* Find a CCL program for a font specified by FONTP, and set the member
- `encoder' of the structure.  */
-
-void
-x_find_ccl_program (fontp)
-     struct font_info *fontp;
-{
-  Lisp_Object list, elt;
-
-  elt = Qnil;
-  for (list = Vfont_ccl_encoder_alist; CONSP (list); list = XCDR (list))
-    {
-      elt = XCAR (list);
-      if (CONSP (elt)
-         && STRINGP (XCAR (elt))
-         && ((fast_c_string_match_ignore_case (XCAR (elt), fontp->name)
-              >= 0)
-             || (fast_c_string_match_ignore_case (XCAR (elt), fontp->full_name)
-                 >= 0)))
-       break;
-    }
-
-  if (! NILP (list))
-    {
-      struct ccl_program *ccl
-       = (struct ccl_program *) xmalloc (sizeof (struct ccl_program));
-
-      if (setup_ccl_program (ccl, XCDR (elt)) < 0)
-       xfree (ccl);
-      else
-       fontp->font_encoder = ccl;
-    }
-}
-
-
-/* Return a char-table whose elements are t if the font FONT_INFO
-   contains a glyph for the corresponding character, and nil if
-   not.  */
-
-Lisp_Object
-x_get_font_repertory (f, font_info)
-     FRAME_PTR f;
-     struct font_info *font_info;
-{
-  XFontStruct *font = (XFontStruct *) font_info->font;
-  Lisp_Object table;
-  int min_byte1, max_byte1, min_byte2, max_byte2;
-  int c;
-  struct charset *charset = CHARSET_FROM_ID (font_info->charset);
-  int offset = CHARSET_OFFSET (charset);
-
-  table = Fmake_char_table (Qnil, Qnil);
-
-  min_byte1 = font->min_byte1;
-  max_byte1 = font->max_byte1;
-  min_byte2 = font->min_char_or_byte2;
-  max_byte2 = font->max_char_or_byte2;
-  if (min_byte1 == 0 && max_byte1 == 0)
-    {
-      if (! font->per_char || font->all_chars_exist == True)
-       {
-         if (offset >= 0)
-           char_table_set_range (table, offset + min_byte2,
-                                 offset + max_byte2, Qt);
-         else
-           for (; min_byte2 <= max_byte2; min_byte2++)
-             {
-               c = DECODE_CHAR (charset, min_byte2);
-               CHAR_TABLE_SET (table, c, Qt);
-             }
-       }
-      else
-       {
-         XCharStruct *pcm = font->per_char;
-         int from = -1;
-         int i;
-
-         for (i = min_byte2; i <= max_byte2; i++, pcm++)
-           {
-             if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
-               {
-                 if (from >= 0)
-                   {
-                     if (offset >= 0)
-                       char_table_set_range (table, offset + from,
-                                             offset + i - 1, Qt);
-                     else
-                       for (; from < i; from++)
-                         {
-                           c = DECODE_CHAR (charset, from);
-                           CHAR_TABLE_SET (table, c, Qt);
-                         }
-                     from = -1;
-                   }
-               }
-             else if (from < 0)
-               from = i;
-           }
-         if (from >= 0)
-           {
-             if (offset >= 0)
-               char_table_set_range (table, offset + from, offset + i - 1,
-                                     Qt);
-             else
-               for (; from < i; from++)
-                 {
-                   c = DECODE_CHAR (charset, from);
-                   CHAR_TABLE_SET (table, c, Qt);
-                 }
-           }
-       }
-    }
-  else
-    {
-      if (! font->per_char || font->all_chars_exist == True)
-       {
-         int i, j;
-
-         if (offset >= 0)
-           for (i = min_byte1; i <= max_byte1; i++)
-             char_table_set_range
-               (table, offset + ((i << 8) | min_byte2),
-                offset + ((i << 8) | max_byte2), Qt);
-         else
-           for (i = min_byte1; i <= max_byte1; i++)        
-             for (j = min_byte2; j <= max_byte2; j++)
-               {
-                 unsigned code = (i << 8) | j;
-                 c = DECODE_CHAR (charset, code);
-                 CHAR_TABLE_SET (table, c, Qt);
-               }
-       }
-      else
-       {
-         XCharStruct *pcm = font->per_char;
-         int i;
-
-         for (i = min_byte1; i <= max_byte1; i++)
-           {
-             int from = -1;
-             int j;
-
-             for (j = min_byte2; j <= max_byte2; j++, pcm++)
-               {
-                 if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
-                   {
-                     if (from >= 0)
-                       {
-                         if (offset >= 0)
-                           char_table_set_range
-                             (table, offset + ((i << 8) | from),
-                              offset + ((i << 8) | (j - 1)), Qt);
-                         else
-                           {
-                             for (; from < j; from++)
-                               {
-                                 unsigned code = (i << 8) | from;
-                                 c = ENCODE_CHAR (charset, code);
-                                 CHAR_TABLE_SET (table, c, Qt);
-                               }
-                           }
-                         from = -1;
-                       }
-                   }
-                 else if (from < 0)
-                   from = j;
-               }
-             if (from >= 0)
-               {
-                 if (offset >= 0)
-                   char_table_set_range
-                     (table, offset + ((i << 8) | from),
-                      offset + ((i << 8) | (j - 1)), Qt);
-                 else
-                   {
-                     for (; from < j; from++)
-                       {
-                         unsigned code = (i << 8) | from;
-                         c = DECODE_CHAR (charset, code);
-                         CHAR_TABLE_SET (table, c, Qt);
-                       }
-                   }
-               }
-           }
-       }
-    }
-
-  return table;
-}
 \f
 /***********************************************************************
                            Initialization
@@ -11386,16 +10126,7 @@ x_term_init (display_name, xrm_option, resource_name)
   dpyinfo->grabbed = 0;
   dpyinfo->reference_count = 0;
   dpyinfo->icon_bitmap_id = -1;
-  dpyinfo->font_table = NULL;
   dpyinfo->n_fonts = 0;
-  dpyinfo->font_table_size = 0;
-#ifdef USE_FONT_BACKEND
-  dpyinfo->font = XLoadQueryFont (dpyinfo->display, "fixed");
-  if (! dpyinfo->font)
-    dpyinfo->font = XLoadQueryFont (dpyinfo->display, "*");
-  if (! dpyinfo->font)
-    abort ();
-#endif /* USE_FONT_BACKEND */
   dpyinfo->bitmaps = 0;
   dpyinfo->bitmaps_size = 0;
   dpyinfo->bitmaps_last = 0;
@@ -11718,29 +10449,6 @@ x_delete_display (dpyinfo)
     xim_close_dpy (dpyinfo);
 #endif
 
-#ifdef USE_FONT_BACKEND
-  if (! enable_font_backend)
-    {
-#endif
-  /* Free the font names in the font table.  */
-  for (i = 0; i < dpyinfo->n_fonts; i++)
-    if (dpyinfo->font_table[i].name)
-      {
-       if (dpyinfo->font_table[i].name != dpyinfo->font_table[i].full_name)
-         xfree (dpyinfo->font_table[i].full_name);
-       xfree (dpyinfo->font_table[i].name);
-      }
-
-  if (dpyinfo->font_table)
-    {
-      if (dpyinfo->font_table->font_encoder)
-       xfree (dpyinfo->font_table->font_encoder);
-      xfree (dpyinfo->font_table);
-    }
-#ifdef USE_FONT_BACKEND
-    }
-#endif
-
   if (dpyinfo->x_id_name)
     xfree (dpyinfo->x_id_name);
   if (dpyinfo->color_cells)
@@ -11825,8 +10533,6 @@ static struct redisplay_interface x_redisplay_interface =
     x_draw_fringe_bitmap,
     0, /* define_fringe_bitmap */
     0, /* destroy_fringe_bitmap */
-    x_per_char_metric,
-    x_encode_char,
     x_compute_glyph_string_overhangs,
     x_draw_glyph_string,
     x_define_frame_cursor,
@@ -11854,18 +10560,6 @@ x_delete_terminal (struct terminal *terminal)
      and dpyinfo->display was set to 0 to indicate that.  */
   if (dpyinfo->display)
     {
-#ifdef USE_FONT_BACKEND
-      if (enable_font_backend)
-       XFreeFont (dpyinfo->display, dpyinfo->font);
-      else
-#endif
-       /* Free the fonts in the font table.  */
-       for (i = 0; i < dpyinfo->n_fonts; i++)
-         if (dpyinfo->font_table[i].name)
-           {
-             XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font);
-           }
-
       x_destroy_all_bitmaps (dpyinfo);
       XSetCloseDownMode (dpyinfo->display, DestroyAll);
 
index 6bb68cf915308fb3ba3142404a67c48ea36467f9..9249056fea6121d01fa8b7e8ed0889d213c1b02d 100644 (file)
@@ -69,7 +69,7 @@ typedef GtkWidget *xt_or_gtk_widget;
 #define WHITE_PIX_DEFAULT(f) WhitePixel (FRAME_X_DISPLAY (f), \
                                         XScreenNumberOfScreen (FRAME_X_SCREEN (f)))
 
-#define FONT_WIDTH(f)  ((f)->max_bounds.width)
+#define FONT_WIDTH(f)  ((f)->max_width)
 #define FONT_HEIGHT(f) ((f)->ascent + (f)->descent)
 #define FONT_BASE(f)    ((f)->ascent)
 #define FONT_DESCENT(f) ((f)->descent)
@@ -170,17 +170,6 @@ struct x_display_info
   /* X Resource data base */
   XrmDatabase xrdb;
 
-  /* A table of all the fonts we have already loaded.  */
-  struct font_info *font_table;
-
-  /* The current capacity of x_font_table.  */
-  int font_table_size;
-
-#ifdef USE_FONT_BACKEND
-  /* This provides a commonly used Font ID on this display.  */
-  XFontStruct *font;
-#endif
-
   /* Minimum width over all characters in all fonts in font_table.  */
   int smallest_char_width;
 
@@ -223,9 +212,7 @@ struct x_display_info
 
   char *x_id_name;
 
-  /* The number of fonts actually stored in x_font_table.
-     font_table[n] is used and valid if 0 <= n < n_fonts.  0 <=
-     n_fonts <= font_table_size and font_table[i].name != 0.  */
+  /* The number of fonts opened for this display.  */
   int n_fonts;
 
   /* Pointer to bitmap records.  */
@@ -404,16 +391,11 @@ extern struct x_display_info *x_display_info_for_name P_ ((Lisp_Object));
 extern struct x_display_info *x_term_init P_ ((Lisp_Object, char *, char *));
 extern int x_display_ok  P_ ((const char *));
 
-extern Lisp_Object x_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
 extern void select_visual P_ ((struct x_display_info *));
-extern struct font_info *x_get_font_info P_ ((struct frame *f, int));
-extern struct font_info *x_load_font P_ ((struct frame *, char *, int));
-extern struct font_info *x_query_font P_ ((struct frame *, char *));
-extern void x_find_ccl_program P_ ((struct font_info *));
-extern Lisp_Object x_get_font_repertory P_ ((struct frame *,
-                                            struct font_info *));
 
 \f
+struct font;
+
 /* Each X frame object points to its own struct x_output object
    in the output_data.x field.  The x_output structure contains
    the information that is specific to X windows.  */
@@ -492,11 +474,7 @@ struct x_output
   int icon_bitmap;
 
   /* Default ASCII font of this frame.  */
-  XFontStruct *font;
-
-#ifdef USE_FONT_BACKEND
-  struct font *fontp;
-#endif /* USE_FONT_BACKEND */
+  struct font *font;
 
   /* The baseline offset of the default ASCII font.  */
   int baseline_offset;
@@ -685,10 +663,6 @@ enum
 #define FRAME_TOOLBAR_HEIGHT(f) ((f)->output_data.x->toolbar_height)
 #define FRAME_BASELINE_OFFSET(f) ((f)->output_data.x->baseline_offset)
 
-#ifdef USE_FONT_BACKEND
-#define FRAME_FONT_OBJECT(f) ((f)->output_data.x->fontp)
-#endif /* USE_FONT_BACKEND */
-
 /* This gives the x_display_info structure for the display F is on.  */
 #define FRAME_X_DISPLAY_INFO(f) ((f)->output_data.x->display_info)