./configure && make && make install

Как всем известно, классическим способом установки приложений в *nix подобных системах является такая последовательность команд:

cd libfoo
./configure
make
make install

Переходим в папку с исходниками, запускаем древний, как говно мамонта, скрипт конфигурирования, затем сборка и инсталляция.

Оказывается, скрипт configure может совершенно спокойно мусорить работать из другой папки:

mkdir build-libfoo
cd build-libfoo
../libfoo/configure
make
make install

После этого можно удалять build-libfoo и папка с исходниками останется в чистом виде. Таким образом можно собирать одну и ту же библиотеку с разными флагами в своих папках, используя одни и те же исходники.

Меняем формат вывода плагина WP-PostRatings

Плагин WP-PostRatings использует функцию number_format_i18n() для вывода рейтинга в числовом виде, используя данные локали. В русском варианте цифры выглядят так: «Рейтинг статьи 4,80 из 5». Как программисту, мне неприятно было видеть запятую в виде разделителя и лишний ноль в конце. Хотя математически все соответствует русским стандартам.

Существует способ поменять формат вывода, но для этого придется править исходники плагина.

Процедура довольно простая: открываем файл wp-postratings/wp-postratings.php в редакторе плагинов. Находим такие строчки:

$value = str_replace("%RATINGS_MAX%", number_format_i18n($ratings_max), $value);
$value = str_replace("%RATINGS_AVERAGE%", number_format_i18n($post_ratings_average), $value);

И меняем функцию number_format_i18n() на number_format():

$value = str_replace("%RATINGS_MAX%", number_format($ratings_max, 1, '.', ''), $value);
$value = str_replace("%RATINGS_AVERAGE%", number_format($post_ratings_average, 1, '.', ''), $value);

После этой процедуры рейтинг будет выводится так: «Рейтинг статьи 4.8 из 5.0». Число в скобках означает количество цифр после запятой.

Тестовое задание для программиста в Trickster Games

Давным-давно, в далеком 2007 году, я работал в славной компании «Trickster Games». Сейчас ее уже нет, но она была известна как разработчик игр для детей и квеста «Петрович и все, все, все..».

Так вот, в те далекие времена мы придумали тестовое задание для программиста:

#include <SomeStream.h>
 
void main()
{
    SomeStream stream;
    stream.info() << "Привет, мир!";
}

Задача: реализовать класс SomeStream таким образом, чтобы после выполнения main() в std::cout было выведено «Привет, мир!\n» (без кавычек). То есть добавить перевод строки в конец фразы.

Тогда никто из кандидатов не смог его решить. Может вам повезет? (:

Вот вам подсказка: крутая система логирования.

Использование библиотеки FreeType для растеризации символов

Всем поклонникам OpenSource приложений известна библиотека растеризации шрифтов FreeType. Ее используют практически все графические приложения под GNU/Linux. Попробуем и мы освоить этот несложный навык.

Сперва про используемые типы:

  • FT_Library — представляет собой структуру для иницизации библиотеки
  • FT_Face — шрифт, который загружается при помощи FT_Library
  • FT_Glyph — глиф шрифта, который создается при помощи FT_Face

Таким образом, для отображения символа нам надо создать объект типа FT_Library, затем загрузить шрифт в объект типа FT_Face, после этого рисовать символы при помощи FT_Glyph.

Символ из шрифта можно извлечь двумя способами:

  1. Получить информацию для его рисования кривыми
  2. Получить готовое изображение

Первый способ нам неинтересен, будем использовать сразу второй. Поехали (проверка ошибок убрана для упрощения кода):

#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» — примерно середина высоты)
  • межстрочный интервал (если вы хотите вывести многострочный текст)
  • кернинг (расстояние между различными буквами)

Подробнее об этом в следующей части.

Выводим текст в OpenGL ES 2.0

Перед каждый разработчиком, если он пишет приложение графическое на своём движке, рано или поздно встаёт вопрос: каким образом вывести текст. Я напомню, что OpenGL(ES) умеет только рисовать треугольники и накладывать на них текстуру.

Таким образом, учитывая доступные средства, вывести текст можно несколькими способами:

  • статическая текстура с готовыми надписями и текстурные координаты каждой надписи (два треугольника на надпись)
  • статическая текстура с символами и текстурные координаты каждого символа (два треугольника на символ)
  • динамическая текстура с символами и файл шрифта (два треугольника на символ)

Статическая текстура с готовыми надписями и текстурные координаты каждой надписи

Все надписи, которые встречаются в игре, рисуются заранее в текстуру. Такой вариант самый быстрый и простой в реализации для программиста. Фактически, вам надо взять текстуру и ее нарисовать (надеюсь вы это уже умеете).
Раскрывает полный простор для творчества, можно рисовать любую надпись, любым стилем и цветом.
Для оптимизации можно все надписи поместить в одну текстуру и рисовать все надписи на экране в один проход. При локализации необходимо рисовать другую текстуру с переведенным текстом.

Плюс/минусы:
+ самый быстрый вариант по скорости работы
+ всю работу за вас делает художник
+ надпись в любом стиле
− медленная локализация
− тратит много памяти
− статическая надпись

Статическая текстура с символами и текстурные координаты каждого символа

Для реализации этого способа необходимо каким-то образом сгенерировать текстурный атлас с каждым символом из шрифта.
Самый медленный в реализации способ из предложенных, зато каждый символ может быть нарисован в любом стиле. Но помните, что для каждого языка придётся заново рисовать каждый символ в выбранном вами стиле.

Плюсы/минусы:
+ относительно быстрая локализация (сгенерировать новую текстуру для языка)
+ шрифт в любом стиле
+ динамическое изменение надписи
− необходимо написать генератор этих текстур
− локализация увеличивает размер приложения

Динамическая текстура и файл шрифта

Фактически этот вариант представляет собой второй способ, но вместо текстуры с символами, используется файл шрифта (например ttf), где все эти символы описаны в векторном формате. В этом случае вместо мегабайтных текстур вам необходимо хранить один файл шрифта размером в десятки, максимум сотни, килобайт.

Текстуру можно создавать двумя способами: заполнить её всеми используемыми символами (26 — латинский алфавит, 33 — кириллица) или добавлять символ только тогда, когда он понадобится. Уже сложившейся традицией для генерации символа из шрифта является использование библиотеки FreeType.

Плюсы/минусы:
+ самая быстрая локализация
+ динамическое изменение надписи
+ самый маленький размер
− шрифт в одном стиле

Про работу с FreeType (+пример) можно почитать в моем следующем посте: «Использование библиотеки FreeType для растеризации символов».

Блог Евгения Жирнова