文字尺寸、宽高的测量 Paint FontMetrics

Paint.FontMetrics类简介

Google文档中的描 述:
/**
* Class that describes the various各种 metrics指标 for a font at a given text size.
* Remember, Y values increase going down, so those values will be positive正数,
* and values that measure distances距离 going up will be negative负数. This class
* is returned by getFontMetrics().
*/
public static class FontMetrics {
//The maximum distance above the baseline for the tallest glyph in the font at a given text size.
public float top;
//【字符顶部】The recommended推荐的 distance above the baseline for singled spaced text.
public float ascent;
//【字符底部】The recommended distance below the baseline for singled spaced text.
public float descent;
//The maximum distance below the baseline for the lowest glyph in the font at a given text size.
public float bottom;
//【字符行间距】The recommended additional额外的 space to add between lines两行之间 of text.
public float leading;
}

网上找的各种模型图

注意Y坐标基准点是在BaseLine那个位置,而非AscentLine或Top那个位置
795730-20170225162406116-1222581102.jpg
795730-20170225162406585-543708895.jpg
795730-20170225162407804-7228627.jpg

Paint的ascent和descent方法--算高度

这两个是native方法
//Return the distance above (negative) the baseline (ascent) based on the current typeface字体 and text size.
public native float ascent();
//Return the distance below (positive) the baseline (descent) based on the current typeface and text size.
public native float descent();
可以通过 mPaint.ascent()+ mPaint.descent() 获取文字高度

Paint的measureText方法--获取宽度

795730-20170225162408382-11345765.png
/**
* Return the width of the text.
*
* @param text The text to measure. Cannot be null.
* @param start The index of the first character to start measuring
* @param end 1 beyond the index of the last character to measure
* @return The width of the text
*/
public float measureText(String text, int start, int end) {
if (text == null) throw new IllegalArgumentException("text cannot be null");
if ((start | end | (end - start) | (text.length() - end)) < 0) throw new IndexOutOfBoundsException();
if (text.length() == 0 || start == end) return 0f;
if (!mHasCompatScaling) return (float) Math.ceil(native_measureText(text, start, end, mBidiFlags));

final float oldSize = getTextSize();
setTextSize(oldSize*mCompatScaling);
float w = native_measureText(text, start, end, mBidiFlags);
setTextSize(oldSize);
return (float) Math.ceil(w*mInvCompatScaling);
}
通过这个方法即可以轻松的获取到文字的的宽度

Paint的getTextBounds方法--获取边界

795730-20170225162409054-1268017118.png
/**
* Return in bounds (allocated by the caller 由调用者分配) the smallest最小的 rectangle that
* encloses围起来 all of the characters, with an implied origin默认的起始位置 at (0,0).
* @param text String to measure and return its bounds
* @param start Index of the first char in the string to measure
* @param end 1 past the last char in the string measure
* @param bounds Returns the unioned bounds of all the text. Must be allocated by the caller.
*/
public void getTextBounds(String text, int start, int end, Rect bounds) {
if ((start | end | (end - start) | (text.length() - end)) < 0) throw new IndexOutOfBoundsException();
if (bounds == null) throw new NullPointerException("need bounds Rect");
nativeGetStringBounds(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, bounds);
}
这个方法需要提供一个参数 Rect 矩形区域,这个方法将文字的区域传递到 Rect

Paint的获取

比如对于TextView,要通过 TextView的 getPaint()得到 Paint,而不能new一个或者拿其他不相干的 Paint
/**
* @return the base paint used for the text. Please use this only to
* consult查阅 the Paint's properties属性 and not to change them.
*/
public TextPaint getPaint() {
return mTextPaint;
}
如果是在自定义View 中,则可以 直接 通过Paint调用相关方法去获取文字的宽高等信息

测试代码

public class MainActivity extends Activity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String text = "aA bB fF gG";
        TextView tv_info = new TextView(this);
        tv_info.setTextColor(Color.BLUE);
        tv_info.setBackgroundColor(0x5500ff00);
        tv_info.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
        tv_info.setText(text);
        setContentView(tv_info);
        tv_info.measure(0, 0);//必须手动调用测量方法,否则getMeasuredHeight获取不到值。另外,即使测量过了getHeight也获取不到值
        Paint mPaint = tv_info.getPaint();
        Log.i("bqt""ascent()的值为" + mPaint.ascent() + ",descent()的值为" + mPaint.descent());//-33.398438, 8.7890625
        Log.i("bqt""字符的高度为" + (-mPaint.ascent() + mPaint.descent()) + ",字符的长度为" + mPaint.measureText(text));//42.1875,190.0
        Log.i("bqt""测量的高度为" + tv_info.getMeasuredHeight() + ",测量的宽度为" + tv_info.getMeasuredWidth());//49,190
        Rect mRect = new Rect();
        mPaint.getTextBounds(text, 0, text.length(), mRect);
        Log.i("bqt""字符的边界为" + mRect.left + "," + mRect.top + "," + mRect.right + "," + mRect.bottom);//1,-28,187,8
        Log.i("bqt""字符的高度为" + (mRect.bottom - mRect.top) + ",字符的长度为" + (mRect.right - mRect.left));//36,186
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值