---
title: "drawText"
description: "Draw styled text using a TextMeasurer.

This draw function supports multi-styling and async font loading.

TextMeasurer carries an internal cache to optimize text layout measurement for repeated calls in
draw phase. If layout affecting attributes like font size, font weight, overflow, softWrap, etc.
are changed in consecutive calls to this method, TextMeasurer and its internal cache that holds
layout results may not offer any benefits. Check out [TextMeasurer] and drawText overloads that
take [TextLayoutResult] to learn more about text layout and draw phase optimizations."
type: "function"
---

<div class='type'>Function</div>


<a id='references'></a>
<div class='sourceset sourceset-common'>Common</div>


```kotlin
fun DrawScope.drawText(
    textMeasurer: TextMeasurer,
    text: AnnotatedString,
    topLeft: Offset = Offset.Zero,
    style: TextStyle = TextStyle.Default,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    placeholders: List<AnnotatedString.Range<Placeholder>> = listOf(),
    size: Size = Size.Unspecified,
    blendMode: BlendMode = DrawScope.DefaultBlendMode,
)
```


Draw styled text using a TextMeasurer.

This draw function supports multi-styling and async font loading.

TextMeasurer carries an internal cache to optimize text layout measurement for repeated calls in
draw phase. If layout affecting attributes like font size, font weight, overflow, softWrap, etc.
are changed in consecutive calls to this method, TextMeasurer and its internal cache that holds
layout results may not offer any benefits. Check out `TextMeasurer` and drawText overloads that
take `TextLayoutResult` to learn more about text layout and draw phase optimizations.

#### Parameters

| | |
| --- | --- |
| textMeasurer | Measures and lays out the text |
| text | Text to be drawn |
| topLeft | Offsets the text from top left point of the current coordinate system. |
| style | the `TextStyle` to be applied to the text |
| overflow | How visual overflow should be handled. |
| softWrap | Whether the text should break at soft line breaks. If false, the glyphs in the text will be positioned as if there was unlimited horizontal space. If `softWrap` is false, `overflow` and TextAlign may have unexpected effects. |
| maxLines | An optional maximum number of lines for the text to span, wrapping if necessary. If the text exceeds the given number of lines, it will be truncated according to `overflow` and `softWrap`. If it is not null, then it must be greater than zero. |
| placeholders | a list of `Placeholder`s that specify ranges of text which will be skipped during layout and replaced with `Placeholder`. It's required that the range of each `Placeholder` doesn't cross paragraph boundary, otherwise `IllegalArgumentException` is thrown. |
| size | how wide and tall the text should be. If left `Size.Unspecified` as its default value, text will be forced to fit inside the total drawing area from where it's placed. If size is specified, `Size.width` will define the width of the text. `Size.height` helps defining the number of lines that fit if `softWrap` is enabled and `overflow` is `TextOverflow.Ellipsis`. Otherwise, `Size.height` either defines where the text is clipped (`TextOverflow.Clip`) or becomes no-op. |
| blendMode | Blending algorithm to be applied to the text |




<div class='sourceset sourceset-common'>Common</div>


```kotlin
fun DrawScope.drawText(
    textMeasurer: TextMeasurer,
    text: String,
    topLeft: Offset = Offset.Zero,
    style: TextStyle = TextStyle.Default,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    size: Size = Size.Unspecified,
    blendMode: BlendMode = DrawScope.DefaultBlendMode,
)
```


Draw text using a TextMeasurer.

This draw function supports only one text style, and async font loading.

TextMeasurer carries an internal cache to optimize text layout measurement for repeated calls in
draw phase. If layout affecting attributes like font size, font weight, overflow, softWrap, etc.
are changed in consecutive calls to this method, TextMeasurer and its internal cache that holds
layout results may not offer any benefits. Check out `TextMeasurer` and drawText overloads that
take `TextLayoutResult` to learn more about text layout and draw phase optimizations.

#### Parameters

| | |
| --- | --- |
| textMeasurer | Measures and lays out the text |
| text | Text to be drawn |
| topLeft | Offsets the text from top left point of the current coordinate system. |
| style | the `TextStyle` to be applied to the text |
| overflow | How visual overflow should be handled. |
| softWrap | Whether the text should break at soft line breaks. If false, the glyphs in the text will be positioned as if there was unlimited horizontal space. If `softWrap` is false, `overflow` and TextAlign may have unexpected effects. |
| maxLines | An optional maximum number of lines for the text to span, wrapping if necessary. If the text exceeds the given number of lines, it will be truncated according to `overflow` and `softWrap`. If it is not null, then it must be greater than zero. |
| size | how wide and tall the text should be. If left `Size.Unspecified` as its default value, text will be forced to fit inside the total drawing area from where it's placed. If size is specified, `Size.width` will define the width of the text. `Size.height` helps defining the number of lines that fit if `softWrap` is enabled and `overflow` is `TextOverflow.Ellipsis`. Otherwise, `Size.height` either defines where the text is clipped (`TextOverflow.Clip`) or becomes no-op. |
| blendMode | Blending algorithm to be applied to the text |




<div class='sourceset sourceset-common'>Common</div>


```kotlin
fun DrawScope.drawText(
    textLayoutResult: TextLayoutResult,
    color: Color = Color.Unspecified,
    topLeft: Offset = Offset.Zero,
    alpha: Float = Float.NaN,
    shadow: Shadow? = null,
    textDecoration: TextDecoration? = null,
    drawStyle: DrawStyle? = null,
    blendMode: BlendMode = DrawScope.DefaultBlendMode,
)
```


Draw an existing text layout as produced by `TextMeasurer`.

This draw function cannot relayout when async font loading resolves. If using async fonts or
other dynamic text layout, you are responsible for invalidating layout on changes.

#### Parameters

| | |
| --- | --- |
| textLayoutResult | Text Layout to be drawn |
| color | Text color to use |
| topLeft | Offsets the text from top left point of the current coordinate system. |
| alpha | opacity to be applied to the `color` from 0.0f to 1.0f representing fully transparent to fully opaque respectively |
| shadow | The shadow effect applied on the text. |
| textDecoration | The decorations to paint on the text (e.g., an underline). |
| drawStyle | Whether or not the text is stroked or filled in. |
| blendMode | Blending algorithm to be applied to the text |




<div class='sourceset sourceset-common'>Common</div>


```kotlin
fun DrawScope.drawText(
    textLayoutResult: TextLayoutResult,
    brush: Brush,
    topLeft: Offset = Offset.Zero,
    alpha: Float = Float.NaN,
    shadow: Shadow? = null,
    textDecoration: TextDecoration? = null,
    drawStyle: DrawStyle? = null,
    blendMode: BlendMode = DrawScope.DefaultBlendMode,
)
```


Draw an existing text layout as produced by `TextMeasurer`.

This draw function cannot relayout when async font loading resolves. If using async fonts or
other dynamic text layout, you are responsible for invalidating layout on changes.

#### Parameters

| | |
| --- | --- |
| textLayoutResult | Text Layout to be drawn |
| brush | The brush to use when drawing the text. |
| topLeft | Offsets the text from top left point of the current coordinate system. |
| alpha | Opacity to be applied to `brush` from 0.0f to 1.0f representing fully transparent to fully opaque respectively. |
| shadow | The shadow effect applied on the text. |
| textDecoration | The decorations to paint on the text (e.g., an underline). |
| drawStyle | Whether or not the text is stroked or filled in. |
| blendMode | Blending algorithm to be applied to the text |




## Code Examples
### DrawTextAnnotatedStringSample
```kotlin
@Composable
fun DrawTextAnnotatedStringSample() {
    val textMeasurer = rememberTextMeasurer()
    Canvas(Modifier.fillMaxSize()) {
        drawText(
            textMeasurer = textMeasurer,
            text =
                buildAnnotatedString {
                    withStyle(ParagraphStyle(textAlign = TextAlign.Start)) { append("Hello") }
                    withStyle(ParagraphStyle(textAlign = TextAlign.End)) { append("World") }
                },
        )
    }
}
```
### DrawTextDrawWithCacheSample
```kotlin
/**
 * This sample demonstrates how to use [drawWithCache] modifier to improve performance when drawing
 * text on DrawScope. We can use [drawWithCache] to calculate the text layout once in
 * [CacheDrawScope] and then repeatedly use the same [TextLayoutResult] in the draw phase.
 *
 * This approach improves performance when the text itself does not change but its draw attributes
 * do change over time, such as during a color animation.
 */
@Composable
fun DrawTextDrawWithCacheSample() {
    // We can disable implicit caching since we will cache in DrawWithCache
    val textMeasurer = rememberTextMeasurer(cacheSize = 0)
    // Apply the current text style from theme, otherwise TextStyle.Default will be used.
    val materialTextStyle = LocalTextStyle.current
    // Animate color repeatedly
    val infiniteTransition = rememberInfiniteTransition()
    val color by
        infiniteTransition.animateColor(
            initialValue = Color.Red,
            targetValue = Color.Blue,
            animationSpec = infiniteRepeatable(tween(1000)),
        )
    Box(
        Modifier.fillMaxSize().drawWithCache {
            // Text layout will be measured just once until the size of the drawing area or
            // materialTextStyle changes.
            val textLayoutResult =
                textMeasurer.measure(
                    text = "Hello, World!",
                    style = materialTextStyle,
                    constraints =
                        Constraints.fixed(
                            width = (size.width / 2).roundToInt(),
                            height = (size.height / 2).roundToInt(),
                        ),
                    overflow = TextOverflow.Ellipsis,
                )
            // color changes will only invalidate draw phase
            onDrawWithContent {
                drawContent()
                drawText(
                    textLayoutResult,
                    color = color,
                    topLeft =
                        Offset(
                            (size.width - textLayoutResult.size.width) / 2,
                            (size.height - textLayoutResult.size.height) / 2,
                        ),
                )
            }
        }
    )
}
```
### DrawTextMeasureInLayoutSample
```kotlin
/**
 * This sample demonstrates how to use layout phase to improve performance when drawing text on
 * DrawScope. We can use [layout] Modifier or [Layout] composable to calculate the text layout
 * during layout phase and then cache the result in a Snapshot aware state to draw it during draw
 * phase.
 */
@Composable
fun DrawTextMeasureInLayoutSample() {
    val textMeasurer = rememberTextMeasurer()
    var textLayoutResult by remember { mutableStateOf<TextLayoutResult?>(null) }
    Canvas(
        Modifier.fillMaxSize().layout { measurable, constraints ->
            val placeable = measurable.measure(constraints)
            // TextLayout can be done any time prior to its use in draw, including in a
            // background thread.
            // In this sample, text layout is measured in layout modifier. This way the layout
            // call can be restarted when async font loading completes due to the fact that
            // `.measure` call is executed in `.layout`.
            textLayoutResult =
                textMeasurer.measure(text = "Hello, World!", style = TextStyle(fontSize = 24.sp))
            layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) }
        }
    ) {
        // This happens during draw phase.
        textLayoutResult?.let { drawText(it) }
    }
}
```
### DrawTextSample
```kotlin
@Composable
fun DrawTextSample() {
    val textMeasurer = rememberTextMeasurer()
    Canvas(Modifier.fillMaxSize()) { drawText(textMeasurer, "Hello, World!") }
}
```
### DrawTextStyledSample
```kotlin
@Composable
fun DrawTextStyledSample() {
    val textMeasurer = rememberTextMeasurer()
    Canvas(Modifier.fillMaxSize()) {
        drawText(
            textMeasurer = textMeasurer,
            text = "Hello, World!",
            style =
                TextStyle(
                    fontSize = 24.sp,
                    fontWeight = FontWeight.Bold,
                    textDecoration = TextDecoration.Underline,
                ),
        )
    }
}
```

