Android: измерение высоты текста на холсте

В настоящее время я работаю над рендерингом Bitmap, который затем хочу отправить на мобильный принтер. Тем не менее, я борюсь с измерением высоты моего текста, поэтому я могу соответствующим образом продвигать позицию y.

Моя базовая конфигурация растрового изображения / холста / краски – это (размер шрифта – 16, а размеры растрового изображения – 200×400 (ширина х высота):

public MyRenderer() { // Initialize bitmap bitmap = Bitmap.createBitmap(200, 400, Bitmap.Config.ARGB_8888); // Initialize canvas canvas = new Canvas(bitmap); // Initialize brush (Paint instance) brush = new Paint(); brush.setTextSize(16); brush.setTypeface(Typeface.SANS_SERIF); brush.setColor(Color.BLACK); brush.setStyle(Paint.Style.FILL); brush.setAntiAlias(true); brush.setTextAlign(Align.LEFT); } 

Пока что так хорошо, теперь я хочу сделать следующее: если я использую метод drawText Paint, мне нужно указать координаты x и y. Что касается x, который равен нулю (при условии выравнивания текста влево), но как и для y, мне нужно будет вычислить высоту каждого текста, который я распечатаю, и добавить его, чтобы я мог отслеживать текущую позицию y.

И здесь это становится странным: я использую следующий метод для определения высоты текста (используя Paint, против которого я инициализировал ранее – это называется «кисть»):

 public int measureHeight(String text) { Rect result = new Rect(); // Measure the text rectangle to get the height brush.getTextBounds(text, 0, text.length(), result); return result.height(); } 

Вышеуказанный метод возвращает следующие значения для следующих текстов:

  1. « Hello World » возвращает высоту 12
  2. « Экземпляр камеры можно использовать для вычисления 3D-преобразований и создания матрицы». Возвращает высоту 16
  3. « Представляем Android Design: место, где вы узнаете о принципах, строительных блоках и шаблонах для создания пользовательских интерфейсов Android мирового класса. Независимо от того, являетесь ли вы профессионалом пользовательского интерфейса или разработчиком, играющим эту роль, эти документы показывают, как принимать правильные проектные решения , Большой и малый. "Возвращает высоту 16

Для меня имеет смысл, что числа 2 и 3 возвращают большую высоту, чем номер 1, но если одна линия имеет высоту 12 (как это делает номер один) – не имеет смысла, что несколько строк имеют высоту 16?

Я что-то упустил? Существует удобный способ измерения ширины текста (с использованием экземпляра paint и call measureText («myText»), который отлично работает, однако я совершенно не понимаю, когда дело доходит до высоты, как и вышеприведенные результаты Не имею никакого смысла для меня.

РЕДАКТИРОВАТЬ

Я знаю, что getTextBounds, вероятно, не делает автоматической обертки многострочного текста, и все в порядке, я уже написал метод разделения текста, но даже если он просто измеряет одну строку, приведенные выше значения длины все еще кажутся маловероятными.

Solutions Collecting From Web of "Android: измерение высоты текста на холсте"

Я думаю, что это потому, что «p» в «вычислении» распространяется ниже базовой линии, тогда как «Hello World» содержит только буквы, которые находятся выше базовой линии.

Так как расстояние линии не должно зависеть от того, какие конкретные буквы, из которых состоит ваш текст, вероятно, вы ищете Paint.FontMetrics, которые можно получить с помощью Paint.getFontMetrics () . Вычислить descent - ascent + leading чтобы получить рекомендуемое базовое расстояние (потому что восхождение имеет отрицательное значение).

В принятом ответе есть небольшая ошибка. Если вам нужна высота текста , вы должны использовать

 Paint.FontMetrics fm = mTextPaint.getFontMetrics(); float textHeight = fm.descent - fm.ascent; 

И если вам нужна высота линии , вы должны использовать

 float lineHeight = fm.bottom - fm.top + fm.leading; 

Ведущий – это необязательный интерлайн-интервал, поэтому, если вам нужно получить высоту линии, вы можете ее включить. Но если вы просто хотите высоту текста, вы можете оставить его.

Заметка

  • Я никогда не видел, чтобы leading был чем-то другим, кроме 0 , и, насколько я могу судить, это даже кажется проигнорированным в исходном коде TextView (и его ассоциированном StaticLayout , StaticLayout и т. Д.). Пожалуйста, поправьте меня, если я ошибаюсь. Так что, вероятно, это безопасно, если вы оставите его вне линии календаря, но я не совсем уверен в этом.

Смотрите также

  • Получение высоты текста из getTextBounds vs FontMetrics vs StaticLayout
  • Значение верхнего, восхождения, базовой линии, спускового механизма, дна и ведущего в Android FontMetrics