- Вопрос или проблема
- Ответ или решение
- Как получить размеры текущего шрифта в терминале?
- 1. Введение в проблемы аспектного соотношения
- 2. Использование ncurses для получения размеров окна
- 3. Использование управляющих последовательностей для получения информации о шрифте
- 4. Расчет размеров шрифта
- 5. Настройка терминала для получения размеров шрифта
- Заключение
Вопрос или проблема
Я работаю над приложением 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 требует комбинирования различных методов, включая использование управляющих последовательностей и конфигурационных настроек терминала. Надеюсь, этот детализированный подход поможет вам добиться точности в ваших графических приложениях, обеспечивая правильное отображение графических объектов в терминале.