logo
Литература_1 / photon_old

Генерирование имён шрифтов

Как описано выше, Photon'овский API требует для идентификации шрифта имя основы, но если Вы хотите быть гибким, можете использовать лигатурное имя шрифта.

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

char * PfGenerateFontName(

char const * pkcDescription,

uint32_t kuiFlags,

uint32_t kuiSize,

char * pcBuff );

Если функция PfGenerateFontName() завершилась успешно, она возвращает указатель на буфер; в случае неудачи возвращается NULL.

Мы определили для Вас тип данных FontName для использования в буфере, переданном функции PfGenerateFontName(). Это массив размером MAX_FONT_TAG. Для успешного программирования шрифта не используйте буфер хранения идентификатора шрифта размером меньшим, чем FontName. Вот вызов функции PtAlert() – такой же, как показан выше, но на этот раз используется вызов PfGenerateFontName():

char Helvetica14[MAX_FONT_TAG];

if ( PfGenerateFontName("Helvetica", 0, 14, Helvetica14) = = NULL ) {

/* Не удалось найти шрифт! */

...

}

answer = PtAlert( base_wgt, NULL, "File Not Saved", NULL, "File has not been saved.\nSave it?",

Helvetica14, 3, btns, NULL, 1, 3, Pt_MODAL );

Теперь то, что мы рассматривали по кусочкам, просто чётко следует по пунктам, необходимым для сборки корректного имени основы для данного шрифта.

Имейте в виду следующие соображения:

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

Вот простая функция инициализации приложения:

/*****************************

*** Глобальные переменные ***

*****************************/

FontName GcaCharter14Bold;

int fcnAppInit( int argc, char *argv[] ) {

/* Локальные переменные */

FontDetails tsFontList [nFONTLIST_SIZE];

short sCurrFont = 0;

char caBuff[20];

/* Получение описания доступных шрифтов */

if (PfQueryFonts (PHFONT_ALL_SYMBOLS, PHFONT_ALL_FONTS,

tsFontList, nFONTLIST_SIZE) = = -1) {

perror ("PfQueryFonts() неудача: ");

return (Pt_CONTINUE);

}

/* Поиск среди них шрифта, совпадающего с нашими спецификациями */

for (sCurrFont = 0; sCurrFont < nFONTLIST_SIZE; sCurrFont++) {

if ( !strcmp (tsFontList[sCurrFont].desc, "Charter")) break; /* мы нашли его */

}

/* Переполнение проверки */

if (sCurrFont == nFONTLIST_SIZE) {

/* проверка на частичное совпадение */

for (sCurrFont = 0; sCurrFont < nFONTLIST_SIZE; sCurrFont++) {

if ( !strncmp (tsFontList[sCurrFont].desc, "Charter", strlen ("Charter")))

break; /* найдено частичное совпадение */

}

if (sCurrFont == nFONTLIST_SIZE) {

printf ("шрифта Charter нет в %d проверенных шрифтах.\n", sCurrFont);

return (Pt_CONTINUE);

}

else printf ("Используется частичное совпадение -- 'Charter'.\n");

}

/* Имеет ли он жирный вариант? */

if (!(tsFontList[sCurrFont].flags & PHFONT_INFO_BOLD)) {

printf ("Charter не доступен как жирный.\n");

return (Pt_CONTINUE);

}

/* Доступен ли 14-пунктый? */

if ( !( (tsFontList[sCurrFont].losize = = tsFontList[sCurrFont].hisize = = 0)

/* пропорциональный шрифт ­– а он может быть изображён в 14 пунктов */

||

( (tsFontList[sCurrFont].losize <= 14 )

&&

(tsFontList[sCurrFont].hisize >= 14 ) ) ) )

/* 14-пунктный умещается между наименьшим и наибольшим доступными размерами */

{

printf ("шрифт Charter не доступен как 14-пунктый.\n");

return (Pt_CONTINUE);

}

/* Генерирование имени основы */

if (PfGenerateFontName( tsFontList[sCurrFont].desc,

PF_STYLE_BOLD, 14, GcaCharter14Bol) = = NULL) {

perror ("PfGenerateFontName() неудача: ");

return (Pt_CONTINUE);

}

/* Теперь Вы можете использовать GcaCharter14Bold как аргумент в PtAlert(), etc. */

/* предотвращает предупреждения (варнинги) об отсутствии ссылок */

argc = argc, argv = argv;

return( Pt_CONTINUE );

} // Функции fcnAppInit()

Чтобы вышеприведенный код работал, Вы должны объявить в глобальном хеадер-файле приложения нижеследующую информацию. Чтобы это сделать, используйте диалог PhAB'а "Startup Info/Modules" (доступный из меню "Application").

/*******************************************

*** определённые пользователем константы ***

*******************************************/

#define nFONTLIST_SIZE 100 /* просто случайно выбранный размер */

/*****************************

*** глобальные переменные ***

******************************/

extern FontName GcaCharter14Bold;

Вы можете избежать использования заданного размера списка, вызвав функцию PfQueryFonts() с параметром n, установленным в 0, и параметром list – в NULL. Если Вы так сделаете, функция PfQueryFonts() вернёт количество совпавших шрифтов, но не будет пытаться заполнить список. Вы можете использовать эту возможность для определения числа записей при выделении памяти.

Помните о том, что определить этот хеадер-файл надо перед тем, как Вы начнёте добавлять ответные реакции и установочные функции – в этом случае это будет автоматически включено как #define. Если Вы забудете сделать это, Вам придётся вернуться назад и добавить оператор ручками. Более полно см. раздел "Задание глобального хеадер-файла" в главе "Работа с приложениями".

И, наконец, вот пример ответной реакции, которая использует нашу строку с именем основы:

int fcnbase_btn_showdlg_ActivateCB( PtWidget_t *widget,

ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo ) {

/* Эта ответная реакция используется для запуска диалогового окна

с целью поупражняться с глобальной переменной GcaCharter14Bold */

PtNotice (ABW_base, NULL, "Демонстрация шрифта ", NULL,

"Это написано 14-пунктовым жирным шрифтом Charter",

GcaCharter14Bold, "OK", NULL, 0);

/* предотвращает предупреждения (варнинги) об отсутствии ссылок */

widget = widget, apinfo = apinfo, cbinfo = cbinfo;

return( Pt_CONTINUE );

}

Yandex.RTB R-A-252273-3
Yandex.RTB R-A-252273-4