Мне требуется отрендерить произвольный текст (с переносами) в простой буффер - альфа канал. Сейчас делаю так (коряво и костыльно на мой взгляд):
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;
}
}
fontSize - размер шрифта в пикселях, указанный при загрузке
Как видите, я тут вычисляю наибольший bearingY для того, чтобы узнать, на какой высоте будет baseline в битмапах. Также вычисляется ширина и высота изображения.
Ещё есть проблема: для некоторых глифов ('I', например) fontFace->glyph->bitmap_left < 0 и, если он в начале строки, то происходит fail.
Вообщем, как лучше всего рендерить текст в таком случае?