Canvas.drawText()中的文本高度

Canvas.drawText()方法

关于文档中的canvas.drawText(String, float, float, Paint)方法:

    /**
     * Draw the text, with origin at (x,y), using the specified paint. The
     * origin is interpreted based on the Align setting in the paint.
     *
     * @param text  The text to be drawn
     * @param x     The x-coordinate of the origin of the text being drawn
     * @param y     The y-coordinate of the baseline of the text being drawn
     * @param paint The paint used for the text (e.g. color, size, style)
     */
    public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
        native_drawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
                paint.getNativeInstance(), paint.mNativeTypeface);
    }

参数x:绘制文本起源的x坐标
参数y:绘制文本基线的y坐标

那么什么是文本基线的y坐标?使用如下代码来测试文本基线的y坐标:

        Rect bounds = new Rect();
        mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        canvas.translate(mX, mY);
        canvas.drawText(mText, mX, mY, mTextPaint);
        canvas.drawLine(mX, mY, mX + bounds.width(), mY, mLinePaint);

其中mX=8,mY=12,canvas.translate(mX, mY)将坐标原点移至到(mX,mY)。

以下为绘制后的图:

从图中可以看出,文本基线的y坐标并非文本高度的中点,文本基线就只是一条简单的文本所处的直线。

关于测量文本的高度

1.getTextBounds(String, int, int, Rect)方法

如果想要居中固定的文本,可以用该方法获得文本高度。

        Rect bounds = new Rect();
        mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
        canvas.translate(mX, mY);
        canvas.drawText(mText, mX, mY, mTextPaint);
        canvas.drawRect(new RectF(mX, mY + bounds.top, mX + bounds.width(), mY + bounds.bottom), mLinePaint);
这里有两张绘制的示例图:


从图中可以看出,不同的文本内容,得到的文本高度不同。如果只是将文本居中绘制,那结果没有问题;如果将文本绘制在其它地方,那么可能会出现差错。

2.Paint.FontMetrics
使用 mTextPaint.getFontMetrics()方法得到的Paint.FontMetrics对象,可以用来获得文本高度,且不论文本内容如何变化,文本高度都是一样,保持不变(从上面的两张图可以看出来)。
Paint.FontMetrics有五个参数:

  • top:在给定字体大小的文本中,最高文字的基线到顶部的距离。
  • ascent:距离文本基线以上的推荐距离。
  • descent:距离文本基线以下的推荐距离。
  • bottom:在给定字体大小的文本中,最低文字的基线到底部的距离。
  • leading:添加在文本行之间额外的推荐距离。

top,ascent,descent,bottom,leading的具体位置如下:

其中,top:绿色;ascent:蓝色;基线:黄色;descent:紫色;bottom:红色。这里descent和bottom重合了。

所以文本的高度为:

float height = fontMetrics.bottom - fontMetrics.top + fontMetrics.leading;

因此,例如绘制相关的文本:

        Rect bounds = new Rect();
        mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        canvas.drawText(mText, mX, mY + (fontMetrics.bottom - fontMetrics.top) / 2, mTextPaint);
        canvas.drawText(mText, mWidth / 2 - bounds.centerX(), mHeight / 2 - bounds.centerY(), mTextPaint);

总结:绘制居中的文本使用getTextBounds()方法获得高度,否则使用 Paint.FontMetrics获得高度。

猜你喜欢

转载自blog.csdn.net/wangjiang_qianmo/article/details/73180042
今日推荐