]> code.delx.au - gnu-emacs/blobdiff - src/fontset.c
Add 2009 to copyright years.
[gnu-emacs] / src / fontset.c
index 82e5b4e65dee2023d553e4d71a3ec723fec59842..eca79168ffb18053d888511e86f1b66f2361e335 100644 (file)
@@ -1,14 +1,14 @@
 /* Fontset handler.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
      Free Software Foundation, Inc.
    Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-     2005, 2006, 2007, 2008
+     2005, 2006, 2007, 2008, 2009
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H14PRO021
    Copyright (C) 2003, 2006
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H13PRO009
+
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
@@ -27,10 +27,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 /* #define FONTSET_DEBUG */
 
 #include <config.h>
-
-#ifdef FONTSET_DEBUG
 #include <stdio.h>
-#endif
 
 #include "lisp.h"
 #include "blockinput.h"
@@ -50,8 +47,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #ifdef WINDOWSNT
 #include "w32term.h"
 #endif
-#ifdef MAC_OS
-#include "macterm.h"
+#ifdef HAVE_NS
+#include "nsterm.h"
 #endif
 #include "termhooks.h"
 
@@ -140,7 +137,7 @@ EXFUN (Fclear_face_cache, 1);
        base: nil
        realized: Alist of font index vs the corresponding repertory
        char-table.
-       
+
    The 8th slot:
        base: nil
        realized: If the base is not the default fontset, a fontset
@@ -191,7 +188,6 @@ static int next_fontset_id;
    font for each character.  */
 static Lisp_Object Vdefault_fontset;
 
-Lisp_Object Vfont_encoding_alist;
 Lisp_Object Vfont_encoding_charset_alist;
 Lisp_Object Vuse_default_ascent;
 Lisp_Object Vignore_relative_composition;
@@ -209,7 +205,7 @@ static Lisp_Object fontset_add P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
                                    Lisp_Object));
 static Lisp_Object fontset_find_font P_ ((Lisp_Object, int, struct face *,
                                          int, int));
-static void reorder_font_vector P_ ((Lisp_Object, Lisp_Object));
+static void reorder_font_vector P_ ((Lisp_Object, struct font *));
 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));
@@ -356,9 +352,8 @@ fontset_add (fontset, range, elt, add)
       int from1, to1;
 
       do {
+       from1 = from, to1 = to;
        args[idx] = char_table_ref_and_range (fontset, from, &from1, &to1);
-       if (to < to1)
-         to1 = to;
        char_table_set_range (fontset, from, to1,
                              NILP (args[idx]) ? args[1 - idx]
                              : Fvconcat (2, args));
@@ -378,14 +373,14 @@ static int
 fontset_compare_rfontdef (val1, val2)
      const void *val1, *val2;
 {
-  return (RFONT_DEF_SCORE (*(Lisp_Object *) val2)
-         - RFONT_DEF_SCORE (*(Lisp_Object *) val1));
+  return (RFONT_DEF_SCORE (*(Lisp_Object *) val1)
+         - RFONT_DEF_SCORE (*(Lisp_Object *) val2));
 }
 
 /* Update FONT-GROUP which has this form:
        [ CHARSET-ORDERED-LIST-TICK PREFERRED-RFONT-DEF
          RFONT-DEF0 RFONT-DEF1 ... ]
-   Reorder RFONT-DEFs according to the current langauge, and update
+   Reorder RFONT-DEFs according to the current language, and update
    CHARSET-ORDERED-LIST-TICK.
 
    If PREFERRED_FAMILY is not nil, that family has the higher priority
@@ -394,54 +389,57 @@ fontset_compare_rfontdef (val1, val2)
 extern Lisp_Object Fassoc_string ();
 
 static void
-reorder_font_vector (font_group, preferred_family)
+reorder_font_vector (font_group, font)
      Lisp_Object font_group;
-     Lisp_Object preferred_family;
+     struct font *font;
 {
+  Lisp_Object vec, font_object;
   int size;
   int i;
   int score_changed = 0;
 
-  size = ASIZE (font_group);
-  /* Exclude the tailing nil elements from the reordering.  */
-  while (NILP (AREF (font_group, size - 1))) size--;
-  size -= 2;
+  if (font)
+    XSETFONT (font_object, font);
+  else
+    font_object = Qnil;
+
+  vec = XCDR (font_group);
+  size = ASIZE (vec);
+  /* Exclude the tailing nil element from the reordering.  */
+  if (NILP (AREF (vec, size - 1)))
+    size--;
 
   for (i = 0; i < size; i++)
     {
-      Lisp_Object rfont_def = AREF (font_group, i + 2);
+      Lisp_Object rfont_def = AREF (vec, i);
       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;
+      int score = RFONT_DEF_SCORE (rfont_def) & 0xFF;
 
-         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 (! font_match_p (font_spec, font_object))
        {
-         if (EQ (lang, Vcurrent_iso639_language))
-           score = 0xFFFF;
-         else if (CONSP (Vcurrent_iso639_language))
-           score = ! NILP (Fmemq (lang, Vcurrent_iso639_language));
-       }
+         Lisp_Object encoding = FONT_DEF_ENCODING (font_def);
 
-      if (! NILP (preferred_family) && ! NILP (family))
-       {
-         if (fast_string_match_ignore_case (preferred_family,
-                                            SYMBOL_NAME (family)) < 0)
-           score |= 0x10000;
+         if (! NILP (encoding))
+           {
+             Lisp_Object tail;
+
+             for (tail = Vcharset_ordered_list;
+                  ! EQ (tail, Vcharset_non_preferred_head) && CONSP (tail);
+                  score += 0x100, tail = XCDR (tail))
+               if (EQ (encoding, XCAR (tail)))
+                 break;
+           }
+         else
+           {
+             Lisp_Object lang = Ffont_get (font_spec, QClang);
+
+             if (! NILP (lang)
+                 && ! EQ (lang, Vcurrent_iso639_language)
+                 && (! CONSP (Vcurrent_iso639_language)
+                     || NILP (Fmemq (lang, Vcurrent_iso639_language))))
+               score |= 0x100;
+           }
        }
       if (RFONT_DEF_SCORE (rfont_def) != score)
        {
@@ -451,10 +449,49 @@ reorder_font_vector (font_group, preferred_family)
     }
 
   if (score_changed)
-    qsort (XVECTOR (font_group)->contents + 2, size, sizeof (Lisp_Object),
+    qsort (XVECTOR (vec)->contents, size, sizeof (Lisp_Object),
           fontset_compare_rfontdef);
+  XSETCAR (font_group, make_number (charset_ordered_list_tick));
+}
+
+static Lisp_Object
+fontset_get_font_group (Lisp_Object fontset, int c)
+{
+  Lisp_Object font_group;
+  Lisp_Object base_fontset;
+  int from = 0, to = MAX_CHAR, i;
 
-  ASET (font_group, 0, make_number (charset_ordered_list_tick));
+  xassert (! BASE_FONTSET_P (fontset));
+  if (c >= 0)
+    font_group = CHAR_TABLE_REF (fontset, c);
+  else
+    font_group = FONTSET_FALLBACK (fontset);
+  if (! NILP (font_group))
+    return font_group;
+  base_fontset = FONTSET_BASE (fontset);
+  if (c >= 0)
+    font_group = char_table_ref_and_range (base_fontset, c, &from, &to);
+  else
+    font_group = FONTSET_FALLBACK (base_fontset);
+  if (NILP (font_group))
+    return Qnil;
+  font_group = Fcopy_sequence (font_group);
+  for (i = 0; i < ASIZE (font_group); i++)
+    if (! NILP (AREF (font_group, i)))
+      {
+       Lisp_Object rfont_def;
+
+       RFONT_DEF_NEW (rfont_def, AREF (font_group, i));
+       /* Remember the original order.  */
+       RFONT_DEF_SET_SCORE (rfont_def, i);
+       ASET (font_group, i, rfont_def);
+      }
+  font_group = Fcons (make_number (-1), font_group);
+  if (c >= 0)
+    char_table_set_range (fontset, from, to, font_group);
+  else
+    FONTSET_FALLBACK (fontset) = font_group;
+  return font_group;
 }
 
 /* Return RFONT-DEF (vector) in the realized fontset FONTSET for the
@@ -477,117 +514,61 @@ fontset_find_font (fontset, c, face, id, fallback)
      struct face *face;
      int id, fallback;
 {
-  Lisp_Object base_fontset, elt, vec;
-  int i, from, to;
-  FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
+  Lisp_Object elt, vec, font_group;
+  int i, charset_matched = -1;
+  FRAME_PTR f = (FRAMEP (FONTSET_FRAME (fontset)))
+    ? XFRAME (selected_frame) : XFRAME (FONTSET_FRAME (fontset));
 
-  base_fontset = FONTSET_BASE (fontset);
-  if (! fallback)
-    vec = CHAR_TABLE_REF (fontset, c);
-  else
-    vec = FONTSET_FALLBACK (fontset);
+  font_group = fontset_get_font_group (fontset, fallback ? -1 : c);
+  if (! CONSP (font_group))
+    return Qnil;
+  vec = XCDR (font_group);
+  if (ASIZE (vec) == 0)
+    return Qnil;
 
-  if (NILP (vec))
+  if (ASIZE (vec) > 1)
     {
-      Lisp_Object range;
-
-      /* We have not yet decided a font for C.  */
-      if (! face)
-       return Qnil;
-      if (! fallback)
-       {
-         elt = char_table_ref_and_range (base_fontset, c, &from, &to);
-         range = Fcons (make_number (from), make_number (to));
-       }
-      else
-       {
-         elt = FONTSET_FALLBACK (base_fontset);
-       }
-      if (NILP (elt))
-       {
-         /* This fontset doesn't specify any font for C. */
-         vec = make_number (0);
-       }
-      else if (ASIZE (elt) == 1 && NILP (AREF (elt, 0)))
-       {
-         /* Explicitly specified no font.  */
-         vec = Qt;
-       }
-      else
-       {
-         /* Build a 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 + 2), Qnil);
-         ASET (vec, 0, make_number (-1));
-         for (i = j = 0; i < size; i++)
-           if (! NILP (AREF (elt, i)))
+      if (XINT (XCAR (font_group)) != charset_ordered_list_tick)
+       /* We have just created the font-group,
+          or the charset priorities were changed.  */
+       reorder_font_vector (font_group, face->ascii_face->font);
+      if (id >= 0)
+       /* Find a spec matching with the charset ID to try at
+          first.  */
+       for (i = 0; i < ASIZE (vec); i++)
+         {
+           Lisp_Object rfont_def = AREF (vec, i);
+           Lisp_Object repertory
+             = FONT_DEF_REPERTORY (RFONT_DEF_FONT_DEF (rfont_def));
+
+           if (XINT (repertory) == id)
              {
-               Lisp_Object rfont_def;
-
-               RFONT_DEF_NEW (rfont_def, AREF (elt, i));
-               ASET (vec, j + 2, rfont_def);
-               j++;
-             }
-       }
-      /* Then store it in the fontset.  */
-      if (! fallback)
-       FONTSET_SET (fontset, range, vec);
-      else
-       FONTSET_FALLBACK (fontset) = vec;
-
-    }
-  if (! VECTORP (vec))
-    return (EQ (vec, Qt) ? Qt : Qnil);
-
-  if (ASIZE (vec) > 4          /* multiple RFONT-DEFs */
-      && XINT (AREF (vec, 0)) != charset_ordered_list_tick)
-    /* We have just created VEC,
-       or the charset priorities were changed.  */
-    reorder_font_vector (vec, face->lface[LFACE_FAMILY_INDEX]);
-  i = 2;
-  if (id >= 0)
-    {
-      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)))
+               charset_matched = i;
                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 < ASIZE (vec); i++)
+  for (i = 0; i < ASIZE (vec); i++)
     {
-      Lisp_Object font_def, font_entity, font_object;
+      Lisp_Object font_entity, font_object;
+
+      if (i == 0 && charset_matched >= 0)
+       {
+         /* Try the element matching with the charset ID at first.  */
+         elt = AREF (vec, charset_matched);
+         charset_matched = -1;
+         i--;
+       }
+      else if (i != charset_matched)
+       elt = AREF (vec, i);
+      else
+       continue;
 
-      elt = AREF (vec, i);
       if (NILP (elt))
-       /* This is the sign of not to try fallback fonts.  */
+       /* This is a sign of not to try the other fonts.  */
        return Qt;
-      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.  */
@@ -609,7 +590,8 @@ fontset_find_font (fontset, c, face, id, fallback)
              RFONT_DEF_SET_FACE (elt, -1);
              continue;
            }
-         font_object = font_open_for_lface (f, font_entity, face->lface, Qnil);
+         font_object = font_open_for_lface (f, font_entity, face->lface,
+                                            FONT_DEF_SPEC (font_def));
          if (NILP (font_object))
            {
              /* Record that the font is unsable.  */
@@ -618,7 +600,7 @@ fontset_find_font (fontset, c, face, id, fallback)
            }
          RFONT_DEF_SET_OBJECT (elt, font_object);
        }
-      
+
       if (font_has_char (f, font_object, c))
        return elt;
 
@@ -678,14 +660,15 @@ fontset_font (fontset, c, face, id)
   Lisp_Object rfont_def;
   Lisp_Object base_fontset;
 
-  /* Try a font-group for C. */
+  /* Try a font-group of FONTSET. */
   rfont_def = fontset_find_font (fontset, c, face, id, 0);
   if (VECTORP (rfont_def))
     return rfont_def;
   if (EQ (rfont_def, Qt))
     return Qnil;
+
+  /* Try a font-group of the default fontset. */
   base_fontset = FONTSET_BASE (fontset);
-  /* Try a font-group for C of the default fontset. */
   if (! EQ (base_fontset, Vdefault_fontset))
     {
       if (NILP (FONTSET_DEFAULT (fontset)))
@@ -693,21 +676,30 @@ fontset_font (fontset, c, face, id)
          = make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
       rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 0);
       if (VECTORP (rfont_def))
-       return (rfont_def);
+       return rfont_def;
+      if (EQ (rfont_def, Qt))
+       return Qnil;
     }
 
-  /* Try a fallback font-group. */
+  /* Try a fallback font-group of FONTSET. */
   rfont_def = fontset_find_font (fontset, c, face, id, 1);
-  if (! VECTORP (rfont_def)
-      && ! EQ (base_fontset, Vdefault_fontset))
-    /* Try a fallback font-group of the default fontset . */
-    rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 1);
+  if (VECTORP (rfont_def))
+    return rfont_def;
+  if (EQ (rfont_def, Qt))
+    return Qnil;
+
+  /* Try a fallback font-group of the default fontset . */
+  if (! EQ (base_fontset, Vdefault_fontset))
+    {
+      rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 1);
+      if (VECTORP (rfont_def))
+       return rfont_def;
+    }
 
-  if (! VECTORP (rfont_def))
-    /* Remeber that we have no font for C.  */
-    FONTSET_SET (fontset, make_number (c), Qt);
+  /* Remeber that we have no font for C.  */
+  FONTSET_SET (fontset, make_number (c), Qt);
 
-  return rfont_def;
+  return Qnil;
 }
 
 /* Return a newly created fontset with NAME.  If BASE is nil, make a
@@ -836,7 +828,7 @@ free_face_fontset (f, face)
   if (! NILP (FONTSET_DEFAULT (fontset)))
     {
       int id = XINT (FONTSET_ID (FONTSET_DEFAULT (fontset)));
-      
+
       fontset = AREF (Vfontset_table, id);
       xassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
       xassert (f == XFRAME (FONTSET_FRAME (fontset)));
@@ -879,26 +871,30 @@ face_for_char (f, face, c, pos, object)
      int c, pos;
      Lisp_Object object;
 {
-  Lisp_Object fontset, rfont_def;
+  Lisp_Object fontset, rfont_def, charset;
   int face_id;
   int id;
 
-  if (ASCII_CHAR_P (c))
+  /* If face->fontset is negative (that happens when no font is found
+     for face), just return face->ascii_face because we can't do
+     anything.  Perhaps, we should fix the callers to assure
+     that face->fontset is always valid.  */
+  if (ASCII_CHAR_P (c) || face->fontset < 0)
     return face->ascii_face->id;
 
   xassert (fontset_id_valid_p (face->fontset));
   fontset = FONTSET_FROM_ID (face->fontset);
   xassert (!BASE_FONTSET_P (fontset));
+
   if (pos < 0)
-    id = -1;
+    {
+      id = -1;
+      charset = Qnil;
+    }
   else
     {
-      Lisp_Object charset;
-
       charset = Fget_char_property (make_number (pos), Qcharset, object);
-      if (NILP (charset))
-       id = -1;
-      else if (CHARSETP (charset))
+      if (CHARSETP (charset))
        {
          Lisp_Object val;
 
@@ -907,7 +903,11 @@ face_for_char (f, face, c, pos, object)
            charset = XCDR (val);
          id = XINT (CHARSET_SYMBOL_ID (charset));
        }
+      else
+       id = -1;
     }
+
+  font_deferred_log ("font for", Fcons (make_number (c), charset), Qnil);
   rfont_def = fontset_font (fontset, c, face, id);
   if (VECTORP (rfont_def))
     {
@@ -937,6 +937,56 @@ face_for_char (f, face, c, pos, object)
 }
 
 
+Lisp_Object
+font_for_char (face, c, pos, object)
+     struct face *face;
+     int c, pos;
+     Lisp_Object object;
+{
+  Lisp_Object fontset, rfont_def, charset;
+  int face_id;
+  int id;
+
+  if (ASCII_CHAR_P (c))
+    {
+      Lisp_Object font_object;
+
+      XSETFONT (font_object, face->ascii_face->font);
+      return font_object;
+    }
+
+  xassert (fontset_id_valid_p (face->fontset));
+  fontset = FONTSET_FROM_ID (face->fontset);
+  xassert (!BASE_FONTSET_P (fontset));
+  if (pos < 0)
+    {
+      id = -1;
+      charset = Qnil;
+    }
+  else
+    {
+      charset = Fget_char_property (make_number (pos), Qcharset, object);
+      if (CHARSETP (charset))
+       {
+         Lisp_Object val;
+
+         val = assoc_no_quit (charset, Vfont_encoding_charset_alist);
+         if (CONSP (val) && CHARSETP (XCDR (val)))
+           charset = XCDR (val);
+         id = XINT (CHARSET_SYMBOL_ID (charset));
+       }
+      else
+       id = -1;
+    }
+
+  font_deferred_log ("font for", Fcons (make_number (c), charset), Qnil);
+  rfont_def = fontset_font (fontset, c, face, id);
+  return (VECTORP (rfont_def)
+         ? RFONT_DEF_OBJECT (rfont_def)
+         : Qnil);
+}
+
+
 /* Make a realized fontset for ASCII face FACE on frame F from the
    base fontset BASE_FONTSET_ID.  If BASE_FONTSET_ID is -1, use the
    default fontset as the base.  Value is the id of the new fontset.
@@ -967,38 +1017,13 @@ make_fontset_for_ascii_face (f, base_fontset_id, face)
 }
 
 \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;
-{
-  Lisp_Object tail, elt;
-
-  for (tail = Vfont_encoding_alist; CONSP (tail); tail = XCDR (tail))
-    {
-      elt = XCAR (tail);
-      if (CONSP (elt)
-         && STRINGP (XCAR (elt))
-         && fast_string_match_ignore_case (XCAR (elt), fontname) >= 0
-         && (SYMBOLP (XCDR (elt))
-             ? CHARSETP (XCDR (elt))
-             : CONSP (XCDR (elt)) && CHARSETP (XCAR (XCDR (elt)))))
-       return (XCDR (elt));
-    }
-  /* We don't know the encoding of this font.  Let's assume `ascii'.  */
-  return Qascii;
-}
-
 
 /* Cache data used by fontset_pattern_regexp.  The car part is a
    pattern string containing at least one wild card, the cdr part is
    the corresponding regular expression.  */
 static Lisp_Object Vcached_fontset_data;
 
-#define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
+#define CACHED_FONTSET_NAME ((char *) SDATA (XCAR (Vcached_fontset_data)))
 #define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
 
 /* If fontset name PATTERN contains any wild card, return regular
@@ -1008,17 +1033,17 @@ static Lisp_Object
 fontset_pattern_regexp (pattern)
      Lisp_Object pattern;
 {
-  if (!index (SDATA (pattern), '*')
-      && !index (SDATA (pattern), '?'))
+  if (!index ((char *) SDATA (pattern), '*')
+      && !index ((char *) SDATA (pattern), '?'))
     /* PATTERN does not contain any wild cards.  */
     return Qnil;
 
   if (!CONSP (Vcached_fontset_data)
-      || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
+      || strcmp ((char *) SDATA (pattern), CACHED_FONTSET_NAME))
     {
       /* We must at first update the cached data.  */
       unsigned char *regex, *p0, *p1;
-      int ndashes = 0, nstars = 0;
+      int ndashes = 0, nstars = 0, nescs = 0;
 
       for (p0 = SDATA (pattern); *p0; p0++)
        {
@@ -1026,15 +1051,20 @@ fontset_pattern_regexp (pattern)
            ndashes++;
          else if (*p0 == '*')
            nstars++;
+         else if (*p0 == '['
+                  || *p0 == '.' || *p0 == '\\'
+                  || *p0 == '+' || *p0 == '^' 
+                  || *p0 == '$')
+           nescs++;
        }
 
       /* If PATTERN is not full XLFD we conert "*" to ".*".  Otherwise
         we convert "*" to "[^-]*" which is much faster in regular
         expression matching.  */
       if (ndashes < 14)
-       p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 2 * nstars + 1);
+       p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 2 * nstars + 2 * nescs + 1);
       else
-       p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 5 * nstars + 1);
+       p1 = regex = (unsigned char *) alloca (SBYTES (pattern) + 5 * nstars + 2 * nescs + 1);
 
       *p1++ = '^';
       for (p0 = SDATA (pattern); *p0; p0++)
@@ -1049,14 +1079,19 @@ fontset_pattern_regexp (pattern)
            }
          else if (*p0 == '?')
            *p1++ = '.';
+         else if (*p0 == '['
+                  || *p0 == '.' || *p0 == '\\'
+                  || *p0 == '+' || *p0 == '^' 
+                  || *p0 == '$')
+           *p1++ = '\\', *p1++ = *p0;
          else
            *p1++ = *p0;
        }
       *p1++ = '$';
       *p1++ = 0;
 
-      Vcached_fontset_data = Fcons (build_string (SDATA (pattern)),
-                                   build_string (regex));
+      Vcached_fontset_data = Fcons (build_string ((char *) SDATA (pattern)),
+                                   build_string ((char *) regex));
     }
 
   return CACHED_FONTSET_REGEX;
@@ -1108,7 +1143,7 @@ fs_query_fontset (name, name_pattern)
       this_name = FONTSET_NAME (fontset);
       if (name_pattern == 1
          ? fast_string_match_ignore_case (name, this_name) >= 0
-         : !strcasecmp (SDATA (name), SDATA (this_name)))
+         : !xstrcasecmp (SDATA (name), SDATA (this_name)))
        return i;
     }
   return -1;
@@ -1171,7 +1206,7 @@ list_fontsets (f, pattern, size)
 
       if (STRINGP (regexp)
          ? (fast_string_match (regexp, name) < 0)
-         : strcmp (SDATA (pattern), SDATA (name)))
+         : strcmp ((char *) SDATA (pattern), (char *) SDATA (name)))
        continue;
 
       val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
@@ -1279,11 +1314,10 @@ generate_ascii_font_name (name, ascii_spec)
      Lisp_Object name, ascii_spec;
 {
   Lisp_Object font_spec = Ffont_spec (0, NULL);
-  Lisp_Object vec;
   int i;
   char xlfd[256];
 
-  if (font_parse_xlfd (SDATA (name), font_spec) < 0)
+  if (font_parse_xlfd ((char *) SDATA (name), font_spec) < 0)
     error ("Not an XLFD font name: %s", SDATA (name));
   for (i = FONT_FOUNDRY_INDEX; i < FONT_EXTRA_INDEX; i++)
     if (! NILP (AREF (ascii_spec, i)))
@@ -1545,7 +1579,6 @@ FONT-SPEC is a vector, a cons, or a string.  See the documentation of
      Lisp_Object name, fontlist;
 {
   Lisp_Object fontset;
-  Lisp_Object val;
   int id;
 
   CHECK_STRING (name);
@@ -1560,10 +1593,10 @@ FONT-SPEC is a vector, a cons, or a string.  See the documentation of
       char xlfd[256];
       int len;
 
-      if (font_parse_xlfd (SDATA (name), font_spec) < 0)
+      if (font_parse_xlfd ((char *) SDATA (name), font_spec) < 0)
        error ("Fontset name must be in XLFD format");
       short_name = AREF (font_spec, FONT_REGISTRY_INDEX);
-      if (strncmp (SDATA (SYMBOL_NAME (short_name)), "fontset-", 8)
+      if (strncmp ((char *) 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)),
@@ -1628,7 +1661,7 @@ fontset_from_font (font_object)
     }
   fontset_spec = Fcopy_font_spec (font_spec);
   ASET (fontset_spec, FONT_REGISTRY_INDEX, alias);
-  name = Ffont_xlfd_name (fontset_spec);
+  name = Ffont_xlfd_name (fontset_spec, Qnil);
   if (NILP (name))
     abort ();
   fontset = make_fontset (Qnil, name, Qnil);
@@ -1638,72 +1671,25 @@ fontset_from_font (font_object)
   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;
-  ASET (font_spec, FONT_FOUNDRY_INDEX, Qnil);
-  ASET (font_spec, FONT_ADSTYLE_INDEX, Qnil);
+  font_spec = Fcopy_font_spec (font_spec);
+  ASET (font_spec, FONT_REGISTRY_INDEX, Qiso10646_1);
   for (i = FONT_WEIGHT_INDEX; i < FONT_EXTRA_INDEX; i++)
     ASET (font_spec, i, Qnil);
   Fset_fontset_font (name, Qlatin, font_spec, Qnil, Qnil);
-  font_spec = Fcopy_font_spec (font_spec);
-  ASET (font_spec, FONT_REGISTRY_INDEX, Qiso10646_1);
   Fset_fontset_font (name, Qnil, font_spec, Qnil, Qnil);
-  return XINT (FONTSET_ID (fontset));
-}
 
-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.
-The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
-  HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
-where
-  OPENED-NAME is the name used for opening the font,
-  FULL-NAME is the full name of the font,
-  SIZE is the maximum bound width of the font,
-  HEIGHT is the height of the font,
-  BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
-  RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
-    how to compose characters.
-If the named font is not yet loaded, return nil.  */)
-     (name, frame)
-     Lisp_Object name, frame;
-{
-  FRAME_PTR f;
-  struct font *font;
-  Lisp_Object info;
-  Lisp_Object font_object;
-
-  (*check_window_system_func) ();
-
-  CHECK_STRING (name);
-  name = Fdowncase (name);
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame);
-  f = XFRAME (frame);
+#ifdef HAVE_NS
+  nsfont_make_fontset_for_font(name, font_object);
+#endif
 
-  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] = 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;
+  return XINT (FONTSET_ID (fontset));
 }
 
-
-/* Return a cons (FONT-NAME . GLYPH-CODE).
-   FONT-NAME is the font name for the character at POSITION in the current
+/* Return a cons (FONT-OBJECT . GLYPH-CODE).
+   FONT-OBJECT is the font for the character at POSITION in the current
    buffer.  This is computed from all the text properties and overlays
    that apply to POSITION.  POSTION may be nil, in which case,
-   FONT-NAME is the font name for display the character CH with the
+   FONT-SPEC is the font for displaying the character CH with the
    default face.
 
    GLYPH-CODE is the glyph code in the font to use for the character.
@@ -1736,7 +1722,6 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
   int c;
   struct frame *f;
   struct face *face;
-  Lisp_Object rfont_def;
   int cs_id;
 
   if (NILP (position))
@@ -1744,7 +1729,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
       CHECK_CHARACTER (ch);
       c = XINT (ch);
       f = XFRAME (selected_frame);
-      face_id = DEFAULT_FACE_ID;
+      face_id = lookup_basic_face (f, DEFAULT_FACE_ID);
       pos = -1;
       cs_id = -1;
     }
@@ -1783,18 +1768,18 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
   face = FACE_FROM_ID (f, face_id);
   if (face->font)
     {
-      struct font *font = face->font;
-      unsigned code = font->driver->encode_char (font, c);
-      Lisp_Object fontname = font->props[FONT_NAME_INDEX];
+      unsigned code = face->font->driver->encode_char (face->font, c);
+      Lisp_Object 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;
+      XSETFONT (font_object, face->font);
       if (cod <= MOST_POSITIVE_FIXNUM)
-       return Fcons (fontname, make_number (code));
-      return Fcons (fontname, Fcons (make_number (code >> 16),
+       return Fcons (font_object, make_number (code));
+      return Fcons (font_object, Fcons (make_number (code >> 16),
                                     make_number (code & 0xFFFF)));
     }
   return Qnil;
@@ -1803,7 +1788,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
 
 DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
        doc: /* Return information about a fontset FONTSET on frame FRAME.
-The value is a char-table of which elements has this form.
+The value is a char-table whose elements have this form:
 
     ((FONT-PATTERN OPENED-FONT ...) ...)
 
@@ -1817,7 +1802,7 @@ OPENED-FONT is a name of a font actually opened.
 
 The char-table has one extra slot.  The value is a char-table
 containing the information about the derived fonts from the default
-fontset.  The format is the same as abobe.  */)
+fontset.  The format is the same as above.  */)
      (fontset, frame)
      Lisp_Object fontset, frame;
 {
@@ -1871,13 +1856,11 @@ fontset.  The format is the same as abobe.  */)
     {
       for (c = 0; c <= MAX_CHAR; )
        {
-         int from, to;
+         int from = c, to = MAX_5_BYTE_CHAR;
 
          if (c <= MAX_5_BYTE_CHAR)
            {
              val = char_table_ref_and_range (fontsets[k], c, &from, &to);
-             if (to > MAX_5_BYTE_CHAR)
-               to = MAX_5_BYTE_CHAR;
            }
          else
            {
@@ -1895,7 +1878,7 @@ fontset.  The format is the same as abobe.  */)
                                 alist);
              alist = Fnreverse (alist);
 
-             /* Then store opend font names to cdr of each elements.  */
+             /* Then store opened font names to cdr of each elements.  */
              for (i = 0; ! NILP (realized[k][i]); i++)
                {
                  if (c <= MAX_5_BYTE_CHAR)
@@ -1931,7 +1914,7 @@ fontset.  The format is the same as abobe.  */)
              for (; CONSP (alist); alist = XCDR (alist))
                {
                  elt = XCAR (alist);
-                 XSETCAR (elt, Ffont_xlfd_name (XCAR (elt)));
+                 XSETCAR (elt, Ffont_xlfd_name (XCAR (elt), Qnil));
                }
            }
          c = to + 1;
@@ -2099,32 +2082,10 @@ syms_of_fontset ()
   auto_fontset_alist = Qnil;
   staticpro (&auto_fontset_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)),
-where ENCODING is a charset or a char-table,
-and REPERTORY is a charset, a char-table, or nil.
-
-If ENCDING and REPERTORY are the same, the element can have the form
-\(REGEXP . ENCODING).
-
-ENCODING is for converting a character to a glyph code of the font.
-If ENCODING is a charset, encoding a character by the charset gives
-the corresponding glyph code.  If ENCODING is a char-table, looking up
-the table by a character gives the corresponding glyph code.
-
-REPERTORY specifies a repertory of characters supported by the font.
-If REPERTORY is a charset, all characters beloging to the charset are
-supported.  If REPERTORY is a char-table, all characters who have a
-non-nil value in the table are supported.  It REPERTORY is nil, Emacs
-gets the repertory information by an opened font and ENCODING.  */);
-  Vfont_encoding_alist = Qnil;
-
   DEFVAR_LISP ("font-encoding-charset-alist", &Vfont_encoding_charset_alist,
               doc: /*
 Alist of charsets vs the charsets to determine the preferred font encoding.
-Each element looks like (CHARSET . ENCDOING-CHARSET),
+Each element looks like (CHARSET . ENCODING-CHARSET),
 where ENCODING-CHARSET is a charset registered in the variable
 `font-encoding-alist' as ENCODING.
 
@@ -2136,7 +2097,7 @@ whose encoding corresponds to ENCODING-CHARSET is preferred.  */);
               doc: /*
 Char table of characters whose ascent values should be ignored.
 If an entry for a character is non-nil, the ascent value of the glyph
-is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
+is assumed to be specified by _MULE_DEFAULT_ASCENT property of a font.
 
 This affects how a composite character which contains
 such a character is displayed on screen.  */);
@@ -2144,7 +2105,7 @@ such a character is displayed on screen.  */);
 
   DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
               doc: /*
-Char table of characters which is not composed relatively.
+Char table of characters which are not composed relatively.
 If an entry for a character is non-nil, a composition sequence
 which contains that character is displayed so that
 the glyph of that character is put without considering
@@ -2177,7 +2138,6 @@ at the vertical center of lines.  */);
   defsubr (&Squery_fontset);
   defsubr (&Snew_fontset);
   defsubr (&Sset_fontset_font);
-  defsubr (&Sfont_info);
   defsubr (&Sinternal_char_font);
   defsubr (&Sfontset_info);
   defsubr (&Sfontset_font);