[android] Android Paint: .measureText() vs .getTextBounds()

You can do what I did to inspect such problem:

Study Android source code, Paint.java source, see both measureText and getTextBounds methods. You'd learn that measureText calls native_measureText, and getTextBounds calls nativeGetStringBounds, which are native methods implemented in C++.

So you'd continue to study Paint.cpp, which implements both.

native_measureText -> SkPaintGlue::measureText_CII

nativeGetStringBounds -> SkPaintGlue::getStringBounds

Now your study checks where these methods differ. After some param checks, both call function SkPaint::measureText in Skia Lib (part of Android), but they both call different overloaded form.

Digging further into Skia, I see that both calls result into same computation in same function, only return result differently.

To answer your question: Both your calls do same computation. Possible difference of result lies in fact that getTextBounds returns bounds as integer, while measureText returns float value.

So what you get is rounding error during conversion of float to int, and this happens in Paint.cpp in SkPaintGlue::doTextBounds in call to function SkRect::roundOut.

The difference between computed width of those two calls may be maximally 1.

EDIT 4 Oct 2011

What may be better than visualization. I took the effort, for own exploring, and for deserving bounty :)

enter image description here

This is font size 60, in red is bounds rectangle, in purple is result of measureText.

It's seen that bounds left part starts some pixels from left, and value of measureText is incremented by this value on both left and right. This is something called Glyph's AdvanceX value. (I've discovered this in Skia sources in SkPaint.cpp)

So the outcome of the test is that measureText adds some advance value to the text on both sides, while getTextBounds computes minimal bounds where given text will fit.

Hope this result is useful to you.

Testing code:

  protected void onDraw(Canvas canvas){
     final String s = "Hello. I'm some text!";

     Paint p = new Paint();
     Rect bounds = new Rect();
     p.setTextSize(60);

     p.getTextBounds(s, 0, s.length(), bounds);
     float mt = p.measureText(s);
     int bw = bounds.width();

     Log.i("LCG", String.format(
          "measureText %f, getTextBounds %d (%s)",
          mt,
          bw, bounds.toShortString())
      );
     bounds.offset(0, -bounds.top);
     p.setStyle(Style.STROKE);
     canvas.drawColor(0xff000080);
     p.setColor(0xffff0000);
     canvas.drawRect(bounds, p);
     p.setColor(0xff00ff00);
     canvas.drawText(s, 0, bounds.bottom, p);
  }

Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to android-layout

How to check if a key exists in Json Object and get its value How to center the elements in ConstraintLayout Android - how to make a scrollable constraintlayout? Add ripple effect to my button with button background color? This view is not constrained vertically. At runtime it will jump to the left unless you add a vertical constraint Is it possible to put a ConstraintLayout inside a ScrollView? Differences between ConstraintLayout and RelativeLayout How to remove title bar from the android activity? How to have EditText with border in Android Lollipop Android: ScrollView vs NestedScrollView

Examples related to textview

Kotlin: How to get and set a text to TextView in Android using Kotlin? How to set a ripple effect on textview or imageview on Android? The specified child already has a parent. You must call removeView() on the child's parent first (Android) Android: Creating a Circular TextView? android on Text Change Listener Android - Set text to TextView Placing a textview on top of imageview in android Rounded corner for textview in android Different font size of strings in the same TextView Auto-fit TextView for Android