Правильное комбинирование позиций персонажей с Harfbuzz

Я пытаюсь отобразить текст с помощью 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.


person Sentmoraap    schedule 14.11.2019    source источник


Ответы (2)


Вы должны попробовать сформировать тот же текст и шрифт с помощью hb-view / hb-shape. Это поможет вам сузить круг проблем. Я предполагаю, что проблема заключается в том, как / учитываете ли вы происхождение глифов в своем атласе.

person behdad    schedule 19.11.2019

Создавайте новый hb_font_t с hb_ft_font_create каждый раз, когда размер шрифта менялся с помощью FT_Set_Pixel_Sizes.

person Sentmoraap    schedule 22.11.2019