X Logical Font Description и HiDPI

Andrey ``Bass'' Shcheglov <[email protected]>
Newsgroups gmane.linux.debian.user.russian
Organization MIPT
Message-ID <[email protected]>
Всем здравствуйте.

*Проблема*: X-сервер отдаёт серверные шрифты в фиксированном разрешении 100 dpi, а не в разрешении, текущем для сервера.

*Немного теории*. Есть серверные шрифты, которые X-клиенту по сети (через TCP либо UNIX socket) "отдаёт" либо сам X-сервер, либо отдельный X Font Server (один или несколько). В отличие от привычных всем клиентских шрифтов (Xft, GTK 2+, Qt 2+), "серверный" backend (он ещё называется core X font backend) не поддерживает антиалиасинг, но поддерживает сетевую прозрачность (т. е. по сети пересылаются bitmap’ы без альфа-канала). На уровне приложения серверные шрифты задаются не в виде `XftFontStruct` (что чаще всего вырождается в привычное нам DejaVu Sans Mono 12, см. <https://keithp.com/~keithp/talks/xtc2001/paper/>), а в виде XLFD <https://wiki.archlinux.org/index.php/X_Logical_Font_Description>. Если мы говорим о локальной машине, то один и тот же файл шрифта может быть зарегистрирован сразу в двух подсистемах и доступен и современным приложениям на базе GTK и Qt, и "суровому легаси" (Xt, Athena, Motif, GTK 1.2, Qt 1.x).

Исторически серверные шрифты были растровыми (*.pcf), а для растра существует такое понятие, как его собственное, растра, разрешение. Поэтому в XLFD есть такие поля, как RESOLUTION_X и RESOLUTION_Y. Чтобы растровый шрифт выглядел на экране адекватно, разрешение растра должно быть близким к разрешению экрана, поэтому растровые шрифты обычно поставлялись с собственным разрешением в 75 dpi и 100 dpi (каталоги /usr/share/fonts/X11/75dpi и /usr/share/fonts/X11/100dpi – как раз про это). Так,

> -bitstream-charter-bold-r-normal--12-120-75-75-p-75-iso8859-1
> -bitstream-charter-bold-r-normal--17-120-100-100-p-107-iso8859-1

-- это один и тот же шрифт размером 12 pt, имеющий характерный размер символа

 * 12 px при разрешении 75 dpi, и
 * 17 px – при 100 dpi, соответственно.

Но, помимо растровых шрифтов, есть ещё векторные (TrueType, OpenType, Adobe Type 1), которые мы все любим и которые можно безбоязненно масштабировать. Некоторые реализации X-сервера (напр., XSun) поддерживали ещё формат Adobe Type 3, в котором шрифт описывался с помощью языка PostScript (Тьюринг-полного, кстати).

К векторным шрифтам понятие разрешения растра, естественно, неприменимо, поэтому в полях RESOLUTION_X и RESOLUTION_Y я могу запрашивать `0`, а могу запрашивать "звёздочки" (`*`), и, в теории, X-сервер должен отдать мне нужный шрифт. Об этом напрямую говорится в статье _Arch Wiki_ по ссылке выше:

> Scalable fonts were designed to be resized. A scalable font name, as shown in the example below, has zeroes in the pixel and point size fields, the two resolution fields, and the average width field.
> ...
> To specify a scalable font at a particular size you only need to provide a value for the POINT_SIZE field, the other size related values can remain at zero. The POINT_SIZE value is in tenths of a point, so the entered value must be the desired point size multiplied by ten.

Так, любой из приведённых ниже двух запросов должен вернуть шрифт `Courier New` размером 12 pt в разрешении X-сервера:

> -monotype-courier new-medium-r-normal--*-120-*-*-m-*-iso10646-1
> -monotype-courier new-medium-r-normal--0-120-0-0-m-0-iso10646-1
*Или, по кр. мере, я так думал*. Штука в том, что, пересев с мониторов с разрешением в 96...115 dpi за 4k-монитор с разрешением в 162 dpi, я заметил, что мои заботливо выбранные векторные шрифты внезапно стали мелковаты.

И выяснилось, что, если явно не указывать RESOLUTION_X и RESOLUTION_Y равными 162 (а никто в здравом уме этого не делает – это пришлось бы каждый раз при изменении монитора переписывать сотни строк Xresources), то X-сервер по умолчанию отдаёт шрифт в разрешении 100 dpi вместо 162. Разница между 17-ю пикселями и 27-ю (пресловутый коэффициент 1.62 = 162 / 100) достаточно заметна. Вот пример для современного Debian 10 (сверху для сравнения дан снимок font-manager, отрисовывающего клиентский шрифт): <https://habrastorage.org/webt/uq/m5/ej/uqm5ej9ys9ynb3vwanrqioayxns.png>.

Я было подумал, что это следствие постепенного выпиливания устаревших подсистем из X11, но в Debian Woody, выпущенном в 2002 году и имеющем ядро 2.2, увидел ровно то же самое: <https://habrastorage.org/webt/j9/24/0r/j9240rroo5q9wasvpn8s9zhpjke.png>. Разве что сам шрифт старый Debian отрисовывает «чище», видимо, выполняя хинтинг на серверной стороне, до пересылки bitmap’ов по сети.

Проблема существовала всегда и в равной степени затрагивает все векторные шрифты (TrueType, OpenType, Type 1).

*Собственно, вопрос*. Есть ли способ, не зашивая жёстко в пользовательские настройки для каждого отдельного ресурса разрешение X-сервера, обойтись меньшей кровью, чем рекомендует автор статьи "Sharing Xresources between systems" <https://jnrowe.github.io/articles/tips/Sharing_Xresources_between_systems.html>?
Поддержка препроцессора в `xrdb`, увы, всё-таки достаточно убога.

Можно ли решить что-то на уровне глобальной конфигурации собственно X-сервера или библиотек, на которые он опирается (libfreetype, libxfont)?

Спасибо.
signature.asc (application/pgp-signature, 195 B)
-----BEGIN PGP SIGNATURE-----

iF0EARECAB0WIQSk78qvEH59Jewf+OAVfbB6hOsMZwUCYBp5BwAKCRAVfbB6hOsM
Z3DAAKDxz2bzIzFRfLJhHD9PySLQGKvZuwCgqJ5JyHm3bTrEARTrlT6rXMHOj1M=
=S2Pe
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.