Gettextbounds в android

Мы использовали прямоугольник, который соответствует данному тексту, например, если дать "ТЕСТИРОВАНИЕ" в gettextbounds api, он даст прямоугольник, который соответствует заданной строке "TESTING", но может ли любой plz уточнить, на каком основании длина прямоугольника рассчитывается, будет ли рассмотрен размер шрифта, если это возможно, чтобы я мог так проверить?

1) Я попытался       CharSequence text = getText();       canvas.drawText(текст, 0, text.length(), mTextX, mTextY, getPaint());

    Paint pt = new Paint ( );
    pt.setTextSize(10);

    TextPaint tp = getPaint();
    String string = "haa";
    Rect currentBounds = new Rect ( );
    //this.setTextSize(/* TypedValue.COMPLEX_UNIT_PX */ 10, /* fontPixelSize*Home.fltFontRatio */ 32);

    tp.getTextBounds((String) text, 0, text.length(), currentBounds );

    Log.e ( " ", "Desired Text " +text);
    Log.e ( " ", "first Ondraw Left " +currentBounds.left);
    Log.e ( " ", "Ondraw Top" +currentBounds.top);
    Log.e ( " ", "Ondraw right " +currentBounds.right);
    Log.e ( " ", "Ondraw bottom " +currentBounds.bottom);

    pt.setTextSize(20);


    tp.getTextBounds((String) text, 0, text.length(), currentBounds );

    Log.e ( "", "Desired Text " +text);
    Log.e ( " ", "Second Ondraw Left " +currentBounds.left);
    Log.e ( " ", "Ondraw Top" +currentBounds.top);
    Log.e ( " ", "Ondraw right " +currentBounds.right);
    Log.e ( "Nrace ", "Ondraw bottom " +currentBounds.bottom);

2) Второй способ я попробовал

    TextPaint tp = getPaint();
    String string = "haa";
    Rect currentBounds = new Rect ( );
    this.setTextSize(/* TypedValue.COMPLEX_UNIT_PX */ 10, /* fontPixelSize*Home.fltFontRatio */ 32);               

    tp.getTextBounds(string, 0, string.length(), currentBounds );

    Log.e ( " ", "first Left " +currentBounds.left);
    Log.e ( " ", "Top" +currentBounds.top);
    Log.e ( " ", "right " +currentBounds.right);
    Log.e ( " ", "bottom " +currentBounds.bottom);

    this.setTextSize(/* TypedValue.COMPLEX_UNIT_PX */ 10, /* fontPixelSize*Home.fltFontRatio */ 10);

    tp.getTextBounds(string, 0, string.length(), currentBounds );

    Log.e ( " ", "Sefond Left " +currentBounds.left);
    Log.e ( " ", "Top" +currentBounds.top);
    Log.e ( " ", "right " +currentBounds.right);
    Log.e ( "", "bottom " +currentBounds.bottom);

В приведенных выше двух методах я пытаюсь выяснить размер прямоугольника для заданного размера текста. если это не очень хорошо, plz посоветуйте мне, разместив несколько примеров кода. Просто сказать, что мне нужно найти различные прямоугольники, которые соответствуют тексту "TESTING" для разных размеров шрифта.

Спасибо заранее.

Ответ 1

Я считаю эту часть API довольно запутанной, однако, я думаю, я почти понял, как она работает. Вызов getTextBounds() возвращает наименьший прямоугольник, который будет содержать все символы, нарисованные последующим вызовом drawText(), с x = 0 и y = 0. Об этом говорится в нескольких словах в справочной системе API. Все, что есть в Paint, и может повлиять на внешний вид текста, учитывается. Вот пример:

Rect bounds = new Rect();

Paint paint = new Paint();
paint.setTextAlign(Align.LEFT);
paint.setTypeface(typeface);
paint.setTextSize(textSize);
paint.getTextBounds(text, 0, text.length(), bounds);

Причина, по которой прямоугольник имеет такие экзотические координаты, состоит в том, что при рисовании текста с drawText() происхождение, к которому относительны x и y, зависит от типографских свойств выбранной Paint. Например, y относится к базовой линии, которая не находится ни выше, ни ниже шрифта, но обычно ударяет ее где-то посередине. По этой причине прямоугольник границ будет иметь (обычно) отрицательный верх и положительное дно. Отрицательная вершина означает, что верхняя часть текста находится выше базовой линии (y уменьшается вверх), а положительное дно означает, что нижняя часть текста находится ниже базовой линии (y увеличивается вниз). Интересно отметить, что при измерении строки, такой как "Привет", нижняя часть, вероятно, будет равна 0, потому что эти символы не имеют нижней части базовой линии. Напротив, когда вы измеряете строку типа "Hg", вы, скорее всего, получите положительное дно, потому что история g ниже базовой линии. Я не уверен, как оценивается горизонтальное положение.

С учетом этого, чтобы нарисовать текст, который вы вычислили, вы можете сделать:

canvas.drawText(text, -bounds.left, -bounds.top, paint);

Это приведет текст к левому верхнему углу холста. Координаты верхнего левого угла равны (0, 0), поэтому для перемещения текста вокруг вас нужно только добавить желаемое количество перемещений:

canvas.drawText(text, -bounds.left + yourX, -bounds.top + yourY, paint);

Другой пример: если вы хотите создать растровое изображение, которое содержит текст, и вы хотите точно разместить свободное пространство, вы можете сделать:

Bitmap bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawText(text, -bounds.left, -bounds.top, paint);

Если вы хотите оставить несколько пикселей влево, вправо, сверху и снизу, скажем 2, вы можете сделать:

Bitmap bitmap = Bitmap.createBitmap(bounds.width() + 4, bounds.height() + 4, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawText(text, -bounds.left + 2, -bounds.top + 2, paint);

Ответ 2

Мое решение:

class Pos {
  public int X;
  public int Y;
}
public static void getTextPositionAndRealBound(Paint paint, String text, int x, int y, Pos pos, Rect bound) {
  paint.getTextBounds(text, 0, text.length(), bound);
  // in X
  bound.left = x;
  bound.right = (int)(paint.measureText(text) + 0.5); // .5f to 1

  // in Y
  y = y - bound.top;
  bound.top = y;
  bound.bottom = bound.height();

  // reset the position
  pos.X = x;
  pos.Y = y;
}

Вы знаете, что X прав, а Y - в координате привязки getTextBounds.

Решение может получить позицию и реальную границу текста. Вы можете переместить текст в любую позицию, просто отредактировать переменную и использовать ее при вызове Canvas.drawText следующим образом:

Pos pos;
Rect bound;
getTextPositionAndRealBound(paint, text, x, y, pos, bound);
canvas.drawText(text, pos.X, pos.Y, paint);

Примечание: спасибо за совет @ToolmakerSteve

Ответ 3

Есть некоторые нюансы, так что лучше один раз увидеть... Красный прямоугольник показывает текстовые границы, x, y - любые координаты (левой нижней точки текстовых границ)

Rect textBounds = new Rect();
Paint textPaint = new Paint();
Paint rectPaint = new Paint();
String text = "java m";

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    textPaint.setTextSize(100);
    textPaint.getTextBounds(text, 0, text.length(), textBounds);

    canvas.drawText(text, x, y, textPaint);

    rectPaint.setColor(Color.RED);
    rectPaint.setStyle(Paint.Style.STROKE);

    canvas.drawRect(
            x,                       // left
            y - textBounds.height(), // top
            x + textBounds.width(),  // right
            y,                       // bottom
            rectPaint);
}

text = "Hello Worlds"

введите описание изображения здесь

text = "java m"

введите описание изображения здесь

Ответ 4

Вот способ, который работает для меня: используйте Paint.measureText(text), чтобы получить ширину text и Paint.getTextBounds(text, 0, text.length(), bounds), чтобы получить text height (height = bounds.height())