[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same fa
From: |
Dima Kogan |
Subject: |
bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes |
Date: |
Tue, 16 Dec 2014 21:36:14 -0800 |
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Dima Kogan <dima@secretsauce.net>
>> Date: Sat, 06 Dec 2014 23:28:34 -0800
>>
>> > Put a breakpoint where Emacs loads new fonts, and see who calls that
>> > code.
>>
>> I'm digging through the code. It's slow going so far, but I'm getting
>> more familiar with it. In my init.el I have in my default-frame-alist
>>
>> (font . "-adobe-courier-medium-r-*-*-*-80-*-*-m-*-iso8859-1")
I just dumped more time into this, and have more information, some of it
(hopefully) actionable.
I just built a optimization-free copy of emacs from the latest git:
e2815bf. This uses the lucid UI. I'm on a recent Debian/sid box.
This allows me to use gdb effectively. I also have a mostly reproducible
way to both break it and to fix it with emacs -Q. I suspect this recipe
is dependent on my window manager and font setup, so it probably
wouldn't trigger failures on other boxes, but it's useful to illustrate
what I'm doing. Recipe:
1. emacs -Q --eval "(progn (custom-set-variables '(default-frame-alist '( (font
. \"-adobe-courier-medium-r-*-*-*-80-*-*-m-*-iso8859-1\")))) (kill-new
\"(face-font \\\"italic\\\")\"))"
2. M-: (face-font "italic")
The commandline eval places this string into the kill-ring so you can
simply M-: C-y, but this is a detail. I expect it to give me an
-adobe-courier font, but at this point it gives me an (ugly)
-urw-.... font. Happens about 80% of the time
3. C-x 5 2
New frame
4. Kill that new frame with my window manager
5. M-: (face-font "italic")
Same font lookup as before. This time it gives me the correct font.
I traced various parts of the data flow. Internally emacs generates a
list of candidate fonts, scores each one against the requested font
spec, and picks the font with the best score. The issue is two-fold:
- The list of candidate fonts changes over time. This is why the issue
self-corrects
- In the above recipe, the "right" font is in the list both times,
however the first (wrong) time there's another candidate in the list
that scores highly, and produces an ugly result
The top-level code flow is
font_find_for_lface() calls
font_list_entities() to get the candidate font list and
font_select_entity() to pick the best candidate; this calls
font_sort_entities() which calls
font_score() to evaluate a specific candidate
The "reference" font that font_score() is asked to match appears to
always be
#<font-spec nil nil nil nil nil medium italic normal 11 nil nil nil nil>
In font_list_entities(), need_filtering = 0 is always true.
When the incorrect font is chosen at the start I see that
font_list_entities() gets a list of fonts from the cache (not from the
driver; driver_list->driver->list() is not invoked here).
font_list_entities() returns this candidate list (a vector):
#<font-entity x adobe courier ## iso8859-1 medium r normal 8 75 100 50 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 34 100 100 200 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 25 100 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 24 75 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 20 100 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 18 75 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 17 100 100 100 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 14 75 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 14 100 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 12 75 100 70 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 11 100 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 10 75 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 0 0 0 0 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 8 75 100 50 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 34 100 100 200 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 25 100 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 24 75 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 20 100 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 18 75 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 17 100 100 100 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 14 75 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 14 100 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 12 75 100 70 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 11 100 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 10 75 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 0 0 0 0 nil>
#<font-entity x adobe courier ## iso8859-1 medium i normal 0 0 0 0 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 8 75 100 50 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 34 100 100 200 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 25 100 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 24 75 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 20 100 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 18 75 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 17 100 100 100 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 14 75 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 14 100 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 12 75 100 70 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 11 100 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 10 75 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 0 0 0 0 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 8 75 100 50 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 34 100 100 200 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 25 100 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 24 75 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 20 100 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 18 75 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 17 100 100 100 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 14 75 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 14 100 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 12 75 100 70 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 11 100 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 10 75 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 0 0 0 0 nil>
#<font-entity x adobe courier ## iso8859-1 bold i normal 0 0 0 0 nil>
font_score() is given a subset of these. Candidates and returned scores:
| font
| score |
|--------------------------------------------------------------------------------+---------|
| #<font-entity x adobe courier ## iso8859-1 medium r normal 8 75 100 50 nil>
| 393616 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 34 100 100 200
nil> | |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 25 100 100 150
nil> | |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 24 75 100 150 nil>
| |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 20 100 100 110
nil> | 1180048 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 18 75 100 110 nil>
| 917904 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 17 100 100 100
nil> | 786832 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 14 75 100 90 nil>
| 393616 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 14 100 100 90 nil>
| 393616 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 12 75 100 70 nil>
| 131472 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 11 100 100 60 nil>
| 400 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 10 75 100 60 nil>
| 131472 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 0 0 0 0 nil>
| 400 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 8 75 100 50 nil>
| 393256 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 34 100 100 200
nil> | |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 25 100 100 150
nil> | |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 24 75 100 150 nil>
| |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 20 100 100 110
nil> | 1179688 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 18 75 100 110 nil>
| 917544 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 17 100 100 100
nil> | 786472 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 14 75 100 90 nil>
| 393256 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 14 100 100 90 nil>
| 393256 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 12 75 100 70 nil>
| 131112 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 11 100 100 60 nil>
| 40 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 10 75 100 60 nil>
| 131112 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 0 0 0 0 nil>
| 40 |
| #<font-entity x adobe courier ## iso8859-1 medium i normal 0 0 0 0 nil>
| 0 |
Fonts with blank scores are disqualified. Lower scores are better, so
the last font with a score of 0 is chosen. This, unfortunately produces
poor results.
When the correct font is chosen further down in the recipe, I see that
font_list_entities() again gets a list of fonts from the cache:
#<font-entity x adobe courier ## iso8859-1 medium r normal 8 75 100 50 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 34 100 100 200 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 25 100 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 24 75 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 20 100 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 18 75 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 17 100 100 100 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 14 75 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 14 100 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 12 75 100 70 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 11 100 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 medium r normal 10 75 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 8 75 100 50 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 34 100 100 200 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 25 100 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 24 75 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 20 100 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 18 75 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 17 100 100 100 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 14 75 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 14 100 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 12 75 100 70 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 11 100 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 medium o normal 10 75 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 8 75 100 50 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 34 100 100 200 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 25 100 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 24 75 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 20 100 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 18 75 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 17 100 100 100 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 14 75 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 14 100 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 12 75 100 70 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 11 100 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 bold r normal 10 75 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 8 75 100 50 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 34 100 100 200 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 25 100 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 24 75 100 150 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 20 100 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 18 75 100 110 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 17 100 100 100 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 14 75 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 14 100 100 90 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 12 75 100 70 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 11 100 100 60 nil>
#<font-entity x adobe courier ## iso8859-1 bold o normal 10 75 100 60 nil>
and the corresponding scores:
| font
| score |
|--------------------------------------------------------------------------------+---------|
| #<font-entity x adobe courier ## iso8859-1 medium r normal 8 75 100 50 nil>
| 393616 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 34 100 100 200
nil> | |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 25 100 100 150
nil> | |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 24 75 100 150 nil>
| |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 20 100 100 110
nil> | 1180048 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 18 75 100 110 nil>
| 917904 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 17 100 100 100
nil> | 786832 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 14 75 100 90 nil>
| 393616 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 14 100 100 90 nil>
| 393616 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 12 75 100 70 nil>
| 131472 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 11 100 100 60 nil>
| 400 |
| #<font-entity x adobe courier ## iso8859-1 medium r normal 10 75 100 60 nil>
| 131472 |
| #<ont-entity x adobe courier ## iso8859-1 medium o normal 8 75 100 50 nil>
| 393256 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 34 100 100 200
nil> | |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 25 100 100 150
nil> | |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 24 75 100 150 nil>
| |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 20 100 100 110
nil> | 1179688 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 18 75 100 110 nil>
| 917544 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 17 100 100 100
nil> | 786472 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 14 75 100 90 nil>
| 393256 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 14 100 100 90 nil>
| 393256 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 12 75 100 70 nil>
| 131112 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 11 100 100 60 nil>
| 40 |
| #<font-entity x adobe courier ## iso8859-1 medium o normal 10 75 100 60 nil>
| 131112 |
| #<font-entity x adobe courier ## iso8859-1 bold r normal 8 75 100 50 nil>
| 444816 |
| #<font-entity x adobe courier ## iso8859-1 bold r normal 34 100 100 200 nil>
| |
| #<font-entity x adobe courier ## iso8859-1 bold r normal 25 100 100 150 nil>
| |
| #<font-entity x adobe courier ## iso8859-1 bold r normal 24 75 100 150 nil>
| |
| #<font-entity x adobe courier ## iso8859-1 bold r normal 20 100 100 110 nil>
| 1231248 |
| #<font-entity x adobe courier ## iso8859-1 bold r normal 18 75 100 110 nil>
| 969104 |
| #<font-entity x adobe courier ## iso8859-1 bold r normal 17 100 100 100 nil>
| 838032 |
| #<font-entity x adobe courier ## iso8859-1 bold r normal 14 75 100 90 nil>
| 444816 |
| #<font-entity x adobe courier ## iso8859-1 bold r normal 14 100 100 90 nil>
| 444816 |
| #<font-entity x adobe courier ## iso8859-1 bold r normal 12 75 100 70 nil>
| 182672 |
| #<font-entity x adobe courier ## iso8859-1 bold r normal 11 100 100 60 nil>
| 51600 |
| #<font-entity x adobe courier ## iso8859-1 bold r normal 10 75 100 60 nil>
| 182672 |
| #<font-entity x adobe courier ## iso8859-1 bold o normal 8 75 100 50 nil>
| 444456 |
| #<font-entity x adobe courier ## iso8859-1 bold o normal 34 100 100 200 nil>
| |
| #<font-entity x adobe courier ## iso8859-1 bold o normal 25 100 100 150 nil>
| |
| #<font-entity x adobe courier ## iso8859-1 bold o normal 24 75 100 150 nil>
| |
| #<font-entity x adobe courier ## iso8859-1 bold o normal 20 100 100 110 nil>
| 1230888 |
| #<font-entity x adobe courier ## iso8859-1 bold o normal 18 75 100 110 nil>
| 968744 |
| #<font-entity x adobe courier ## iso8859-1 bold o normal 17 100 100 100 nil>
| 837672 |
| #<font-entity x adobe courier ## iso8859-1 bold o normal 14 75 100 90 nil>
| 444456 |
| #<font-entity x adobe courier ## iso8859-1 bold o normal 14 100 100 90 nil>
| 444456 |
| #<font-entity x adobe courier ## iso8859-1 bold o normal 12 75 100 70 nil>
| 182312 |
| #<font-entity x adobe courier ## iso8859-1 bold o normal 11 100 100 60 nil>
| 51240 |
| #<font-entity x adobe courier ## iso8859-1 bold o normal 10 75 100 60 nil>
| 182312 |
The best font has a score of 40, and it is the "right" answer.
I'm not an expert, but it seems wrong to me that the candidate list does
not stay constant. Furthermore, it's odd that the bold fonts are not
passed to font_score() during the "bad" pass, but ARE passed to it during
the "good" pass. Furthermore, the fonts that have "0 0 0 0" all score
relatively well in the "bad" pass, and the best match is one of those.
In the "good" pass those "0 0 0 0" fonts aren't there at all.
I'm going to stop investigating for today. If this is enough for
somebody knowledgeable to investigate, then that's great. Otherwise I'll
keep digging myself later. What's the "right" behavior? I suspect that
blocking out the "0 0 0 0" fonts would be sufficient to solve my issue,
but wouldn't address the other things that look wrong and possibly are
an issue for others.
- bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes, Dima Kogan, 2014/12/07
- bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes, Eli Zaretskii, 2014/12/07
- bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes,
Dima Kogan <=
- bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes, Dmitry Antipov, 2014/12/19
- bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes, Dima Kogan, 2014/12/19
- bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes, Dmitry Antipov, 2014/12/22
- bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes, Jan Djärv, 2014/12/22
- bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes, Dima Kogan, 2014/12/26
- bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes, Stefan Monnier, 2014/12/26
- bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes, Dima Kogan, 2014/12/27