首页 >> 大全

canvas.drawText理解和FontMetrics文字测量

2023-09-30 大全 20 作者:考证青年

在ui开发开发中,label文本标签是最长用到的。中提供了帮我们用来展示文本文字。而的也提供了用于帮助我们在自定义view的时候绘制展示文本。

先简单看一下这段代码

private val paint = Paint(Paint.ANTI_ALIAS_FLAG)init {paint.textSize = 150Fpaint.style = Paint.Style.FILL_AND_STROKEpaint.color = Color.parseColor("#FFFFFF")
}override fun onDraw(canvas: Canvas?) {super.onDraw(canvas)canvas?.drawColor(Color.parseColor("#80F14400"))val textLabel = "Hello World, Hello Python"canvas?.drawText(textLabel, 0F, 0F, paint)
}

上面这段代码,是一个最简单的使用。按照我们对坐标系的理解,貌似没什么问题,应该是在view的左上角绘制文本,文本完整展示。

从真实的展示上效果来看,和我们想要的效果完全不一致,为什么会出现这种情况呢?还是看一下的方法定义吧。

从方法的注释中可以得知的x和y分别是用来定义文字绘制的起始点,而这个起始点的y坐标是基于(基线)。想要理解的概念,就要理解文字的测量规则,文字测量规则是使用方法中定义的。而是从Paint.()获取。

在看定义之前,先看一下这张图,这张图是从别人博客copy过来的(对于图片中的值,图中理解不是很正确,暂时忽略)

指的是行的额外间距,即对于上下相邻的两行,上行的 线和下行的 top 线的距离

类主要是定义了文字的测量属性。

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值等于. + -.。那么,可以打印一下的各个属性的值,看一下输出。

val fontMetrics = paint.fontMetrics
Log.e("info", "fontMetrics-->top: " + fontMetrics.top)
Log.e("info", "fontMetrics-->leading: " + fontMetrics.leading)
Log.e("info", "fontMetrics-->ascent: " + fontMetrics.ascent)
Log.e("info", "fontMetrics-->descent: " + fontMetrics.descent)
Log.e("info", "fontMetrics-->bottom: " + fontMetrics.bottom)

E/info: –>top: -157.2

E/info: –>: 0.0

E/info: –>: -139.2

E/info: –>: 36.

E/info: –>: 40.65

将打印的结果对照图,会发现,起始数据基于,在上方的为负数、下方的为正数。

知道了怎么每个值的意义和的计算方式之后,我们就可以根据作为绘制出来每个属性的辅助线和文字

val fontMetrics = paint.fontMetrics
val baseline = fontMetrics.bottom + kotlin.math.abs(fontMetrics.top) - fontMetrics.descent
canvas?.save()
//将坐标零点y值移动到baseline
canvas?.translate(0F,baseline
)
paint.color = Color.BLUE
val textLabel = "Hello,Python"
canvas?.drawText(textLabel, 0F, 0F, paint)
paint.style = Paint.Style.STROKE
//绘制top
paint.color = Color.BLUE
canvas?.drawLine(0F, fontMetrics.top, width.toFloat(), fontMetrics.top, paint)
paint.color = Color.YELLOW
//绘制ascent
canvas?.drawLine(0F, fontMetrics.ascent, width.toFloat(), fontMetrics.ascent, paint)
paint.color = Color.GRAY
//绘制descent
canvas?.drawLine(0F, fontMetrics.descent, width.toFloat(), fontMetrics.descent, paint)
paint.color = Color.parseColor("#F15500")
//绘制bottom
canvas?.drawLine(0F, fontMetrics.bottom, width.toFloat(), fontMetrics.bottom, paint)
//绘制baseline
paint.color = Color.parseColor("#8080FF")
paint.pathEffect = DashPathEffect(floatArrayOf(10F, 10F), 0F)
canvas?.drawLine(0F, 0F, width.toFloat(), 0F, paint)
canvas?.restore()

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了