Include coding.h and termhooks.h.
[bpt/emacs.git] / src / fontset.c
index edcbaa6..701ab66 100644 (file)
@@ -1,8 +1,8 @@
 /* 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
@@ -50,9 +50,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #ifdef HAVE_NS
 #include "nsterm.h"
 #endif
-#ifdef MAC_OS
-#include "macterm.h"
-#endif
 #include "termhooks.h"
 
 #include "font.h"
@@ -92,7 +89,8 @@ EXFUN (Fclear_face_cache, 1);
    An element of a base fontset is a vector of FONT-DEFs which itself
    is a vector [ FONT-SPEC ENCODING REPERTORY ].
 
-   An element of a realized fontset is nil, t, or a vector of this form:
+   An element of a realized fontset is nil, t, 0, or a vector of this
+   form:
 
        [ CHARSET-ORDERED-LIST-TICK PREFERRED-RFONT-DEF
          RFONT-DEF0 RFONT-DEF1 ... ]
@@ -110,6 +108,10 @@ EXFUN (Fclear_face_cache, 1);
    The value t means that no font is available for the corresponding
    range of characters.
 
+   The value 0 means that no font is available for the corresponding
+   range of characters in this fontset, but may be available in the
+   default fontset.
+
 
    A fontset has 9 extra slots.
 
@@ -355,9 +357,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));
@@ -422,16 +423,16 @@ reorder_font_vector (font_group, font)
 
       if (! font_match_p (font_spec, font_object))
        {
-         Lisp_Object repertory = FONT_DEF_REPERTORY (font_def);
+         Lisp_Object encoding = FONT_DEF_ENCODING (font_def);
 
-         if (! NILP (repertory))
+         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 (repertory, XCAR (tail)))
+               if (EQ (encoding, XCAR (tail)))
                  break;
            }
          else
@@ -463,7 +464,7 @@ fontset_get_font_group (Lisp_Object fontset, int c)
 {
   Lisp_Object font_group;
   Lisp_Object base_fontset;
-  int from, to, i;
+  int from = 0, to = MAX_CHAR, i;
 
   xassert (! BASE_FONTSET_P (fontset));
   if (c >= 0)
@@ -478,7 +479,11 @@ fontset_get_font_group (Lisp_Object fontset, int c)
   else
     font_group = FONTSET_FALLBACK (base_fontset);
   if (NILP (font_group))
-    return Qnil;
+    {
+      if (c >= 0)
+       char_table_set_range (fontset, from, to, make_number (0));
+      return Qnil;
+    }
   font_group = Fcopy_sequence (font_group);
   for (i = 0; i < ASIZE (font_group); i++)
     if (! NILP (AREF (font_group, i)))
@@ -519,13 +524,13 @@ fontset_find_font (fontset, c, face, id, fallback)
      int id, fallback;
 {
   Lisp_Object elt, vec, font_group;
-  int i;
-  FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset));
-  int charset_matched = -1;
+  int i, charset_matched = -1;
+  FRAME_PTR f = (FRAMEP (FONTSET_FRAME (fontset)))
+    ? XFRAME (selected_frame) : XFRAME (FONTSET_FRAME (fontset));
 
   font_group = fontset_get_font_group (fontset, fallback ? -1 : c);
   if (! CONSP (font_group))
-    return Qnil;
+    return font_group;
   vec = XCDR (font_group);
   if (ASIZE (vec) == 0)
     return Qnil;
@@ -700,7 +705,7 @@ fontset_font (fontset, c, face, id)
        return rfont_def;
     }
 
-  /* Remeber that we have no font for C.  */
+  /* Remember that we have no font for C.  */
   FONTSET_SET (fontset, make_number (c), Qt);
 
   return Qnil;
@@ -875,11 +880,15 @@ 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));
@@ -887,25 +896,27 @@ face_for_char (f, face, c, pos, object)
   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;
 
-         val = assoc_no_quit (charset, Vfont_encoding_charset_alist);
+         val = assq_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);
   if (VECTORP (rfont_def))
     {
@@ -935,6 +946,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 = assq_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.
@@ -1804,13 +1865,11 @@ fontset.  The format is the same as above.  */)
     {
       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
            {
@@ -1905,6 +1964,8 @@ patterns.  */)
        if (VECTORP (elt))
          for (j = 0; j < ASIZE (elt); j++)
            {
+             Lisp_Object family, registry;
+
              val = AREF (elt, j);
              repertory = AREF (val, 1);
              if (INTEGERP (repertory))
@@ -1920,7 +1981,14 @@ patterns.  */)
                    continue;
                }
              val = AREF (val, 0);
-             val = Fcons (AREF (val, 0), AREF (val, 5));
+             /* VAL is a FONT-SPEC */
+             family = AREF (val, FONT_FAMILY_INDEX);
+             if (! NILP (family))
+               family = SYMBOL_NAME (family);
+             registry = AREF (val, FONT_REGISTRY_INDEX);
+             if (! NILP (registry))
+               registry = SYMBOL_NAME (registry);
+             val = Fcons (family, registry);
              if (NILP (all))
                return val;
              list = Fcons (val, list);