У меня возникли некоторые проблемы с использованием freetype2 рендеринга текста, адаптируя его от использования SDL_ttf ранее.
Код ниже приводит к следующему изображению:
Ясно, что не шрифт DejaVu Sans, на который он установлен, но, к сожалению, я не понимаю, что происходит не так.
Я думаю, что код в основном не требует пояснений — blit_rect.address является целевым буфером
/**
* Blit text to the screen.
* @param text Text to display.
* @param colour Colour of the text.
* @param xpos Absolute horizontal position at the display.
* @param ypos Absolute vertical position at the display.
* @param width Available width of the text (in pixels).
* @param align Horizontal alignment of the string.
*/
void VideoSystem::BlitText(const uint8 *text, uint32 colour, int xpos, int ypos, int width, Alignment align)
{
this->blit_rect.ValidateAddress();
int w, h;
this->GetTextSize(text, &w, &h);
ypos += h;
int real_w = std::min(w, width);
switch (align) {
case ALG_LEFT:
break;
case ALG_CENTER:
xpos += (width - real_w) / 2;
break;
case ALG_RIGHT:
xpos += width - real_w;
break;
default: NOT_REACHED();
}
bool use_kerning = FT_HAS_KERNING(this->face);
uint previous = 0;
FT_GlyphSlot slot = this->face->glyph;
for (const uint8 *pt = text; *pt != '\0';) {
uint32 u32;
int len = DecodeUtf8Char(pt, strlen((const char *)pt), &u32);
if (len == 0) break;
pt += len;
uint glyph = FT_Get_Char_Index(this->face, u32);
if (use_kerning && previous && glyph) {
FT_Vector delta;
FT_Get_Kerning(this->face, previous, glyph, FT_KERNING_DEFAULT, &delta);
xpos += delta.x >> 6;
}
if (FT_Load_Glyph(this->face, glyph, FT_LOAD_RENDER) != 0) {
}
uint32 *dest = this->blit_rect.address + (xpos + slot->bitmap_left) + (ypos - slot->bitmap_top) * this->blit_rect.pitch;
for (int i = 0; i < slot->bitmap.rows; i++) {
if (ypos - slot->bitmap_top + i < 0) continue;
for (int j = 0; j < slot->bitmap.pitch; j++) {
if (xpos + slot->bitmap_left + j < 0) continue;
if (slot->bitmap.buffer[i * slot->bitmap.pitch + j] > 0) {
dest[i * this->blit_rect.pitch + j] = slot->bitmap.buffer[i * slot->bitmap.pitch + j];
}
}
}
previous = glyph;
xpos += slot->advance.x >> 6;
ypos += slot->advance.y >> 6;
}
}
РЕДАКТИРОВАТЬ: шрифт загружается с:
/* Freetype init */
if (FT_Init_FreeType(&this->library) != 0) {
}
if (FT_New_Face(this->library, font_name, 0, &this->face) != 0) {
}
/** @todo use actual screen dpi? */
if (FT_Set_Char_Size(this->face, 0, font_size * 64, 0, 0) != 0) {
}
EDIT2:
добавление FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL);
(или же FT_RENDER_MODE_MONO
) после того, как FT_Load_Glyph ничего не делает.
Любые другие комментарии о качестве оценили, конечно
Задача ещё не решена.