Subject: bug#52888: 29.0.50; font_{delete_unmatched,score} do not handle nil FONT_WEIGHT_INDEX

From: Sean Whitton <[email-masked]>
Date: Thu, 06 Jan 2022 11:10:12 -0700

Hello,

On Thu 06 Jan 2022 at 02:29PM +02, Eli Zaretskii wrote:

> OK, but (a) we need a comment there explaining why FC_VARIABLE is used
> as the condition, and (b) we'd also need to merge the temporary fix in
> font.c to master.

Here's an updated patch.  I don't think I can help with (b) but let me
know if there's something I can do.

Thanks!

-- 
Sean Whitton
>From 8f2c3b969af77e707429ac4a51fa439831c5d075 Mon Sep 17 00:00:00 2001
From: Sean Whitton <[email-masked]>
Date: Tue, 4 Jan 2022 19:07:29 -0700
Subject: [PATCH v3] Skip virtual FcPattern entries for variable weight fonts

* src/ftfont.c (ftfont_list): Pass FC_VARIABLE to FcObjectSetBuild.
* src/ftfont.c (ftfont_pattern_entity): Skip meta/virtual FcPattern
entries for variable weight fonts (Bug#52888).
---
 src/ftfont.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/src/ftfont.c b/src/ftfont.c
index 2bdcce306b..5797300d23 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -189,6 +189,24 @@ ftfont_pattern_entity (FcPattern *p, Lisp_Object extra)
     return Qnil;
   if (FcPatternGetInteger (p, FC_INDEX, 0, &idx) != FcResultMatch)
     return Qnil;
+#ifdef FC_VARIABLE
+  /* This is a virtual/meta FcPattern for a variable weight font, from
+     which it is possible to extract an FcRange value specifying the
+     minimum and maximum weights available in this file.  We don't
+     need to know that information explicitly, so skip it.  We will be
+     called with an FcPattern for each actually available, non-virtual
+     weight.
+
+     Fontconfig started generating virtual/meta patterns for variable
+     weight fonts in the same release that FC_VARIABLE was added, so
+     we conditionalize on that constant.  This also ensures that
+     FcPatternGetRange is available.  */
+  FcRange *range;
+  if (FcPatternGetRange (p, FC_WEIGHT, 0, &range) == FcResultMatch
+      && FcPatternGetBool (p, FC_VARIABLE, 0, &b) == FcResultMatch
+      && b == FcTrue)
+    return Qnil;
+#endif	/* FC_VARIABLE */
 
   file = (char *) str;
   key = Fcons (build_unibyte_string (file), make_fixnum (idx));
@@ -863,6 +881,9 @@ ftfont_list (struct frame *f, Lisp_Object spec)
 #if defined HAVE_XFT && defined FC_COLOR
                              FC_COLOR,
 #endif
+#ifdef FC_VARIABLE
+			     FC_VARIABLE,
+#endif	/* FC_VARIABLE */
 			     NULL);
   if (! objset)
     goto err;
-- 
2.30.2