]> code.delx.au - gnu-emacs/blobdiff - src/fontset.c
Fix crash in fontset-info
[gnu-emacs] / src / fontset.c
index ac50be1c925650ff3960b9f45333945cd56250f1..5fc92feb130b344df91a8b7c55711d393e14fc6d 100644 (file)
@@ -1,6 +1,6 @@
 /* Fontset handler.
 
-Copyright (C) 2001-2014 Free Software Foundation, Inc.
+Copyright (C) 2001-2015 Free Software Foundation, Inc.
 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
   2005, 2006, 2007, 2008, 2009, 2010, 2011
   National Institute of Advanced Industrial Science and Technology (AIST)
@@ -152,11 +152,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /********** VARIABLES and FUNCTION PROTOTYPES **********/
 
-static Lisp_Object Qfontset;
-static Lisp_Object Qfontset_info;
-static Lisp_Object Qprepend, Qappend;
-Lisp_Object Qlatin;
-
 /* Vector containing all fontsets.  */
 static Lisp_Object Vfontset_table;
 
@@ -354,16 +349,17 @@ fontset_add (Lisp_Object fontset, Lisp_Object range, Lisp_Object elt, Lisp_Objec
        from1 = from, to1 = to;
        args[idx] = char_table_ref_and_range (fontset, from, &from1, &to1);
        char_table_set_range (fontset, from, to1,
-                             NILP (args[idx]) ? args[1 - idx]
-                             : Fvconcat (2, args));
+                             (NILP (args[idx]) ? args[1 - idx]
+                              : CALLMANY (Fvconcat, args)));
        from = to1 + 1;
       } while (from < to);
     }
   else
     {
       args[idx] = FONTSET_FALLBACK (fontset);
-      set_fontset_fallback
-       (fontset, NILP (args[idx]) ? args[1 - idx] : Fvconcat (2, args));
+      set_fontset_fallback (fontset,
+                           (NILP (args[idx]) ? args[1 - idx]
+                            : CALLMANY (Fvconcat, args)));
     }
 }
 
@@ -896,18 +892,46 @@ face_for_char (struct frame *f, struct face *face, int c,
   if (ASCII_CHAR_P (c) || CHAR_BYTE8_P (c))
     return face->ascii_face->id;
 
-#ifdef HAVE_NS
-  if (face->font)
+  if (c > 0 && EQ (CHAR_TABLE_REF (Vchar_script_table, c), Qsymbol))
     {
-      /* Fonts often have characters in other scripts, like symbol, even if they
-         don't match script: symbol.  So check if the character is present
-         in the current face first.  Only enable for NS for now, but should
-         perhaps be general?  */
+      /* Fonts often have characters for punctuation and other
+         symbols, even if they don't match the 'symbol' script.  So
+         check if the character is present in the current ASCII face
+         first, and if so, use the same font as used by that face.
+         This avoids unnecessarily switching to another font when the
+         frame's default font will do.  We only do this for symbols so
+         that users could still setup fontsets to force Emacs to use
+         specific fonts for characters from other scripts, because
+         choice of fonts is frequently affected by cultural
+         preferences and font features, not by font coverage.
+         However, these considerations are unlikely to be relevant to
+         punctuation and other symbols, since the latter generally
+         aren't specific to any culture, and don't require
+         sophisticated OTF features.  */
       Lisp_Object font_object;
-      XSETFONT (font_object, face->font);
-      if (font_has_char (f, font_object, c)) return face->id;
-    }
+
+      if (face->ascii_face->font)
+       {
+         XSETFONT (font_object, face->ascii_face->font);
+         if (font_has_char (f, font_object, c))
+           return face->ascii_face->id;
+       }
+
+#if 0
+      /* Try the current face.  Disabled because it can cause
+        counter-intuitive results, whereby the font used for some
+        character depends on the characters that precede it on
+        display.  See the discussion of bug #15138.  Note that the
+        original bug reported in #15138 was in a situation where face
+        == face->ascii_face, so the above code solves that situation
+        without risking the undesirable consequences.  */
+      if (face->font)
+       {
+         XSETFONT (font_object, face->font);
+         if (font_has_char (f, font_object, c)) return face->id;
+       }
 #endif
+    }
 
   fontset = FONTSET_FROM_ID (face->fontset);
   eassert (!BASE_FONTSET_P (fontset));
@@ -1078,7 +1102,7 @@ fontset_pattern_regexp (Lisp_Object pattern)
         expression matching.  */
       ptrdiff_t regexsize = (SBYTES (pattern)
                             + (ndashes < 14 ? 2 : 5) * nstars
-                            + 2 * nescs + 1);
+                            + 2 * nescs + 3);
       USE_SAFE_ALLOCA;
       p1 = regex = SAFE_ALLOCA (regexsize);
 
@@ -1437,12 +1461,8 @@ appended.  By default, FONT-SPEC overrides the previous settings.  */)
     }
   else if (STRINGP (font_spec))
     {
-      Lisp_Object args[2];
-
       fontname = font_spec;
-      args[0] = QCname;
-      args[1] = font_spec;
-      font_spec = Ffont_spec (2, args);
+      font_spec = CALLN (Ffont_spec, QCname, fontname);
     }
   else if (FONT_SPEC_P (font_spec))
     fontname = Ffont_xlfd_name (font_spec, Qnil);
@@ -1836,7 +1856,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
       w = XWINDOW (window);
       f = XFRAME (w->frame);
       face_id = face_at_buffer_position (w, pos, &dummy,
-                                        pos + 100, 0, -1);
+                                        pos + 100, false, -1);
     }
   if (! CHAR_VALID_P (c))
     return Qnil;
@@ -1963,7 +1983,7 @@ format is the same as above.  */)
                  for (j = 0; j < ASIZE (val); j++)
                    {
                      elt = AREF (val, j);
-                     if (FONT_OBJECT_P (RFONT_DEF_OBJECT (elt)))
+                     if (!NILP (elt) && FONT_OBJECT_P (RFONT_DEF_OBJECT (elt)))
                        {
                          Lisp_Object font_object = RFONT_DEF_OBJECT (elt);
                          Lisp_Object slot, name;
@@ -2151,7 +2171,6 @@ syms_of_fontset (void)
   DEFSYM (Qfontset_info, "fontset-info");
   Fput (Qfontset_info, Qchar_table_extra_slots, make_number (1));
 
-  DEFSYM (Qprepend, "prepend");
   DEFSYM (Qappend, "append");
   DEFSYM (Qlatin, "latin");