面向螺丝编程之文字基线和baseLine公式推导

395 阅读2分钟

eac5e7f7aba44947b2b3046406f9be90.png

其实在drawText方法中,中传入的第三个参数y的实际意义是文字的基线所在的位置!

public void drawText(String text, float x, float y, Paint paint)

上面这个构造函数是最常用的drawText方法,传进去一个String对象就能画出对应的文字。这里x、y两个参数需要非常注意,(x,y)是并不是绘制文字所在矩形的左上角的点。比如,要画"harvic's blog"这几个字,这个(x,y)坐标应当是下图中绿色小点的位置。注意:这个x是基于paint.setTextAlign(Paint.Align.LEFT);来的。

再强调一遍:y所代表的是基线的位置!

20200430152751526.png

6510f1821f874ca5aaff26896e2c9374.png

把ascent、descent 值打印出来,发现 ascent 为 - 316,descent 为 82 ,因此可以计算出基线(偏移)为117。

这里的 ascent 和 descent 的值,实际是基于基线而得。可理解为:以文字基线为准,向上平移316像素为绘制区域的顶,向下平移82像素为绘制区域的底(基线向上为负 向下为正)。

已知基线与绘制区顶相距316,与底相距82,可以得出绘制区高度为 descent - ascent:82 - (-316) = 398。

绘制区中线高度为( descent - ascent)/ 2 = 398 / 2 = 199 。

绘制区中线高度等价于中线与绘制区底之间的距离,这个距离减去 基线与绘制区底 之间的距离,就是

中线与基线之间的距离: (descent - ascent) / 2 - descent = 199 - 82 = 117。

推导完毕上代码:

 /**
   * 计算绘制文字时的基线到中轴线的距离
   * 
   * @param p
   * @return 基线和centerY的距离
   */
  public static float getBaseline(Paint p) {
    FontMetrics fontMetrics = p.getFontMetrics();
    return (fontMetrics.descent - fontMetrics.ascent) / 2 -fontMetrics.descent;
    // 一样
    //return (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
   }  
  
@Override
protected void onDraw(Canvas canvas) {
    //坐标(0,0)在左上角,此时基线的y坐标就是高度的一半(中轴线) +基线到中轴线的距离
    canvas.drawText(mText, 0, getHeight() / 2 + getBaseline(mPaint), mPaint);
}

参考文章1:blog.csdn.net/zenmela2011…