Соц. Инженерия: Создаём окошко с текстом
В этой статье мы будет без использования фотошопа делать окошко с текстом. Мне кажется, результат будет интересным, интереснее чем название самой статьи.
Мы будет использовать для этого библиотеки GTK и fontconfig. Также я скачал ttf-шрифт PerfectDOSVGA437.
Для начала вам необходимо их установить. Для начинающих линуксойдов я дам несколько вариантов команд, в зависимости от вашего :
# ubuntu/debian sudo apt-get update sudo apt-get install libgtk-3-dev libfontconfig1-dev # fedora/centos/rhel sudo dnf install gtk3-devel fontconfig-devel # opensuse sudo zypper install gtk3-devel fontconfig-devel # ArchLinux sudo pacman -S gtk3 fontconfig
Для начала нам нужно заняться встраиванием шрифта. Я заранее позаботился об этом и создал гист с perfectdosvga. Вам необходимо скачать его. Я назову файл с этим кодом systemfont.h
Приступаем к самому коду. Для удобства я определю размеры окна через define
#include <gtk/gtk.h>
#include <fontconfig/fontconfig.h>
#include <stdio.h>
// Размеры окна
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
// Включение массива шрифта
#include "systemfont.h"
// Функция для создания временного файла из встроенного массива
char* create_temp_font_file() {
char *temp_path = "/tmp/temp_font.ttf";
FILE *fp = fopen(temp_path, "wb");
if (fp == NULL) {
perror("Failed to create temp font file");
return NULL;
}
fwrite(PerfectDOSVGA437_ttf, 1, PerfectDOSVGA437_ttf_len, fp);
fclose(fp);
return temp_path;
}Воспользуемся немного cairo и создадим событие отрисовки. Пусть экран у меня будет чёрный, а текст белый. Нам нужно будет инициализировать fontconfig и вызвать функцию создания временного файла
gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
// Заливка экрана
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_paint(cr);
// Установка цвета текста
cairo_set_source_rgb(cr, 1, 1, 1);
// Создание временного файла
char *font_path = create_temp_font_file();
if (!font_path) return FALSE;
// Инициализация конфигурации шрифта
FcConfig *config = FcInitLoadConfigAndFonts();
FcConfigAppFontAddFile(config, (const FcChar8 *)font_path);
FcConfigSetCurrent(config);Дальше поступим так, как любят педанты. Нарисуем текст и всё после этого приберём. В том числе и не забудем удалить временный файл
// Задаём контекст и наш шрифт
PangoContext *context = gtk_widget_create_pango_context(widget);
PangoFontDescription *desc = pango_font_description_from_string("PerfectDOSVGA437 12");
// Создание слоя
PangoLayout *layout = pango_layout_new(context);
pango_layout_set_text(layout, "Hello, TeleType!", -1);
pango_layout_set_font_description(layout, desc);
// Отрисовка
cairo_move_to(cr, 10, 10);
pango_cairo_show_layout(cr, layout);
// Шмотки на базу!
g_object_unref(layout);
pango_font_description_free(desc);
g_object_unref(context);
FcConfigDestroy(config);
remove(font_path);
return FALSE;
}int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
// Создание окна
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Just Window");
gtk_window_set_default_size(GTK_WINDOW(window), WINDOW_WIDTH, WINDOW_HEIGHT);
// Запрет изменения размеров окна
gtk_widget_set_size_request(window, WINDOW_WIDTH, WINDOW_HEIGHT);
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
// Обработка сигнала закрытия окна
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
// Создание области для рисования
GtkWidget *drawing_area = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), drawing_area);
g_signal_connect(G_OBJECT(drawing_area), "draw", G_CALLBACK(on_draw_event), NULL); // Установка функции отрисовки
gtk_widget_show_all(window);
gtk_main();
return 0;
}В целях мастер-класса я просто скомпилирую это через gcc -o main main.c $(pkg-config --cflags --libs gtk+-3.0 fontconfig)