【Android 应用开发】Canvas 绘制文字 ( 文字尺寸测量 | 基线绘制 )

举报
韩曙亮 发表于 2022/01/11 00:15:38 2022/01/11
【摘要】 文章目录 I . 文字尺寸测量II . 基线绘制 I . 文字尺寸测量 1 . 精准绘制需求 : Canvas 绘制文字时 , 有时需要精准的控制文字的绘...



I . 文字尺寸测量



1 . 精准绘制需求 : Canvas 绘制文字时 , 有时需要精准的控制文字的绘制 , 如绘制到指定的区域 , 居中 , 或者位于某个精准的坐标 ;


2 . 精准测量 : 要实现精准绘制 , 必须对字符串绘制的区域有详细的测量 , 如字符串绘制的 宽度 , 高度 等信息时必须知道的 ;


3 . 测量文字宽度 ( 粗略 ) : 调用 Paint 的 measureText ( ) 方法 , 可以测量整体宽度 ;

//1 . 创建画笔
Paint paint = new Paint();
//2 . 要绘制的字符串
String text = "ABCD";

//3 . 测量宽度
float textWidth = paint.measureText(text);

//4 . 打印测量结果 : textWidth : 32.0
Log.i(TAG, "textWidth : " + textWidth);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4 . 测量文字每个字符的宽度 ( 精确 ) : 调用 Paint 的 getTextWidths ( ) 方法 , 可以测量每个字符的宽度 ;

//1 . 创建画笔
Paint paint = new Paint();
//2 . 要绘制的字符串
String text = "ABCD";

//3 . 获取 从第 0 个开始 , text.length() 个字符 , 每个字符的宽度 , 将其存储到 widths 数组中
float[] widths = new float[text.length()];
paint.getTextWidths(text, 0, text.length(), widths);

//4 . 打印测量结果 : widths[0] : 8.0 , widths[1] : 8.0 , widths[2] : 8.0 , widths[3] : 8.0
Log.i(TAG, "widths[0] : " + widths[0] +
        " , widths[1] : " + widths[1] +
        " , widths[2] : " + widths[2] +
        " , widths[3] : " + widths[3]);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

5 . 测量文字矩形区域 ( 推荐 ) : 调用 Paint 的 getTextBounds ( ) 方法 , 可以测量字符串绘制的矩形区域 , 可以获取其宽度 , 高度 , 左上右下 等信息 ;

//1 . 创建画笔
Paint paint = new Paint();

//2 . 要绘制的字符串
String text = "ABCD";

//3 . 测量结果载体
Rect rect = new Rect();

//4 . 测量绘制字符串的矩形区域 , 将测量结果放入 rect 对象中
paint.getTextBounds(text,0, text.length(), rect);

//5 . 打印结果 : rect : Rect(0, -9 - 31, 0)
Log.i(TAG, "rect : " + rect);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14


II . 基线绘制



1 . 隐含的五条线 : 使用 Canvas 绘制的字符串 , 每个绘制的字符串 , 都隐含五条线 :

① Top 线 : 字符串绘制最顶部 , 不会超过该线 ;

② Asent 线 : 字母的最高点 ;

③ Baseline 线 : 文字绘制的基线 ;

④ Descent 线 : 字母的最低点 ;

⑤ Bottom 线 : 字符串绘制最顶部 , 不会低于该线 ;


2 . 获取上述除基线外的四个值 : 注意这几个值的加减关系 , 每条线的值减去基线的值 , 有正数 , 有负数 ;

FontMetrics fontMetrics = mPaint.getFontMetrics();

//Top - Baseline : top : -12.673828
fontMetrics.top;

//Ascent - Baseline : ascent : -11.1328125
fontMetrics.ascent;

//Descent - Baseline : descent : 2.9296875
fontMetrics.descent;

//Bottom - Baseline : bottom : 3.2519531
fontMetrics.bottom;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4 . 相关数的正负值 :


基线的位置是 0 : Baseline = 0 ;

每个值的正负 : 高于基线的大于 0 , 小于基线的小于 0 ; 即 Top 和 Asent 是小于 0 的数 ; Descent 和 Bottom 是大于 0 的数 ;


5 . 已知顶端位置绘制字符串 :


Baseline + Top = 绘制字符串最顶端值 ;

Baseline = 绘制字符串最顶端值 - Top ;

此时 , 如果已知绘制的最顶端的值 , 调用 drawText 方法 , 需要传入一个基线值 , 此时就需要用到 “Baseline = 绘制字符串最顶端值 - Top” 公式了 ;

下面是在 ( 0 , 100 ) 坐标系位置绘制字符串 , 字符串的左上角是 ( 0 , 100 ) 坐标 ;

//创建画笔
Paint paint = new Paint();
//要绘制的字符串
String text = "ABCD";

//打印四个值 : 
//top : -12.673828 , leading : 0.0 , ascent : -11.1328125 , descent : 2.9296875 , bottom : 3.2519531
L.i(TAG, "top : " + paint.getFontMetrics().top +
        " , leading : " + paint.getFontMetrics().leading +
        " , ascent : " + paint.getFontMetrics().ascent +
        " , descent : " + paint.getFontMetrics().descent +
        " , bottom : " + paint.getFontMetrics().bottom);

//计算出文字基线的值
float baseline = 100 - paint.getFontMetrics().top;

//在 ( 0 , 100 ) 坐标系位置绘制字符 , 字符串的左上角是 ( 0 , 100)
canvas.drawText(text , 0, baseline , paint);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

下面的图片仅供参考 :

在这里插入图片描述

文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。

原文链接:hanshuliang.blog.csdn.net/article/details/104759387

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。