* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
@ 2014-11-20 6:13 Dima Kogan
2014-11-20 16:10 ` Eli Zaretskii
0 siblings, 1 reply; 32+ messages in thread
From: Dima Kogan @ 2014-11-20 6:13 UTC (permalink / raw)
To: 19117
[-- Attachment #1: Type: text/plain, Size: 1267 bytes --]
Hi. I'm observing an issue when running the latest GNU Emacs built from
source using the lucid X toolkit; this is on a Debian machine running
X11 (build details at the end).
Starting a few months ago (this is a regression) I'm seeing that
sometimes Emacs renders some faces with an unrequested (and ugly) font.
I can usually make it do the right thing by moving Emacs windows around
or resizing them, or maybe opening a new Emacs frame. It's not
consistent, and I don't know exactly what triggers it breaking or how I
can reliably fix it.
I'm attaching two screenshots of 'M-x describe-face italic' when it's
broken and right after I moved the windows around a bit, and re-invoked
describe-face. Note the very different font. Using what-cursor-position
I can see that in the wrong case the font is
-urw-nimbus mono l-regular-o-normal--11-79-100-100-p-70-iso8859-1 (#x70)
and in the right case the font is
-adobe-courier-medium-o-normal--11-80-100-100-m-60-iso8859-1 (#x6D)
The latter is correct since I customized my default-frame-alist to contain
(font . "-adobe-courier-medium-r-*-*-*-80-*-*-m-*-iso8859-1")
Can somebody give me some pointers on how to debug this to make this bug
report useful? I see the breakage many times a day every day.
Thanks.
[-- Attachment #2: good.png --]
[-- Type: image/png, Size: 2729 bytes --]
[-- Attachment #3: bad.png --]
[-- Type: image/png, Size: 2760 bytes --]
[-- Attachment #4: Type: text/plain, Size: 1216 bytes --]
In GNU Emacs 25.0.50.1 (x86_64-pc-linux-gnu, X toolkit, Xaw scroll bars)
of 2014-11-02 on lilbastard, modified by Debian
(emacs-snapshot package, version 2:20141102+emacs-24.4-1596-gb8f900f-1)
Windowing system distributor `The X.Org Foundation', version 11.0.11600000
System Description: Debian GNU/Linux unstable (sid)
Configured using:
`configure --build x86_64-linux-gnu --host x86_64-linux-gnu
--prefix=/usr --sharedstatedir=/var/lib --libexecdir=/usr/lib
--localstatedir=/var --infodir=/usr/share/info/emacs-snapshot
--mandir=/usr/share/man --with-pop=yes
--enable-locallisppath=/etc/emacs-snapshot:/etc/emacs:/usr/local/share/emacs/25.0.50/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/25.0.50/site-lisp:/usr/share/emacs/site-lisp
--with-crt-dir=/usr/lib/x86_64-linux-gnu/ --with-x=yes
--with-x-toolkit=lucid 'CFLAGS=-DDEBIAN -DSITELOAD_PURESIZE_EXTRA=5000
-g -O2' CPPFLAGS=-D_FORTIFY_SOURCE=2 'LDFLAGS=-g -Wl,--as-needed
-znocombreloc''
Configured features:
XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS GSETTINGS NOTIFY
LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT LIBOTF XFT ZLIB
Important settings:
value of $LC_ALL: C
value of $LANG: C
locale-coding-system: nil
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-11-20 6:13 bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes Dima Kogan
@ 2014-11-20 16:10 ` Eli Zaretskii
2014-12-07 7:28 ` Dima Kogan
0 siblings, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2014-11-20 16:10 UTC (permalink / raw)
To: Dima Kogan; +Cc: 19117
> From: Dima Kogan <dima@secretsauce.net>
> Date: Wed, 19 Nov 2014 22:13:47 -0800
>
> Starting a few months ago (this is a regression) I'm seeing that
> sometimes Emacs renders some faces with an unrequested (and ugly) font.
"Sometimes"? Can it be that it happens when Emacs needs to display
some character not available in the "non-ugly" font?
> I can usually make it do the right thing by moving Emacs windows around
> or resizing them, or maybe opening a new Emacs frame.
??? Incredible. You mean, you do all that magic, and the font used
for some text suddenly changes? Without killing the buffer with that
text?
> Can somebody give me some pointers on how to debug this to make this bug
> report useful? I see the breakage many times a day every day.
Put a breakpoint where Emacs loads new fonts, and see who calls that
code.
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-11-20 16:10 ` Eli Zaretskii
@ 2014-12-07 7:28 ` Dima Kogan
2014-12-07 16:12 ` Eli Zaretskii
0 siblings, 1 reply; 32+ messages in thread
From: Dima Kogan @ 2014-12-07 7:28 UTC (permalink / raw)
To: 19117
Eli Zaretskii <eliz@gnu.org> writes:
>> Starting a few months ago (this is a regression) I'm seeing that
>> sometimes Emacs renders some faces with an unrequested (and ugly) font.
>
> "Sometimes"? Can it be that it happens when Emacs needs to display
> some character not available in the "non-ugly" font?
No, it's independent of displaying any particular characters, as far as
I can tell. On my machine I can start emacs (with all my .emacs stuff
sadly) and issue
(face-font "italic")
and it reports the wrong font. Moving windows around fixes it, and makes
it report the correct font.
>> I can usually make it do the right thing by moving Emacs windows around
>> or resizing them, or maybe opening a new Emacs frame.
>
> ??? Incredible. You mean, you do all that magic, and the font used
> for some text suddenly changes? Without killing the buffer with that
> text?
Not 100% sure. The exact sequence to make it recover eludes me, so I'm
not sure if buffers need to be killed or refreshed in any way. Once it
recovers, things look good and (face-font "italic") reports the right
thing.
>> Can somebody give me some pointers on how to debug this to make this bug
>> report useful? I see the breakage many times a day every day.
>
> 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'm looking at realize_x_face() in xfaces.c. When I create a new frame
by pressing C-x 5 2, all the faces get re-realized, and I can see which
fonts are chosen. That function takes in a list of face attributes, and
associates a font with each face. I'm looking at attrs[LFACE_FONT_INDEX]
on input and face->font on output. For most faces, these two values are
#<font-object "-adobe-courier-medium-r-normal--11-80-100-100-m-60-iso8859-1">
"-adobe-courier-medium-r-normal--11-80-100-100-m-60-iso8859-1"
which is correct: we're asking for a particular font and we're getting
it. For many faces, however these values are
#<font-spec nil adobe courier ## iso8859-1 medium nil normal 11 100 100 60 ((user-spec . "-adobe-courier-medium-r-*-*-*-80-*-*-m-*-iso8859-1"))>
"-urw-nimbus mono l-regular-o-normal--11-79-100-100-p-70-iso8859-1"
or
#<font-spec nil adobe courier ## iso8859-1 medium nil normal 11 100 100 60 ((user-spec . "-adobe-courier-medium-r-*-*-*-80-*-*-m-*-iso8859-1"))>
"-adobe-courier-medium-o-normal--11-80-100-100-m-60-iso8859-1"
Here we're requesting a slanted version of the default font. Sometimes
emacs picks the right one (-adobe-courier-medium-o-...), but at other
times it picks the wrong one (-urw-....). The exact set of faces that
get the wrong font varies with each invocation of realize_x_face(), but
there's always at least one wrong one.
That's the only conclusive evidence I have so far, but I'm still looking
into it. Any suggestions welcome.
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-07 7:28 ` Dima Kogan
@ 2014-12-07 16:12 ` Eli Zaretskii
2014-12-17 5:36 ` Dima Kogan
0 siblings, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2014-12-07 16:12 UTC (permalink / raw)
To: Dima Kogan; +Cc: 19117
> 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'm looking at realize_x_face() in xfaces.c. When I create a new frame
> by pressing C-x 5 2, all the faces get re-realized, and I can see which
> fonts are chosen. That function takes in a list of face attributes, and
> associates a font with each face. I'm looking at attrs[LFACE_FONT_INDEX]
> on input and face->font on output. For most faces, these two values are
>
> #<font-object "-adobe-courier-medium-r-normal--11-80-100-100-m-60-iso8859-1">
> "-adobe-courier-medium-r-normal--11-80-100-100-m-60-iso8859-1"
>
> which is correct: we're asking for a particular font and we're getting
> it.
the above is a font object.
> For many faces, however these values are
>
> #<font-spec nil adobe courier ## iso8859-1 medium nil normal 11 100 100 60 ((user-spec . "-adobe-courier-medium-r-*-*-*-80-*-*-m-*-iso8859-1"))>
> "-urw-nimbus mono l-regular-o-normal--11-79-100-100-p-70-iso8859-1"
>
> or
>
> #<font-spec nil adobe courier ## iso8859-1 medium nil normal 11 100 100 60 ((user-spec . "-adobe-courier-medium-r-*-*-*-80-*-*-m-*-iso8859-1"))>
> "-adobe-courier-medium-o-normal--11-80-100-100-m-60-iso8859-1"
These two aren't font objects, they are font specs, a different
object. See font.h for their respective descriptions (unless you
already read that).
> Here we're requesting a slanted version of the default font. Sometimes
> emacs picks the right one (-adobe-courier-medium-o-...), but at other
> times it picks the wrong one (-urw-....). The exact set of faces that
> get the wrong font varies with each invocation of realize_x_face(), but
> there's always at least one wrong one.
Does the backtrace tell something about the reason(s) for the
differences?
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-07 16:12 ` Eli Zaretskii
@ 2014-12-17 5:36 ` Dima Kogan
2014-12-17 6:57 ` Dima Kogan
0 siblings, 1 reply; 32+ messages in thread
From: Dima Kogan @ 2014-12-17 5:36 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 19117
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.
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-17 5:36 ` Dima Kogan
@ 2014-12-17 6:57 ` Dima Kogan
2014-12-18 16:24 ` Eli Zaretskii
2014-12-19 15:28 ` Dmitry Antipov
0 siblings, 2 replies; 32+ messages in thread
From: Dima Kogan @ 2014-12-17 6:57 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 19117
I just looked a bit more.
As I mentioned in the last message, the font description that results in
ugly rendering is
#<font-entity x adobe courier ## iso8859-1 medium i normal 0 0 0 0 nil>
Apparently the "0 0 0 0" represents a "scalable" font. Not 100% sure
what this means in the context of X11. In Emacs, we load this font with
XLoadQueryFont() in xfont_open(). I wrote a small program to see what
this means on my box:
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
int main(void)
{
Display* dpy = XOpenDisplay(":0.0");
const char* font_input = "-adobe-courier-medium-i-normal-*-0-0-0-0-p-0-iso8859-1";
const char* font_output;
unsigned long value;
XFontStruct *font = XLoadQueryFont(dpy, font_input);
XGetFontProperty (font, XA_FONT, &value);
font_output = XGetAtomName (dpy, (Atom) value);
fprintf(stderr, "font '%s' loaded as '%s'\n", font_input, font_output);
return 0;
}
Here I load the scalable font that Emacs is choosing (and that xlsfonts
says exists on my machine). Then after it is loaded, I ask what the font
is called. The output is this:
font '-adobe-courier-medium-i-normal-*-0-0-0-0-p-0-iso8859-1' loaded as '-urw-nimbus mono l-regular-o-normal--17-120-100-100-p-100-iso8859-1'
So this completely explains why I'm getting ugly rendering. Emacs is
picking a scalable adobe font, which XLoadQueryFont() interprets as a
17-pixel urw bitmap font. Since I was asking for an 11-pixel font to
begin with, emacs is down-scaling this font by a factor of 11/17, which
does not look so good.
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-17 6:57 ` Dima Kogan
@ 2014-12-18 16:24 ` Eli Zaretskii
2014-12-20 8:08 ` Jan Djärv
2014-12-19 15:28 ` Dmitry Antipov
1 sibling, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2014-12-18 16:24 UTC (permalink / raw)
To: Dima Kogan, Dmitry Antipov, Jan Djärv; +Cc: 19117
> From: Dima Kogan <dima@secretsauce.net>
> Cc: 19117@debbugs.gnu.org
> Date: Tue, 16 Dec 2014 22:57:41 -0800
>
> I just looked a bit more.
Dmitry, Jan, could you please help Dima here?
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-17 6:57 ` Dima Kogan
2014-12-18 16:24 ` Eli Zaretskii
@ 2014-12-19 15:28 ` Dmitry Antipov
2014-12-19 22:46 ` Dima Kogan
1 sibling, 1 reply; 32+ messages in thread
From: Dmitry Antipov @ 2014-12-19 15:28 UTC (permalink / raw)
To: Dima Kogan; +Cc: 19117
On 12/17/2014 09:57 AM, Dima Kogan wrote:
> Apparently the "0 0 0 0" represents a "scalable" font. Not 100% sure
> what this means in the context of X11. In Emacs, we load this font with
> XLoadQueryFont() in xfont_open(). I wrote a small program to see what
> this means on my box:
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <X11/Xlib.h>
> #include <X11/Xatom.h>
> int main(void)
> {
> Display* dpy = XOpenDisplay(":0.0");
>
> const char* font_input = "-adobe-courier-medium-i-normal-*-0-0-0-0-p-0-iso8859-1";
> const char* font_output;
> unsigned long value;
>
> XFontStruct *font = XLoadQueryFont(dpy, font_input);
> XGetFontProperty (font, XA_FONT, &value);
> font_output = XGetAtomName (dpy, (Atom) value);
>
> fprintf(stderr, "font '%s' loaded as '%s'\n", font_input, font_output);
> return 0;
> }
>
> Here I load the scalable font that Emacs is choosing (and that xlsfonts
> says exists on my machine). Then after it is loaded, I ask what the font
> is called. The output is this:
>
> font '-adobe-courier-medium-i-normal-*-0-0-0-0-p-0-iso8859-1' loaded as
> '-urw-nimbus mono l-regular-o-normal--17-120-100-100-p-100-iso8859-1'
Hm. On my system (Fedora 21), there are no -adobe-courier-medium-i-normal-*
fonts but:
$ xlsfonts | grep -- -adobe-utopia-bold-i-normal-
-adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso10646-1
-adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso10646-1
-adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso8859-1
-adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso8859-1
-adobe-utopia-bold-i-normal--10-100-75-75-p-58-iso10646-1
-adobe-utopia-bold-i-normal--12-120-75-75-p-70-iso10646-1
-adobe-utopia-bold-i-normal--14-100-100-100-p-78-iso10646-1
-adobe-utopia-bold-i-normal--14-100-100-100-p-78-iso8859-1
-adobe-utopia-bold-i-normal--15-140-75-75-p-82-iso10646-1
-adobe-utopia-bold-i-normal--17-120-100-100-p-93-iso10646-1
-adobe-utopia-bold-i-normal--17-120-100-100-p-93-iso8859-1
-adobe-utopia-bold-i-normal--19-140-100-100-p-109-iso10646-1
-adobe-utopia-bold-i-normal--19-140-100-100-p-109-iso8859-1
-adobe-utopia-bold-i-normal--19-180-75-75-p-105-iso10646-1
-adobe-utopia-bold-i-normal--25-180-100-100-p-139-iso10646-1
-adobe-utopia-bold-i-normal--25-180-100-100-p-139-iso8859-1
-adobe-utopia-bold-i-normal--25-240-75-75-p-140-iso10646-1
-adobe-utopia-bold-i-normal--33-240-100-100-p-186-iso10646-1
-adobe-utopia-bold-i-normal--33-240-100-100-p-186-iso8859-1
And running your program with -adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso8859-1
produces:
font '-adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso8859-1' loaded as '-adobe-utopia-bold-i-normal--17-120-100-100-p-94-iso8859-1'
Your X behaves pretty strange; I can't explain this just now.
Also, what happens if you specify default font via ~/.Xdefaults
and run with emacs -q (small 'q', not 'Q')?
Dmitry
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-19 15:28 ` Dmitry Antipov
@ 2014-12-19 22:46 ` Dima Kogan
2014-12-22 8:01 ` Dmitry Antipov
2014-12-22 8:28 ` Jan Djärv
0 siblings, 2 replies; 32+ messages in thread
From: Dima Kogan @ 2014-12-19 22:46 UTC (permalink / raw)
To: Dmitry Antipov; +Cc: 19117
Dmitry Antipov <dmantipov@yandex.ru> writes:
> Hm. On my system (Fedora 21), there are no -adobe-courier-medium-i-normal-*
> fonts but:
>
> $ xlsfonts | grep -- -adobe-utopia-bold-i-normal-
> -adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso10646-1
> -adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso10646-1
> -adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso8859-1
> -adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso8859-1
> -adobe-utopia-bold-i-normal--10-100-75-75-p-58-iso10646-1
> -adobe-utopia-bold-i-normal--12-120-75-75-p-70-iso10646-1
> -adobe-utopia-bold-i-normal--14-100-100-100-p-78-iso10646-1
> -adobe-utopia-bold-i-normal--14-100-100-100-p-78-iso8859-1
> -adobe-utopia-bold-i-normal--15-140-75-75-p-82-iso10646-1
> -adobe-utopia-bold-i-normal--17-120-100-100-p-93-iso10646-1
> -adobe-utopia-bold-i-normal--17-120-100-100-p-93-iso8859-1
> -adobe-utopia-bold-i-normal--19-140-100-100-p-109-iso10646-1
> -adobe-utopia-bold-i-normal--19-140-100-100-p-109-iso8859-1
> -adobe-utopia-bold-i-normal--19-180-75-75-p-105-iso10646-1
> -adobe-utopia-bold-i-normal--25-180-100-100-p-139-iso10646-1
> -adobe-utopia-bold-i-normal--25-180-100-100-p-139-iso8859-1
> -adobe-utopia-bold-i-normal--25-240-75-75-p-140-iso10646-1
> -adobe-utopia-bold-i-normal--33-240-100-100-p-186-iso10646-1
> -adobe-utopia-bold-i-normal--33-240-100-100-p-186-iso8859-1
>
> And running your program with -adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso8859-1
> produces:
>
> font '-adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso8859-1' loaded as '-adobe-utopia-bold-i-normal--17-120-100-100-p-94-iso8859-1'
>
> Your X behaves pretty strange; I can't explain this just now.
>
> Also, what happens if you specify default font via ~/.Xdefaults
> and run with emacs -q (small 'q', not 'Q')?
Hi. Thank you for looking.
First off, setting the font in the .Xresources has the same effect as
doing it with the lisp snippet on the commandline.
My font configuration is stock from Debian; I didn't mess with it. The
adobe->urw conversion probably comes from
/usr/share/fonts/X11/Type1/fonts.alias which on my machine contains many
lines such as
-adobe-courier-medium-o-normal--0-0-0-0-p-0-iso8859-2 "-urw-nimbus mono l-regular-o-normal--0-0-0-0-p-0-iso8859-2"
That file contains only aliases from scalable fonts to other scalable
fonts, but it's probably the cause in any case.
I do suspect that the adobe->urw conversion is not important here. What
IS important is that we ask Emacs for a particular size 11 font, it
gives back a size 0 (scalable) font, and when you ask X for that size 0
font, you get back a size 17 font. You are seeing this too, apparently.
You asked X for a scalable font
-adobe-utopia-bold-i-normal--0-0-0-0-p-0-iso8859-1
and X gave you a size-17 font
-adobe-utopia-bold-i-normal--17-120-100-100-p-94-iso8859-1
So in your case, if you ask Emacs for a size-11 -adobe-utopia-... font
then does Emacs pick a scalable font for you? If so, I would expect
things to not look very good, since you'll get a 17->11 scaling.
The questions for Emacs are:
- Should the candidate font list stay consistent as Emacs runs?
- Should the candidate font list contain any scalable fonts?
The answer to the 1st question is probably "yes". Do you know the answer
to the 2nd? I can keep probing if you tell me which observed behavior is
wrong.
My suspicion is that there's some race condition here that is tickled by
my window manager. I'm using notion, which is a niche WM, so this
wouldn't be widely reported. But even so, it has been working fine for
many years, only regressing 6 months ago or so.
Thanks again
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-18 16:24 ` Eli Zaretskii
@ 2014-12-20 8:08 ` Jan Djärv
0 siblings, 0 replies; 32+ messages in thread
From: Jan Djärv @ 2014-12-20 8:08 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Dmitry Antipov, 19117@debbugs.gnu.org, Dima Kogan
I'm travelling, so it will be some days before I can look at this.
Jan D.
18 dec 2014 kl. 17:24 skrev Eli Zaretskii <eliz@gnu.org>:
>> From: Dima Kogan <dima@secretsauce.net>
>> Cc: 19117@debbugs.gnu.org
>> Date: Tue, 16 Dec 2014 22:57:41 -0800
>>
>> I just looked a bit more.
>
> Dmitry, Jan, could you please help Dima here?
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-19 22:46 ` Dima Kogan
@ 2014-12-22 8:01 ` Dmitry Antipov
2014-12-22 8:28 ` Jan Djärv
1 sibling, 0 replies; 32+ messages in thread
From: Dmitry Antipov @ 2014-12-22 8:01 UTC (permalink / raw)
To: Dima Kogan; +Cc: 19117
[-- Attachment #1: Type: text/plain, Size: 1199 bytes --]
On 12/20/2014 01:46 AM, Dima Kogan wrote:
> So in your case, if you ask Emacs for a size-11 -adobe-utopia-... font
> then does Emacs pick a scalable font for you? If so, I would expect
> things to not look very good, since you'll get a 17->11 scaling.
Hm...below are my results of running:
emacs -Q --font "-adobe-utopia-bold-i-normal--11-120-100-100-p-94-iso8859-1"
and
emacs -Q --font "-adobe-utopia-bold-i-normal--17-120-100-100-p-94-iso8859-1"
respectively. May be *-11-* is just too small to see glitches on my screen,
but I can't complain about ugly rendering.
> - Should the candidate font list stay consistent as Emacs runs?
IIUC yes, unless you install/remove new/existing fonts and
do 'xset +/-fp /path/to/new|old/fonts' as Emacs runs.
> - Should the candidate font list contain any scalable fonts?
I'll try to check.
> My suspicion is that there's some race condition here that is tickled by
> my window manager. I'm using notion, which is a niche WM, so this
> wouldn't be widely reported. But even so, it has been working fine for
> many years, only regressing 6 months ago or so.
If you suspect the WM-side tricks, try to investigate this issue under twm
as well.
Dmitry
[-- Attachment #2: emacs-adobe-11.png --]
[-- Type: image/png, Size: 39342 bytes --]
[-- Attachment #3: emacs-adobe-17.png --]
[-- Type: image/png, Size: 78463 bytes --]
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-19 22:46 ` Dima Kogan
2014-12-22 8:01 ` Dmitry Antipov
@ 2014-12-22 8:28 ` Jan Djärv
2014-12-26 19:43 ` Dima Kogan
1 sibling, 1 reply; 32+ messages in thread
From: Jan Djärv @ 2014-12-22 8:28 UTC (permalink / raw)
To: Dima Kogan, Dmitry Antipov; +Cc: 19117
Den 2014-12-19 23:46, Dima Kogan skrev:
>
> The questions for Emacs are:
>
> - Should the candidate font list stay consistent as Emacs runs?
> - Should the candidate font list contain any scalable fonts?
>
> The answer to the 1st question is probably "yes". Do you know the answer
> to the 2nd? I can keep probing if you tell me which observed behavior is
> wrong.
The answer to the first one is no. Or rather, it is out of Emacs control.
Since you are using non-client fonts, the list is determined by the X- or
font-server. The fact that you can get two matches suggests that your font
spec is underspecified, if your goal is to get just one specific font.
I see no bug here.
Jan D.
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-22 8:28 ` Jan Djärv
@ 2014-12-26 19:43 ` Dima Kogan
2014-12-27 2:17 ` Stefan Monnier
0 siblings, 1 reply; 32+ messages in thread
From: Dima Kogan @ 2014-12-26 19:43 UTC (permalink / raw)
To: Jan Djärv; +Cc: 19117
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=utf-8, Size: 3305 bytes --]
Jan Djärv <jan.h.d@swipnet.se> writes:
> Den 2014-12-19 23:46, Dima Kogan skrev:
>
>> The questions for Emacs are:
>>
>> - Should the candidate font list stay consistent as Emacs runs?
>> - Should the candidate font list contain any scalable fonts?
>>
>> The answer to the 1st question is probably "yes". Do you know the answer
>> to the 2nd? I can keep probing if you tell me which observed behavior is
>> wrong.
>
> The answer to the first one is no. Or rather, it is out of Emacs control.
> Since you are using non-client fonts, the list is determined by the X- or
> font-server. The fact that you can get two matches suggests that your font
> spec is underspecified, if your goal is to get just one specific font.
>
> I see no bug here.
Hi. The observed behavior (same face getting different fonts of varying
ugliness over time) cannot be considered correct, but I cannot yet say
where the bad behavior lies. It could be in Emacs or X or the Debian
font configuration.
Looking at this some more, I'm now more confused than when I started.
Any enlightenment is welcome.
To summarize the earlier findings:
- Emacs is asked for a font that matches the spec
#<font-spec nil nil nil nil nil medium italic normal 11 nil nil nil nil>
- The font chosen by emacs can vary here. When it chooses the "ugly"
path, it picks
#<font-entity x adobe courier ## iso8859-1 medium i normal 0 0 0 0 nil>
- When X is asked for a corresponding font
-adobe-courier-medium-i-normal-*-0-0-0-0-p-0-iso8859-1
it actually loads
-urw-nimbus mono l-regular-o-normal--17-120-100-100-p-100-iso8859-1
Note that we originally sought an 11-px font, but got a 17-px one
instead.
OK. So the hypothesis is that the 11-px version of that 17-px urw font
does not exist, hence it's down-scaling the 17-px version. However,
apparently I can do
xfontsel -pattern "-urw-nimbus mono l-regular-o-normal--11-*-*-*-p-70-iso8859-1"
and it works. I.e. xfontsel doesn't complain that the font doesn't
exist, it simply shows me the ugly 11-px font I'm complaining about.
I don't think this font actually exists (it's ugly; a human would not
draw it). However if I ask the font system whether it exists or not, it
unambiguously says yes:
$ xlsfonts -fn "-urw-nimbus mono l-regular-o-normal--11-*-*-*-p-70-iso8859-1"
-urw-nimbus mono l-regular-o-normal--11-79-100-100-p-70-iso8859-1
However, when I use a wildcard for the font size, (so * instead of 11),
it reports that the 11-px font does NOT exist, but a 17-px one does:
$ xlsfonts -fn "-urw-nimbus mono l-regular-o-normal--*-*-*-*-p-70-iso8859-1"
-urw-nimbus mono l-regular-o-normal--17-120-100-100-p-70-iso8859-1
This 17-px font looks good in xfontsel, but it's obviously bigger than
the 11-px one.
It looks like the font specs have a pixel-size and a point-size, (11-79)
and (17-120), with the ratio staying roughly constant in either case, so
the 11-79 is almost certainly a scaled version of 17-120. Problem is
that the rendering is based on the px-size only, so it looks like crap.
Is this how X fonts are supposed to work? What if Emacs treated scalable
fonts by looking at the actual px-sizes that were available (17 in this
case) and only evaluating those? Would that be a reasonable thing to do?
I can work on an implementation if it is.
Thanks
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-26 19:43 ` Dima Kogan
@ 2014-12-27 2:17 ` Stefan Monnier
2014-12-27 9:17 ` Dima Kogan
2014-12-30 9:44 ` Dima Kogan
0 siblings, 2 replies; 32+ messages in thread
From: Stefan Monnier @ 2014-12-27 2:17 UTC (permalink / raw)
To: Dima Kogan; +Cc: 19117
> $ xlsfonts -fn "-urw-nimbus mono l-regular-o-normal--11-*-*-*-p-70-iso8859-1"
> -urw-nimbus mono l-regular-o-normal--11-79-100-100-p-70-iso8859-1
> However, when I use a wildcard for the font size, (so * instead of 11),
> it reports that the 11-px font does NOT exist, but a 17-px one does:
> $ xlsfonts -fn "-urw-nimbus mono l-regular-o-normal--*-*-*-*-p-70-iso8859-1"
> -urw-nimbus mono l-regular-o-normal--17-120-100-100-p-70-iso8859-1
That's indeed the expected behavior for server-side scaled bitmap fonts.
> What if Emacs treated scalable fonts by looking at the actual px-sizes
> that were available (17 in this case) and only evaluating those?
IIUC if `scalable-fonts-allowed' is set to nil, that's what should happen.
Stefan
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-27 2:17 ` Stefan Monnier
@ 2014-12-27 9:17 ` Dima Kogan
2014-12-30 9:44 ` Dima Kogan
1 sibling, 0 replies; 32+ messages in thread
From: Dima Kogan @ 2014-12-27 9:17 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 19117
Stefan Monnier <monnier@iro.umontreal.ca> writes:
> IIUC if `scalable-fonts-allowed' is set to nil, that's what should happen.
This was a VERY useful comment. I do not touch scalable-fonts-allowed,
so it should be the default (i.e. nil), meaning that I should already be
disallowing these fonts. Looking at it deeper I see that the font list
is obtained by xfont_list_pattern() in xfont.c. This is an XListFonts()
call, with emacs then filtering the resulting list in various ways.
I see XListFonts() return consistent results, but the post-filtering of
the list is inconsistent. Specifically, the inconsistent piece is
exactly the scalable_fonts_allowed check in xfont_list_pattern():
https://github.com/emacs-mirror/emacs/blob/162660c3639a68a7b71439bdd713d54f940274b8/src/xfont.c#L416
When we get here, scalable_fonts_allowed is sometimes non-nil, which is
the direct cause of my problem. Forcefully removing that check and
always assuming that it IS nil makes this bug go away.
I haven't verified this yet, but presumably scalable_fonts_allowed is
getting set to t in realize_basic_faces() in xfaces.c:
https://github.com/emacs-mirror/emacs/blob/162660c3639a68a7b71439bdd713d54f940274b8/src/xfaces.c#L5236
Any comment on that? That bit of code was there since 2001, so
presumably it's reasonable. Anybody know more?
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-27 2:17 ` Stefan Monnier
2014-12-27 9:17 ` Dima Kogan
@ 2014-12-30 9:44 ` Dima Kogan
2014-12-30 16:57 ` Stefan Monnier
1 sibling, 1 reply; 32+ messages in thread
From: Dima Kogan @ 2014-12-30 9:44 UTC (permalink / raw)
To: 19117
Hi. I looked at this some more. The scalable-fonts-allowed is indeed
being set to t in realize_basic_faces().
As emacs runs, the font lists are generated (xfont_list() called)
multiple times, and there are many code paths that end up doing that.
Some code paths go through realize_basic_faces(), and thus allow
scalable fonts, and some code paths do NOT go through that function.
Each time a new emacs frame is created, xfont_list() is called multiple
times, and if the last time it is called, the code path went through
realize_basic_faces(), then I get the wrong fonts chosen for that frame.
This is not consistent, so sometimes I see the bad behavior.
What's the best route from here? Options:
1. Look at all the (very numerous, and complicated) code paths, and set
it up such that realize_basic_faces() is never the last one. I don't
know enough to do this (yet), and can't tell if this is even appropriate
2. Do not set scalable-fonts-allowed to t in realize_basic_faces(). Does
anybody know why this is desirable?
3. Never choose scalable X fonts, regardless of scalable-fonts-allowed.
If the X scalable fonts are simply scaled bitmaps, then the scaled
result will never look particularly good, so choosing these is not
useful. This almost certainly doesn't apply to the other font backends
(xft, etc)
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-30 9:44 ` Dima Kogan
@ 2014-12-30 16:57 ` Stefan Monnier
2014-12-30 18:33 ` Dima Kogan
0 siblings, 1 reply; 32+ messages in thread
From: Stefan Monnier @ 2014-12-30 16:57 UTC (permalink / raw)
To: Dima Kogan; +Cc: 19117
> 2. Do not set scalable-fonts-allowed to t in realize_basic_faces(). Does
> anybody know why this is desirable?
Have you looked at the "git blame" output to try and see when/why we do that?
Stefan
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-30 16:57 ` Stefan Monnier
@ 2014-12-30 18:33 ` Dima Kogan
2014-12-30 20:05 ` Eli Zaretskii
0 siblings, 1 reply; 32+ messages in thread
From: Dima Kogan @ 2014-12-30 18:33 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 19117
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>> 2. Do not set scalable-fonts-allowed to t in realize_basic_faces(). Does
>> anybody know why this is desirable?
>
> Have you looked at the "git blame" output to try and see when/why we do that?
I did look at earlier it without any particular enlightenment. But I
just looked at it again, and it IS helpful, actually. This is all from
2001, written by Gerd Moellmann. Here are the changes in chronological
order
https://github.com/emacs-mirror/emacs/commit/702a1e8e
https://github.com/emacs-mirror/emacs/commit/441bf856
https://github.com/emacs-mirror/emacs/commit/eeffb293
The logic was using a realizing_default_face_p variable (changed in the
last commit), anad roughtly it did this:
x_face_list_fonts()
{
get_all_fonts();
for(fonts)
{
if(!font_scalable)
add to list;
}
if (realizing_default_face_p
&& no fonts in list
&& some were scalable)
{
for(fonts)
{
if(!font_scalable)
add to list;
}
}
...
}
So we only added the scalable fonts if no other fonts were found. The
new logic does not do this; it always adds the scalable fonts. The
docstring of scalable-fonts-allowed further indicates that the original
intent was a last-resort like before:
Note that if value is nil, a scalable font might still be used, if no
other font of the appropriate family and registry is available.
I will patch xfont_list_pattern() to accept a 3rd type of
scalable-fonts-allowed: 'fallback where we add these fonts only if no
others are available, and in realize_basic_faces() I'll use THAT value.
Does that sound reasonable?
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-30 18:33 ` Dima Kogan
@ 2014-12-30 20:05 ` Eli Zaretskii
2014-12-31 4:06 ` Dima Kogan
0 siblings, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2014-12-30 20:05 UTC (permalink / raw)
To: Dima Kogan; +Cc: 19117
> From: Dima Kogan <dima@secretsauce.net>
> Date: Tue, 30 Dec 2014 10:33:17 -0800
> Cc: 19117@debbugs.gnu.org
>
> I will patch xfont_list_pattern() to accept a 3rd type of
> scalable-fonts-allowed: 'fallback where we add these fonts only if no
> others are available, and in realize_basic_faces() I'll use THAT value.
> Does that sound reasonable?
Please note that on MS-Windows the scalable fonts were always used in
this scenario, back with that code, and there was a comment explaining
that otherwise too few fonts will be available on Windows.
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-30 20:05 ` Eli Zaretskii
@ 2014-12-31 4:06 ` Dima Kogan
2015-01-02 9:43 ` Eli Zaretskii
0 siblings, 1 reply; 32+ messages in thread
From: Dima Kogan @ 2014-12-31 4:06 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 19117
[-- Attachment #1: Type: text/plain, Size: 1698 bytes --]
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Dima Kogan <dima@secretsauce.net>
>> Date: Tue, 30 Dec 2014 10:33:17 -0800
>> Cc: 19117@debbugs.gnu.org
>>
>> I will patch xfont_list_pattern() to accept a 3rd type of
>> scalable-fonts-allowed: 'fallback where we add these fonts only if no
>> others are available, and in realize_basic_faces() I'll use THAT value.
>> Does that sound reasonable?
>
> Please note that on MS-Windows the scalable fonts were always used in
> this scenario, back with that code, and there was a comment explaining
> that otherwise too few fonts will be available on Windows.
Hi. I'm attaching patches. The first one does this:
scalable font logic now matches the docs and is more consistent
A nil value of scalable-fonts-allowed allows scalable fonts if no others
were found. This is the previously-documented behavior.
realize_basic_faces() no longer forces scalable-fonts-allowed to t. If
nil, some fonts will always be found even if only scalable fonts are
available, as set by the other part of this patch.
This is simpler than what I proposed earlier, since it does not
introduce a third setting to scalable-fonts-allowed: the default nil
value is sufficient. The patch mimics the older behavior to loop through
the whole font list a second time if no non-scalable fonts were found
and some scalable fonts WERE found, but were skipped the first time
around due to scalable-fonts-allowed. This fixes my bug. The patch
touches many lines, but almost all of it is indentation.
The second patch is mostly unrelated. It removes some redundant code.
I don't believe the behavior on Windows should be affected at all, but I
have not verified this.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-scalable-font-logic-now-matches-the-docs-and-is-more.patch --]
[-- Type: text/x-diff, Size: 8924 bytes --]
From af0ec4452c5157e526af3c1190c3e8ba6f72c982 Mon Sep 17 00:00:00 2001
From: Dima Kogan <dima@secretsauce.net>
Date: Tue, 30 Dec 2014 20:05:11 -0800
Subject: [PATCH 1/2] scalable font logic now matches the docs and is more
consistent
A nil value of scalable-fonts-allowed allows scalable fonts if no others
were found. This is the previously-documented behavior.
realize_basic_faces() no longer forces scalable-fonts-allowed to t. If
nil, some fonts will always be found even if only scalable fonts are
available, as set by the other part of this patch.
---
src/xfaces.c | 3 --
src/xfont.c | 172 +++++++++++++++++++++++++++++++++--------------------------
2 files changed, 95 insertions(+), 80 deletions(-)
diff --git a/src/xfaces.c b/src/xfaces.c
index 446107e..0aa9968 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -5228,12 +5228,10 @@ static bool
realize_basic_faces (struct frame *f)
{
bool success_p = 0;
- ptrdiff_t count = SPECPDL_INDEX ();
/* Block input here so that we won't be surprised by an X expose
event, for instance, without having the faces set up. */
block_input ();
- specbind (Qscalable_fonts_allowed, Qt);
if (realize_default_face (f))
{
@@ -5267,7 +5265,6 @@ realize_basic_faces (struct frame *f)
success_p = 1;
}
- unbind_to (count, Qnil);
unblock_input ();
return success_p;
}
diff --git a/src/xfont.c b/src/xfont.c
index 06a4479..c6a3f2b 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -388,94 +388,112 @@ xfont_list_pattern (Display *display, const char *pattern,
Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
Lisp_Object scripts = Qnil, entity = Qnil;
+ /* We take two passes over the font list. The second pass is
+ taken only if scalable-fonts-allowed is nil, and only
+ scalable fonts were found.
+ */
+ int i_pass;
+ bool skipped_some_scalable_fonts = false;
+
for (i = 0; i < ASIZE (xfont_scratch_props); i++)
ASET (xfont_scratch_props, i, Qnil);
for (i = 0; i < num_fonts; i++)
indices[i] = names[i];
qsort (indices, num_fonts, sizeof (char *), compare_font_names);
- for (i = 0; i < num_fonts; i++)
- {
- ptrdiff_t len;
+ for (i_pass = 0; i_pass < 2; i_pass++)
+ {
+ for (i = 0; i < num_fonts; i++)
+ {
+ ptrdiff_t len;
- if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
- continue;
- if (NILP (entity))
- entity = font_make_entity ();
- len = xfont_decode_coding_xlfd (indices[i], -1, buf);
- if (font_parse_xlfd (buf, len, entity) < 0)
- continue;
- ASET (entity, FONT_TYPE_INDEX, Qx);
- /* Avoid auto-scaled fonts. */
- if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
- && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
- && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
- && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
- continue;
- /* Avoid not-allowed scalable fonts. */
- if (NILP (Vscalable_fonts_allowed))
- {
- int size = 0;
+ if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
+ continue;
+ if (NILP (entity))
+ entity = font_make_entity ();
+ len = xfont_decode_coding_xlfd (indices[i], -1, buf);
+ if (font_parse_xlfd (buf, len, entity) < 0)
+ continue;
+ ASET (entity, FONT_TYPE_INDEX, Qx);
+ /* Avoid auto-scaled fonts. */
+ if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
+ && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
+ && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
+ && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
+ continue;
+ /* Avoid not-allowed scalable fonts. */
+ if (NILP (Vscalable_fonts_allowed))
+ {
+ int size = 0;
- if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
- size = XINT (AREF (entity, FONT_SIZE_INDEX));
- else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
- size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
- if (size == 0)
- continue;
- }
- else if (CONSP (Vscalable_fonts_allowed))
- {
- Lisp_Object tail, elt;
+ if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
+ size = XINT (AREF (entity, FONT_SIZE_INDEX));
+ else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
+ size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
+ if (size == 0 && i_pass == 0)
+ {
+ skipped_some_scalable_fonts = true;
+ continue;
+ }
+ }
+ else if (CONSP (Vscalable_fonts_allowed))
+ {
+ Lisp_Object tail, elt;
- for (tail = Vscalable_fonts_allowed; CONSP (tail);
- tail = XCDR (tail))
- {
- elt = XCAR (tail);
- if (STRINGP (elt)
- && fast_c_string_match_ignore_case (elt, indices[i],
- len) >= 0)
- break;
- }
- if (! CONSP (tail))
- continue;
- }
+ for (tail = Vscalable_fonts_allowed; CONSP (tail);
+ tail = XCDR (tail))
+ {
+ elt = XCAR (tail);
+ if (STRINGP (elt)
+ && fast_c_string_match_ignore_case (elt, indices[i],
+ len) >= 0)
+ break;
+ }
+ if (! CONSP (tail))
+ continue;
+ }
- /* Avoid fonts of invalid registry. */
- if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
- continue;
+ /* Avoid fonts of invalid registry. */
+ if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
+ continue;
- /* Update encoding and repertory if necessary. */
- if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
- {
- registry = AREF (entity, FONT_REGISTRY_INDEX);
- if (font_registry_charsets (registry, &encoding, &repertory) < 0)
- encoding = NULL;
- }
- if (! encoding)
- /* Unknown REGISTRY, not supported. */
- continue;
- if (repertory)
- {
- if (NILP (script)
- || xfont_chars_supported (chars, NULL, encoding, repertory))
- list = Fcons (entity, list), entity = Qnil;
- continue;
- }
- if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
- word_size * 7)
- || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
- {
- vcopy (xfont_scratch_props, 0,
- aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
- ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
- scripts = xfont_supported_scripts (display, indices[i],
- xfont_scratch_props, encoding);
- }
- if (NILP (script)
- || ! NILP (Fmemq (script, scripts)))
- list = Fcons (entity, list), entity = Qnil;
- }
+ /* Update encoding and repertory if necessary. */
+ if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
+ {
+ registry = AREF (entity, FONT_REGISTRY_INDEX);
+ if (font_registry_charsets (registry, &encoding, &repertory) < 0)
+ encoding = NULL;
+ }
+ if (! encoding)
+ /* Unknown REGISTRY, not supported. */
+ continue;
+ if (repertory)
+ {
+ if (NILP (script)
+ || xfont_chars_supported (chars, NULL, encoding, repertory))
+ list = Fcons (entity, list), entity = Qnil;
+ continue;
+ }
+ if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
+ word_size * 7)
+ || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
+ {
+ vcopy (xfont_scratch_props, 0,
+ aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
+ ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
+ scripts = xfont_supported_scripts (display, indices[i],
+ xfont_scratch_props, encoding);
+ }
+ if (NILP (script)
+ || ! NILP (Fmemq (script, scripts)))
+ list = Fcons (entity, list), entity = Qnil;
+ }
+
+ /* We skip the second pass unless we really need it. */
+ if (!(NILP (list) /* No fonts found on the first pass */
+ && skipped_some_scalable_fonts)) /* and we skipped some scalable ones. */
+ break;
+ }
XFreeFontNames (names);
}
--
2.1.3
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-removed-unused-variable-assignment.patch --]
[-- Type: text/x-diff, Size: 642 bytes --]
From 282bee4cfe6775063358c616e966593501620b54 Mon Sep 17 00:00:00 2001
From: Dima Kogan <dima@secretsauce.net>
Date: Tue, 30 Dec 2014 20:05:58 -0800
Subject: [PATCH 2/2] removed unused variable assignment
---
src/font.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/font.c b/src/font.c
index 70e6316..dc821dd 100644
--- a/src/font.c
+++ b/src/font.c
@@ -2160,7 +2160,6 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
}
/* Score the size. Maximum difference is 127. */
- i = FONT_SIZE_INDEX;
if (! NILP (spec_prop[FONT_SIZE_INDEX])
&& XINT (AREF (entity, FONT_SIZE_INDEX)) > 0)
{
--
2.1.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2014-12-31 4:06 ` Dima Kogan
@ 2015-01-02 9:43 ` Eli Zaretskii
2015-01-02 21:07 ` Dima Kogan
0 siblings, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2015-01-02 9:43 UTC (permalink / raw)
To: Dima Kogan; +Cc: 19117
> From: Dima Kogan <dima@secretsauce.net>
> Cc: monnier@iro.umontreal.ca, 19117@debbugs.gnu.org
> Date: Tue, 30 Dec 2014 20:06:38 -0800
>
> Eli Zaretskii <eliz@gnu.org> writes:
>
> >> From: Dima Kogan <dima@secretsauce.net>
> >> Date: Tue, 30 Dec 2014 10:33:17 -0800
> >> Cc: 19117@debbugs.gnu.org
> >>
> >> I will patch xfont_list_pattern() to accept a 3rd type of
> >> scalable-fonts-allowed: 'fallback where we add these fonts only if no
> >> others are available, and in realize_basic_faces() I'll use THAT value.
> >> Does that sound reasonable?
> >
> > Please note that on MS-Windows the scalable fonts were always used in
> > this scenario, back with that code, and there was a comment explaining
> > that otherwise too few fonts will be available on Windows.
>
> Hi. I'm attaching patches. The first one does this:
>
> scalable font logic now matches the docs and is more consistent
>
> A nil value of scalable-fonts-allowed allows scalable fonts if no others
> were found. This is the previously-documented behavior.
>
> realize_basic_faces() no longer forces scalable-fonts-allowed to t. If
> nil, some fonts will always be found even if only scalable fonts are
> available, as set by the other part of this patch.
>
> This is simpler than what I proposed earlier, since it does not
> introduce a third setting to scalable-fonts-allowed: the default nil
> value is sufficient. The patch mimics the older behavior to loop through
> the whole font list a second time if no non-scalable fonts were found
> and some scalable fonts WERE found, but were skipped the first time
> around due to scalable-fonts-allowed. This fixes my bug. The patch
> touches many lines, but almost all of it is indentation.
>
>
> The second patch is mostly unrelated. It removes some redundant code.
>
> I don't believe the behavior on Windows should be affected at all, but I
> have not verified this.
Thanks.
I don't really know how to test these changes on Windows, since most
of the changes are in xfont.c, and the equivalent w32font.c has no
similar code that I could identify. And since I'm not an expert on
fonts, I'm stuck.
I've built Emacs with your changes and verified that x-list-fonts
still returns the same number of fonts, and the buffer font selection
dialog still seems to offer the same list of fonts AFAICS.
Can you suggest any further way of testing the patch?
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2015-01-02 9:43 ` Eli Zaretskii
@ 2015-01-02 21:07 ` Dima Kogan
2015-02-02 8:10 ` Dima Kogan
0 siblings, 1 reply; 32+ messages in thread
From: Dima Kogan @ 2015-01-02 21:07 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 19117
Eli Zaretskii <eliz@gnu.org> writes:
> I don't really know how to test these changes on Windows, since most
> of the changes are in xfont.c, and the equivalent w32font.c has no
> similar code that I could identify. And since I'm not an expert on
> fonts, I'm stuck.
>
> I've built Emacs with your changes and verified that x-list-fonts
> still returns the same number of fonts, and the buffer font selection
> dialog still seems to offer the same list of fonts AFAICS.
>
> Can you suggest any further way of testing the patch?
Hi. The patch changes xfont.c (X11-only I believe) and xfaces.c (applies
to Windows as well, I believe).
In xfaces.c it changes the value of scalable-fonts-allowed in some
cases, but that variable is ONLY used in xfont.c. Thus any system that
does not use xfont.c should be unaffected by scalable-fonts-allowed, and
thus this patch.
So I guess the test you already ran is the best you can do: the patch
shouldn't change anything, and you have observed this under nominal
conditions.
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2015-01-02 21:07 ` Dima Kogan
@ 2015-02-02 8:10 ` Dima Kogan
2015-02-03 17:53 ` Stefan Monnier
0 siblings, 1 reply; 32+ messages in thread
From: Dima Kogan @ 2015-02-02 8:10 UTC (permalink / raw)
To: 19117
This is a gentle ping. Is there anything more I can do to get this
merged?
Thanks!
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2015-02-02 8:10 ` Dima Kogan
@ 2015-02-03 17:53 ` Stefan Monnier
2015-02-05 2:41 ` handa
2015-02-05 15:08 ` Jan D.
0 siblings, 2 replies; 32+ messages in thread
From: Stefan Monnier @ 2015-02-03 17:53 UTC (permalink / raw)
To: Dima Kogan; +Cc: 19117
> This is a gentle ping. Is there anything more I can do to get this
> merged?
I could install it, but I really have no idea whether your patch does
the right thing, because I'm too unfamiliar with this code.
Jan? Handa?
Stefan
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2015-02-03 17:53 ` Stefan Monnier
@ 2015-02-05 2:41 ` handa
2015-02-15 13:47 ` K. Handa
2015-02-05 15:08 ` Jan D.
1 sibling, 1 reply; 32+ messages in thread
From: handa @ 2015-02-05 2:41 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 19117, dima
In article <jwvfvamhoh2.fsf-monnier+emacsbugs@gnu.org>, Stefan Monnier <monnier@iro.umontreal.ca> writes:
> > This is a gentle ping. Is there anything more I can do to get this
> > merged?
> I could install it, but I really have no idea whether your patch does
> the right thing, because I'm too unfamiliar with this code.
> Jan? Handa?
I'm currently on a trip, and can't study the patch until
next week, sorry.
---
K. Handa
handa@gnu.org
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2015-02-03 17:53 ` Stefan Monnier
2015-02-05 2:41 ` handa
@ 2015-02-05 15:08 ` Jan D.
2015-02-05 20:41 ` Dima Kogan
1 sibling, 1 reply; 32+ messages in thread
From: Jan D. @ 2015-02-05 15:08 UTC (permalink / raw)
To: Stefan Monnier, Dima Kogan; +Cc: 19117
Stefan Monnier skrev den 2015-02-03 18:53:
>> This is a gentle ping. Is there anything more I can do to get this
>> merged?
>
> I could install it, but I really have no idea whether your patch does
> the right thing, because I'm too unfamiliar with this code.
> Jan? Handa?
>
The patch looks bigger than it is because lot of the diff is just
increased indentation. I guess it looks OK. These old fonts are
deprecated anyway, so if it does the right thing for the OP, I guess we
can install it.
But the comment here:
+ /* We skip the second pass unless we really need it. */
+ if (!(NILP (list) /* No fonts found on
the first pass */
+ && skipped_some_scalable_fonts)) /* and we skipped some
scalable ones. */
+ break;
looks like it really should be /* Fonts found on the first pass */
Jan D.
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2015-02-05 15:08 ` Jan D.
@ 2015-02-05 20:41 ` Dima Kogan
2015-02-07 7:24 ` Jan D.
2015-02-07 7:59 ` Jan D.
0 siblings, 2 replies; 32+ messages in thread
From: Dima Kogan @ 2015-02-05 20:41 UTC (permalink / raw)
To: Jan D.; +Cc: 19117
[-- Attachment #1: Type: text/plain, Size: 606 bytes --]
Jan D. <jan.h.d@swipnet.se> writes:
>
> But the comment here:
>
> + /* We skip the second pass unless we really need it. */
> + if (!(NILP (list) /* No fonts found on
> the first pass */
> + && skipped_some_scalable_fonts)) /* and we skipped some
> scalable ones. */
> + break;
>
>
> looks like it really should be /* Fonts found on the first pass */
There was an ! there, so it made it unclear what the comment is
referring to. Attaching new patches that apply against the current
master, and have a clarified comment in that place
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-scalable-font-logic-now-matches-the-docs-and-is-more.patch --]
[-- Type: text/x-diff, Size: 9005 bytes --]
From 4e895fb38c84342021b602dd4a9830b55fe56a58 Mon Sep 17 00:00:00 2001
From: Dima Kogan <dima@secretsauce.net>
Date: Tue, 30 Dec 2014 20:05:11 -0800
Subject: [PATCH 1/2] scalable font logic now matches the docs and is more
consistent
A nil value of scalable-fonts-allowed allows scalable fonts if no others
were found. This is the previously-documented behavior.
realize_basic_faces() no longer forces scalable-fonts-allowed to t. If
nil, some fonts will always be found even if only scalable fonts are
available, as set by the other part of this patch.
---
src/xfaces.c | 3 --
src/xfont.c | 173 +++++++++++++++++++++++++++++++++--------------------------
2 files changed, 96 insertions(+), 80 deletions(-)
diff --git a/src/xfaces.c b/src/xfaces.c
index 6e01ab0..d0fe872 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -5141,12 +5141,10 @@ static bool
realize_basic_faces (struct frame *f)
{
bool success_p = false;
- ptrdiff_t count = SPECPDL_INDEX ();
/* Block input here so that we won't be surprised by an X expose
event, for instance, without having the faces set up. */
block_input ();
- specbind (Qscalable_fonts_allowed, Qt);
if (realize_default_face (f))
{
@@ -5180,7 +5178,6 @@ realize_basic_faces (struct frame *f)
success_p = true;
}
- unbind_to (count, Qnil);
unblock_input ();
return success_p;
}
diff --git a/src/xfont.c b/src/xfont.c
index 3a0f5e3..5f1c61c 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -388,94 +388,113 @@ xfont_list_pattern (Display *display, const char *pattern,
Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
Lisp_Object scripts = Qnil, entity = Qnil;
+ /* We take two passes over the font list. The second pass is
+ taken only if scalable-fonts-allowed is nil, and only
+ scalable fonts were found.
+ */
+ int i_pass;
+ bool skipped_some_scalable_fonts = false;
+
for (i = 0; i < ASIZE (xfont_scratch_props); i++)
ASET (xfont_scratch_props, i, Qnil);
for (i = 0; i < num_fonts; i++)
indices[i] = names[i];
qsort (indices, num_fonts, sizeof (char *), compare_font_names);
- for (i = 0; i < num_fonts; i++)
- {
- ptrdiff_t len;
+ for (i_pass = 0; i_pass < 2; i_pass++)
+ {
+ for (i = 0; i < num_fonts; i++)
+ {
+ ptrdiff_t len;
- if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
- continue;
- if (NILP (entity))
- entity = font_make_entity ();
- len = xfont_decode_coding_xlfd (indices[i], -1, buf);
- if (font_parse_xlfd (buf, len, entity) < 0)
- continue;
- ASET (entity, FONT_TYPE_INDEX, Qx);
- /* Avoid auto-scaled fonts. */
- if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
- && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
- && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
- && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
- continue;
- /* Avoid not-allowed scalable fonts. */
- if (NILP (Vscalable_fonts_allowed))
- {
- int size = 0;
+ if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
+ continue;
+ if (NILP (entity))
+ entity = font_make_entity ();
+ len = xfont_decode_coding_xlfd (indices[i], -1, buf);
+ if (font_parse_xlfd (buf, len, entity) < 0)
+ continue;
+ ASET (entity, FONT_TYPE_INDEX, Qx);
+ /* Avoid auto-scaled fonts. */
+ if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
+ && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
+ && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
+ && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
+ continue;
+ /* Avoid not-allowed scalable fonts. */
+ if (NILP (Vscalable_fonts_allowed))
+ {
+ int size = 0;
- if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
- size = XINT (AREF (entity, FONT_SIZE_INDEX));
- else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
- size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
- if (size == 0)
- continue;
- }
- else if (CONSP (Vscalable_fonts_allowed))
- {
- Lisp_Object tail, elt;
+ if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
+ size = XINT (AREF (entity, FONT_SIZE_INDEX));
+ else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
+ size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
+ if (size == 0 && i_pass == 0)
+ {
+ skipped_some_scalable_fonts = true;
+ continue;
+ }
+ }
+ else if (CONSP (Vscalable_fonts_allowed))
+ {
+ Lisp_Object tail, elt;
- for (tail = Vscalable_fonts_allowed; CONSP (tail);
- tail = XCDR (tail))
- {
- elt = XCAR (tail);
- if (STRINGP (elt)
- && fast_c_string_match_ignore_case (elt, indices[i],
- len) >= 0)
- break;
- }
- if (! CONSP (tail))
- continue;
- }
+ for (tail = Vscalable_fonts_allowed; CONSP (tail);
+ tail = XCDR (tail))
+ {
+ elt = XCAR (tail);
+ if (STRINGP (elt)
+ && fast_c_string_match_ignore_case (elt, indices[i],
+ len) >= 0)
+ break;
+ }
+ if (! CONSP (tail))
+ continue;
+ }
- /* Avoid fonts of invalid registry. */
- if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
- continue;
+ /* Avoid fonts of invalid registry. */
+ if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
+ continue;
- /* Update encoding and repertory if necessary. */
- if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
- {
- registry = AREF (entity, FONT_REGISTRY_INDEX);
- if (font_registry_charsets (registry, &encoding, &repertory) < 0)
- encoding = NULL;
- }
- if (! encoding)
- /* Unknown REGISTRY, not supported. */
- continue;
- if (repertory)
- {
- if (NILP (script)
- || xfont_chars_supported (chars, NULL, encoding, repertory))
- list = Fcons (entity, list), entity = Qnil;
- continue;
- }
- if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
- word_size * 7)
- || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
- {
- vcopy (xfont_scratch_props, 0,
- aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
- ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
- scripts = xfont_supported_scripts (display, indices[i],
- xfont_scratch_props, encoding);
- }
- if (NILP (script)
- || ! NILP (Fmemq (script, scripts)))
- list = Fcons (entity, list), entity = Qnil;
- }
+ /* Update encoding and repertory if necessary. */
+ if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
+ {
+ registry = AREF (entity, FONT_REGISTRY_INDEX);
+ if (font_registry_charsets (registry, &encoding, &repertory) < 0)
+ encoding = NULL;
+ }
+ if (! encoding)
+ /* Unknown REGISTRY, not supported. */
+ continue;
+ if (repertory)
+ {
+ if (NILP (script)
+ || xfont_chars_supported (chars, NULL, encoding, repertory))
+ list = Fcons (entity, list), entity = Qnil;
+ continue;
+ }
+ if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
+ word_size * 7)
+ || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
+ {
+ vcopy (xfont_scratch_props, 0,
+ aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
+ ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
+ scripts = xfont_supported_scripts (display, indices[i],
+ xfont_scratch_props, encoding);
+ }
+ if (NILP (script)
+ || ! NILP (Fmemq (script, scripts)))
+ list = Fcons (entity, list), entity = Qnil;
+ }
+
+ /* We skip the second pass unless we really need it. */
+ if (! /* Loop again if... */
+ (NILP (list) /* No fonts found on the first pass */
+ && skipped_some_scalable_fonts)) /* and we skipped some scalable ones. */
+ break;
+ }
XFreeFontNames (names);
}
--
2.1.4
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-removed-unused-variable-assignment.patch --]
[-- Type: text/x-diff, Size: 642 bytes --]
From 80bdfb936f9dd24fd8bb0ce0aecc10f796dd4f6f Mon Sep 17 00:00:00 2001
From: Dima Kogan <dima@secretsauce.net>
Date: Tue, 30 Dec 2014 20:05:58 -0800
Subject: [PATCH 2/2] removed unused variable assignment
---
src/font.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/font.c b/src/font.c
index 9ea43cd..b2b43c7 100644
--- a/src/font.c
+++ b/src/font.c
@@ -2136,7 +2136,6 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
}
/* Score the size. Maximum difference is 127. */
- i = FONT_SIZE_INDEX;
if (! NILP (spec_prop[FONT_SIZE_INDEX])
&& XINT (AREF (entity, FONT_SIZE_INDEX)) > 0)
{
--
2.1.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2015-02-05 20:41 ` Dima Kogan
@ 2015-02-07 7:24 ` Jan D.
2015-02-07 7:59 ` Jan D.
1 sibling, 0 replies; 32+ messages in thread
From: Jan D. @ 2015-02-07 7:24 UTC (permalink / raw)
To: Dima Kogan; +Cc: 19117
Hi.
There is a Dmitriy Kogan in the copyright list. Is that you?
Jan D.
> 5 feb 2015 kl. 21:41 skrev Dima Kogan <dima@secretsauce.net>:
>
> Jan D. <jan.h.d@swipnet.se> writes:
>
>>
>> But the comment here:
>>
>> + /* We skip the second pass unless we really need it. */
>> + if (!(NILP (list) /* No fonts found on
>> the first pass */
>> + && skipped_some_scalable_fonts)) /* and we skipped some
>> scalable ones. */
>> + break;
>>
>>
>> looks like it really should be /* Fonts found on the first pass */
>
> There was an ! there, so it made it unclear what the comment is
> referring to. Attaching new patches that apply against the current
> master, and have a clarified comment in that place
>
>> From 4e895fb38c84342021b602dd4a9830b55fe56a58 Mon Sep 17 00:00:00 2001
> From: Dima Kogan <dima@secretsauce.net>
> Date: Tue, 30 Dec 2014 20:05:11 -0800
> Subject: [PATCH 1/2] scalable font logic now matches the docs and is more
> consistent
>
> A nil value of scalable-fonts-allowed allows scalable fonts if no others
> were found. This is the previously-documented behavior.
>
> realize_basic_faces() no longer forces scalable-fonts-allowed to t. If
> nil, some fonts will always be found even if only scalable fonts are
> available, as set by the other part of this patch.
> ---
> src/xfaces.c | 3 --
> src/xfont.c | 173 +++++++++++++++++++++++++++++++++--------------------------
> 2 files changed, 96 insertions(+), 80 deletions(-)
>
> diff --git a/src/xfaces.c b/src/xfaces.c
> index 6e01ab0..d0fe872 100644
> --- a/src/xfaces.c
> +++ b/src/xfaces.c
> @@ -5141,12 +5141,10 @@ static bool
> realize_basic_faces (struct frame *f)
> {
> bool success_p = false;
> - ptrdiff_t count = SPECPDL_INDEX ();
>
> /* Block input here so that we won't be surprised by an X expose
> event, for instance, without having the faces set up. */
> block_input ();
> - specbind (Qscalable_fonts_allowed, Qt);
>
> if (realize_default_face (f))
> {
> @@ -5180,7 +5178,6 @@ realize_basic_faces (struct frame *f)
> success_p = true;
> }
>
> - unbind_to (count, Qnil);
> unblock_input ();
> return success_p;
> }
> diff --git a/src/xfont.c b/src/xfont.c
> index 3a0f5e3..5f1c61c 100644
> --- a/src/xfont.c
> +++ b/src/xfont.c
> @@ -388,94 +388,113 @@ xfont_list_pattern (Display *display, const char *pattern,
> Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
> Lisp_Object scripts = Qnil, entity = Qnil;
>
> + /* We take two passes over the font list. The second pass is
> + taken only if scalable-fonts-allowed is nil, and only
> + scalable fonts were found.
> + */
> + int i_pass;
> + bool skipped_some_scalable_fonts = false;
> +
> for (i = 0; i < ASIZE (xfont_scratch_props); i++)
> ASET (xfont_scratch_props, i, Qnil);
> for (i = 0; i < num_fonts; i++)
> indices[i] = names[i];
> qsort (indices, num_fonts, sizeof (char *), compare_font_names);
>
> - for (i = 0; i < num_fonts; i++)
> - {
> - ptrdiff_t len;
> + for (i_pass = 0; i_pass < 2; i_pass++)
> + {
> + for (i = 0; i < num_fonts; i++)
> + {
> + ptrdiff_t len;
>
> - if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
> - continue;
> - if (NILP (entity))
> - entity = font_make_entity ();
> - len = xfont_decode_coding_xlfd (indices[i], -1, buf);
> - if (font_parse_xlfd (buf, len, entity) < 0)
> - continue;
> - ASET (entity, FONT_TYPE_INDEX, Qx);
> - /* Avoid auto-scaled fonts. */
> - if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
> - && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
> - && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
> - && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
> - continue;
> - /* Avoid not-allowed scalable fonts. */
> - if (NILP (Vscalable_fonts_allowed))
> - {
> - int size = 0;
> + if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
> + continue;
> + if (NILP (entity))
> + entity = font_make_entity ();
> + len = xfont_decode_coding_xlfd (indices[i], -1, buf);
> + if (font_parse_xlfd (buf, len, entity) < 0)
> + continue;
> + ASET (entity, FONT_TYPE_INDEX, Qx);
> + /* Avoid auto-scaled fonts. */
> + if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
> + && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
> + && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
> + && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
> + continue;
> + /* Avoid not-allowed scalable fonts. */
> + if (NILP (Vscalable_fonts_allowed))
> + {
> + int size = 0;
>
> - if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
> - size = XINT (AREF (entity, FONT_SIZE_INDEX));
> - else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
> - size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
> - if (size == 0)
> - continue;
> - }
> - else if (CONSP (Vscalable_fonts_allowed))
> - {
> - Lisp_Object tail, elt;
> + if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
> + size = XINT (AREF (entity, FONT_SIZE_INDEX));
> + else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
> + size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
> + if (size == 0 && i_pass == 0)
> + {
> + skipped_some_scalable_fonts = true;
> + continue;
> + }
> + }
> + else if (CONSP (Vscalable_fonts_allowed))
> + {
> + Lisp_Object tail, elt;
>
> - for (tail = Vscalable_fonts_allowed; CONSP (tail);
> - tail = XCDR (tail))
> - {
> - elt = XCAR (tail);
> - if (STRINGP (elt)
> - && fast_c_string_match_ignore_case (elt, indices[i],
> - len) >= 0)
> - break;
> - }
> - if (! CONSP (tail))
> - continue;
> - }
> + for (tail = Vscalable_fonts_allowed; CONSP (tail);
> + tail = XCDR (tail))
> + {
> + elt = XCAR (tail);
> + if (STRINGP (elt)
> + && fast_c_string_match_ignore_case (elt, indices[i],
> + len) >= 0)
> + break;
> + }
> + if (! CONSP (tail))
> + continue;
> + }
>
> - /* Avoid fonts of invalid registry. */
> - if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
> - continue;
> + /* Avoid fonts of invalid registry. */
> + if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
> + continue;
>
> - /* Update encoding and repertory if necessary. */
> - if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
> - {
> - registry = AREF (entity, FONT_REGISTRY_INDEX);
> - if (font_registry_charsets (registry, &encoding, &repertory) < 0)
> - encoding = NULL;
> - }
> - if (! encoding)
> - /* Unknown REGISTRY, not supported. */
> - continue;
> - if (repertory)
> - {
> - if (NILP (script)
> - || xfont_chars_supported (chars, NULL, encoding, repertory))
> - list = Fcons (entity, list), entity = Qnil;
> - continue;
> - }
> - if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
> - word_size * 7)
> - || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
> - {
> - vcopy (xfont_scratch_props, 0,
> - aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
> - ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
> - scripts = xfont_supported_scripts (display, indices[i],
> - xfont_scratch_props, encoding);
> - }
> - if (NILP (script)
> - || ! NILP (Fmemq (script, scripts)))
> - list = Fcons (entity, list), entity = Qnil;
> - }
> + /* Update encoding and repertory if necessary. */
> + if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
> + {
> + registry = AREF (entity, FONT_REGISTRY_INDEX);
> + if (font_registry_charsets (registry, &encoding, &repertory) < 0)
> + encoding = NULL;
> + }
> + if (! encoding)
> + /* Unknown REGISTRY, not supported. */
> + continue;
> + if (repertory)
> + {
> + if (NILP (script)
> + || xfont_chars_supported (chars, NULL, encoding, repertory))
> + list = Fcons (entity, list), entity = Qnil;
> + continue;
> + }
> + if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
> + word_size * 7)
> + || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
> + {
> + vcopy (xfont_scratch_props, 0,
> + aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
> + ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
> + scripts = xfont_supported_scripts (display, indices[i],
> + xfont_scratch_props, encoding);
> + }
> + if (NILP (script)
> + || ! NILP (Fmemq (script, scripts)))
> + list = Fcons (entity, list), entity = Qnil;
> + }
> +
> + /* We skip the second pass unless we really need it. */
> + if (! /* Loop again if... */
> + (NILP (list) /* No fonts found on the first pass */
> + && skipped_some_scalable_fonts)) /* and we skipped some scalable ones. */
> + break;
> + }
> XFreeFontNames (names);
> }
>
> --
> 2.1.4
>
>> From 80bdfb936f9dd24fd8bb0ce0aecc10f796dd4f6f Mon Sep 17 00:00:00 2001
> From: Dima Kogan <dima@secretsauce.net>
> Date: Tue, 30 Dec 2014 20:05:58 -0800
> Subject: [PATCH 2/2] removed unused variable assignment
>
> ---
> src/font.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/src/font.c b/src/font.c
> index 9ea43cd..b2b43c7 100644
> --- a/src/font.c
> +++ b/src/font.c
> @@ -2136,7 +2136,6 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
> }
>
> /* Score the size. Maximum difference is 127. */
> - i = FONT_SIZE_INDEX;
> if (! NILP (spec_prop[FONT_SIZE_INDEX])
> && XINT (AREF (entity, FONT_SIZE_INDEX)) > 0)
> {
> --
> 2.1.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2015-02-05 20:41 ` Dima Kogan
2015-02-07 7:24 ` Jan D.
@ 2015-02-07 7:59 ` Jan D.
2015-02-07 8:28 ` Dima Kogan
1 sibling, 1 reply; 32+ messages in thread
From: Jan D. @ 2015-02-07 7:59 UTC (permalink / raw)
To: Dima Kogan; +Cc: 19117
Can you add ChangeLog entries for this so we can install it?
Thanks,
Jan D.
> 5 feb 2015 kl. 21:41 skrev Dima Kogan <dima@secretsauce.net>:
>
> Jan D. <jan.h.d@swipnet.se> writes:
>
>>
>> But the comment here:
>>
>> + /* We skip the second pass unless we really need it. */
>> + if (!(NILP (list) /* No fonts found on
>> the first pass */
>> + && skipped_some_scalable_fonts)) /* and we skipped some
>> scalable ones. */
>> + break;
>>
>>
>> looks like it really should be /* Fonts found on the first pass */
>
> There was an ! there, so it made it unclear what the comment is
> referring to. Attaching new patches that apply against the current
> master, and have a clarified comment in that place
>
>> From 4e895fb38c84342021b602dd4a9830b55fe56a58 Mon Sep 17 00:00:00 2001
> From: Dima Kogan <dima@secretsauce.net>
> Date: Tue, 30 Dec 2014 20:05:11 -0800
> Subject: [PATCH 1/2] scalable font logic now matches the docs and is more
> consistent
>
> A nil value of scalable-fonts-allowed allows scalable fonts if no others
> were found. This is the previously-documented behavior.
>
> realize_basic_faces() no longer forces scalable-fonts-allowed to t. If
> nil, some fonts will always be found even if only scalable fonts are
> available, as set by the other part of this patch.
> ---
> src/xfaces.c | 3 --
> src/xfont.c | 173 +++++++++++++++++++++++++++++++++--------------------------
> 2 files changed, 96 insertions(+), 80 deletions(-)
>
> diff --git a/src/xfaces.c b/src/xfaces.c
> index 6e01ab0..d0fe872 100644
> --- a/src/xfaces.c
> +++ b/src/xfaces.c
> @@ -5141,12 +5141,10 @@ static bool
> realize_basic_faces (struct frame *f)
> {
> bool success_p = false;
> - ptrdiff_t count = SPECPDL_INDEX ();
>
> /* Block input here so that we won't be surprised by an X expose
> event, for instance, without having the faces set up. */
> block_input ();
> - specbind (Qscalable_fonts_allowed, Qt);
>
> if (realize_default_face (f))
> {
> @@ -5180,7 +5178,6 @@ realize_basic_faces (struct frame *f)
> success_p = true;
> }
>
> - unbind_to (count, Qnil);
> unblock_input ();
> return success_p;
> }
> diff --git a/src/xfont.c b/src/xfont.c
> index 3a0f5e3..5f1c61c 100644
> --- a/src/xfont.c
> +++ b/src/xfont.c
> @@ -388,94 +388,113 @@ xfont_list_pattern (Display *display, const char *pattern,
> Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
> Lisp_Object scripts = Qnil, entity = Qnil;
>
> + /* We take two passes over the font list. The second pass is
> + taken only if scalable-fonts-allowed is nil, and only
> + scalable fonts were found.
> + */
> + int i_pass;
> + bool skipped_some_scalable_fonts = false;
> +
> for (i = 0; i < ASIZE (xfont_scratch_props); i++)
> ASET (xfont_scratch_props, i, Qnil);
> for (i = 0; i < num_fonts; i++)
> indices[i] = names[i];
> qsort (indices, num_fonts, sizeof (char *), compare_font_names);
>
> - for (i = 0; i < num_fonts; i++)
> - {
> - ptrdiff_t len;
> + for (i_pass = 0; i_pass < 2; i_pass++)
> + {
> + for (i = 0; i < num_fonts; i++)
> + {
> + ptrdiff_t len;
>
> - if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
> - continue;
> - if (NILP (entity))
> - entity = font_make_entity ();
> - len = xfont_decode_coding_xlfd (indices[i], -1, buf);
> - if (font_parse_xlfd (buf, len, entity) < 0)
> - continue;
> - ASET (entity, FONT_TYPE_INDEX, Qx);
> - /* Avoid auto-scaled fonts. */
> - if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
> - && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
> - && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
> - && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
> - continue;
> - /* Avoid not-allowed scalable fonts. */
> - if (NILP (Vscalable_fonts_allowed))
> - {
> - int size = 0;
> + if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
> + continue;
> + if (NILP (entity))
> + entity = font_make_entity ();
> + len = xfont_decode_coding_xlfd (indices[i], -1, buf);
> + if (font_parse_xlfd (buf, len, entity) < 0)
> + continue;
> + ASET (entity, FONT_TYPE_INDEX, Qx);
> + /* Avoid auto-scaled fonts. */
> + if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
> + && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
> + && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
> + && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
> + continue;
> + /* Avoid not-allowed scalable fonts. */
> + if (NILP (Vscalable_fonts_allowed))
> + {
> + int size = 0;
>
> - if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
> - size = XINT (AREF (entity, FONT_SIZE_INDEX));
> - else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
> - size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
> - if (size == 0)
> - continue;
> - }
> - else if (CONSP (Vscalable_fonts_allowed))
> - {
> - Lisp_Object tail, elt;
> + if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
> + size = XINT (AREF (entity, FONT_SIZE_INDEX));
> + else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
> + size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
> + if (size == 0 && i_pass == 0)
> + {
> + skipped_some_scalable_fonts = true;
> + continue;
> + }
> + }
> + else if (CONSP (Vscalable_fonts_allowed))
> + {
> + Lisp_Object tail, elt;
>
> - for (tail = Vscalable_fonts_allowed; CONSP (tail);
> - tail = XCDR (tail))
> - {
> - elt = XCAR (tail);
> - if (STRINGP (elt)
> - && fast_c_string_match_ignore_case (elt, indices[i],
> - len) >= 0)
> - break;
> - }
> - if (! CONSP (tail))
> - continue;
> - }
> + for (tail = Vscalable_fonts_allowed; CONSP (tail);
> + tail = XCDR (tail))
> + {
> + elt = XCAR (tail);
> + if (STRINGP (elt)
> + && fast_c_string_match_ignore_case (elt, indices[i],
> + len) >= 0)
> + break;
> + }
> + if (! CONSP (tail))
> + continue;
> + }
>
> - /* Avoid fonts of invalid registry. */
> - if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
> - continue;
> + /* Avoid fonts of invalid registry. */
> + if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
> + continue;
>
> - /* Update encoding and repertory if necessary. */
> - if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
> - {
> - registry = AREF (entity, FONT_REGISTRY_INDEX);
> - if (font_registry_charsets (registry, &encoding, &repertory) < 0)
> - encoding = NULL;
> - }
> - if (! encoding)
> - /* Unknown REGISTRY, not supported. */
> - continue;
> - if (repertory)
> - {
> - if (NILP (script)
> - || xfont_chars_supported (chars, NULL, encoding, repertory))
> - list = Fcons (entity, list), entity = Qnil;
> - continue;
> - }
> - if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
> - word_size * 7)
> - || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
> - {
> - vcopy (xfont_scratch_props, 0,
> - aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
> - ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
> - scripts = xfont_supported_scripts (display, indices[i],
> - xfont_scratch_props, encoding);
> - }
> - if (NILP (script)
> - || ! NILP (Fmemq (script, scripts)))
> - list = Fcons (entity, list), entity = Qnil;
> - }
> + /* Update encoding and repertory if necessary. */
> + if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
> + {
> + registry = AREF (entity, FONT_REGISTRY_INDEX);
> + if (font_registry_charsets (registry, &encoding, &repertory) < 0)
> + encoding = NULL;
> + }
> + if (! encoding)
> + /* Unknown REGISTRY, not supported. */
> + continue;
> + if (repertory)
> + {
> + if (NILP (script)
> + || xfont_chars_supported (chars, NULL, encoding, repertory))
> + list = Fcons (entity, list), entity = Qnil;
> + continue;
> + }
> + if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
> + word_size * 7)
> + || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
> + {
> + vcopy (xfont_scratch_props, 0,
> + aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
> + ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
> + scripts = xfont_supported_scripts (display, indices[i],
> + xfont_scratch_props, encoding);
> + }
> + if (NILP (script)
> + || ! NILP (Fmemq (script, scripts)))
> + list = Fcons (entity, list), entity = Qnil;
> + }
> +
> + /* We skip the second pass unless we really need it. */
> + if (! /* Loop again if... */
> + (NILP (list) /* No fonts found on the first pass */
> + && skipped_some_scalable_fonts)) /* and we skipped some scalable ones. */
> + break;
> + }
> XFreeFontNames (names);
> }
>
> --
> 2.1.4
>
>> From 80bdfb936f9dd24fd8bb0ce0aecc10f796dd4f6f Mon Sep 17 00:00:00 2001
> From: Dima Kogan <dima@secretsauce.net>
> Date: Tue, 30 Dec 2014 20:05:58 -0800
> Subject: [PATCH 2/2] removed unused variable assignment
>
> ---
> src/font.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/src/font.c b/src/font.c
> index 9ea43cd..b2b43c7 100644
> --- a/src/font.c
> +++ b/src/font.c
> @@ -2136,7 +2136,6 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
> }
>
> /* Score the size. Maximum difference is 127. */
> - i = FONT_SIZE_INDEX;
> if (! NILP (spec_prop[FONT_SIZE_INDEX])
> && XINT (AREF (entity, FONT_SIZE_INDEX)) > 0)
> {
> --
> 2.1.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2015-02-07 7:59 ` Jan D.
@ 2015-02-07 8:28 ` Dima Kogan
2015-02-09 14:58 ` Jan D.
0 siblings, 1 reply; 32+ messages in thread
From: Dima Kogan @ 2015-02-07 8:28 UTC (permalink / raw)
To: Jan D.; +Cc: 19117
[-- Attachment #1: Type: text/plain, Size: 248 bytes --]
Jan D. <jan.h.d@swipnet.se> writes:
> Can you add ChangeLog entries for this so we can install it?
Attached. Let me know if there are issues with the changelog style.
Also, I'm including everything in one patch. It was mostly like that
already.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-scalable-font-logic-now-matches-the-docs-and-is-more.patch --]
[-- Type: text/x-diff, Size: 9881 bytes --]
From 2380816e2160236b35f06eed63839f5e71280686 Mon Sep 17 00:00:00 2001
From: Dima Kogan <dima@secretsauce.net>
Date: Tue, 30 Dec 2014 20:05:11 -0800
Subject: [PATCH] scalable font logic now matches the docs and is more
consistent
A nil value of scalable-fonts-allowed allows scalable fonts if no others
were found. This is the previously-documented behavior.
realize_basic_faces() no longer forces scalable-fonts-allowed to t. If
nil, some fonts will always be found even if only scalable fonts are
available, as set by the other part of this patch.
---
src/ChangeLog | 8 +++
src/font.c | 1 -
src/xfaces.c | 3 -
src/xfont.c | 173 ++++++++++++++++++++++++++++++++--------------------------
4 files changed, 104 insertions(+), 81 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index cd72f98..d189b7e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
+2015-02-07 Dima Kogan <dima@secretsauce.net>
+
+ * xfont.c (xfont_list_pattern):
+ * xfaces.c (realize_basic_faces):
+ * font.c (font_score): scalable font logic now matches the docs
+ and is more consistent
+ Fixes: bug#19117
+
2015-02-07 Paul Eggert <eggert@cs.ucla.edu>
Remove no-longer-used cursor_in_echo_area code
diff --git a/src/font.c b/src/font.c
index 9ea43cd..b2b43c7 100644
--- a/src/font.c
+++ b/src/font.c
@@ -2136,7 +2136,6 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
}
/* Score the size. Maximum difference is 127. */
- i = FONT_SIZE_INDEX;
if (! NILP (spec_prop[FONT_SIZE_INDEX])
&& XINT (AREF (entity, FONT_SIZE_INDEX)) > 0)
{
diff --git a/src/xfaces.c b/src/xfaces.c
index 6e01ab0..d0fe872 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -5141,12 +5141,10 @@ static bool
realize_basic_faces (struct frame *f)
{
bool success_p = false;
- ptrdiff_t count = SPECPDL_INDEX ();
/* Block input here so that we won't be surprised by an X expose
event, for instance, without having the faces set up. */
block_input ();
- specbind (Qscalable_fonts_allowed, Qt);
if (realize_default_face (f))
{
@@ -5180,7 +5178,6 @@ realize_basic_faces (struct frame *f)
success_p = true;
}
- unbind_to (count, Qnil);
unblock_input ();
return success_p;
}
diff --git a/src/xfont.c b/src/xfont.c
index 3a0f5e3..5f1c61c 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -388,94 +388,113 @@ xfont_list_pattern (Display *display, const char *pattern,
Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
Lisp_Object scripts = Qnil, entity = Qnil;
+ /* We take two passes over the font list. The second pass is
+ taken only if scalable-fonts-allowed is nil, and only
+ scalable fonts were found.
+ */
+ int i_pass;
+ bool skipped_some_scalable_fonts = false;
+
for (i = 0; i < ASIZE (xfont_scratch_props); i++)
ASET (xfont_scratch_props, i, Qnil);
for (i = 0; i < num_fonts; i++)
indices[i] = names[i];
qsort (indices, num_fonts, sizeof (char *), compare_font_names);
- for (i = 0; i < num_fonts; i++)
- {
- ptrdiff_t len;
+ for (i_pass = 0; i_pass < 2; i_pass++)
+ {
+ for (i = 0; i < num_fonts; i++)
+ {
+ ptrdiff_t len;
- if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
- continue;
- if (NILP (entity))
- entity = font_make_entity ();
- len = xfont_decode_coding_xlfd (indices[i], -1, buf);
- if (font_parse_xlfd (buf, len, entity) < 0)
- continue;
- ASET (entity, FONT_TYPE_INDEX, Qx);
- /* Avoid auto-scaled fonts. */
- if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
- && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
- && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
- && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
- continue;
- /* Avoid not-allowed scalable fonts. */
- if (NILP (Vscalable_fonts_allowed))
- {
- int size = 0;
+ if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
+ continue;
+ if (NILP (entity))
+ entity = font_make_entity ();
+ len = xfont_decode_coding_xlfd (indices[i], -1, buf);
+ if (font_parse_xlfd (buf, len, entity) < 0)
+ continue;
+ ASET (entity, FONT_TYPE_INDEX, Qx);
+ /* Avoid auto-scaled fonts. */
+ if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
+ && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
+ && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
+ && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
+ continue;
+ /* Avoid not-allowed scalable fonts. */
+ if (NILP (Vscalable_fonts_allowed))
+ {
+ int size = 0;
- if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
- size = XINT (AREF (entity, FONT_SIZE_INDEX));
- else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
- size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
- if (size == 0)
- continue;
- }
- else if (CONSP (Vscalable_fonts_allowed))
- {
- Lisp_Object tail, elt;
+ if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
+ size = XINT (AREF (entity, FONT_SIZE_INDEX));
+ else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
+ size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
+ if (size == 0 && i_pass == 0)
+ {
+ skipped_some_scalable_fonts = true;
+ continue;
+ }
+ }
+ else if (CONSP (Vscalable_fonts_allowed))
+ {
+ Lisp_Object tail, elt;
- for (tail = Vscalable_fonts_allowed; CONSP (tail);
- tail = XCDR (tail))
- {
- elt = XCAR (tail);
- if (STRINGP (elt)
- && fast_c_string_match_ignore_case (elt, indices[i],
- len) >= 0)
- break;
- }
- if (! CONSP (tail))
- continue;
- }
+ for (tail = Vscalable_fonts_allowed; CONSP (tail);
+ tail = XCDR (tail))
+ {
+ elt = XCAR (tail);
+ if (STRINGP (elt)
+ && fast_c_string_match_ignore_case (elt, indices[i],
+ len) >= 0)
+ break;
+ }
+ if (! CONSP (tail))
+ continue;
+ }
- /* Avoid fonts of invalid registry. */
- if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
- continue;
+ /* Avoid fonts of invalid registry. */
+ if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
+ continue;
- /* Update encoding and repertory if necessary. */
- if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
- {
- registry = AREF (entity, FONT_REGISTRY_INDEX);
- if (font_registry_charsets (registry, &encoding, &repertory) < 0)
- encoding = NULL;
- }
- if (! encoding)
- /* Unknown REGISTRY, not supported. */
- continue;
- if (repertory)
- {
- if (NILP (script)
- || xfont_chars_supported (chars, NULL, encoding, repertory))
- list = Fcons (entity, list), entity = Qnil;
- continue;
- }
- if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
- word_size * 7)
- || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
- {
- vcopy (xfont_scratch_props, 0,
- aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
- ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
- scripts = xfont_supported_scripts (display, indices[i],
- xfont_scratch_props, encoding);
- }
- if (NILP (script)
- || ! NILP (Fmemq (script, scripts)))
- list = Fcons (entity, list), entity = Qnil;
- }
+ /* Update encoding and repertory if necessary. */
+ if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
+ {
+ registry = AREF (entity, FONT_REGISTRY_INDEX);
+ if (font_registry_charsets (registry, &encoding, &repertory) < 0)
+ encoding = NULL;
+ }
+ if (! encoding)
+ /* Unknown REGISTRY, not supported. */
+ continue;
+ if (repertory)
+ {
+ if (NILP (script)
+ || xfont_chars_supported (chars, NULL, encoding, repertory))
+ list = Fcons (entity, list), entity = Qnil;
+ continue;
+ }
+ if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
+ word_size * 7)
+ || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
+ {
+ vcopy (xfont_scratch_props, 0,
+ aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
+ ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
+ scripts = xfont_supported_scripts (display, indices[i],
+ xfont_scratch_props, encoding);
+ }
+ if (NILP (script)
+ || ! NILP (Fmemq (script, scripts)))
+ list = Fcons (entity, list), entity = Qnil;
+ }
+
+ /* We skip the second pass unless we really need it. */
+ if (! /* Loop again if... */
+ (NILP (list) /* No fonts found on the first pass */
+ && skipped_some_scalable_fonts)) /* and we skipped some scalable ones. */
+ break;
+ }
XFreeFontNames (names);
}
--
2.1.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2015-02-07 8:28 ` Dima Kogan
@ 2015-02-09 14:58 ` Jan D.
0 siblings, 0 replies; 32+ messages in thread
From: Jan D. @ 2015-02-09 14:58 UTC (permalink / raw)
To: Dima Kogan; +Cc: 19117-done
Commited.
> 7 feb 2015 kl. 09:28 skrev Dima Kogan <dima@secretsauce.net>:
>
> Jan D. <jan.h.d@swipnet.se> writes:
>
>> Can you add ChangeLog entries for this so we can install it?
>
> Attached. Let me know if there are issues with the changelog style.
Many, I rewrote them.
Jan D.
> Also, I'm including everything in one patch. It was mostly like that
> already.
>
>> From 2380816e2160236b35f06eed63839f5e71280686 Mon Sep 17 00:00:00 2001
> From: Dima Kogan <dima@secretsauce.net>
> Date: Tue, 30 Dec 2014 20:05:11 -0800
> Subject: [PATCH] scalable font logic now matches the docs and is more
> consistent
>
> A nil value of scalable-fonts-allowed allows scalable fonts if no others
> were found. This is the previously-documented behavior.
>
> realize_basic_faces() no longer forces scalable-fonts-allowed to t. If
> nil, some fonts will always be found even if only scalable fonts are
> available, as set by the other part of this patch.
> ---
> src/ChangeLog | 8 +++
> src/font.c | 1 -
> src/xfaces.c | 3 -
> src/xfont.c | 173 ++++++++++++++++++++++++++++++++--------------------------
> 4 files changed, 104 insertions(+), 81 deletions(-)
>
> diff --git a/src/ChangeLog b/src/ChangeLog
> index cd72f98..d189b7e 100644
> --- a/src/ChangeLog
> +++ b/src/ChangeLog
> @@ -1,3 +1,11 @@
> +2015-02-07 Dima Kogan <dima@secretsauce.net>
> +
> + * xfont.c (xfont_list_pattern):
> + * xfaces.c (realize_basic_faces):
> + * font.c (font_score): scalable font logic now matches the docs
> + and is more consistent
> + Fixes: bug#19117
> +
> 2015-02-07 Paul Eggert <eggert@cs.ucla.edu>
>
> Remove no-longer-used cursor_in_echo_area code
> diff --git a/src/font.c b/src/font.c
> index 9ea43cd..b2b43c7 100644
> --- a/src/font.c
> +++ b/src/font.c
> @@ -2136,7 +2136,6 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
> }
>
> /* Score the size. Maximum difference is 127. */
> - i = FONT_SIZE_INDEX;
> if (! NILP (spec_prop[FONT_SIZE_INDEX])
> && XINT (AREF (entity, FONT_SIZE_INDEX)) > 0)
> {
> diff --git a/src/xfaces.c b/src/xfaces.c
> index 6e01ab0..d0fe872 100644
> --- a/src/xfaces.c
> +++ b/src/xfaces.c
> @@ -5141,12 +5141,10 @@ static bool
> realize_basic_faces (struct frame *f)
> {
> bool success_p = false;
> - ptrdiff_t count = SPECPDL_INDEX ();
>
> /* Block input here so that we won't be surprised by an X expose
> event, for instance, without having the faces set up. */
> block_input ();
> - specbind (Qscalable_fonts_allowed, Qt);
>
> if (realize_default_face (f))
> {
> @@ -5180,7 +5178,6 @@ realize_basic_faces (struct frame *f)
> success_p = true;
> }
>
> - unbind_to (count, Qnil);
> unblock_input ();
> return success_p;
> }
> diff --git a/src/xfont.c b/src/xfont.c
> index 3a0f5e3..5f1c61c 100644
> --- a/src/xfont.c
> +++ b/src/xfont.c
> @@ -388,94 +388,113 @@ xfont_list_pattern (Display *display, const char *pattern,
> Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
> Lisp_Object scripts = Qnil, entity = Qnil;
>
> + /* We take two passes over the font list. The second pass is
> + taken only if scalable-fonts-allowed is nil, and only
> + scalable fonts were found.
> + */
> + int i_pass;
> + bool skipped_some_scalable_fonts = false;
> +
> for (i = 0; i < ASIZE (xfont_scratch_props); i++)
> ASET (xfont_scratch_props, i, Qnil);
> for (i = 0; i < num_fonts; i++)
> indices[i] = names[i];
> qsort (indices, num_fonts, sizeof (char *), compare_font_names);
>
> - for (i = 0; i < num_fonts; i++)
> - {
> - ptrdiff_t len;
> + for (i_pass = 0; i_pass < 2; i_pass++)
> + {
> + for (i = 0; i < num_fonts; i++)
> + {
> + ptrdiff_t len;
>
> - if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
> - continue;
> - if (NILP (entity))
> - entity = font_make_entity ();
> - len = xfont_decode_coding_xlfd (indices[i], -1, buf);
> - if (font_parse_xlfd (buf, len, entity) < 0)
> - continue;
> - ASET (entity, FONT_TYPE_INDEX, Qx);
> - /* Avoid auto-scaled fonts. */
> - if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
> - && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
> - && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
> - && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
> - continue;
> - /* Avoid not-allowed scalable fonts. */
> - if (NILP (Vscalable_fonts_allowed))
> - {
> - int size = 0;
> + if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
> + continue;
> + if (NILP (entity))
> + entity = font_make_entity ();
> + len = xfont_decode_coding_xlfd (indices[i], -1, buf);
> + if (font_parse_xlfd (buf, len, entity) < 0)
> + continue;
> + ASET (entity, FONT_TYPE_INDEX, Qx);
> + /* Avoid auto-scaled fonts. */
> + if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
> + && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
> + && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
> + && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
> + continue;
> + /* Avoid not-allowed scalable fonts. */
> + if (NILP (Vscalable_fonts_allowed))
> + {
> + int size = 0;
>
> - if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
> - size = XINT (AREF (entity, FONT_SIZE_INDEX));
> - else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
> - size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
> - if (size == 0)
> - continue;
> - }
> - else if (CONSP (Vscalable_fonts_allowed))
> - {
> - Lisp_Object tail, elt;
> + if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
> + size = XINT (AREF (entity, FONT_SIZE_INDEX));
> + else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
> + size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
> + if (size == 0 && i_pass == 0)
> + {
> + skipped_some_scalable_fonts = true;
> + continue;
> + }
> + }
> + else if (CONSP (Vscalable_fonts_allowed))
> + {
> + Lisp_Object tail, elt;
>
> - for (tail = Vscalable_fonts_allowed; CONSP (tail);
> - tail = XCDR (tail))
> - {
> - elt = XCAR (tail);
> - if (STRINGP (elt)
> - && fast_c_string_match_ignore_case (elt, indices[i],
> - len) >= 0)
> - break;
> - }
> - if (! CONSP (tail))
> - continue;
> - }
> + for (tail = Vscalable_fonts_allowed; CONSP (tail);
> + tail = XCDR (tail))
> + {
> + elt = XCAR (tail);
> + if (STRINGP (elt)
> + && fast_c_string_match_ignore_case (elt, indices[i],
> + len) >= 0)
> + break;
> + }
> + if (! CONSP (tail))
> + continue;
> + }
>
> - /* Avoid fonts of invalid registry. */
> - if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
> - continue;
> + /* Avoid fonts of invalid registry. */
> + if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
> + continue;
>
> - /* Update encoding and repertory if necessary. */
> - if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
> - {
> - registry = AREF (entity, FONT_REGISTRY_INDEX);
> - if (font_registry_charsets (registry, &encoding, &repertory) < 0)
> - encoding = NULL;
> - }
> - if (! encoding)
> - /* Unknown REGISTRY, not supported. */
> - continue;
> - if (repertory)
> - {
> - if (NILP (script)
> - || xfont_chars_supported (chars, NULL, encoding, repertory))
> - list = Fcons (entity, list), entity = Qnil;
> - continue;
> - }
> - if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
> - word_size * 7)
> - || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
> - {
> - vcopy (xfont_scratch_props, 0,
> - aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
> - ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
> - scripts = xfont_supported_scripts (display, indices[i],
> - xfont_scratch_props, encoding);
> - }
> - if (NILP (script)
> - || ! NILP (Fmemq (script, scripts)))
> - list = Fcons (entity, list), entity = Qnil;
> - }
> + /* Update encoding and repertory if necessary. */
> + if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
> + {
> + registry = AREF (entity, FONT_REGISTRY_INDEX);
> + if (font_registry_charsets (registry, &encoding, &repertory) < 0)
> + encoding = NULL;
> + }
> + if (! encoding)
> + /* Unknown REGISTRY, not supported. */
> + continue;
> + if (repertory)
> + {
> + if (NILP (script)
> + || xfont_chars_supported (chars, NULL, encoding, repertory))
> + list = Fcons (entity, list), entity = Qnil;
> + continue;
> + }
> + if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
> + word_size * 7)
> + || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
> + {
> + vcopy (xfont_scratch_props, 0,
> + aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
> + ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
> + scripts = xfont_supported_scripts (display, indices[i],
> + xfont_scratch_props, encoding);
> + }
> + if (NILP (script)
> + || ! NILP (Fmemq (script, scripts)))
> + list = Fcons (entity, list), entity = Qnil;
> + }
> +
> + /* We skip the second pass unless we really need it. */
> + if (! /* Loop again if... */
> + (NILP (list) /* No fonts found on the first pass */
> + && skipped_some_scalable_fonts)) /* and we skipped some scalable ones. */
> + break;
> + }
> XFreeFontNames (names);
> }
>
> --
> 2.1.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes
2015-02-05 2:41 ` handa
@ 2015-02-15 13:47 ` K. Handa
0 siblings, 0 replies; 32+ messages in thread
From: K. Handa @ 2015-02-15 13:47 UTC (permalink / raw)
To: 19117; +Cc: dima
In article <87bnl9nkqe.fsf@gnu.org>, handa <handa@gnu.org> writes:
> In article <jwvfvamhoh2.fsf-monnier+emacsbugs@gnu.org>, Stefan Monnier <monnier@iro.umontreal.ca> writes:
> > > This is a gentle ping. Is there anything more I can do to get this
> > > merged?
> > I could install it, but I really have no idea whether your patch does
> > the right thing, because I'm too unfamiliar with this code.
> > Jan? Handa?
Sorry for the late response. I agree that the patch is
doing the correct thing, but it seems that it overlooks the
case of scalable-fonts-allowed being a cons:
else if (CONSP (Vscalable_fonts_allowed))
{
Lisp_Object tail;
for (tail = Vscalable_fonts_allowed; CONSP (tail);
tail = XCDR (tail))
{
Lisp_Object elt = XCAR (tail);
if (STRINGP (elt)
&& (fast_c_string_match_ignore_case (elt, indices[i],
len)
>= 0))
break;
}
if (! CONSP (tail))
continue;
}
Here too, skipped_some_scalable_fonts must be set to true
before "continue;".
And, one trivial comment on ChangeLog entry :-p
* xfaces.c (realize_basic_faces): Don't set Qscalable_fonts_allowed to
t.
Isn't it better to use the pair Qscalable_fonts_allowed and
Qt, or the pair scalable-fonts-allowed and t?
---
Kenichi Handa
handa@gnu.org
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2015-02-15 13:47 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-20 6:13 bug#19117: 25.0.50; emacs on x11 chooses different fonts for the same face sometimes Dima Kogan
2014-11-20 16:10 ` Eli Zaretskii
2014-12-07 7:28 ` Dima Kogan
2014-12-07 16:12 ` Eli Zaretskii
2014-12-17 5:36 ` Dima Kogan
2014-12-17 6:57 ` Dima Kogan
2014-12-18 16:24 ` Eli Zaretskii
2014-12-20 8:08 ` Jan Djärv
2014-12-19 15:28 ` Dmitry Antipov
2014-12-19 22:46 ` Dima Kogan
2014-12-22 8:01 ` Dmitry Antipov
2014-12-22 8:28 ` Jan Djärv
2014-12-26 19:43 ` Dima Kogan
2014-12-27 2:17 ` Stefan Monnier
2014-12-27 9:17 ` Dima Kogan
2014-12-30 9:44 ` Dima Kogan
2014-12-30 16:57 ` Stefan Monnier
2014-12-30 18:33 ` Dima Kogan
2014-12-30 20:05 ` Eli Zaretskii
2014-12-31 4:06 ` Dima Kogan
2015-01-02 9:43 ` Eli Zaretskii
2015-01-02 21:07 ` Dima Kogan
2015-02-02 8:10 ` Dima Kogan
2015-02-03 17:53 ` Stefan Monnier
2015-02-05 2:41 ` handa
2015-02-15 13:47 ` K. Handa
2015-02-05 15:08 ` Jan D.
2015-02-05 20:41 ` Dima Kogan
2015-02-07 7:24 ` Jan D.
2015-02-07 7:59 ` Jan D.
2015-02-07 8:28 ` Dima Kogan
2015-02-09 14:58 ` Jan D.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).