bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#21028: Slow font rendering in emacs


From: Ralf Jung
Subject: bug#21028: Slow font rendering in emacs
Date: Tue, 14 Mar 2017 20:39:56 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0

Hi,

>> Well, maybe it makes little sense to you -- however, this requires
>> expert knowledge about unicode blocks.  I don't have that knowledge, and
>> I think it is a bug if configuring a straight-forward fallback chain of
>> fonts requires such knowledge.
> 
> I don't think there's a bug here.  Fontsets are complex and delicate
> means of customizing how Emacs looks for fonts, so using them does
> require expert knowledge.  Emacs believes the specifications in the
> fontset blindly, so a misconfigured fontset could cause a real
> slowdown.
> 
> The way we try to solve these issues is by having Emacs DTRT by
> default, at least on most modern platforms.  Emacs 25.1 made a
> significant step forward in this regard.  If that's still not enough,
> then the way to improve that is to describe your needs and installed
> fonts, and ask for a fontset that would exist in Emacs by default,
> which will do what you (and presumably others) would want.
> 
> IOW, the way to fix this is to augment the existing default fonts or
> maybe create an additional ready-to-be-used fontset that users could
> simply tell Emacs to use, without any tinkering.

I think we can agree that ideally, the default should DTRT.
Unfortunately, I noticed no change when upgrading to Emacs 25; that may
be because of which exact fonts I have installed.

>> Anyway, I just tried the above, and the result is that things are just
>> as slow as with my previous "bad" setup.  And this time, I honestly
>> can't think of a clearer / more sensible way to tell emacs that these
>> are the fonts I (mainly) want to use for unicode characters.
> 
> The more sensible way is to specify explicit ranges of codepoints
> where you want certain fonts, and leave the rest to the defaults.

Well, IMHO it is not very sensible to do this manually.  For example,
the supported codepoint ranges of the fonts won't change during the
runtime of Emacs, so Emacs could perfectly well build a more refined
per-block fallback cascade from the coarse-grained information I provide
(essentially caching the information whether a font supports no, some,
or all characters of any given block).

>> How can searching two fonts take so much time?
> 
> They are searched many times, including their variants.
> 
>> 95% of the characters in
>> my document are present in Fira Sans, and only about 0.1% of the
>> characters (I am guessing here, I suspect actually it's even less) are
>> present in neither DejaVu nor Fira Sans.  So having these two fonts
>> first should result in very quick, successful lookups.
> 
> These lookups are done many times, and Emacs also looks in other fonts
> on your system, because the above fontset specification doesn't remove
> all the other fonts that are in the fontset.  IOW, your spec is too
> general, and thus doesn't allow Emacs to efficiently zero in on the
> font you want in each case.

Oh, I would be happy if there was a way to remove all the other fonts
from the fontsets.  Then at least I could be sure that there's not one
or two random characters left for which it still picks TeX Gyre or
whatever other random font I happen to have installed -- or maybe that
font is picked only when I select the character, or so.  I suppose I
wouldn't even need to add my fonts to multiple fontsets then for them to
actually have any effect.

Of course I would be even more happy if I wouldn't have to do anything.

>>> Try this instead:
>>>
>>>   (set-fontset-font "fontset-default" 'greek
>>>                     (font-spec :name "DejaVu Sans Mono"
>>>                 :size 11.0 :registry "iso10646-1") nil 'prepend)
>>>   (set-fontset-font "fontset-default" 'cyrillic
>>>                     (font-spec :name "DejaVu Sans Mono"
>>>                 :size 11.0 :registry "iso10646-1") nil 'prepend)
>>>   (set-fontset-font "fontset-default" 'latin
>>>                     (font-spec :name "DejaVu Sans Mono"
>>>                 :size 11.0 :registry "iso10646-1") nil 'prepend)
>>>   (set-fontset-font "fontset-default" 'greek
>>>                     (font-spec :name "Monospace"
>>>                 :size 11.0 :registry "iso10646-1") nil 'prepend)
>>>   (set-fontset-font "fontset-default" 'cyrillic
>>>                     (font-spec :name "Monospace"
>>>                 :size 11.0 :registry "iso10646-1") nil 'prepend)
>>>   (set-fontset-font "fontset-default" 'latin
>>>                     (font-spec :name "Monospace"
>>>                 :size 11.0 :registry "iso10646-1") nil 'prepend)
>>>   (set-fontset-font t nil (font-spec :name "Symbola"
>>>                                      :size 11.0 :registry "iso10646-1")
>>>                           nil 'append)
>>
>> With this configuration, emacs picks STIX to render ∃.  It also picks
>> "DejaVu Math TeX Gyre" for ↦.  This breaks the monospace grid.  Both of
>> these characters are supported by DejaVu Sans Mono.
> 
> Well, I don't really know the details of what you want to achieve, so
> the above might need some tweaking, like using explicit ranges of
> codepoints.

On a high level, what I want to achieve is for things to look like they
do in Kate/gedit. ;)  Now that's probably not very instructive, so here
is what I think these editors pick for various characters, just to give
you some examples (deduced by checking that the characters look the same
in emacs and Kate, and then asking emacs which font it used):

all basic ASCII, Latin, Greek characters: Fira Sans Mono
→  Fira Sans Mono
∃  DejaVu Mono (not supported by Fira, it seems)
∀  DejaVu Mono (not supported by Fira, it seems)
∗  DejaVu Mono (not supported by Fira, it seems)
⋅  DejaVu Mono (not supported by Fira, it seems)

Of course this is just an excerpt of the characters we use.  From all I
can tell, the general rule is "if the character is supported by Fira,
use that font; else of it is supported by DejaVu, use that font; else do
<no idea what it does>"

>> You say these fonts support only Latin, Cyrillic and Greek -- but for
>> example Fira Sans Mono supports → and … and ↑, and DejaVu Mono supports
>> ∃ and ↦ and ▷.  Are these all in one of these ranges?
> 
> No.  But the rest of the blocks are covered only very partially,

Wait -- if Fira already covers the entire Latic, Greek and Cyrillic
range, how can it make any sense to even have a fallback to DejaVu here?
 I thought the entire purpose of these fallback chains was to deal with
fonts supporting random characters in some blocks, so that one cannot
tell in advance exactly which font to use for which block.
So, maybe I could figure out which 2 or 3 unicode blocks all the special
characters are in, and then I could set up Fira followed by DejaVu just
for these blocks.  Then I could have emacs pick the fonts I want without
being slow.
Of course, I already have a configuration that picks the fonts I want
and is not slow -- and the one I have doesn't even require me to
maintain a list of unicode blocks we use, which is a clear advantage.

> so my
> suggestion would be to find a single monospaced font that covers the
> other characters (symbols and punctuation), and use only it, instead
> of having some of them displayed by one font and the rest by another
> (and probably quite a few not covered by any of them).

I don't think the font is to blame here.  After all, other applications
manage to deal with exactly the same fonts just fine.
Unfortunately, I don't know *how* everybody else is selecting fonts, I
only know they do a better job at it than emacs, and they have no
problem dealing with fonts that only partially support some blocks.
Probably fontconfig is doing most of the work here, but I am really just
guessing.

Kind regards,
Ralf





reply via email to

[Prev in Thread] Current Thread [Next in Thread]