Класс CFont. Вывод текста под наклоном.
Автор статьи: Alexander E. Popov
Класс CFont (шрифт) инкапсулирует
графический объект Windows шрифт. Для создания
объекта этого класса существует конструктор без
параметров. Чтобы создать собственный шрифт,
можно вызвать одну из следующих функций: CreateFont,
CreateFontIndirect, CreatePointFont или CreatePointFontIndirect.
Для использования созданного шрифта
необходимо выбрать его в контекст устройства:
...
LOGFONT lf={ ...};
CPaintDC dc(this);
CFont font;
font.CreateFontIndirect(&lf);
CFont *pFont = dc.SelectObject(&font);
...
После использования нужно вернуть ранее
установленный шрифт и удалить созданный шрифт:
dc.SelectObject(pFont);
font.DeleteObject();
Можно создать шрифт при помощи функции
BOOL CreateFontIndirect( const LOGFONT* lpLogFont )
Единственный параметр lpLogFont этой функции
указывает на структуру LOGFONT, которая и определяет
шрифт:
typedef struct tagLOGFONT { /* lf */
LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
CHAR lfFaceName[LF_FACESIZE];
} LOGFONT;
Поле lfHeight определяет высоту символов
шрифта в логических единицах. Высота последних
определяется как разность между полной высотой
символа и размером области для отображения
специальных знаков, например, ударения. Это поле
интерпретируется в зависимости от знака
следующим образом:
- Если lfHeight>0, то значение преобразуется в
единицы устройства вывода и используется для
выбора шрифта из имеющихся, соответствующего по
высоте символа
- Если lfHeight=0, то для нахождения шрифта
используется значение высоты по умолчанию
- Если lfHeight<0, то значение преобразуется в
единицы устройства вывода и используется для
выбора шрифта из имеющихся, соответствующего по
высоте символа
При поиске подходящего шрифта выбирается шрифт
с наибольшей высотой символа, не превышающей
требуемого значения.
Для режима отображения ММ_ТЕХТ высота
может быть определена через размер шрифта,
задаваемого в пунктах (points), следующим образом:
lfHeight=-MulDiv(PointSize, dc.GetDeviceCaps(LOGPIXELSY), 72);
Поле lfWidth определяет определяет
среднюю ширину символов в логических единицах.
Если lfWidth=0, то выбирается шрифт, наиболее
подходящий конкретному устройству (device) по
возможностям масштабирования.
Поле lfEscapement определяет угол в
десятых долях градуса между каждой линией
выводимого текста (базовой линией) и
горизонталью.
Поле lfOrientation определяет угол в
десятых долях градуса между базовой линией
каждого символа и горизонталью.
Примечание
В Windows 95/98 значения полей lfEscapement и lfOrientation должны
совпадать, т.е. вся строка текста должна иметь
один и тот же наклон, при этом когда базовые линии
символов лежат на базовой линии строки. В Windows NT
при установке графического режима GM_ADVANCED (при
помощи Win32 API функции SetGraphicsMode) lfEscapement и lfOrientation не
обязательно должны быть равны.
lfWeight определяет толщину шрифта и
принимает значения в диапазоне от 0 до 1000. Если
lfWeight=0, то используется толщина(weight) по умолчанию.
Weight |
Value |
0 |
FW_DONTCARE |
100 |
FW_THIN |
200 |
FW_EXTRALIGHT |
200 |
FW_ULTRALIGHT |
300 |
FW_LIGHT |
400 |
FW_NORMAL |
400 |
FW_REGULAR |
500 |
FW_MEDIUM |
600 |
FW_SEMIBOLD |
700 |
FW_DEMIBOLD |
700 |
FW_BOLD |
800 |
FW_EXTRABOLD |
800 |
FW_ULTRABOLD |
900 |
FW_HEAVY |
900 |
FW_BLACK |
Поле lfItalic определяет установлено
ли курсивное начертание шрифта.
Поле lfUnderline определяет установлено
ли подчеркнутое начертание шрифта.
Поле IfStrikeOut определяет установлено
ли перечеркнутое начертание шрифта.
Поле lfCharSet определяет кодировку
шрифта. Определены следующие кодировки: ANSI_CHARSET,
DEFAULT_CHARSET, SYMBOL_CHARSET, SHIFTJIS_CHARSET, GB2312_CHARSET, HANGEUL_CHARSET,
CHINESEBIG5_CHARSET, OEM_CHARSET. В Windows 95 также определены:
JOHAB_CHARSET, HEBREW_CHARSET, ARABIC_CHARSET, GREEK_CHARSET, TURKISH_CHARSET,
THAI_CHARSET, EASTEUROPE_CHARSET, RUSSIAN_CHARSET, MAC_CHARSET, BALTIC_CHARSET.
Значение OEM_CHARSET определяет кодировку, не
зависющую от операционной системы.
Значение DEFAULT_CHARSET требует задания имени (поля
IfFaceName) и размера шрифта. Отсутствие
запрашиваемого шрифта может привести к
непредсказуемым результатам, т.к. он будет
подменен шрифтом, подходящим по другим
параметрам, но неизвестной кодировкой. Особенно
важно задание правильной кодировки при указании
имени шрифта в явном виде, т.к. именно кодировка в
первую очередь определяет набор установленных
шрифтов, среди которых будет произведен поиск по
имени.
В системе могут существовать и шрифты с другими
кодировками. Если приложение использует шрифт с
неизвестной кодировкой, то оно не должно
пытаться перевести строки, которые должны быть
представлены этим шрифтом.
Задавая имя шрифта (поле IfFaceName), убедитесь, что
значение lfCharSet совпадает с кодировкой шрифта с
именем, указанном в lfFaceName.
Поле lfOutPrecision определяет насколько
точно шрифт должен соответствовать
запрашиваемым параметрам шрифта, таким как
высота, ширина, ориентация и др. Оно может
принимать следующие значения:
OUT_CHARACTER_PRECIS |
Не используется. |
OUT_DEFAULT_PRECIS |
Определяет механизм выбора шрифта, принятый по
умолчанию |
OUT_DEVICE_PRECIS |
Указывает, что должен быть выбран системный
шрифт (Device font), если в системе установлено
несколько шрифтов с одним и тем же именем. |
OUT_OUTLINE_PRECIS |
Windows NT: Указывает, что должен быть выбран шрифт
TrueType или векторный шрифт.
Windows 95: Значение не используется. |
OUT_RASTER_PRECIS |
Указывает, что должен быть выбран растровый
шрифт, если в системе установлено несколько
шрифтов с одним и тем же именем. |
OUT_STRING_PRECIS |
Это значение не используется механизмом
выбора шрифтов, но оно возвращается при
перечислении растровых шрифтов. |
OUT_STROKE_PRECIS |
Windows NT: Это значение не используется механизмом
выбора шрифтов, но возвращается при перечислении
шрифтов TrueType, растровых или векторных шрифтов.
Windows 95: Используется при выборе векторных шрифтов,
а также возвращается при перечислении векторных
шрифтов или шрифтов TrueType. |
OUT_TT_ONLY_PRECIS |
Указывает, что должен быть выбран шрифт TrueType.
Если в системе не установлено ни одного шрифта
TrueType, то используется механизм выбора шрифтов,
принятый по умолчанию. |
OUT_TT_PRECIS |
Указывает, что должен быть выбран шрифт TrueType,
если в системе установлено несколько шрифтов с
одним и тем же именем. |
Приложение может использовать значения
OUT_DEVICE_PRECIS, OUT_RASTER_PRECIS, и OUT_TT_PRECIS для управления
механизмом выбора шрифта, если в ОС установлено
несколько шрифтов с одним и тем же именем.
Поле lfClipPrecision Определяет механизм
отсечения символов, т.е. как отсекаются символы,
частично находящиеся вне области вывода. Может
принимать следующие значения: CLIP_CHARACTER_PRECIS,
CLIP_DEFAULT_PRECIS, CLIP_STROKE_PRECIS.
Поле lfQuality определяет качество
вывода, т.е. насколько качественно graphics device interface
(GDI) должно попытаться найти шрифт. Может
принимать следующие значения:
DEFAULT_QUALITY |
Качество вывода не имеет значения. |
DRAFT_QUALITY |
Качество вывода менее важно, чем при
использовании значения PROOF_QUALITY. Для растровых
шрифтов разрешается масштабирование. Жирное,
курсивное, подчеркнутое и перечеркнутое
начертания шрифта могут быть синтезированы при
необходимости. |
PROOF_QUALITY |
Качество символов более важно, чем сходство
остальных логических атрибутов шрифта. Для
растровых шрифтов (GDI fonts) масштабирование
недоступно и выбирается ближайший по размеру
шрифт. Может быть выбран шрифт не совсем
требуемого размера, зато качество шрифта высокое
и нет искажений при выводе символов. Жирное,
курсивное, подчеркнутое и перечеркнутое
начертания шрифта могут быть синтезированы при
необходимости. |
Поле lfPitchAndFamily определяет тип и
семейство шрифта. Два младших бита определяют
тип шрифта и могут принимать следующие значения:
DEFAULT_PITCH, FIXED_PITCH (непропорциональный шрифт, т.е. все
символы имеют одинаковый размер), VARIABLE_PITCH (пропорциональный
шрифт).
Биты с 4 по 7 определяют семейство шрифта и могут
принимать следующие значения:
FF_DECORATIVE |
Декоративный шрифт, например Old English. |
FF_DONTCARE |
Семейство шрифта не имеет значения. |
FF_MODERN |
Непропорциональный шрифт с засечками (serif) или
без, например Pica, Elite, CourierNew®) |
FF_ROMAN |
Пропорциональный шрифт с засечками, например
MS® Serif. |
FF_SCRIPT |
Шрифт, походящий на рукописный тескт, например
Script, Cursive. |
FF_SWISS |
Пропорциональный шрифт без засечек, например
MS® Sans Serif. |
Значение поля lfPitchAndFamily может быть получено
применением логической операции OR к типу и
семейству шрифта.
Поле lfFaceName указывает на строку,
оканчивающуюся символом с кодом ноль (null-terminated
string), которая определяет имя (typeface name) шрифта.
Длина строки не должна превышать 32 символов.
Функция Windows EnumFonts() может быть использована для
перечисления typeface name всех доступных в настоящее
время шрифтов. Если lfFaceName=NULL, то GDI использует
typeface, принятый по умолчанию.
Создать шрифт можно с помощью функции
BOOL CFont::CreateFont( int nHeight, int nWidth, int nEscapement, int nOrientation,
int nWeight, BYTE bItalic, BYTE bUnderline, BYTE cStrikeOut, BYTE nCharSet, BYTE
nOutPrecision, BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily, LPCTSTR
lpszFacename );
Параметры последней принимают те же значения,
что и поля LOGFONT.
Также создать шрифт можно с помощью
функции
BOOL CFont::CreatePointFontIndirect( const LOGFONT* lpLogFont, CDC* pDC = NULL );
Где lpLogFont - указатель на уже знакомую структуру
LOGFONT, pDC - указатель на объект контекста
устройства, используемый для перевода высоты в
lfHeight в логические единицы. Если pDC=NULL, то в
качестве контекста устройства используется
контекст экрана.
И наконец шрифт можно создать с
помощью функции
BOOL CFont::CreatePointFont( int nPointSize, LPCTSTR lpszFaceName, CDC* pDC = NULL
);
Где nPointSize - высота шрифта в десятых долях пункта
(point). (Например, nPointSize=120 - соответствует шрифту с
высотой в 12 пунктов.);
lpszFaceName - CString или указатель на null-terminated string,
определяет имя шрифта (Длина строки не должна
превышать 30 символов. Функция Windows EnumFontFamilies()
может быть использована для перечисления всех
доступных в данный момент шрифтов. Если
lpszFaceName=NULL, то GDI использует шрифт, независящий от
устройства);
pDC - определяется, как и в предыдущей функции.
Пример
void CCreateFontIndirectView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect rect;
GetClientRect ( &rect ) ;
CFont font;
int angle=450;
LOGFONT lf = { 32, 0, angle, angle, FW_BOLD, 0, 0, 0,
RUSSIAN_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS,
PROOF_QUALITY, VARIABLE_PITCH | FF_ROMAN, NULL } ;
font.CreateFontIndirect( &lf ) ;
CFont * pFont = dc.SelectObject( &font) ;
CString str("Hello world");
rect.OffsetRect( 0, rect.Height()/3 );
dc.DrawText( str, rect, DT_NOCLIP ) ;
rect.OffsetRect( rect.Width()/3, rect.Height()/3 );
dc.SetBkMode( TRANSPARENT );
dc.DrawText( str, rect, DT_NOCLIP ) ;
dc.SelectObject ( pFont ) ;
font.DeleteObject ( ) ;
// Do not call CView::OnPaint() for painting messages
}
Download
Проект на VC++ 5.0 и это описание
|