LINUX.ORG.RU

[freetype2] Рендеринг текста


0

1

Мне требуется отрендерить произвольный текст (с переносами) в простой буффер - альфа канал. Сейчас делаю так (коряво и костыльно на мой взгляд):

    int x = 0;
    int y = 0;
    int lines = 1;
    int bearingY = 0;
    int width = 0;
    int i;

    std::string text = t;

    for (i = 0; i < text.length(); i++)
    {
        FT_UInt glyph_index;
        glyph_index = FT_Get_Char_Index(fontFace, text.at(i));
        FT_Load_Glyph(fontFace, glyph_index, FT_LOAD_DEFAULT);
        bearingY = bearingY < fontFace->glyph->metrics.horiBearingY >> 6 ? fontFace->glyph->metrics.horiBearingY >> 6 : bearingY;
        x += fontFace->glyph->advance.x >> 6;

        if (text.at(i) == '\n')
        {
            width = x > width ? x : width;
            x = 0;
            lines++;
        }
    }
    width = x > width ? x : width;

    int fullHeight = lines * fontSize;
    int lineHeight = fontSize;
    int fullWidth = width;

    x = 0;
    y = 0;
    int line = 0;

    unsigned char *imageData = new unsigned char[fullWidth * fullHeight];
    memset(imageData, 0, fullWidth * fullHeight);

    for (i = 0; i < text.length(); i++)
    {
        if (text.at(i) == '\n')
        {
            x = 0;
            line++;
        }
        else
        {
            FT_UInt glyph_index;
            glyph_index = FT_Get_Char_Index(fontFace, text.at(i));
            FT_Load_Glyph(fontFace, glyph_index, FT_LOAD_DEFAULT);
            FT_Render_Glyph(fontFace->glyph, FT_RENDER_MODE_NORMAL);

            drawGlyph(imageData, fullWidth,
                      x + fontFace->glyph->bitmap_left, bearingY - fontFace->glyph->bitmap_top + line * fontSize,
                      fontFace->glyph->bitmap.width, fontFace->glyph->bitmap.rows,
                      fontFace->glyph->bitmap.buffer);

            x += fontFace->glyph->advance.x >> 6;
        }
    }
drawGlyph() - функция, которая рисует (копирует) в главный буффер.

fontSize - размер шрифта в пикселях, указанный при загрузке

Как видите, я тут вычисляю наибольший bearingY для того, чтобы узнать, на какой высоте будет baseline в битмапах. Также вычисляется ширина и высота изображения.

Ещё есть проблема: для некоторых глифов ('I', например) fontFace->glyph->bitmap_left < 0 и, если он в начале строки, то происходит fail.

Вообщем, как лучше всего рендерить текст в таком случае?

★★★★

м.б. посмотреть как это реализовано в SDL_ttf ?

anonymous2 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.