Использование Freetype. Получение битового образа символов

Блоговая публикация пользователя: Flashhell Эта публикация была перенесена из личного блога пользователя в общие разделы уровок сайта.

Использование Freetype. Получение битового образа символов

В этом уроке вы подробнее познакомитесь с библиотекой Freetype, чтобы в дальнейшем использовать эти знания для рендера текста в OpenGL с ее помощью.

Скачать проект (Visual studio 2008) 

В этом проекте используется полная, статическая, "тяжелая" MT версия Freetype, собранная мной. Хотя Fretype можно собрать по модулям, я не стал этого делать. Также в проекте есть папочка to_SDK, к которой в свойствах проекта прописан путь к ней. В ней лежат заголовки (Heareds) Freetype. И если у Вас по какой-либо причине не отображаются какие-то заголовки, переместите содержимое папки в C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include или поправьте свойства проекта.

Полезные ссылки:

Сайт проекта Freetype
Документация и инструкции

Если говорить конкретно, то Freetype - это шрифтовый движок.

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

Практически весь текст в Linux и других Unix подобных системах был считан с помощью этой библиотеки.

Кстати, сама библиотека не имеет методов для обработки и непосредственной отрисовки на экран графики.

Разберем небольшой пример использования Freetype.

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

Код:
/*http://esate.ru, Flashhell*/

/*    Небольшой пример использования Freetype.                     */
/*    Пример сделан на основе примера из документации к Freetype   */
/*    Отрисуем строку в текстовый файл.                            */
/*         FreeType 2 library.                                     */

// Подключаем Freetype
#include <ft2build.h> 
#include FT_FREETYPE_H

// Подключаем стандартные классы и функции работы с файлами
#include <fstream>
// Для потоков ввода/вывода (cin, cout...)
#include <iostream>
// Для работы со строками
#include <string>

// ! Подключаем отдельные классы, чтоб не писать std::
//  но и не засорять глобальное пространство имен
using std::string;
using std::wstring;
using std::cout;
using std::cin;

// ! Указатели на библиотеку и Face
FT_Library ft;
FT_Face face;

// ! Объект для работы с файлами
std::ofstream file;

int main( int argc, char**  argv )
{
  // ! Устанавлеваем локаль для нормальной работы с кирилицей
  std::wcin.imbue(std::locale("rus_rus.866"));

  string font_file_name;     // путь к шритфу
  wstring draw_str;          // юникод текст для отрисовки
  string render_to_file_name;// файл для сохранения отрисованной строки

  // ! Просим путь к файлу шрифта
  cout<<"Enter font file path: \n";
  std::getline(std::cin, font_file_name);

  // ! Инициализация библиотеки Freetype
  if(FT_Init_FreeType(&ft)) 
  {
    cout<<"Could not init freetype library\n";
    return 1;
  }

  // ! Загрузка шрифта 
  if(FT_New_Face(ft, font_file_name.c_str(), 0, &face)) 
  {
    // ! Не удалось загрузить
    cout<<"Could not "<<font_file_name<<"\n";
    return 1;
  }

  // ! Просим ввести текст для отрисовки
  cout<<"Enter text to render: \n";
  std::getline(std::wcin, draw_str);

  // ! Просим ввести путь к файлу для сохранения
  cout<<"Enter file to save render result: \n";
  std::getline(std::cin, render_to_file_name);

  // ! Открываем файл для записи (или создаем, если его нет)
  file.open(render_to_file_name.c_str(), std::ios_base::out);
  if(!file)
  {
    // ! Не удалось открыть файл
    cout<<"Could open file: "<<render_to_file_name<<"\n";
    return 1;
  }

  // ! Установка размера пикселя (специфическое понятие в Freetype)
  //  и обязательное для FT_Load_Glyph
  FT_Set_Pixel_Sizes(face, 0, 36);
  // ! Указатель на глиф
  FT_GlyphSlot g = face->glyph;

  // ! Цикл отрисовки образов символов из строки в файл 
  for(unsigned int i = 0; i < draw_str.size(); ++i)
  {
    // ! Пытаемся загрузить образ одного символа
    //  эта функция(FT_Load_Char) вызывает FT_Load_Glyph и FT_Get_Char_Index
    if(FT_Load_Char(face, draw_str.at(i), FT_LOAD_RENDER))
    {
      // ! Не удалось загрузить битовый образ символа
      cout<<"glyph not load!! \n";
      continue;
    }

    // ! Отрисовываем образ в файл
    for (int y = 0; y < g->bitmap.rows; ++y)
    {
      for (int i = 0; i < g->bitmap.width; ++i)
      {
        // ! Вытяваем значение байта образа
        unsigned char c = g->bitmap.buffer[y * g->bitmap.width + i];
        if(c == 0)
          file<<' ';     // Если ноль, записываем пробел
        else if(c < 128)
          file<<'+';     // Если "прозрачность" ниже 128
        else
          file<<'#';     // Если "прозрачность" выше 128
      }
      file<<'\n';
    }
    file<<"\n\n";
  }

  // ! Заставлем сбросить внутренний буфер Ofstream в файл
  file.flush();
  // ! Закрываем файл
  file.close();

  // ! Освобождаем выделенные ресурсы и библиотеку
  FT_Done_Face(face);
  FT_Done_FreeType(ft);
}


Здесь намеренно все происходит в Main, для простоты.

Уроки OpenGL различных тематик: Консольное окно созданной программы Рисунок 1. Консольное окно созданной программы.

Уроки OpenGL различных тематик: Результат вывода текста с помощью написанной программы Рисунок 2. Результат вывода текста с помощью написанной программы.

Нет доступа к просмотру комментариев.

^