Как я могу получить размеры текущего шрифта в терминале?

Вопрос или проблема

Я работаю над приложением ncurses, которое создает очень квадратные графические изображения с использованием алфавитно-цифровых символов. Я хотел бы иметь возможность определять размеры (в частности, соотношение сторон) глифов шрифта, чтобы корректировать это, изменяя способ отрисовки моих графиков (чтобы квадрат всегда выглядел как квадрат).

Я могу использовать

void getmaxyx(WINDOW *win, int y, int x);

функцию в ncurses, чтобы получить размер экрана/окна в символах, но поскольку многие окна могут быть свободно изменены в размерах, это ненадежно. Есть ли аналогичная функция (или внешний механизм) для получения размеров шрифта?

С xterm или совместимыми терминалами, если операции шрифта не были отключены:

$ xtermcontrol --get-font
DejaVu Sans Mono

Это отправляет последовательность управления <ESC>]50;?<ESC>\, и терминал отвечает <ESC>]50;font-name<ESC>\. См. ссылку.

Таким образом, вы также можете запросить это с помощью zsh, например, с:

$ IFS=$';\e' read -rsd'\' -t0.2 $'font?\e]50;?\e\\' font font rest
$ typeset font
font="DejaVu Sans Mono"

Однако allowFontOps обычно отключен по умолчанию. Вы можете установить ресурс *allowFontOps: true, чтобы включить их, или желательно оставить его отключенным, но установить *disallowedFontOps: SetFont, чтобы разрешить GetFont, но не SetFont.

Для получения размера установите:

*disallowedWindowOps: 1,2,3,4,5,6,7,8,9,11,13,19,20,21,GetSelection,SetSelection,SetWinLines,SetXprop

ресурс, который запрещает все, кроме GetWinSizeChars и GetWinSizePixels, затем с zsh:

$ IFS=';t' read -rsdt -t0.2 $'x?\e[18t' cy cx rest
$ IFS=';t' read -rsdt -t0.2 $'x?\e[14t' y x rest
$ echo ${x}x${y} ${cx}x${cy}
1916x1012 147x38

\e[18t запрашивает размер окна в количестве ячеек, \e[14t в количестве пикселей, так что вы можете получить размер ячейки с:

$ printf '%gx%g\n' '1.*x/cx' '1.*y/cy'
13x26

К сожалению, такие вещи, как размер шрифта, или различные шрифты, или подобные вещи, к сожалению, относятся к загрузке графического драйвера для оборудования и его применению в качестве графической среды, которая загружается только, когда вы используете графическую среду из Linux и не из консоли (только алфавитный режим) или используя CTRL+T для включения терминала во время сеанса Windows в любом случае.

Единственная возможность использовать разные размеры шрифтов может быть через ncurses, но в соответствии со стандартами POSIX это невозможно. Если вы хотите в любом случае применить разные размеры шрифтов, существует множество сред, таких как processing, поддерживаемая Java, которые предложат вам решение.

Ответ или решение

Как получить размеры текущего шрифта в терминале?

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

1. Введение в проблемы аспектного соотношения

При использовании alphanumeric символов для создания графических объектов важно учитывать размеры отдельных символов, так как они могут различаться в зависимости от используемого шрифта и конфигураций терминала. Это искажение может приводить к тому, что квадратные элементы выглядят как прямоугольники, что, безусловно, нежелательно в графических приложениях.

2. Использование ncurses для получения размеров окна

Вы можете использовать макрос getmaxyx для определения размеров окна в терминальных единицах – символах. Однако, учитывая динамическую природу терминальных окон (возможность их изменения), этот метод не всегда дает представление о фактических размерах символов. Вам необходимо воспользоваться дополнительными средствами для рендеринга.

void getmaxyx(WINDOW *win, int y, int x);

Этот метод получает размеры окна в символах, но как упоминалось, не учитывает истинные размеры шрифта и его аспектное соотношение.

3. Использование управляющих последовательностей для получения информации о шрифте

На терминалах, совместимых с xterm, вы можете использовать управляющие последовательности для получения информации о текущем шрифте и его размере. В частности, последовательность ESC]50;?ESC\ позволяет узнать название используемого шрифта. Выполните следующую команду в терминале:

xtermcontrol --get-font

Это вернет название шрифта, если разрешение на выполнение операций со шрифтами не отключено.

Чтобы получить размер клетки в пикселях, можно использовать следующие управляющие последовательности:

  • ESC[18t — для размера окна в символах.
  • ESC[14t — для размера окна в пикселях.

Для выполнения команд, например, в zsh вы можете использовать следующий подход:

IFS=';t' read -rsdt -t0.2 $'x?\e[18t' cy cx rest
IFS=';t' read -rsdt -t0.2 $'x?\e[14t' y x rest

4. Расчет размеров шрифта

После получения размеров окна в символах и пикселях можно рассчитать размеры отдельного символа и их аспектное соотношение следующим образом:

printf '%gx%g\n' '1.*x/cx' '1.*y/cy'

Это вернет размеры текущего шрифта в единицах измерения, что позволит вам корректировать рендеринг ваших графических объектов.

5. Настройка терминала для получения размеров шрифта

Если вы сталкиваетесь с проблемами при получении необходимых данных о шрифте, убедитесь, что настройки вашего терминала позволяют выполнять операции с шрифтами. Для этого настройте ресурс allowFontOps в вашем конфигурационном файле терминала:

*allowFontOps: true
*disallowedFontOps: SetFont

Это гарантирует, что вы можете выполнить операции на чтение, но предотвратите любые изменения.

Заключение

Получение размеров шрифта и корректировка аспектного соотношения в терминах управления графикой в ncurses требует комбинирования различных методов, включая использование управляющих последовательностей и конфигурационных настроек терминала. Надеюсь, этот детализированный подход поможет вам добиться точности в ваших графических приложениях, обеспечивая правильное отображение графических объектов в терминале.

Оцените материал
Добавить комментарий

Капча загружается...