Subject: bug#43177: Bug: Emacs 27.1 hangs forever in `FcCharSetSubtractCount' from '/usr/lib/libfontconfig.so.1'

From: Robert Pluim <[email-masked]>
Date: Mon, 07 Sep 2020 16:18:07 +0200

>>>>> On Fri, 04 Sep 2020 20:26:15 +0300, Eli Zaretskii <[email-masked]> said:

    >> From: Robert Pluim <[email-masked]>
    >> Cc: [email-masked],  [email-masked],
    >> [email-masked]
    >> Date: Fri, 04 Sep 2020 16:04:35 +0200
    >> 
    Eli> Shouldn't we query those other backends if the first one couldn't find
    Eli> a font, even if the variable is nil?  Otherwise, this change could
    Eli> cause regressions in some (hopefully rare) cases, whereby some
    Eli> characters will display as hex codes where previously they were shown
    Eli> using some font.
    >> Thatʼs what this does.

    Eli> Then I guess we should install it.

If anyone wants me to change the name or the verbiage, speak up,
otherwise Iʼll push this tomorrow.

diff --git a/etc/NEWS b/etc/NEWS
index f0644c8ea9..f45cb86175 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -98,7 +98,14 @@ specify 'cursor-type' to be '(box . SIZE)', the cursor becomes a hollow
 box if the point is on an image larger than 'SIZE' pixels in any
 dimension.
 
-+++
+** Fonts are no longer always searched for in all available backends.
+Previously, when looking for a matching font, Emacs would check all
+the available font backends, even if it had already found a match.
+This could cause slowdowns with large numbers of fonts installed, and
+in most cases the font found by later backends was never used.  This
+behavior can be changed by setting 'font-query-all-backends' to t.
+
++++ 
 ** New user option 'word-wrap-by-category'.
 When word-wrap is enabled, and this option is non-nil, that allows
 Emacs to break lines after more characters than just whitespace
diff --git a/src/font.c b/src/font.c
index 2786a772dc..779b852096 100644
--- a/src/font.c
+++ b/src/font.c
@@ -2810,7 +2810,13 @@ font_list_entities (struct frame *f, Lisp_Object spec)
 		|| ! NILP (Vface_ignored_fonts)))
 	  val = font_delete_unmatched (val, need_filtering ? spec : Qnil, size);
 	if (ASIZE (val) > 0)
-	  list = Fcons (val, list);
+          {
+            list = Fcons (val, list);
+            /* Querying further backends can be very slow, so we only do
+               it if the user has explicitly requested it (Bug#43177).  */
+            if (query_all_font_backends == false)
+              break;
+          }
       }
 
   list = Fnreverse (list);
@@ -5527,6 +5533,13 @@ syms_of_font (void)
 cause Xft crashes.  Only has an effect in Xft builds.  */);
   xft_ignore_color_fonts = true;
 
+  DEFVAR_BOOL ("query-all-font-backends", query_all_font_backends,
+               doc: /*
+If non-nil attempt to query all available font backends.
+By default Emacs will stop searching for a matching font at the first
+match.  */);
+  query_all_font_backends = false;
+
 #ifdef HAVE_WINDOW_SYSTEM
 #ifdef HAVE_FREETYPE
   syms_of_ftfont ();