2018/02/22

measureText と getTextBounds の違い

Android の [android.graphics.Paint](https://developer.android.com/reference/android/graphics/Paint.html) にはテキストサイズ計測用のメソッドが2つ用意されています。
`Paint#measureText(String)` と `Paint#getTextBounds(String, int, int, Rect)` ですが、これらの違いを調べてみました。



### measureText の方が少しだけ大きい
結論から言うと、以下の図のように `getTextBounds()` はテキストがぴったり入る矩形を返すのに対し、`measureText()` は左右に余白が入ります。

> 参考 > > [Android Paint: .measureText() vs .getTextBounds() - Stack Overflow](https://stackoverflow.com/questions/7549182/android-paint-measuretext-vs-gettextbounds) なお、この画像は以下の AndroidFontMetrics というアプリを使って作成しました。 フォントのメトリックスが視覚的に確認できるので便利です。 [GitHub - suragch/AndroidFontMetrics: An Android app for measuring and testing FontMetrics](https://github.com/suragch/AndroidFontMetrics) ### 余白は何なのか `getTextBounds()` で取得した矩形の `left` の値は大抵0ではありません。 例えば、上記の図だと `left` の値は 14 になりますフォントサイズは 180。 この `left` の値は [SkPaint.cpp](https://github.com/google/skia/blob/master/src/core/SkPaint.cpp) 中で先頭の文字のグリフによって決定されています。 つまり、上記の例だと、最初の文字が `M` の場合、それ以降の文字によらず 14 になります。 また、右の余白は最後の文字のグリフで決定し、`measureText() - textBounds.right` で求められます。
### AndroidFontMetrics はちょっと間違っているかもしれない と、ここまで書いてきて先に紹介した AndroidFontMetrics の動作が間違っているのではないかと気づきました。 AndroidFontMetrics は左右の余白を平均化して中央に配置するようにしており、`TextBounds.left` の値が反映されていませんコードを見ると反映されているように見えるのですが、実は逆に打ち消してしまっている。 多分、以下のように素直に描画するのが正しいはず。 ```diff --- a/app/src/main/java/net/studymongolian/fontmetrics/FontMetricsView.java +++ b/app/src/main/java/net/studymongolian/fontmetrics/FontMetricsView.java @@ -148,7 +148,7 @@ public class FontMetricsView extends View { mTextPaint.getTextBounds(mText, 0, mText.length(), mBounds); // draw vertical line just before the left bounds - startX = getPaddingLeft() + mBounds.left - (width - mBounds.width())/2; + startX = getPaddingLeft(); stopX = startX; startY = -verticalAdjustment; stopY = startY + this.getHeight(); ``` > 同日追記 > > 一応 Pull Request を出してみた

0 件のコメント: