]> code.delx.au - gnu-emacs/blobdiff - src/xfont.c
Fix an error in Tramp for rsync
[gnu-emacs] / src / xfont.c
index 10cc321b60cd8eb5f7dfb9837d7b6c3494511f88..8fbe94c01abecac425b6fa3f76a01c1c5eeaebc3 100644 (file)
@@ -1,5 +1,5 @@
 /* xfont.c -- X core font driver.
-   Copyright (C) 2006-2015 Free Software Foundation, Inc.
+   Copyright (C) 2006-2016 Free Software Foundation, Inc.
    Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H13PRO009
@@ -8,8 +8,8 @@ This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -24,15 +24,12 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <X11/Xlib.h>
 
 #include "lisp.h"
-#include "dispextern.h"
 #include "xterm.h"
 #include "frame.h"
 #include "blockinput.h"
 #include "character.h"
 #include "charset.h"
-#include "fontset.h"
 #include "font.h"
-#include "ccl.h"
 
 \f
 /* X core font driver.  */
@@ -132,7 +129,7 @@ static int xfont_check (struct frame *, struct font *);
 struct font_driver xfont_driver =
   {
     LISP_INITIALLY_ZERO,       /* Qx */
-    0,                         /* case insensitive */
+    false,                     /* case insensitive */
     xfont_get_cache,
     xfont_list,
     xfont_match,
@@ -269,7 +266,7 @@ xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
        }
       return (i >= 0);
     }
-  return 0;
+  return false;
 }
 
 /* A hash table recoding which font supports which scripts.  Each key
@@ -394,88 +391,101 @@ xfont_list_pattern (Display *display, const char *pattern,
        indices[i] = names[i];
       qsort (indices, num_fonts, sizeof (char *), compare_font_names);
 
-      for (i = 0; i < num_fonts; i++)
-       {
-         ptrdiff_t len;
+      /* Take one or two passes over the font list.  Do the second
+        pass only if we really need it, i.e., only if the first pass
+        found no fonts and skipped some scalable fonts.  */
+      bool skipped_some_scalable_fonts = false;
+      for (int i_pass = 0;
+          (i_pass == 0
+           || (i_pass == 1 && NILP (list) && skipped_some_scalable_fonts));
+          i_pass++)
+       for (i = 0; i < num_fonts; i++)
+         {
+           ptrdiff_t len;
+
+           if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
+             continue;
+           if (NILP (entity))
+             entity = font_make_entity ();
+           len = xfont_decode_coding_xlfd (indices[i], -1, buf);
+           if (font_parse_xlfd (buf, len, entity) < 0)
+             continue;
+           ASET (entity, FONT_TYPE_INDEX, Qx);
+           /* Avoid auto-scaled fonts.  */
+           if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
+               && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
+               && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
+               && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
+             continue;
+           /* Avoid not-allowed scalable fonts.  */
+           if (NILP (Vscalable_fonts_allowed))
+             {
+               int size = 0;
 
-         if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
-           continue;
-         if (NILP (entity))
-           entity = font_make_entity ();
-         len = xfont_decode_coding_xlfd (indices[i], -1, buf);
-         if (font_parse_xlfd (buf, len, entity) < 0)
-           continue;
-         ASET (entity, FONT_TYPE_INDEX, Qx);
-         /* Avoid auto-scaled fonts.  */
-         if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
-             && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
-             && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
-             && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
-           continue;
-         /* Avoid not-allowed scalable fonts.  */
-         if (NILP (Vscalable_fonts_allowed))
-           {
-             int size = 0;
+               if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
+                 size = XINT (AREF (entity, FONT_SIZE_INDEX));
+               else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
+                 size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
+               if (size == 0 && i_pass == 0)
+                 {
+                   skipped_some_scalable_fonts = true;
+                   continue;
+                 }
+             }
+           else if (CONSP (Vscalable_fonts_allowed))
+             {
+               Lisp_Object tail;
 
-             if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
-               size = XINT (AREF (entity, FONT_SIZE_INDEX));
-             else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
-               size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
-             if (size == 0)
-               continue;
-           }
-         else if (CONSP (Vscalable_fonts_allowed))
-           {
-             Lisp_Object tail, elt;
-
-             for (tail = Vscalable_fonts_allowed; CONSP (tail);
-                  tail = XCDR (tail))
-               {
-                 elt = XCAR (tail);
-                 if (STRINGP (elt)
-                     && fast_c_string_match_ignore_case (elt, indices[i],
-                                                         len) >= 0)
-                   break;
-               }
-             if (! CONSP (tail))
-               continue;
-           }
+               for (tail = Vscalable_fonts_allowed; CONSP (tail);
+                    tail = XCDR (tail))
+                 {
+                   Lisp_Object elt = XCAR (tail);
+                   if (STRINGP (elt)
+                       && (fast_c_string_match_ignore_case (elt, indices[i],
+                                                            len)
+                           >= 0))
+                     break;
+                 }
+               if (! CONSP (tail))
+                 continue;
+             }
 
-         /* Avoid fonts of invalid registry.  */
-         if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
-           continue;
+           /* Avoid fonts of invalid registry.  */
+           if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
+             continue;
 
-         /* Update encoding and repertory if necessary.  */
-         if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
-           {
-             registry = AREF (entity, FONT_REGISTRY_INDEX);
-             if (font_registry_charsets (registry, &encoding, &repertory) < 0)
-               encoding = NULL;
-           }
-         if (! encoding)
-           /* Unknown REGISTRY, not supported.  */
-           continue;
-         if (repertory)
-           {
-             if (NILP (script)
-                 || xfont_chars_supported (chars, NULL, encoding, repertory))
-               list = Fcons (entity, list), entity = Qnil;
+           /* Update encoding and repertory if necessary.  */
+           if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
+             {
+               registry = AREF (entity, FONT_REGISTRY_INDEX);
+               if (font_registry_charsets (registry, &encoding, &repertory) < 0)
+                 encoding = NULL;
+             }
+           if (! encoding)
+             /* Unknown REGISTRY, not supported.  */
              continue;
-           }
-         if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
-                     word_size * 7)
-             || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
-           {
-             vcopy (xfont_scratch_props, 0,
-                    aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
-             ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
-             scripts = xfont_supported_scripts (display, indices[i],
-                                                xfont_scratch_props, encoding);
-           }
-         if (NILP (script)
-             || ! NILP (Fmemq (script, scripts)))
-           list = Fcons (entity, list), entity = Qnil;
-       }
+           if (repertory)
+             {
+               if (NILP (script)
+                   || xfont_chars_supported (chars, NULL, encoding, repertory))
+                 list = Fcons (entity, list), entity = Qnil;
+               continue;
+             }
+           if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
+                       word_size * 7)
+               || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
+             {
+               vcopy (xfont_scratch_props, 0,
+                      aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
+               ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
+               scripts = xfont_supported_scripts (display, indices[i],
+                                                  xfont_scratch_props,
+                                                  encoding);
+             }
+           if (NILP (script)
+               || ! NILP (Fmemq (script, scripts)))
+             list = Fcons (entity, list), entity = Qnil;
+         }
       XFreeFontNames (names);
     }
 
@@ -625,7 +635,7 @@ xfont_list_family (struct frame *f)
   char **names;
   int num_fonts, i;
   Lisp_Object list;
-  char *last_family IF_LINT (= 0);
+  char *last_family UNINIT;
   int last_len;
 
   block_input ();
@@ -983,7 +993,7 @@ xfont_text_extents (struct font *font, unsigned int *code,
   int i, width = 0;
   bool first;
 
-  for (i = 0, first = 1; i < nglyphs; i++)
+  for (i = 0, first = true; i < nglyphs; i++)
     {
       XChar2b char2b;
       static XCharStruct *pcm;
@@ -1000,7 +1010,7 @@ xfont_text_extents (struct font *font, unsigned int *code,
          metrics->rbearing = pcm->rbearing;
          metrics->ascent = pcm->ascent;
          metrics->descent = pcm->descent;
-         first = 0;
+         first = false;
        }
       else
        {
@@ -1106,13 +1116,7 @@ void
 syms_of_xfont (void)
 {
   staticpro (&xfont_scripts_cache);
-  { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
-       is called fairly late, when QCtest and Qequal are known to be set.  */
-    Lisp_Object args[2];
-    args[0] = QCtest;
-    args[1] = Qequal;
-    xfont_scripts_cache = Fmake_hash_table (2, args);
-  }
+  xfont_scripts_cache = CALLN (Fmake_hash_table, QCtest, Qequal);
   staticpro (&xfont_scratch_props);
   xfont_scratch_props = Fmake_vector (make_number (8), Qnil);
   xfont_driver.type = Qx;