美文网首页
Canvas drawText文字垂直居中方案

Canvas drawText文字垂直居中方案

作者: zizi192 | 来源:发表于2021-07-19 16:18 被阅读0次

    最近绘制自定义view时,用到画笔绘制文本,针对drawText的绘制做一些总结。

    Canvas.drawText的方法定义如下:

        /**
         * 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) {
            super.drawText(text, x, y, paint);
        }
    

    其中,x坐标比较好理解,是文本起始绘制位置的x坐标。但是y是指文本绘制的baseline的y坐标。

    以(0,0)为原点的绘制效果.png
    具体测试代码可参考Android 图解Canvas drawText文字居中的那些事

    要理解上图中的绘制效果,让我们再认识下FontMetrics类,该类是Paint的内部类。

    /**
         * 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;
        }
    

    在设置好字体尺寸后,通过Paint.getFontMetricsInt()方法来获得一个FontMetrics对象。FontMetrics定义了几个绘制时要用到的关键坐标位置,各位置含义和图示如下。注意,这四个字段的值是相对于baseline的相对值。

    • top值: 可绘制的最高高度y坐标 - baseline线y坐标,为负值
    • bottom值:可绘制的最低高度y坐标 - baseline线y坐标,为正值
    • ascent值:系统建议的字符绘制最高高度y坐标 - baseline线y坐标,为负值
    • descent值:系统建议的字符绘制最低高度y坐标 - baseline线y坐标,为正值


      FontMetrics标线.png

    baseline计算

    场景1:给定文字绘制最高点的y值

    即已知Top值,则baseline = top - fontMetrics.top.

    场景2:给定文字绘制的中间线y值

    1、已知a段(bottom和baseline之间距离)高度:a = fontMetrics.bottom
    2、计算b段(bottom和中线的距离)高度:b = (fontMetrics.bottom - fontMetrics.top)/2
    3、计算c段(baseline和中线的距离)高度:c=b-a
    4、计算baseline = centerY + c = centerY + b -a = centerY - (fontMetrics.bottom + fontMetrics.top) /2


    image.png

    实际计算时,也可以用decent和asent,即baseline = centerY - (fontMetrics.ascent + fontMetrics.descent) /2

    场景3:指定文字绘制的Rect

    原理和场景2一致,此时centerY=(rect.bottom+rect.top)/2。
    最终baseLine = (rect.bottom+rect.top)/2 - (fontMetrics.top + fontMetrics.bottom) /2

    参考文档:
    Android 图解Canvas drawText文字居中的那些事
    drawText方法的baseline计算
    Android Canvas drawText实现中文垂直居中

    相关文章

      网友评论

          本文标题:Canvas drawText文字垂直居中方案

          本文链接:https://www.haomeiwen.com/subject/duacmltx.html