Всем поклонникам OpenSource приложений известна библиотека растеризации шрифтов FreeType. Ее используют практически все графические приложения под GNU/Linux. Попробуем и мы освоить этот несложный навык.
Сперва про используемые типы:
FT_Library
— представляет собой структуру для иницизации библиотекиFT_Face
— шрифт, который загружается при помощиFT_Library
FT_Glyph
— глиф шрифта, который создается при помощиFT_Face
Таким образом, для отображения символа нам надо создать объект типа FT_Library
, затем загрузить шрифт в объект типа FT_Face
, после этого рисовать символы при помощи FT_Glyph
.
Символ из шрифта можно извлечь двумя способами:
- Получить информацию для его рисования кривыми
- Получить готовое изображение
Первый способ нам неинтересен, будем использовать сразу второй. Поехали (проверка ошибок убрана для упрощения кода):
#include <ft2build.h>
#include FT_FREETYPE_H
int main()
{
// Библиотека FreeType
FT_Library library = 0;
// Инициализация библиотеки
FT_Init_FreeType(&library);
// Шрифт
FT_Face face = 0;
// Загрузка шрифта
FT_New_Face(library, "tahoma.ttf", 0, &face);
// Установка размера пикселя
FT_Set_Pixel_Sizes(face, 24, 12);
// Код символа (юникод)
const FT_ULong charCode = L'W';
// Загрузка глифа из шрифта с его отрисовкой
FT_Load_Char(face, charCode, FT_LOAD_RENDER);
// Получение готового к использованию глифа
FT_GlyphSlot glyph = face->glyph;
// Получение размеров глифа
const int width = glyph->bitmap.width;
const int height = glyph->bitmap.rows;
const int pitch = glyph->bitmap.pitch;
// Вывод символа в консоли
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
// Получение прозрачности точки (x, y)
const int a = glyph->bitmap.buffer[y * pitch + x];
if (a > 127)
{
printf("*");
}
else
{
printf(" ");
}
}
printf("\n");
}
// Удаление шрифта
FT_Done_Face(face);
face = 0;
// Удаление библиотеки
FT_Done_FreeType(library);
library = 0;
}
Консоль:
** *** ***
** **** **
** **** ***
** ** ** **
** * ** ***
** ** ** **
** * * ***
**** ****
*** ***
Отличная работа, но для вывода слова из нескольких букв простого изображения символа недостаточно. Необходимо иметь следующую информацию:
- положение горизонтальной базовой линии (например, «W» — внизу, «y» — примерно середина высоты)
- межстрочный интервал (если вы хотите вывести многострочный текст)
- кернинг (расстояние между различными буквами)
Подробнее об этом в следующей части.