Android: измерьте высоту текста на холсте - PullRequest
8 голосов
/ 20 февраля 2012

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

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

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);
}

Пока все хорошо, теперьто, что я хочу сделать, это: если я использую метод PaintText от 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. " Экземпляр камеры может использоваться для вычисления трехмерных преобразований и генерации матрицы."возвращает высоту 16
  3. " Представляем Аroid Design: место, где можно узнать о принципах, строительных блоках и шаблонах для создания пользовательских интерфейсов Android мирового класса.Независимо от того, являетесь ли вы профессионалом в области пользовательского интерфейса или разработчиком, играющим эту роль, эти документы показывают, как принимать правильные дизайнерские решения, большие и малые."возвращает высоту 16

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

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

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

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

Ответы [ 2 ]

16 голосов
/ 20 февраля 2012

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

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

5 голосов
/ 07 февраля 2017

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

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

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

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

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

Примечание

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

См. Также

...