Создание собственных шрифтов




 

Рис. 8.2. Окно программы, использующей встроенные шрифты

 

Хотя на первый взгляд это может показаться сложным, на самом деле создавать собственные шрифты довольно просто. При этом Вы получите два существенных преимущества. Во-первых, собственные шрифты придают программе уникальный внешний вид, отличающий ее от других. Во-вторых, собственные шрифты позволяют лучше управлять выводом текста. Прежде чем начать писать программу создания собственного шрифта, необходимо отметить, что его создание не означает определе­ние нового шрифта. Скорее это выглядит как клонирование существующего шрифта и подгонка его параметров согласно задаваемым Вами спецификациям (то есть не нужно определять форму каждого символа создаваемого шрифта.)

Для создания собственного шрифта используется функция API CreateFont():

 

HFONT CreateFont(int Height, int Width,

int Escapement, int Orientation,

int Weight, DWORD Ital,

DWORD Underline, DWORD StrikeThru,

DWORD Charset, DWORD Precision,

DWORD ClipPreqision, DWORD Quality,

DWORD Pitch, LPCSTR FontName);

 

Требуемая высота шрифта задается параметром Height, а ширина – параметром Width. Если параметр Width равен 0, Windows автоматически подставляет значение, определяемое текущими пропорциями шрифта. Значения Height и Width задаются в логических единицах.

Угол наклона текста в окне может быть любым. Угол по отношению к горизон­тальной оси задается параметром Escapement. Для текста, отображаемого горизонталь­но, этот параметр должен быть равен 0. В противном случае он определяет угол наклона текста в десятых долях градуса. Так, значение 900 определяет угол наклона, равный 90 градусам.

Угол наклона для каждого отдельного символа можно указать при помощи параметра Orientation. Этот параметр задает угол наклона каждого символа по отношению к горизонтальной оси также в десятых долях градуса.

Параметр Weight задает насыщенность (жирность) шрифта и может принимать значения в диапазоне от 0 до 1000. Значение 0 определяет насыщенность по умолчанию, значение 400 – нормальную насыщенность, а 700 – жирный шрифт. Для задания насыщенности шрифта можно также использовать следующие макросы:

FW_DONTCARE

FW_EXTRALIGHT

FW_LIGHT

FW_NORMAL

FW_MEDIUM

FW_SEMIBOLD

FW_BOLD

FW_EXTRABOLD

FW_HEAVY

 

Для создания наклонного шрифта следует задать ненулевое значение параметра Ital. Если параметр Underline не равен нулю, создается подчеркнутый шрифт. Для создания шрифта, все символы которого зачеркнуты горизонтальной линией, необ­ходимо задать ненулевое значение для параметра StrikeThru.

Параметр Charset определяет множество символов шрифта. В следующем примере мы будем использовать ANSI_CHARSET. Параметр Precision задает точность отобра­жения шрифта, которая определяет, насколько точно созданный шрифт соответствует задаваемым характеристикам. В примере, приведенном в данной главе, параметр принимает значение OUT_DEFAULT_PRECIS. Значение параметра ClipPrecision определяет «точность отсечения» шрифта, иначе говоря – как будут «отсекаться» символы шрифта, не попадающие в видимую область вывода. В следующем примере этот параметр принимает значение CLIP_DEFAULT_PRECIS.

Для подробного дальнейшего изучения того, какие значения могут принимать параметры Charset, Precision и ClipPrecision, обратитесь к Руководству по функциям и форматам данных API (или к MSDN Library Help – приложению Visual C++ 6.0).

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

DEFAULT_QUALITY

DRAFT_QUALITY

PROOF_QUALITY

 

Параметр Pitch задает тип и семейство шрифта. Имеется три варианта задания типа шрифта:

DEFAULT_PITCH

FIXED_PITCH

VARIABLE_PITCH

 

Семейство шрифта может быть задано одним из шести возможных значений:

FF_DECORATIVE

FF_DONTCARE

FF_MODERN

FF_ROMAN

FF_SCRIPT

FF_SWISS

 

Значение параметра Pitch формируется комбинацией типа и семейства шрифта при помощи операции логического ИЛИ.

В параметре FontName передается указатель на строку, содержащую имя шрифта. Такая строка может содержать не более 32 символов. Указываемый шрифт должен быть установлен в Вашей системе.

При успешном завершении функция CreateFont() возвращает дескриптор создан­ного логического шрифта. В случае возникновения ошибки возвращается NULL.

Замечание: Функция CreateFont() физически не создает новый шрифт, – она только преобра­зует шрифт, реально существующий в системе, таким образом, чтобы полученный в результате шрифт максимально соответствовал задаваемым спецификациям.

Шрифты, создаваемые при помощи функции CreateFont(), должны быть удалены, прежде чем программа завершит свое выполнение. Для удаления шрифта использует­ся функция DeleteObject().

 

Пример 8-4. Ниже приводится текст программы, демонстрирующей работу с двумя логическими шрифтами. Один из шрифтов базируется на шрифте Times New RomanCyr, а другой – на шрифте Parsek Cyrillic. Каждый раз при выборе команды меню Сменить шрифт выбирается и отобра­жается новый шрифт. Эта программа использует тот же файл ресурсов, что и пример из предыдущего раздела.

 

// Создание собственных шрифтов

#include <Windows.h>

#include <String.h>

#include <Stdio.h>

#include "Text.h"

 

LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM);

char szWinName[] = "МоеОкно"; // Имя класса окна

char str[255]; // Буфер строки вывода

char frame[40]= "По умолчанию"; // Имя шрифта

int X=0, Y=0; // Текущие координаты строки

int maxX, maxY; // Размеры экрана

HDC memdc; // DC виртуального окна

HBITMAP hbit; // Растр - это виртуальное окно

HBRUSH hbrush; // Дескриптор кисти

HFONT holdf, hnewf1, hnewf2; // Дескрипторы шрифтов

 

int WINAPI WinMain (HINSTANCE hThisInst,

HINSTANCE hPrevInst,

LPSTR lpszArgs,

int nWinMode)

{

HWND hwnd;

MSG msg;

WNDCLASS wcl;

HACCEL hAccel;

// Определить класс окна

wcl.hInstance=hThisInst; // Дескриптор приложения

wcl.lpszClassName=szWinName; // Имя класса окна

wcl.lpfnWndProc=WindowFunc; // Функция окна

wcl.style=0; // Стиль по умолчанию

wcl.hIcon=LoadIcon(NULL,IDI_APPLICATION); // Иконка

wcl.hCursor=LoadCursor(NULL,IDC_ARROW); // Курсор

wcl.lpszMenuName="MYMENU"; // Меню

wcl.cbClsExtra=0; // Без дополнительной

wcl.cbWndExtra=0; // информации

// Определить заполнение окна белым цветом

wcl.hbrBackground=

(HBRUSH)GetStockObject(WHITE_BRUSH);

if(!RegisterClass(&wcl)) // Зарегистр. класс окна

return 0;

// Создать окно

hwnd=CreateWindow(szWinName, // Имя класса

"Создание собственных шрифтов",

WS_OVERLAPPEDWINDOW,// Стиль окна

CW_USEDEFAULT, // Х-координата

CW_USEDEFAULT, // Y-координата

CW_USEDEFAULT, // Ширина окна

CW_USEDEFAULT, // Высота окна

HWND_DESKTOP, // Нет родит. окна

NULL, // Нет меню

hThisInst, // Дескрип. приложения

NULL); // Без дополит. аргументов

// Загрузить акселераторы

hAccel=LoadAccelerators(hThisInst,"MYMENU");

ShowWindow(hwnd,nWinMode); // Показать окно и

UpdateWindow(hwnd); // перерисовать содержимое

// Запустить цикл обработки сообщений

while(GetMessage (&msg,NULL,0,0))

if(!TranslateAccelerator(hwnd,hAccel,&msg))

{

TranslateMessage(&msg); // Использ.Клавиатуры

DispatchMessage (&msg); // Возврат к Windows

}

return msg.wParam;

}

 

// Следующая функция вызывается операционной системой

// Windows и получает в качестве параметров сообщения

// из очереди сообщений данного приложения

 

LRESULT CALLBACK WindowFunc(HWND hwnd,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

HDC hdc;

PAINTSTRUCT paintstruct;

TEXTMETRIC tm;

SIZE size;

static fontswitch=0;

switch(message)

{

case WM_CREATE: // Получаем размеры экрана

maxX=GetSystemMetrics(SM_CXSCREEN);

maxY=GetSystemMetrics(SM_CYSCREEN);

hdc=GetDC(hwnd); // Совмест. с окном растр

memdc=CreateCompatibleDC(hdc);

hbit=CreateCompatibleBitmap(hdc,maxX,maxY);

SelectObject(memdc,hbit);

hbrush=(HBRUSH)GetStockObject(WHITE_BRUSH);

SelectObject(memdc,hbrush);

PatBlt(memdc,0,0,maxX,maxY,PATCOPY);

// Создать новые шрифты

hnewfl=CreateFont(16,0,0,0,FW_NORMAL,0,0,0,

AHSI_CHARSET,

OUT_DEFAULT_PRECIS,

CLIP_DEFAULT_PRECIS,

DEFAOLT_QUALITY,

DEFAULT_PITCH|FW_DONTCARE,

"Times New Roman Cyr");

hnewf2=CreateFont(24,0,0,0,FW_SEMIBOLD,0,0,

0,ANSI_CHARSET,

OUT_DEFAULT_PRECIS,

CLIP_DEFAULT_PRECIS,

DEFAULT_QUALITY,

DEFAULT_PITCH|FW_DONTCARE,

"Parsek Cyrillic");

ReleaseDC(hwnd,hdc);

break;

case WM_COMMAND:

switch(LOWORD(wParam))

{

case ID_SHOW:

SetTextColor(memdc,RGB(0,0,0)); // Черн

SetBkMode(memdc,TRANSPARENT); // Прозра

GetTextMetrics(memdc,&tm); // Метрики

sprintf(str,

"Высота шрифта %s равна %ld пикселей.",

fname,tm.tmHeight);

TextOut(memdc,X,Y,str,strlen(str));

Y=Y+tm.tmHeight // Следующая

+tm.tmExternalLeading; // строка

strcpy(str,"Это следующая строка. ");

TextOut(memdc,X,Y,str,strlen(str));

GetTextExtentPoint32(memdc,str, //Длина

strlen(str),

&size);

sprintf(str,

"Длина предыдущей строки %ld.",

size.cx);

X=size.cx; // В конец предыдущей строки

TextOut(memdc,X,Y,str,strlen(str));

Y=Y+tm.tmHeight // Следующая

+tm.tmExternalLeading; // строка

X=0; // X опять в начало

sprintf(str,"Размеры экрана %d на %d.",

maxX,maxY);

TextOut(memdc,X,Y,str,strlen(str));

Y=Y+tm.tmHeight // Следующая

+tm.tmExternalLeading; // строка

InvalidateRect(hwnd,NULL,1); //Сообщить

break;

case ID_FONT:

switch(fontswitch) // На новый шрифт

{

case 0: // Переключиться на шрифт 1

holdf=(HFONT)SelectObject(memdc,

hnewfl);

fontswitch=1;

strcpy(fname,

"Times New Roman Cyr");

break;

case 1: // Переключиться на шрифт 1

SelectObject(memdc,hnewf2);

fontswitch=2;

strcpy(fname,

"Parsek Cyrillic");

break;

case 2: // Переключиться на старый

SelectObject(memdc,holdf);

fontswitch=0;

strcpy(fname,"Default");

break;

}

break;

case ID_RESET:

X=Y=0; // Стереть перерисовкой фона

PatBlt(memdc,0,0,maxX,maxY,PATCOPY);

InvalidateRect(hwnd,NULL,1); //Сообщить

break;

case ID_HELP:

MessageBox(hwnd,"F2: вывести текст\n"

"F3: сменить шрифт\n"

"F4: с начала экрана",

"Помощь",MB_OK);

break;

}

break;

case WM_PAINT: // Перерисовка окна

hdc=BeginPaint(hwnd,&paintstruct); // Пол. DC

// Теперь копируем растр из памяти на экран

BitBlt(hdc,0,0,maxX,maxY,memdc,0,0,SRCCOPY);

EndPaint(hwnd,&paintstruct); // Освободить DC

break;

case WM_DESTROY: // Завершение программы

DeleteDC(memdc); // Удалить виртуальное окно

PostQuitMessage(0);

break;

default:

// Все сообщения, не обрабатываемые в данной

// функции, направляются на обработку по

// умолчанию

return DefWindowProc(hwnd,message,

wParam,lParam);

}

return 0;

 

}

Рис. 8.3. Окно программы, работающей с логическими шрифтами

 

Пример вывода этой программы показан на рис. 8.3.

В заключение надо отметить, что Windows обладает весьма богатыми возможно­стями работы со шрифтами и текстом. В следующей главе мы будем продолжать рассматривать вопросы, связанные с отображением графической информации.




Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-03-31 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: