Окт 14

Выравнивание по ширине (выключка)

Функция TextOut обеспечивает выравнивание текста по левому или правому краю, а также по центру. Вид выравнивания зависит от текущего режима выравнивания. Но при этом функция не поддерживает выравнивание по ширине (выключку). Выравнивание по ширине означает, что левый край текста должен быть выровнен по левой границе области, а правый край — по правой границе. Это достигается равномерным увеличением протяженности пробелов, разделяющих слова в строке.
Для решения указанной проблемы GDI позволяет использовать функции GetTextExtentPoint32 и SetTextJustification.
Допустим, что надо реализовать выключку при выводе строк текста в область с левой границей х и правой границей х + width. Предполагается, что протяженность строк не превышает width логических единиц. План решения обычно содержит следующие шаги:
1. С помощью инструкций
SIZE size;
GetTextExtentPoint32(hDC, IpString. nCount. Ssize):
получить размеры обрамляющего прямоугольника для строки IpString, содержащей nCount символов. Эти размеры возвращаются в виде значений полей параметра size. Поле size.cx будет содержать ширину обрамляющего прямоугольника, а поле size.су — высоту обрамляющего прямоугольника.
2. Подсчитать количество разделительных символов nBreak в строке IpString. Разделительным символом обычно является пробел, но он может быть переопределен в каком-либо шрифте на другой символ. Если нужно уточнить, какой символ на самом деле является разделительным, используйте функцию GetTextMetrics с последующим анализом поля tmBreakChar структуры TEXTMETRIC.
3. Вычислить размер пространства, которое необходимо распределить между nBreak разделительными символами:
int breakExtra = width - size.cx;
4. Вызвать функцию
SetTextJustification(hdc, breakExtra. nBreak);
передав ей определенные выше величины breakExtra и nBreak. Функция SetText-Justification присвоит атрибуту контекста устройства, отвечающему за выключку текста, величину дополнительного интервала, используемую после этого функциями TextOut и ExtTextOut.
5. Позаботиться о том, чтобы текущий режим выравнивания текста содержал флаг TA_LEFT (значение по умолчанию). После этого уже можно вызвать функцию TextOut для отображения строки текста.
Следует отметить, что при каждом вызове функции SetTextJustification накапливается погрешность, если величина breakExtra не делится нацело на nBreak. Чтобы эта погрешность не повлияла на последующую работу функции GetTextExtent-Point32 при выводе многострочного текста, рекомендуется перед обращением к GetTextExtentPoint32 сбросить накопленную погрешность вызовом функции
SetTextJustification(hdc. 0. 0);
В листинге 2.1 приводится программа, в которой демонстрируется описанная технология выравнивания текста по ширине.