Linux и WYSIWYG

В этом очень коротком очерке я расскажу о нюансах, из-за которых масштаб 100% в графическом редакторе на экране может не совпадать с реальным размером.

Потребовалось мне допечатать на существующий лист бумаги немного текста и графики. Решил напросвет подогнать. Выставил масштаб 100%, прикладываю лист к экрану, а между тем, что на экране и на бумаге, разбег процентов на 20%.
Так бывает, когда реальная разрешающая способность экрана (в точках на дюйм) не совпадает с тем, что думает программа. Когда у программы есть задача нарисовать на экране что-то длиной, например, L см, она вычисляет сколько это в пикселях. Для этого она получает DPI, а далее примерно по следующей формуле $L_{px} = L \cdot DPI/2.54$ получает длину в пикселях.

Собственно проблема в том, как программе добыть этот DPI, и тут начинаются пляски с бубном. Вообще, монитор умеет отдавать видеокарте, а та в свою очередь ОС, свои линейные размеры. Для этого служит интерфейс DDC (Display Data Channel) и протокол EDID. А далее начинаются проблемы.

Проблема №1 — протокол EDID передает линейные размеры экрана с точностью до см. Казалось бы не беда, но полсантиметра на небольшом экране (как у лэптопов) — это 3–4%. Не катастрофа, но и это можно избежать.

Проблема №2 — X.org, не смотря на то, что считывает размеры через EDID, почему-то всё равно в моём случае их не применил и поставил DPI равным 96. Узнать это можно следующей командой в графическом терминале:

$ xdpyinfo | grep resolution
  resolution:    96x96 dots per inch


Проблема №3 — приложение может использовать другие источники для получения DPI. Так случается с приложениями, использующими библиотеку GTK3. Почему так? Не знаю. Оставим это на совести разработчиков GTK3.

Итак, подтюним всё это дело.

1) Измерим линейкой монитор. В моём случае получается 347 мм на 195 мм.

2) Расчитаем DPI. Для этого нам потребуется узнать разрешение монитора. У меня 1600×900. Скорее всего DPI одинаковый для вертикального и горизонтального измерения, но это не всегда так. $DPI_x = 1600 * 25.4/347 \approx 117$. $DPI_y = 900 * 25.4/195 \approx 117$.

3) Открываем файл конфигурации X.org /etc/X11/xorg.conf. Если такого файла нет, то из-под root нужно запустить:

X.org -configure


и полученный файл записать в указанный путь. В секцию Monitor добавить строчку DisplaySize, должно получиться что-то похожее на это:

Section «Monitor»
Identifier «Monitor0»
VendorName «Monitor Vendor»
ModelName «Monitor Model»
DisplaySize 347 195
EndSection


Этим мы решим проблему 1 и 2.

4) Создать файл ~/.Xresources или добавить в существующий настройку DPI:

Xft.dpi: 117


Эти мы решим проблему 3.

После чего перезапустить X-сессию и всё должно подцепиться.

© Habrahabr.ru