Subject: bug#2667: Still seeing inconsistent fonts

From: Stefan Monnier <[email-masked]>
Date: Wed, 20 May 2009 15:43:00 -0400

> ∀ belongs to `symbol' script, but the xfont backend didn't
> support :script font property.  That is because I was afraid
> that it made the font listing extremely slow (we must open
> all iso10646-1 fonts to check if it supports the requested
> characters).  Actually my trial implementation of :script
> property supports took more than 1 minute to display HELLO
> file.

1 minute would be a problem, indeed.

> But, if we can use this heuristic:

>    X fonts that have the same property values except for
>    size related properties supports the same set of
>    characters on all display.  For example, all these fonts 

> -adobe-courier-medium-r-normal--8-80-75-75-m-50-iso10646-1
> -adobe-courier-medium-r-normal--10-100-75-75-m-60-iso10646-1
> -adobe-courier-medium-r-normal--11-80-100-100-m-60-iso10646-1
> -adobe-courier-medium-r-normal--12-120-75-75-m-70-iso10646-1
> -adobe-courier-medium-r-normal--14-100-100-100-m-90-iso10646-1
> -adobe-courier-medium-r-normal--14-140-75-75-m-90-iso10646-1
> -adobe-courier-medium-r-normal--17-120-100-100-m-100-iso10646-1
> -adobe-courier-medium-r-normal--18-180-75-75-m-110-iso10646-1
> -adobe-courier-medium-r-normal--20-140-100-100-m-110-iso10646-1
> -adobe-courier-medium-r-normal--24-240-75-75-m-150-iso10646-1
> -adobe-courier-medium-r-normal--25-180-100-100-m-150-iso10646-1
> -adobe-courier-medium-r-normal--34-240-100-100-m-200-iso10646-1

>    suports the same set of characters.

That assumption is obviously not guaranteed to hold, and I don't think
it really holds in practice, but it looks like an acceptable tradeoff,
since the cases where it doesn't hold shouldn't be too frequent.

> we can list fonts in a realistic time.  Attached is the
> patch to try it.  Could you please test it?  As the change
> is not simple, I have not yet installed it.

I tried it on my smallest machine, and it seems fast enough: C-h h takes
approximately the same amount of time with it than it did under Emacs-22.3
(around 3s to 4s).
[ And this even though the Emacs-22.3 I used was built with -O2 and
  such, whereas my Emacs-CVS is built with -O1, USE_LISP_UNION_TYPE,
  ENABLE_CHECKING, and a few additional runtime tests.  ]

The machines I used to test it were all running Debian testing, with
a fairly standard set of fonts.  I don't know how it would behave for
people with many more fonts installed (most of which would presumably
be scalable and hence wouldn't be affected by the heuristic).

> -static Lisp_Object xfont_list_pattern P_ ((Lisp_Object, Display *, char *));
> +static int xfont_chars_supported P_ ((Lisp_Object, XFontStruct *,
> +				      struct charset *, struct charset *));

Please just use ANSI-style declarations rather than K&R in new code.

> +  /* Two special cases to avoid opening rather big fonts.  */
> +  if (AREF (props, 2), Qja)
> +    return Fcons (intern ("kana"), Fcons (intern ("han"), Qnil));
> +  if (AREF (props, 2), Qko)
> +    return Fcons (intern ("hangul"), Qnil);

You need EQ (..) around those two tests.

> +  if (NILP (val))
> +    script = Qnil;
> +  else
> +    script = XCDR (val);

Aka: script = CDR (val);

> +  if (! repertory && NILP (xfont_scripts_cache))
> +    {
> +      Lisp_Object args[2];
> +
> +      args[0] = QCtest;
> +      args[1] = Qequal;
> +      xfont_scripts_cache = Fmake_hash_table (2, args);
> +    }
[...]
> @@ -996,6 +1173,8 @@
>  void
>  syms_of_xfont ()
>  {
> +  staticpro (&xfont_scripts_cache);
> +  xfont_scripts_cache = Qnil;
>    xfont_driver.type = Qx;
>    register_font_driver (&xfont_driver, NULL);
>  }

Why not just:

@@ -996,6 +1173,8 @@
 void
 syms_of_xfont ()
 {
+  staticpro (&xfont_scripts_cache);
+  {
+    Lisp_Object args[2];
+    args[0] = QCtest;
+    args[1] = Qequal;
+    xfont_scripts_cache = Fmake_hash_table (2, args);
+  }
   xfont_driver.type = Qx;
   register_font_driver (&xfont_driver, NULL);
 }

        Stefan