Subject: Re: bug#30874: 27.0.50; Emacs crashes

From: Robert Pluim <[email-masked]>
Date: Fri, 30 Mar 2018 12:36:45 +0200

Eli Zaretskii <[email-masked]> writes:

>> As I understand it, we should use fontconfig for finding fonts,
>> harfbuzz for doing the layout, and cairo to actually render the
>> result
>
> Does harfbuzz require Cairo?  If it does, that's unfortunate, because
> the Cairo rendering option currently has a few known and annoying
> redisplay bugs, which no one seems to be willing/capable of fixing.

Until someone fixes
<https://debbugs.gnu.org/cgi/bugreport.cgi?bug=20890>, Cairo is
basically unusable for me even without the redisplay issues.

>> plus itʼs Emacs redisplay, which Iʼm told is scary
>
> Don't believe the rumors too much.  Besides, adding a font backend
> doesn't require to mess with the display code in any way, all you need
> is implement the interfaces you see documented in 'struct font_driver'
> defined in font.h (reusing the methods of existing backends where
> appropriate, as xftfont does with ftfont methods); all the rest is
> already taken care of in the infrastructure.  The only interface
> between font back-end methods and the display engine is via 'struct
> glyph_string', which is a relatvely simple data structure.
>
>> I do note we have an Xft font backend, a freetype one, and a
>> freetype+cairo one already, which seems excessive.
>
> You forgot xfont and freetype-without-XFT.  It could be that we could
> remove some of them, but I don't know which ones are used and how
> much.  And freetype+cairo is not used much because of the Cairo
> problems.

I suspect Xft is the only one really used, since freetype-without-xft
is disabled if I read configure.ac right. Freetype + cairo is the one
we should probably target, as Xft used direct X calls which will stop
working once the world moves to Wayland.

>> > As a stopgap, I think we should find a way of ignoring the problematic
>> > fonts.  Is there some way of detecting them?
>> 
>> You mean short of running ftfont_get_bitmap over every available
>> codepoint in the font and skipping it if the resulting width * height
>> is > 4096 [1]?  That would probably detect a problematic font pretty
>> quickly, but is not very elegant. Also Iʼm not sure we get to
>> intervene before Xft decides that it needs to fall back to that font.
>
> AFAIK, there's no "fallback" per se.  Whenever the already-loaded
> fonts don't support a character, Emacs looks for the fonts that do
> using the "match" method.  If we always fail these fonts in that
> method, they will never be used.

Yes, I was confused about what was happening. This explains why I was
not getting Symbola as well: that font doesnʼt have a glyph for #x274c

>> > AFAICT, we could do that
>> > either in ftfont_match or in its subroutine ftfont_spec_pattern.  We
>> > could then pretend that these fonts don't match any font spec, perhaps
>> > subject to some variable (which would provide a 'fire escape"), which
>> > I think would fix the problem.
>> 
>> Iʼm hoping that matching on something like !'family emoji' would work,
>> although Iʼve not figured out how to express that in fontconfig-speak.
>
> I thought there could be a way of detecting those "color bitmap fonts"
> by examining their attributes in ftfont_match and/or
> ftfont_spec_pattern.  Then we could return a failure indication for
> them.

So the pattern returned from fontconfig doesnʼt indicate anything
specific we could use, but itʼs possible to modify the pattern we use
for requesting. The following patch against emacs-26 fixes the crash
for me (Emacs ends up using "Noto Emoji"). Definitely not intended to
be applied to emacs-26.

modified   src/ftfont.c
@@ -764,6 +764,8 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots
   if (scalable >= 0
       && ! FcPatternAddBool (pattern, FC_SCALABLE, scalable ? FcTrue : FcFalse))
     goto err;
+  /* We really don't like color fonts, they cause Xft crashes.  */
+  FcPatternAddBool(pattern, FC_COLOR, FcFalse);
 
   goto finish;