Tips for Android Canvas.drawText Function

Why?

If you start doing the Android platform’s customized view components, you may need to draw something special in your Canvas object. It’s very straightforward to draw a circle, a rectangle, an arc, etc. You probably would ask one question:

What about drawing a string on your canvas?

Well, that’s a good question. Let’s see how to draw a string fundamentally.

Basic way to draw a string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class CustomizeView(context: Context) : View(context) {

private val textPaint = Paint()
private val renderText = "Random String"
private val startX = 20f
private val startY = 60f

init {
textPaint.apply {
color = Color.BLACK
style = Paint.Style.STROKE
strokeCap = Paint.Cap.ROUND
textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 30f, resources.displayMetrics)
}
}

override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)

canvas?.drawText(renderText, startX, startY, textPaint)
}
}

I create a customized view that displays a Random String on the screen. As you can see, the most important thing for a personalized view you need to take care of is its onDraw function. In this function, you can draw whatever you want as long as you know how to draw objects.

Find the center point of the string

Let’s draw a circle and put the above string behind the circle we have outlined. The request here is to get the string’s center point and let this string locate at the circle’s center. Let’s see how to do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)

canvas?.apply {

val textBound = Rect()
textPaint.getTextBounds(renderText, 0, renderText.length, textBound)

drawText(renderText,
circleCenterX - textBound.width() / 2,
circleCenterY - textBound.height() / 2,
textPaint)
drawCircle(circleCenterX, circleCenterY, circleRadius, circlePaint)
}
}

The first thought that comes to my mind is that I want to get the text bound for this specific text and then let both the text’s width/height bound divide by 2. This coordinate would be the start point to draw. Let’s see what the result is.

DrawText_Exmaple.png
Drawing the string at the center point of the circle

The basic introduction of the font metrics

It doesn’t look at what we want to show on the screen. Let’s get into the font metrics on the Android platform. Here is a picture from reference [1].

1*v1FDlH-vFEnhXDFDxp6OXg.png

Here are some brief descriptions for different positions:

Top: the maximum distance above the baseline for the tallest glyph in a string at given text size.

Ascent: the recommended distance above the baseline for the singled spaced text.

Mean line: the top line for the letters that don’t have the ascending.

Baseline: the line that each character sits upon.

Descent: the recommended distance below the baseline for the singled spaced text.

Bottom: the maximum distance below the baseline for the lowest glyph in a string at given text size.

Leading: the space between lines. It shows the distance between the former line’s bottom and the latter line’s top.

Line height: the distance between top and bottom.

To find the string’s center y, you will need to use these two values - Ascent and Descent.

Happy coding - enjoy.

Reference

[1] Android 101: Typography. One way or another, every developer… | by Orhan Obut | ProAndroidDev

Tips for Android Canvas.drawText Function

Why?

If you start doing the Android platform’s customized view components, you may need to draw something special in your Canvas object. It’s very straightforward to draw a circle, a rectangle, an arc, etc. You probably would ask one question:

What about drawing a string on your canvas?

Well, that’s a good question. Let’s see how to draw a string fundamentally.

Basic way to draw a string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class CustomizeView(context: Context) : View(context) {

private val textPaint = Paint()
private val renderText = "Random String"
private val startX = 20f
private val startY = 60f

init {
textPaint.apply {
color = Color.BLACK
style = Paint.Style.STROKE
strokeCap = Paint.Cap.ROUND
textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 30f, resources.displayMetrics)
}
}

override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)

canvas?.drawText(renderText, startX, startY, textPaint)
}
}

I create a customized view that displays a Random String on the screen. As you can see, the most important thing for a personalized view you need to take care of is its onDraw function. In this function, you can draw whatever you want as long as you know how to draw objects.

Find the center point of the string

Let’s draw a circle and put the above string behind the circle we have outlined. The request here is to get the string’s center point and let this string locate at the circle’s center. Let’s see how to do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)

canvas?.apply {

val textBound = Rect()
textPaint.getTextBounds(renderText, 0, renderText.length, textBound)

drawText(renderText,
circleCenterX - textBound.width() / 2,
circleCenterY - textBound.height() / 2,
textPaint)
drawCircle(circleCenterX, circleCenterY, circleRadius, circlePaint)
}
}

The first thought that comes to my mind is that I want to get the text bound for this specific text and then let both the text’s width/height bound divide by 2. This coordinate would be the start point to draw. Let’s see what the result is.

DrawText_Exmaple.png
Drawing the string at the center point of the circle

The basic introduction of the font metrics

It doesn’t look at what we want to show on the screen. Let’s get into the font metrics on the Android platform. Here is a picture from reference [1].

1*v1FDlH-vFEnhXDFDxp6OXg.png

Here are some brief descriptions for different positions:

Top: the maximum distance above the baseline for the tallest glyph in a string at given text size.

Ascent: the recommended distance above the baseline for the singled spaced text.

Mean line: the top line for the letters that don’t have the ascending.

Baseline: the line that each character sits upon.

Descent: the recommended distance below the baseline for the singled spaced text.

Bottom: the maximum distance below the baseline for the lowest glyph in a string at given text size.

Leading: the space between lines. It shows the distance between the former line’s bottom and the latter line’s top.

Line height: the distance between top and bottom.

To find the string’s center y, you will need to use these two values - Ascent and Descent.

Happy coding - enjoy.

Reference

[1] Android 101: Typography. One way or another, every developer… | by Orhan Obut | ProAndroidDev