Внимание!

Эта публикация перенесена в раздел уроков по адресу Использование freetype. Получение битового образа символов.
К ней прикреплена новая отдельная ветка комментариев форума, которую вы можетет найти после текста публикации.
Обсуждение публикации рекуомендуется вести по новому адресу, который указан выше.

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

Думаю практически все программисты(и не только) знают или хотя бы слышали, что такое freetype. Поэтому не будет долгих вступлении, копипаста информации с других ресурсов, о том, что такое freetype.
[spoiler]
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, для простоты.=)





Цель
Цель этого поста чуток познакомить Вас с библиотекой freetype, для того чтобы в дальнейшем использовать эти знания для рендера текста в OpenGL с ее помощью.
P.S. Просто хотел разбить урок о рендере текста в OpenGL))


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

Полезные ссылки
сайт проекта freetype
документация и туториалы
0       2335        02.08.2012        2

Внимание!

Эта публикация перенесена в раздел уроков по адресу Использование freetype. Получение битового образа символов.
К ней прикреплена новая отдельная ветка комментариев форума, которую вы можетет найти после текста публикации.
Обсуждение публикации рекуомендуется вести по новому адресу, который указан выше.

0  
01.09.2012 00:00:00
А можно использовать этот метод, только сохранять символ не в текстовый файл в виде символов, а картинку tga например?
0  
03.09.2012 00:00:00
Можно, взять OpenIL и с помощью него сохранить все в TGA. Как нибудь напишу пример.
^