[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

X Logical Font Description и HiDPI



Всем здравствуйте.

*Проблема*: 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)?

Спасибо.

Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: