Список постов в категории "Программирование"

./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. Давайте освоим эту библиотеку.

Основные объекты FreeType:

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

Эти параметры доступны через структуру FT_Face. Подробнее о работе с текстом — в следующей части!

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

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

Существуют три основных подхода:

Готовые текстовые битмапы

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

Плюсы:

  • Максимальная производительность
  • Полная свобода дизайна (любые стили и эффекты)
  • Всю работу делает художник/дизайнер

Минусы:

  • Медленная локализация
  • Большой расход памяти
  • Нельзя динамически менять текст

Текстура с символами (текстурный атлас)

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

Плюсы:

  • Относительно высокая производительность
  • Быстрая локализация (сгенерировать новую текстуру для языка)
  • Шрифт в любом стиле
  • Динамическое изменение надписи

Минусы:

  • Необходимо написать генератор этих текстур
  • Для разных языков нужны разные атласы
  • Локализация увеличивает размер приложения

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

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

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

Плюсы:

  • Минимальный расход памяти (один файл шрифта)
  • Простая локализация
  • Полная динамичность текста
  • Поддержка всех языков

Минусы:

  • Требует больше CPU при первом использовании символов
  • Ограниченный стиль (зависит от шрифта)
  • Сложная реализация

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

Личный блог Евгения Жирнова