Paint.breakText() считает глифы, а не символы

Один из наших разработчиков столкнулся с проблемой, когда Paint.breakText() (в котором говорится о том, что он считает «символы») на самом деле считает глифы.

Представьте, что вы переносите только одно слово "fit". Он поместится в строке, поэтому вы ожидаете, что breakText() вернет 3. На некоторых устройствах это так; в других случаях "fi" образует лигатуру, а breakText() возвращает 2. Это заставляет вас рисовать

fi
t

... это не то, что вы хотите!

Есть ли

  1. Флаг, чтобы заставить breakText() считать символы Java, а не глифы? Или же
  2. Способ определить, что "fi" будет рассматриваться как один глиф?

person Jon Shemitz    schedule 03.12.2013    source источник
comment
stackoverflow.com/questions/5120905/   -  person Jules G.M.    schedule 03.12.2013
comment
Да, я видел это. Но, вы знаете, на самом деле это противоположный вопрос: строки, состоящие из «l» и «f», выходят за пределы прямоугольника, а не строки с преждевременно рвущимися лигатурами.   -  person Jon Shemitz    schedule 03.12.2013
comment
.. если вы просто хотите подсчитать символы, не можете ли вы просто использовать String.length() ?   -  person Jules G.M.    schedule 03.12.2013
comment
Спасибо за попытку помочь, Юлий, но что заставляет вас думать, что String.length() имеет какое-то значение? Представьте, что вы пытаетесь обернуть более длинную строку, как пять шлюх, фиксированных рыбных кексов - все эти лигатуры вызовут аналогичные проблемы, но это гораздо худший пример, потому что то, где произойдет неправильный перенос, будет зависеть от ширины окна.   -  person Jon Shemitz    schedule 03.12.2013


Ответы (2)


Это кажется неоптимальным, но способ, которым мы с этим справляемся, состоит в том, чтобы использовать paint.breakText("fit", true, 1000, null) == 2 в качестве флага bugExists, а затем использовать measureText() для проверки результатов.

person Jon Shemitz    schedule 05.12.2013

Я нашел, как это сделать хорошо здесь: Android: Paint.breakText(...) неточен?

мой код:

при создании:

paintOfText.setSubpixelText(true);
breakTextNumber = paintOfText.breakText(textToBreak, true,
    maximumSizeOfText, null);

в классе рендеринга:

if (breakTextNumber < textToBreak.length()) {
    while (textToBreak.charAt(breakTextNumber) != ' ') {
        breakTextNumber--;
    }
    myCanvas.drawText(textToBreak.substring(0, breakTextNumber),
            placeToDrawX, placeToDrawY, paintOfText);
    myCanvas.drawText(
            textToBreak.substring(breakTextNumber+1),
            placeToDrawX, placeToDrawY2,, paintOfText);
    }
}

Это просто разделить текст на 2 строки, обрезав строку пробелами. Надеюсь, поможет.

person Ruben Ferradás    schedule 02.07.2015
comment
setSubpixelText(true) ничего не делает с kitkat :( - person zeus; 06.10.2016