I was trying to draw text inside circle and square in Jetpack Compose and I encounter this issue. The text holder/container (I am not sure what we call it), the light red rectangle, which holds the actual text, doesn't center the text drawn.
I followed this answer to draw the text exactly at the center of the circle but it still doesn't seem to be precisely at the center of the circle. As we can see, the text resides little lower part inside that light red rectangle.
As we can see in this picture, the text is already touching the lower part of the circle while we have plenty of space at the top.
Is it something to deal with the baseline? How this can be fixed?
or this is a bug?
The code:
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Green.copy(alpha = 0.2f))
.padding(36.dp),
contentAlignment = Alignment.Center
) {
val textMeasurer = rememberTextMeasurer()
val textToDraw = "O"
val style = TextStyle(
fontSize = 328.sp,
background = Color.Red.copy(alpha = 0.2f)
)
val textLayoutResult = remember(textToDraw, style) {
textMeasurer.measure(textToDraw, style)
}
Canvas(modifier = Modifier.fillMaxSize()) {
drawCircle(
center = Offset(
x = center.x,
y = center.y
),
radius = 350f,
color = Color.Blue,
style = Stroke(
width = 8f
)
)
drawText(
textMeasurer = textMeasurer,
text = textToDraw,
style = style,
topLeft = Offset(
x = center.x - textLayoutResult.size.width / 2,
y = center.y - textLayoutResult.size.height / 2
)
)
drawPoints(
points = listOf(Offset(center.x, center.y)),
pointMode = PointMode.Points,
cap = StrokeCap.Round,
color = Color.Red,
strokeWidth = 25f
)
}
}
If I make the font smaller (about 176sp in above code), it looks like below. that tells that the light red rectangle is perfectly centered within the circle but not just the text it holds.
Any help or suggestions are appreciated.
This is probably related to the font metrics, and the uneven padding added by the platform on top of the first line and bottom of last line of your text (also know as includeFontPadding).
Why don't you try:
val style = TextStyle(
fontSize = 328.sp,
background = Red.copy(alpha = 0.2f),
platformStyle = PlatformTextStyle(includeFontPadding = false)
)
That should give you a more accurate result:
Result might not be 100% perfect due to pixel exactitude and unavoidable padding in the glyph itself (the actual image used to draw the char).