首先必须注意,Xft.dpi
资源的值不一定准确——这取决于系统和/或用户登录脚本是否正确设置了它。
同样重要的是要记住该Xft.dpi
资源旨在供Xft库使用,而不是由寻找屏幕分辨率的任意程序使用。
Xft.dpi
资源可以如下设置。此示例有效地仅处理具有单个屏幕的显示,并注意它使用xdpyinfo
. 这也表明它可能不精确,但可以四舍五入。最后这个例子显示了水平和垂直分辨率的计算,但Xft真的只想要水平分辨率:
SCREENDPI=$(xdpyinfo | sed -n 's/^[ ]*resolution:[ ]*\([^ ][^ ]*\) .*$/\1/p;//q')
SCREENDPI_X=$(expr "$SCREENDPI" : '\([0-9]*\)x')
SCREENDPI_Y=$(expr "$SCREENDPI" : '[0-9]*x\([0-9]*\)')
# N.B.: If true screen resolution is within 10% of 100DPI it makes the most
# sense to claim 100DPI to avoid font-scaling artifacts for bitmap fonts.
if expr \( $SCREENDPI_X / 100 = 1 \) \& \( $SCREENDPI_X % 100 \<= 10 \) >/dev/null; then
FontXDPI=100
fi
if expr \( $SCREENDPI_Y / 100 = 1 \) \& \( $SCREENDPI_Y % 100 \<= 10 \) >/dev/null; then
FontYDPI=100
fi
echo "Xft.dpi: ${FontYDPI}" | xrdb -merge
我真的希望我知道为什么Xft至少没有尝试找出屏幕的分辨率本身,而不是一直依赖其设置的“dpi”资源,但我发现当前的实现只使用资源设置,所以实际上总是需要像上面这样的东西来正确设置资源(而且还必须确保 X 服务器本身已经正确配置了正确的物理屏幕尺寸)。
从 C 程序中,您只想做xdpyinfo
它本身所做的事情,并跳过所有关于Xft资源的废话。这是xdpyinfo
解释的代码:
Display *dpy;
dpy = XOpenDisplay(displayname);
for (scr = 0; scr < ScreenCount(dpy); scr++) {
int xres, yres;
/*
* there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
*
* dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
* = N pixels / (M inch / 25.4)
* = N * 25.4 pixels / M inch
*/
xres = ((((double) DisplayWidth(dpy, scr)) * 25.4) /
((double) DisplayWidthMM(dpy, scr))) + 0.5;
yres = ((((double) DisplayHeight(dpy, scr)) * 25.4) /
((double) DisplayHeightMM(dpy, scr))) + 0.5;
}
XCloseDisplay(dpy);
另请注意,如果您出于某种奇怪的原因缩放整个显示器(例如使用xrandr
),那么您应该希望字体与其他所有字体一样缩放。使用全屏缩放来缩放字体只是一个可怕的坏技巧,尤其是在大多数情况下,告诉应用程序使用正确缩放的字体会更简单,这些字体将以恒定的屏幕点大小显示(这正是Xft使用“dpi”资源来做什么)。我猜 Ubuntu 做了一些愚蠢的事情来改变屏幕分辨率,例如使用xrandr
来扩大图标和其他屏幕小部件的外观尺寸,而应用程序不必知道屏幕尺寸和分辨率,然后它必须通过重写来欺骗Xft这Xft.dpi
资源。
请注意,如果您避免全屏缩放,那么不使用Xft的应用程序仍然可以通过正确请求正确缩放的字体来获得正确的字体缩放,即即使使用位图字体,您也可以通过以下方式将它们缩放到正确的物理屏幕尺寸在字体规范中使用屏幕的实际分辨率。例如,从上面的 shell 片段继续:
# For pre-Xft applications we can specify physical font text sizes IFF we also tell
# it the screen's actual resolution when requesting a font. Note the use of the
# rounded values here.
#
DecentDeciPt="80"
DecentPt="8"
export DecentDeciPt DecentPt
#
# Best is to arrange one's font-path to get the desired one first, but....
# If you know the name of a font family that you like and you can be sure
# it is installed and in the font-path somewhere....
#
DefaultFontSpec='-*-liberation mono-medium-r-*-*-*-${DecentDeciPt}-${FontXDPI}-${FontYDPI}-m-*-iso10646-1'
export DefaultFontSpec
#
# For Xft we have set the Xft.dpi resource so this allows the physical font size to
# be specified (e.g. with Xterm's "-fs" option) and for a decent scalable font
# to be chosen:
#
DefaultFTFontSpec="-*-*-medium-r-*-*-*-*-0-0-m-*-iso10646-1"
DefaultFTFontSpecL1="-*-*-medium-r-*-*-*-*-0-0-m-*-iso8859-1"
export DefaultFTFontSpec DefaultFTFontSpecL1
# Set a default font that should work for everything
#
eval echo "*font: ${DefaultFontSpec}" | xrdb -merge
最后,这是一个使用上述设置(即上面的资源和 shell 变量)启动xterm
(已编译为使用XftXft.dpi
)以在屏幕上以 10.0 点的物理大小显示文本的示例:
xterm -fs 10 -fa $DefaultFTFontSpec