Всем привет! Пытаюсь решить проблему с библиотекой fribidi для правильного отображения арабского текста.
Арабский текст читается справо-на-лево, а физически хранится (к примеру в файле) слево-на-право. Столкнулся со следующей проблемой: текст правильно разворачивается, а вот стоящая в конце текста точка(также справедливо для запятой, восклицательного знака, многоточия) не переносится. Пример как должно быть:
Word1 Word2. --> .2droW 1droW
Word1 Word2. --> 2droW 1droW.
Методом проб было выяснено, если после точки идет числовая последовательность, он нормально переносит точку и цифру. Почему не происходит перенос знаков, стоящих в конце предложения - не понимаю. Может сталкивался кто с таким поведением?
В качестве основы взял код фильтра ffmpeg - «vf_drawtext», который использует fribidi.
std::wstring document::fribidi_convert(const wchar_t* s)
{
const FriBidiFlags flags = FRIBIDI_FLAGS_DEFAULT | FRIBIDI_FLAGS_ARABIC;
std::wstring result(s);
if (s != nullptr) {
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
std::string byte_str = converter.to_bytes(s);
FriBidiChar unicodestr[byte_str.size() * sizeof(FriBidiChar)] = {0};
int unicodestr_len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, byte_str.c_str(),
byte_str.size(), unicodestr);
FriBidiCharType bidi_types[unicodestr_len * sizeof(FriBidiCharType)] = {0};
fribidi_get_bidi_types(unicodestr, unicodestr_len, bidi_types);
FriBidiParType direction = FRIBIDI_PAR_LTR;
FriBidiLevel embedding_levels[unicodestr_len * sizeof(FriBidiLevel)] = {0};
if (!fribidi_get_par_embedding_levels(bidi_types, unicodestr_len,
&direction, embedding_levels)) {
return result;
}
FriBidiArabicProp ar_props[unicodestr_len * sizeof(FriBidiArabicProp)] = {0};
fribidi_get_joining_types(unicodestr, unicodestr_len, ar_props);
fribidi_join_arabic(bidi_types, unicodestr_len, embedding_levels, ar_props);
fribidi_shape(flags, embedding_levels, unicodestr_len, ar_props, unicodestr);
if (!fribidi_reorder_line(flags, bidi_types, unicodestr_len, 0,
direction, embedding_levels, unicodestr, nullptr)) {
return result;
}
int i = 0, j = 0;
for (i = 0, j = 0; i < unicodestr_len; i++) {
if (unicodestr[i] != FRIBIDI_CHAR_FILL)
unicodestr[j++] = unicodestr[i];
}
int result_len = j;
char swap_str[(result_len * 4 + 1) * sizeof(char)] = {0};
result_len = fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, unicodestr, result_len, swap_str);
result = converter.from_bytes(swap_str);
}
return result;
}