HarfBuzz hb_shape возвращает изолированную глиффу.

Вопрос или проблема

Я использую функцию harfbuzz hb_shape() для получения окончательного индекса глифа, но получаю изолированный глиф без примененных к нему gsub, если закомментирую функцию .hb_buffer_set_direction. А если не закомментирую, тогда получаю глиф вне арабского диапазона. Кто-нибудь может помочь понять, как это исправить? И почему это происходит?
Ниже приведен пример кода:-

           FT_Library    library;
            FT_Face       face;
            FT_Error      error;
            char*         fontfilepath;

        fontfilepath      = "D:/Amiri-Bold.ttf";
        error = FT_Init_FreeType( &library );
        error = FT_New_Face( library, fontfilepath, 0, &face );
        hb_font_t* hb_font = hb_ft_font_create(face, NULL);
        hb_buffer_t* hb_buffer = hb_buffer_create();
        const uint16_t* textt = (const uint16_t*) tempdata;
        hb_buffer_set_script(hb_buffer, HB_SCRIPT_ARABIC); // Установить скрипт на арабский
        hb_buffer_set_language(hb_buffer, hb_language_from_string("ara", -1));
        hb_buffer_set_direction(hb_buffer, HB_DIRECTION_RTL); // Установить направление справа налево для арабского
        hb_buffer_add_utf16(hb_buffer, textt, -1, 0, -1);
        hb_shape(hb_font, hb_buffer, NULL, 0);
        unsigned int glyph_count;
        hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(hb_buffer, &glyph_count);

        // Теперь glyph_info содержит массив индексов глифов
        for (unsigned int ii = 0; ii < glyph_count; ii++) {

            char str[7];
            // Получить индекс глифа напрямую из FreeType
            FT_UInt glyph_index;// = FT_Get_Char_Index(face, glyph_info[ii].codepoint);
            glyph_index = FT_Get_Char_Index(face, glyph_info[ii].codepoint);
            sprintf(str, "%04X", glyph_index);

            vContentStream->PutBlock((CBytePtr)/*"0037"*/str, 4);
        }

Ответ или решение

Для начала давайте разберем вашу проблему с использованием функции hb_shape() из библиотеки Harfbuzz. Судя по вашему описанию, вы сталкиваетесь с двумя основными проблемами:

  1. Когда вы комментируете функцию hb_buffer_set_direction, вы получаете изолированные глифы без применения обработки замены (GSUB).
  2. При использовании hb_buffer_set_direction вы получаете глифы, выходящие за пределы арабского диапазона.

Причины возникновения проблем

1. Изолированные глифы без применения GSUB

Арабский алфавит имеет особую природу соединения букв (конотация и соединение). В зависимости от контекста, в котором буквы находятся (в начале слова, в середине или в конце), они могут соединяться или отображаться по-разному (изолированные формы). Когда вы комментируете направление, Harfbuzz не может правильно определить положение символа в строке, и, следовательно, не применяет необходимые операции замены.

2. Глифы вне арабского диапазона

Когда направление правильно установлено, но возвращаемые глифы не соответствуют ожидаемым арабским индексам, это может указывать на то, что ваша строка с кодировкой неправильно формируется, или возникают проблемы с использованием hb_shape(). Возможно, библиотека не может правильно сопоставить кодовые точки с соответствующими глифами.

Рекомендации по решению

  1. Убедитесь в корректности входных данных: Прежде всего, убедитесь, что массив tempdata, который вы передаете в hb_buffer_add_utf16(), содержит корректные значения. Это должны быть коды символов, корректно представленные в формате UTF-16.

  2. Проверьте шрифт: Убедитесь, что файл шрифта "Amiri-Bold.ttf" корректно загружен и содержит необходимые глифы для арабских символов. Возможны проблемы с шрифтом, которые могут привести к отсутствию необходимых форм глифов.

  3. Правильное применение замены: Убедитесь, что hb_shape() вызывается после того, как вы установили язык и направление. Попробуйте выполнить последовательность установок следующим образом:

    hb_buffer_set_script(hb_buffer, HB_SCRIPT_ARABIC);
    hb_buffer_set_language(hb_buffer, hb_language_from_string("ara", -1));
    hb_buffer_set_direction(hb_buffer, HB_DIRECTION_RTL);
    hb_buffer_add_utf16(hb_buffer, textt, -1, 0, -1);
    hb_shape(hb_font, hb_buffer, NULL, 0);
  4. Отладка и анализ: Используйте отладчик или вставьте вывод для проверки значений в glyph_info после выполнения hb_shape(). Это может помочь вам понять, какие индексы глифов получаются и соответствуют ли они вашим ожиданиям.

  5. Обратитесь к документации: Ознакомьтесь с основными примерами и документацией Harfbuzz, чтобы убедиться в том, что вы используете функции библиотеки правильно.

Заключение

Работа с текстом на арабском языке требует внимательного подхода, и каждый аспект, от направления до обработки глифов, имеет значение. Следуя приведенным рекомендациям, вы сможете диагностировать и исправить возникшие проблемы. Если проблемы сохраняются, не стесняйтесь обращаться к сообществам разработчиков и форумам, где опытные пользователи могут предложить свою помощь и советы.

Оцените материал
Добавить комментарий

Капча загружается...