В этом выпуске продолжим писать программу просмотра
графических файлов - image_viewer. В этот раз займёмся выводом текста на
экран в различных режимах и с форматированием. В GTK+ формированием и
отображением текста занимается целая библиотека - Pango. Ещё есть векторная
графическая библиотека Сairo, но она позволяет уже выводить текст под разными
углами, но пока мы заёмёмся Pango. С помощью библиотеки Pango можно выводить
текст в кодировке UTF8, таким образом текст может быть
интернациональным.
Часть 1.
Рассмотрим, как можно вывести текст в область рисования с помощью функций
Pango.
Пока графический файл не открыт, будем выводить текст посредине
экрана: Выберите картинку в меню File->Open
File
Для этого в файл image_viewer.c в функцию перерисовки картинки map_expose()
вставим код: // выбираем цвет
для рисования - красный; color.red = 65535; color.green= 0; color.blue
= 0; gdk_gc_set_rgb_fg_color (gc, &color); { int
size_x,size_y; char *text="Выберите картинку в меню File->Open
File";//Файл->Открыть файл PangoFontMap *fontmap=NULL;
PangoLayout *layout = NULL; PangoFontDescription *desc; GdkScreen *screen =
gdk_screen_get_default(); PangoContext *context =
(PangoContext*)gdk_pango_context_get_for_screen(screen); //
шрифт desc = pango_context_get_font_description(context);
// меняем параметры шрифта pango_font_description_set_family(desc,"Arial");
pango_font_description_set_style(desc,PANGO_STYLE_ITALIC);//PANGO_STYLE_NORMAL
pango_font_description_set_weight(desc,PANGO_WEIGHT_BOLD);
pango_font_description_set_size(desc,16*PANGO_SCALE);
pango_context_load_font(context,desc); // Pango слой
layout = pango_layout_new(context);
pango_layout_set_text(layout,text,(int)strlen(text));
pango_layout_get_size(layout,&size_x,&size_y);// узнаём размеры текста
для вывода на экран // переводим в пиксели
size_x/=PANGO_SCALE; size_y/=PANGO_SCALE; // отрисовываем
текст на экран
gdk_draw_layout(draw_area->window,gc,dx/2-size_x/2,dy/2-size_y/2,layout);
// очистка памяти g_object_unref(context);
g_object_unref(layout); }
Для вывода текста создаётся слой Pango - PangoLayout, в который помещаем текст, а
затем слой Pango отображаем в GDK окне виджета draw_area. А теперь
поподробнее: Для начала создаём контекст Pango - PangoContext, который нужен
для создания PangoLayout.
Форматированный текст может быть выведен и в
обычных текстовых метках. Для этого текст должен быть описан с использованием
тега <span> (подобно языку HTML) Вот пример
использования тега <span>: (строка с жирным и перечёркнутым
тёмно-синей чертой текстом)
"<span weight="bold"strikethrough="true"strikethrough_color="darkblue">Bold and
dark blue text</span>"
Для того, чтобы текстовая метка не
вывела всё это форматирование в простом виде, текст добавлять нужно не с помощью
gtk_label_set_text(), а специальной функцией:
Которая выводит текст разбирая содержимое
тега <span>. Вот его описание:
Атрибут тега span
Описание
font_desc
Строка с описанием шрифта, например "Sans Italic 12"; любой span атрибут
может быть задан здесь.
font_family
Имя шрифта
face
То же самое, что и font_family
size
Размер шрифта, может принимать относительные значения: 'smaller' или
'larger' и абсолютные значения: 'xx-small', 'x- small', 'small', 'medium',
'large', 'x-large', 'xx-large'. Также размер можно указывать в цифрах, но
только в масштабе x1024. Например для шрифта 12.5, size='12800'
(12.5x1024=12800), но проще использовать font_desc='12.5' .
style
Наклон шрифта, может принимать значения: 'normal', 'oblique',
'italic'
weight
Жирность шрифта, может принимать значения: 'ultralight', 'light', 'normal',
'bold', 'ultrabold', 'heavy', или числа
variant
'normal' или 'smallcaps'
stretch
Ширина шрифта, может принимать значения:'ultracondensed', 'extracondensed',
'condensed','semicondensed', 'normal', 'semiexpanded',
'expanded','extraexpanded', 'ultraexpanded'
foreground
Цвет символов.В виде RGB, один и тот же цвет может быть определен как
'#00FF00' или '#0F0' или 'green'
background
Цвет фона.В виде RGB, один и тот же цвет может быть определен как '#FF0000'
или '#F00' или 'red'
underline
Нижнее подчёркивание, может принимать значения: 'single', 'double', 'low',
'none'
underline_color
Цвет нижнего подчёркивания, в виде RGB, без underline не имеет
смысла
Перечёркивание текста, может принимать значения: 'true' or
'false'
strikethrough_color
Цвет линии перечёркивания текста, в виде RGB, без strikethrough
не имеет смысла
fallback
Принимает значения: 'true'(по умолчанию) or 'false'. Можно ли выбрать шрифт
с другими характеристиками, если заданный не доступен в системе. Если
fallback='false', то при недоступности шрифта может быть выдана ошибка, а если
fallback='true' - буден выбран максимально похожий шрифт.
lang
Код используемого языка
Вместо тега <span> можно использовать и некоторые другие,
с меньшими возможностями, например
<b>bold</b> означает жирный текст.
Описание дополнительных тегов дано в таблице:
Дополнительные теги
b
Жирный текст
big
Увеличить шрифт, тоже самое, что и <span size="larger">
i
Наклон
s
Перечёркивание
sub
Опускание вниз текста
sup
Подъём вверх текста
small
Уменьшить шрифт, тоже самое, что и <span size="smaller">
tt
Шрифт с равномерными сомволами по ширине(Monospace)
u
Нижнее подчёркивание
В качестве примера использования новой возможности добавим диалог "О
программе" и напишем в нём форматированный текст.
В обработчик меню menuitem_response() добавим перехват выбора меню About:
if
(!strcmp(menu_name,"About")) { // диалог - о программе;
dlg_about(GTK_WIDGET(window)); }
Вот код диалоговой функции:
// диалог
- О программе int dlg_about(GtkWidget *parent) { GtkWidget
*dialog=NULL; GtkWidget *vbox; GtkWidget *label; gchar
*str; // создаём диалог с одной кнопкой OK dialog =
gtk_dialog_new_with_buttons("О программе",(GtkWindow*)parent,
GTK_DIALOG_MODAL|
GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_NO_SEPARATOR,
GTK_STOCK_OK,
GTK_RESPONSE_OK,
NULL);
Здесь нет ничего необычно, создаётся окно dialog, упаковываем в него
текстовую метку label, отображаем диалог и запускаем ожидание нажатия клавиши
кнопки OK (или закрытия диалога). Вот строка, которую будем выводить в текстовой
метке: (Синий текст, жирый и большой.)