Смекни!
smekni.com

Семейства шрифтов в Windows (стр. 3 из 5)

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

В этом разделе мы будем говорить только о создании собственных растровых шрифтовых ресурсов. Это связано с тем, что стандартные редакторы шрифтовых ресурсов (включаемые в SDK и компиляторы) позволяют создавать только растровые шрифты.

Для начала мы должны нарисовать требуемые нам шрифты с помощью какого-либо редактора ресурсов. Растровые шрифты обычно размещаются в файлах с расширением .FNT (это не шрифтовой файл, а отдельный ресурс, как, скажем, битмап). Нам может понадобится нарисовать несколько шрифтов разного размера, но имеющих общее начертание. Эти шрифты будут сохранены в разных .FNT файлах.

Далее мы должны построить шрифтовой файл .FON, содержащий наши шрифты. Этот файл являться библиотекой ресурсов. Практически он оформлен как обычное Windows приложение, которое содержит только ресурсы. Мы можем описать такое приложение, как приложение вообще не имеющее сегмента кода, или как библиотеку.

Так как наша библиотека должна содержать шрифтовые ресурсы, то мы должны задать файл описания ресурсов .RC, содержащий список нарисованных нами шрифтов, например:

1 FONT fonta.fnt

2 FONT fontb.fnt

3 FONT fontc.fnt

Конечно нам понадобится файл описания приложения .DEF в несколько специфичном виде:

LIBRARY

DESCRIPTION 'FONTRES DISPLAY : 40-char terminal'

EXETYPE WINDOWS

STUB 'WINSTUB.EXE'

DATA NONE

Надо обратить внимание на использование слова LIBRARY, вместо NAME, для указания того, что это не обычное приложение, а библиотека. Далее мы должны указать, что наша библиотека не имеет данных 'DATA NONE' и составить описание нашего шрифта. Для этого мы должны в DESCRIPTION указать строку специального формата:

DESCRIPTION 'FONTRES aspect,logpixelsx,logpixelsy : comment'

DESCRIPTION 'FONTRES DEVICESPECIFIC device : comment'

DESCRIPTION 'FONTRES DISPLAY : comment'

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

Второй формат задает шрифт, созданный для конкретного устройства. Параметр device задает имя устройства, для которого шрифт спроектирован, например: IBM 8514. Третий формат указывает, что шрифт спроектирован для дисплея.

Далее мы должны построить библиотеку ресурсов. Как уже говорилось, это можно сделать двумя способами - создав приложение не имеющее кода или создав приложение, являющееся разделяемой библиотекой.

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

_TEXT segment byte public 'CODE'

_TEXT ends

end

Этот файл описывает только один сегмент нулевой длины.

После этого мы можем приступить к построению шрифтового файла. Для этого мы сначала компилируем ассемблерный файл:

tasm file.asm

затем мы должны построить нашу библиотеку и включить в нее спроектированные ресурсы:

tlink file.obj,file.exe,nul,,file.def

rc file.rc

rename file.exe file.fon

Теперь мы располагаем собственным шрифтовым ресурсом, который мы можем применять в нашем приложении. Еще раз надо отметить, что обязательно применение 'Borland TLINK' для построения файла, так как другие сборщики могут построить неверный модуль.

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

#include <windows.h>

extern "C" {

int CALLBACK LibMain(

HANDLE hInstance, WORD wDataSeg, WORD cbHeapSize,LPSTR lpszCmdLine) {

// обычно функция LibMain() разблокирует сегмент данных

// если он имеет динамический heap.

// if ( cbHeapSize ) UnlockData( 0 );

// так как мы вообще не имеем данных (и heap тоже)

// то можем этого не делать.

return 1;}

int CALLBACK WEP( int bSystemExit ) {

return TRUE;}}

Этот файл содержит две процедуры - LibMain() - которая заменяет обычный WinMain() и вызывается при инициализации библиотеки - и процедуру WEP(), которая вызывается при удалении ненужной библиотеки.

В этом файле надо обратить внимание на то, что функция LibMain описана как CALLBACK (PASCAL FAR), в отличие от WinMain. К сожалению, некоторые компиляторы предполагают, что она должна быть NEAR для моделей памяти с одним сегментом кода. В качестве выхода можно изменить имя, например, написать его только большими буквами. Тогда компилятор не распознает эту функцию как стандартную и не сделает ошибки, а сборщик осуществит правильное связывание, так как функция декларирована как CALLBACK (PASCAL FAR).

Вторая особенность - указание, что имена функций не должны кодироваться как C++ имена ( extern "C" ). Это опять–же связано с особенностями некоторых компиляторов, которые не распознают функцию WEP() (Windows Exit Procedure) как стандартную, и осуществляют для нее C++ кодирование имени - при этом сборщик не может правильно построить задачу.

В остальном построение шрифтового файла не отличается от рассмотренного, конечно кроме компиляции исходного текста, которая выполняется как для обычного Windows-приложения:

bcc -ms -W file.c file.def

2.3 Особенности TrueType шрифтов

Сейчас мы рассмотрим некоторые особенности применения собственных TrueType шрифтов. Эти особенности связаны с тем, что TrueType шрифт представлен в совершенно иной форме, чем растровые шрифты. Если Вы с помощью какого-либо инструментального средства (например, FontoGrapher) создадите TrueType шрифт, то обнаружите, что он представлен в виде файла с расширением .TTF.

Однако применять .TTF файл непосредственно нельзя. Для того, что бы можно было использовать TrueType шрифт надо построить промежуточный файл, обычно с расширением .FOT, который можно использовать вместо файла .FON для добавления шрифта в таблицу ресурсов. Для построения этого файла Вы должны воспользоваться функцией

BOOL CreateScalableFontResource(

nHidden, lpszResourceFile, lpszFontFile, lpszPath);

Эта функция создает файл с именем lpszResourceFile для доступа к .TTF файлу, заданному параметром lpszFontFile, параметр lpszPath указывает путь до .TTF файла. Последний оставшийся параметр nHidden указывает возможность использования шрифта другими приложениями. Если он 0, то другие приложения имеют доступ к этому шрифту, а если 1, то доступ запрещен и этот шрифт не перечисляется при переборе шрифтов (EnumFonts(), EnumFontFamilies()).

2.4 Настройка приложений

Заканчивая разговор о шрифтах, удобно рассмотреть еще один компонент Windows - средства для настройки приложений. Под настройкой (иногда "профилированием") понимается задание характеристик приложения и их сохранение для использования при следующем запуске.

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

Такие файлы (обычно имеющие расширение .INI) являются обычными ASCII–файлами, разделенными на секции, начинающиеся с имени секции, заключенного в квадратные скобки. Далее следует список параметров в виде ‘параметр=значение’, каждый параметр размещается в отдельной строке. В этот файл можно вставлять комментарии - строки начинающиеся с ‘;’.

Пример взят из файла WORKSHOP.INI:

[User Controls]

BorShade=E:&bsol;BORLANDC&bsol;WORKSHOP&bsol;BWCC.DLL

[RWS_Bitmap]

PercentLeft=50

ZoomLeft=1

ZoomRight=1

bVert=0

[RWS_Font]

PercentLeft=50

ZoomLeft=4

ZoomRight=1

bVert=1

Для работы с такими файлами Windows предоставляет набор функций, осуществляющих запись и чтение параметров:

int GetProfileInt(lpszSection, lpszEntry, nDefault);

int GetProfileString(lpszSection, lpszEntry, lpszDefault, lpsBuffer, nMaxBuffer);

BOOL WriteProfileString(lpszSection, lpszEntry, lpszString);

Параметр lpszSection задает имя секции (скобок в имени указывать не надо), lpszEntry - имя параметра. Если мы получаем значение параметра, то можем указать значение по умолчанию, которое возвращается, если данный параметр не найден.

С помощью функции GetProfileString() можно получить список имен всех параметров в секции, указав lpszEntry= NULL. При этом имена параметров секции будут скопированы в буфер последовательно друг за другом, каждое имя будет заканчиваться 0 и после последнего имени будут стоять два 0.

Функция WriteProfileString() позволяет не только записывать параметры, но и удалять, для чего надо указать lpszString=NULL. Можно удалить целиком всю секцию, указав lpszEntry=NULL.

Все три рассмотренных функции используют файл WIN.INI. При этом имя секции часто ассоциируется с именем приложения. (Поэтому в документации имя секции часто называется именем приложения).

Конечно, часто бывает неудобно использовать общий файл настройки для всех существующих приложений (при этом, в частности, трудно организовать удаление приложений). Windows предоставляет возможность использовать собственный файл настройки (и даже несколько). Для работы с собственными файлами настройки предусмотрены еще три функции:

int GetPrivateProfileInt( lpszSection, lpszEntry, nDefault, lpszIniFile );

int GetPrivateProfileString(

lpszSection, lpszEntry, lpszDefault, lpsBuffer, nMaxBuffer, lpszIniFile);

BOOL WritePrivateProfileString(

lpszSection, lpszEntry, lpszString, lpszIniFile);

Последний параметр этих функций задает имя файла настройки. Если Вы не указываете путь к файлу, то он размещается в каталоге Windows.

2.5 Информация стандартных файлов настройки (win.ini и system.ini) о шрифтах и о принтере

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

Сейчас мы рассмотрим информацию, хранимую в этом файле, касающуюся шрифтов. Самая существенная для нас секция - [fonts]. В этой секции перечислены все шрифты, которые помещаются в системную таблицу при запуске Windows. Формат записей:

face name = file.fon

face name - это имя шрифта, а file.fon - имя шрифтового файла, содержащего растровый или векторный шрифт, или file.fot - TrueType шрифт.