相同配置的urxvt在不同的X服务器上具有不同的宽度/字体渲染

时间:2018-08-22 15:08:49

标签: fonts x11 xorg urxvt

我有两个不同的台式机主机,通过它们的DisplayPort输出连接到同一4K显示器上的两个DisplayPort输入:

  • idyllic ,这是一种小型计算机,其使用赛扬N3350处理器的板载Intel HD Graphics 500。 (据我所知,我在另一个地方也有一个类似的系统,配备奔腾N4200处理器和Intel 505图形卡,在4K时功能相同。)
  • 对数,一个相当普通的旧ATX系统,带有Intel i5-3450 CPU和ATI Radeon 7870显卡

两个系统都完全运行最新的Debian 9,并且配置与我可以管理的相同。特别是:

  • 两个服务器上的X服务器DPI均为96,并用grep DPI /var/log/Xorg.0.logxdpyinfo | grep dots检查
  • 两个系统上的Xft DPI均为120,并用xrdb -query | grep dpi检查。
  • 两者都使用来自同一文件的xrdb -cpp cpp -merge $HOME/.Xresources配置,并且我已经确认xrdb -query在两者上产生相同的输出。在这两个系统上,~/.fonts中都加载了完全相同的一组Source Code Pro字体。

在其中一个上,我都可以启动一个80列的xterm,并用XTerm*VT100*font: -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1配置,它们看起来相同,宽484像素。如果我使用ssh -X在本地X服务器上显示的另一台计算机上启动xterm客户端,这不会改变。

但是,urxvt取决于我使用的X服务器。我已将字体X资源配置为:

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

当我启动urxvt以显示在田园的X服务器上时,无论是在本地还是以ssh -X在其他主机上启动,一个80列的终端都是644像素宽垂直最大化时为106列高。但是,当我启动它以显示在 logarithmic 的X服务器上(还是在本地或使用ssh -X的远程客户端上)时,80列urxvt的宽度为726像素,但垂直最大化时仍高106列。

所以,问题是

是什么原因导致对数上的urxvt变宽,又如何使其与田园诗般的一样小巧?即使您不知道,调试提示也将不胜感激。我很高兴编写与X11服务器通信的程序(最好是Python或类似的程序,而不是C或类似的程序),并让我进行类似于urxvt的渲染,以查看是否可以通过这种方式发现问题。 ,如果您对我应该调用哪些API以及应该寻找什么样的结果有具体建议。

另一个问题:xft:字体是由X客户端渲染的,对吗?如果是正确的话,这似乎暗示了X11服务器中的某些设置正在更改 same 主机上的 same 客户端如何呈现字体,具体取决于哪个X11。正在与之通信的服务器。

编辑:xfce4-terminal信息

我尝试启动xfce4-terminal并将字体设置为9点Source Code Pro介质;它在两个X11服务器上的输出相同,始终以urxvt对数上使用的更宽的格式显示。这似乎表明这与urxvt本身或Xft库有关(如果xfce4-terminal不使用它;我很确定urxvt可以这样做) ,而不是FreeType?

编辑:xtrace信息

我从xtrace获得了更多信息(感谢@Uli Schlachter!),至少可以让我更详细地了解问题出在哪里。即使仅运行xtrace urxvt -e true也会产生数百KB的输出,因此很显然,我不会在此处包括所有内容,但是这里有一些关键内容。下面的差异是会话田园诗田园诗田园诗对数,即田园诗在这两种情况下都运行urxvt,但首先在自身上显示,然后在对数上远程显示。

在每次CreateWindow调用的第156行中,都确认创建了具有相同高度但宽度不同的窗口,如我上面提到的(我测量了一个窗口宽度固定不变,而其他两个像素固定不变):

-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}

从每条线的第138行开始,我看到了这个差异(为了清楚起见,第二行被截断了),似乎可以通过创建width=7width=9来确定创建的字形,以确认这是一个字符宽度问题。

-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,...

(此操作将继续进行,宽度为8对10、9对11等)

因此,大概是什么原因导致了出现在138行之前的某处。在此之前,大多数差异似乎是用于对象的ID号的变化,因此找出什么是真正的差异有些痛苦。

那我看到什么主要区别?嗯,客户端连接后的初始响应几乎是相同的,只是 logarithmic (带有离散Radeon显卡的对数)返回了 lot 个视觉效果。两者都以:

开头
{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},

此后的列表似乎主要是重复的,在对数方面有很多重复。

下一个大不同是Reply to QueryPictFormats:在{em>对数一侧,screens=... depths=... visuals={...}视觉列表再次更长。

但是到最后,还有一个更明显的区别:

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

此后有一个固定的QueryFont,它返回一些不同的数据,这些数据看起来就像ID,并且无论如何似乎仅用于创建游标,因为它随后被立即关闭。然后,直到第139行为止,它似乎几乎是相同的(再次是模ID,除非我错过了什么)。

编辑:FontConfig调试

我还尝试使用FC_DEBUG=8191 urxvt -e true 2>outputfile针对每个服务器检查FC_DEBUG。我确认这样做时宽度确实仍然不同。区别这两个输出文件将在8.5 MB的输出中产生以下差异的三个实例(-是_idyllic , +`是对数):

-   rgba: 0(i)(s)
+   rgba: 1(i)(s)

1 个答案:

答案 0 :(得分:0)

问题是通过Xft / FreeType进行的子像素渲染,与其他一些设置一样,可以对渲染的字体宽度产生巨大影响,而根本不改变高度。

FontConfig调试清楚地表明亚像素渲染设置是不同的。在X资源中显式设置此设置将使两个系统工作相同:

  • Xft.rgba: rgb将使两个系统都在两个X11服务器上更宽地显示字体(在不设置此设置的情况下,当两个都呈现为 logarithmic 时,它们的方式)。
  • Xft.rgba: none将使两个系统都在两个X11服务器上缩小字体(当这两个系统在没有设置的情况下渲染为 idyllic 时,它们的方式)。

因此,将Xft.rgba: none添加到~/.Xresources可以解决此问题。

虽然此答案目前已被接受,因为它可以解决问题,但我很高兴更改为接受另一个答案,该答案对此处的实际情况提供了更深入的解释。