美文网首页Android学习
getTextBounds中bounds的坐标原点

getTextBounds中bounds的坐标原点

作者: sunnyxibei | 来源:发表于2017-08-02 09:04 被阅读241次

    在使用getTextBouds的时候,demo绘制了一个大写的字母A,log打印了一下

    Rect bounds = new Rect();
    ........
    paint.getTextBounds(text,0,text.length(),bounds);
    

    bounds.top = -318;
    bounds.bottom = 0;
    遂认为原点是文字TextBounds的左下角。
    但事实却打脸了,犯了盲人摸象的错误,以偏概全。
    Api中是这样说明的:

    Return in bounds (allocated by the caller) the smallest rectangle that
    encloses all of the characters, with an implied origin at (0,0).
    

    然而并没有明确 implied origin 到底是哪个点。上面我认为原点是bounds的左下角,然而并不是,所以baseline的起点应该是唯一合理的原点了,下面来验证。

    OK,我们再来看一下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) {
        native_drawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
                paint.getNativeInstance(), paint.mNativeTypeface);
    }
    
    

    这里的y,是baseline对应的y轴坐标值。
    所以,事实上,我们要计算出y轴的坐标值和外框Rect中点middle的y坐标之间的差值。
    然后middle+差值,就是baseline应该的坐标。

    minus = (bounds.top + bounds.bottom)/2;
    注意,top在baseline上方,所以是负值,bottom在baseline下方(也有可能和baseline重合),所以是零或者正值。
    minus计算出来是个负值,所以middle = middle - minus;
    这样处理了一下,文字果然居中了。
    so,上面的猜测是正确的,原点就是baseline的左边起点,问题搞定了。

    核心细节有两个:

    1. drawText绘制文字时,y是baseline的y
    2. bounds的implied origin at (0,0).这个点是baseline的左边起点

    来个图方便理解

    drawText.png

    相关文章

      网友评论

      • 刻舟求剑KJ:为什么 height = bounds.top + bounds.bottom 而不是 height = bounds.bottom - bounds.top 呢
        刻舟求剑KJ:@sunnyxibei 我理解错了,我以为你这里的 height 是要计算 bounds 的高度:joy:
        sunnyxibei:@刻舟求剑KJ
        top在x轴(baseline)上方,是负值
        bottom在x轴下方,是正值
        so,你感受一下。。。

      本文标题:getTextBounds中bounds的坐标原点

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