Вопрос или проблема
Я использую функцию 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. Судя по вашему описанию, вы сталкиваетесь с двумя основными проблемами:
- Когда вы комментируете функцию
hb_buffer_set_direction
, вы получаете изолированные глифы без применения обработки замены (GSUB). - При использовании
hb_buffer_set_direction
вы получаете глифы, выходящие за пределы арабского диапазона.
Причины возникновения проблем
1. Изолированные глифы без применения GSUB
Арабский алфавит имеет особую природу соединения букв (конотация и соединение). В зависимости от контекста, в котором буквы находятся (в начале слова, в середине или в конце), они могут соединяться или отображаться по-разному (изолированные формы). Когда вы комментируете направление, Harfbuzz не может правильно определить положение символа в строке, и, следовательно, не применяет необходимые операции замены.
2. Глифы вне арабского диапазона
Когда направление правильно установлено, но возвращаемые глифы не соответствуют ожидаемым арабским индексам, это может указывать на то, что ваша строка с кодировкой неправильно формируется, или возникают проблемы с использованием hb_shape()
. Возможно, библиотека не может правильно сопоставить кодовые точки с соответствующими глифами.
Рекомендации по решению
-
Убедитесь в корректности входных данных: Прежде всего, убедитесь, что массив
tempdata
, который вы передаете вhb_buffer_add_utf16()
, содержит корректные значения. Это должны быть коды символов, корректно представленные в формате UTF-16. -
Проверьте шрифт: Убедитесь, что файл шрифта "Amiri-Bold.ttf" корректно загружен и содержит необходимые глифы для арабских символов. Возможны проблемы с шрифтом, которые могут привести к отсутствию необходимых форм глифов.
-
Правильное применение замены: Убедитесь, что
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);
-
Отладка и анализ: Используйте отладчик или вставьте вывод для проверки значений в
glyph_info
после выполненияhb_shape()
. Это может помочь вам понять, какие индексы глифов получаются и соответствуют ли они вашим ожиданиям. -
Обратитесь к документации: Ознакомьтесь с основными примерами и документацией Harfbuzz, чтобы убедиться в том, что вы используете функции библиотеки правильно.
Заключение
Работа с текстом на арабском языке требует внимательного подхода, и каждый аспект, от направления до обработки глифов, имеет значение. Следуя приведенным рекомендациям, вы сможете диагностировать и исправить возникшие проблемы. Если проблемы сохраняются, не стесняйтесь обращаться к сообществам разработчиков и форумам, где опытные пользователи могут предложить свою помощь и советы.