Avoid the use of snprintf.
[bpt/emacs.git] / src / font.c
index 1ac994d..a5b873a 100644 (file)
@@ -1,8 +1,9 @@
 /* font.c -- "Font" primitives.
-   Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
-   Copyright (C) 2006, 2007, 2008, 2009, 2010
-     National Institute of Advanced Industrial Science and Technology (AIST)
-     Registration Number H13PRO009
+
+Copyright (C) 2006-2011  Free Software Foundation, Inc.
+Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
+  National Institute of Advanced Industrial Science and Technology (AIST)
+  Registration Number H13PRO009
 
 This file is part of GNU Emacs.
 
@@ -20,8 +21,8 @@ You should have received a copy of the GNU General Public License
 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
+#include <float.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <ctype.h>
 #include <setjmp.h>
 
@@ -62,8 +63,6 @@ static Lisp_Object QCf;
    font_driver *)->list when a specified font is not found. */
 static Lisp_Object null_vector;
 
-static Lisp_Object Vfont_weight_table, Vfont_slant_table, Vfont_width_table;
-
 /* Vector of Vfont_weight_table, Vfont_slant_table, and Vfont_width_table. */
 static Lisp_Object font_style_table;
 
@@ -123,21 +122,22 @@ static const struct table_entry width_table[] =
   { 200, { "ultra-expanded", "ultraexpanded", "wide" }}
 };
 
-Lisp_Object QCfoundry, QCadstyle, QCregistry;
+Lisp_Object QCfoundry;
+static Lisp_Object QCadstyle, QCregistry;
 /* Symbols representing keys of font extra info.  */
 Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript, QCavgwidth;
-Lisp_Object QCantialias, QCfont_entity, QCfc_unknown_spec;
+Lisp_Object QCantialias, QCfont_entity;
+static Lisp_Object QCfc_unknown_spec;
 /* Symbols representing values of font spacing property.  */
-Lisp_Object Qc, Qm, Qp, Qd;
+static Lisp_Object Qc, Qm, Qd;
+Lisp_Object Qp;
 /* Special ADSTYLE properties to avoid fonts used for Latin
    characters; used in xfont.c and ftfont.c.  */
 Lisp_Object Qja, Qko;
 
-Lisp_Object QCuser_spec;
-
-Lisp_Object Vfont_encoding_alist;
+static Lisp_Object QCuser_spec;
 
-/* Alist of font registry symbol and the corresponding charsets
+/* Alist of font registry symbols and the corresponding charset
    information.  The information is retrieved from
    Vfont_encoding_alist on demand.
 
@@ -164,7 +164,7 @@ static struct font_driver_list *font_driver_list;
 
 /* Creaters of font-related Lisp object.  */
 
-Lisp_Object
+static Lisp_Object
 font_make_spec (void)
 {
   Lisp_Object font_spec;
@@ -220,40 +220,54 @@ static int font_pixel_size (FRAME_PTR f, Lisp_Object);
 static Lisp_Object font_open_entity (FRAME_PTR, Lisp_Object, int);
 static Lisp_Object font_matching_entity (FRAME_PTR, Lisp_Object *,
                                          Lisp_Object);
+static unsigned font_encode_char (Lisp_Object, int);
 
 /* 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 FORCE_SYMBOL is zero and all characters in STR are digits, it
-   returns an integer.  Otherwise, it returns a symbol interned from
+   If STR is "*", return nil.
+   If FORCE_SYMBOL is zero and all characters in STR are digits,
+   return an integer.  Otherwise, return a symbol interned from
    STR.  */
 
 Lisp_Object
-font_intern_prop (const char *str, int len, int force_symbol)
+font_intern_prop (const char *str, ptrdiff_t len, int force_symbol)
 {
-  int i;
+  ptrdiff_t i;
   Lisp_Object tem;
   Lisp_Object obarray;
-  int nbytes, nchars;
+  EMACS_INT nbytes, nchars;
 
   if (len == 1 && *str == '*')
     return Qnil;
-  if (!force_symbol && len >=1 && isdigit (*str))
+  if (!force_symbol && 0 < len && '0' <= *str && *str <= '9')
     {
       for (i = 1; i < len; i++)
-       if (! isdigit (str[i]))
+       if (! ('0' <= str[i] && str[i] <= '9'))
          break;
       if (i == len)
-       return make_number (atoi (str));
+       {
+         EMACS_INT n;
+
+         i = 0;
+         for (n = 0; (n += str[i++] - '0') <= MOST_POSITIVE_FIXNUM; n *= 10)
+           {
+             if (i == len)
+               return make_number (n);
+             if (MOST_POSITIVE_FIXNUM / 10 < n)
+               break;
+           }
+
+         xsignal1 (Qoverflow_error, make_string (str, len));
+       }
     }
 
   /* The following code is copied from the function intern (in
-     lread.c), and modified to suite our purpose.  */
+     lread.c), and modified to suit our purpose.  */
   obarray = Vobarray;
-  if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
+  if (!VECTORP (obarray) || ASIZE (obarray) == 0)
     obarray = check_obarray (obarray);
   parse_str_as_multibyte ((unsigned char *) str, len, &nchars, &nbytes);
   if (len == nchars || len != nbytes)
@@ -305,7 +319,7 @@ font_pixel_size (FRAME_PTR f, Lisp_Object spec)
    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
+   font_style_table if VAL is a symbol, and return the closest index if
    VAL is an integer.  */
 
 int
@@ -313,11 +327,11 @@ font_style_to_value (enum font_property_index prop, Lisp_Object val, int noerror
 {
   Lisp_Object table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX);
   int len = ASIZE (table);
-  int i, j;
 
   if (SYMBOLP (val))
     {
-      unsigned char *s;
+      int i, j;
+      char *s;
       Lisp_Object args[2], elt;
 
       /* At first try exact match.  */
@@ -327,12 +341,12 @@ font_style_to_value (enum font_property_index prop, Lisp_Object val, int noerror
            return ((XINT (AREF (AREF (table, i), 0)) << 8)
                    | (i << 4) | (j - 1));
       /* Try also with case-folding match.  */
-      s = SDATA (SYMBOL_NAME (val));
+      s = SSDATA (SYMBOL_NAME (val));
       for (i = 0; i < len; i++)
        for (j = 1; j < ASIZE (AREF (table, i)); j++)
          {
            elt = AREF (AREF (table, i), j);
-           if (xstrcasecmp (s, SDATA (SYMBOL_NAME (elt))) == 0)
+           if (xstrcasecmp (s, SSDATA (SYMBOL_NAME (elt))) == 0)
              return ((XINT (AREF (AREF (table, i), 0)) << 8)
                      | (i << 4) | (j - 1));
          }
@@ -473,7 +487,7 @@ font_registry_charsets (Lisp_Object registry, struct charset **encoding, struct
 }
 
 \f
-/* Font property value validaters.  See the comment of
+/* Font property value validators.  See the comment of
    font_property_table for the meaning of the arguments.  */
 
 static Lisp_Object font_prop_validate (int, Lisp_Object, Lisp_Object);
@@ -502,10 +516,9 @@ font_prop_validate_style (Lisp_Object style, Lisp_Object 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))
     {
-      n = XINT (val);
+      int n = XINT (val);
       if (((n >> 4) & 0xF)
          >= ASIZE (AREF (font_style_table, prop - FONT_WEIGHT_INDEX)))
        val = Qerror;
@@ -592,7 +605,7 @@ font_prop_validate_otf (Lisp_Object prop, Lisp_Object val)
   return val;
 }
 
-/* Structure of known font property keys and validater of the
+/* Structure of known font property keys and validator of the
    values.  */
 static const struct
 {
@@ -701,7 +714,7 @@ font_put_extra (Lisp_Object font, Lisp_Object prop, Lisp_Object val)
 
 static int parse_matrix (const char *);
 static int font_expand_wildcards (Lisp_Object *, int);
-static int font_parse_name (const char *, Lisp_Object);
+static int font_parse_name (char *, Lisp_Object);
 
 /* An enumerator for each field of an XLFD font name.  */
 enum xlfd_field_index
@@ -743,7 +756,7 @@ enum xlfd_field_mask
 };
 
 
-/* Parse P pointing the pixel/point size field of the form
+/* Parse P pointing to the pixel/point size field of the form
    `[A B C D]' which specifies a transformation matrix:
 
        A  B  0
@@ -776,7 +789,7 @@ parse_matrix (const char *p)
 }
 
 /* Expand a wildcard field in FIELD (the first N fields are filled) to
-   multiple fields to fill in all 14 XLFD fields while restring a
+   multiple fields to fill in all 14 XLFD fields while restricting a
    field position by its contents.  */
 
 static int
@@ -981,9 +994,9 @@ font_expand_wildcards (Lisp_Object *field, int n)
    a fully specified XLFD.  */
 
 int
-font_parse_xlfd (const char *name, Lisp_Object font)
+font_parse_xlfd (char *name, Lisp_Object font)
 {
-  int len = strlen (name);
+  ptrdiff_t len = strlen (name);
   int i, j, n;
   char *f[XLFD_LAST_INDEX + 1];
   Lisp_Object val;
@@ -1165,9 +1178,10 @@ font_parse_xlfd (const char *name, Lisp_Object font)
 int
 font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
 {
-  char *f[XLFD_REGISTRY_INDEX + 1];
+  char *p;
+  const char *f[XLFD_REGISTRY_INDEX + 1];
   Lisp_Object val;
-  int i, j, len = 0;
+  int i, j, len;
 
   font_assert (FONTP (font));
 
@@ -1182,33 +1196,27 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
       if (NILP (val))
        {
          if (j == XLFD_REGISTRY_INDEX)
-           f[j] = "*-*", len += 4;
+           f[j] = "*-*";
          else
-           f[j] = "*", len += 2;
+           f[j] = "*";
        }
       else
        {
          if (SYMBOLP (val))
            val = SYMBOL_NAME (val);
          if (j == XLFD_REGISTRY_INDEX
-             && ! strchr ((char *) SDATA (val), '-'))
+             && ! strchr (SSDATA (val), '-'))
            {
              /* Change "jisx0208*" and "jisx0208" to "jisx0208*-*".  */
-             if (SDATA (val)[SBYTES (val) - 1] == '*')
-               {
-                 f[j] = alloca (SBYTES (val) + 3);
-                 sprintf (f[j], "%s-*", SDATA (val));
-                 len += SBYTES (val) + 3;
-               }
-             else
-               {
-                 f[j] = alloca (SBYTES (val) + 4);
-                 sprintf (f[j], "%s*-*", SDATA (val));
-                 len += SBYTES (val) + 4;
-               }
+             ptrdiff_t alloc = SBYTES (val) + 4;
+             if (nbytes <= alloc)
+               return -1;
+             f[j] = p = alloca (alloc);
+             sprintf (p, "%s%s-*", SDATA (val),
+                      "*" + (SDATA (val)[SBYTES (val) - 1] == '*'));
            }
          else
-           f[j] = (char *) SDATA (val), len += SBYTES (val) + 1;
+           f[j] = SSDATA (val);
        }
     }
 
@@ -1217,11 +1225,11 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
     {
       val = font_style_symbolic (font, i, 0);
       if (NILP (val))
-       f[j] = "*", len += 2;
+       f[j] = "*";
       else
        {
          val = SYMBOL_NAME (val);
-         f[j] = (char *) SDATA (val), len += SBYTES (val) + 1;
+         f[j] = SSDATA (val);
        }
     }
 
@@ -1229,65 +1237,62 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
   font_assert (NUMBERP (val) || NILP (val));
   if (INTEGERP (val))
     {
-      i = XINT (val);
-      if (i <= 0)
-       i = pixel_size;
-      if (i > 0)
+      EMACS_INT v = XINT (val);
+      if (v <= 0)
+       v = pixel_size;
+      if (v > 0)
        {
-         f[XLFD_PIXEL_INDEX] = alloca (22);
-         len += sprintf (f[XLFD_PIXEL_INDEX], "%d-*", i) + 1;
+         f[XLFD_PIXEL_INDEX] = p =
+           alloca (sizeof "-*" + INT_STRLEN_BOUND (EMACS_INT));
+         sprintf (p, "%"pI"d-*", v);
        }
       else
-       f[XLFD_PIXEL_INDEX] = "*-*", len += 4;
+       f[XLFD_PIXEL_INDEX] = "*-*";
     }
   else if (FLOATP (val))
     {
-      i = XFLOAT_DATA (val) * 10;
-      f[XLFD_PIXEL_INDEX] = alloca (12);
-      len += sprintf (f[XLFD_PIXEL_INDEX], "*-%d", i) + 1;
+      double v = XFLOAT_DATA (val) * 10;
+      f[XLFD_PIXEL_INDEX] = p = alloca (sizeof "*-" + 1 + DBL_MAX_10_EXP + 1);
+      sprintf (p, "*-%.0f", v);
     }
   else
-    f[XLFD_PIXEL_INDEX] = "*-*", len += 4;
+    f[XLFD_PIXEL_INDEX] = "*-*";
 
   if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
     {
-      i = XINT (AREF (font, FONT_DPI_INDEX));
-      f[XLFD_RESX_INDEX] = alloca (22);
-      len += sprintf (f[XLFD_RESX_INDEX],
-                     "%d-%d", i, i) + 1;
+      EMACS_INT v = XINT (AREF (font, FONT_DPI_INDEX));
+      f[XLFD_RESX_INDEX] = p =
+       alloca (sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT));
+      sprintf (p, "%"pI"d-%"pI"d", v, v);
     }
   else
-    f[XLFD_RESX_INDEX] = "*-*", len += 4;
+    f[XLFD_RESX_INDEX] = "*-*";
   if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
     {
-      int spacing = XINT (AREF (font, FONT_SPACING_INDEX));
+      EMACS_INT spacing = XINT (AREF (font, FONT_SPACING_INDEX));
 
       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;
+    f[XLFD_SPACING_INDEX] = "*";
   if (INTEGERP (AREF (font,  FONT_AVGWIDTH_INDEX)))
     {
-      f[XLFD_AVGWIDTH_INDEX] = alloca (11);
-      len += sprintf (f[XLFD_AVGWIDTH_INDEX], "%ld",
-                      (long) XINT (AREF (font, FONT_AVGWIDTH_INDEX))) + 1;
+      f[XLFD_AVGWIDTH_INDEX] = p = alloca (INT_BUFSIZE_BOUND (EMACS_INT));
+      sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX)));
     }
   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-%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_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX],
-                 f[XLFD_REGISTRY_INDEX]);
+    f[XLFD_AVGWIDTH_INDEX] = "*";
+  len = esnprintf (name, nbytes, "-%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_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX],
+                  f[XLFD_REGISTRY_INDEX]);
+  return len == nbytes - 1 ? -1 : len;
 }
 
 /* Parse NAME (null terminated) and store information in FONT
@@ -1305,13 +1310,13 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
 
    This function tries to guess which format it is.  */
 
-int
-font_parse_fcname (const char *name, Lisp_Object font)
+static int
+font_parse_fcname (char *name, Lisp_Object font)
 {
   char *p, *q;
   char *size_beg = NULL, *size_end = NULL;
   char *props_beg = NULL, *family_end = NULL;
-  int len = strlen (name);
+  ptrdiff_t len = strlen (name);
 
   if (len == 0)
     return -1;
@@ -1377,30 +1382,31 @@ font_parse_fcname (const char *name, Lisp_Object font)
              if (*q != '=')
                {
                  /* Must be an enumerated value.  */
-                 int word_len;
+                 ptrdiff_t word_len;
                  p = p + 1;
                  word_len = q - p;
                  val = font_intern_prop (p, q - p, 1);
 
-#define PROP_MATCH(STR,N) ((word_len == N) && memcmp (p, STR, N) == 0)
+#define PROP_MATCH(STR) (word_len == strlen (STR)              \
+                        && memcmp (p, STR, strlen (STR)) == 0)
 
-                 if (PROP_MATCH ("light", 5)
-                     || PROP_MATCH ("medium", 6)
-                     || PROP_MATCH ("demibold", 8)
-                     || PROP_MATCH ("bold", 4)
-                     || PROP_MATCH ("black", 5))
+                 if (PROP_MATCH ("light")
+                     || PROP_MATCH ("medium")
+                     || PROP_MATCH ("demibold")
+                     || PROP_MATCH ("bold")
+                     || PROP_MATCH ("black"))
                    FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, val);
-                 else if (PROP_MATCH ("roman", 5)
-                          || PROP_MATCH ("italic", 6)
-                          || PROP_MATCH ("oblique", 7))
+                 else if (PROP_MATCH ("roman")
+                          || PROP_MATCH ("italic")
+                          || PROP_MATCH ("oblique"))
                    FONT_SET_STYLE (font, FONT_SLANT_INDEX, val);
-                 else if (PROP_MATCH ("charcell", 8))
+                 else if (PROP_MATCH ("charcell"))
                    ASET (font, FONT_SPACING_INDEX,
                          make_number (FONT_SPACING_CHARCELL));
-                 else if (PROP_MATCH ("mono", 4))
+                 else if (PROP_MATCH ("mono"))
                    ASET (font, FONT_SPACING_INDEX,
                          make_number (FONT_SPACING_MONO));
-                 else if (PROP_MATCH ("proportional", 12))
+                 else if (PROP_MATCH ("proportional"))
                    ASET (font, FONT_SPACING_INDEX,
                          make_number (FONT_SPACING_PROPORTIONAL));
 #undef PROP_MATCH
@@ -1449,110 +1455,84 @@ font_parse_fcname (const char *name, Lisp_Object font)
     {
       /* Either a fontconfig-style name with no size and property
         data, or a GTK-style name.  */
-      Lisp_Object prop;
-      int word_len, prop_found = 0;
+      Lisp_Object weight = Qnil, slant = Qnil;
+      Lisp_Object width  = Qnil, size  = Qnil;
+      char *word_start;
+      ptrdiff_t word_len;
+
+      /* Scan backwards from the end, looking for a size.  */
+      for (p = name + len - 1; p >= name; p--)
+       if (!isdigit (*p))
+         break;
+
+      if ((p < name + len - 1) && ((p + 1 == name) || *p == ' '))
+       /* Found a font size.  */
+       size = make_float (strtod (p + 1, NULL));
+      else
+       p = name + len;
 
-      for (p = name; *p; p = *q ? q + 1 : q)
+      /* Now P points to the termination of the string, sans size.
+        Scan backwards, looking for font properties.  */
+      for (; p > name; p = q)
        {
-         if (isdigit (*p))
+         for (q = p - 1; q >= name; q--)
            {
-             int size_found = 1;
-
-             for (q = p + 1; *q && *q != ' '; q++)
-               if (! isdigit (*q) && *q != '.')
-                 {
-                   size_found = 0;
-                   break;
-                 }
-             if (size_found)
-               {
-                 double point_size = strtod (p, &q);
-                 ASET (font, FONT_SIZE_INDEX, make_float (point_size));
-                 continue;
-               }
+             if (q > name && *(q-1) == '\\')
+               --q;   /* Skip quoting backslashes.  */
+             else if (*q == ' ')
+               break;
            }
 
-         for (q = p + 1; *q && *q != ' '; q++)
-           if (*q == '\\' && q[1])
-             q++;
-         word_len = q - p;
-
-#define PROP_MATCH(STR,N) ((word_len == N) && memcmp (p, STR, N) == 0)
-
-         if (PROP_MATCH ("Ultra-Light", 11))
-           {
-             prop_found = 1;
-             prop = font_intern_prop ("ultra-light", 11, 1);
-             FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
-           }
-         else if (PROP_MATCH ("Light", 5))
-           {
-             prop_found = 1;
-             prop = font_intern_prop ("light", 5, 1);
-             FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
-           }
-         else if (PROP_MATCH ("Book", 4))
-           {
-             prop_found = 1;
-             prop = font_intern_prop ("book", 4, 1);
-             FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
-           }
-         else if (PROP_MATCH ("Medium", 6))
-           {
-             prop_found = 1;
-             prop = font_intern_prop ("medium", 6, 1);
-             FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
-           }
-         else if (PROP_MATCH ("Semi-Bold", 9))
-           {
-             prop_found = 1;
-             prop = font_intern_prop ("semi-bold", 9, 1);
-             FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
-           }
-         else if (PROP_MATCH ("Bold", 4))
-           {
-             prop_found = 1;
-             prop = font_intern_prop ("bold", 4, 1);
-             FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
-           }
-         else if (PROP_MATCH ("Italic", 6))
-           {
-             prop_found = 1;
-             prop = font_intern_prop ("italic", 4, 1);
-             FONT_SET_STYLE (font, FONT_SLANT_INDEX, prop);
-           }
-         else if (PROP_MATCH ("Oblique", 7))
-           {
-             prop_found = 1;
-             prop = font_intern_prop ("oblique", 7, 1);
-             FONT_SET_STYLE (font, FONT_SLANT_INDEX, prop);
-           }
-         else if (PROP_MATCH ("Semi-Condensed", 14))
-           {
-             prop_found = 1;
-             prop = font_intern_prop ("semi-condensed", 14, 1);
-             FONT_SET_STYLE (font, FONT_WIDTH_INDEX, prop);
-           }
-         else if (PROP_MATCH ("Condensed", 9))
+         word_start = q + 1;
+         word_len = p - word_start;
+
+#define PROP_MATCH(STR)                                                \
+         (word_len == strlen (STR)                             \
+          && memcmp (word_start, STR, strlen (STR)) == 0)
+#define PROP_SAVE(VAR, STR)                                    \
+         (VAR = NILP (VAR) ? font_intern_prop (STR, strlen (STR), 1) : VAR)
+
+         if (PROP_MATCH ("Ultra-Light"))
+           PROP_SAVE (weight, "ultra-light");
+         else if (PROP_MATCH ("Light"))
+           PROP_SAVE (weight, "light");
+         else if (PROP_MATCH ("Book"))
+           PROP_SAVE (weight, "book");
+         else if (PROP_MATCH ("Medium"))
+           PROP_SAVE (weight, "medium");
+         else if (PROP_MATCH ("Semi-Bold"))
+           PROP_SAVE (weight, "semi-bold");
+         else if (PROP_MATCH ("Bold"))
+           PROP_SAVE (weight, "bold");
+         else if (PROP_MATCH ("Italic"))
+           PROP_SAVE (slant, "italic");
+         else if (PROP_MATCH ("Oblique"))
+           PROP_SAVE (slant, "oblique");
+         else if (PROP_MATCH ("Semi-Condensed"))
+           PROP_SAVE (width, "semi-condensed");
+         else if (PROP_MATCH ("Condensed"))
+           PROP_SAVE (width, "condensed");
+         /* An unknown word must be part of the font name.  */
+         else
            {
-             prop_found = 1;
-             prop = font_intern_prop ("condensed", 9, 1);
-             FONT_SET_STYLE (font, FONT_WIDTH_INDEX, prop);
+             family_end = p;
+             break;
            }
-         else {
-           if (prop_found)
-             return -1; /* Unknown property in GTK-style font name.  */
-           family_end = q;
-         }
        }
 #undef PROP_MATCH
+#undef PROP_SAVE
 
       if (family_end)
-       {
-         Lisp_Object family;
-         family = font_intern_prop (name, family_end - name, 1);
-         ASET (font, FONT_FAMILY_INDEX, family);
-       }
+       ASET (font, FONT_FAMILY_INDEX,
+             font_intern_prop (name, family_end - name, 1));
+      if (!NILP (size))
+       ASET (font, FONT_SIZE_INDEX, size);
+      if (!NILP (weight))
+       FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, weight);
+      if (!NILP (slant))
+       FONT_SET_STYLE (font, FONT_SLANT_INDEX, slant);
+      if (!NILP (width))
+       FONT_SET_STYLE (font, FONT_WIDTH_INDEX, width);
     }
 
   return 0;
@@ -1563,25 +1543,22 @@ font_parse_fcname (const char *name, Lisp_Object font)
    FONT_SIZE_INDEX of FONT is 0, use PIXEL_SIZE instead.  */
 
 int
-font_unparse_fcname (Lisp_Object font, int pixel_size, const char *name, int nbytes)
+font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
 {
   Lisp_Object family, foundry;
-  Lisp_Object tail, val;
+  Lisp_Object val;
   int point_size;
-  int i, len = 1;
+  int i;
   char *p;
+  char *lim;
   Lisp_Object styles[3];
   const char *style_names[3] = { "weight", "slant", "width" };
-  char work[256];
 
   family = AREF (font, FONT_FAMILY_INDEX);
   if (! NILP (family))
     {
       if (SYMBOLP (family))
-       {
-         family = SYMBOL_NAME (family);
-         len += SBYTES (family);
-       }
+       family = SYMBOL_NAME (family);
       else
        family = Qnil;
     }
@@ -1592,172 +1569,55 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, const char *name, int nby
       if (XINT (val) != 0)
        pixel_size = XINT (val);
       point_size = -1;
-      len += 21;               /* for ":pixelsize=NUM" */
     }
-  else if (FLOATP (val))
+  else
     {
+      if (! FLOATP (val))
+       abort ();
       pixel_size = -1;
       point_size = (int) XFLOAT_DATA (val);
-      len += 11;               /* for "-NUM" */
     }
 
   foundry = AREF (font, FONT_FOUNDRY_INDEX);
   if (! NILP (foundry))
     {
       if (SYMBOLP (foundry))
-       {
-         foundry = SYMBOL_NAME (foundry);
-         len += 9 + SBYTES (foundry); /* ":foundry=NAME" */
-       }
+       foundry = SYMBOL_NAME (foundry);
       else
        foundry = Qnil;
     }
 
   for (i = 0; i < 3; i++)
-    {
-      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])));
-    }
-
-  if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
-    len += sprintf (work, ":dpi=%ld", (long)XINT (AREF (font, FONT_DPI_INDEX)));
-  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 key = XCAR (XCAR (tail)), val = XCDR (XCAR (tail));
+    styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
 
-      len += SBYTES (SYMBOL_NAME (key)) + 1; /* for :KEY= */
-      if (STRINGP (val))
-       len += SBYTES (val);
-      else if (INTEGERP (val))
-       len += sprintf (work, "%ld", (long) XINT (val));
-      else if (SYMBOLP (val))
-       len += (NILP (val) ? 5 : 4); /* for "false" or "true" */
-    }
-
-  if (len > nbytes)
-    return -1;
   p = name;
+  lim = name + nbytes;
   if (! NILP (family))
-    p += sprintf (p, "%s", SDATA (family));
+    p += esnprintf (p, lim - p, "%s", SSDATA (family));
   if (point_size > 0)
-    {
-      if (p == name)
-       p += sprintf (p, "%d", point_size);
-      else
-       p += sprintf (p, "-%d", point_size);
-    }
+    p += esnprintf (p, lim - p, "-%d" + (p == name), point_size);
   else if (pixel_size > 0)
-    p += sprintf (p, ":pixelsize=%d", pixel_size);
+    p += esnprintf (p, lim - p, ":pixelsize=%d", pixel_size);
   if (! NILP (AREF (font, FONT_FOUNDRY_INDEX)))
-    p += sprintf (p, ":foundry=%s",
-                 SDATA (SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX))));
+    p += esnprintf (p, lim - p, ":foundry=%s",
+                   SSDATA (SYMBOL_NAME (AREF (font,
+                                              FONT_FOUNDRY_INDEX))));
   for (i = 0; i < 3; i++)
     if (! NILP (styles[i]))
-      p += sprintf (p, ":%s=%s", style_names[i],
-                   SDATA (SYMBOL_NAME (styles[i])));
+      p += esnprintf (p, lim - p, ":%s=%s", style_names[i],
+                     SSDATA (SYMBOL_NAME (styles[i])));
   if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
-    p += sprintf (p, ":dpi=%ld", (long) XINT (AREF (font, FONT_DPI_INDEX)));
+    p += esnprintf (p, lim - p, ":dpi=%"pI"d",
+                   XINT (AREF (font, FONT_DPI_INDEX)));
   if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
-    p += sprintf (p, ":spacing=%ld",
-                  (long) XINT (AREF (font, FONT_SPACING_INDEX)));
+    p += esnprintf (p, lim - p, ":spacing=%"pI"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);
-}
-
-/* Store GTK-style font name of FONT (font-spec or font-entity) in
-   NAME (NBYTES length), and return the name length.  F is the frame
-   on which the font is displayed; it is used to calculate the point
-   size.  */
-
-int
-font_unparse_gtkname (Lisp_Object font, struct frame *f, char *name, int nbytes)
-{
-  char *p;
-  int len = 1;
-  Lisp_Object family, weight, slant, size;
-  int point_size = -1;
-
-  family = AREF (font, FONT_FAMILY_INDEX);
-  if (! NILP (family))
-    {
-      if (! SYMBOLP (family))
-       return -1;
-      family = SYMBOL_NAME (family);
-      len += SBYTES (family);
-    }
-
-  weight = font_style_symbolic (font, FONT_WEIGHT_INDEX, 0);
-  if (EQ (weight, Qnormal))
-    weight = Qnil;
-  else if (! NILP (weight))
-    {
-      weight = SYMBOL_NAME (weight);
-      len += SBYTES (weight);
-    }
-
-  slant = font_style_symbolic (font, FONT_SLANT_INDEX, 0);
-  if (EQ (slant, Qnormal))
-    slant = Qnil;
-  else if (! NILP (slant))
-    {
-      slant = SYMBOL_NAME (slant);
-      len += SBYTES (slant);
-    }
-
-  size = AREF (font, FONT_SIZE_INDEX);
-  /* Convert pixel size to point size.  */
-  if (INTEGERP (size))
-    {
-      Lisp_Object font_dpi = AREF (font, FONT_DPI_INDEX);
-      int dpi = 75;
-      if (INTEGERP (font_dpi))
-       dpi = XINT (font_dpi);
-      else if (f)
-       dpi = f->resy;
-      point_size = PIXEL_TO_POINT (XINT (size), dpi);
-      len += 11;
-    }
-  else if (FLOATP (size))
-    {
-      point_size = (int) XFLOAT_DATA (size);
-      len += 11;
-    }
-
-  if (len > nbytes)
-    return -1;
-
-  p = name + sprintf (name, "%s", SDATA (family));
-
-  if (! NILP (weight))
-    {
-      char *q = p;
-      p += sprintf (p, " %s", SDATA (weight));
-      q[1] = toupper (q[1]);
-    }
-
-  if (! NILP (slant))
-    {
-      char *q = p;
-      p += sprintf (p, " %s", SDATA (slant));
-      q[1] = toupper (q[1]);
-    }
-
-  if (point_size > 0)
-    p += sprintf (p, " %d", point_size);
-
-  return (p - name);
+    p += esnprintf (p, lim - p,
+                   (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0
+                    ? ":scalable=true"
+                    : ":scalable=false"));
+  return lim - p == 1 ? -1 : p - name;
 }
 
 /* Parse NAME (null terminated) and store information in FONT
@@ -1765,7 +1625,7 @@ font_unparse_gtkname (Lisp_Object font, struct frame *f, char *name, int nbytes)
    0.  Otherwise return -1.  */
 
 static int
-font_parse_name (const char *name, Lisp_Object font)
+font_parse_name (char *name, Lisp_Object font)
 {
   if (name[0] == '-' || strchr (name, '*') || strchr (name, '?'))
     return font_parse_xlfd (name, font);
@@ -1788,7 +1648,7 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec
     {
       CHECK_STRING (family);
       len = SBYTES (family);
-      p0 = (char *) SDATA (family);
+      p0 = SSDATA (family);
       p1 = strchr (p0, '-');
       if (p1)
        {
@@ -1807,7 +1667,7 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec
       /* Convert "XXX" and "XXX*" to "XXX*-*".  */
       CHECK_STRING (registry);
       len = SBYTES (registry);
-      p0 = (char *) SDATA (registry);
+      p0 = SSDATA (registry);
       p1 = strchr (p0, '-');
       if (! p1)
        {
@@ -1833,8 +1693,7 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec
 #define LGSTRING_GLYPH_SIZE 8
 
 static int
-check_gstring (gstring)
-     Lisp_Object gstring;
+check_gstring (Lisp_Object gstring)
 {
   Lisp_Object val;
   int i, j;
@@ -1888,8 +1747,7 @@ check_gstring (gstring)
 }
 
 static void
-check_otf_features (otf_features)
-     Lisp_Object otf_features;
+check_otf_features (Lisp_Object otf_features)
 {
   Lisp_Object val;
 
@@ -1903,14 +1761,16 @@ check_otf_features (otf_features)
     {
       CHECK_SYMBOL (Fcar (val));
       if (SBYTES (SYMBOL_NAME (XCAR (val))) > 4)
-       error ("Invalid OTF GSUB feature: %s", SYMBOL_NAME (XCAR (val)));
+       error ("Invalid OTF GSUB feature: %s",
+              SDATA (SYMBOL_NAME (XCAR (val))));
     }
   otf_features = XCDR (otf_features);
   for (val = Fcar (otf_features); ! NILP (val);  val = Fcdr (val))
     {
       CHECK_SYMBOL (Fcar (val));
       if (SBYTES (SYMBOL_NAME (XCAR (val))) > 4)
-       error ("Invalid OTF GPOS feature: %s", SYMBOL_NAME (XCAR (val)));
+       error ("Invalid OTF GPOS feature: %s",
+              SDATA (SYMBOL_NAME (XCAR (val))));
     }
 }
 
@@ -1920,8 +1780,7 @@ check_otf_features (otf_features)
 Lisp_Object otf_list;
 
 static Lisp_Object
-otf_tag_symbol (tag)
-     OTF_Tag tag;
+otf_tag_symbol (OTF_Tag tag)
 {
   char name[5];
 
@@ -1930,8 +1789,7 @@ otf_tag_symbol (tag)
 }
 
 static OTF *
-otf_open (file)
-     Lisp_Object file;
+otf_open (Lisp_Object file)
 {
   Lisp_Object val = Fassoc (file, otf_list);
   OTF *otf;
@@ -1940,7 +1798,7 @@ otf_open (file)
     otf = XSAVE_VALUE (XCDR (val))->pointer;
   else
     {
-      otf = STRINGP (file) ? OTF_open ((char *) SDATA (file)) : NULL;
+      otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL;
       val = make_save_value (otf, 0);
       otf_list = Fcons (Fcons (file, val), otf_list);
     }
@@ -1953,8 +1811,7 @@ otf_open (file)
    (struct font_driver).otf_capability.  */
 
 Lisp_Object
-font_otf_capability (font)
-     struct font *font;
+font_otf_capability (struct font *font)
 {
   OTF *otf;
   Lisp_Object capability = Fcons (Qnil, Qnil);
@@ -2028,9 +1885,7 @@ font_otf_capability (font)
    FEATURES.  */
 
 static void
-generate_otf_features (spec, features)
-     Lisp_Object spec;
-     char *features;
+generate_otf_features (Lisp_Object spec, char *features)
 {
   Lisp_Object val;
   char *p;
@@ -2052,12 +1907,12 @@ generate_otf_features (spec, features)
       else if (! asterisk)
        {
          val = SYMBOL_NAME (val);
-         p += sprintf (p, "%s", SDATA (val));
+         p += esprintf (p, "%s", SDATA (val));
        }
       else
        {
          val = SYMBOL_NAME (val);
-         p += sprintf (p, "~%s", SDATA (val));
+         p += esprintf (p, "~%s", SDATA (val));
        }
     }
   if (CONSP (spec))
@@ -2065,8 +1920,7 @@ generate_otf_features (spec, features)
 }
 
 Lisp_Object
-font_otf_DeviceTable (device_table)
-     OTF_DeviceTable *device_table;
+font_otf_DeviceTable (OTF_DeviceTable *device_table)
 {
   int len = device_table->StartSize - device_table->EndSize + 1;
 
@@ -2075,9 +1929,7 @@ font_otf_DeviceTable (device_table)
 }
 
 Lisp_Object
-font_otf_ValueRecord (value_format, value_record)
-     int value_format;
-     OTF_ValueRecord *value_record;
+font_otf_ValueRecord (int value_format, OTF_ValueRecord *value_record)
 {
   Lisp_Object val = Fmake_vector (make_number (8), Qnil);
 
@@ -2101,8 +1953,7 @@ font_otf_ValueRecord (value_format, value_record)
 }
 
 Lisp_Object
-font_otf_Anchor (anchor)
-     OTF_Anchor *anchor;
+font_otf_Anchor (OTF_Anchor *anchor)
 {
   Lisp_Object val;
 
@@ -2161,14 +2012,14 @@ font_rescale_ratio (Lisp_Object font_entity)
    font-spec.  The score value is 32 bit (`unsigned'), and the smaller
    the value is, the closer the font is to the font-spec.
 
-   The lowest 2 bits of the score is used for driver type.  The font
+   The lowest 2 bits of the score are used for driver type.  The font
    available by the most preferred font driver is 0.
 
-   Each 7-bit in the higher 28 bits are used for numeric properties
+   The 4 7-bit fields in the higher 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.  Note that flots for FONT_TYPE_INDEX and
+   property in a score.  Note that floats for FONT_TYPE_INDEX and
    FONT_REGISTRY_INDEX are not used.  */
 static int sort_shift_bits[FONT_SIZE_INDEX + 1];
 
@@ -2186,12 +2037,11 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
   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);
-
+       EMACS_INT diff = ((XINT (AREF (entity, i)) >> 8)
+                         - (XINT (spec_prop[i]) >> 8));
        if (diff < 0)
          diff = - diff;
-       if (diff > 0)
-         score |= min (diff, 127) << sort_shift_bits[i];
+       score |= min (diff, 127) << sort_shift_bits[i];
       }
 
   /* Score the size.  Maximum difference is 127.  */
@@ -2201,8 +2051,8 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
     {
       /* We use the higher 6-bit for the actual size difference.  The
         lowest bit is set if the DPI is different.  */
-      int diff;
-      int pixel_size = XINT (spec_prop[FONT_SIZE_INDEX]);
+      EMACS_INT diff;
+      EMACS_INT pixel_size = XINT (spec_prop[FONT_SIZE_INDEX]);
 
       if (CONSP (Vface_font_rescale_alist))
        pixel_size *= font_rescale_ratio (entity);
@@ -2287,7 +2137,7 @@ font_sort_entities (Lisp_Object list, Lisp_Object prefer, Lisp_Object frame, int
   unsigned best_score;
   Lisp_Object best_entity;
   struct frame *f = XFRAME (frame);
-  Lisp_Object tail, vec;
+  Lisp_Object tail, vec IF_LINT (= Qnil);
   USE_SAFE_ALLOCA;
 
   for (i = FONT_WEIGHT_INDEX; i <= FONT_AVGWIDTH_INDEX; i++)
@@ -2706,12 +2556,12 @@ font_clear_cache (FRAME_PTR f, Lisp_Object cache, struct font_driver *driver)
 static Lisp_Object scratch_font_spec, scratch_font_prefer;
 
 /* Check each font-entity in VEC, and return a list of font-entities
-   that satisfy this condition:
+   that satisfy these conditions:
      (1) matches with SPEC and SIZE if SPEC is not nil, and
      (2) doesn't match with any regexps in Vface_ignored_fonts (if non-nil).
 */
 
-Lisp_Object
+static Lisp_Object
 font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size)
 {
   Lisp_Object entity, val;
@@ -2808,14 +2658,12 @@ font_list_entities (Lisp_Object frame, Lisp_Object spec)
   for (i = FONT_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX; i++)
     ASET (scratch_font_spec, i, AREF (spec, i));
   for (i = FONT_WEIGHT_INDEX; i < FONT_EXTRA_INDEX; i++)
-    {
-      ASET (scratch_font_spec, i, Qnil);
-      if (! NILP (AREF (spec, i)))
-       need_filtering = 1;
-      if (i == FONT_DPI_INDEX)
-       /* Skip FONT_SPACING_INDEX  */
-       i++;
-    }
+    if (i != FONT_SPACING_INDEX)
+      {
+       ASET (scratch_font_spec, i, Qnil);
+       if (! NILP (AREF (spec, i)))
+         need_filtering = 1;
+      }
   ASET (scratch_font_spec, FONT_SPACING_INDEX, AREF (spec, FONT_SPACING_INDEX));
   ASET (scratch_font_spec, FONT_EXTRA_INDEX, AREF (spec, FONT_EXTRA_INDEX));
 
@@ -2838,7 +2686,7 @@ font_list_entities (Lisp_Object frame, Lisp_Object spec)
              val = null_vector;
            else
              val = Fvconcat (1, &val);
-           copy = Fcopy_font_spec (scratch_font_spec);
+           copy = copy_font_spec (scratch_font_spec);
            ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type);
            XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache)));
          }
@@ -2866,7 +2714,7 @@ font_matching_entity (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec)
   struct font_driver_list *driver_list = f->font_driver_list;
   Lisp_Object ftype, size, entity;
   Lisp_Object frame;
-  Lisp_Object work = Fcopy_font_spec (spec);
+  Lisp_Object work = copy_font_spec (spec);
 
   XSETFRAME (frame, f);
   ftype = AREF (spec, FONT_TYPE_INDEX);
@@ -2893,7 +2741,7 @@ font_matching_entity (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec)
        else
          {
            entity = driver_list->driver->match (frame, work);
-           copy = Fcopy_font_spec (work);
+           copy = copy_font_spec (work);
            ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type);
            XSETCDR (cache, Fcons (Fcons (copy, entity), XCDR (cache)));
          }
@@ -2915,7 +2763,7 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size)
   Lisp_Object objlist, size, val, font_object;
   struct font *font;
   int min_width, height;
-  int scaled_pixel_size;
+  int scaled_pixel_size = pixel_size;
 
   font_assert (FONT_ENTITY_P (entity));
   size = AREF (entity, FONT_SIZE_INDEX);
@@ -2983,7 +2831,7 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size)
 
 /* Close FONT_OBJECT that is opened on frame F.  */
 
-void
+static void
 font_close_object (FRAME_PTR f, Lisp_Object font_object)
 {
   struct font *font = XFONT_OBJECT (font_object);
@@ -3039,7 +2887,7 @@ font_has_char (FRAME_PTR f, Lisp_Object font, int c)
 
 /* Return the glyph ID of FONT_OBJECT for character C.  */
 
-unsigned
+static unsigned
 font_encode_char (Lisp_Object font_object, int c)
 {
   struct font *font;
@@ -3060,22 +2908,6 @@ font_get_name (Lisp_Object font_object)
 }
 
 
-/* Return the specification of FONT_OBJECT.  */
-
-Lisp_Object
-font_get_spec (Lisp_Object font_object)
-{
-  Lisp_Object spec = font_make_spec ();
-  int i;
-
-  for (i = 0; i < FONT_SIZE_INDEX; i++)
-    ASET (spec, i, AREF (font_object, i));
-  ASET (spec, FONT_SIZE_INDEX,
-       make_number (XFONT_OBJECT (font_object)->pixel_size));
-  return spec;
-}
-
-
 /* Create a new font spec from FONT_NAME, and return it.  If FONT_NAME
    could not be parsed by font_parse_name, return Qnil.  */
 
@@ -3085,7 +2917,7 @@ font_spec_from_name (Lisp_Object font_name)
   Lisp_Object spec = Ffont_spec (0, NULL);
 
   CHECK_STRING (font_name);
-  if (font_parse_name ((char *) SDATA (font_name), spec) == -1)
+  if (font_parse_name (SSDATA (font_name), spec) == -1)
     return Qnil;
   font_put_extra (spec, QCname, font_name);
   font_put_extra (spec, QCuser_spec, font_name);
@@ -3103,7 +2935,7 @@ font_clear_prop (Lisp_Object *attrs, enum font_property_index prop)
 
   if (! NILP (Ffont_get (font, QCname)))
     {
-      font = Fcopy_font_spec (font);
+      font = copy_font_spec (font);
       font_put_extra (font, QCname, Qnil);
     }
 
@@ -3114,7 +2946,7 @@ font_clear_prop (Lisp_Object *attrs, enum font_property_index prop)
       && prop != FONT_SIZE_INDEX)
     return;
   if (EQ (font, attrs[LFACE_FONT_INDEX]))
-    font = Fcopy_font_spec (font);
+    font = copy_font_spec (font);
   ASET (font, prop, Qnil);
   if (prop == FONT_FAMILY_INDEX || prop == FONT_FOUNDRY_INDEX)
     {
@@ -3144,52 +2976,8 @@ font_clear_prop (Lisp_Object *attrs, enum font_property_index prop)
   attrs[LFACE_FONT_INDEX] = font;
 }
 
-void
-font_update_lface (FRAME_PTR f, Lisp_Object *attrs)
-{
-  Lisp_Object spec;
-
-  spec = attrs[LFACE_FONT_INDEX];
-  if (! FONT_SPEC_P (spec))
-    return;
-
-  if (! NILP (AREF (spec, FONT_FOUNDRY_INDEX)))
-    attrs[LFACE_FOUNDRY_INDEX] = SYMBOL_NAME (AREF (spec, FONT_FOUNDRY_INDEX));
-  if (! NILP (AREF (spec, FONT_FAMILY_INDEX)))
-    attrs[LFACE_FAMILY_INDEX] = SYMBOL_NAME (AREF (spec, FONT_FAMILY_INDEX));
-  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);
-         attrs[LFACE_HEIGHT_INDEX] = make_number (point);
-       }
-      else if (FLOATP (AREF (spec, FONT_SIZE_INDEX)))
-       {
-         point = XFLOAT_DATA (AREF (spec, FONT_SIZE_INDEX)) * 10;
-         attrs[LFACE_HEIGHT_INDEX] = make_number (point);
-       }
-    }
-}
-
-
-/* Selecte a font from ENTITIES (list of font-entity vectors) that
-   supports C and matches best with ATTRS and PIXEL_SIZE.  */
+/* Select a font from ENTITIES (list of font-entity vectors) that
+   supports C and is the best match for ATTRS and PIXEL_SIZE.  */
 
 static Lisp_Object
 font_select_entity (Lisp_Object frame, Lisp_Object entities, Lisp_Object *attrs, int pixel_size, int c)
@@ -3232,8 +3020,8 @@ font_select_entity (Lisp_Object frame, Lisp_Object entities, Lisp_Object *attrs,
   return font_sort_entities (entities, prefer, frame, c);
 }
 
-/* Return a font-entity satisfying SPEC and best matching with face's
-   font related attributes in ATTRS.  C, if not negative, is a
+/* Return a font-entity that satisfies SPEC and is the best match for
+   face's font related attributes in ATTRS.  C, if not negative, is a
    character that the entity must support.  */
 
 Lisp_Object
@@ -3241,7 +3029,7 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
 {
   Lisp_Object work;
   Lisp_Object frame, entities, val;
-  Lisp_Object size, foundry[3], *family, registry[3], adstyle[3];
+  Lisp_Object foundry[3], *family, registry[3], adstyle[3];
   int pixel_size;
   int i, j, k, l;
 
@@ -3269,12 +3057,11 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
        return Qnil;
     }
 
-  work = Fcopy_font_spec (spec);
+  work = copy_font_spec (spec);
   ASET (work, FONT_TYPE_INDEX, AREF (spec, FONT_TYPE_INDEX));
   XSETFRAME (frame, f);
-  size = AREF (spec, FONT_SIZE_INDEX);
   pixel_size = font_pixel_size (f, spec);
-  if (pixel_size == 0)
+  if (pixel_size == 0 && INTEGERP (attrs[LFACE_HEIGHT_INDEX]))
     {
       double pt = XINT (attrs[LFACE_HEIGHT_INDEX]);
 
@@ -3287,7 +3074,7 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
   else if (STRINGP (attrs[LFACE_FOUNDRY_INDEX]))
     {
       val = attrs[LFACE_FOUNDRY_INDEX];
-      foundry[0] = font_intern_prop ((char *) SDATA (val), SBYTES (val), 1);
+      foundry[0] = font_intern_prop (SSDATA (val), SBYTES (val), 1);
       foundry[1] = Qnil;
       foundry[2] = null_vector;
     }
@@ -3318,7 +3105,7 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
   if (NILP (val) && STRINGP (attrs[LFACE_FAMILY_INDEX]))
     {
       val = attrs[LFACE_FAMILY_INDEX];
-      val = font_intern_prop ((char *) SDATA (val), SBYTES (val), 1);
+      val = font_intern_prop (SSDATA (val), SBYTES (val), 1);
     }
   if (NILP (val))
     {
@@ -3425,8 +3212,8 @@ font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_O
 }
 
 
-/* Find a font satisfying SPEC and best matching with face's
-   attributes in ATTRS on FRAME, and return the opened
+/* Find a font that satisfies SPEC and is the best match for
+   face's attributes in ATTRS on FRAME, and return the opened
    font-object.  */
 
 Lisp_Object
@@ -3438,13 +3225,12 @@ font_load_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec)
   if (NILP (entity))
     {
       /* No font is listed for SPEC, but each font-backend may have
-        the different criteria about "font matching".  So, try
-        it.  */
+        different criteria about "font matching".  So, try it.  */
       entity = font_matching_entity (f, attrs, spec);
       if (NILP (entity))
        return Qnil;
     }
-  /* Don't loose the original name that was put in initially.  We need
+  /* Don't lose the original name that was put in initially.  We need
      it to re-apply the font when font parameters (like hinting or dpi) have
      changed.  */
   entity = font_open_for_lface (f, entity, attrs, spec);
@@ -3478,7 +3264,7 @@ font_done_for_face (FRAME_PTR f, struct face *face)
 }
 
 
-/* Open a font matching with font-spec SPEC on frame F.  If no proper
+/* Open a font that is a match for font-spec SPEC on frame F.  If no proper
    font is found, return Qnil.  */
 
 Lisp_Object
@@ -3502,7 +3288,7 @@ font_open_by_spec (FRAME_PTR f, Lisp_Object spec)
 }
 
 
-/* Open a font matching with NAME on frame F.  If no proper font is
+/* Open a font that matches NAME on frame F.  If no proper font is
    found, return Qnil.  */
 
 Lisp_Object
@@ -3515,7 +3301,7 @@ font_open_by_name (FRAME_PTR f, const char *name)
   args[1] = make_unibyte_string (name, strlen (name));
   spec = Ffont_spec (2, args);
   ret = font_open_by_spec (f, spec);
-  /* Do not loose name originally put in.  */
+  /* Do not lose name originally put in.  */
   if (!NILP (ret))
     font_put_extra (ret, QCuser_spec, args[1]);
 
@@ -3526,7 +3312,7 @@ font_open_by_name (FRAME_PTR f, const char *name)
 /* Register font-driver DRIVER.  This function is used in two ways.
 
    The first is with frame F non-NULL.  In this case, make DRIVER
-   available (but not yet activated) on F.  All frame creaters
+   available (but not yet activated) on F.  All frame creators
    (e.g. Fx_create_frame) must call this function at least once with
    an available font-driver.
 
@@ -3589,14 +3375,13 @@ Lisp_Object
 font_update_drivers (FRAME_PTR f, Lisp_Object new_drivers)
 {
   Lisp_Object active_drivers = Qnil;
-  struct font_driver *driver;
   struct font_driver_list *list;
 
   /* At first, turn off non-requested drivers, and turn on requested
      drivers.  */
   for (list = f->font_driver_list; list; list = list->next)
     {
-      driver = list->driver;
+      struct font_driver *driver = list->driver;
       if ((EQ (new_drivers, Qt) || ! NILP (Fmemq (driver->type, new_drivers)))
          != list->on)
        {
@@ -3724,20 +3509,73 @@ font_get_frame_data (FRAME_PTR f, struct font_driver *driver)
 }
 
 
+/* Sets attributes on a font.  Any properties that appear in ALIST and
+   BOOLEAN_PROPERTIES or NON_BOOLEAN_PROPERTIES are set on the font.
+   BOOLEAN_PROPERTIES and NON_BOOLEAN_PROPERTIES are NULL-terminated
+   arrays of strings.  This function is intended for use by the font
+   drivers to implement their specific font_filter_properties.  */
+void
+font_filter_properties (Lisp_Object font,
+                       Lisp_Object alist,
+                       const char *const boolean_properties[],
+                       const char *const non_boolean_properties[])
+{
+  Lisp_Object it;
+  int i;
+
+  /* Set boolean values to Qt or Qnil */
+  for (i = 0; boolean_properties[i] != NULL; ++i)
+    for (it = alist; ! NILP (it); it = XCDR (it))
+      {
+        Lisp_Object key = XCAR (XCAR (it));
+        Lisp_Object val = XCDR (XCAR (it));
+        char *keystr = SSDATA (SYMBOL_NAME (key));
+
+        if (strcmp (boolean_properties[i], keystr) == 0)
+          {
+            const char *str = INTEGERP (val) ? (XINT (val) ? "true" : "false")
+             : SYMBOLP (val) ? SSDATA (SYMBOL_NAME (val))
+             : "true";
+
+            if (strcmp ("false", str) == 0 || strcmp ("False", str) == 0
+                || strcmp ("FALSE", str) == 0 || strcmp ("FcFalse", str) == 0
+                || strcmp ("off", str) == 0 || strcmp ("OFF", str) == 0
+                || strcmp ("Off", str) == 0)
+              val = Qnil;
+           else
+              val = Qt;
+
+            Ffont_put (font, key, val);
+          }
+      }
+
+  for (i = 0; non_boolean_properties[i] != NULL; ++i)
+    for (it = alist; ! NILP (it); it = XCDR (it))
+      {
+        Lisp_Object key = XCAR (XCAR (it));
+        Lisp_Object val = XCDR (XCAR (it));
+        char *keystr = SSDATA (SYMBOL_NAME (key));
+        if (strcmp (non_boolean_properties[i], keystr) == 0)
+          Ffont_put (font, key, val);
+      }
+}
+
+
 /* Return the font used to draw character C by FACE at buffer position
    POS in window W.  If STRING is non-nil, it is a string containing C
    at index POS.  If C is negative, get C from the current buffer or
    STRING.  */
 
-Lisp_Object
-font_at (int c, EMACS_INT pos, struct face *face, struct window *w, Lisp_Object string)
+static Lisp_Object
+font_at (int c, EMACS_INT pos, struct face *face, struct window *w,
+        Lisp_Object string)
 {
   FRAME_PTR f;
   int multibyte;
   Lisp_Object font_object;
 
   multibyte = (NILP (string)
-              ? ! NILP (current_buffer->enable_multibyte_characters)
+              ? ! NILP (BVAR (current_buffer, enable_multibyte_characters))
               : STRING_MULTIBYTE (string));
   if (c < 0)
     {
@@ -3801,7 +3639,7 @@ font_at (int c, EMACS_INT pos, struct face *face, struct window *w, Lisp_Object
 #ifdef HAVE_WINDOW_SYSTEM
 
 /* Check how many characters after POS (at most to *LIMIT) can be
-   displayed by the same font on the window W.  FACE, if non-NULL, is
+   displayed by the same font in the window W.  FACE, if non-NULL, is
    the face selected for the character at POS.  If STRING is not nil,
    it is the string to check instead of the current buffer.  In that
    case, FACE must be not NULL.
@@ -3845,8 +3683,9 @@ font_range (EMACS_INT pos, EMACS_INT *limit, struct window *w, struct face *face
       else
        FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, pos, pos_byte);
       category = CHAR_TABLE_REF (Vunicode_category_table, c);
-      if (EQ (category, QCf)
-         || CHAR_VARIATION_SELECTOR_P (c))
+      if (INTEGERP (category)
+         && (XINT (category) == UNICODE_CATEGORY_Cf
+             || CHAR_VARIATION_SELECTOR_P (c)))
        continue;
       if (NILP (font_object))
        {
@@ -3945,14 +3784,14 @@ GSUB and GPOS may contain `nil' element.  In such a case, the font
 must not have any of the remaining elements.
 
 For instance, if the VALUE is `(thai nil nil (mark))', the font must
-be an OpenType font, and whose GPOS table of `thai' script's default
+be an OpenType font whose GPOS table of `thai' script's default
 language system must contain `mark' feature.
 
 usage: (font-spec ARGS...)  */)
-  (int nargs, Lisp_Object *args)
+  (ptrdiff_t nargs, Lisp_Object *args)
 {
   Lisp_Object spec = font_make_spec ();
-  int i;
+  ptrdiff_t i;
 
   for (i = 0; i < nargs; i += 2)
     {
@@ -3966,7 +3805,7 @@ usage: (font-spec ARGS...)  */)
       if (EQ (key, QCname))
        {
          CHECK_STRING (val);
-         font_parse_name ((char *) SDATA (val), spec);
+         font_parse_name (SSDATA (val), spec);
          font_put_extra (spec, key, val);
        }
       else
@@ -3988,9 +3827,9 @@ usage: (font-spec ARGS...)  */)
   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.  */)
-  (Lisp_Object font)
+/* Return a copy of FONT as a font-spec.  */
+Lisp_Object
+copy_font_spec (Lisp_Object font)
 {
   Lisp_Object new_spec, tail, prev, extra;
   int i;
@@ -4014,18 +3853,18 @@ DEFUN ("copy-font-spec", Fcopy_font_spec, Scopy_font_spec, 1, 1, 0,
   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.  */)
-  (Lisp_Object from, Lisp_Object to)
+/* Merge font-specs FROM and TO, and return a new font-spec.
+   Every specified property in FROM overrides the corresponding
+   property in TO.  */
+Lisp_Object
+merge_font_spec (Lisp_Object from, Lisp_Object to)
 {
   Lisp_Object extra, tail;
   int i;
 
   CHECK_FONT (from);
   CHECK_FONT (to);
-  to = Fcopy_font_spec (to);
+  to = copy_font_spec (to);
   for (i = 0; i < FONT_EXTRA_INDEX; i++)
     ASET (to, i, AREF (from, i));
   extra = AREF (to, FONT_EXTRA_INDEX);
@@ -4082,7 +3921,6 @@ Layout tags.  */)
        val = fontp->driver->otf_capability (fontp);
       else
        val = Fcons (Qnil, Qnil);
-      font_put_extra (font, QCotf, val);
     }
   else
     val = Fcdr (val);
@@ -4309,7 +4147,7 @@ DEFUN ("font-xlfd-name", Ffont_xlfd_name, Sfont_xlfd_name, 1, 2, 0,
 FONT is a font-spec, font-entity, or font-object.
 If the name is too long for XLFD (maximum 255 chars), return nil.
 If the 2nd optional arg FOLD-WILDCARDS is non-nil,
-the consecutive wildcards are folded to one.  */)
+the consecutive wildcards are folded into one.  */)
   (Lisp_Object font, Lisp_Object fold_wildcards)
 {
   char name[256];
@@ -4326,7 +4164,7 @@ the consecutive wildcards are folded to one.  */)
        {
          if (NILP (fold_wildcards))
            return font_name;
-         strcpy (name, (char *) SDATA (font_name));
+         strcpy (name, SSDATA (font_name));
          goto done;
        }
       pixel_size = XFONT_OBJECT (font)->pixel_size;
@@ -4415,7 +4253,7 @@ created glyph-string.  Otherwise, the value is nil.  */)
 {
   struct font *font;
   Lisp_Object font_object, n, glyph;
-  int i, j, from, to;
+  EMACS_INT i, j, from, to;
 
   if (! composition_gstring_p (gstring))
     signal_error ("Invalid glyph-string: ", gstring);
@@ -4487,7 +4325,7 @@ DEFUN ("font-variation-glyphs", Ffont_variation_glyphs, Sfont_variation_glyphs,
        doc: /* Return a list of variation glyphs for CHAR in FONT-OBJECT.
 Each element of the value is a cons (VARIATION-SELECTOR . GLYPH-ID),
 where
-  VARIATION-SELECTOR is a chracter code of variation selection
+  VARIATION-SELECTOR is a character code of variation selection
     (#xFE00..#xFE0F or #xE0100..#xE01EF)
   GLYPH-ID is a glyph code of the corresponding variation glyph.  */)
   (Lisp_Object font_object, Lisp_Object character)
@@ -4509,16 +4347,8 @@ where
   for (i = 0; i < 255; i++)
     if (variations[i])
       {
-       Lisp_Object code;
        int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16));
-       /* Stops GCC whining about limited range of data type.  */
-       EMACS_INT var = variations[i];
-
-       if (var > MOST_POSITIVE_FIXNUM)
-         code = Fcons (make_number ((variations[i]) >> 16),
-                       make_number ((variations[i]) & 0xFFFF));
-       else
-         code = make_number (variations[i]);
+       Lisp_Object code = INTEGER_TO_CONS (variations[i]);
        val = Fcons (Fcons (make_number (vs), code), val);
       }
   return val;
@@ -4556,7 +4386,7 @@ the value is 0.
 If GSTRING-OUT is too short to hold produced glyphs, no glyphs are
 produced in GSTRING-OUT, and the value is nil.
 
-See the documentation of `font-make-gstring' for the format of
+See the documentation of `composition-get-gstring' for the format of
 glyph-string.  */)
   (Lisp_Object otf_features, Lisp_Object gstring_in, Lisp_Object from, Lisp_Object to, Lisp_Object gstring_out, Lisp_Object index)
 {
@@ -4691,10 +4521,10 @@ The value is a vector:
   [ NAME FILENAME PIXEL-SIZE SIZE ASCENT DESCENT SPACE-WIDTH AVERAGE-WIDTH
     CAPABILITY ]
 
-NAME is a string of the font name (or nil if the font backend doesn't
+NAME is the font name, a string (or nil if the font backend doesn't
 provide a name).
 
-FILENAME is a string of the font file (or nil if the font backend
+FILENAME is the font file name, a string (or nil if the font backend
 doesn't provide a file name).
 
 PIXEL-SIZE is a pixel size by which the font is opened.
@@ -4770,7 +4600,7 @@ the corresponding element is nil.  */)
    Lisp_Object object)
 {
   struct font *font;
-  int i, len, c;
+  int i, len;
   Lisp_Object *chars, vec;
   USE_SAFE_ALLOCA;
 
@@ -4788,6 +4618,7 @@ the corresponding element is nil.  */)
       bytepos = CHAR_TO_BYTE (charpos);
       for (i = 0; charpos < XFASTINT (to); i++)
        {
+         int c;
          FETCH_CHAR_ADVANCE (c, charpos, bytepos);
          chars[i] = make_number (c);
        }
@@ -4809,7 +4640,7 @@ the corresponding element is nil.  */)
       if (STRING_MULTIBYTE (object))
        for (i = 0; i < len; i++)
          {
-           c = STRING_CHAR_ADVANCE (p);
+           int c = STRING_CHAR_ADVANCE (p);
            chars[i] = make_number (c);
          }
       else
@@ -4841,10 +4672,9 @@ the corresponding element is nil.  */)
       Lisp_Object g;
       int c = XFASTINT (chars[i]);
       unsigned code;
-      EMACS_INT cod;
       struct font_metrics metrics;
 
-      cod = code = font->driver->encode_char (font, c);
+      code = font->driver->encode_char (font, c);
       if (code == FONT_INVALID_CODE)
        continue;
       g = Fmake_vector (make_number (LGLYPH_SIZE), Qnil);
@@ -4989,7 +4819,7 @@ If the named font is not yet loaded, return nil.  */)
 
       if (fontset >= 0)
        name = fontset_ascii (fontset);
-      font_object = font_open_by_name (f, (char *) SDATA (name));
+      font_object = font_open_by_name (f, SSDATA (name));
     }
   else if (FONT_OBJECT_P (name))
     font_object = name;
@@ -5048,8 +4878,6 @@ build_style_table (const struct table_entry *entry, int nelement)
   return table;
 }
 
-Lisp_Object Vfont_log;
-
 /* The deferred font-log data of the form [ACTION ARG RESULT].
    If ACTION is not nil, that is added to the log when font_add_log is
    called next time.  At that time, ACTION is set back to nil.  */
@@ -5062,14 +4890,14 @@ static Lisp_Object Vfont_log_deferred;
 void
 font_add_log (const char *action, Lisp_Object arg, Lisp_Object result)
 {
-  Lisp_Object tail, val;
+  Lisp_Object val;
   int i;
 
   if (EQ (Vfont_log, Qt))
     return;
   if (STRINGP (AREF (Vfont_log_deferred, 0)))
     {
-      char *str = (char *) SDATA (AREF (Vfont_log_deferred, 0));
+      char *str = SSDATA (AREF (Vfont_log_deferred, 0));
 
       ASET (Vfont_log_deferred, 0, Qnil);
       font_add_log (str, AREF (Vfont_log_deferred, 1),
@@ -5118,6 +4946,7 @@ font_add_log (const char *action, Lisp_Object arg, Lisp_Object result)
     }
   else if (CONSP (result))
     {
+      Lisp_Object tail;
       result = Fcopy_sequence (result);
       for (tail = result; CONSP (tail); tail = XCDR (tail))
        {
@@ -5255,7 +5084,7 @@ syms_of_font (void)
   defsubr (&Sfont_info);
 #endif
 
-  DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
+  DEFVAR_LISP ("font-encoding-alist", Vfont_encoding_alist,
               doc: /*
 Alist of fontname patterns vs the corresponding encoding and repertory info.
 Each element looks like (REGEXP . (ENCODING . REPERTORY)),
@@ -5282,7 +5111,7 @@ gets the repertory information by an opened font and ENCODING.  */);
      table used by the font display code.  So we make them read-only,
      to avoid this confusing situation.  */
 
-  DEFVAR_LISP_NOPRO ("font-weight-table", &Vfont_weight_table,
+  DEFVAR_LISP_NOPRO ("font-weight-table", Vfont_weight_table,
               doc: /*  Vector of valid font weight values.
 Each element has the form:
     [NUMERIC-VALUE SYMBOLIC-NAME ALIAS-NAME ...]
@@ -5290,13 +5119,13 @@ NUMERIC-VALUE is an integer, and SYMBOLIC-NAME and ALIAS-NAME are symbols. */);
   Vfont_weight_table = BUILD_STYLE_TABLE (weight_table);
   XSYMBOL (intern_c_string ("font-weight-table"))->constant = 1;
 
-  DEFVAR_LISP_NOPRO ("font-slant-table", &Vfont_slant_table,
+  DEFVAR_LISP_NOPRO ("font-slant-table", Vfont_slant_table,
               doc: /*  Vector of font slant symbols vs the corresponding numeric values.
 See `font-weight-table' for the format of the vector. */);
   Vfont_slant_table = BUILD_STYLE_TABLE (slant_table);
   XSYMBOL (intern_c_string ("font-slant-table"))->constant = 1;
 
-  DEFVAR_LISP_NOPRO ("font-width-table", &Vfont_width_table,
+  DEFVAR_LISP_NOPRO ("font-width-table", Vfont_width_table,
               doc: /*  Alist of font width symbols vs the corresponding numeric values.
 See `font-weight-table' for the format of the vector. */);
   Vfont_width_table = BUILD_STYLE_TABLE (width_table);
@@ -5308,7 +5137,7 @@ See `font-weight-table' for the format of the vector. */);
   ASET (font_style_table, 1, Vfont_slant_table);
   ASET (font_style_table, 2, Vfont_width_table);
 
-  DEFVAR_LISP ("font-log", &Vfont_log, doc: /*
+  DEFVAR_LISP ("font-log", Vfont_log, doc: /*
 *Logging list of font related actions and results.
 The value t means to suppress the logging.
 The initial value is set to nil if the environment variable
@@ -5347,6 +5176,3 @@ init_font (void)
 {
   Vfont_log = egetenv ("EMACS_FONT_LOG") ? Qnil : Qt;
 }
-
-/* arch-tag: 74c9475d-5976-4c93-a327-942ae3072846
-   (do not change this comment) */