Различные стили печати в пределах семейства шрифта могут иметь разную ширину. Например, полужирные и курсивные стили семейства всегда более широкие, чем прямой (латинский) стиль для заданного размера пункта. Когда Вы показываете на экране или печатаете несколько типов стилей шрифта в одной строчке, то должны следить за шириной строки, чтобы избежать получить буквы, отображенные или напечатанные одна поверх другой.
Вы можете использовать две функции, чтобы извлечь ширину (или протяженность) текста при текущем шрифте. Функция GetTabbedTextExtent вычисляет ширину и высоту символьной строки. Если строка содержит один или несколько символов табуляции, ширина строки базируется на заданном массиве позиций табуляции. Функция GetTextExtentPoint32 вычисляет ширину и высоту строки текста.
Когда необходимо, система синтезирует шрифт, изменяя битовые образы символов. Чтобы синтезировать букву в полужирном шрифте, система рисует букву дважды: с отправной точки, и снова со сдвигом на один пиксель вправо от отправной точки. Чтобы синтезировать букву в курсивном шрифте, система рисует два ряда пикселей внизу символьного знакоместа, перемещает отправную точку на один пиксель вправо, рисует следующие два ряда, и продолжает это до тех пор, пока не нарисует букву. При помощи перемещения пикселей каждая буква показывается сдвинутой вправо. Величина сдвига фрагмента изображения является функцией высоты буквы.
Один из способов записать строку текста, которая содержит несколько шрифтов, это использовать функцию GetTextExtentPoint32 после каждого вызова функции TextOut и добавлять длину к текущей позиции. Нижеследующий пример пишет в строке " Это - типовая строка. " После использования полужирных букв для слов "Это - ", делаем переключение на курсивные буквы для слова "типовая", затем возвращаемся к полужирным буквам для слова "строка". После печати всех строк, система восстанавливает буквы по умолчанию.
int XIncrement; int YStart; TEXTMETRIC tm; HFONT hfntDefault, hfntItalic, hfntBold; SIZE sz; LPSTR lpszString1 = "This is a "; LPSTR lpszString2 = "sample "; LPSTR lpszString3 = "string."; // Создаем полужирный и курсивный логические шрифты. hfntItalic = MyCreateFont(); hfntBold = MyCreateFont(); // Выбираем полужирный шрифт и выводим первую строку, // начинающуюся в заданной точке (XIncrement, YStart). XIncrement = 10; YStart = 50; hfntDefault = SelectObject(hdc, hfntBold); TextOut(hdc, XIncrement, YStart, lpszString1, lstrlen(lpszString1)); // Вычислим длину первой строки и добавим это значение // к x-приращению, которое используется для операции вывода текста. GetTextExtentPoint32(hdc, lpszString1, lstrlen(lpszString1), &sz); XIncrement += sz.cx; // Извлекаем значение выступа из структуры TEXTMETRIC и вычитаем его // из x-приращения. (Это необходимо только для не TrueType растровых шрифтов). GetTextMetrics(hdc, &tm); XIncrement -= tm.tmOverhang; // Выберем курсивный шрифт и выведем вторую строку // начинающуюся с точки (XIncrement, YStart). hfntBold = SelectObject(hdc, hfntItalic); GetTextMetrics(hdc, &tm); XIncrement -= tm.tmOverhang; TextOut(hdc, XIncrement, YStart, lpszString2, lstrlen(lpszString2)); // Вычислим длину второй строки и добавим это значение // к x-приращению, которое используется для операции вывода текста. GetTextExtentPoint32(hdc, lpszString2, lstrlen(lpszString2), &sz); XIncrement += sz.cx; // Повторно выберем полужирный шрифт и выведем третью строку, // которая начинается с точки (XIncrement, YStart). SelectObject(hdc, hfntBold); TextOut(hdc, XIncrement - tm.tmOverhang, YStart, lpszString3, lstrlen(lpszString3)); // Повторно выберем первоначальный шрифт. SelectObject(hdc, hfntDefault); // Удалим полужирный и курсивный шрифты. DeleteObject(hfntItalic); DeleteObject(hfntBold);
|
В этом примере, функция GetTextExtentPoint32 инициализирует члены структуры SIZE длиной и высотой заданной строки. Функция GetTextMetrics извлекает нависание для текущего шрифта. Поскольку нависание обнуляется, если шрифт - TrueType, значение выступа не изменяет размещение строки. Однако для растровых шрифтов важно использовать значение выступа.
Выступ вычитается из полужирной строки один раз, чтобы перевести последующие символы ближе к концу строки, если шрифт - растровый. Поскольку выступ воздействует и на начало и на конец курсивной строки в растровом шрифте, глиф начинается справа от заданной позиции и до конца слева от конечной точки последнего символьного знакоместа. (Функция GetTextExtentPoint32 извлекает длину символьных знакомест, а не длину глифа.) Чтобы рассчитать выступ в растровой курсивной строке, пример вычитает выступ перед размещением строки и вычитает его снова перед размещением последующих символов.
Функция SetTextJustification добавляет дополнительное пространство к символам разрыва в строке текста. Вы можете использовать функцию GetTextExtentPoint, чтобы выяснить длину строки, а затем вычесть эту длину от общей суммы пространства, которое строка должна занять, и использовать функцию SetTextJustification, чтобы распределить дополнительное пространство среди символов разрыва в строке. Функция SetTextCharacterExtra добавляет дополнительное пространство к каждому символьному знакоместу в выбранном шрифте, включая символ разрыва. (Вы можете использовать функцию GetTextCharacterExtra, чтобы выяснить текущую величину дополнительного пространства, добавляемого к символьным знакоместам; параметр по умолчанию обнуляется.)
Вы можете помещать символы с большей точностью при помощи использования функции GetCharWidth32 или GetCharABCWidths, чтобы извлечь ширину конкретных знаков в шрифте. Функция GetCharABCWidths более точна чем функция GetCharWidth32, но она может быть использована только с шрифтами TrueType.
Разбивка букв также дает возможность приложению выполнить очень точное выравнивание текста. Например, когда приложения выравнивает растровый прямой (латинский) шрифт по правой стороне без использования разбивки букв, ширина, занимаемая символом в строке, рассчитывается как ширина символа. Это означает, что выравнивается незаполненное пространство справа от глифа в его точечном рисунке, а не глиф непосредственно. При помощи использования ширины алфавита (АВС), прикладные программы имеют большую гибкость в размещении и удалении незаполненного пространства при выравнивании текста, потому что они имеют информацию, которая позволяют им точно управлять межсимвольным интервалом.