FontMetrics
FontMetrics是Paint的一个内部类,用于描述给定文本大小的字体的各项参数:
public static class FontMetricsInt {
/**
* 在给定字体大小的文本中,最高字符的顶部在基线上方的最大距离。
*/
public float top;
/**
* 对于单行文本,文本在基线上方的距离
*/
public float ascent;
/**
* 对于单行文本,文本在基线下方的距离
*/
public float descent;
/**
* 在给定字体大小的文本中,最低字符的顶部在基线上方的最大距离。
*/
public float bottom;
/**
* 两行文本之间的距离
*/
public float leading;
@Override public String toString() {
return "FontMetricsInt: top=" + top + " ascent=" + ascent +
" descent=" + descent + " bottom=" + bottom +
" leading=" + leading;
}
}
从网上找了个图片来描述各个参数:
BaseLine是基线,Android在绘制文本的基础行。为什么会有基线这个概念呢?外文并不像中文这样,它们是由字母而组成的,而多数字母排列是沿着基准线,但是,像”p”或者”y”之类的字母会超过基线向下延伸,超过的部分称为降部,反之,基线以上的称为升部。Baseline往上至字符“最高处”的距离我们称之为ascent(上坡度),Baseline往下至字符“最低处”的距离我们称之为descent(下坡度)。又因为Android系统中,对于坐标系的定义,Y值增加向下延伸,因此,获取到的descent为正值,而ascent为负值。
leading是两行文本之间的距离,官方并没有明确的解释,应该是上一行的descent与下一行的ascent之间的距离。
关于top、bottom描述的比较模糊,对于top而言,是指最高字符的顶部在基线上方的最大距离,可是,又与ascent的定义有所冲突。借鉴下TextView对于文本的控制,其总会为文本留下部分内边距,因为TextView在绘制文本时会考虑一些特殊符号,比如音调符号。我们是不是可以这样理解:
- top = ascent + 文本上方预留边距
- bottom = descent + 文本下方预留边距
为了验证FontMetrics中的各个参数,现自定义View,绘制 “yearξτβбшㄎěǔぬも测试a”这个字符串:
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
paintText.apply {
textSize = 96f
strokeWidth = 3f
}
// FontMetrics对象
val fontMetrics = paintText.fontMetricsInt
val topY = fontMetrics.top
val ascentY = fontMetrics.ascent
val descentY = fontMetrics.descent
val bottomY = fontMetrics.bottom
val leading =