Я пытаюсь отобразить текст с помощью Harfbuzz и подписанного атласа поля расстояний.
Код в основном такой:
void drawText(const std::wstring &str, Vec2 pos)
{
// Init harfbuzz
hb_buffer_t *hbBuf = hb_buffer_create();
hb_buffer_set_direction(hbBuf, HB_DIRECTION_LTR);
hb_buffer_set_script(hbBuf, HB_SCRIPT_LATIN);
hb_buffer_set_language(hbBuf, hb_language_from_string("en", 2));
// Process string
hb_buffer_add_utf32(hbBuf, reinterpret_cast<const uint32_t*>(str.c_str()), -1, 0, -1);
hb_shape(font.hb, hbBuf, nullptr, 0);
// Display string
unsigned int nbGlyphs;
hb_glyph_info_t *glyphInfos = hb_buffer_get_glyph_infos(hbBuf, &nbGlyphs);
hb_glyph_position_t *glyphPos = hb_buffer_get_glyph_positions(hbBuf, &nbGlyphs);
for(unsigned int i = 0; i < nbGlyphs; i++)
{
Vec2 drawPos = pos + Vec2(glyphPos[i].x_offset, glyphPos[i].y_offset) / 64.f;
drawGlyph(glyphInfos[i].codepoint, drawPos);
pos.x += glyphPos[i].x_advance / 64.f;
pos.y += glyphPos[i].y_advance / 64.f;
}
}
Текст выглядит правильно для английской фразы, но когда я проверяю его с диакритическими знаками, они выглядят неуместными. Я тестирую это с помощью aâa aâ̈a bb̂b bb̂̈b bb̧b bb͜b bb︠︡b. Строка Unicode не содержит предварительно объединенных символов. Harfbuzz
использует предварительно комбинированный символ â, благодаря чему этот выглядит хорошо. Большинство других диакритических знаков отключены.
Текст с диакритическими знаками слева от того места, где они должны быть
Когда я умножаю x_offset на 0,5, объединяющиеся символы располагаются лучше. Акценты и седиль находятся в правой позиции x. Акценты не складываются и расположены слишком низко на b. Дуга под BBB (U + 035C) должна соединять две последние буквы, а не центрироваться на 2-й b.
Я также пробовал с U+FE20 и U+FE21 на предыдущей группе b. В моих тестах U+FE21 находится на 2-м b, но похоже, что он должен быть на 3-м.
Проверьте с помощью glyphPos[i].x_offset * 0.5f, лучше, но все же неправильно
Я пытался использовать несколько шрифтов, но из этих шрифтов только NotoSansDisplay-Regular.ttf имел комбинированные символы. Мне не удалось заставить программу отображать эту строку, как ожидалось, в моей системе Debian (тестирование с HarfBuzz 2.6.4-1).
С Windows я получил лучшие результаты. Вот чего я ожидаю: акценты расставлены, комбинирующий двойной бреве под ним в нужном месте, седилья выключена.
Отображение текста ближе к ожидаемому
Я делаю что-то не так с HarfBuzz, или я тестирую нишевые случаи, которые HarfBuzz еще не поддерживает?
ИЗМЕНИТЬ:
Реальная проблема не была описана выше. Я загрузил шрифт с помощью FreeType FT_New_Face
, а затем создал hb_font_t
с помощью hb_ft_font_create. Для каждой нарисованной строки я называл FT_Set_Pixel_Sizes
, но сохранял hb_font_t
.