1

I have two different desktop hosts connected via their DisplayPort outputs to two DisplayPort inputs on the same 4K monitor:

  • idyllic, a small-form-factor PC using the onboard Intel HD Graphics 500 of its Celeron N3350 processor. (I've also a similar system at another location with a Pentium N4200 processor and Intel 505 graphics that functions identically at 4K, as far as I can tell.)
  • logarithmic, a fairly generic old ATX system with an Intel i5-3450 CPU and an ATI Radeon 7870 graphics card

Both systems are running fully up-to-date Debian 9 and are configured as identically as I can manage. In particular:

  • The X server DPI is 96 on both systems, checked with grep DPI /var/log/Xorg.0.log and xdpyinfo | grep dots
  • The Xft DPI is 120 on both systems, checked with xrdb -query | grep dpi.
  • Both are configured with xrdb -cpp cpp -merge $HOME/.Xresources from an identical file, and I've confirmed that xrdb -query produces identical output on both. I also have exactly the same set of Source Code Pro fonts loaded into ~/.fonts on both systems.

On either of them I can start an 80-column xterm, configured with XTerm*VT100*font: -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1 and they look identical and are 484 pixels wide. This doesn't change if I start the xterm client on the other machine displaying on the local X server using ssh -X.

However, urxvt is different depending on which X server I'm using. I've configured the font X resource as:

Rxvt.font:  xft:Source Code Pro:size=9,xft:Source Han Sans,xft:DejaVu Serif:size=8,xft:DejaVu Sans Mono:size=8

When I start urxvt to display on idyllic's X server, either locally or started on the other host with ssh -X, an 80 column terminal is 644 pixels wide and 106 columns high when maximized vertically. However, when I start it to display on logarithmic's X server (again either locally or with a remote client using ssh -X), an 80 column urxvt is 726 pixels wide, though still 106 columns high when maximized vertically.

So, the question:

What's causing urxvt on logarithmic to be wider, and how do I make it the same nice narrow size as idyllic? Even if you don't know, debugging hints would be appreciated. I'm happy to write programs (preferring Python or similar over C or similar) that talk to the X11 servers and let me play around with similar rendering to what urxvt is doing to see if the problem can be found that way, if you have concrete suggestions on what APIs I should be calling and what kind of results I should be looking for.

A side question: xft: fonts are rendered by the X client, right? If that's correct, it would seem to be a big hint that some setting in the X11 server is changing how the same client on the same host is rendering fonts depending on which X11 server it's talking to.

EDIT: xfce4-terminal Information

I've tried starting up an xfce4-terminal and setting the font to 9 point Source Code Pro medium; it comes out the same on both X11 servers, always in the wider format that urxvt uses on logarithmic. This seems to indicate that it's something to do with urxvt itself or perhaps the Xft library (if xfce4-terminal doesn't use that; I am pretty sure that urxvt does), and not FreeType?

EDIT: xtrace Information

I have further information from xtrace (thanks for the idea, @Uli Schlachter!) that at least lets me see things go wrong in more detail. Running even just xtrace urxvt -e true produces a couple of hundred kilobytes of output, so obviously I'm not going to include that all here, but here are some key bits. The diffs below are of sessions idyllicidyllic and idylliclogarithmic, i.e., idyllic ran the urxvt in both cases but displayed first on itself and second remotely on logarithmic.

At line 156 in each the CreateWindow call confirms windows being created with the same height but different widths, as I mentioned above (I measured one window width dead on, but the other two pixels out):

-000:<:005e: 48: Request(1): CreateWindow depth=0x18 window=0x03200009 parent=0x000000e7 x=0 y=0 width=644 height=904 border-width=0 class=InputOutput(0x0001) visual=0x00000021 value-list={background-pixel=0x00ffffe0 border-pixel=0x00ffffe0 override-redirect=false(0x00) colormap=0x00000020}
+000:<:005e: 48: Request(1): CreateWindow depth=0x18 window=0x05400009 parent=0x000004bb x=0 y=0 width=724 height=904 border-width=0 class=InputOutput(0x0001) visual=0x00000021 value-list={background-pixel=0x00ffffe0 border-pixel=0x00ffffe0 override-redirect=false(0x00) colormap=0x00000020}

Starting at line 138 of each I see this diff (second line truncated for sanity), which seems to confirm, with width=7 vs. width=9 for the glyphs being created, that it's a character width issue.

-000:<:004c: 12: RENDER-Request(139,17): CreateGlyphSet gsid=0x03200008 format=0x00000024
-000:<:004d:108: RENDER-Request(139,20): AddGlyphs glyphset=0x03200008 glyphids=0x0000036d; glyphs={width=7 height=10 x=-1 y=10 xOff=9 yOff=0}; data=0x00,0x3e,...
+000:<:004c: 12: RENDER-Request(139,17): CreateGlyphSet gsid=0x05400008 format=0x00000026
+000:<:004d:388: RENDER-Request(139,20): AddGlyphs glyphset=0x05400008 glyphids=0x0000036d; glyphs={width=9 height=10 x=0 y=10 xOff=9 yOff=0}; data=0x00,0x00,...

(This continues on for further characters, with width 8 vs. 10, 9 vs. 11, etc.)

So presumably whatever it was that's causing this came somewhere before line 138. Looking before that the majority of diffs seem to be changes in the ID numbers used for objects, so it's a bit painful to find out what the real diffs are.

So what major differences do I see? Well, the initial response after the client connects is almost identical except that logarithmic (the one with the discrete Radeon graphics card) returns a lot more visuals. Both start with:

{id=0x00000021 class=TrueColor(0x04) bits/rgb-value=8 colormap-entries=256 red-mask=0x00ff0000 green-mask=0x0000ff00 blue-mask=0x000000ff},
{id=0x00000022 class=DirectColor(0x05) bits/rgb-value=8 colormap-entries=256 red-mask=0x00ff0000 green-mask=0x0000ff00 blue-mask=0x000000ff},

The list after that seems mainly duplicates, just with a lot more duplicates on the logarithmic side.

The next big difference is in a Reply to QueryPictFormats: where the screens=... depths=... visuals={...} list of visuals is, again, much much longer on the logarithmic side.

But at the very end of that there is a more notable difference:

-subpixels=Unknown(0x0);
+subpixels=HorizontalRGB(0x1);

After that there's a QueryFont for fixed which returns some differing data, which looks like just IDs, and anyway seems used only for creating a cursor as it's then closed immediately after that. Then it goes and seems to be pretty much the same (again, modulo IDs, unless I missed something) until line 139.

EDIT: FontConfig Debugging

I've also tried checking FC_DEBUG against each server with FC_DEBUG=8191 urxvt -e true 2>outputfile. I confirmed that the width is indeed still different when done this way. Diffing the two output files produces in the 8.5 MB of output only three instances of the following difference (- is _idyllic,+` is logarithmic):

-   rgba: 0(i)(s)
+   rgba: 1(i)(s)
cjs
  • 25,752
  • 9
  • 89
  • 101
  • Does running fc-match 'Source Code Pro:size=9' produce the same output on both computer? (Repeat with all the other fonts that you are listing) Can you find the file with the given file name on both computers and check that e.g. their sha512 sums are identical? – Uli Schlachter Aug 23 '18 at 10:01
  • `fc-match 'Source Code Pro:size=10'` produces `SourceCodePro-Medium.otf: "Source Code Pro" "Medium"` on both computers, and the sha1sum of the files on each match. The same is true for all the other fonts in the list. However, I'm not sure how this would be relevant given that a urxvt client on either computer produces the same results on a given X11 server. I.e., urxvt on both _idyllic_ and _logarithmic_ looks fine when displayed on _idyllic_, and both are too wide when displayed on _logarithmic_. – cjs Aug 23 '18 at 16:32
  • urxvt uses the font of the system that it is running on, no? – Uli Schlachter Aug 24 '18 at 16:29
  • As I said at the end of the question, I do believe that urxvt does use the fonts of the system on which it's running. That's why I checked and confirmed that, regardless of which host urxvt is running on, I see it behaving differently depending on which X11 server it's connecting to, making me conclude that the issue is something different between the X11 servers, not the urxvt clients. – cjs Aug 26 '18 at 02:36
  • 1
    Whoops, sorry. Then I got things mixed up. New debugging idea: You could run urxvt under x11trace (called xtrace on Debian) and compare the output for both. This shouldn't be easy as there are likely tons of differences in the output – Uli Schlachter Aug 27 '18 at 09:10
  • @UliSchlachter Well, I think that xtrace is definitely a great idea, but in this particular case I'm not sure it's helping much. I've added some info on that to the end of the post; let me know if you have any thoughts. – cjs Sep 03 '18 at 13:07
  • I also just had a thought to see if `xfce4-terminal` has the same issue as `urxvt` and it doesn't (or, from my point of view, has the same 'too wide' issue on both systems). Details are in a separate section in the body of the question. – cjs Sep 03 '18 at 13:31

1 Answers1

2

The issue is the subpixel rendering by Xft/FreeType which, as with a few other settings, can have a dramatic effect on the width of fonts that are rendered while not changing the height at all.

The FontConfig debugging makes it clear that the subpixel rendering setting is different. Setting this explicitly in the X resources will make both systems work the same:

  • Xft.rgba: rgb will make both systems render the font wider on both X11 servers (the way they do when either renders to logarithmic without this set).
  • Xft.rgba: none will make both systems render the font narrower on both X11 servers (the way they do when either renders to idyllic without this set).

Thus, adding Xft.rgba: none to the ~/.Xresources fixes the problem.

while this answer is currently the accepted one because it solves the problem, I would be very pleased to change accept another answer that provides a deeper explanation of exactly what's going on here.

cjs
  • 25,752
  • 9
  • 89
  • 101