LINUX.ORG.RU

Использование библиотеки fribidi для правильного отображения арабского текста

 , ,


0

1

Всем привет! Пытаюсь решить проблему с библиотекой fribidi для правильного отображения арабского текста.

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

Word1 Word2. --> .2droW 1droW
И как получается через fribidi:
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;
}


Последнее исправление: batchar (всего исправлений: 3)

Скорее всего, потому что у тебя два и более подряд латинских знака, которые среди арабского текста пишутся по латински.

P.S.

Если хочешь использовать арабскую пунктуацию, используй арабские знаки: ؟ ،

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

re

Кроме арабского текста ничего нет в строке. Только арабские буквы.

batchar
() автор топика

Решено

После точки стояли пробелы. Нужно отфильтровать текст

batchar
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.