文字区域

来源:互联网 发布:濮阳招聘数控编程 编辑:程序博客网 时间:2024/05/16 22:18

概述

android文字绘制中,不得不说到的就是文字的基线,baseline,小时候写的四线的英文如下:

这里写图片描述

其中的第三条线就是文字的基线(baseline),看起来文字好像是坐在上面一样。

绘制文字的方法drawText在前面已经讲过了,这里就不再赘述。

下面看一看android中基线的位置:

这里写图片描述

红色的是基线,两条红色的交点就是绘制的起点。绘制代码如下:

int baselineX = 100;int baselineY = 100;canvas.drawText("just for test", baselineX, baselineY, paint);canvas.drawLine(baselineX, baselineY, 1000, baselineY, linePaint);canvas.drawLine(baselineX, baselineY, baselineX, 0, linePaint);

由此可见,一般的图形绘制是以左上角为起点,而文字绘制的时候,指定起点实际上是基线的起点。

在Paint中,有一个setTextAlign的方法,这个方法主要是设置绘制起点于文字所在矩形的位置。

setTextAlign(Align align);

他接收参数Align,值为

Paint.Align.LEFT   //绘制起点在文字矩形左边Paint.Align.CENTER //绘制起点在文字矩形中间Paint.Align.RIGHT  //绘制起点在文字矩形右边

效果分别如下

这里写图片描述 这里写图片描述 这里写图片描述

以上基本讲解了文字区域和基线以及起点的一个关系。

FontMetrics

要了解FontMetrics先看如下的一张图:

这里写图片描述

  • ascent: 系统建议的,绘制单个字符时,字符应当的最高高度所在线
  • descent:系统建议的,绘制单个字符时,字符应当的最低高度所在线
  • top: 可绘制的最高高度所在线
  • bottom: 可绘制的最低高度所在线

    如上,加上baseline那么文字相关的就有5条线

    FontMetrics有如下属性,他们并不是直接对应上面的四条线的y坐标,而是和baseline的相对关系。

    public float top;
    public float ascent;
    public float descent;
    public float bottom;

    关系如下

    1. ascent = ascent线的y坐标 - baseline线的y坐标;
    2. descent = descent线的y坐标 - baseline线的y坐标;
    3. top = top线的y坐标 - baseline线的y坐标;
    4. bottom = bottom线的y坐标 - baseline线的y坐标;

    那么根据上诉公式可以推出,这四条线的y坐标都等于对应FontMetrics属性+baseline的y坐标。

  • ascent线Y坐标 = baseline线的y坐标 + fontMetric.ascent;

  • descent线Y坐标 = baseline线的y坐标 + fontMetric.descent;
  • top线Y坐标 = baseline线的y坐标 + fontMetric.top;
  • bottom线Y坐标 = baseline线的y坐标 + fontMetric.bottom;

    那么如何得到FontMetrics值呢,代码如下:

    Paint.FontMetrics fontMetrics = paint.getFontMetrics();

    绘制出如上的线条如下

    这里写图片描述

区域

如何判断文字在绘制中占据的区域。文字不仅仅是占据文字可见的区域,由于上面讲述的几条线条并不是紧贴文字的,所以文字绘制占据的区域实际上比可见局域大。

文字所占据区域的高度,根据上面的内容,就是top线条和bottom线条的间距。那么宽度如何得到呢:

float width = paint.measureText(text);

使用上诉方法,可以测量出具体字符串所对应的宽度。

这里得到的宽,高所组成的矩形,实际上是文字绘制过程中占据的实际大小,比文字可见大小大。那么如何获得紧紧包裹文字可见内容的区域呢,需要使用如下方法:

public void getTextBounds(String text, int start, int end, Rect bounds);  

它将会返回字符串可见区域占据的最小的边界。
注意:这个方法返回的rect是以0,0做为基线的坐标,因此要得到文字实际上占据的位置,需要根据绘制起点做适当的平移。

看如下示例图:

这里写图片描述

代码如下:

      //绘制占据局域    float width = paint.measureText(text);    RectF rectF = new RectF(baselineX, top, baselineX + width, bottom);    paint.setColor(Color.RED);    canvas.drawRect(rectF, paint);    //绘制文字可见矩形    Rect minRect = new Rect();    paint.getTextBounds(text, 0, text.length(), minRect);    minRect.left += baselineX;    minRect.right += baselineX;    minRect.top += baselineY;    minRect.bottom += baselineY;    paint.setColor(Color.GREEN);    canvas.drawRect(minRect, paint);    //绘制文字    paint.setColor(Color.BLUE);    canvas.drawText(text, baselineX, baselineY, paint);
0 0
原创粉丝点击