美文网首页
Paint的基本使用

Paint的基本使用

作者: code希必地 | 来源:发表于2020-12-14 13:57 被阅读0次

1、文字的绘制

1.1、四线格与基线

先看下文字在四线格中的展示


image.png

在Canvas中绘制文字也是有规则的,这个规则就是基线,下面看下什么是基线


image.png
从上图可见,只要基线确定了,那么文字的位置就确定。

1.2、drawText()与基线的关系

public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint)

上面函数是常用的绘制文字的方法,其中(x,y)并不是绘制文字的左上角点,而是基线开始处的位置,如下图小点的位置就是点(x,y)


image.png

可见:

  • drawText()函数中y就是基线的位置
  • 只要x坐标、基线的位置、文字的大小确定了,文字的位置就确定了。

1.3、绘图四线格和FontMetrics

1.3.1、文字的绘图四线格

除了基线之前,绘制文字还有4条线:ascent、descent、top和bottom,如下图所示


image.png
  • ascent:绘制单个字符时,字符应当的最高高度所在线
  • descent:在绘制单个字符时,字符应当的最低高度所在线
  • top:可绘制的最高高度所在线
  • bottom:可绘制的最低高度所在线
    单看字面意思,可能还是不好理解它们的区别,下面举个例子:


    image.png

    图中灰色部分表示电视屏幕,白色虚线框表示安全区域框,这个安全区域框就是系统推荐的显示区域,但是由于制式不同,每个国家电视屏幕大小不一致,可能会导致视频被裁剪,但是系统推荐的区域内,无论那种制式都是可以完整显示的。
    同样,在绘制文字时,ascent是系统推荐的绘制文字最高高度所在,表示在绘制文字时,要尽量在这个最高高度线以下进行绘制,descent是系统推荐的最低高度所在线,要尽量在这个最低高度线以上进行绘制。top表示文字可绘制的最高高度线所在,bottom表示文字可绘制的最低高度线所在。ascent、descent是系统推荐的绘制高度,而top、bottom是物理上最高、最低可绘制的高度。

1.3.2、FontMetrics

上面所提到的ascent、descent、top、bottom是如何计算的呢?系统提供了FontMetrics,它里面有4个成员变量:

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

它们的计算方式和含义如下:

  • ascent=ascent线的y坐标-基线的y点坐标
  • descent=descent线的y坐标-基线的y点坐标
  • top=top点的y坐标-基线的y点坐标
  • bottom=bottom点的y坐标-基线的y点坐标
    示例:绘制出各条线的位置
override fun onDraw(canvas: Canvas?) {
    super.onDraw(canvas)
    paint.setColor(Color.RED)
    paint.textSize=120f

    canvas?.drawText("harvic \\’ s blog", baselinex, baselineY, paint)

    val fontMetrics = paint.getFontMetrics()
    val ascentY = fontMetrics.ascent + baselineY
    val dsecentY = fontMetrics.descent + baselineY
    val topY = fontMetrics.top + baselineY
    val bottomY = fontMetrics.bottom + baselineY
    val mWidth = width.toFloat()
    val lineArray = floatArrayOf(
        baselinex, ascentY, mWidth, ascentY,
        baselinex, baselineY, mWidth, baselineY,
        baselinex, dsecentY, mWidth, dsecentY,
        baselinex, topY, mWidth, topY,
        baselinex, bottomY, mWidth, bottomY
    )
    canvas?.drawLines(lineArray,paint)
}

效果图如下


image.png

1.4、常见函数

下面讲解下如何获取文字所占的宽度、高度以及最小矩形


image.png

灰色部分就是文字所占的宽度和高度,黑色部分就是所占的最小矩形。

1.4.1、高度

字符串所占的高度很容易计算,直接用bottom线所在的y坐标减去top线坐在的y坐标即可。

val fontMetrics = paint.getFontMetrics()
val bottom=baselineY+fontMetrics.bottom
val top=baselineY+fontMetrics.top
val height=bottom-top

1.4.2、宽度

宽度也非常容易得到,利用下面函数即可

public float measureText(String text)

示例如下

 paint.textSize = 120f
val width = paint.measureText("harvic \\’ s blog")

1.4.3、最小矩形

最小矩形也是通过系统函数获取的,函数及其意义如下:

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

这个函数的作用是获取指定字符串的最小矩形,以(0,0)所在位置为基线

  • String text:要测量的最小矩形字符串
  • int start:要测量的起始字符在字符串中的索引
  • int end:要测量的字符结束的位置
  • Rect bounds:接收测量的结果
    示例:
canvas?.drawText(str, 0f, 200f, paint)

paint.getTextBounds(str, 0, str.length, dstRect)
Log.e(javaClass.simpleName,"${dstRect.toShortString()}")
paint.style = Paint.Style.STROKE
paint.setColor(Color.BLACK)
canvas?.drawRect(dstRect, paint)

打印log如下:

PaintView: [8,-90][547,26]

发现最小矩形左上角的点的y坐标为负值,这是因为getTextBounds()获取的最小矩形是以(0,0)所在位置为基线,所以为负值。
看下面的原理图


image.png

从图中可知,只需要向下平移baselineY的距离即可,修改上面的代码即可正确的绘制出矩形实际的位置

canvas?.drawText(str, 0f, 200f, paint)
//增加平移代码
canvas?.translate(0f,200f)
paint.getTextBounds(str, 0, str.length, dstRect)
Log.e(javaClass.simpleName,"${dstRect.toShortString()}")
paint.style = Paint.Style.STROKE
paint.setColor(Color.BLACK)
canvas?.drawRect(dstRect, paint)

效果图如下


image.png

1.5、示例

1.5.1、给定左上角点绘图

假定给出所有绘制文字的左上角点,然后画出文字,先来看一张图片


image.png

图中红色点就为给出的点,我们可以利用这个点,计算出基线的y坐标baselineY。
上面学习了FontMetrics,可得到一个公式

val fontMetrics = paint.getFontMetrics()
fontMetrics.top = mTop - baseLineY

所以基线的Y坐标为

val baseLineY = mTop - fontMetrics.top

最终代码如下

//画top线
canvas?.drawLine(0f,mTop,width.toFloat(),mTop,paint)

val fontMetrics = paint.getFontMetrics()
val baseLineY = mTop - fontMetrics.top

//画基线
canvas?.drawLine(0f,baseLineY,width.toFloat(),baseLineY,paint)

//绘制文字
canvas?.drawText(str, 0f, baseLineY, paint)

1.5.2、给定中间线绘制文字

加上文字所在矩形的中间线,目前存在下面几条线,如下图:


image.png

从上图进行推导baseline的y坐标,过程如下:

A=C=(bottom.y-top.y)/2 即A=C=(FontMetrics.bottom-FontMetrics.top)/2
C=(bottom.y-baseline.y)+B 即C=FontMetrics.bottom+B
B=baseline.y-center.y 
则C=FontMetrics.bottom+baseline.y-center.y 
即(FontMetrics.bottom-FontMetrics.top)/2=FontMetrics.bottom+baseline.y-center.y 
则baseline.y=(-FontMetrics.top-FontMetrics.bottom)/2+center.y

计算出baseline.y之后就可以计算出top.bottom了

val top = fontMetrics.top + baselineY
val bottom=fontMetrics.bottom+baselineY

具体代码如下:

val fontMetrics = paint.getFontMetrics()
//画基线
val baselineY = (-fontMetrics.top - fontMetrics.bottom) / 2 + mCenter
canvas?.drawLine(0f, baselineY, width.toFloat(), baselineY, paint)
//画top线
val mTop = fontMetrics.top + baselineY
canvas?.drawLine(0f, mTop, width.toFloat(), mTop, paint)
//画center
canvas?.drawLine(0f, mCenter, width.toFloat(), mCenter, paint)
//画bottom
val mBottom = fontMetrics.bottom + baselineY
canvas?.drawLine(0f, mBottom, width.toFloat(), mBottom, paint)
//画文字
canvas?.drawText(str, 0f, baselineY, paint)

效果如下


image.png

2、Paint常用函数

  • setStrokeMiter(float miter):设置画笔的倾斜度,并没有什么用处
  • PathEffect setPathEffect(PathEffect effect):设置路径的样式,参数是派生自PathEffect左右子类:ComposePathEffect、CornerPathEffect、DashPathEffect、DiscretePathEffect、PathDashPathEffect、SumPathEffect,能实现复杂的路径效果,每种路径效果对应下图


    image.png
  • public void setStrokeCap(Cap cap):设置线帽样式,取值有三个:BUTT(无线帽)、ROUND(圆形线帽)、SQUARE(方形线帽)。


    image.png
  • public void setStrokeJoin(Join join):设置路径转角的样式,取值有三个:MITER(结合处为锐角)、ROUND(结合处为圆弧)、BEVEL(结合处为直线)


    image.png

相关文章

  • Paint基本使用

    Paint 基本使用《Paint的方法主要可以抽象成两大类》:

  • Paint 基本使用

    Paint 基本使用 《Paint的方法主要可以抽象成两大类》: 1.1 负责设置获取图形绘制、路径相关的 1.s...

  • Paint的基本使用

    绘制文字 1.0 绘制文字其实是使用Canvas当中的drawText()函数来绘制的: 在drawText()函...

  • Paint的基本使用

    1、文字的绘制 1.1、四线格与基线 先看下文字在四线格中的展示 在Canvas中绘制文字也是有规则的,这个规则就...

  • 二.Paint的基本使用

    前言 在讲述自定义控件的时候,我们讲到了自定义控件的基本步骤,那么在自定义控件中,我们第一个需要了解的就是Pain...

  • Android UI | Paint 详解

    Paint 基本使用《Paint的方法主要可以抽象成两大类》: 1.1 负责设置获取图形绘制、路径相关的 1.2 ...

  • Paint画笔高级应用(一)

    Paint我们分为两篇文章讲解 一,讲解基本常见的Api和渲染器的使用二,过滤器的使用及Paint的总结 Pain...

  • UI绘制_Paint基本使用

    这里我们来学习一下Paint的使用,废话不多说,开始撸码 正文 开始我们先要学习一下Paint的简单使用喽! 设置...

  • 三.Canvas的基本用法

    前言 在之前讲过画笔Paint的基本使用,这篇文章让我们来了解下画布---Canvas的基本使用。 今天讲解的内容...

  • UI绘制_Paint的高级渲染

    上一篇讲解了Paint的基本使用,从初始化到绘制,学好了基本功接下来要开始Paint的高级渲染的部分在开始之前还是...

网友评论

      本文标题:Paint的基本使用

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