Гайды
June 1, 2024

Соц. Инженерия: Создаём окошко с текстом

В этой статье мы будет без использования фотошопа делать окошко с текстом. Мне кажется, результат будет интересным, интереснее чем название самой статьи.

Мы будет использовать для этого библиотеки 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)

Результат:

Sheo,
Copyleft (C) DigitalHazard 2024