NioX5199
NioX5199

Reputation: 1802

Measuring text width to be drawn on Canvas ( Android )

Is there a method which returns the width ( in pixels ) of a text to be drawn on an Android canvas using the drawText() method according to the Paint used to draw it?

Upvotes: 140

Views: 90190

Answers (8)

Binh Ho
Binh Ho

Reputation: 4983

This should work.

fun String.getWidth(fontSize: Float): Float {
    val textPaint = TextPaint()
    textPaint.textSize = fontSize
    textPaint.typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD)

    return textPaint.measureText(this)
}

Advance for text with new line break

fun String.getWidth(fontSize: Float): Float {
    val textPaint = TextPaint()
    textPaint.textSize = fontSize
    textPaint.typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD)
    val texts = this.split("\n")
    if (texts.size == 1) {
        return textPaint.measureText(this)
    }

    var finalWidth = 0f
    for (text in texts) {
        val thisLineWidth = text.getWidth(fontSize)
        if (thisLineWidth > finalWidth) {
            finalWidth = thisLineWidth
        }
    }

    return finalWidth
}

Upvotes: 0

Marc Bernstein
Marc Bernstein

Reputation: 11511

Have you looked at android.graphics.Paint#measureText(String txt)?

Upvotes: 256

Jim Baca
Jim Baca

Reputation: 6122

There's actually three different ways of measuring text.

GetTextBounds:

val paint = Paint()
paint.typeface = ResourcesCompat.getFont(context, R.font.kaushanscript)
paint.textSize = 500f
paint.color = Color.argb(255, 3, 221, 252)
val contents = "g"
val rect = Rect()
paint.getTextBounds(contents, 0, 1, rect)
val width = rect.width()

MeasureTextWidth:

val paint = Paint()
paint.typeface = ResourcesCompat.getFont(context, R.font.kaushanscript)
paint.textSize = 500f
paint.color = Color.argb(255, 3, 221, 252)
val contents = "g"
val width = paint.measureText(contents, 0, 1)

And getTextWidths:

val paint = Paint()
paint.typeface = ResourcesCompat.getFont(context, R.font.kaushanscript)
paint.textSize = 500f
paint.color = Color.argb(255, 3, 221, 252)
val contents = "g"
val rect = Rect()
val arry = FloatArray(contents.length)
paint.getTextBounds(contents, 0, contents.length, rect)
paint.getTextWidths(contents, 0, contents.length, arry)
val width = ary.sum()

Note that getTextWidths could be useful if you are trying to determine when to wrap text to the next line.

The measureTextWidth and getTextWidth are equal and have the advanced width that measure that others have posted about. Some consider this space excessive. However, this is very subjective and dependent on the font.

For example the width from measure text bounds may actually look too small:

measure text bounds looks small

However when adding an additional text the bounds for one letter looks normal: measure text bounds looks normal for strings

Images taken from Android Developers Guide to Custom Canvas Drawing

Upvotes: 7

Suragch
Suragch

Reputation: 512586

Supplemental answer

There is a slight difference between the width returned by Paint.measureText and Paint.getTextBounds. measureText returns a width that includes the glyph's advanceX value padding the beginning and end of the string. The Rect width returned by getTextBounds does not have this padding because the bounds is the Rect that tightly wraps the text.

source

Upvotes: 19

Hiren Patel
Hiren Patel

Reputation: 52810

Well I have done in different way:

String finalVal ="Hiren Patel";

Paint paint = new Paint();
paint.setTextSize(40);
Typeface typeface = Typeface.createFromAsset(getAssets(), "Helvetica.ttf");
paint.setTypeface(typeface);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);

Rect result = new Rect();
paint.getTextBounds(finalVal, 0, finalVal.length(), result);

Log.i("Text dimensions", "Width: "+result.width()+"-Height: "+result.height());

Hope this will help you.

Upvotes: 1

Ashish John
Ashish John

Reputation: 1905

you can use "textPaint.getTextSize()" to get text width

Upvotes: -1

Armin J.
Armin J.

Reputation: 455

I used the methods measureText() and getTextPath()+computeBounds() and build up an Excel with all text attributes for fixed size font that can be found under https://github.com/ArminJo/android-blue-display/blob/master/TextWidth.xlsx . There you will find also simple formulas for other text attributes like ascend etc.

The app as well as the function drawFontTest() for generating the raw values used in the excel are also available in this repo.

Upvotes: 1

hamid reza zavareh
hamid reza zavareh

Reputation: 389

Paint paint = new Paint();
Rect bounds = new Rect();

int text_height = 0;
int text_width = 0;

paint.setTypeface(Typeface.DEFAULT);// your preference here
paint.setTextSize(25);// have this the same as your text size

String text = "Some random text";

paint.getTextBounds(text, 0, text.length(), bounds);

text_height =  bounds.height();
text_width =  bounds.width();

Upvotes: 38

Related Questions