Пользовательские шрифты для TextView, основанные на языках внутри String

У меня есть два файла шрифтов TTF, которые должны быть применены на TextView основанный на языках внутри String, Например, рассмотрим этот пример текста:

эй, как дела ضعيف

Я могу просто применить диапазон гарнитуры шрифта на основе языка, но для этого требуется настраиваемая разметка в каждой строке, получаемой с нашего сервера, например

 <ttf1>hey what's up <ttf1><ttf2>ضعيف</ttf2>

И разбор каждого String во время выполнения даст удар производительности. Есть ли другой подход для достижения этой цели?

Для начала, скажем, мне нужно сделать это только для направления текста, то есть RTL и LTR, поэтому в приведенном выше примере английский - это LTR, а арабский - это RTL. Будет ли это по-другому?

Я попытался объединить эти два файла шрифтов, но есть проблемы с высотой строки, и если я исправлю это для одного файла шрифта, он будет поврежден для другого файла.

1 ответ

Решение

Я нашел более элегантное решение, чем ручная разметка с помощью кого-то:

String paragraph = "hey what's up ضعيف";
int NO_FLAG = 0;
Bidi bidi = new Bidi(paragraph, NO_FLAG);
int runCount = bidi.getRunCount();
for (int i = 0; i < runCount; i++) {
    String ltrtl = bidi.getRunLevel(i) % 2 == 0 ? "ltr" : "rtl";
    String subString = paragraph.substring(bidi.getRunStart(i), bidi.getRunLimit(i));
    Log.d(">>bidi:" + i,  subString+" is "+ltrtl);
}

печатает:

эй, что случилось, это буква

ضعيف это rtl

Так что теперь можно легко построить TypefaceSpan или же MetricAffectingSpan в зависимости от языкового направления:

SpannableString spanString = new SpannableString(paragraph);
for (int i = 0; i < runCount; i++) {
    Object span = bidi.getRunLevel(i) % 2 == 0 ? ltrFontSpan : rtlFontSpan;
    spanString.setSpan(span, bidi.getRunStart(i), bidi.getRunLimit(i), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 
}
textView.setText(spanString);
Другие вопросы по тегам